Make Pango-handled text accept legacy CP1252-encoded text
This commit is contained in:
parent
05d78e8ebd
commit
6e5f3f7ecb
@ -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);
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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) {
|
||||
|
@ -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);
|
||||
|
Loading…
Reference in New Issue
Block a user