diff options
| author | ManoloFLTK <41016272+ManoloFLTK@users.noreply.github.com> | 2024-10-07 16:20:44 +0200 |
|---|---|---|
| committer | ManoloFLTK <41016272+ManoloFLTK@users.noreply.github.com> | 2024-10-07 16:20:59 +0200 |
| commit | 6e5f3f7ecb3cc0039e113a5e3b2409ba0f7e7cea (patch) | |
| tree | 8e77b247811c2765ef8a098d1dc9343ba12ef9a5 | |
| parent | 05d78e8ebdf2d695bd2b3a448ed95bece4f544bb (diff) | |
Make Pango-handled text accept legacy CP1252-encoded text
| -rw-r--r-- | src/drivers/Cairo/Fl_Cairo_Graphics_Driver.H | 1 | ||||
| -rw-r--r-- | src/drivers/Cairo/Fl_Cairo_Graphics_Driver.cxx | 41 | ||||
| -rw-r--r-- | src/drivers/PostScript/Fl_PostScript.cxx | 1 | ||||
| -rw-r--r-- | src/drivers/Xlib/Fl_Xlib_Graphics_Driver_font_xft.cxx | 5 |
4 files changed, 48 insertions, 0 deletions
diff --git a/src/drivers/Cairo/Fl_Cairo_Graphics_Driver.H b/src/drivers/Cairo/Fl_Cairo_Graphics_Driver.H index f0679d457..5f7da4f8a 100644 --- a/src/drivers/Cairo/Fl_Cairo_Graphics_Driver.H +++ b/src/drivers/Cairo/Fl_Cairo_Graphics_Driver.H @@ -66,6 +66,7 @@ public: PangoLayout *pango_layout() {return pango_layout_;} void set_cairo(cairo_t *c, float f = 0); static cairo_pattern_t *calc_cairo_mask(const Fl_RGB_Image *rgb); + static const char *clean_utf8(const char* str, int &n); void check_status(void); diff --git a/src/drivers/Cairo/Fl_Cairo_Graphics_Driver.cxx b/src/drivers/Cairo/Fl_Cairo_Graphics_Driver.cxx index 113713c46..3c6bd8fa3 100644 --- a/src/drivers/Cairo/Fl_Cairo_Graphics_Driver.cxx +++ b/src/drivers/Cairo/Fl_Cairo_Graphics_Driver.cxx @@ -1311,11 +1311,50 @@ void Fl_Cairo_Graphics_Driver::font(Fl_Font fnum, Fl_Fontsize s) { } +// Scans the input string str with fl_utf8decode() that accepts also non-UTF-8 +// and processes it as if encoded in CP1252. +// Returns a true UTF-8 string and its length, possibly transformed from CP1252. +// If the input string is true UTF-8, returned string is the same memory as input. +// Otherwise, returned string is in private memory allocated inside clean_utf8() +// and extended when necessary. +const char *Fl_Cairo_Graphics_Driver::clean_utf8(const char* str, int &n) { + static char *utf8_buffer = NULL; + static int utf8_buffer_len = 0; + char *q = utf8_buffer; + const char *p = str; + const char *retval = str; + int len, len2; + const char *end = str + n; + char buf4[4]; + while (p < end) { + unsigned codepoint = fl_utf8decode(p, end, &len); + len2 = fl_utf8encode(codepoint, buf4); + if (retval != str || len != len2) { // switch to using utf8_buffer + if (!utf8_buffer_len || utf8_buffer_len < (q - utf8_buffer) + len2) { + utf8_buffer_len += (q - utf8_buffer) + len2 + 1000; + utf8_buffer = (char *)realloc(utf8_buffer, utf8_buffer_len); + } + if (retval == str) { + retval = utf8_buffer; + q = utf8_buffer; + if (p > str) { memcpy(q, str, p - str); q += (p - str); } + } + memcpy(q, buf4, len2); + q += len2; + } + p += len; + } + if (retval != str) n = q - retval; + return retval; +} + + void Fl_Cairo_Graphics_Driver::draw(const char* str, int n, float x, float y) { if (!n) return; cairo_save(cairo_); Fl_Cairo_Font_Descriptor *fd = (Fl_Cairo_Font_Descriptor*)font_descriptor(); cairo_translate(cairo_, x - 1, y - (fd->line_height - fd->descent) / float(PANGO_SCALE) - 1); + str = clean_utf8(str, n); pango_layout_set_text(pango_layout_, str, n); pango_cairo_show_layout(cairo_, pango_layout_); // 1.1O cairo_restore(cairo_); @@ -1383,6 +1422,7 @@ double Fl_Cairo_Graphics_Driver::width(const char* str, int n) { int Fl_Cairo_Graphics_Driver::do_width_unscaled_(const char* str, int n) { if (!n) return 0; + str = clean_utf8(str, n); pango_layout_set_text(pango_layout_, str, n); PangoRectangle p_rect; pango_layout_get_extents(pango_layout_, NULL, &p_rect); @@ -1391,6 +1431,7 @@ int Fl_Cairo_Graphics_Driver::do_width_unscaled_(const char* str, int n) { void Fl_Cairo_Graphics_Driver::text_extents(const char* txt, int n, int& dx, int& dy, int& w, int& h) { + txt = clean_utf8(txt, n); pango_layout_set_text(pango_layout_, txt, n); PangoRectangle ink_rect; pango_layout_get_extents(pango_layout_, &ink_rect, NULL); diff --git a/src/drivers/PostScript/Fl_PostScript.cxx b/src/drivers/PostScript/Fl_PostScript.cxx index a1f511bef..324d1c6f9 100644 --- a/src/drivers/PostScript/Fl_PostScript.cxx +++ b/src/drivers/PostScript/Fl_PostScript.cxx @@ -1572,6 +1572,7 @@ void Fl_PostScript_Graphics_Driver::transformed_draw(const char* str, int n, dou pango_layout_set_font_description(pango_layout_, pfd); int pwidth, pheight; cairo_save(cairo_); + str = Fl_Cairo_Graphics_Driver::clean_utf8(str, n); pango_layout_set_text(pango_layout_, str, n); pango_layout_get_size(pango_layout_, &pwidth, &pheight); if (pwidth > 0) { 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 959711b63..2f2b956a8 100644 --- a/src/drivers/Xlib/Fl_Xlib_Graphics_Driver_font_xft.cxx +++ b/src/drivers/Xlib/Fl_Xlib_Graphics_Driver_font_xft.cxx @@ -18,6 +18,7 @@ #include "../../flstring.h" #include "Fl_Xlib_Graphics_Driver.H" +#include "../Cairo/Fl_Cairo_Graphics_Driver.H" #include <FL/Fl.H> #include <FL/fl_draw.H> #include <FL/fl_string_functions.h> // fl_strdup() @@ -1208,6 +1209,7 @@ void Fl_Xlib_Graphics_Driver::draw_unscaled(int angle, const char *str, int n, i double l = width_unscaled(str, n); pango_matrix_rotate(&mat, angle); // 1.6 pango_context_set_matrix(pctxt_, &mat); // 1.6 + str = Fl_Cairo_Graphics_Driver::clean_utf8(str, n); pango_layout_set_text(playout_, str, n); int w, h; pango_layout_get_pixel_size(playout_, &w, &h); @@ -1263,6 +1265,7 @@ void Fl_Xlib_Graphics_Driver::do_draw(int from_right, const char *str, int n, in } const char *old = 0; if (!str2) old = pango_layout_get_text(playout_); + str = Fl_Cairo_Graphics_Driver::clean_utf8(str, n); if (!old || (int)strlen(old) != n || memcmp(str, old, n)) // do not re-set text if equal to text already in layout pango_layout_set_text(playout_, str, n); if (str2) free(str2); @@ -1335,6 +1338,7 @@ double Fl_Xlib_Graphics_Driver::do_width_unscaled_(const char* str, int n) { if (!playout_) context(); int width, height; pango_layout_set_font_description(playout_, pfd_array[font_]); + str = Fl_Cairo_Graphics_Driver::clean_utf8(str, n); pango_layout_set_text(playout_, str, n); pango_layout_get_pixel_size(playout_, &width, &height); return (double)width; @@ -1343,6 +1347,7 @@ double Fl_Xlib_Graphics_Driver::do_width_unscaled_(const char* str, int n) { void Fl_Xlib_Graphics_Driver::text_extents_unscaled(const char *str, int n, int &dx, int &dy, int &w, int &h) { if (!playout_) context(); pango_layout_set_font_description(playout_, pfd_array[font_]); + str = Fl_Cairo_Graphics_Driver::clean_utf8(str, n); pango_layout_set_text(playout_, str, n); int y_correction; fl_pango_layout_get_pixel_extents(playout_, dx, dy, w, h, descent_unscaled(), height_unscaled(), y_correction); |
