Pango layout performance with set_height
- From: Ben Dean-Kawamura <ben pculture org>
- To: gtk-list gnome org
- Subject: Pango layout performance with set_height
- Date: Fri, 10 Dec 2010 01:35:30 -0500
I'm one of the developers for Miro (getmiro.com) and I'm trying to
work on performance issues. I think I've identified one issue, which
is that pango seems to be slow when laying out text that goes below
the bottom of its height.
For example, suppose I have a very large portion of text, but I want
to render it in a 50px tall area. I call pango_layout_set_text() with
the long text, then pango_layout_set_height()
pango_layout_set_width(), and pango_layout_set_ellipsize(). Then when
I call pango_cairo_show_layout(), pango_layout_get_lines(), or any
other function that requires pango to lay out the text, it seems to
take a long time, even if the width and height are very small. I'm
not sure what's happening, but it seems that pango is layout out text
and/or generating glyphs that won't be shown.
Attached is a small C program that gets at what I'm saying. Whether I
use the long text or the short text, the performance should be
similar, since pango only needs to render 1 line of it in either case.
However, rendering the long text takes significantly longer than the
short text (5-7 times longer).
Is there anyway that I can speed up rendering when much of my text is
below the bottom of the PangoLayout height?
Ben
#include <gdk/gdk.h>
#include <gtk/gtk.h>
#include <pango/pango.h>
#include <string.h>
static int first_expose = 1;
static char long_text[] = "Lorem ipsum dolor sit amet, consectetur adipiscing elit."
"Proin congue magna a libero tincidunt porttitor. Suspendisse tellus "
"urna, suscipit ut venenatis quis, feugiat a diam. Phasellus venenatis "
"sagittis nisl, vitae molestie mi faucibus sit amet. In luctus neque "
"quis nisi condimentum id scelerisque enim commodo. Phasellus neque "
"risus, porttitor sed venenatis ut, viverra ac ante. Phasellus magna "
"diam, posuere vitae vehicula vel, accumsan eget lectus. Phasellus in "
"lectus in risus dapibus convallis laoreet accumsan odio. Morbi eu nisi "
"sed magna convallis imperdiet. Curabitur at elementum urna. Etiam in "
"erat vitae neque lacinia ornare. Curabitur a semper nisi. Quisque "
"volutpat dui et augue congue in interdum nunc ullamcorper. Cum sociis "
"natoque penatibus et magnis dis parturient montes, nascetur ridiculus "
"mus. Fusce luctus erat a nulla suscipit commodo. Sed sem tellus, "
"vehicula quis pharetra eget, rhoncus accumsan justo. Aliquam fringilla "
"sapien adipiscing sem varius adipiscing. Vestibulum iaculis est id "
"augue ullamcorper et fringilla lorem ultrices. Donec at faucibus purus. "
"\n\n"
"Mauris dapibus, arcu vel consequat ultricies, lectus nisi porta nunc, "
"iaculis sagittis elit diam ut felis. Integer nec sagittis libero. "
"Mauris semper, enim et porttitor sodales, massa diam convallis ipsum, "
"sed tincidunt libero dui at eros. Etiam id nulla in dolor lobortis "
"fermentum vel et arcu. Praesent eu nisi quis lorem auctor gravida eget "
"quis ante. Mauris condimentum, eros sit amet eleifend pretium, ipsum "
"purus suscipit metus, vel ullamcorper ipsum est sed velit. Vestibulum "
"ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia "
"Curae; Suspendisse ac rhoncus magna. Fusce at nisl libero, quis viverra "
"nibh. Aliquam gravida odio id arcu viverra id luctus velit facilisis. "
"Mauris dictum consectetur nunc eget sagittis. Suspendisse et enim ac "
"mi hendrerit scelerisque ut eu quam. "
"\n\n"
"Aenean id felis risus. Proin aliquet mollis vulputate. Aliquam rhoncus "
"convallis risus, sed commodo diam dictum et. Fusce mattis pellentesque "
"metus sit amet ultricies. Phasellus turpis dolor, commodo et dignissim "
"quis, posuere quis turpis. Nulla faucibus, dui vel aliquam ullamcorper, "
"tellus odio semper mi, pretium molestie orci arcu in diam. Nam in metus "
"felis. Nunc interdum, urna sed ullamcorper elementum, augue mauris "
"hendrerit quam, at sagittis nibh magna molestie sapien. Mauris feugiat "
"commodo auctor. Sed et ipsum ut neque consequat cursus vel et urna. "
"Phasellus in mauris metus, sit amet rhoncus est. Phasellus blandit, "
"eros vel iaculis ornare, neque augue dignissim lectus, at semper dui "
"ligula ut eros. In hac habitasse platea dictumst. Proin accumsan mauris "
"id turpis laoreet eget tempor elit semper. Pellentesque porttitor "
"sapien sit amet magna fringilla pulvinar. Pellentesque in dignissim "
"nibh. Donec nulla augue, luctus id euismod id, interdum ornare nunc. ";
char short_text[] = "Lorem ipsum dolor sit amet, consectetur adipiscing elit."
"Proin congue magna a libero tincidunt porttitor. Suspendisse tellus ";
// uncomment one of the following lines to switch between long/short text
// char *the_text = short_text;
char *the_text = long_text;
void timeit(gpointer data)
{
int i;
GtkWidget* widget = GTK_WIDGET(data);
for(i = 0; i < 500; i++) {
the_text[0] = 'a' + (i % 26);
the_text[1] = 'A' + ((i / 26) % 26);
gtk_widget_queue_draw(widget);
gdk_window_process_updates(widget->window, TRUE);
}
gtk_main_quit();
}
gboolean on_expose (GtkWidget *widget, GdkEventExpose *event, gpointer data)
{
PangoContext* context;
PangoLayout* layout;
cairo_t* cr;
cr = gdk_cairo_create(event->window);
context = pango_cairo_create_context(cr);
layout = pango_layout_new(context);
pango_layout_set_width(layout, 200 * PANGO_SCALE);
pango_layout_set_height(layout, 20 * PANGO_SCALE);
pango_layout_set_ellipsize(layout, PANGO_ELLIPSIZE_END);
pango_layout_set_text(layout, the_text, strlen(the_text));
cairo_move_to(cr, 0.0, 0.0);
pango_cairo_show_layout (cr, layout);
if(first_expose) {
g_idle_add((GSourceFunc) timeit, widget);
first_expose = 0;
}
return TRUE;
}
int main(int argc, char** argv)
{
gtk_init (&argc, &argv);
GtkWidget *drawing_area = gtk_drawing_area_new();
gtk_widget_set_size_request (drawing_area, 200, 200);
g_signal_connect (G_OBJECT (drawing_area), "expose_event",
G_CALLBACK (on_expose), NULL);
GtkWidget *window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
gtk_container_add(GTK_CONTAINER(window), drawing_area);
gtk_widget_show_all(GTK_WIDGET(window));
gtk_main();
return 0;
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]