~noskcaj/ubuntu/trusty/gthumb/3.2.5

« back to all changes in this revision

Viewing changes to gthumb/cairo-utils.c

  • Committer: Package Import Robot
  • Author(s): David Paleino
  • Date: 2011-12-22 22:40:29 UTC
  • mfrom: (5.2.19 sid)
  • Revision ID: package-import@ubuntu.com-20111222224029-l58g65u1nfa6ojtg
Tags: 3:2.14.1-1
* New upstream version (Closes: #652692)
* Patches refreshed
* Bump build-dependencies requirements
* Fix FTBFS, added missing #include
* debian/watch fixed to point to new location (.xz tarballs)

Show diffs side-by-side

added added

removed removed

Lines of Context:
21
21
 
22
22
#include <config.h>
23
23
#include <math.h>
 
24
#include <string.h>
24
25
#include "cairo-utils.h"
25
26
 
26
27
 
 
28
const unsigned char cairo_channel[4] = { CAIRO_RED, CAIRO_GREEN, CAIRO_BLUE, CAIRO_ALPHA };
 
29
 
 
30
 
 
31
static cairo_user_data_key_t surface_metadata_key;
 
32
static cairo_user_data_key_t surface_pixels_key;
 
33
 
 
34
 
 
35
static void
 
36
surface_metadata_free (void *data)
 
37
{
 
38
        cairo_surface_metadata_t *metadata = data;
 
39
        g_free (metadata);
 
40
}
 
41
 
 
42
 
 
43
static void
 
44
surface_pixels_free (void *data)
 
45
{
 
46
        g_free (data);
 
47
}
 
48
 
 
49
 
 
50
inline int
 
51
_cairo_multiply_alpha (int color,
 
52
                       int alpha)
 
53
{
 
54
        int temp = (alpha * color) + 0x80;
 
55
        return ((temp + (temp >> 8)) >> 8);
 
56
}
 
57
 
 
58
 
27
59
void
28
60
_gdk_color_to_cairo_color (GdkColor      *g_color,
29
61
                           cairo_color_t *c_color)
47
79
 
48
80
 
49
81
void
 
82
_cairo_clear_surface (cairo_surface_t  **surface)
 
83
{
 
84
        cairo_surface_destroy (*surface);
 
85
        *surface = NULL;
 
86
}
 
87
 
 
88
 
 
89
cairo_surface_metadata_t *
 
90
_cairo_image_surface_get_metadata (cairo_surface_t *surface)
 
91
{
 
92
        cairo_surface_metadata_t *metadata;
 
93
 
 
94
        metadata = cairo_surface_get_user_data (surface, &surface_metadata_key);
 
95
        if (metadata == NULL) {
 
96
                metadata = g_new0 (cairo_surface_metadata_t, 1);
 
97
                cairo_surface_set_user_data (surface, &surface_metadata_key, metadata, surface_metadata_free);
 
98
        }
 
99
 
 
100
        return metadata;
 
101
}
 
102
 
 
103
 
 
104
gboolean
 
105
_cairo_image_surface_get_has_alpha (cairo_surface_t *surface)
 
106
{
 
107
        cairo_surface_metadata_t *metadata;
 
108
 
 
109
        if (surface == NULL)
 
110
                return FALSE;
 
111
 
 
112
        metadata = cairo_surface_get_user_data (surface, &surface_metadata_key);
 
113
        if (metadata != NULL)
 
114
                return metadata->has_alpha;
 
115
 
 
116
        return cairo_image_surface_get_format (surface) == CAIRO_FORMAT_ARGB32;
 
117
}
 
118
 
 
119
 
 
120
cairo_surface_t *
 
121
_cairo_image_surface_copy (cairo_surface_t *source)
 
122
{
 
123
        cairo_surface_t *result;
 
124
        cairo_format_t   format;
 
125
        int              width;
 
126
        int              height;
 
127
        int              stride;
 
128
        unsigned char   *pixels;
 
129
        cairo_status_t   status;
 
130
        int              source_stride;
 
131
        int              destination_stride;
 
132
        unsigned char   *p_source;
 
133
        unsigned char   *p_destination;
 
134
        int              row_size;
 
135
 
 
136
        if (source == NULL)
 
137
                return NULL;
 
138
 
 
139
        format = cairo_image_surface_get_format (source);
 
140
        width = cairo_image_surface_get_width (source);
 
141
        height = cairo_image_surface_get_height (source);
 
142
        stride = cairo_format_stride_for_width (format, width);
 
143
        pixels = g_try_malloc (stride * height);
 
144
        if (pixels == NULL)
 
145
                return NULL;
 
146
 
 
147
        result = cairo_image_surface_create_for_data (pixels, format, width, height, stride);
 
148
        status = cairo_surface_status (result);
 
149
        if (status != CAIRO_STATUS_SUCCESS) {
 
150
                g_warning ("_cairo_image_surface_copy: could not create the surface: %s", cairo_status_to_string (status));
 
151
                cairo_surface_destroy (result);
 
152
                return NULL;
 
153
        }
 
154
 
 
155
        status = cairo_surface_set_user_data (result, &surface_pixels_key, pixels, surface_pixels_free);
 
156
        if (status != CAIRO_STATUS_SUCCESS) {
 
157
                g_warning ("_cairo_image_surface_copy: could not set the user data: %s", cairo_status_to_string (status));
 
158
                cairo_surface_destroy (result);
 
159
                return NULL;
 
160
        }
 
161
 
 
162
        cairo_surface_flush (result);
 
163
 
 
164
        source_stride = cairo_image_surface_get_stride (source);
 
165
        destination_stride = cairo_image_surface_get_stride (result);
 
166
        p_source = cairo_image_surface_get_data (source);
 
167
        p_destination = cairo_image_surface_get_data (result);
 
168
        row_size = width * 4;
 
169
        while (height-- > 0) {
 
170
                memcpy (p_destination, p_source, row_size);
 
171
 
 
172
                p_source += source_stride;
 
173
                p_destination += destination_stride;
 
174
        }
 
175
 
 
176
        cairo_surface_mark_dirty (result);
 
177
 
 
178
        return result;
 
179
}
 
180
 
 
181
 
 
182
cairo_surface_t *
 
183
_cairo_image_surface_copy_subsurface (cairo_surface_t *source,
 
184
                                      int              src_x,
 
185
                                      int              src_y,
 
186
                                      int              width,
 
187
                                      int              height)
 
188
{
 
189
        cairo_surface_t *destination;
 
190
        cairo_status_t   status;
 
191
        int              source_stride;
 
192
        int              destination_stride;
 
193
        unsigned char   *p_source;
 
194
        unsigned char   *p_destination;
 
195
        int              row_size;
 
196
 
 
197
        g_return_val_if_fail (source != NULL, NULL);
 
198
        g_return_val_if_fail (src_x + width <= cairo_image_surface_get_width (source), NULL);
 
199
        g_return_val_if_fail (src_y + height <= cairo_image_surface_get_height (source), NULL);
 
200
 
 
201
        destination = cairo_image_surface_create (cairo_image_surface_get_format (source), width, height);
 
202
        status = cairo_surface_status (destination);
 
203
        if (status != CAIRO_STATUS_SUCCESS) {
 
204
                g_warning ("_cairo_image_surface_copy_subsurface: could not create the surface: %s", cairo_status_to_string (status));
 
205
                cairo_surface_destroy (destination);
 
206
                return NULL;
 
207
        }
 
208
 
 
209
        cairo_surface_flush (destination);
 
210
 
 
211
        source_stride = cairo_image_surface_get_stride (source);
 
212
        destination_stride = cairo_image_surface_get_stride (destination);
 
213
        p_source = cairo_image_surface_get_data (source) + (src_y * source_stride) + (src_x * 4);
 
214
        p_destination = cairo_image_surface_get_data (destination);
 
215
        row_size = width * 4;
 
216
        while (height-- > 0) {
 
217
                memcpy (p_destination, p_source, row_size);
 
218
 
 
219
                p_source += source_stride;
 
220
                p_destination += destination_stride;
 
221
        }
 
222
 
 
223
        cairo_surface_mark_dirty (destination);
 
224
 
 
225
        return destination;
 
226
}
 
227
 
 
228
 
 
229
cairo_surface_t *
 
230
_cairo_image_surface_create_from_pixbuf (GdkPixbuf *pixbuf)
 
231
{
 
232
        cairo_surface_t          *surface;
 
233
        cairo_surface_metadata_t *metadata;
 
234
        int                      width;
 
235
        int                      height;
 
236
        int                      p_stride;
 
237
        int                      p_n_channels;
 
238
        guchar                  *p_pixels;
 
239
        int                      s_stride;
 
240
        unsigned char           *s_pixels;
 
241
        int                      h, w;
 
242
        guint32                  pixel;
 
243
        guchar                   r, g, b, a;
 
244
 
 
245
        if (pixbuf == NULL)
 
246
                return NULL;
 
247
 
 
248
        g_object_get (G_OBJECT (pixbuf),
 
249
                      "width", &width,
 
250
                      "height", &height,
 
251
                      "rowstride", &p_stride,
 
252
                      "n-channels", &p_n_channels,
 
253
                      "pixels", &p_pixels,
 
254
                      NULL );
 
255
        surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, width, height);
 
256
        cairo_surface_flush (surface);
 
257
        s_stride = cairo_image_surface_get_stride (surface);
 
258
        s_pixels = cairo_image_surface_get_data (surface);
 
259
 
 
260
        metadata = _cairo_image_surface_get_metadata (surface);
 
261
        metadata->has_alpha = (p_n_channels == 4);
 
262
 
 
263
        if (p_n_channels == 4) {
 
264
                guchar *s_iter;
 
265
                guchar *p_iter;
 
266
 
 
267
                for (h = 0; h < height; h++) {
 
268
                        s_iter = s_pixels;
 
269
                        p_iter = p_pixels;
 
270
 
 
271
                        for (w = 0; w < width; w++) {
 
272
                                a = p_iter[3];
 
273
                                if (a == 0xff) {
 
274
                                        pixel = CAIRO_RGBA_TO_UINT32 (p_iter[0], p_iter[1], p_iter[2], 0xff);
 
275
                                }
 
276
                                else if (a == 0) {
 
277
                                        pixel = 0;
 
278
                                }
 
279
                                else {
 
280
                                        r = _cairo_multiply_alpha (p_iter[0], a);
 
281
                                        g = _cairo_multiply_alpha (p_iter[1], a);
 
282
                                        b = _cairo_multiply_alpha (p_iter[2], a);
 
283
                                        pixel = CAIRO_RGBA_TO_UINT32 (r, g, b, a);
 
284
                                }
 
285
                                memcpy (s_iter, &pixel, sizeof (guint32));
 
286
 
 
287
                                s_iter += 4;
 
288
                                p_iter += p_n_channels;
 
289
                        }
 
290
 
 
291
                        s_pixels += s_stride;
 
292
                        p_pixels += p_stride;
 
293
                }
 
294
        }
 
295
        else {
 
296
                guchar *s_iter;
 
297
                guchar *p_iter;
 
298
 
 
299
                for (h = 0; h < height; h++) {
 
300
                        s_iter = s_pixels;
 
301
                        p_iter = p_pixels;
 
302
 
 
303
                        for (w = 0; w < width; w++) {
 
304
                                pixel = CAIRO_RGBA_TO_UINT32 (p_iter[0], p_iter[1], p_iter[2], 0xff);
 
305
                                memcpy (s_iter, &pixel, sizeof (guint32));
 
306
 
 
307
                                s_iter += 4;
 
308
                                p_iter += p_n_channels;
 
309
                        }
 
310
 
 
311
                        s_pixels += s_stride;
 
312
                        p_pixels += p_stride;
 
313
                }
 
314
        }
 
315
 
 
316
        cairo_surface_mark_dirty (surface);
 
317
 
 
318
        return surface;
 
319
}
 
