Fix handing of html entities in copied text by Fl_Help_View widget.

git-svn-id: file:///fltk/svn/fltk/branches/branch-1.3-porting@11747 ea41ed52-d2ee-0310-a9c1-e6b18d33e121
This commit is contained in:
Manolo Gouy 2016-05-19 16:50:09 +00:00
parent ccf3681097
commit 867e640cb8
2 changed files with 30 additions and 18 deletions

View File

@ -275,7 +275,7 @@ public:
int handle(int);
private:
void hv_draw(const char *t, int x, int y);
void hv_draw(const char *t, int x, int y, int entity_extra_length = 0);
char begin_selection();
char extend_selection();
void end_selection(int c=0);

View File

@ -225,11 +225,9 @@ Fl_Color Fl_Help_View::hv_selection_color;
Fl_Color Fl_Help_View::hv_selection_text_color;
/*
* Limitation: if a word contains &code; notations, we will calculate a wrong length.
*
* This function must be optimized for speed!
*/
void Fl_Help_View::hv_draw(const char *t, int x, int y)
void Fl_Help_View::hv_draw(const char *t, int x, int y, int entity_extra_length)
{
if (selected && current_view==this && current_pos<selection_last && current_pos>=selection_first) {
Fl_Color c = fl_color();
@ -255,7 +253,7 @@ void Fl_Help_View::hv_draw(const char *t, int x, int y)
selection_push_last = l;
} else {
selection_drag_first = f;
selection_drag_last = l;
selection_drag_last = l + entity_extra_length;
}
}
}
@ -722,7 +720,9 @@ Fl_Help_View::draw()
underline = 0;
initfont(font, fsize, fcolor);
// byte length difference between html entity (encoded by &...;) and
// UTF-8 encoding of same character
int entity_extra_length = 0;
for (ptr = block->start, buf.clear(); ptr < block->end;)
{
if ((*ptr == '<' || isspace((*ptr)&255)) && buf.size() > 0)
@ -744,8 +744,9 @@ Fl_Help_View::draw()
hh = 0;
}
hv_draw(buf.c_str(), xx + x() - leftline_, yy + y());
hv_draw(buf.c_str(), xx + x() - leftline_, yy + y(), entity_extra_length);
buf.clear();
entity_extra_length = 0;
if (underline) {
xtra_ww = isspace((*ptr)&255)?(int)fl_width(' '):0;
fl_xyline(xx + x() - leftline_, yy + y() + 1,
@ -1116,7 +1117,7 @@ Fl_Help_View::draw()
if (!pre) current_pos = (int) (ptr-value_);
needspace = 1;
}
else if (*ptr == '&')
else if (*ptr == '&') // process html entity
{
ptr ++;
@ -1125,8 +1126,12 @@ Fl_Help_View::draw()
if (qch < 0)
buf.add('&');
else {
int utf8l = buf.size();
buf.add(qch);
utf8l = buf.size() - utf8l; // length of added UTF-8 text
const char *oldptr = ptr;
ptr = strchr(ptr, ';') + 1;
entity_extra_length += ptr - (oldptr-1) - utf8l; // extra length between html entity and UTF-8
}
if ((fsize + 2) > hh)
@ -3025,15 +3030,15 @@ void Fl_Help_View::end_selection(int clipboard)
{
if (!selected || current_view!=this)
return;
// convert the select part of our html text into some kind of somewhat readable ASCII
// convert the select part of our html text into some kind of somewhat readable UTF-8
// and store it in the selection buffer
// *FIXME* Should be UTF-8 (not ASCII), including HTML Entities &x; etc.
char p = 0, pre = 0;;
int p = 0;
char pre = 0;
int len = (int) strlen(value_);
char *txt = (char*)malloc(len+1), *d = txt;
const char *s = value_, *cmd, *src;
for (;;) {
char c = *s++;
int c = *s++;
if (c==0) break;
if (c=='<') { // begin of some html command. Skip until we find a '>'
cmd = s;
@ -3080,26 +3085,33 @@ void Fl_Help_View::end_selection(int clipboard)
}
continue;
}
if (c=='&') { // special characters (HTML entities) // *FIXME* *UTF-8*
const char *s2 = s;
if (c=='&') { // special characters (HTML entities)
int xx = quote_char(s);
if (xx>=0) {
c = (char)xx; // *FIXME* *UTF-8*
if (xx >= 0) {
c = xx;
for (;;) {
char cc = *s++;
if (!cc || cc==';') break;
}
}
}
int n = (int) (s-value_);
int n = (int) (s2-value_);
if (n>selection_first && n<=selection_last) {
if (!pre && isspace(c&255)) c = ' ';
if (p!=' '||c!=' ')
*d++ = c;
if (p!=' ' || c!=' ') {
if (s2 != s) { // c was an HTML entity
d += fl_utf8encode(c, d);
}
else *d++ = c;
}
p = c;
}
if (n>selection_last) break; // stop parsing html after end of selection
}
*d = 0;
Fl::copy(txt, (int) strlen(txt), clipboard);
//printf("copy [%s]\n", txt);
free(txt);
}