|
Packit |
0ec9dd |
#include <stdlib.h>
|
|
Packit |
0ec9dd |
#include <string.h>
|
|
Packit |
0ec9dd |
#include <pango/pango.h>
|
|
Packit |
0ec9dd |
#include <pango/pangocairo.h>
|
|
Packit |
0ec9dd |
|
|
Packit |
0ec9dd |
#define WIDTH 100
|
|
Packit |
0ec9dd |
#define HEIGHT 100
|
|
Packit |
0ec9dd |
const char *text = "Hamburgerfonts\nวิวิวิวิวิวิ\nبهداد";
|
|
Packit |
0ec9dd |
|
|
Packit |
0ec9dd |
int num_iters = 50;
|
|
Packit |
0ec9dd |
|
|
Packit |
0ec9dd |
GMutex mutex;
|
|
Packit |
0ec9dd |
|
|
Packit |
0ec9dd |
static cairo_surface_t *
|
|
Packit |
0ec9dd |
create_surface (void)
|
|
Packit |
0ec9dd |
{
|
|
Packit |
0ec9dd |
return cairo_image_surface_create (CAIRO_FORMAT_A8, WIDTH, HEIGHT);
|
|
Packit |
0ec9dd |
}
|
|
Packit |
0ec9dd |
|
|
Packit |
0ec9dd |
static PangoLayout *
|
|
Packit |
0ec9dd |
create_layout (cairo_t *cr)
|
|
Packit |
0ec9dd |
{
|
|
Packit |
0ec9dd |
PangoLayout *layout = pango_cairo_create_layout (cr);
|
|
Packit |
0ec9dd |
pango_layout_set_text (layout, text, -1);
|
|
Packit |
0ec9dd |
pango_layout_set_width (layout, WIDTH * PANGO_SCALE);
|
|
Packit |
0ec9dd |
return layout;
|
|
Packit |
0ec9dd |
}
|
|
Packit |
0ec9dd |
|
|
Packit |
0ec9dd |
static void
|
|
Packit |
0ec9dd |
draw (cairo_t *cr, PangoLayout *layout, unsigned int i)
|
|
Packit |
0ec9dd |
{
|
|
Packit |
0ec9dd |
cairo_set_source_rgba (cr, 1, 1, 1, 1);
|
|
Packit |
0ec9dd |
cairo_paint (cr);
|
|
Packit |
0ec9dd |
cairo_set_source_rgba (cr, 1, 1, 1, 0);
|
|
Packit |
0ec9dd |
cairo_set_operator (cr, CAIRO_OPERATOR_SOURCE);
|
|
Packit |
0ec9dd |
|
|
Packit |
0ec9dd |
cairo_identity_matrix (cr);
|
|
Packit |
0ec9dd |
cairo_scale (cr, (100 + i) / 100., (100 + i) / 100.);
|
|
Packit |
0ec9dd |
pango_cairo_update_layout (cr, layout);
|
|
Packit |
0ec9dd |
|
|
Packit |
0ec9dd |
pango_cairo_show_layout (cr, layout);
|
|
Packit |
0ec9dd |
}
|
|
Packit |
0ec9dd |
|
|
Packit |
0ec9dd |
static gpointer
|
|
Packit |
0ec9dd |
thread_func (gpointer data)
|
|
Packit |
0ec9dd |
{
|
|
Packit |
0ec9dd |
cairo_surface_t *surface = data;
|
|
Packit |
0ec9dd |
PangoLayout *layout;
|
|
Packit |
0ec9dd |
int i;
|
|
Packit |
0ec9dd |
|
|
Packit |
0ec9dd |
cairo_t *cr = cairo_create (surface);
|
|
Packit |
0ec9dd |
|
|
Packit |
0ec9dd |
layout = create_layout (cr);
|
|
Packit |
0ec9dd |
|
|
Packit |
0ec9dd |
g_mutex_lock (&mutex);
|
|
Packit |
0ec9dd |
g_mutex_unlock (&mutex);
|
|
Packit |
0ec9dd |
|
|
Packit |
0ec9dd |
for (i = 0; i < num_iters; i++)
|
|
Packit |
0ec9dd |
draw (cr, layout, i);
|
|
Packit |
0ec9dd |
|
|
Packit |
0ec9dd |
g_object_unref (layout);
|
|
Packit |
0ec9dd |
|
|
Packit |
0ec9dd |
cairo_destroy (cr);
|
|
Packit |
0ec9dd |
|
|
Packit |
0ec9dd |
return 0;
|
|
Packit |
0ec9dd |
}
|
|
Packit |
0ec9dd |
|
|
Packit |
0ec9dd |
int
|
|
Packit |
0ec9dd |
main (int argc, char **argv)
|
|
Packit |
0ec9dd |
{
|
|
Packit |
0ec9dd |
int num_threads = 5;
|
|
Packit |
0ec9dd |
int i;
|
|
Packit |
0ec9dd |
GPtrArray *threads = g_ptr_array_new ();
|
|
Packit |
0ec9dd |
GPtrArray *surfaces = g_ptr_array_new ();
|
|
Packit |
0ec9dd |
|
|
Packit |
0ec9dd |
if (argc > 1)
|
|
Packit |
0ec9dd |
num_threads = atoi (argv[1]);
|
|
Packit |
0ec9dd |
if (argc > 2)
|
|
Packit |
0ec9dd |
num_iters = atoi (argv[2]);
|
|
Packit |
0ec9dd |
|
|
Packit |
0ec9dd |
#if !GLIB_CHECK_VERSION (2, 35, 3)
|
|
Packit |
0ec9dd |
g_type_init();
|
|
Packit |
0ec9dd |
#endif
|
|
Packit |
0ec9dd |
|
|
Packit |
0ec9dd |
g_mutex_lock (&mutex);
|
|
Packit |
0ec9dd |
|
|
Packit |
0ec9dd |
for (i = 0; i < num_threads; i++)
|
|
Packit |
0ec9dd |
{
|
|
Packit |
0ec9dd |
char buf[10];
|
|
Packit |
0ec9dd |
cairo_surface_t *surface = create_surface ();
|
|
Packit |
0ec9dd |
g_ptr_array_add (surfaces, surface);
|
|
Packit |
0ec9dd |
g_snprintf (buf, sizeof (buf), "%d", i);
|
|
Packit |
0ec9dd |
g_ptr_array_add (threads,
|
|
Packit |
0ec9dd |
g_thread_new (buf,
|
|
Packit |
0ec9dd |
thread_func,
|
|
Packit |
0ec9dd |
surface));
|
|
Packit |
0ec9dd |
}
|
|
Packit |
0ec9dd |
|
|
Packit |
0ec9dd |
/* Let them loose! */
|
|
Packit |
0ec9dd |
g_mutex_unlock (&mutex);
|
|
Packit |
0ec9dd |
|
|
Packit |
0ec9dd |
for (i = 0; i < num_threads; i++)
|
|
Packit |
0ec9dd |
g_thread_join (g_ptr_array_index (threads, i));
|
|
Packit |
0ec9dd |
|
|
Packit |
0ec9dd |
g_ptr_array_free (threads, TRUE);
|
|
Packit |
0ec9dd |
|
|
Packit |
0ec9dd |
/* Now, draw a reference image and check results. */
|
|
Packit |
0ec9dd |
{
|
|
Packit |
0ec9dd |
cairo_surface_t *ref_surface = create_surface ();
|
|
Packit |
0ec9dd |
cairo_t *cr = cairo_create (ref_surface);
|
|
Packit |
0ec9dd |
PangoLayout *layout = create_layout (cr);
|
|
Packit |
0ec9dd |
unsigned char *ref_data = cairo_image_surface_get_data (ref_surface);
|
|
Packit |
0ec9dd |
unsigned int len = WIDTH * HEIGHT;
|
|
Packit |
0ec9dd |
|
|
Packit |
0ec9dd |
draw (cr, layout, num_iters - 1);
|
|
Packit |
0ec9dd |
|
|
Packit |
0ec9dd |
g_object_unref (layout);
|
|
Packit |
0ec9dd |
cairo_destroy (cr);
|
|
Packit |
0ec9dd |
|
|
Packit |
0ec9dd |
/* cairo_surface_write_to_png (ref_surface, "test-pangocairo-threads-reference.png"); */
|
|
Packit |
0ec9dd |
|
|
Packit |
0ec9dd |
g_assert (WIDTH == cairo_format_stride_for_width (CAIRO_FORMAT_A8, WIDTH));
|
|
Packit |
0ec9dd |
|
|
Packit |
0ec9dd |
for (i = 0; i < num_threads; i++)
|
|
Packit |
0ec9dd |
{
|
|
Packit |
0ec9dd |
cairo_surface_t *surface = g_ptr_array_index (surfaces, i);
|
|
Packit |
0ec9dd |
unsigned char *data = cairo_image_surface_get_data (surface);
|
|
Packit |
0ec9dd |
if (memcmp (ref_data, data, len))
|
|
Packit |
0ec9dd |
{
|
|
Packit |
0ec9dd |
fprintf (stderr, "image for thread %d different from reference image.\n", i);
|
|
Packit |
0ec9dd |
cairo_surface_write_to_png (ref_surface, "test-pangocairo-threads-reference.png");
|
|
Packit |
0ec9dd |
cairo_surface_write_to_png (surface, "test-pangocairo-threads-failed.png");
|
|
Packit |
0ec9dd |
return 1;
|
|
Packit |
0ec9dd |
}
|
|
Packit |
0ec9dd |
cairo_surface_destroy (surface);
|
|
Packit |
0ec9dd |
}
|
|
Packit |
0ec9dd |
|
|
Packit |
0ec9dd |
cairo_surface_destroy (ref_surface);
|
|
Packit |
0ec9dd |
}
|
|
Packit |
0ec9dd |
|
|
Packit |
0ec9dd |
g_ptr_array_free (surfaces, TRUE);
|
|
Packit |
0ec9dd |
|
|
Packit |
0ec9dd |
pango_cairo_font_map_set_default (NULL);
|
|
Packit |
0ec9dd |
|
|
Packit |
0ec9dd |
return 0;
|
|
Packit |
0ec9dd |
}
|