* 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
This commit is contained in:
Benoît Minisini 2015-05-14 21:32:48 +00:00
parent 3f22948435
commit bec95180a1
4 changed files with 59 additions and 35 deletions

View file

@ -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)

View file

@ -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()

View file

@ -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()

View file

@ -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"