320
 
 
321
 
 
322
cairo_surface_t *
 
323
_cairo_image_surface_create_compatible (cairo_surface_t *surface)
 
324
{
 
325
        return cairo_image_surface_create (cairo_image_surface_get_format (surface),
 
326
                                           cairo_image_surface_get_width (surface),
 
327
                                           cairo_image_surface_get_height (surface));
 
328
}
 
329
 
 
330
 
 
331
cairo_surface_t *
 
332
_cairo_image_surface_scale_to (cairo_surface_t *surface,
 
333
                               int              width,
 
334
                               int              height,
 
335
                               cairo_filter_t   filter)
 
336
{
 
337
        cairo_surface_t *scaled;
 
338
        cairo_t         *cr;
 
339
 
 
340
        scaled = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, width, height);
 
341
        cr = cairo_create (scaled);
 
342
        cairo_scale (cr, (double) width / cairo_image_surface_get_width (surface), (double) height / cairo_image_surface_get_height (surface));
 
343
        cairo_set_source_surface (cr, surface, 0, 0);
 
344
        cairo_pattern_set_filter (cairo_get_source (cr), filter);
 
345
        cairo_rectangle (cr, 0, 0, cairo_image_surface_get_width (surface), cairo_image_surface_get_height (surface));
 
346
        cairo_fill (cr);
 
