test-pangocairo-threads.c 3.32 KB
Newer Older
1
#include <stdlib.h>
2
#include <string.h>
3 4 5
#include <pango/pango.h>
#include <pango/pangocairo.h>

6 7
#define WIDTH 100
#define HEIGHT 100
8
const char *text = "Hamburgerfonts\nวิวิวิวิวิวิ\nبهداد";
9

10
int num_iters = 50;
11

12 13
GMutex mutex;

14 15 16 17 18 19
static cairo_surface_t *
create_surface (void)
{
  return cairo_image_surface_create (CAIRO_FORMAT_A8, WIDTH, HEIGHT);
}

20 21 22 23 24
static PangoLayout *
create_layout (cairo_t *cr)
{
  PangoLayout *layout = pango_cairo_create_layout (cr);
  pango_layout_set_text (layout, text, -1);
25
  pango_layout_set_width (layout, WIDTH * PANGO_SCALE);
26 27 28 29
  return layout;
}

static void
30
draw (cairo_t *cr, PangoLayout *layout, unsigned int i)
31 32 33 34 35 36
{
  cairo_set_source_rgba (cr, 1, 1, 1, 1);
  cairo_paint (cr);
  cairo_set_source_rgba (cr, 1, 1, 1, 0);
  cairo_set_operator (cr, CAIRO_OPERATOR_SOURCE);

37
  cairo_identity_matrix (cr);
Behdad Esfahbod's avatar
Behdad Esfahbod committed
38
  cairo_scale (cr, (100 + i) / 100.,  (100 + i) / 100.);
39
  pango_cairo_update_layout (cr, layout);
40 41 42 43

  pango_cairo_show_layout (cr, layout);
}

44 45 46
static gpointer
thread_func (gpointer data)
{
47
  cairo_surface_t *surface = data;
48
  PangoLayout *layout;
49
  int i;
50 51

  cairo_t *cr = cairo_create (surface);
52

53 54
  layout = create_layout (cr);

55 56 57
  g_mutex_lock (&mutex);
  g_mutex_unlock (&mutex);

58
  for (i = 0; i < num_iters; i++)
59
    draw (cr, layout, i);
60

Behdad Esfahbod's avatar
Behdad Esfahbod committed
61 62 63 64
  g_object_unref (layout);

  cairo_destroy (cr);

65 66 67 68 69 70
  return 0;
}

int
main (int argc, char **argv)
{
71
  int num_threads = 5;
72
  int i;
73
  GPtrArray *threads = g_ptr_array_new ();
74
  GPtrArray *surfaces = g_ptr_array_new ();
75 76 77 78 79 80

  if (argc > 1)
    num_threads = atoi (argv[1]);
  if (argc > 2)
    num_iters = atoi (argv[2]);

81
  g_mutex_lock (&mutex);
82 83

  for (i = 0; i < num_threads; i++)
84
    {
85
      char buf[10];
86 87
      cairo_surface_t *surface = create_surface ();
      g_ptr_array_add (surfaces, surface);
Behdad Esfahbod's avatar
Behdad Esfahbod committed
88
      g_snprintf (buf, sizeof (buf), "%d", i);
89
      g_ptr_array_add (threads,
90
		       g_thread_new (buf,
91 92 93
				     thread_func,
				     surface));
    }
94

95 96 97
  /* Let them loose! */
  g_mutex_unlock (&mutex);

98 99
  for (i = 0; i < num_threads; i++)
    g_thread_join (g_ptr_array_index (threads, i));
100

Behdad Esfahbod's avatar
Behdad Esfahbod committed
101 102
  g_ptr_array_free (threads, TRUE);

103 104 105 106 107 108 109 110
  /* Now, draw a reference image and check results. */
  {
    cairo_surface_t *ref_surface = create_surface ();
    cairo_t *cr = cairo_create (ref_surface);
    PangoLayout *layout = create_layout (cr);
    unsigned char *ref_data = cairo_image_surface_get_data (ref_surface);
    unsigned int len = WIDTH * HEIGHT;

111
    draw (cr, layout, num_iters - 1);
112

Behdad Esfahbod's avatar
Behdad Esfahbod committed
113 114 115
    g_object_unref (layout);
    cairo_destroy (cr);

116 117 118 119 120 121 122 123 124 125 126 127 128 129 130
    /* cairo_surface_write_to_png (ref_surface, "test-pangocairo-threads-reference.png"); */

    g_assert (WIDTH == cairo_format_stride_for_width (CAIRO_FORMAT_A8, WIDTH));

    for (i = 0; i < num_threads; i++)
      {
	cairo_surface_t *surface = g_ptr_array_index (surfaces, i);
	unsigned char *data = cairo_image_surface_get_data (surface);
	if (memcmp (ref_data, data, len))
	  {
	    fprintf (stderr, "image for thread %d different from reference image.\n", i);
	    cairo_surface_write_to_png (ref_surface, "test-pangocairo-threads-reference.png");
	    cairo_surface_write_to_png (surface, "test-pangocairo-threads-failed.png");
	    return 1;
	  }
Behdad Esfahbod's avatar
Behdad Esfahbod committed
131
	cairo_surface_destroy (surface);
132
      }
Behdad Esfahbod's avatar
Behdad Esfahbod committed
133 134

    cairo_surface_destroy (ref_surface);
135 136
  }

Behdad Esfahbod's avatar
Behdad Esfahbod committed
137 138 139 140
  g_ptr_array_free (surfaces, TRUE);

  pango_cairo_font_map_set_default (NULL);

141 142
  return 0;
}