diff options
| author | Albrecht Schlosser <albrechts.fltk@online.de> | 2020-01-08 19:50:35 +0100 |
|---|---|---|
| committer | Albrecht Schlosser <albrechts.fltk@online.de> | 2020-01-08 19:50:35 +0100 |
| commit | 2df013931bbb57f00b66cbaa115a846327ac2aea (patch) | |
| tree | 1eaa40d5eaa50fd9f5d47420fcc5ba0296fff13e /src/drivers | |
| parent | 3f1f8715853cd855aa66062f50843b21071f288a (diff) | |
Improve X11 coordinate clipping for text (STR 2798)
Text outside the 16-bit X11 coordinate space must be clipped before
calling X11 draw functions, otherwise text might appear anywhere
in the window because X11 would "truncate" the coordinates instead
of proper clipping (X11 handles only 16-bit coordinates).
Diffstat (limited to 'src/drivers')
| -rw-r--r-- | src/drivers/Xlib/Fl_Xlib_Graphics_Driver_font_x.cxx | 33 | ||||
| -rw-r--r-- | src/drivers/Xlib/Fl_Xlib_Graphics_Driver_font_xft.cxx | 13 |
2 files changed, 37 insertions, 9 deletions
diff --git a/src/drivers/Xlib/Fl_Xlib_Graphics_Driver_font_x.cxx b/src/drivers/Xlib/Fl_Xlib_Graphics_Driver_font_x.cxx index 377be7c91..2e615e241 100644 --- a/src/drivers/Xlib/Fl_Xlib_Graphics_Driver_font_x.cxx +++ b/src/drivers/Xlib/Fl_Xlib_Graphics_Driver_font_x.cxx @@ -642,23 +642,33 @@ void Fl_Xlib_Graphics_Driver::text_extents_unscaled(const char *c, int n, int &d if (gc_) XUtf8_measure_extents(fl_display, fl_window, ((Fl_Xlib_Font_Descriptor*)font_descriptor())->font, gc_, &xx, &yy, &ww, &hh, c, n); W = ww; H = hh; dx = xx; dy = yy; -// This is the safe but mostly wrong thing we used to do... -// W = 0; H = 0; -// fl_measure(c, W, H, 0); -// dx = 0; -// dy = fl_descent() - H; } void Fl_Xlib_Graphics_Driver::draw_unscaled(const char* c, int n, int x, int y) { + + // transform coordinates and clip if outside 16-bit space (STR 2798) + + int x1 = x + offset_x_; + if (x1 < clip_min() || x1 > clip_max()) return; + + int y1 = y + offset_y_; + if (y1 < clip_min() || y1 > clip_max()) return; + if (font_gc != gc_) { if (!font_descriptor()) this->font(FL_HELVETICA, FL_NORMAL_SIZE); font_gc = gc_; XSetFont(fl_display, gc_, ((Fl_Xlib_Font_Descriptor*)font_descriptor())->font->fid); } - if (gc_) XUtf8DrawString(fl_display, fl_window, ((Fl_Xlib_Font_Descriptor*)font_descriptor())->font, gc_, x+offset_x_, y+offset_y_, c, n); + if (gc_) XUtf8DrawString(fl_display, fl_window, ((Fl_Xlib_Font_Descriptor*)font_descriptor())->font, gc_, x1, y1, c, n); } void Fl_Xlib_Graphics_Driver::draw_unscaled(int angle, const char *str, int n, int x, int y) { + + // clip if outside 16-bit space (STR 2798) + + if (x < clip_min() || x > clip_max()) return; + if (y < clip_min() || y > clip_max()) return; + static char warning = 0; // issue warning only once if (!warning && angle != 0) { warning = 1; @@ -670,11 +680,20 @@ void Fl_Xlib_Graphics_Driver::draw_unscaled(int angle, const char *str, int n, i } void Fl_Xlib_Graphics_Driver::rtl_draw_unscaled(const char* c, int n, int x, int y) { + + // transform coordinates and clip if outside 16-bit space (STR 2798) + + int x1 = x + offset_x_; + if (x1 < clip_min() || x1 > clip_max()) return; + + int y1 = y + offset_y_; + if (y1 < clip_min() || y1 > clip_max()) return; + if (font_gc != gc_) { if (!font_descriptor()) this->font(FL_HELVETICA, FL_NORMAL_SIZE); font_gc = gc_; } - if (gc_) XUtf8DrawRtlString(fl_display, fl_window, ((Fl_Xlib_Font_Descriptor*)font_descriptor())->font, gc_, x+offset_x_, y+offset_y_, c, n); + if (gc_) XUtf8DrawRtlString(fl_display, fl_window, ((Fl_Xlib_Font_Descriptor*)font_descriptor())->font, gc_, x1, y1, c, n); } float Fl_Xlib_Graphics_Driver::scale_font_for_PostScript(Fl_Font_Descriptor *desc, int s) { diff --git a/src/drivers/Xlib/Fl_Xlib_Graphics_Driver_font_xft.cxx b/src/drivers/Xlib/Fl_Xlib_Graphics_Driver_font_xft.cxx index 4fdd070aa..26d624b8d 100644 --- a/src/drivers/Xlib/Fl_Xlib_Graphics_Driver_font_xft.cxx +++ b/src/drivers/Xlib/Fl_Xlib_Graphics_Driver_font_xft.cxx @@ -782,6 +782,15 @@ void Fl_Xlib_Graphics_Driver::text_extents_unscaled(const char *c, int n, int &d } void Fl_Xlib_Graphics_Driver::draw_unscaled(const char *str, int n, int x, int y) { + + // transform coordinates and clip if outside 16-bit space (STR 2798) + + int x1 = x + offset_x_ * scale() + line_delta_; + if (x1 < clip_min() || x1 > clip_max()) return; + + int y1 = y + offset_y_ * scale() + line_delta_; + if (y1 < clip_min() || y1 > clip_max()) return; + #if USE_OVERLAY XftDraw*& draw_ = fl_overlay ? draw_overlay : ::draw_; if (fl_overlay) { @@ -814,9 +823,9 @@ void Fl_Xlib_Graphics_Driver::draw_unscaled(const char *str, int n, int x, int y const wchar_t *buffer = utf8reformat(str, n); #ifdef __CYGWIN__ - XftDrawString16(draw_, &color, ((Fl_Xlib_Font_Descriptor*)font_descriptor())->font, x+offset_x_*scale()+line_delta_, y+offset_y_*scale()+line_delta_, (XftChar16 *)buffer, n); + XftDrawString16(draw_, &color, ((Fl_Xlib_Font_Descriptor*)font_descriptor())->font, x1, y1, (XftChar16 *)buffer, n); #else - XftDrawString32(draw_, &color, ((Fl_Xlib_Font_Descriptor*)font_descriptor())->font, x+offset_x_*scale()+line_delta_, y+offset_y_*scale()+line_delta_, (XftChar32 *)buffer, n); + XftDrawString32(draw_, &color, ((Fl_Xlib_Font_Descriptor*)font_descriptor())->font, x1, y1, (XftChar32 *)buffer, n); #endif } } |