347
 
 
348
        cairo_destroy (cr);
 
349
 
 
350
        return scaled;
 
351
}
 
352
 
 
353
 
 
354
void
 
355
_cairo_image_surface_transform_get_steps (cairo_format_t  format,
 
356
                                          int             width,
 
357
                                          int             height,
 
358
                                          GthTransform    transform,
 
359
                                          int            *destination_width_p,
 
360
                                          int            *destination_height_p,
 
361
                                          int            *line_start_p,
 
362
                                          int            *line_step_p,
 
363
                                          int            *pixel_step_p)
 
364
{
 
365
        int destination_stride;
 
366
        int destination_width = 0;
 
367
        int destination_height = 0;
 
368
        int line_start = 0;
 
369
        int line_step = 0;
 
370
        int pixel_step = 0;
 
371
 
 
372
        switch (transform) {
 
373
        case GTH_TRANSFORM_NONE:
 
374
        default:
 
375
                destination_width = width;
 
376
                destination_height = height;
 
377
                destination_stride = cairo_format_stride_for_width (format, destination_width);
 
378
                line_start = 0;
 
379
                line_step = destination_stride;
 
380
                pixel_step = 4;
 
381
                break;
 
382
 
 
383
        case GTH_TRANSFORM_FLIP_H:
 
384
                destination_width = width;
 
385
                destination_height = height;
 
386
                destination_stride = cairo_format_stride_for_width (format, destination_width);
 
387
                line_start = (destination_width - 1) * 4;
 
388
                line_step = destination_stride;
 
389
                pixel_step = -4;
 
390
                break;
 
391
 
 
392
        case GTH_TRANSFORM_ROTATE_180:
 
393
                destination_width = width;
 
394
                destination_height = height;
 
395
                destination_stride = cairo_format_stride_for_width (format, destination_width);
 
396
                line_start = ((destination_height - 1) * destination_stride) + ((destination_width - 1) * 4);
 
397
                line_step = -destination_stride;
 
398
                pixel_step = -4;
 
399
                break;
 
400
 
 
401
        case GTH_TRANSFORM_FLIP_V:
 
402
                destination_width = width;
 
403
                destination_height = height;
 
404
                destination_stride = cairo_format_stride_for_width (format, destination_width);
 
405
                line_start = (destination_height - 1) * destination_stride;
 
406
                line_step = -destination_stride;
 
407
                pixel_step = 4;
 
408
                break;
 
409
 
 
410
        case GTH_TRANSFORM_TRANSPOSE:
 
411
                destination_width = height;
 
412
                destination_height = width;
 
413
                destination_stride = cairo_format_stride_for_width (format, destination_width);
 
414
                line_start = 0;
 
415
                line_step = 4;
 
416
                pixel_step = destination_stride;
 
417
                break;
 
418
 
 
419
        case GTH_TRANSFORM_ROTATE_90:
 
420
                destination_width = height;
 
421
                destination_height = width;
 
422
                destination_stride = cairo_format_stride_for_width (format, destination_width);
 
423
                line_start = (destination_width - 1) * 4;
 
424
                line_step = -4;
 
425
                pixel_step = destination_stride;
 
426
                break;
 
427
 
 
428
        case GTH_TRANSFORM_TRANSVERSE:
 
429
                destination_width = height;
 
430
                destination_height = width;
 
431
                destination_stride = cairo_format_stride_for_width (format, destination_width);
 
432
                line_start = ((destination_height - 1) * destination_stride) + ((destination_width - 1) * 4);
 
433
                line_step = -4;
 
434
                pixel_step = -destination_stride;
 
435
                break;
 
436
 
 
437
        case GTH_TRANSFORM_ROTATE_270:
 
438
                destination_width = height;
 
439
                destination_height = width;
 
440
                destination_stride = cairo_format_stride_for_width (format, destination_width);
 
441
                line_start = (destination_height - 1) * destination_stride;
 
442
                line_step = 4;
 
443
                pixel_step = -destination_stride;
 
444
                break;
 
445
        }
 
446
 
 
447
        if (destination_width_p != NULL)
 
448
                *destination_width_p = destination_width;
 
449
        if (destination_height_p != NULL)
 
450
                *destination_height_p = destination_height;
 
451
        if (line_start_p != NULL)
 
452
                *line_start_p = line_start;
 
453
        if (line_step_p != NULL)
 
454
                *line_step_p = line_step;
 
455
        if (pixel_step_p != NULL)
 
456
                *pixel_step_p = pixel_step;
 
457
}
 
