summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorManolo Gouy <Manolo>2016-05-19 16:50:09 +0000
committerManolo Gouy <Manolo>2016-05-19 16:50:09 +0000
commit867e640cb836f4a54141541536222c6304a7d2ed (patch)
tree3e9f5a018e0eb5f3fb87e584c8ce583f358fb7e8 /src
parentccf3681097763b8246d314d73cfee6dffdddaf86 (diff)
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
Diffstat (limited to 'src')
-rw-r--r--src/Fl_Help_View.cxx46
1 files changed, 29 insertions, 17 deletions
diff --git a/src/Fl_Help_View.cxx b/src/Fl_Help_View.cxx
index 9ef1cbaf8..223064bfb 100644
--- a/src/Fl_Help_View.cxx
+++ b/src/Fl_Help_View.cxx
@@ -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);
}