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:
parent
ccf3681097
commit
867e640cb8
@ -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);
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user