458
 
 
459
 
 
460
cairo_surface_t *
 
461
_cairo_image_surface_transform (cairo_surface_t *source,
 
462
                                GthTransform     transform)
 
463
{
 
464
        cairo_surface_t *destination = NULL;
 
465
        cairo_format_t   format;
 
466
        int              width;
 
467
        int              height;
 
468
        int              source_stride;
 
469
        int              destination_width;
 
470
        int              destination_height;
 
471
        int              line_start;
 
472
        int              line_step;
 
473
        int              pixel_step;
 
474
        unsigned char   *p_source_line;
 
475
        unsigned char   *p_destination_line;
 
476
        unsigned char   *p_source;
 
477
        unsigned char   *p_destination;
 
478
        int              x;
 
479
 
 
480
        if (source == NULL)
 
481
                return NULL;
 
482
 
 
483
        format = cairo_image_surface_get_format (source);
 
484
        width = cairo_image_surface_get_width (source);
 
485
        height = cairo_image_surface_get_height (source);
 
486
        source_stride = cairo_image_surface_get_stride (source);
 
487
 
 
488
        _cairo_image_surface_transform_get_steps (format,
 
489
                                                  width,
 
490
                                                  height,
 
491
                                                  transform,
 
492
                                                  &destination_width,
 
493
                                                  &destination_height,
 
494
                                                  &line_start,
 
495
                                                  &line_step,
 
496
                                                  &pixel_step);
 
497
 
 
498
        destination = cairo_image_surface_create (format, destination_width, destination_height);
 
499
        cairo_surface_flush (destination);
 
500
        p_source_line = cairo_image_surface_get_data (source);
 
501
        p_destination_line = cairo_image_surface_get_data (destination) + line_start;
 
502
        while (height-- > 0) {
 
503
                p_source = p_source_line;
 
504
                p_destination = p_destination_line;
 
505
                for (x = 0; x < width; x++) {
 
506
                        memcpy (p_destination, p_source, 4);
 
507
                        p_source += 4;
 
508
                        p_destination += pixel_step;
 
509
                }
 
510
                p_source_line += source_stride;
 
511
                p_destination_line += line_step;
 
512
        }
 
513
 
 
514
        cairo_surface_mark_dirty (destination);
 
515
 
 
516
        return destination;
 
517
}
 
