summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/drivers/Cairo/Fl_Cairo_Graphics_Driver.H1
-rw-r--r--src/drivers/Cairo/Fl_Cairo_Graphics_Driver.cxx41
-rw-r--r--src/drivers/PostScript/Fl_PostScript.cxx1
-rw-r--r--src/drivers/Xlib/Fl_Xlib_Graphics_Driver_font_xft.cxx5
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);