From bec95180a1a3208523f7b2aaaa160e56a0d6bab4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Beno=C3=AEt=20Minisini?= Date: Thu, 14 May 2015 21:32:48 +0000 Subject: [PATCH] [GB.GTK] * OPT: Cache Pango layout in each painter so that it is not recreated at each text drawing. * BUG: Copying a control font now should works as expected. * OPT: Paint.TextSize does not compute text size twice anymore. git-svn-id: svn://localhost/gambas/trunk@7083 867c0c6c-44f3-4631-809d-bfa615b0a4ec --- gb.gtk/src/cpaint_impl.cpp | 49 ++++++++++++++++++++++++++++---------- gb.gtk/src/gcontrol.cpp | 3 --- gb.gtk/src/gfont.cpp | 41 +++++++++++++++---------------- gb.gtk/src/gfont.h | 1 + 4 files changed, 59 insertions(+), 35 deletions(-) diff --git a/gb.gtk/src/cpaint_impl.cpp b/gb.gtk/src/cpaint_impl.cpp index 11461840b..ac4c92f7a 100644 --- a/gb.gtk/src/cpaint_impl.cpp +++ b/gb.gtk/src/cpaint_impl.cpp @@ -96,6 +96,8 @@ typedef GtkPrintContext *print_context; CFONT *font; CFONT **font_stack; + PangoLayout *layout; + float ascent; cairo_matrix_t init; double dx; double dy; @@ -368,8 +370,12 @@ static void End(GB_PAINT *d) void *device = d->device; GB_PAINT_EXTRA *dx = EXTRA(d); + if (dx->layout) + g_object_unref(dx->layout); + if (dx->font_stack) GB.FreeArray(POINTER(&dx->font_stack)); + GB.Unref(POINTER(&dx->font)); if (GB.Is(device, CLASS_Picture)) @@ -431,6 +437,21 @@ static void Antialias(GB_PAINT *d, int set, int *antialias) *antialias = (cairo_get_antialias(CONTEXT(d)) == CAIRO_ANTIALIAS_NONE) ? 0 : 1; } +static void _Font(GB_PAINT *d, int set, GB_FONT *font); + +static void update_layout(GB_PAINT *d) +{ + CFONT *font; + GB_PAINT_EXTRA *dx = EXTRA(d); + + if (dx->layout) + { + _Font(d, FALSE, (GB_FONT *)&font); + gt_add_layout_from_font(dx->layout, font->font, d->resolutionY); + dx->ascent = font->font->ascentF(); + } +} + // Font is used by X11! static void _Font(GB_PAINT *d, int set, GB_FONT *font) { @@ -444,6 +465,8 @@ static void _Font(GB_PAINT *d, int set, GB_FONT *font) } else EXTRA(d)->font = NULL; + + update_layout(d); } else { @@ -926,14 +949,20 @@ static PangoLayout *create_pango_layout(GB_PAINT *d) /*if (dx->print_context) return gtk_print_context_create_pango_layout(dx->print_context); else*/ - return pango_cairo_create_layout(dx->context); + + if (!dx->layout) + { + dx->layout = pango_cairo_create_layout(dx->context); + update_layout(d); + } + + return dx->layout; } static void draw_text(GB_PAINT *d, bool rich, const char *text, int len, float w, float h, int align, bool draw) { char *html = NULL; PangoLayout *layout; - CFONT *font; float tw, th, offx, offy; layout = create_pango_layout(d); @@ -949,9 +978,6 @@ static void draw_text(GB_PAINT *d, bool rich, const char *text, int len, float w else pango_layout_set_text(layout, text, len); - _Font(d, FALSE, (GB_FONT *)&font); - gt_add_layout_from_font(layout, font->font, d->resolutionY); - if (align == GB_DRAW_ALIGN_DEFAULT) align = ALIGN_TOP_NORMAL; @@ -964,7 +990,7 @@ static void draw_text(GB_PAINT *d, bool rich, const char *text, int len, float w else { offx = 0; - offy = -(font->font->ascentF()); + offy = -(EXTRA(d)->ascent); } cairo_rel_move_to(CONTEXT(d), offx + DX(d), offy + DY(d)); @@ -973,8 +999,6 @@ static void draw_text(GB_PAINT *d, bool rich, const char *text, int len, float w else pango_cairo_layout_path(CONTEXT(d), layout); - g_object_unref(layout); - if (html) g_free(html); } @@ -1019,11 +1043,10 @@ static void get_text_extents(GB_PAINT *d, bool rich, const char *text, int len, GetCurrentPoint(d, &x, &y); ext->x1 = (float)rect.x / PANGO_SCALE + x; - ext->y1 = (float)rect.y / PANGO_SCALE + y - font->font->ascentF(); + ext->y1 = (float)rect.y / PANGO_SCALE + y - EXTRA(d)->ascent; ext->x2 = ext->x1 + (float)rect.width / PANGO_SCALE; ext->y2 = ext->y1 + (float)rect.height / PANGO_SCALE; - g_object_unref(layout); if (html) g_free(html); } @@ -1044,9 +1067,11 @@ static void TextSize(GB_PAINT *d, const char *text, int len, float *w, float *h) _Font(d, FALSE, (GB_FONT *)&font); scale = (float)d->resolutionY / gDesktop::resolution(); + + font->font->textSize(text, len, w, h); - *w = font->font->width(text, len) * scale; - *h = font->font->height(text, len) * scale; + *w *= scale; + *h *= scale; } static void RichTextSize(GB_PAINT *d, const char *text, int len, float sw, float *w, float *h) diff --git a/gb.gtk/src/gcontrol.cpp b/gb.gtk/src/gcontrol.cpp index fac43e9c7..1fbff8ff0 100644 --- a/gb.gtk/src/gcontrol.cpp +++ b/gb.gtk/src/gcontrol.cpp @@ -743,10 +743,7 @@ gFont* gControl::font() void gControl::actualFontTo(gFont *ft) { - //fprintf(stderr, "actualFontTo: %s: %s / %s (_font = %s)\n", name(), ft->toString(), ft->toFullString(), _font ? _font->toFullString() : NULL); font()->copyTo(ft); - ft->setAllFrom(_font); - //fprintf(stderr, "==> %s: %s / %s (_font = %s)\n", name(), ft->toString(), ft->toFullString(), _font ? _font->toFullString() : NULL); } void gControl::resolveFont() diff --git a/gb.gtk/src/gfont.cpp b/gb.gtk/src/gfont.cpp index 6567d9cc2..1e79f5d34 100644 --- a/gb.gtk/src/gfont.cpp +++ b/gb.gtk/src/gfont.cpp @@ -486,6 +486,7 @@ const char *gFont::toString() ret = g_string_free(desc, false); gt_free_later(ret); + return ret; } @@ -518,34 +519,34 @@ const char *gFont::toFullString() return ret; } -int gFont::width(const char *text, int len) +void gFont::textSize(const char *text, int len, float *w, float *h) { PangoLayout *ly; - int w; + int tw = 0, th = 0; - if (!text || !*text) return 0; + if (text && len) + { + ly = pango_layout_new(ct); + pango_layout_set_text(ly, text, len); + pango_layout_get_size(ly, &tw, &th); + } - ly=pango_layout_new(ct); - pango_layout_set_text(ly,text,len); - pango_layout_get_size(ly,&w,NULL); - g_object_unref(G_OBJECT(ly)); - - return gt_pango_to_pixel(w); + if (w) *w = (float)tw / PANGO_SCALE; + if (h) *h = (float)th / PANGO_SCALE; +} + +int gFont::width(const char *text, int len) +{ + float fw; + textSize(text, len, &fw, NULL); + return gt_pango_to_pixel(fw * PANGO_SCALE); } int gFont::height(const char *text, int len) { - PangoLayout *ly; - int h; - - if (len == 0 || !text || !*text) text = " "; - - ly=pango_layout_new(ct); - pango_layout_set_text(ly,text,len); - pango_layout_get_size(ly,NULL,&h); - g_object_unref(G_OBJECT(ly)); - - return gt_pango_to_pixel(h); + float fh; + textSize(text, len, NULL, &fh); + return gt_pango_to_pixel(fh * PANGO_SCALE); } int gFont::height() diff --git a/gb.gtk/src/gfont.h b/gb.gtk/src/gfont.h index ca43bce2e..e364bff02 100644 --- a/gb.gtk/src/gfont.h +++ b/gb.gtk/src/gfont.h @@ -74,6 +74,7 @@ public: int width(const char *text, int len = -1); int height(const char *text, int len = -1); int height(); + void textSize(const char *text, int len, float *w, float *h); void richTextSize(const char *txt, int len, float sw, float *w, float *h); //"Private"