518
 
 
519
 
 
520
void
50
521
_cairo_paint_full_gradient (cairo_surface_t *surface,
51
522
                            GdkColor        *h_color1,
52
523
                            GdkColor        *h_color2,
69
540
        if (cairo_surface_status (surface) != CAIRO_STATUS_SUCCESS)
70
541
                return;
71
542
 
 
543
        cairo_surface_flush (surface);
 
544
 
72
545
        _gdk_color_to_cairo_color_255 (h_color1, &hcolor1);
73
546
        _gdk_color_to_cairo_color_255 (h_color2, &hcolor2);
74
547
        _gdk_color_to_cairo_color_255 (v_color1, &vcolor1);
85
558
                x = (double) (height - h) / height;
86
559
 
87
560
                for (w = 0; w < width; w++) {
88
 
                        y = (double) (width - w) / width;
89
 
 
 
561
                        y        = (double) (width - w) / width;
90
562
                        x_y      = x * y;
91
563
                        x_1_y    = x * (1.0 - y);
92
564
                        y_1_x    = y * (1.0 - x);
96
568
                        green = hcolor1.g * x_y + hcolor2.g * x_1_y + vcolor1.g * y_1_x + vcolor2.g * _1_x_1_y;
97
569
                        blue  = hcolor1.b * x_y + hcolor2.b * x_1_y + vcolor1.b * y_1_x + vcolor2.b * _1_x_1_y;
98
570
 
99
 
#if G_BYTE_ORDER == G_LITTLE_ENDIAN
100
 
                        /* BGRA */
101
 
                        s_iter[0] = blue;
102
 
                        s_iter[1] = green;
103
 
                        s_iter[2] = red;
104
 
                        s_iter[3] = 0xff;
105
 
#elif G_BYTE_ORDER == G_BIG_ENDIAN
106
 
                        /* ARGB */
107
 
                        s_iter[0] = 0xff;
108
 
                        s_iter[1] = red;
109
 
                        s_iter[2] = green;
110
 
                        s_iter[3] = blue;
111
 
#else /* PDP endianness */
112
 
                        /* RABG */
113
 
                        s_iter[0] = red;
114
 
                        s_iter[1] = 0xff;
115
 
                        s_iter[2] = blue;
116
 
                        s_iter[3] = green;
117
 
#endif
 
571
                        CAIRO_SET_RGB (s_iter, red, green, blue);
118
572
 
119
573
                        s_iter += 4;
120
574
                }
121
575
 
122
576
                s_pixels += s_stride;
123
577
        }
 
578
 
 
579
        cairo_surface_mark_dirty (surface);
124
580
}
125
581
 
126
582
 
132
588
                         double   h,
133
589
                         double   r)
134
590
{
135
 
        cairo_move_to (cr, x, y + r);
136
 
        if (r > 0)
137
 
                cairo_arc (cr, x + r, y + r, r, 1.0 * M_PI, 1.5 * M_PI);
138
 
        cairo_rel_line_to (cr, w - (r * 2), 0);
139
 
        if (r > 0)
140
 
                cairo_arc (cr, x + w - r, y + r, r, 1.5 * M_PI, 2.0 * M_PI);
141
 
        cairo_rel_line_to (cr, 0, h - (r * 2));
142
 
        if (r > 0)
143
 
                cairo_arc (cr, x + w - r, y + h - r, r, 0.0 * M_PI, 0.5 * M_PI);
144
 
        cairo_rel_line_to (cr, - (w - (r * 2)), 0);
145
 
        if (r > 0)
146
 
                cairo_arc (cr, x + r, y + h - r, r, 0.5 * M_PI, 1.0 * M_PI);
147
 
        cairo_rel_line_to (cr, 0, - (h - (r * 2)));
 
591
        if (r == 0) {
 
592
                cairo_rectangle (cr, x, y, w, h);
 
593
        }
 
594
        else if (r == 1) {
 
595
                cairo_move_to (cr, x + 1, y);
 
596
                cairo_rel_line_to (cr, w - 2, 0);
 
597
                cairo_rel_line_to (cr, 1, 1);
 
598
                cairo_rel_line_to (cr, 0, h - 2);
 
599
                cairo_rel_line_to (cr, -1, 1);
 
600
                cairo_rel_line_to (cr, - (w - 2), 0);
 
601
                cairo_rel_line_to (cr, -1, -1);
 
602
                cairo_rel_line_to (cr, 0, - (h - 2));
 
603
                cairo_rel_line_to (cr, 1, -1);
 
604
        }
 
605
        else {
 
606
                cairo_move_to (cr, x, y + r);
 
607
                if (r > 0)
 
608
                        cairo_arc (cr, x + r, y + r, r, 1.0 * M_PI, 1.5 * M_PI);
 
609
                cairo_rel_line_to (cr, w - (r * 2), 0);
 
610
                if (r > 0)
 
611
                        cairo_arc (cr, x + w - r, y + r, r, 1.5 * M_PI, 2.0 * M_PI);
 
612
                cairo_rel_line_to (cr, 0, h - (r * 2));
 
613
                if (r > 0)
 
614
                        cairo_arc (cr, x + w - r, y + h - r, r, 0.0 * M_PI, 0.5 * M_PI);
 
615
                cairo_rel_line_to (cr, - (w - (r * 2)), 0);
 
616
                if (r > 0)
 
617
                        cairo_arc (cr, x + r, y + h - r, r, 0.5 * M_PI, 1.0 * M_PI);
 
618
                cairo_rel_line_to (cr, 0, - (h - (r * 2)));
 
619
        }
148
620
}
149
621
 
150
622
 
300
772
 
301
773
        cairo_restore (cr);
302
774
}
 
775
 
 
776
 
 
777
#define GOLDEN_RATIO        1.6180339887
 
778
#define GOLDER_RATIO_FACTOR (GOLDEN_RATIO / (1.0 + 2.0 * GOLDEN_RATIO))
 
779
#define GRID_STEP_1         10
 
780
#define GRID_STEP_2         (GRID_STEP_1 * 5)
 
781
#define GRID_STEP_3         (GRID_STEP_2 * 2)
 
782
 
 
783
 
 
784
void
 
785
_cairo_paint_grid (cairo_t      *cr,
 
786
                   GdkRectangle *rectangle,
 
787
                   GthGridType   grid_type)
 
788
{
 
789
        double ux, uy;
 
790
 
 
791
        cairo_save (cr);
 
792
 
 
793
        ux = uy = 1.0;
 
794
        cairo_device_to_user_distance (cr, &ux, &uy);
 
795
        cairo_set_line_width (cr, MAX (ux, uy));
 
796
 
 
797
        cairo_rectangle (cr, rectangle->x - ux + 0.5, rectangle->y - uy + 0.5, rectangle->width + (ux * 2), rectangle->height + (uy * 2));
 
798
        cairo_clip (cr);
 
799
 
 
800
#if CAIRO_VERSION >= CAIRO_VERSION_ENCODE(1, 9, 2)
 
801
        /* cairo_set_operator (cr, CAIRO_OPERATOR_DIFFERENCE); */
 
802
#endif
 
803
 
 
804
        cairo_rectangle (cr, rectangle->x + 0.5, rectangle->y + 0.5, rectangle->width - 0.5, rectangle->height - 0.5);
 
805
        cairo_set_source_rgb (cr, 1.0, 1.0, 1.0);
 
806
        cairo_stroke (cr);
 
807
 
 
808
        if (grid_type == GTH_GRID_NONE) {
 
809
                cairo_restore (cr);
 
810
                return;
 
811
        }
 
812
 
 
813
        cairo_set_operator (cr, CAIRO_OPERATOR_OVER);
 
814
 
 
815
        if (grid_type == GTH_GRID_THIRDS) {
 
816
                int i;
 
817
 
 
818
                cairo_set_source_rgba (cr, 1.0, 1.0, 1.0, 0.60);
 
819
                for (i = 1; i < 3; i++) {
 
820
                        cairo_move_to (cr, rectangle->x + rectangle->width * i / 3 + 0.5, rectangle->y + 1.5);
 
821
                        cairo_line_to (cr, rectangle->x + rectangle->width * i / 3 + 0.5, rectangle->y + rectangle->height - 0.5);
 
822
 
 
823
                        cairo_move_to (cr, rectangle->x + 1.5, rectangle->y + rectangle->height * i / 3 + 0.5);
 
824
                        cairo_line_to (cr, rectangle->x + rectangle->width - 0.5, rectangle->y + rectangle->height * i / 3 + 0.5);
 
825
                }
 
826
                cairo_stroke (cr);
 
827
 
 
828
                cairo_set_source_rgba (cr, 1.0, 1.0, 1.0, 0.10);
 
829
                for (i = 1; i < 9; i++) {
 
830
 
 
831
                        if (i % 3 == 0)
 
832
                                continue;
 
833
 
 
834
                        cairo_move_to (cr, rectangle->x + rectangle->width * i / 9 + 0.5, rectangle->y + 1.5);
 
835
                        cairo_line_to (cr, rectangle->x + rectangle->width * i / 9 + 0.5, rectangle->y + rectangle->height - 0.5);
 
836
 
 
837
                        cairo_move_to (cr, rectangle->x + 1.5, rectangle->y + rectangle->height * i / 9 + 0.5);
 
838
                        cairo_line_to (cr, rectangle->x + rectangle->width - 0.5, rectangle->y + rectangle->height * i / 9 + 0.5);
 
839
                }
 
840
                cairo_stroke (cr);
 
841
        }
 
842
        else if (grid_type == GTH_GRID_GOLDEN) {
 
843
                cairo_set_source_rgba (cr, 1.0, 1.0, 1.0, 0.60);
 
844
 
 
845
                int grid_x0, grid_x1, grid_x2, grid_x3;
 
846
                int grid_y0, grid_y1, grid_y2, grid_y3;
 
847
                int x_delta, y_delta;
 
848
 
 
849
                grid_x0 = rectangle->x;
 
850
                grid_x3 = rectangle->x + rectangle->width;
 
851
 
 
852
                grid_y0 = rectangle->y;
 
853
                grid_y3 = rectangle->y + rectangle->height;
 
854
 
 
855
                x_delta = rectangle->width * GOLDER_RATIO_FACTOR;
 
856
                y_delta = rectangle->height * GOLDER_RATIO_FACTOR;
 
857
 
 
858
                grid_x1 = grid_x0 + x_delta;
 
859
                grid_x2 = grid_x3 - x_delta;
 
860
                grid_y1 = grid_y0 + y_delta;
 
861
                grid_y2 = grid_y3 - y_delta;
 
862
 
 
863
                cairo_move_to (cr, grid_x1 + 0.5, grid_y0 + 0.5);
 
864
                cairo_line_to (cr, grid_x1 + 0.5, grid_y3 + 0.5);
 
865
 
 
866
                if (x_delta < rectangle->width / 2) {
 
867
                        cairo_move_to (cr, grid_x2 + 0.5, grid_y0 + 0.5);
 
868
                        cairo_line_to (cr, grid_x2 + 0.5, grid_y3 + 0.5);
 
869
                }
 
870
 
 
871
                cairo_move_to (cr, grid_x0 + 0.5, grid_y1 + 0.5);
 
872
                cairo_line_to (cr, grid_x3 + 0.5, grid_y1 + 0.5);
 
873
 
 
874
                if (y_delta < rectangle->height / 2) {
 
875
                        cairo_move_to (cr, grid_x0 + 0.5, grid_y2 + 0.5);
 
876
                        cairo_line_to (cr, grid_x3 + 0.5, grid_y2 + 0.5);
 
877
                }
 
878
 
 
879
                cairo_stroke (cr);
 
880
        }
 
881
        else if (grid_type == GTH_GRID_CENTER) {
 
882
                int i;
 
883
 
 
884
                cairo_set_source_rgba (cr, 1.0, 1.0, 1.0, 0.60);
 
885
                cairo_move_to (cr, rectangle->x + rectangle->width / 2 + 0.5, rectangle->y + 1.5);
 
886
                cairo_line_to (cr, rectangle->x + rectangle->width / 2 + 0.5, rectangle->y + rectangle->height - 0.5);
 
887
                cairo_move_to (cr, rectangle->x + 1.5, rectangle->y + rectangle->height / 2 + 0.5);
 
888
                cairo_line_to (cr, rectangle->x + rectangle->width - 0.5, rectangle->y + rectangle->height / 2 + 0.5);
 
889
                cairo_stroke (cr);
 
890
 
 
891
                cairo_set_source_rgba (cr, 1.0, 1.0, 1.0, 0.10);
 
892
                for (i = 1; i < 4; i++) {
 
893
 
 
894
                        if (i == 2)
 
895
                                continue;
 
896
 
 
897
                        cairo_move_to (cr, rectangle->x + rectangle->width * i / 4 + 0.5, rectangle->y + 1.5);
 
898
                        cairo_line_to (cr, rectangle->x + rectangle->width * i / 4 + 0.5, rectangle->y + rectangle->height - 0.5);
 
899
                        cairo_move_to (cr, rectangle->x + 1.5, rectangle->y + rectangle->height * i / 4 + 0.5);
 
900
                        cairo_line_to (cr, rectangle->x + rectangle->width - 0.5, rectangle->y + rectangle->height * i / 4 + 0.5);
 
901
                }
 
902
                cairo_stroke (cr);
 
903
        }
 
904
        else if (grid_type == GTH_GRID_UNIFORM) {
 
905
 
 
906
                int x;
 
907
                int y;
 
908
 
 
909
                cairo_set_source_rgba (cr, 1.0, 1.0, 1.0, 0.40);
 
910
                for (x = GRID_STEP_3; x < rectangle->width; x += GRID_STEP_3) {
 
911
                        cairo_move_to (cr, rectangle->x + x + 0.5, rectangle->y + 1.5);
 
912
                        cairo_line_to (cr, rectangle->x + x + 0.5, rectangle->y + rectangle->height - 0.5);
 
913
                }
 
914
                for (y = GRID_STEP_3; y < rectangle->height; y += GRID_STEP_3) {
 
915
                        cairo_move_to (cr, rectangle->x + 1.5, rectangle->y + y + 0.5);
 
916
                        cairo_line_to (cr, rectangle->x + rectangle->width - 0.5, rectangle->y + y + 0.5);
 
917
                }
 
918
                cairo_stroke (cr);
 
919
 
 
920
                cairo_set_source_rgba (cr, 1.0, 1.0, 1.0, 0.20);
 
921
                for (x = GRID_STEP_2; x < rectangle->width; x += GRID_STEP_2) {
 
922
                        if (x % GRID_STEP_3 == 0)
 
923
                                continue;
 
924
                        cairo_move_to (cr, rectangle->x + x + 0.5, rectangle->y + 1.5);
 
925
                        cairo_line_to (cr, rectangle->x + x + 0.5, rectangle->y + rectangle->height - 0.5);
 
926
                }
 
927
                for (y = GRID_STEP_2; y < rectangle->height; y += GRID_STEP_2) {
 
928
                        if (y % GRID_STEP_3 == 0)
 
929
                                continue;
 
930
                        cairo_move_to (cr, rectangle->x + 1.5, rectangle->y + y + 0.5);
 
931
                        cairo_line_to (cr, rectangle->x + rectangle->width - 0.5, rectangle->y + y + 0.5);
 
932
                }
 
933
                cairo_stroke (cr);
 
934
 
 
935
                cairo_set_source_rgba (cr, 1.0, 1.0, 1.0, 0.10);
 
936
                for (x = GRID_STEP_1; x < rectangle->width; x += GRID_STEP_1) {
 
937
                        if (x % GRID_STEP_2 == 0)
 
938
                                continue;
 
939
                        cairo_move_to (cr, rectangle->x + x + 0.5, rectangle->y + 1.5);
 
940
                        cairo_line_to (cr, rectangle->x + x + 0.5, rectangle->y + rectangle->height - 0.5);
 
941
                }
 
942
                for (y = GRID_STEP_1; y < rectangle->height; y += GRID_STEP_1) {
 
943
                        if (y % GRID_STEP_2 == 0)
 
944
                                continue;
 
945
                        cairo_move_to (cr, rectangle->x + 1.5, rectangle->y + y + 0.5);
 
946
                        cairo_line_to (cr, rectangle->x + rectangle->width - 0.5, rectangle->y + y + 0.5);
 
947
                }
 
948
                cairo_stroke (cr);
 
949
        }
 
950
 
 
951
        cairo_restore (cr);
 
952
}