Rev 1892 | Go to most recent revision | Show entire file | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed
Rev 1892 | Rev 3959 | ||
---|---|---|---|
Line 36... | Line 36... | ||
36 | * Carl D. Worth |
36 | * Carl D. Worth |
37 | */ |
37 | */ |
Line 38... | Line 38... | ||
38 | 38 | ||
Line 39... | Line 39... | ||
39 | #include "cairoint.h" |
39 | #include "cairoint.h" |
- | 40 | ||
40 | 41 | #include "cairo-array-private.h" |
|
- | 42 | #include "cairo-clip-inline.h" |
|
41 | #include "cairo-surface-fallback-private.h" |
43 | #include "cairo-clip-private.h" |
42 | #include "cairo-clip-private.h" |
44 | #include "cairo-damage-private.h" |
- | 45 | #include "cairo-device-private.h" |
|
- | 46 | #include "cairo-error-private.h" |
|
43 | #include "cairo-device-private.h" |
47 | #include "cairo-list-inline.h" |
44 | #include "cairo-error-private.h" |
48 | #include "cairo-image-surface-inline.h" |
- | 49 | #include "cairo-recording-surface-private.h" |
|
45 | #include "cairo-recording-surface-private.h" |
50 | #include "cairo-region-private.h" |
Line 46... | Line 51... | ||
46 | #include "cairo-region-private.h" |
51 | #include "cairo-surface-inline.h" |
47 | #include "cairo-tee-surface-private.h" |
52 | #include "cairo-tee-surface-private.h" |
48 | 53 | ||
Line 56... | Line 61... | ||
56 | * targets that cairo can render to. The actual drawings are |
61 | * targets that cairo can render to. The actual drawings are |
57 | * performed using a cairo |
62 | * performed using a cairo |
58 | * |
63 | * |
59 | * A cairo surface is created by using |
64 | * A cairo surface is created by using |
60 | * constructors, typically of the form |
65 | * constructors, typically of the form |
61 | * cairo_ |
66 | * |
62 | * |
67 | * |
63 | * Most surface types allow accessing the surface without using Cairo |
68 | * Most surface types allow accessing the surface without using Cairo |
64 | * functions. If you do this, keep in mind that it is mandatory that you call |
69 | * functions. If you do this, keep in mind that it is mandatory that you call |
65 | * cairo_surface_flush() before reading from or writing to the surface and that |
70 | * cairo_surface_flush() before reading from or writing to the surface and that |
66 | * you must use cairo_surface_mark_dirty() after modifying it. |
71 | * you must use cairo_surface_mark_dirty() after modifying it. |
Line 89... | Line 94... | ||
89 | * |
94 | * |
90 | * |
95 | * |
91 | * Note that for other surface types it might be necessary to acquire the |
96 | * Note that for other surface types it might be necessary to acquire the |
92 | * surface's device first. See cairo_device_acquire() for a discussion of |
97 | * surface's device first. See cairo_device_acquire() for a discussion of |
93 | * devices. |
98 | * devices. |
94 | */ |
99 | **/ |
Line 95... | Line 100... | ||
95 | 100 | ||
96 | #define DEFINE_NIL_SURFACE(status, name) \ |
101 | #define DEFINE_NIL_SURFACE(status, name) \ |
97 | const cairo_surface_t name = { \ |
102 | const cairo_surface_t name = { \ |
98 | NULL, /* backend */ \ |
103 | NULL, /* backend */ \ |
99 | NULL, /* device */ \ |
104 | NULL, /* device */ \ |
100 | CAIRO_SURFACE_TYPE_IMAGE, /* type */ \ |
105 | CAIRO_SURFACE_TYPE_IMAGE, /* type */ \ |
101 | CAIRO_CONTENT_COLOR, /* content */ \ |
106 | CAIRO_CONTENT_COLOR, /* content */ \ |
102 | CAIRO_REFERENCE_COUNT_INVALID, /* ref_count */ \ |
107 | CAIRO_REFERENCE_COUNT_INVALID, /* ref_count */ \ |
103 | status, /* status */ \ |
108 | status, /* status */ \ |
- | 109 | 0, /* unique id */ \ |
|
- | 110 | 0, /* serial */ \ |
|
- | 111 | NULL, /* damage */ \ |
|
104 | 0, /* unique id */ \ |
112 | FALSE, /* _finishing */ \ |
105 | FALSE, /* finished */ \ |
113 | FALSE, /* finished */ \ |
106 | TRUE, /* is_clear */ \ |
114 | TRUE, /* is_clear */ \ |
107 | FALSE, /* has_font_options */ \ |
115 | FALSE, /* has_font_options */ \ |
108 | FALSE, /* owns_device */ \ |
116 | FALSE, /* owns_device */ \ |
Line 121... | Line 129... | ||
121 | { NULL, NULL }, /* snapshot */ \ |
129 | { NULL, NULL }, /* snapshot */ \ |
122 | { CAIRO_ANTIALIAS_DEFAULT, /* antialias */ \ |
130 | { CAIRO_ANTIALIAS_DEFAULT, /* antialias */ \ |
123 | CAIRO_SUBPIXEL_ORDER_DEFAULT, /* subpixel_order */ \ |
131 | CAIRO_SUBPIXEL_ORDER_DEFAULT, /* subpixel_order */ \ |
124 | CAIRO_LCD_FILTER_DEFAULT, /* lcd_filter */ \ |
132 | CAIRO_LCD_FILTER_DEFAULT, /* lcd_filter */ \ |
125 | CAIRO_HINT_STYLE_DEFAULT, /* hint_style */ \ |
133 | CAIRO_HINT_STYLE_DEFAULT, /* hint_style */ \ |
126 | CAIRO_HINT_METRICS_DEFAULT /* hint_metrics */ \ |
134 | CAIRO_HINT_METRICS_DEFAULT, /* hint_metrics */ \ |
- | 135 | CAIRO_ROUND_GLYPH_POS_DEFAULT /* round_glyph_positions */ \ |
|
127 | } /* font_options */ \ |
136 | } /* font_options */ \ |
128 | } |
137 | } |
Line 129... | Line 138... | ||
129 | 138 | ||
Line 142... | Line 151... | ||
142 | static DEFINE_NIL_SURFACE(CAIRO_STATUS_INVALID_STRIDE, _cairo_surface_nil_invalid_stride); |
151 | static DEFINE_NIL_SURFACE(CAIRO_STATUS_INVALID_STRIDE, _cairo_surface_nil_invalid_stride); |
143 | static DEFINE_NIL_SURFACE(CAIRO_STATUS_INVALID_SIZE, _cairo_surface_nil_invalid_size); |
152 | static DEFINE_NIL_SURFACE(CAIRO_STATUS_INVALID_SIZE, _cairo_surface_nil_invalid_size); |
144 | static DEFINE_NIL_SURFACE(CAIRO_STATUS_DEVICE_TYPE_MISMATCH, _cairo_surface_nil_device_type_mismatch); |
153 | static DEFINE_NIL_SURFACE(CAIRO_STATUS_DEVICE_TYPE_MISMATCH, _cairo_surface_nil_device_type_mismatch); |
145 | static DEFINE_NIL_SURFACE(CAIRO_STATUS_DEVICE_ERROR, _cairo_surface_nil_device_error); |
154 | static DEFINE_NIL_SURFACE(CAIRO_STATUS_DEVICE_ERROR, _cairo_surface_nil_device_error); |
Line -... | Line 155... | ||
- | 155 | ||
- | 156 | static DEFINE_NIL_SURFACE(CAIRO_INT_STATUS_UNSUPPORTED, _cairo_surface_nil_unsupported); |
|
- | 157 | static DEFINE_NIL_SURFACE(CAIRO_INT_STATUS_NOTHING_TO_DO, _cairo_surface_nil_nothing_to_do); |
|
- | 158 | ||
- | 159 | static void _cairo_surface_finish_snapshots (cairo_surface_t *surface); |
|
- | 160 | static void _cairo_surface_finish (cairo_surface_t *surface); |
|
146 | 161 | ||
147 | /** |
162 | /** |
148 | * _cairo_surface_set_error: |
163 | * _cairo_surface_set_error: |
149 | * @surface: a surface |
164 | * @surface: a surface |
150 | * @status: a status value indicating an error |
165 | * @status: a status value indicating an error |
Line 162... | Line 177... | ||
162 | * breakpoint in _cairo_error() to generate a stack trace for when the |
177 | * breakpoint in _cairo_error() to generate a stack trace for when the |
163 | * user causes cairo to detect an error. |
178 | * user causes cairo to detect an error. |
164 | * |
179 | * |
165 | * Return value: the error status. |
180 | * Return value: the error status. |
166 | **/ |
181 | **/ |
167 | cairo_status_t |
182 | cairo_int_status_t |
168 | _cairo_surface_set_error (cairo_surface_t *surface, |
183 | _cairo_surface_set_error (cairo_surface_t *surface, |
169 | cairo_status_t status) |
184 | cairo_int_status_t status) |
170 | { |
185 | { |
- | 186 | /* NOTHING_TO_DO is magic. We use it to break out of the inner-most |
|
- | 187 | * surface function, but anything higher just sees "success". |
|
- | 188 | */ |
|
171 | if (status == CAIRO_INT_STATUS_NOTHING_TO_DO) |
189 | if (status == CAIRO_INT_STATUS_NOTHING_TO_DO) |
172 | status = CAIRO_STATUS_SUCCESS; |
190 | status = CAIRO_INT_STATUS_SUCCESS; |
Line -... | Line 191... | ||
- | 191 | ||
173 | 192 | if (status == CAIRO_INT_STATUS_SUCCESS || |
|
174 | if (status == CAIRO_STATUS_SUCCESS || status >= CAIRO_INT_STATUS_UNSUPPORTED) |
193 | status >= (int)CAIRO_INT_STATUS_LAST_STATUS) |
Line 175... | Line 194... | ||
175 | return status; |
194 | return status; |
176 | 195 | ||
177 | /* Don't overwrite an existing error. This preserves the first |
196 | /* Don't overwrite an existing error. This preserves the first |
Line 178... | Line 197... | ||
178 | * error, which is the most significant. */ |
197 | * error, which is the most significant. */ |
179 | _cairo_status_set_error (&surface->status, status); |
198 | _cairo_status_set_error (&surface->status, (cairo_status_t)status); |
Line 180... | Line 199... | ||
180 | 199 | ||
Line 199... | Line 218... | ||
199 | * special "wrapper" surfaces such as cairo_paginated_surface_t |
218 | * special "wrapper" surfaces such as cairo_paginated_surface_t |
200 | * can override surface->type with the type of the "child" |
219 | * can override surface->type with the type of the "child" |
201 | * surface. */ |
220 | * surface. */ |
202 | return surface->type; |
221 | return surface->type; |
203 | } |
222 | } |
204 | slim_hidden_def (cairo_surface_get_type); |
- | |
Line 205... | Line 223... | ||
205 | 223 | ||
206 | /** |
224 | /** |
207 | * cairo_surface_get_content: |
225 | * cairo_surface_get_content: |
208 | * @surface: a #cairo_surface_t |
226 | * @surface: a #cairo_surface_t |
Line 218... | Line 236... | ||
218 | cairo_content_t |
236 | cairo_content_t |
219 | cairo_surface_get_content (cairo_surface_t *surface) |
237 | cairo_surface_get_content (cairo_surface_t *surface) |
220 | { |
238 | { |
221 | return surface->content; |
239 | return surface->content; |
222 | } |
240 | } |
223 | slim_hidden_def(cairo_surface_get_content); |
- | |
Line 224... | Line 241... | ||
224 | 241 | ||
225 | /** |
242 | /** |
226 | * cairo_surface_status: |
243 | * cairo_surface_status: |
227 | * @surface: a #cairo_surface_t |
244 | * @surface: a #cairo_surface_t |
Line 231... | Line 248... | ||
231 | * |
248 | * |
232 | * Return value: %CAIRO_STATUS_SUCCESS, %CAIRO_STATUS_NULL_POINTER, |
249 | * Return value: %CAIRO_STATUS_SUCCESS, %CAIRO_STATUS_NULL_POINTER, |
233 | * %CAIRO_STATUS_NO_MEMORY, %CAIRO_STATUS_READ_ERROR, |
250 | * %CAIRO_STATUS_NO_MEMORY, %CAIRO_STATUS_READ_ERROR, |
234 | * %CAIRO_STATUS_INVALID_CONTENT, %CAIRO_STATUS_INVALID_FORMAT, or |
251 | * %CAIRO_STATUS_INVALID_CONTENT, %CAIRO_STATUS_INVALID_FORMAT, or |
235 | * %CAIRO_STATUS_INVALID_VISUAL. |
252 | * %CAIRO_STATUS_INVALID_VISUAL. |
- | 253 | * |
|
- | 254 | * Since: 1.0 |
|
236 | **/ |
255 | **/ |
237 | cairo_status_t |
256 | cairo_status_t |
238 | cairo_surface_status (cairo_surface_t *surface) |
257 | cairo_surface_status (cairo_surface_t *surface) |
239 | { |
258 | { |
240 | return surface->status; |
259 | return surface->status; |
Line 359... | Line 378... | ||
359 | cairo_surface_t *snapshot; |
378 | cairo_surface_t *snapshot; |
Line 360... | Line 379... | ||
360 | 379 | ||
361 | cairo_list_foreach_entry (snapshot, cairo_surface_t, |
380 | cairo_list_foreach_entry (snapshot, cairo_surface_t, |
362 | &surface->snapshots, snapshot) |
381 | &surface->snapshots, snapshot) |
363 | { |
- | |
364 | /* XXX is_similar? */ |
382 | { |
365 | if (snapshot->backend == backend) |
383 | if (snapshot->backend == backend) |
366 | return snapshot; |
384 | return snapshot; |
Line 367... | Line 385... | ||
367 | } |
385 | } |
368 | 386 | ||
Line 369... | Line 387... | ||
369 | return NULL; |
387 | return NULL; |
370 | } |
- | |
371 | - | ||
372 | static cairo_bool_t |
- | |
373 | _cairo_surface_is_writable (cairo_surface_t *surface) |
- | |
374 | { |
- | |
375 | return ! surface->finished && |
- | |
376 | surface->snapshot_of == NULL && |
- | |
377 | ! _cairo_surface_has_snapshots (surface) && |
- | |
378 | ! _cairo_surface_has_mime_data (surface); |
- | |
379 | } |
388 | } |
380 | 389 | ||
381 | static void |
390 | cairo_status_t |
382 | _cairo_surface_begin_modification (cairo_surface_t *surface) |
391 | _cairo_surface_begin_modification (cairo_surface_t *surface) |
383 | { |
- | |
Line 384... | Line 392... | ||
384 | assert (surface->status == CAIRO_STATUS_SUCCESS); |
392 | { |
385 | assert (! surface->finished); |
- | |
386 | assert (surface->snapshot_of == NULL); |
393 | assert (surface->status == CAIRO_STATUS_SUCCESS); |
Line 387... | Line 394... | ||
387 | 394 | assert (! surface->finished); |
|
388 | _cairo_surface_detach_snapshots (surface); |
395 | |
389 | _cairo_surface_detach_mime_data (surface); |
396 | return _cairo_surface_flush (surface, 1); |
Line 404... | Line 411... | ||
404 | 411 | ||
405 | CAIRO_REFERENCE_COUNT_INIT (&surface->ref_count, 1); |
412 | CAIRO_REFERENCE_COUNT_INIT (&surface->ref_count, 1); |
406 | surface->status = CAIRO_STATUS_SUCCESS; |
413 | surface->status = CAIRO_STATUS_SUCCESS; |
407 | surface->unique_id = _cairo_surface_allocate_unique_id (); |
414 | surface->unique_id = _cairo_surface_allocate_unique_id (); |
- | 415 | surface->finished = FALSE; |
|
408 | surface->finished = FALSE; |
416 | surface->_finishing = FALSE; |
- | 417 | surface->is_clear = FALSE; |
|
- | 418 | surface->serial = 0; |
|
409 | surface->is_clear = FALSE; |
419 | surface->damage = NULL; |
Line 410... | Line 420... | ||
410 | surface->owns_device = (device != NULL); |
420 | surface->owns_device = (device != NULL); |
411 | 421 | ||
Line 453... | Line 463... | ||
453 | cairo_surface_t *surface; |
463 | cairo_surface_t *surface; |
Line 454... | Line 464... | ||
454 | 464 | ||
455 | if (unlikely (other->status)) |
465 | if (unlikely (other->status)) |
Line -... | Line 466... | ||
- | 466 | return _cairo_surface_create_in_error (other->status); |
|
456 | return _cairo_surface_create_in_error (other->status); |
467 | |
- | 468 | surface = NULL; |
|
457 | 469 | if (other->backend->create_similar) |
|
- | 470 | surface = other->backend->create_similar (other, content, width, height); |
|
- | 471 | if (surface == NULL) |
|
- | 472 | surface = cairo_surface_create_similar_image (other, |
|
Line 458... | Line -... | ||
458 | if (other->backend->create_similar == NULL) |
- | |
459 | return NULL; |
- | |
460 | 473 | _cairo_format_from_content (content), |
|
461 | surface = other->backend->create_similar (other, |
474 | width, height); |
Line 462... | Line 475... | ||
462 | content, width, height); |
475 | |
Line 463... | Line 476... | ||
463 | if (surface == NULL || surface->status) |
476 | if (unlikely (surface->status)) |
Line 483... | Line 496... | ||
483 | * be examined with cairo_surface_get_type(). |
496 | * be examined with cairo_surface_get_type(). |
484 | * |
497 | * |
485 | * Initially the surface contents are all 0 (transparent if contents |
498 | * Initially the surface contents are all 0 (transparent if contents |
486 | * have transparency, black otherwise.) |
499 | * have transparency, black otherwise.) |
487 | * |
500 | * |
- | 501 | * Use cairo_surface_create_similar_image() if you need an image surface |
|
- | 502 | * which can be painted quickly to the target surface. |
|
- | 503 | * |
|
488 | * Return value: a pointer to the newly allocated surface. The caller |
504 | * Return value: a pointer to the newly allocated surface. The caller |
489 | * owns the surface and should call cairo_surface_destroy() when done |
505 | * owns the surface and should call cairo_surface_destroy() when done |
490 | * with it. |
506 | * with it. |
491 | * |
507 | * |
492 | * This function always returns a valid pointer, but it will return a |
508 | * This function always returns a valid pointer, but it will return a |
493 | * pointer to a "nil" surface if @other is already in an error state |
509 | * pointer to a "nil" surface if @other is already in an error state |
494 | * or any other error occurs. |
510 | * or any other error occurs. |
- | 511 | * |
|
- | 512 | * Since: 1.0 |
|
495 | **/ |
513 | **/ |
496 | cairo_surface_t * |
514 | cairo_surface_t * |
497 | cairo_surface_create_similar (cairo_surface_t *other, |
515 | cairo_surface_create_similar (cairo_surface_t *other, |
498 | cairo_content_t content, |
516 | cairo_content_t content, |
499 | int width, |
517 | int width, |
500 | int height) |
518 | int height) |
501 | { |
519 | { |
- | 520 | cairo_surface_t *surface; |
|
- | 521 | ||
502 | if (unlikely (other->status)) |
522 | if (unlikely (other->status)) |
503 | return _cairo_surface_create_in_error (other->status); |
523 | return _cairo_surface_create_in_error (other->status); |
504 | if (unlikely (other->finished)) |
524 | if (unlikely (other->finished)) |
505 | return _cairo_surface_create_in_error (CAIRO_STATUS_SURFACE_FINISHED); |
525 | return _cairo_surface_create_in_error (CAIRO_STATUS_SURFACE_FINISHED); |
- | 526 | if (unlikely (width < 0 || height < 0)) |
|
- | 527 | return _cairo_surface_create_in_error (CAIRO_STATUS_INVALID_SIZE); |
|
Line 506... | Line 528... | ||
506 | 528 | ||
507 | if (unlikely (! CAIRO_CONTENT_VALID (content))) |
529 | if (unlikely (! CAIRO_CONTENT_VALID (content))) |
Line 508... | Line 530... | ||
508 | return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_INVALID_CONTENT)); |
530 | return _cairo_surface_create_in_error (CAIRO_STATUS_INVALID_CONTENT); |
509 | 531 | ||
510 | return _cairo_surface_create_similar_solid (other, |
532 | surface = _cairo_surface_create_similar_solid (other, |
- | 533 | content, width, height, |
|
- | 534 | CAIRO_COLOR_TRANSPARENT); |
|
- | 535 | assert (surface->is_clear); |
|
- | 536 | ||
- | 537 | return surface; |
|
- | 538 | } |
|
- | 539 | ||
- | 540 | /** |
|
- | 541 | * cairo_surface_create_similar_image: |
|
- | 542 | * @other: an existing surface used to select the preference of the new surface |
|
- | 543 | * @format: the format for the new surface |
|
- | 544 | * @width: width of the new surface, (in device-space units) |
|
- | 545 | * @height: height of the new surface (in device-space units) |
|
- | 546 | * |
|
- | 547 | * Create a new image surface that is as compatible as possible for uploading |
|
- | 548 | * to and the use in conjunction with an existing surface. However, this surface |
|
- | 549 | * can still be used like any normal image surface. |
|
- | 550 | * |
|
- | 551 | * Initially the surface contents are all 0 (transparent if contents |
|
- | 552 | * have transparency, black otherwise.) |
|
- | 553 | * |
|
- | 554 | * Use cairo_surface_create_similar() if you don't need an image surface. |
|
- | 555 | * |
|
- | 556 | * Return value: a pointer to the newly allocated image surface. The caller |
|
- | 557 | * owns the surface and should call cairo_surface_destroy() when done |
|
- | 558 | * with it. |
|
- | 559 | * |
|
- | 560 | * This function always returns a valid pointer, but it will return a |
|
- | 561 | * pointer to a "nil" surface if @other is already in an error state |
|
- | 562 | * or any other error occurs. |
|
- | 563 | * |
|
- | 564 | * Since: 1.12 |
|
- | 565 | **/ |
|
- | 566 | cairo_surface_t * |
|
- | 567 | cairo_surface_create_similar_image (cairo_surface_t *other, |
|
- | 568 | cairo_format_t format, |
|
- | 569 | int width, |
|
- | 570 | int height) |
|
- | 571 | { |
|
- | 572 | cairo_surface_t *image; |
|
- | 573 | ||
- | 574 | if (unlikely (other->status)) |
|
- | 575 | return _cairo_surface_create_in_error (other->status); |
|
- | 576 | if (unlikely (other->finished)) |
|
- | 577 | return _cairo_surface_create_in_error (CAIRO_STATUS_SURFACE_FINISHED); |
|
- | 578 | ||
- | 579 | if (unlikely (width < 0 || height < 0)) |
|
- | 580 | return _cairo_surface_create_in_error (CAIRO_STATUS_INVALID_SIZE); |
|
- | 581 | if (unlikely (! CAIRO_FORMAT_VALID (format))) |
|
- | 582 | return _cairo_surface_create_in_error (CAIRO_STATUS_INVALID_FORMAT); |
|
- | 583 | ||
- | 584 | image = NULL; |
|
- | 585 | if (other->backend->create_similar_image) |
|
- | 586 | image = other->backend->create_similar_image (other, |
|
- | 587 | format, width, height); |
|
- | 588 | if (image == NULL) |
|
- | 589 | image = cairo_image_surface_create (format, width, height); |
|
- | 590 | ||
- | 591 | assert (image->is_clear); |
|
- | 592 | ||
- | 593 | return image; |
|
- | 594 | } |
|
- | 595 | slim_hidden_def (cairo_surface_create_similar_image); |
|
- | 596 | ||
- | 597 | /** |
|
- | 598 | * _cairo_surface_map_to_image: |
|
- | 599 | * @surface: an existing surface used to extract the image from |
|
- | 600 | * @extents: limit the extraction to an rectangular region |
|
- | 601 | * |
|
- | 602 | * Returns an image surface that is the most efficient mechanism for |
|
- | 603 | * modifying the backing store of the target surface. The region |
|
- | 604 | * retrieved is limited to @extents. |
|
- | 605 | * |
|
- | 606 | * Note, the use of the original surface as a target or source whilst |
|
- | 607 | * it is mapped is undefined. The result of mapping the surface |
|
- | 608 | * multiple times is undefined. Calling cairo_surface_destroy() or |
|
- | 609 | * cairo_surface_finish() on the resulting image surface results in |
|
- | 610 | * undefined behavior. Changing the device transform of the image |
|
- | 611 | * surface or of @surface before the image surface is unmapped results |
|
- | 612 | * in undefined behavior. |
|
- | 613 | * |
|
- | 614 | * Assumes that @surface is valid (CAIRO_STATUS_SUCCESS, |
|
- | 615 | * non-finished). |
|
- | 616 | * |
|
- | 617 | * Return value: a pointer to the newly allocated image surface. The |
|
- | 618 | * caller must use _cairo_surface_unmap_image() to destroy this image |
|
- | 619 | * surface. |
|
- | 620 | * |
|
- | 621 | * This function always returns a valid pointer, but it will return a |
|
- | 622 | * pointer to a "nil" surface if @other is already in an error state |
|
- | 623 | * or any other error occurs. |
|
- | 624 | * |
|
- | 625 | * The returned image might have a %CAIRO_FORMAT_INVALID format. |
|
- | 626 | **/ |
|
- | 627 | cairo_image_surface_t * |
|
- | 628 | _cairo_surface_map_to_image (cairo_surface_t *surface, |
|
- | 629 | const cairo_rectangle_int_t *extents) |
|
- | 630 | { |
|
- | 631 | cairo_image_surface_t *image = NULL; |
|
- | 632 | ||
- | 633 | assert (extents != NULL); |
|
- | 634 | ||
- | 635 | /* TODO: require map_to_image != NULL */ |
|
- | 636 | if (surface->backend->map_to_image) |
|
- | 637 | image = surface->backend->map_to_image (surface, extents); |
|
- | 638 | ||
- | 639 | if (image == NULL) |
|
- | 640 | image = _cairo_image_surface_clone_subimage (surface, extents); |
|
- | 641 | ||
- | 642 | return image; |
|
- | 643 | } |
|
- | 644 | ||
- | 645 | /** |
|
- | 646 | * _cairo_surface_unmap_image: |
|
- | 647 | * @surface: the surface passed to _cairo_surface_map_to_image(). |
|
- | 648 | * @image: the currently mapped image |
|
- | 649 | * |
|
- | 650 | * Unmaps the image surface as returned from |
|
- | 651 | * _cairo_surface_map_to_image(). |
|
- | 652 | * |
|
- | 653 | * The content of the image will be uploaded to the target surface. |
|
- | 654 | * Afterwards, the image is destroyed. |
|
- | 655 | * |
|
- | 656 | * Using an image surface which wasn't returned by |
|
- | 657 | * _cairo_surface_map_to_image() results in undefined behavior. |
|
- | 658 | * |
|
- | 659 | * An image surface in error status can be passed to |
|
- | 660 | * _cairo_surface_unmap_image(). |
|
- | 661 | * |
|
- | 662 | * Return value: the unmap status. |
|
- | 663 | * |
|
- | 664 | * Even if the unmap status is not successful, @image is destroyed. |
|
- | 665 | **/ |
|
- | 666 | cairo_int_status_t |
|
- | 667 | _cairo_surface_unmap_image (cairo_surface_t *surface, |
|
- | 668 | cairo_image_surface_t *image) |
|
- | 669 | { |
|
- | 670 | cairo_surface_pattern_t pattern; |
|
- | 671 | cairo_rectangle_int_t extents; |
|
- | 672 | cairo_clip_t *clip; |
|
- | 673 | cairo_int_status_t status; |
|
- | 674 | ||
- | 675 | /* map_to_image can return error surfaces */ |
|
- | 676 | if (unlikely (image->base.status)) { |
|
- | 677 | status = image->base.status; |
|
- | 678 | goto destroy; |
|
- | 679 | } |
|
- | 680 | ||
- | 681 | /* If the image is untouched just skip the update */ |
|
- | 682 | if (image->base.serial == 0) { |
|
- | 683 | status = CAIRO_STATUS_SUCCESS; |
|
- | 684 | goto destroy; |
|
- | 685 | } |
|
- | 686 | ||
- | 687 | /* TODO: require unmap_image != NULL */ |
|
- | 688 | if (surface->backend->unmap_image && |
|
- | 689 | ! _cairo_image_surface_is_clone (image)) |
|
- | 690 | { |
|
- | 691 | status = surface->backend->unmap_image (surface, image); |
|
- | 692 | if (status != CAIRO_INT_STATUS_UNSUPPORTED) |
|
- | 693 | return status; |
|
- | 694 | } |
|
- | 695 | ||
- | 696 | _cairo_pattern_init_for_surface (&pattern, &image->base); |
|
- | 697 | pattern.base.filter = CAIRO_FILTER_NEAREST; |
|
- | 698 | ||
- | 699 | /* We have to apply the translate from map_to_image's extents.x and .y */ |
|
- | 700 | cairo_matrix_init_translate (&pattern.base.matrix, |
|
- | 701 | image->base.device_transform.x0, |
|
- | 702 | image->base.device_transform.y0); |
|
- | 703 | ||
- | 704 | /* And we also have to clip the operation to the image's extents */ |
|
- | 705 | extents.x = image->base.device_transform_inverse.x0; |
|
- | 706 | extents.y = image->base.device_transform_inverse.y0; |
|
- | 707 | extents.width = image->width; |
|
- | 708 | extents.height = image->height; |
|
- | 709 | clip = _cairo_clip_intersect_rectangle (NULL, &extents); |
|
- | 710 | ||
- | 711 | status = _cairo_surface_paint (surface, |
|
511 | content, width, height, |
712 | CAIRO_OPERATOR_SOURCE, |
- | 713 | &pattern.base, |
|
- | 714 | clip); |
|
- | 715 | ||
- | 716 | _cairo_pattern_fini (&pattern.base); |
|
- | 717 | _cairo_clip_destroy (clip); |
|
- | 718 | ||
- | 719 | destroy: |
|
- | 720 | cairo_surface_finish (&image->base); |
|
- | 721 | cairo_surface_destroy (&image->base); |
|
- | 722 | ||
- | 723 | return status; |
|
- | 724 | } |
|
- | 725 | ||
- | 726 | /** |
|
- | 727 | * cairo_surface_map_to_image: |
|
- | 728 | * @surface: an existing surface used to extract the image from |
|
- | 729 | * @extents: limit the extraction to an rectangular region |
|
- | 730 | * |
|
- | 731 | * Returns an image surface that is the most efficient mechanism for |
|
- | 732 | * modifying the backing store of the target surface. The region retrieved |
|
- | 733 | * may be limited to the @extents or %NULL for the whole surface |
|
- | 734 | * |
|
- | 735 | * Note, the use of the original surface as a target or source whilst |
|
- | 736 | * it is mapped is undefined. The result of mapping the surface |
|
- | 737 | * multiple times is undefined. Calling cairo_surface_destroy() or |
|
- | 738 | * cairo_surface_finish() on the resulting image surface results in |
|
- | 739 | * undefined behavior. Changing the device transform of the image |
|
- | 740 | * surface or of @surface before the image surface is unmapped results |
|
- | 741 | * in undefined behavior. |
|
- | 742 | * |
|
- | 743 | * Return value: a pointer to the newly allocated image surface. The caller |
|
- | 744 | * must use cairo_surface_unmap_image() to destroy this image surface. |
|
- | 745 | * |
|
- | 746 | * This function always returns a valid pointer, but it will return a |
|
- | 747 | * pointer to a "nil" surface if @other is already in an error state |
|
- | 748 | * or any other error occurs. If the returned pointer does not have an |
|
- | 749 | * error status, it is guaranteed to be an image surface whose format |
|
- | 750 | * is not %CAIRO_FORMAT_INVALID. |
|
- | 751 | * |
|
- | 752 | * Since: 1.12 |
|
- | 753 | **/ |
|
- | 754 | cairo_surface_t * |
|
- | 755 | cairo_surface_map_to_image (cairo_surface_t *surface, |
|
- | 756 | const cairo_rectangle_int_t *extents) |
|
- | 757 | { |
|
- | 758 | cairo_rectangle_int_t rect; |
|
- | 759 | cairo_image_surface_t *image; |
|
- | 760 | cairo_status_t status; |
|
- | 761 | ||
- | 762 | if (unlikely (surface->status)) |
|
- | 763 | return _cairo_surface_create_in_error (surface->status); |
|
- | 764 | if (unlikely (surface->finished)) |
|
- | 765 | return _cairo_surface_create_in_error (CAIRO_STATUS_SURFACE_FINISHED); |
|
- | 766 | ||
- | 767 | if (extents == NULL) { |
|
- | 768 | if (unlikely (! surface->backend->get_extents (surface, &rect))) |
|
- | 769 | return _cairo_surface_create_in_error (CAIRO_STATUS_INVALID_SIZE); |
|
- | 770 | ||
- | 771 | extents = ▭ |
|
- | 772 | } else { |
|
- | 773 | cairo_rectangle_int_t surface_extents; |
|
- | 774 | ||
- | 775 | /* If this surface is bounded, we can't map parts |
|
- | 776 | * that are outside of it. */ |
|
- | 777 | if (likely (surface->backend->get_extents (surface, &surface_extents))) { |
|
- | 778 | if (unlikely (! _cairo_rectangle_contains_rectangle (&surface_extents, extents))) |
|
- | 779 | return _cairo_surface_create_in_error (CAIRO_STATUS_INVALID_SIZE); |
|
- | 780 | } |
|
- | 781 | } |
|
- | 782 | ||
- | 783 | image = _cairo_surface_map_to_image (surface, extents); |
|
- | 784 | ||
- | 785 | status = image->base.status; |
|
- | 786 | if (unlikely (status)) { |
|
- | 787 | cairo_surface_destroy (&image->base); |
|
- | 788 | return _cairo_surface_create_in_error (status); |
|
- | 789 | } |
|
- | 790 | ||
- | 791 | if (image->format == CAIRO_FORMAT_INVALID) { |
|
- | 792 | cairo_surface_destroy (&image->base); |
|
- | 793 | image = _cairo_image_surface_clone_subimage (surface, extents); |
|
- | 794 | } |
|
- | 795 | ||
- | 796 | return &image->base; |
|
- | 797 | } |
|
- | 798 | ||
- | 799 | /** |
|
- | 800 | * cairo_surface_unmap_image: |
|
- | 801 | * @surface: the surface passed to cairo_surface_map_to_image(). |
|
- | 802 | * @image: the currently mapped image |
|
- | 803 | * |
|
- | 804 | * Unmaps the image surface as returned from #cairo_surface_map_to_image(). |
|
- | 805 | * |
|
- | 806 | * The content of the image will be uploaded to the target surface. |
|
- | 807 | * Afterwards, the image is destroyed. |
|
- | 808 | * |
|
- | 809 | * Using an image surface which wasn't returned by cairo_surface_map_to_image() |
|
- | 810 | * results in undefined behavior. |
|
- | 811 | * |
|
- | 812 | * Since: 1.12 |
|
- | 813 | **/ |
|
- | 814 | void |
|
- | 815 | cairo_surface_unmap_image (cairo_surface_t *surface, |
|
- | 816 | cairo_surface_t *image) |
|
- | 817 | { |
|
- | 818 | cairo_int_status_t status = CAIRO_STATUS_SUCCESS; |
|
- | 819 | ||
- | 820 | if (unlikely (surface->status)) { |
|
- | 821 | status = surface->status; |
|
- | 822 | goto error; |
|
- | 823 | } |
|
- | 824 | if (unlikely (surface->finished)) { |
|
- | 825 | status = _cairo_error (CAIRO_STATUS_SURFACE_FINISHED); |
|
- | 826 | goto error; |
|
- | 827 | } |
|
- | 828 | if (unlikely (image->status)) { |
|
- | 829 | status = image->status; |
|
- | 830 | goto error; |
|
- | 831 | } |
|
- | 832 | if (unlikely (image->finished)) { |
|
- | 833 | status = _cairo_error (CAIRO_STATUS_SURFACE_FINISHED); |
|
- | 834 | goto error; |
|
- | 835 | } |
|
- | 836 | if (unlikely (! _cairo_surface_is_image (image))) { |
|
- | 837 | status = _cairo_error (CAIRO_STATUS_SURFACE_TYPE_MISMATCH); |
|
- | 838 | goto error; |
|
- | 839 | } |
|
- | 840 | ||
- | 841 | status = _cairo_surface_unmap_image (surface, |
|
- | 842 | (cairo_image_surface_t *) image); |
|
- | 843 | if (unlikely (status)) |
|
- | 844 | _cairo_surface_set_error (surface, status); |
|
- | 845 | ||
- | 846 | return; |
|
- | 847 | ||
- | 848 | error: |
|
- | 849 | _cairo_surface_set_error (surface, status); |
|
512 | CAIRO_COLOR_TRANSPARENT, |
850 | cairo_surface_finish (image); |
Line 513... | Line 851... | ||
513 | TRUE); |
851 | cairo_surface_destroy (image); |
514 | } |
852 | } |
515 | 853 | ||
516 | cairo_surface_t * |
854 | cairo_surface_t * |
517 | _cairo_surface_create_similar_solid (cairo_surface_t *other, |
855 | _cairo_surface_create_similar_solid (cairo_surface_t *other, |
518 | cairo_content_t content, |
856 | cairo_content_t content, |
519 | int width, |
- | |
520 | int height, |
857 | int width, |
521 | const cairo_color_t *color, |
858 | int height, |
522 | cairo_bool_t allow_fallback) |
859 | const cairo_color_t *color) |
523 | { |
860 | { |
Line 524... | Line 861... | ||
524 | cairo_status_t status; |
861 | cairo_status_t status; |
525 | cairo_surface_t *surface; |
862 | cairo_surface_t *surface; |
526 | cairo_solid_pattern_t pattern; |
- | |
527 | - | ||
528 | surface = _cairo_surface_create_similar_scratch (other, content, |
- | |
529 | width, height); |
863 | cairo_solid_pattern_t pattern; |
530 | if (surface == NULL && allow_fallback) |
864 | |
Line 531... | Line 865... | ||
531 | surface = _cairo_image_surface_create_with_content (content, |
865 | surface = _cairo_surface_create_similar_scratch (other, content, |
532 | width, height); |
866 | width, height); |
533 | if (surface == NULL || surface->status) |
867 | if (unlikely (surface->status)) |
Line 544... | Line 878... | ||
544 | } |
878 | } |
Line 545... | Line 879... | ||
545 | 879 | ||
546 | return surface; |
880 | return surface; |
Line 547... | Line -... | ||
547 | } |
- | |
548 | - | ||
549 | cairo_surface_t * |
- | |
550 | _cairo_surface_create_solid_pattern_surface (cairo_surface_t *other, |
- | |
551 | const cairo_solid_pattern_t *solid_pattern) |
- | |
552 | { |
- | |
553 | if (other->backend->create_solid_pattern_surface != NULL) { |
- | |
554 | cairo_surface_t *surface; |
- | |
555 | - | ||
556 | surface = other->backend->create_solid_pattern_surface (other, |
- | |
557 | solid_pattern); |
- | |
558 | if (surface) |
- | |
559 | return surface; |
- | |
560 | } |
- | |
561 | - | ||
562 | return _cairo_surface_create_similar_solid (other, |
- | |
563 | _cairo_color_get_content (&solid_pattern->color), |
- | |
564 | 1, 1, |
- | |
565 | &solid_pattern->color, |
- | |
566 | FALSE); |
- | |
567 | } |
- | |
568 | - | ||
569 | cairo_int_status_t |
- | |
570 | _cairo_surface_repaint_solid_pattern_surface (cairo_surface_t *other, |
- | |
571 | cairo_surface_t *solid_surface, |
- | |
572 | const cairo_solid_pattern_t *solid_pattern) |
- | |
573 | { |
- | |
574 | /* Solid pattern surface for these backends are special and not trivial |
- | |
575 | * to repaint. Skip repainting. |
- | |
576 | * |
- | |
577 | * This does not work optimally with things like analysis surface that |
- | |
578 | * are proxies. But returning UNSUPPORTED is *safe* as it only |
- | |
579 | * disables some caching. |
- | |
580 | */ |
- | |
581 | if (other->backend->create_solid_pattern_surface != NULL && |
- | |
582 | ! other->backend->can_repaint_solid_pattern_surface (solid_surface, |
- | |
583 | solid_pattern)) |
- | |
584 | { |
- | |
585 | return CAIRO_INT_STATUS_UNSUPPORTED; |
- | |
586 | } |
- | |
587 | - | ||
588 | return _cairo_surface_paint (solid_surface, |
- | |
589 | CAIRO_OPERATOR_SOURCE, |
- | |
590 | &solid_pattern->base, |
- | |
591 | NULL); |
- | |
592 | } |
881 | } |
593 | 882 | ||
594 | /** |
883 | /** |
595 | * cairo_surface_reference: |
884 | * cairo_surface_reference: |
596 | * @surface: a #cairo_surface_t |
885 | * @surface: a #cairo_surface_t |
Line 601... | Line 890... | ||
601 | * |
890 | * |
602 | * The number of references to a #cairo_surface_t can be get using |
891 | * The number of references to a #cairo_surface_t can be get using |
603 | * cairo_surface_get_reference_count(). |
892 | * cairo_surface_get_reference_count(). |
604 | * |
893 | * |
605 | * Return value: the referenced #cairo_surface_t. |
894 | * Return value: the referenced #cairo_surface_t. |
- | 895 | * |
|
- | 896 | * Since: 1.0 |
|
606 | **/ |
897 | **/ |
607 | cairo_surface_t * |
898 | cairo_surface_t * |
608 | cairo_surface_reference (cairo_surface_t *surface) |
899 | cairo_surface_reference (cairo_surface_t *surface) |
609 | { |
900 | { |
610 | if (surface == NULL || |
901 | if (surface == NULL || |
Line 624... | Line 915... | ||
624 | * @surface: a #cairo_surface_t |
915 | * @surface: a #cairo_surface_t |
625 | * |
916 | * |
626 | * Decreases the reference count on @surface by one. If the result is |
917 | * Decreases the reference count on @surface by one. If the result is |
627 | * zero, then @surface and all associated resources are freed. See |
918 | * zero, then @surface and all associated resources are freed. See |
628 | * cairo_surface_reference(). |
919 | * cairo_surface_reference(). |
- | 920 | * |
|
- | 921 | * Since: 1.0 |
|
629 | **/ |
922 | **/ |
630 | void |
923 | void |
631 | cairo_surface_destroy (cairo_surface_t *surface) |
924 | cairo_surface_destroy (cairo_surface_t *surface) |
632 | { |
925 | { |
633 | if (surface == NULL || |
926 | if (surface == NULL || |
Line 639... | Line 932... | ||
639 | if (! _cairo_reference_count_dec_and_test (&surface->ref_count)) |
932 | if (! _cairo_reference_count_dec_and_test (&surface->ref_count)) |
640 | return; |
933 | return; |
Line 641... | Line 934... | ||
641 | 934 | ||
Line 642... | Line 935... | ||
642 | assert (surface->snapshot_of == NULL); |
935 | assert (surface->snapshot_of == NULL); |
643 | 936 | ||
- | 937 | if (! surface->finished) { |
|
- | 938 | _cairo_surface_finish_snapshots (surface); |
|
- | 939 | /* We may have been referenced by a snapshot prior to have |
|
- | 940 | * detaching it with the copy-on-write. |
|
- | 941 | */ |
|
Line 644... | Line 942... | ||
644 | if (! surface->finished) |
942 | if (CAIRO_REFERENCE_COUNT_GET_VALUE (&surface->ref_count)) |
- | 943 | return; |
|
- | 944 | ||
- | 945 | _cairo_surface_finish (surface); |
|
645 | cairo_surface_finish (surface); |
946 | } |
Line 646... | Line 947... | ||
646 | 947 | ||
647 | /* paranoid check that nobody took a reference whilst finishing */ |
948 | if (surface->damage) |
Line 648... | Line 949... | ||
648 | assert (! CAIRO_REFERENCE_COUNT_HAS_REFERENCE (&surface->ref_count)); |
949 | _cairo_damage_destroy (surface->damage); |
649 | 950 | ||
Line -... | Line 951... | ||
- | 951 | _cairo_user_data_array_fini (&surface->user_data); |
|
- | 952 | _cairo_user_data_array_fini (&surface->mime_data); |
|
- | 953 | ||
- | 954 | if (surface->owns_device) |
|
- | 955 | cairo_device_destroy (surface->device); |
|
650 | _cairo_user_data_array_fini (&surface->user_data); |
956 | |
651 | _cairo_user_data_array_fini (&surface->mime_data); |
957 | assert (surface->snapshot_of == NULL); |
652 | 958 | assert (! _cairo_surface_has_snapshots (surface)); |
|
Line 653... | Line 959... | ||
653 | if (surface->owns_device) |
959 | /* paranoid check that nobody took a reference whilst finishing */ |
Line 676... | Line 982... | ||
676 | return 0; |
982 | return 0; |
Line 677... | Line 983... | ||
677 | 983 | ||
678 | return CAIRO_REFERENCE_COUNT_GET_VALUE (&surface->ref_count); |
984 | return CAIRO_REFERENCE_COUNT_GET_VALUE (&surface->ref_count); |
Line -... | Line 985... | ||
- | 985 | } |
|
- | 986 | ||
- | 987 | static void |
|
- | 988 | _cairo_surface_finish_snapshots (cairo_surface_t *surface) |
|
- | 989 | { |
|
- | 990 | cairo_status_t status; |
|
- | 991 | ||
- | 992 | /* update the snapshots *before* we declare the surface as finished */ |
|
- | 993 | surface->_finishing = TRUE; |
|
- | 994 | status = _cairo_surface_flush (surface, 0); |
|
- | 995 | (void) status; |
|
- | 996 | } |
|
- | 997 | ||
- | 998 | static void |
|
- | 999 | _cairo_surface_finish (cairo_surface_t *surface) |
|
- | 1000 | { |
|
- | 1001 | cairo_status_t status; |
|
- | 1002 | ||
- | 1003 | surface->finished = TRUE; |
|
- | 1004 | ||
- | 1005 | /* call finish even if in error mode */ |
|
- | 1006 | if (surface->backend->finish) { |
|
- | 1007 | status = surface->backend->finish (surface); |
|
- | 1008 | if (unlikely (status)) |
|
- | 1009 | _cairo_surface_set_error (surface, status); |
|
- | 1010 | } |
|
- | 1011 | ||
- | 1012 | assert (surface->snapshot_of == NULL); |
|
- | 1013 | assert (!_cairo_surface_has_snapshots (surface)); |
|
679 | } |
1014 | } |
680 | 1015 | ||
681 | /** |
1016 | /** |
682 | * cairo_surface_finish: |
1017 | * cairo_surface_finish: |
683 | * @surface: the #cairo_surface_t to finish |
1018 | * @surface: the #cairo_surface_t to finish |
Line 694... | Line 1029... | ||
694 | * |
1029 | * |
695 | * When the last call to cairo_surface_destroy() decreases the |
1030 | * When the last call to cairo_surface_destroy() decreases the |
696 | * reference count to zero, cairo will call cairo_surface_finish() if |
1031 | * reference count to zero, cairo will call cairo_surface_finish() if |
697 | * it hasn't been called already, before freeing the resources |
1032 | * it hasn't been called already, before freeing the resources |
698 | * associated with the surface. |
1033 | * associated with the surface. |
- | 1034 | * |
|
- | 1035 | * Since: 1.0 |
|
699 | **/ |
1036 | **/ |
700 | void |
1037 | void |
701 | cairo_surface_finish (cairo_surface_t *surface) |
1038 | cairo_surface_finish (cairo_surface_t *surface) |
702 | { |
1039 | { |
703 | cairo_status_t status; |
- | |
704 | - | ||
705 | if (surface == NULL) |
1040 | if (surface == NULL) |
706 | return; |
1041 | return; |
Line 707... | Line 1042... | ||
707 | 1042 | ||
708 | if (CAIRO_REFERENCE_COUNT_IS_INVALID (&surface->ref_count)) |
1043 | if (CAIRO_REFERENCE_COUNT_IS_INVALID (&surface->ref_count)) |
Line 709... | Line 1044... | ||
709 | return; |
1044 | return; |
710 | 1045 | ||
Line 711... | Line 1046... | ||
711 | if (surface->finished) |
1046 | if (surface->finished) |
712 | return; |
1047 | return; |
713 | - | ||
714 | /* update the snapshots *before* we declare the surface as finished */ |
- | |
Line 715... | Line 1048... | ||
715 | _cairo_surface_detach_snapshots (surface); |
1048 | |
- | 1049 | /* We have to be careful when decoupling potential reference cycles */ |
|
716 | if (surface->snapshot_of != NULL) |
1050 | cairo_surface_reference (surface); |
Line 717... | Line -... | ||
717 | _cairo_surface_detach_snapshot (surface); |
- | |
718 | - | ||
719 | cairo_surface_flush (surface); |
- | |
720 | surface->finished = TRUE; |
- | |
721 | 1051 | ||
722 | /* call finish even if in error mode */ |
- | |
723 | if (surface->backend->finish) { |
1052 | _cairo_surface_finish_snapshots (surface); |
724 | status = surface->backend->finish (surface); |
1053 | /* XXX need to block and wait for snapshot references */ |
Line 725... | Line 1054... | ||
725 | if (unlikely (status)) |
1054 | _cairo_surface_finish (surface); |
726 | status = _cairo_surface_set_error (surface, status); |
1055 | |
Line 758... | Line 1087... | ||
758 | * Return user data previously attached to @surface using the specified |
1087 | * Return user data previously attached to @surface using the specified |
759 | * key. If no user data has been attached with the given key this |
1088 | * key. If no user data has been attached with the given key this |
760 | * function returns %NULL. |
1089 | * function returns %NULL. |
761 | * |
1090 | * |
762 | * Return value: the user data previously attached or %NULL. |
1091 | * Return value: the user data previously attached or %NULL. |
- | 1092 | * |
|
- | 1093 | * Since: 1.0 |
|
763 | **/ |
1094 | **/ |
764 | void * |
1095 | void * |
765 | cairo_surface_get_user_data (cairo_surface_t *surface, |
1096 | cairo_surface_get_user_data (cairo_surface_t *surface, |
766 | const cairo_user_data_key_t *key) |
1097 | const cairo_user_data_key_t *key) |
767 | { |
1098 | { |
- | 1099 | /* Prevent reads of the array during teardown */ |
|
768 | return _cairo_user_data_array_get_data (&surface->user_data, |
1100 | if (! CAIRO_REFERENCE_COUNT_HAS_REFERENCE (&surface->ref_count)) |
769 | key); |
1101 | return NULL; |
- | 1102 | ||
- | 1103 | return _cairo_user_data_array_get_data (&surface->user_data, key); |
|
770 | } |
1104 | } |
Line 771... | Line 1105... | ||
771 | 1105 | ||
772 | /** |
1106 | /** |
773 | * cairo_surface_set_user_data: |
1107 | * cairo_surface_set_user_data: |
Line 782... | Line 1116... | ||
782 | * call this function with the key that was used to set it and %NULL |
1116 | * call this function with the key that was used to set it and %NULL |
783 | * for @data. |
1117 | * for @data. |
784 | * |
1118 | * |
785 | * Return value: %CAIRO_STATUS_SUCCESS or %CAIRO_STATUS_NO_MEMORY if a |
1119 | * Return value: %CAIRO_STATUS_SUCCESS or %CAIRO_STATUS_NO_MEMORY if a |
786 | * slot could not be allocated for the user data. |
1120 | * slot could not be allocated for the user data. |
- | 1121 | * |
|
- | 1122 | * Since: 1.0 |
|
787 | **/ |
1123 | **/ |
788 | cairo_status_t |
1124 | cairo_status_t |
789 | cairo_surface_set_user_data (cairo_surface_t *surface, |
1125 | cairo_surface_set_user_data (cairo_surface_t *surface, |
790 | const cairo_user_data_key_t *key, |
1126 | const cairo_user_data_key_t *key, |
791 | void *user_data, |
1127 | void *user_data, |
792 | cairo_destroy_func_t destroy) |
1128 | cairo_destroy_func_t destroy) |
793 | { |
1129 | { |
794 | if (CAIRO_REFERENCE_COUNT_IS_INVALID (&surface->ref_count)) |
1130 | if (CAIRO_REFERENCE_COUNT_IS_INVALID (&surface->ref_count)) |
795 | return surface->status; |
1131 | return surface->status; |
Line -... | Line 1132... | ||
- | 1132 | ||
- | 1133 | if (! CAIRO_REFERENCE_COUNT_HAS_REFERENCE (&surface->ref_count)) |
|
- | 1134 | return _cairo_error (CAIRO_STATUS_SURFACE_FINISHED); |
|
796 | 1135 | ||
797 | return _cairo_user_data_array_set_data (&surface->user_data, |
1136 | return _cairo_user_data_array_set_data (&surface->user_data, |
798 | key, user_data, destroy); |
1137 | key, user_data, destroy); |
Line 799... | Line 1138... | ||
799 | } |
1138 | } |
Line 820... | Line 1159... | ||
820 | cairo_user_data_slot_t *slots; |
1159 | cairo_user_data_slot_t *slots; |
821 | int i, num_slots; |
1160 | int i, num_slots; |
Line 822... | Line 1161... | ||
822 | 1161 | ||
823 | *data = NULL; |
1162 | *data = NULL; |
- | 1163 | *length = 0; |
|
- | 1164 | ||
824 | *length = 0; |
1165 | /* Prevent reads of the array during teardown */ |
825 | if (unlikely (surface->status)) |
1166 | if (! CAIRO_REFERENCE_COUNT_HAS_REFERENCE (&surface->ref_count)) |
Line 826... | Line 1167... | ||
826 | return; |
1167 | return; |
827 | 1168 | ||
828 | /* The number of mime-types attached to a surface is usually small, |
1169 | /* The number of mime-types attached to a surface is usually small, |
829 | * typically zero. Therefore it is quicker to do a strcmp() against |
1170 | * typically zero. Therefore it is quicker to do a strcmp() against |
830 | * each key than it is to intern the string (i.e. compute a hash, |
1171 | * each key than it is to intern the string (i.e. compute a hash, |
831 | * search the hash table, and do a final strcmp). |
1172 | * search the hash table, and do a final strcmp). |
832 | */ |
1173 | */ |
833 | num_slots = surface->mime_data.num_elements; |
1174 | num_slots = surface->mime_data.num_elements; |
834 | slots = _cairo_array_index (&surface->mime_data, 0); |
1175 | slots = _cairo_array_index (&surface->mime_data, 0); |
835 | for (i = 0; i < num_slots; i++) { |
1176 | for (i = 0; i < num_slots; i++) { |
Line 836... | Line 1177... | ||
836 | if (strcmp ((char *) slots[i].key, mime_type) == 0) { |
1177 | if (slots[i].key != NULL && strcmp ((char *) slots[i].key, mime_type) == 0) { |
837 | cairo_mime_data_t *mime_data = slots[i].user_data; |
1178 | cairo_mime_data_t *mime_data = slots[i].user_data; |
838 | 1179 | ||
Line 861... | Line 1202... | ||
861 | /** |
1202 | /** |
862 | * CAIRO_MIME_TYPE_JP2: |
1203 | * CAIRO_MIME_TYPE_JP2: |
863 | * |
1204 | * |
864 | * The Joint Photographic Experts Group (JPEG) 2000 image coding standard (ISO/IEC 15444-1). |
1205 | * The Joint Photographic Experts Group (JPEG) 2000 image coding standard (ISO/IEC 15444-1). |
865 | * |
1206 | * |
866 | * @Since: 1.10 |
1207 | * Since: 1.10 |
867 | */ |
1208 | **/ |
Line 868... | Line 1209... | ||
868 | 1209 | ||
869 | /** |
1210 | /** |
870 | * CAIRO_MIME_TYPE_JPEG: |
1211 | * CAIRO_MIME_TYPE_JPEG: |
871 | * |
1212 | * |
872 | * The Joint Photographic Experts Group (JPEG) image coding standard (ISO/IEC 10918-1). |
1213 | * The Joint Photographic Experts Group (JPEG) image coding standard (ISO/IEC 10918-1). |
873 | * |
1214 | * |
874 | * @Since: 1.10 |
1215 | * Since: 1.10 |
Line 875... | Line 1216... | ||
875 | */ |
1216 | **/ |
876 | 1217 | ||
877 | /** |
1218 | /** |
878 | * CAIRO_MIME_TYPE_PNG: |
1219 | * CAIRO_MIME_TYPE_PNG: |
879 | * |
1220 | * |
880 | * The Portable Network Graphics image file format (ISO/IEC 15948). |
1221 | * The Portable Network Graphics image file format (ISO/IEC 15948). |
881 | * |
1222 | * |
Line 882... | Line 1223... | ||
882 | * @Since: 1.10 |
1223 | * Since: 1.10 |
883 | */ |
1224 | **/ |
884 | 1225 | ||
885 | /** |
1226 | /** |
886 | * CAIRO_MIME_TYPE_URI: |
1227 | * CAIRO_MIME_TYPE_URI: |
887 | * |
1228 | * |
- | 1229 | * URI for an image file (unofficial MIME type). |
|
- | 1230 | * |
|
- | 1231 | * Since: 1.10 |
|
- | 1232 | **/ |
|
- | 1233 | ||
- | 1234 | /** |
|
- | 1235 | * CAIRO_MIME_TYPE_UNIQUE_ID: |
|
- | 1236 | * |
|
888 | * URI for an image file (unofficial MIME type). |
1237 | * Unique identifier for a surface (cairo specific MIME type). |
Line 889... | Line 1238... | ||
889 | * |
1238 | * |
890 | * @Since: 1.10 |
1239 | * Since: 1.12 |
891 | */ |
1240 | **/ |
892 | 1241 | ||
Line 910... | Line 1259... | ||
910 | * surfaces) to emit this data instead of making a snapshot of the |
1259 | * surfaces) to emit this data instead of making a snapshot of the |
911 | * @surface. This approach tends to be faster and requires less |
1260 | * @surface. This approach tends to be faster and requires less |
912 | * memory and disk space. |
1261 | * memory and disk space. |
913 | * |
1262 | * |
914 | * The recognized MIME types are the following: %CAIRO_MIME_TYPE_JPEG, |
1263 | * The recognized MIME types are the following: %CAIRO_MIME_TYPE_JPEG, |
915 | * %CAIRO_MIME_TYPE_PNG, %CAIRO_MIME_TYPE_JP2, %CAIRO_MIME_TYPE_URI. |
1264 | * %CAIRO_MIME_TYPE_PNG, %CAIRO_MIME_TYPE_JP2, %CAIRO_MIME_TYPE_URI, |
- | 1265 | * %CAIRO_MIME_TYPE_UNIQUE_ID. |
|
916 | * |
1266 | * |
917 | * See corresponding backend surface docs for details about which MIME |
1267 | * See corresponding backend surface docs for details about which MIME |
918 | * types it can handle. Caution: the associated MIME data will be |
1268 | * types it can handle. Caution: the associated MIME data will be |
919 | * discarded if you draw on the surface afterwards. Use this function |
1269 | * discarded if you draw on the surface afterwards. Use this function |
920 | * with care. |
1270 | * with care. |
921 | * |
1271 | * |
922 | * Since: 1.10 |
- | |
923 | * |
- | |
924 | * Return value: %CAIRO_STATUS_SUCCESS or %CAIRO_STATUS_NO_MEMORY if a |
1272 | * Return value: %CAIRO_STATUS_SUCCESS or %CAIRO_STATUS_NO_MEMORY if a |
925 | * slot could not be allocated for the user data. |
1273 | * slot could not be allocated for the user data. |
- | 1274 | * |
|
- | 1275 | * Since: 1.10 |
|
926 | **/ |
1276 | **/ |
927 | cairo_status_t |
1277 | cairo_status_t |
928 | cairo_surface_set_mime_data (cairo_surface_t *surface, |
1278 | cairo_surface_set_mime_data (cairo_surface_t *surface, |
929 | const char *mime_type, |
1279 | const char *mime_type, |
930 | const unsigned char *data, |
1280 | const unsigned char *data, |
Line 933... | Line 1283... | ||
933 | void *closure) |
1283 | void *closure) |
934 | { |
1284 | { |
935 | cairo_status_t status; |
1285 | cairo_status_t status; |
936 | cairo_mime_data_t *mime_data; |
1286 | cairo_mime_data_t *mime_data; |
Line -... | Line 1287... | ||
- | 1287 | ||
- | 1288 | if (CAIRO_REFERENCE_COUNT_IS_INVALID (&surface->ref_count)) |
|
- | 1289 | return surface->status; |
|
- | 1290 | ||
- | 1291 | if (! CAIRO_REFERENCE_COUNT_HAS_REFERENCE (&surface->ref_count)) |
|
- | 1292 | return _cairo_error (CAIRO_STATUS_SURFACE_FINISHED); |
|
937 | 1293 | ||
938 | if (unlikely (surface->status)) |
1294 | if (unlikely (surface->status)) |
939 | return surface->status; |
1295 | return surface->status; |
940 | if (surface->finished) |
1296 | if (unlikely (surface->finished)) |
Line 941... | Line 1297... | ||
941 | return _cairo_surface_set_error (surface, _cairo_error (CAIRO_STATUS_SURFACE_FINISHED)); |
1297 | return _cairo_surface_set_error (surface, _cairo_error (CAIRO_STATUS_SURFACE_FINISHED)); |
942 | 1298 | ||
943 | status = _cairo_intern_string (&mime_type, -1); |
1299 | status = _cairo_intern_string (&mime_type, -1); |
Line 961... | Line 1317... | ||
961 | status = _cairo_user_data_array_set_data (&surface->mime_data, |
1317 | status = _cairo_user_data_array_set_data (&surface->mime_data, |
962 | (cairo_user_data_key_t *) mime_type, |
1318 | (cairo_user_data_key_t *) mime_type, |
963 | mime_data, |
1319 | mime_data, |
964 | _cairo_mime_data_destroy); |
1320 | _cairo_mime_data_destroy); |
965 | if (unlikely (status)) { |
1321 | if (unlikely (status)) { |
966 | if (mime_data != NULL) |
- | |
967 | free (mime_data); |
1322 | free (mime_data); |
Line 968... | Line 1323... | ||
968 | 1323 | ||
969 | return _cairo_surface_set_error (surface, status); |
1324 | return _cairo_surface_set_error (surface, status); |
Line 970... | Line 1325... | ||
970 | } |
1325 | } |
971 | 1326 | ||
972 | return CAIRO_STATUS_SUCCESS; |
1327 | return CAIRO_STATUS_SUCCESS; |
Line -... | Line 1328... | ||
- | 1328 | } |
|
- | 1329 | slim_hidden_def (cairo_surface_set_mime_data); |
|
- | 1330 | ||
- | 1331 | /** |
|
- | 1332 | * cairo_surface_supports_mime_type: |
|
- | 1333 | * @surface: a #cairo_surface_t |
|
- | 1334 | * @mime_type: the mime type |
|
- | 1335 | * |
|
- | 1336 | * Return whether @surface supports @mime_type. |
|
- | 1337 | * |
|
- | 1338 | * Return value: %TRUE if @surface supports |
|
- | 1339 | * @mime_type, %FALSE otherwise |
|
- | 1340 | * |
|
- | 1341 | * Since: 1.12 |
|
- | 1342 | **/ |
|
- | 1343 | cairo_bool_t |
|
- | 1344 | cairo_surface_supports_mime_type (cairo_surface_t *surface, |
|
- | 1345 | const char *mime_type) |
|
- | 1346 | { |
|
- | 1347 | const char **types; |
|
- | 1348 | ||
- | 1349 | if (unlikely (surface->status)) |
|
- | 1350 | return FALSE; |
|
- | 1351 | if (unlikely (surface->finished)) { |
|
- | 1352 | _cairo_surface_set_error (surface, _cairo_error (CAIRO_STATUS_SURFACE_FINISHED)); |
|
- | 1353 | return FALSE; |
|
- | 1354 | } |
|
- | 1355 | ||
- | 1356 | if (surface->backend->get_supported_mime_types) { |
|
- | 1357 | types = surface->backend->get_supported_mime_types (surface); |
|
- | 1358 | if (types) { |
|
- | 1359 | while (*types) { |
|
- | 1360 | if (strcmp (*types, mime_type) == 0) |
|
- | 1361 | return TRUE; |
|
- | 1362 | types++; |
|
- | 1363 | } |
|
- | 1364 | } |
|
- | 1365 | } |
|
- | 1366 | ||
- | 1367 | return FALSE; |
|
973 | } |
1368 | } |
974 | slim_hidden_def (cairo_surface_set_mime_data); |
1369 | slim_hidden_def (cairo_surface_supports_mime_type); |
975 | 1370 | ||
976 | static void |
1371 | static void |
Line 1023... | Line 1418... | ||
1023 | **/ |
1418 | **/ |
1024 | void |
1419 | void |
1025 | _cairo_surface_set_font_options (cairo_surface_t *surface, |
1420 | _cairo_surface_set_font_options (cairo_surface_t *surface, |
1026 | cairo_font_options_t *options) |
1421 | cairo_font_options_t *options) |
1027 | { |
1422 | { |
1028 | cairo_status_t status; |
- | |
1029 | - | ||
1030 | if (surface->status) |
1423 | if (surface->status) |
1031 | return; |
1424 | return; |
Line 1032... | Line 1425... | ||
1032 | 1425 | ||
Line 1033... | Line 1426... | ||
1033 | assert (surface->snapshot_of == NULL); |
1426 | assert (surface->snapshot_of == NULL); |
1034 | - | ||
1035 | if (surface->finished) { |
1427 | |
1036 | status = _cairo_surface_set_error (surface, |
1428 | if (surface->finished) { |
1037 | _cairo_error (CAIRO_STATUS_SURFACE_FINISHED)); |
1429 | _cairo_surface_set_error (surface, _cairo_error (CAIRO_STATUS_SURFACE_FINISHED)); |
Line 1038... | Line 1430... | ||
1038 | return; |
1430 | return; |
1039 | } |
1431 | } |
Line 1055... | Line 1447... | ||
1055 | * Retrieves the default font rendering options for the surface. |
1447 | * Retrieves the default font rendering options for the surface. |
1056 | * This allows display surfaces to report the correct subpixel order |
1448 | * This allows display surfaces to report the correct subpixel order |
1057 | * for rendering on them, print surfaces to disable hinting of |
1449 | * for rendering on them, print surfaces to disable hinting of |
1058 | * metrics and so forth. The result can then be used with |
1450 | * metrics and so forth. The result can then be used with |
1059 | * cairo_scaled_font_create(). |
1451 | * cairo_scaled_font_create(). |
- | 1452 | * |
|
- | 1453 | * Since: 1.0 |
|
1060 | **/ |
1454 | **/ |
1061 | void |
1455 | void |
1062 | cairo_surface_get_font_options (cairo_surface_t *surface, |
1456 | cairo_surface_get_font_options (cairo_surface_t *surface, |
1063 | cairo_font_options_t *options) |
1457 | cairo_font_options_t *options) |
1064 | { |
1458 | { |
Line 1082... | Line 1476... | ||
1082 | 1476 | ||
1083 | _cairo_font_options_init_copy (options, &surface->font_options); |
1477 | _cairo_font_options_init_copy (options, &surface->font_options); |
1084 | } |
1478 | } |
Line -... | Line 1479... | ||
- | 1479 | slim_hidden_def (cairo_surface_get_font_options); |
|
- | 1480 | ||
- | 1481 | cairo_status_t |
|
- | 1482 | _cairo_surface_flush (cairo_surface_t *surface, unsigned flags) |
|
- | 1483 | { |
|
- | 1484 | /* update the current snapshots *before* the user updates the surface */ |
|
- | 1485 | _cairo_surface_detach_snapshots (surface); |
|
- | 1486 | if (surface->snapshot_of != NULL) |
|
- | 1487 | _cairo_surface_detach_snapshot (surface); |
|
- | 1488 | _cairo_surface_detach_mime_data (surface); |
|
- | 1489 | ||
- | 1490 | return __cairo_surface_flush (surface, flags); |
|
1085 | slim_hidden_def (cairo_surface_get_font_options); |
1491 | } |
1086 | 1492 | ||
1087 | /** |
1493 | /** |
1088 | * cairo_surface_flush: |
1494 | * cairo_surface_flush: |
1089 | * @surface: a #cairo_surface_t |
1495 | * @surface: a #cairo_surface_t |
1090 | * |
1496 | * |
1091 | * Do any pending drawing for the surface and also restore any |
1497 | * Do any pending drawing for the surface and also restore any |
1092 | * temporary modifications cairo has made to the surface's |
1498 | * temporary modifications cairo has made to the surface's |
1093 | * state. This function must be called before switching from |
1499 | * state. This function must be called before switching from |
1094 | * drawing on the surface with cairo to drawing on it directly |
1500 | * drawing on the surface with cairo to drawing on it directly |
- | 1501 | * with native APIs. If the surface doesn't support direct access, |
|
- | 1502 | * then this function does nothing. |
|
1095 | * with native APIs. If the surface doesn't support direct access, |
1503 | * |
1096 | * then this function does nothing. |
1504 | * Since: 1.0 |
1097 | **/ |
1505 | **/ |
1098 | void |
1506 | void |
1099 | cairo_surface_flush (cairo_surface_t *surface) |
1507 | cairo_surface_flush (cairo_surface_t *surface) |
Line 1104... | Line 1512... | ||
1104 | return; |
1512 | return; |
Line 1105... | Line 1513... | ||
1105 | 1513 | ||
1106 | if (surface->finished) |
1514 | if (surface->finished) |
Line 1107... | Line -... | ||
1107 | return; |
- | |
1108 | - | ||
1109 | /* update the current snapshots *before* the user updates the surface */ |
- | |
1110 | _cairo_surface_detach_snapshots (surface); |
- | |
1111 | 1515 | return; |
|
1112 | if (surface->backend->flush) { |
1516 | |
1113 | status = surface->backend->flush (surface); |
1517 | status = _cairo_surface_flush (surface, 0); |
1114 | if (unlikely (status)) |
- | |
1115 | status = _cairo_surface_set_error (surface, status); |
1518 | if (unlikely (status)) |
1116 | } |
1519 | _cairo_surface_set_error (surface, status); |
Line 1117... | Line 1520... | ||
1117 | } |
1520 | } |
1118 | slim_hidden_def (cairo_surface_flush); |
1521 | slim_hidden_def (cairo_surface_flush); |
1119 | 1522 | ||
1120 | /** |
1523 | /** |
1121 | * cairo_surface_mark_dirty: |
1524 | * cairo_surface_mark_dirty: |
1122 | * @surface: a #cairo_surface_t |
1525 | * @surface: a #cairo_surface_t |
1123 | * |
1526 | * |
- | 1527 | * Tells cairo that drawing has been done to surface using means other |
|
- | 1528 | * than cairo, and that cairo should reread any cached areas. Note |
|
1124 | * Tells cairo that drawing has been done to surface using means other |
1529 | * that you must call cairo_surface_flush() before doing such drawing. |
1125 | * than cairo, and that cairo should reread any cached areas. Note |
1530 | * |
1126 | * that you must call cairo_surface_flush() before doing such drawing. |
1531 | * Since: 1.0 |
1127 | */ |
1532 | **/ |
- | 1533 | void |
|
- | 1534 | cairo_surface_mark_dirty (cairo_surface_t *surface) |
|
- | 1535 | { |
|
- | 1536 | cairo_rectangle_int_t extents; |
|
- | 1537 | ||
- | 1538 | if (unlikely (surface->status)) |
|
- | 1539 | return; |
|
- | 1540 | if (unlikely (surface->finished)) { |
|
- | 1541 | _cairo_surface_set_error (surface, _cairo_error (CAIRO_STATUS_SURFACE_FINISHED)); |
|
- | 1542 | return; |
|
1128 | void |
1543 | } |
- | 1544 | ||
- | 1545 | _cairo_surface_get_extents (surface, &extents); |
|
1129 | cairo_surface_mark_dirty (cairo_surface_t *surface) |
1546 | cairo_surface_mark_dirty_rectangle (surface, |
1130 | { |
1547 | extents.x, extents.y, |
Line 1131... | Line 1548... | ||
1131 | cairo_surface_mark_dirty_rectangle (surface, 0, 0, -1, -1); |
1548 | extents.width, extents.height); |
1132 | } |
1549 | } |
Line 1145... | Line 1562... | ||
1145 | * for other parts of the surface. |
1562 | * for other parts of the surface. |
1146 | * |
1563 | * |
1147 | * Any cached clip set on the surface will be reset by this function, |
1564 | * Any cached clip set on the surface will be reset by this function, |
1148 | * to make sure that future cairo calls have the clip set that they |
1565 | * to make sure that future cairo calls have the clip set that they |
1149 | * expect. |
1566 | * expect. |
- | 1567 | * |
|
- | 1568 | * Since: 1.0 |
|
1150 | */ |
1569 | **/ |
1151 | void |
1570 | void |
1152 | cairo_surface_mark_dirty_rectangle (cairo_surface_t *surface, |
1571 | cairo_surface_mark_dirty_rectangle (cairo_surface_t *surface, |
1153 | int x, |
1572 | int x, |
1154 | int y, |
1573 | int y, |
1155 | int width, |
1574 | int width, |
1156 | int height) |
1575 | int height) |
1157 | { |
1576 | { |
1158 | cairo_status_t status; |
1577 | cairo_status_t status; |
Line 1159... | Line 1578... | ||
1159 | 1578 | ||
1160 | if (surface->status) |
1579 | if (unlikely (surface->status)) |
Line 1161... | Line 1580... | ||
1161 | return; |
1580 | return; |
Line 1162... | Line 1581... | ||
1162 | 1581 | ||
1163 | assert (surface->snapshot_of == NULL); |
1582 | assert (surface->snapshot_of == NULL); |
1164 | 1583 | ||
1165 | if (surface->finished) { |
1584 | if (unlikely (surface->finished)) { |
Line 1166... | Line 1585... | ||
1166 | status = _cairo_surface_set_error (surface, _cairo_error (CAIRO_STATUS_SURFACE_FINISHED)); |
1585 | _cairo_surface_set_error (surface, _cairo_error (CAIRO_STATUS_SURFACE_FINISHED)); |
1167 | return; |
1586 | return; |
1168 | } |
1587 | } |
1169 | 1588 | ||
1170 | /* The application *should* have called cairo_surface_flush() before |
1589 | /* The application *should* have called cairo_surface_flush() before |
Line 1171... | Line 1590... | ||
1171 | * modifying the surface independently of cairo (and thus having to |
1590 | * modifying the surface independently of cairo (and thus having to |
- | 1591 | * call mark_dirty()). */ |
|
- | 1592 | assert (! _cairo_surface_has_snapshots (surface)); |
|
- | 1593 | assert (! _cairo_surface_has_mime_data (surface)); |
|
- | 1594 | ||
- | 1595 | surface->is_clear = FALSE; |
|
- | 1596 | surface->serial++; |
|
- | 1597 | ||
- | 1598 | if (surface->damage) { |
|
- | 1599 | cairo_box_t box; |
|
- | 1600 | ||
- | 1601 | box.p1.x = x; |
|
- | 1602 | box.p1.y = y; |
|
Line 1172... | Line 1603... | ||
1172 | * call mark_dirty()). */ |
1603 | box.p2.x = x + width; |
1173 | assert (! _cairo_surface_has_snapshots (surface)); |
1604 | box.p2.y = y + height; |
1174 | assert (! _cairo_surface_has_mime_data (surface)); |
1605 | |
1175 | 1606 | surface->damage = _cairo_damage_add_box (surface->damage, &box); |
|
Line 1185... | Line 1616... | ||
1185 | x + surface->device_transform.x0, |
1616 | x + surface->device_transform.x0, |
1186 | y + surface->device_transform.y0, |
1617 | y + surface->device_transform.y0, |
1187 | width, height); |
1618 | width, height); |
Line 1188... | Line 1619... | ||
1188 | 1619 | ||
1189 | if (unlikely (status)) |
1620 | if (unlikely (status)) |
1190 | status = _cairo_surface_set_error (surface, status); |
1621 | _cairo_surface_set_error (surface, status); |
1191 | } |
1622 | } |
1192 | } |
1623 | } |
Line 1193... | Line 1624... | ||
1193 | slim_hidden_def (cairo_surface_mark_dirty_rectangle); |
1624 | slim_hidden_def (cairo_surface_mark_dirty_rectangle); |
Line 1214... | Line 1645... | ||
1214 | double sx, |
1645 | double sx, |
1215 | double sy) |
1646 | double sy) |
1216 | { |
1647 | { |
1217 | cairo_status_t status; |
1648 | cairo_status_t status; |
Line 1218... | Line 1649... | ||
1218 | 1649 | ||
1219 | if (surface->status) |
1650 | if (unlikely (surface->status)) |
Line 1220... | Line 1651... | ||
1220 | return; |
1651 | return; |
Line 1221... | Line 1652... | ||
1221 | 1652 | ||
1222 | assert (surface->snapshot_of == NULL); |
1653 | assert (surface->snapshot_of == NULL); |
1223 | 1654 | ||
1224 | if (surface->finished) { |
1655 | if (unlikely (surface->finished)) { |
Line 1225... | Line 1656... | ||
1225 | status = _cairo_surface_set_error (surface, _cairo_error (CAIRO_STATUS_SURFACE_FINISHED)); |
1656 | _cairo_surface_set_error (surface, _cairo_error (CAIRO_STATUS_SURFACE_FINISHED)); |
- | 1657 | return; |
|
- | 1658 | } |
|
- | 1659 | ||
- | 1660 | status = _cairo_surface_begin_modification (surface); |
|
Line 1226... | Line 1661... | ||
1226 | return; |
1661 | if (unlikely (status)) { |
1227 | } |
1662 | _cairo_surface_set_error (surface, status); |
1228 | 1663 | return; |
|
1229 | _cairo_surface_begin_modification (surface); |
1664 | } |
Line 1256... | Line 1691... | ||
1256 | * sufficient to do this, since functions like |
1691 | * sufficient to do this, since functions like |
1257 | * cairo_device_to_user() will expose the hidden offset. |
1692 | * cairo_device_to_user() will expose the hidden offset. |
1258 | * |
1693 | * |
1259 | * Note that the offset affects drawing to the surface as well as |
1694 | * Note that the offset affects drawing to the surface as well as |
1260 | * using the surface in a source pattern. |
1695 | * using the surface in a source pattern. |
- | 1696 | * |
|
- | 1697 | * Since: 1.0 |
|
1261 | **/ |
1698 | **/ |
1262 | void |
1699 | void |
1263 | cairo_surface_set_device_offset (cairo_surface_t *surface, |
1700 | cairo_surface_set_device_offset (cairo_surface_t *surface, |
1264 | double x_offset, |
1701 | double x_offset, |
1265 | double y_offset) |
1702 | double y_offset) |
1266 | { |
1703 | { |
1267 | cairo_status_t status; |
1704 | cairo_status_t status; |
Line 1268... | Line 1705... | ||
1268 | 1705 | ||
1269 | if (surface->status) |
1706 | if (unlikely (surface->status)) |
Line 1270... | Line 1707... | ||
1270 | return; |
1707 | return; |
Line 1271... | Line 1708... | ||
1271 | 1708 | ||
1272 | assert (surface->snapshot_of == NULL); |
1709 | assert (surface->snapshot_of == NULL); |
1273 | 1710 | ||
1274 | if (surface->finished) { |
1711 | if (unlikely (surface->finished)) { |
Line 1275... | Line 1712... | ||
1275 | status = _cairo_surface_set_error (surface, _cairo_error (CAIRO_STATUS_SURFACE_FINISHED)); |
1712 | _cairo_surface_set_error (surface, _cairo_error (CAIRO_STATUS_SURFACE_FINISHED)); |
- | 1713 | return; |
|
- | 1714 | } |
|
- | 1715 | ||
- | 1716 | status = _cairo_surface_begin_modification (surface); |
|
Line 1276... | Line 1717... | ||
1276 | return; |
1717 | if (unlikely (status)) { |
1277 | } |
1718 | _cairo_surface_set_error (surface, status); |
Line 1278... | Line 1719... | ||
1278 | 1719 | return; |
|
Line 1351... | Line 1792... | ||
1351 | double x_pixels_per_inch, |
1792 | double x_pixels_per_inch, |
1352 | double y_pixels_per_inch) |
1793 | double y_pixels_per_inch) |
1353 | { |
1794 | { |
1354 | cairo_status_t status; |
1795 | cairo_status_t status; |
Line 1355... | Line 1796... | ||
1355 | 1796 | ||
1356 | if (surface->status) |
1797 | if (unlikely (surface->status)) |
Line 1357... | Line 1798... | ||
1357 | return; |
1798 | return; |
Line 1358... | Line 1799... | ||
1358 | 1799 | ||
1359 | assert (surface->snapshot_of == NULL); |
1800 | assert (surface->snapshot_of == NULL); |
1360 | 1801 | ||
1361 | if (surface->finished) { |
1802 | if (unlikely (surface->finished)) { |
Line 1362... | Line 1803... | ||
1362 | status = _cairo_surface_set_error (surface, _cairo_error (CAIRO_STATUS_SURFACE_FINISHED)); |
1803 | _cairo_surface_set_error (surface, _cairo_error (CAIRO_STATUS_SURFACE_FINISHED)); |
1363 | return; |
1804 | return; |
1364 | } |
1805 | } |
1365 | 1806 | ||
1366 | if (x_pixels_per_inch <= 0 || y_pixels_per_inch <= 0) { |
1807 | if (x_pixels_per_inch <= 0 || y_pixels_per_inch <= 0) { |
1367 | /* XXX Could delay raising the error until we fallback, but throwing |
1808 | /* XXX Could delay raising the error until we fallback, but throwing |
1368 | * the error here means that we can catch the real culprit. |
1809 | * the error here means that we can catch the real culprit. |
Line 1369... | Line 1810... | ||
1369 | */ |
1810 | */ |
- | 1811 | _cairo_surface_set_error (surface, CAIRO_STATUS_INVALID_MATRIX); |
|
- | 1812 | return; |
|
- | 1813 | } |
|
- | 1814 | ||
Line 1370... | Line 1815... | ||
1370 | status = _cairo_surface_set_error (surface, CAIRO_STATUS_INVALID_MATRIX); |
1815 | status = _cairo_surface_begin_modification (surface); |
1371 | return; |
1816 | if (unlikely (status)) { |
1372 | } |
1817 | _cairo_surface_set_error (surface, status); |
1373 | 1818 | return; |
|
Line 1429... | Line 1874... | ||
1429 | cairo_image_surface_t **image_out, |
1874 | cairo_image_surface_t **image_out, |
1430 | void **image_extra) |
1875 | void **image_extra) |
1431 | { |
1876 | { |
1432 | cairo_status_t status; |
1877 | cairo_status_t status; |
Line 1433... | Line 1878... | ||
1433 | 1878 | ||
1434 | if (surface->status) |
1879 | if (unlikely (surface->status)) |
Line 1435... | Line 1880... | ||
1435 | return surface->status; |
1880 | return surface->status; |
Line 1436... | Line 1881... | ||
1436 | 1881 | ||
Line 1447... | Line 1892... | ||
1447 | _cairo_debug_check_image_surface_is_defined (&(*image_out)->base); |
1892 | _cairo_debug_check_image_surface_is_defined (&(*image_out)->base); |
Line 1448... | Line 1893... | ||
1448 | 1893 | ||
1449 | return CAIRO_STATUS_SUCCESS; |
1894 | return CAIRO_STATUS_SUCCESS; |
Line -... | Line 1895... | ||
- | 1895 | } |
|
- | 1896 | ||
- | 1897 | cairo_status_t |
|
- | 1898 | _cairo_surface_default_acquire_source_image (void *_surface, |
|
- | 1899 | cairo_image_surface_t **image_out, |
|
- | 1900 | void **image_extra) |
|
- | 1901 | { |
|
- | 1902 | cairo_surface_t *surface = _surface; |
|
- | 1903 | cairo_rectangle_int_t extents; |
|
- | 1904 | ||
- | 1905 | if (unlikely (! surface->backend->get_extents (surface, &extents))) |
|
- | 1906 | return _cairo_error (CAIRO_STATUS_INVALID_SIZE); |
|
- | 1907 | ||
- | 1908 | *image_out = _cairo_surface_map_to_image (surface, &extents); |
|
- | 1909 | *image_extra = NULL; |
|
- | 1910 | return (*image_out)->base.status; |
|
1450 | } |
1911 | } |
1451 | 1912 | ||
1452 | /** |
1913 | /** |
1453 | * _cairo_surface_release_source_image: |
1914 | * _cairo_surface_release_source_image: |
1454 | * @surface: a #cairo_surface_t |
1915 | * @surface: a #cairo_surface_t |
Line 1465... | Line 1926... | ||
1465 | 1926 | ||
1466 | if (surface->backend->release_source_image) |
1927 | if (surface->backend->release_source_image) |
1467 | surface->backend->release_source_image (surface, image, image_extra); |
1928 | surface->backend->release_source_image (surface, image, image_extra); |
Line 1468... | Line -... | ||
1468 | } |
- | |
1469 | - | ||
1470 | /** |
- | |
1471 | * _cairo_surface_acquire_dest_image: |
- | |
1472 | * @surface: a #cairo_surface_t |
- | |
1473 | * @interest_rect: area of @surface for which fallback drawing is being done. |
- | |
1474 | * A value of %NULL indicates that the entire surface is desired. |
- | |
1475 | * XXXX I'd like to get rid of being able to pass %NULL here (nothing seems to) |
- | |
1476 | * @image_out: location to store a pointer to an image surface that includes at least |
- | |
1477 | * the intersection of @interest_rect with the visible area of @surface. |
- | |
1478 | * This surface could be @surface itself, a surface held internal to @surface, |
- | |
1479 | * or it could be a new surface with a copy of the relevant portion of @surface. |
- | |
1480 | * If a new surface is created, it should have the same channels and depth |
- | |
1481 | * as @surface so that copying to and from it is exact. |
- | |
1482 | * @image_rect: location to store area of the original surface occupied |
- | |
1483 | * by the surface stored in @image. |
- | |
1484 | * @image_extra: location to store image specific backend data |
- | |
1485 | * |
- | |
1486 | * Retrieves a local image for a surface for implementing a fallback drawing |
- | |
1487 | * operation. After calling this function, the implementation of the fallback |
- | |
1488 | * drawing operation draws the primitive to the surface stored in @image_out |
- | |
1489 | * then calls _cairo_surface_release_dest_image(), |
- | |
1490 | * which, if a temporary surface was created, copies the bits back to the |
- | |
1491 | * main surface and frees the temporary surface. |
- | |
1492 | * |
- | |
1493 | * Return value: %CAIRO_STATUS_SUCCESS or %CAIRO_STATUS_NO_MEMORY. |
- | |
1494 | * %CAIRO_INT_STATUS_UNSUPPORTED can be returned but this will mean that |
- | |
1495 | * the backend can't draw with fallbacks. It's possible for the routine |
- | |
1496 | * to store %NULL in @local_out and return %CAIRO_STATUS_SUCCESS; |
- | |
1497 | * that indicates that no part of @interest_rect is visible, so no drawing |
- | |
1498 | * is necessary. _cairo_surface_release_dest_image() should not be called in that |
- | |
1499 | * case. |
- | |
1500 | **/ |
- | |
1501 | cairo_status_t |
- | |
1502 | _cairo_surface_acquire_dest_image (cairo_surface_t *surface, |
- | |
1503 | cairo_rectangle_int_t *interest_rect, |
- | |
1504 | cairo_image_surface_t **image_out, |
- | |
1505 | cairo_rectangle_int_t *image_rect, |
- | |
1506 | void **image_extra) |
- | |
1507 | { |
- | |
1508 | cairo_status_t status; |
- | |
1509 | - | ||
1510 | if (surface->status) |
- | |
1511 | return surface->status; |
- | |
1512 | - | ||
1513 | assert (_cairo_surface_is_writable (surface)); |
- | |
1514 | - | ||
1515 | if (surface->backend->acquire_dest_image == NULL) |
- | |
1516 | return CAIRO_INT_STATUS_UNSUPPORTED; |
- | |
1517 | - | ||
1518 | status = surface->backend->acquire_dest_image (surface, |
- | |
1519 | interest_rect, |
- | |
1520 | image_out, |
- | |
1521 | image_rect, |
- | |
1522 | image_extra); |
- | |
1523 | if (unlikely (status)) |
- | |
1524 | return _cairo_surface_set_error (surface, status); |
- | |
1525 | - | ||
1526 | _cairo_debug_check_image_surface_is_defined (&(*image_out)->base); |
- | |
1527 | - | ||
1528 | return CAIRO_STATUS_SUCCESS; |
- | |
1529 | } |
- | |
1530 | - | ||
1531 | /** |
- | |
1532 | * _cairo_surface_release_dest_image: |
- | |
1533 | * @surface: a #cairo_surface_t |
- | |
1534 | * @interest_rect: same as passed to the matching _cairo_surface_acquire_dest_image() |
- | |
1535 | * @image: same as returned from the matching _cairo_surface_acquire_dest_image() |
- | |
1536 | * @image_rect: same as returned from the matching _cairo_surface_acquire_dest_image() |
- | |
1537 | * @image_extra: same as return from the matching _cairo_surface_acquire_dest_image() |
- | |
1538 | * |
- | |
1539 | * Finishes the operation started with _cairo_surface_acquire_dest_image(), by, if |
- | |
1540 | * necessary, copying the image from @image back to @surface and freeing any |
- | |
1541 | * resources that were allocated. |
1929 | } |
1542 | **/ |
1930 | |
1543 | void |
- | |
1544 | _cairo_surface_release_dest_image (cairo_surface_t *surface, |
1931 | void |
1545 | cairo_rectangle_int_t *interest_rect, |
- | |
1546 | cairo_image_surface_t *image, |
1932 | _cairo_surface_default_release_source_image (void *surface, |
1547 | cairo_rectangle_int_t *image_rect, |
1933 | cairo_image_surface_t *image, |
1548 | void *image_extra) |
- | |
1549 | { |
- | |
1550 | assert (_cairo_surface_is_writable (surface)); |
- | |
1551 | - | ||
1552 | if (surface->backend->release_dest_image) |
- | |
1553 | surface->backend->release_dest_image (surface, interest_rect, |
- | |
1554 | image, image_rect, image_extra); |
- | |
1555 | } |
- | |
1556 | - | ||
1557 | static cairo_status_t |
- | |
1558 | _cairo_recording_surface_clone_similar (cairo_surface_t *surface, |
- | |
1559 | cairo_surface_t *src, |
- | |
1560 | int src_x, |
- | |
1561 | int src_y, |
- | |
1562 | int width, |
- | |
1563 | int height, |
- | |
1564 | int *clone_offset_x, |
- | |
1565 | int *clone_offset_y, |
- | |
1566 | cairo_surface_t **clone_out) |
- | |
1567 | { |
- | |
1568 | cairo_recording_surface_t *recorder = (cairo_recording_surface_t *) src; |
1934 | void *image_extra) |
1569 | cairo_surface_t *similar; |
- | |
1570 | cairo_status_t status; |
- | |
1571 | - | ||
1572 | similar = _cairo_surface_has_snapshot (src, surface->backend); |
- | |
1573 | if (similar != NULL) { |
- | |
1574 | *clone_out = cairo_surface_reference (similar); |
- | |
1575 | *clone_offset_x = 0; |
- | |
1576 | *clone_offset_y = 0; |
- | |
1577 | return CAIRO_STATUS_SUCCESS; |
- | |
1578 | } |
- | |
1579 | - | ||
1580 | if (recorder->unbounded || |
- | |
1581 | width*height*8 < recorder->extents.width*recorder->extents.height) |
- | |
1582 | { |
- | |
1583 | similar = _cairo_surface_create_similar_solid (surface, |
- | |
1584 | src->content, |
- | |
1585 | width, height, |
- | |
1586 | CAIRO_COLOR_TRANSPARENT, |
- | |
1587 | FALSE); |
- | |
1588 | if (similar == NULL) |
- | |
1589 | return CAIRO_INT_STATUS_UNSUPPORTED; |
- | |
1590 | if (unlikely (similar->status)) |
- | |
1591 | return similar->status; |
- | |
1592 | - | ||
1593 | cairo_surface_set_device_offset (similar, -src_x, -src_y); |
- | |
1594 | - | ||
1595 | status = _cairo_recording_surface_replay (src, similar); |
- | |
1596 | if (unlikely (status)) { |
- | |
1597 | cairo_surface_destroy (similar); |
- | |
1598 | return status; |
- | |
1599 | } |
- | |
1600 | } else { |
- | |
1601 | similar = _cairo_surface_create_similar_scratch (surface, |
- | |
1602 | src->content, |
- | |
1603 | recorder->extents.width, |
- | |
1604 | recorder->extents.height); |
- | |
1605 | if (similar == NULL) |
- | |
1606 | return CAIRO_INT_STATUS_UNSUPPORTED; |
- | |
1607 | if (unlikely (similar->status)) |
- | |
1608 | return similar->status; |
- | |
1609 | - | ||
1610 | status = _cairo_recording_surface_replay (src, similar); |
- | |
1611 | if (unlikely (status)) { |
- | |
1612 | cairo_surface_destroy (similar); |
- | |
1613 | return status; |
- | |
1614 | } |
- | |
1615 | - | ||
1616 | _cairo_surface_attach_snapshot (src, similar, NULL); |
- | |
1617 | - | ||
1618 | src_x = src_y = 0; |
- | |
1619 | } |
- | |
1620 | - | ||
1621 | *clone_out = similar; |
- | |
1622 | *clone_offset_x = src_x; |
- | |
1623 | *clone_offset_y = src_y; |
- | |
1624 | return CAIRO_STATUS_SUCCESS; |
- | |
1625 | } |
- | |
1626 | - | ||
1627 | /** |
- | |
1628 | * _cairo_surface_clone_similar: |
- | |
1629 | * @surface: a #cairo_surface_t |
- | |
1630 | * @src: the source image |
- | |
1631 | * @content: target content mask |
- | |
1632 | * @src_x: extent for the rectangle in src we actually care about |
- | |
1633 | * @src_y: extent for the rectangle in src we actually care about |
- | |
1634 | * @width: extent for the rectangle in src we actually care about |
- | |
1635 | * @height: extent for the rectangle in src we actually care about |
- | |
1636 | * @clone_out: location to store a surface compatible with @surface |
- | |
1637 | * and with contents identical to @src. The caller must call |
- | |
1638 | * cairo_surface_destroy() on the result. |
- | |
1639 | * |
- | |
1640 | * Creates a surface with contents identical to @src but that |
- | |
1641 | * can be used efficiently with @surface. If @surface and @src are |
- | |
1642 | * already compatible then it may return a new reference to @src. |
- | |
1643 | * |
- | |
1644 | * Return value: %CAIRO_STATUS_SUCCESS if a surface was created and stored |
- | |
1645 | * in @clone_out. Otherwise %CAIRO_INT_STATUS_UNSUPPORTED or another |
- | |
1646 | * error like %CAIRO_STATUS_NO_MEMORY. |
- | |
1647 | **/ |
- | |
1648 | cairo_status_t |
- | |
1649 | _cairo_surface_clone_similar (cairo_surface_t *surface, |
- | |
1650 | cairo_surface_t *src, |
- | |
1651 | int src_x, |
- | |
1652 | int src_y, |
- | |
1653 | int width, |
- | |
1654 | int height, |
- | |
1655 | int *clone_offset_x, |
- | |
1656 | int *clone_offset_y, |
- | |
1657 | cairo_surface_t **clone_out) |
- | |
1658 | { |
- | |
1659 | cairo_status_t status = CAIRO_INT_STATUS_UNSUPPORTED; |
- | |
1660 | cairo_image_surface_t *image; |
- | |
1661 | void *image_extra; |
- | |
1662 | - | ||
1663 | if (unlikely (surface->status)) |
- | |
1664 | return surface->status; |
- | |
1665 | - | ||
1666 | if (unlikely (surface->finished)) |
- | |
1667 | return _cairo_error (CAIRO_STATUS_SURFACE_FINISHED); |
- | |
1668 | - | ||
1669 | #if CAIRO_HAS_TEE_SURFACE |
- | |
1670 | - | ||
1671 | if (src->type == CAIRO_SURFACE_TYPE_TEE) { |
- | |
1672 | cairo_surface_t *match; |
- | |
1673 | - | ||
1674 | match = _cairo_tee_surface_find_match (src, |
- | |
1675 | surface->backend, |
- | |
1676 | src->content); |
- | |
1677 | if (match != NULL) |
- | |
1678 | src = match; |
- | |
1679 | } |
- | |
1680 | - | ||
1681 | #endif |
- | |
1682 | - | ||
1683 | if (surface->backend->clone_similar != NULL) { |
- | |
1684 | status = surface->backend->clone_similar (surface, src, |
- | |
1685 | src_x, src_y, |
- | |
1686 | width, height, |
- | |
1687 | clone_offset_x, |
- | |
1688 | clone_offset_y, |
- | |
1689 | clone_out); |
- | |
1690 | if (status == CAIRO_INT_STATUS_UNSUPPORTED) { |
- | |
1691 | if (_cairo_surface_is_image (src)) |
- | |
1692 | return CAIRO_INT_STATUS_UNSUPPORTED; |
- | |
1693 | - | ||
1694 | /* First check to see if we can replay to a similar surface */ |
- | |
1695 | if (_cairo_surface_is_recording (src)) { |
- | |
1696 | return _cairo_recording_surface_clone_similar (surface, src, |
- | |
1697 | src_x, src_y, |
- | |
1698 | width, height, |
- | |
1699 | clone_offset_x, |
- | |
1700 | clone_offset_y, |
- | |
1701 | clone_out); |
- | |
1702 | } |
- | |
1703 | - | ||
1704 | /* If we failed, try again with an image surface */ |
- | |
1705 | status = _cairo_surface_acquire_source_image (src, &image, &image_extra); |
- | |
1706 | if (status == CAIRO_STATUS_SUCCESS) { |
- | |
1707 | status = |
- | |
1708 | surface->backend->clone_similar (surface, &image->base, |
- | |
1709 | src_x, src_y, |
- | |
1710 | width, height, |
- | |
1711 | clone_offset_x, |
- | |
1712 | clone_offset_y, |
- | |
1713 | clone_out); |
- | |
1714 | - | ||
1715 | _cairo_surface_release_source_image (src, image, image_extra); |
- | |
1716 | } |
- | |
1717 | } |
- | |
1718 | } |
- | |
1719 | - | ||
1720 | /* If we're still unsupported, hit our fallback path to get a clone */ |
- | |
1721 | if (status == CAIRO_INT_STATUS_UNSUPPORTED) { |
- | |
1722 | status = |
- | |
1723 | _cairo_surface_fallback_clone_similar (surface, src, |
- | |
1724 | src_x, src_y, |
- | |
1725 | width, height, |
- | |
1726 | clone_offset_x, |
- | |
1727 | clone_offset_y, |
- | |
1728 | clone_out); |
- | |
1729 | } |
- | |
1730 | - | ||
1731 | if (unlikely (status)) |
- | |
1732 | return status; |
- | |
1733 | - | ||
1734 | /* Update the clone's device_transform (which the underlying surface |
- | |
1735 | * backend knows nothing about) */ |
- | |
1736 | if (*clone_out != src) { |
- | |
1737 | (*clone_out)->device_transform = src->device_transform; |
- | |
1738 | (*clone_out)->device_transform_inverse = src->device_transform_inverse; |
- | |
1739 | } |
- | |
1740 | - | ||
1741 | return status; |
- | |
1742 | } |
- | |
1743 | - | ||
1744 | /** |
- | |
1745 | * _cairo_surface_is_similar |
- | |
1746 | * @surface_a: a #cairo_surface_t |
- | |
1747 | * @surface_b: a #cairo_surface_t |
- | |
1748 | * @content: a #cairo_content_t |
- | |
1749 | * |
- | |
1750 | * Find out whether the given surfaces share the same backend, |
- | |
1751 | * and if so, whether they can be considered similar. |
- | |
1752 | * |
- | |
1753 | * The definition of "similar" depends on the backend. In |
- | |
1754 | * general, it means that the surface is equivalent to one |
- | |
1755 | * that would have been generated by a call to cairo_surface_create_similar(). |
- | |
1756 | * |
- | |
1757 | * Return value: %TRUE if the surfaces are similar. |
- | |
1758 | **/ |
- | |
1759 | cairo_bool_t |
- | |
1760 | _cairo_surface_is_similar (cairo_surface_t *surface_a, |
- | |
1761 | cairo_surface_t *surface_b) |
- | |
1762 | { |
- | |
1763 | if (surface_a->backend != surface_b->backend) |
- | |
1764 | return FALSE; |
- | |
1765 | - | ||
1766 | if (surface_a->backend->is_similar != NULL) |
- | |
1767 | return surface_a->backend->is_similar (surface_a, surface_b); |
- | |
1768 | - | ||
1769 | return TRUE; |
- | |
1770 | } |
- | |
1771 | - | ||
1772 | cairo_status_t |
- | |
1773 | _cairo_surface_composite (cairo_operator_t op, |
- | |
1774 | const cairo_pattern_t *src, |
- | |
1775 | const cairo_pattern_t *mask, |
- | |
1776 | cairo_surface_t *dst, |
- | |
1777 | int src_x, |
- | |
1778 | int src_y, |
- | |
1779 | int mask_x, |
- | |
1780 | int mask_y, |
- | |
1781 | int dst_x, |
- | |
1782 | int dst_y, |
- | |
1783 | unsigned int width, |
- | |
1784 | unsigned int height, |
- | |
1785 | cairo_region_t *clip_region) |
- | |
1786 | { |
- | |
1787 | cairo_int_status_t status; |
- | |
1788 | - | ||
1789 | if (unlikely (dst->status)) |
- | |
1790 | return dst->status; |
- | |
1791 | - | ||
1792 | assert (_cairo_surface_is_writable (dst)); |
- | |
1793 | - | ||
1794 | if (mask) { |
- | |
1795 | /* These operators aren't interpreted the same way by the backends; |
- | |
1796 | * they are implemented in terms of other operators in cairo-gstate.c |
- | |
1797 | */ |
- | |
1798 | assert (op != CAIRO_OPERATOR_SOURCE && op != CAIRO_OPERATOR_CLEAR); |
- | |
1799 | } |
- | |
1800 | - | ||
1801 | if (dst->backend->composite) { |
- | |
1802 | status = dst->backend->composite (op, |
- | |
1803 | src, mask, dst, |
- | |
1804 | src_x, src_y, |
- | |
1805 | mask_x, mask_y, |
- | |
1806 | dst_x, dst_y, |
- | |
1807 | width, height, |
- | |
1808 | clip_region); |
- | |
1809 | if (status != CAIRO_INT_STATUS_UNSUPPORTED) |
- | |
1810 | return _cairo_surface_set_error (dst, status); |
- | |
1811 | } |
- | |
1812 | - | ||
1813 | return _cairo_surface_set_error (dst, |
- | |
1814 | _cairo_surface_fallback_composite (op, |
- | |
1815 | src, mask, dst, |
- | |
1816 | src_x, src_y, |
- | |
1817 | mask_x, mask_y, |
- | |
1818 | dst_x, dst_y, |
- | |
1819 | width, height, |
- | |
1820 | clip_region)); |
- | |
1821 | } |
- | |
1822 | - | ||
1823 | /** |
- | |
1824 | * _cairo_surface_fill_rectangle: |
- | |
1825 | * @surface: a #cairo_surface_t |
- | |
1826 | * @op: the operator to apply to the rectangle |
- | |
1827 | * @color: the source color |
- | |
1828 | * @x: X coordinate of rectangle, in backend coordinates |
- | |
1829 | * @y: Y coordinate of rectangle, in backend coordinates |
- | |
1830 | * @width: width of rectangle, in backend coordinates |
- | |
1831 | * @height: height of rectangle, in backend coordinates |
- | |
1832 | * |
- | |
1833 | * Applies an operator to a rectangle using a solid color as the source. |
- | |
1834 | * See _cairo_surface_fill_rectangles() for full details. |
- | |
1835 | * |
- | |
1836 | * Return value: %CAIRO_STATUS_SUCCESS or the error that occurred |
- | |
1837 | **/ |
- | |
1838 | cairo_status_t |
- | |
1839 | _cairo_surface_fill_rectangle (cairo_surface_t *surface, |
- | |
1840 | cairo_operator_t op, |
- | |
1841 | const cairo_color_t *color, |
- | |
1842 | int x, |
- | |
1843 | int y, |
- | |
1844 | int width, |
- | |
1845 | int height) |
- | |
1846 | { |
- | |
1847 | cairo_rectangle_int_t rect; |
- | |
1848 | - | ||
1849 | if (surface->status) |
- | |
1850 | return surface->status; |
- | |
1851 | - | ||
1852 | assert (_cairo_surface_is_writable (surface)); |
- | |
1853 | - | ||
1854 | rect.x = x; |
- | |
1855 | rect.y = y; |
- | |
Line 1856... | Line 1935... | ||
1856 | rect.width = width; |
1935 | { |
- | 1936 | cairo_status_t ignored; |
|
1857 | rect.height = height; |
1937 | |
Line 1858... | Line -... | ||
1858 | - | ||
1859 | return _cairo_surface_fill_rectangles (surface, op, color, &rect, 1); |
- | |
1860 | } |
- | |
1861 | - | ||
1862 | /** |
- | |
1863 | * _cairo_surface_fill_region: |
- | |
1864 | * @surface: a #cairo_surface_t |
- | |
1865 | * @op: the operator to apply to the region |
- | |
1866 | * @color: the source color |
- | |
1867 | * @region: the region to modify, in backend coordinates |
- | |
1868 | * |
- | |
1869 | * Applies an operator to a set of rectangles specified as a |
- | |
1870 | * #cairo_region_t using a solid color as the source. |
- | |
1871 | * See _cairo_surface_fill_rectangles() for full details. |
- | |
1872 | * |
- | |
1873 | * Return value: %CAIRO_STATUS_SUCCESS or the error that occurred |
- | |
1874 | **/ |
- | |
1875 | cairo_status_t |
- | |
1876 | _cairo_surface_fill_region (cairo_surface_t *surface, |
- | |
1877 | cairo_operator_t op, |
- | |
1878 | const cairo_color_t *color, |
- | |
1879 | cairo_region_t *region) |
- | |
1880 | { |
- | |
1881 | int num_rects; |
- | |
1882 | cairo_rectangle_int_t stack_rects[CAIRO_STACK_ARRAY_LENGTH (cairo_rectangle_int_t)]; |
- | |
1883 | cairo_rectangle_int_t *rects = stack_rects; |
- | |
1884 | cairo_status_t status; |
- | |
1885 | int i; |
- | |
1886 | - | ||
1887 | if (surface->status) |
- | |
1888 | return surface->status; |
- | |
1889 | - | ||
1890 | assert (_cairo_surface_is_writable (surface)); |
- | |
Line 1891... | Line 1938... | ||
1891 | 1938 | ignored = _cairo_surface_unmap_image (surface, image); |
|
1892 | num_rects = cairo_region_num_rectangles (region); |
1939 | (void)ignored; |
1893 | if (num_rects == 0) |
1940 | } |
1894 | return CAIRO_STATUS_SUCCESS; |
1941 | |
1895 | - | ||
1896 | /* catch a common reduction of _cairo_clip_combine_with_surface() */ |
- | |
1897 | if (op == CAIRO_OPERATOR_IN && |
- | |
1898 | _cairo_color_equal (color, CAIRO_COLOR_WHITE)) |
- | |
1899 | { |
- | |
1900 | return CAIRO_STATUS_SUCCESS; |
1942 | |
1901 | } |
- | |
1902 | 1943 | cairo_surface_t * |
|
1903 | if (num_rects > ARRAY_LENGTH (stack_rects)) { |
- | |
1904 | rects = _cairo_malloc_ab (num_rects, |
- | |
1905 | sizeof (cairo_rectangle_int_t)); |
1944 | _cairo_surface_get_source (cairo_surface_t *surface, |
Line 1906... | Line -... | ||
1906 | if (rects == NULL) { |
- | |
1907 | return _cairo_surface_set_error (surface, |
- | |
1908 | _cairo_error (CAIRO_STATUS_NO_MEMORY)); |
- | |
1909 | } |
- | |
1910 | } |
- | |
1911 | - | ||
1912 | for (i = 0; i < num_rects; i++) |
- | |
1913 | cairo_region_get_rectangle (region, i, &rects[i]); |
- | |
1914 | - | ||
1915 | status = _cairo_surface_fill_rectangles (surface, |
- | |
1916 | op, color, rects, num_rects); |
- | |
1917 | - | ||
1918 | if (rects != stack_rects) |
- | |
1919 | free (rects); |
- | |
1920 | - | ||
1921 | return _cairo_surface_set_error (surface, status); |
- | |
1922 | } |
- | |
1923 | - | ||
1924 | /** |
- | |
1925 | * _cairo_surface_fill_rectangles: |
- | |
1926 | * @surface: a #cairo_surface_t |
- | |
1927 | * @op: the operator to apply to the region |
- | |
1928 | * @color: the source color |
- | |
1929 | * @rects: the rectangles to modify, in backend coordinates |
- | |
1930 | * @num_rects: the number of rectangles in @rects |
- | |
1931 | * |
- | |
1932 | * Applies an operator to a set of rectangles using a solid color |
- | |
1933 | * as the source. Note that even if the operator is an unbounded operator |
- | |
1934 | * such as %CAIRO_OPERATOR_IN, only the given set of rectangles |
1945 | cairo_rectangle_int_t *extents) |
1935 | * is affected. This differs from _cairo_surface_composite_trapezoids() |
1946 | { |
1936 | * where the entire destination rectangle is cleared. |
- | |
1937 | * |
- | |
1938 | * Return value: %CAIRO_STATUS_SUCCESS or the error that occurred |
1947 | assert (surface->backend->source); |
1939 | **/ |
- | |
1940 | cairo_status_t |
1948 | return surface->backend->source (surface, extents); |
1941 | _cairo_surface_fill_rectangles (cairo_surface_t *surface, |
- | |
1942 | cairo_operator_t op, |
- | |
1943 | const cairo_color_t *color, |
- | |
1944 | cairo_rectangle_int_t *rects, |
- | |
1945 | int num_rects) |
- | |
1946 | { |
- | |
1947 | cairo_int_status_t status; |
- | |
1948 | 1949 | } |
|
1949 | if (surface->status) |
- | |
1950 | return surface->status; |
- | |
1951 | - | ||
1952 | assert (_cairo_surface_is_writable (surface)); |
- | |
1953 | - | ||
1954 | if (num_rects == 0) |
- | |
1955 | return CAIRO_STATUS_SUCCESS; |
- | |
1956 | 1950 | ||
1957 | if (surface->backend->fill_rectangles) { |
- | |
1958 | status = surface->backend->fill_rectangles (surface, |
- | |
1959 | op, color, |
- | |
1960 | rects, num_rects); |
- | |
1961 | if (status != CAIRO_INT_STATUS_UNSUPPORTED) |
- | |
1962 | return _cairo_surface_set_error (surface, status); |
1951 | cairo_surface_t * |
1963 | } |
1952 | _cairo_surface_default_source (void *surface, |
Line 1964... | Line 1953... | ||
1964 | 1953 | cairo_rectangle_int_t *extents) |
|
1965 | return _cairo_surface_set_error (surface, |
1954 | { |
1966 | _cairo_surface_fallback_fill_rectangles (surface, |
1955 | if (extents) |
Line 1987... | Line 1976... | ||
1987 | return _cairo_error (CAIRO_STATUS_SURFACE_FINISHED); |
1976 | return _cairo_error (CAIRO_STATUS_SURFACE_FINISHED); |
Line 1988... | Line 1977... | ||
1988 | 1977 | ||
1989 | return CAIRO_STATUS_SUCCESS; |
1978 | return CAIRO_STATUS_SUCCESS; |
Line -... | Line 1979... | ||
- | 1979 | } |
|
- | 1980 | ||
- | 1981 | static cairo_bool_t |
|
- | 1982 | nothing_to_do (cairo_surface_t *surface, |
|
- | 1983 | cairo_operator_t op, |
|
- | 1984 | const cairo_pattern_t *source) |
|
- | 1985 | { |
|
- | 1986 | if (_cairo_pattern_is_clear (source)) { |
|
- | 1987 | if (op == CAIRO_OPERATOR_OVER || op == CAIRO_OPERATOR_ADD) |
|
- | 1988 | return TRUE; |
|
- | 1989 | ||
- | 1990 | if (op == CAIRO_OPERATOR_SOURCE) |
|
- | 1991 | op = CAIRO_OPERATOR_CLEAR; |
|
- | 1992 | } |
|
- | 1993 | ||
- | 1994 | if (op == CAIRO_OPERATOR_CLEAR && surface->is_clear) |
|
- | 1995 | return TRUE; |
|
- | 1996 | ||
- | 1997 | if (op == CAIRO_OPERATOR_ATOP && (surface->content & CAIRO_CONTENT_COLOR) ==0) |
|
- | 1998 | return TRUE; |
|
- | 1999 | ||
- | 2000 | return FALSE; |
|
1990 | } |
2001 | } |
1991 | 2002 | ||
1992 | cairo_status_t |
2003 | cairo_status_t |
1993 | _cairo_surface_paint (cairo_surface_t *surface, |
2004 | _cairo_surface_paint (cairo_surface_t *surface, |
1994 | cairo_operator_t op, |
2005 | cairo_operator_t op, |
1995 | const cairo_pattern_t *source, |
2006 | const cairo_pattern_t *source, |
1996 | cairo_clip_t *clip) |
2007 | const cairo_clip_t *clip) |
Line -... | Line 2008... | ||
- | 2008 | { |
|
1997 | { |
2009 | cairo_int_status_t status; |
1998 | cairo_status_t status; |
2010 | |
- | 2011 | TRACE ((stderr, "%s\n", __FUNCTION__)); |
|
- | 2012 | if (unlikely (surface->status)) |
|
Line 1999... | Line 2013... | ||
1999 | 2013 | return surface->status; |
|
2000 | if (unlikely (surface->status)) |
2014 | if (unlikely (surface->finished)) |
Line 2001... | Line 2015... | ||
2001 | return surface->status; |
2015 | return _cairo_surface_set_error (surface, _cairo_error (CAIRO_STATUS_SURFACE_FINISHED)); |
- | 2016 | ||
2002 | 2017 | if (_cairo_clip_is_all_clipped (clip)) |
|
Line 2003... | Line -... | ||
2003 | if (clip && clip->all_clipped) |
- | |
2004 | return CAIRO_STATUS_SUCCESS; |
2018 | return CAIRO_STATUS_SUCCESS; |
2005 | - | ||
2006 | if (op == CAIRO_OPERATOR_CLEAR && surface->is_clear) |
2019 | |
2007 | return CAIRO_STATUS_SUCCESS; |
- | |
Line 2008... | Line 2020... | ||
2008 | 2020 | status = _pattern_has_error (source); |
|
2009 | if (op == CAIRO_OPERATOR_OVER && |
2021 | if (unlikely (status)) |
2010 | _cairo_pattern_is_clear (source)) |
2022 | return status; |
Line 2011... | Line -... | ||
2011 | { |
- | |
2012 | return CAIRO_STATUS_SUCCESS; |
- | |
2013 | } |
- | |
2014 | 2023 | ||
2015 | status = _pattern_has_error (source); |
2024 | if (nothing_to_do (surface, op, source)) |
2016 | if (unlikely (status)) |
- | |
2017 | return status; |
- | |
2018 | - | ||
2019 | _cairo_surface_begin_modification (surface); |
- | |
2020 | - | ||
2021 | if (surface->backend->paint != NULL) { |
- | |
2022 | status = surface->backend->paint (surface, op, source, clip); |
2025 | return CAIRO_STATUS_SUCCESS; |
- | 2026 | ||
- | 2027 | status = _cairo_surface_begin_modification (surface); |
|
Line 2023... | Line 2028... | ||
2023 | if (status != CAIRO_INT_STATUS_UNSUPPORTED) |
2028 | if (unlikely (status)) |
2024 | goto FINISH; |
2029 | return status; |
Line 2025... | Line 2030... | ||
2025 | } |
2030 | |
2026 | 2031 | status = surface->backend->paint (surface, op, source, clip); |
|
2027 | status = _cairo_surface_fallback_paint (surface, op, source, clip); |
2032 | if (status != CAIRO_INT_STATUS_NOTHING_TO_DO) { |
2028 | 2033 | surface->is_clear = op == CAIRO_OPERATOR_CLEAR && clip == NULL; |
|
2029 | FINISH: |
2034 | surface->serial++; |
2030 | surface->is_clear = op == CAIRO_OPERATOR_CLEAR && clip == NULL; |
2035 | } |
2031 | 2036 | ||
2032 | return _cairo_surface_set_error (surface, status); |
2037 | return _cairo_surface_set_error (surface, status); |
Line -... | Line 2038... | ||
- | 2038 | } |
|
2033 | } |
2039 | |
2034 | 2040 | cairo_status_t |
|
- | 2041 | _cairo_surface_mask (cairo_surface_t *surface, |
|
- | 2042 | cairo_operator_t op, |
|
Line 2035... | Line 2043... | ||
2035 | cairo_status_t |
2043 | const cairo_pattern_t *source, |
2036 | _cairo_surface_mask (cairo_surface_t *surface, |
- | |
2037 | cairo_operator_t op, |
- | |
2038 | const cairo_pattern_t *source, |
- | |
2039 | const cairo_pattern_t *mask, |
2044 | const cairo_pattern_t *mask, |
Line 2040... | Line 2045... | ||
2040 | cairo_clip_t *clip) |
2045 | const cairo_clip_t *clip) |
2041 | { |
2046 | { |
2042 | cairo_status_t status; |
2047 | cairo_int_status_t status; |
2043 | 2048 | ||
2044 | if (unlikely (surface->status)) |
2049 | TRACE ((stderr, "%s\n", __FUNCTION__)); |
2045 | return surface->status; |
2050 | if (unlikely (surface->status)) |
Line 2046... | Line -... | ||
2046 | - | ||
2047 | if (clip && clip->all_clipped) |
- | |
2048 | return CAIRO_STATUS_SUCCESS; |
- | |
2049 | - | ||
2050 | if (op == CAIRO_OPERATOR_CLEAR && surface->is_clear) |
- | |
2051 | return CAIRO_STATUS_SUCCESS; |
- | |
2052 | 2051 | return surface->status; |
|
2053 | /* If the mask is blank, this is just an expensive no-op */ |
2052 | if (unlikely (surface->finished)) |
2054 | if (_cairo_pattern_is_clear (mask) && |
2053 | return _cairo_surface_set_error (surface, _cairo_error (CAIRO_STATUS_SURFACE_FINISHED)); |
Line 2055... | Line 2054... | ||
2055 | _cairo_operator_bounded_by_mask (op)) |
2054 | |
2056 | { |
2055 | if (_cairo_clip_is_all_clipped (clip)) |
2057 | return CAIRO_STATUS_SUCCESS; |
2056 | return CAIRO_STATUS_SUCCESS; |
Line 2058... | Line 2057... | ||
2058 | } |
2057 | |
2059 | - | ||
2060 | if (op == CAIRO_OPERATOR_OVER && |
- | |
2061 | _cairo_pattern_is_clear (source)) |
- | |
2062 | { |
2058 | /* If the mask is blank, this is just an expensive no-op */ |
2063 | return CAIRO_STATUS_SUCCESS; |
- | |
2064 | } |
- | |
Line 2065... | Line 2059... | ||
2065 | 2059 | if (_cairo_pattern_is_clear (mask) && |
|
- | 2060 | _cairo_operator_bounded_by_mask (op)) |
|
- | 2061 | { |
|
Line -... | Line 2062... | ||
- | 2062 | return CAIRO_STATUS_SUCCESS; |
|
2066 | status = _pattern_has_error (source); |
2063 | } |
2067 | if (unlikely (status)) |
2064 | |
- | 2065 | status = _pattern_has_error (source); |
|
- | 2066 | if (unlikely (status)) |
|
Line 2068... | Line 2067... | ||
2068 | return status; |
2067 | return status; |
2069 | 2068 | ||
Line 2070... | Line 2069... | ||
2070 | status = _pattern_has_error (mask); |
2069 | status = _pattern_has_error (mask); |
Line 2100... | Line 2099... | ||
2100 | const cairo_stroke_style_t *stroke_style, |
2099 | const cairo_stroke_style_t *stroke_style, |
2101 | const cairo_matrix_t *stroke_ctm, |
2100 | const cairo_matrix_t *stroke_ctm, |
2102 | const cairo_matrix_t *stroke_ctm_inverse, |
2101 | const cairo_matrix_t *stroke_ctm_inverse, |
2103 | double stroke_tolerance, |
2102 | double stroke_tolerance, |
2104 | cairo_antialias_t stroke_antialias, |
2103 | cairo_antialias_t stroke_antialias, |
2105 | cairo_clip_t *clip) |
2104 | const cairo_clip_t *clip) |
2106 | { |
2105 | { |
2107 | cairo_status_t status; |
2106 | cairo_int_status_t status; |
Line -... | Line 2107... | ||
- | 2107 | ||
2108 | 2108 | TRACE ((stderr, "%s\n", __FUNCTION__)); |
|
2109 | if (unlikely (surface->status)) |
2109 | if (unlikely (surface->status)) |
- | 2110 | return surface->status; |
|
- | 2111 | if (unlikely (surface->finished)) |
|
Line 2110... | Line 2112... | ||
2110 | return surface->status; |
2112 | return _cairo_surface_set_error (surface, _cairo_error (CAIRO_STATUS_SURFACE_FINISHED)); |
2111 | 2113 | ||
Line 2112... | Line 2114... | ||
2112 | if (clip && clip->all_clipped) |
2114 | if (_cairo_clip_is_all_clipped (clip)) |
2113 | return CAIRO_STATUS_SUCCESS; |
2115 | return CAIRO_STATUS_SUCCESS; |
2114 | 2116 | ||
Line 2125... | Line 2127... | ||
2125 | 2127 | ||
2126 | status = _pattern_has_error (stroke_source); |
2128 | status = _pattern_has_error (stroke_source); |
2127 | if (unlikely (status)) |
2129 | if (unlikely (status)) |
Line 2128... | Line 2130... | ||
2128 | return status; |
2130 | return status; |
- | 2131 | ||
- | 2132 | status = _cairo_surface_begin_modification (surface); |
|
Line 2129... | Line 2133... | ||
2129 | 2133 | if (unlikely (status)) |
|
2130 | _cairo_surface_begin_modification (surface); |
2134 | return status; |
2131 | 2135 | ||
Line 2159... | Line 2163... | ||
2159 | clip); |
2163 | clip); |
2160 | if (unlikely (status)) |
2164 | if (unlikely (status)) |
2161 | goto FINISH; |
2165 | goto FINISH; |
Line 2162... | Line 2166... | ||
2162 | 2166 | ||
- | 2167 | FINISH: |
|
2163 | FINISH: |
2168 | if (status != CAIRO_INT_STATUS_NOTHING_TO_DO) { |
- | 2169 | surface->is_clear = FALSE; |
|
- | 2170 | surface->serial++; |
|
Line 2164... | Line 2171... | ||
2164 | surface->is_clear = FALSE; |
2171 | } |
2165 | 2172 | ||
Line 2166... | Line 2173... | ||
2166 | return _cairo_surface_set_error (surface, status); |
2173 | return _cairo_surface_set_error (surface, status); |
2167 | } |
2174 | } |
2168 | 2175 | ||
2169 | cairo_status_t |
2176 | cairo_status_t |
2170 | _cairo_surface_stroke (cairo_surface_t *surface, |
2177 | _cairo_surface_stroke (cairo_surface_t *surface, |
2171 | cairo_operator_t op, |
2178 | cairo_operator_t op, |
2172 | const cairo_pattern_t *source, |
2179 | const cairo_pattern_t *source, |
2173 | cairo_path_fixed_t *path, |
2180 | const cairo_path_fixed_t *path, |
2174 | const cairo_stroke_style_t *stroke_style, |
2181 | const cairo_stroke_style_t *stroke_style, |
2175 | const cairo_matrix_t *ctm, |
2182 | const cairo_matrix_t *ctm, |
2176 | const cairo_matrix_t *ctm_inverse, |
2183 | const cairo_matrix_t *ctm_inverse, |
2177 | double tolerance, |
2184 | double tolerance, |
2178 | cairo_antialias_t antialias, |
2185 | cairo_antialias_t antialias, |
Line -... | Line 2186... | ||
- | 2186 | const cairo_clip_t *clip) |
|
2179 | cairo_clip_t *clip) |
2187 | { |
2180 | { |
2188 | cairo_int_status_t status; |
- | 2189 | ||
- | 2190 | TRACE ((stderr, "%s\n", __FUNCTION__)); |
|
Line 2181... | Line 2191... | ||
2181 | cairo_status_t status; |
2191 | if (unlikely (surface->status)) |
2182 | 2192 | return surface->status; |
|
Line 2183... | Line 2193... | ||
2183 | if (unlikely (surface->status)) |
2193 | if (unlikely (surface->finished)) |
- | 2194 | return _cairo_surface_set_error (surface, _cairo_error (CAIRO_STATUS_SURFACE_FINISHED)); |
|
2184 | return surface->status; |
2195 | |
Line 2185... | Line -... | ||
2185 | - | ||
2186 | if (clip && clip->all_clipped) |
2196 | if (_cairo_clip_is_all_clipped (clip)) |
2187 | return CAIRO_STATUS_SUCCESS; |
- | |
2188 | 2197 | return CAIRO_STATUS_SUCCESS; |
|
2189 | if (op == CAIRO_OPERATOR_CLEAR && surface->is_clear) |
- | |
Line 2190... | Line 2198... | ||
2190 | return CAIRO_STATUS_SUCCESS; |
2198 | |
2191 | 2199 | status = _pattern_has_error (source); |
|
2192 | if (op == CAIRO_OPERATOR_OVER && |
2200 | if (unlikely (status)) |
Line 2193... | Line -... | ||
2193 | _cairo_pattern_is_clear (source)) |
- | |
2194 | { |
- | |
2195 | return CAIRO_STATUS_SUCCESS; |
- | |
2196 | } |
2201 | return status; |
2197 | 2202 | ||
2198 | status = _pattern_has_error (source); |
2203 | if (nothing_to_do (surface, op, source)) |
2199 | if (unlikely (status)) |
2204 | return CAIRO_STATUS_SUCCESS; |
2200 | return status; |
2205 | |
2201 | - | ||
2202 | _cairo_surface_begin_modification (surface); |
2206 | status = _cairo_surface_begin_modification (surface); |
2203 | - | ||
2204 | if (surface->backend->stroke != NULL) { |
- | |
2205 | status = surface->backend->stroke (surface, op, source, |
- | |
2206 | path, stroke_style, |
- | |
2207 | ctm, ctm_inverse, |
- | |
2208 | tolerance, antialias, |
- | |
2209 | clip); |
- | |
2210 | - | ||
2211 | if (status != CAIRO_INT_STATUS_UNSUPPORTED) |
- | |
2212 | goto FINISH; |
- | |
2213 | } |
2207 | if (unlikely (status)) |
- | 2208 | return status; |
|
- | 2209 | ||
Line 2214... | Line 2210... | ||
2214 | 2210 | status = surface->backend->stroke (surface, op, source, |
|
2215 | status = _cairo_surface_fallback_stroke (surface, op, source, |
2211 | path, stroke_style, |
Line 2216... | Line 2212... | ||
2216 | path, stroke_style, |
2212 | ctm, ctm_inverse, |
2217 | ctm, ctm_inverse, |
2213 | tolerance, antialias, |
2218 | tolerance, antialias, |
2214 | clip); |
2219 | clip); |
2215 | if (status != CAIRO_INT_STATUS_NOTHING_TO_DO) { |
2220 | 2216 | surface->is_clear = FALSE; |
|
2221 | FINISH: |
2217 | surface->serial++; |
2222 | surface->is_clear = FALSE; |
2218 | } |
2223 | 2219 | ||
2224 | return _cairo_surface_set_error (surface, status); |
2220 | return _cairo_surface_set_error (surface, status); |
2225 | } |
2221 | } |
2226 | 2222 | ||
Line -... | Line 2223... | ||
- | 2223 | cairo_status_t |
|
2227 | cairo_status_t |
2224 | _cairo_surface_fill (cairo_surface_t *surface, |
2228 | _cairo_surface_fill (cairo_surface_t *surface, |
2225 | cairo_operator_t op, |
- | 2226 | const cairo_pattern_t *source, |
|
- | 2227 | const cairo_path_fixed_t *path, |
|
Line 2229... | Line 2228... | ||
2229 | cairo_operator_t op, |
2228 | cairo_fill_rule_t fill_rule, |
2230 | const cairo_pattern_t *source, |
2229 | double tolerance, |
Line 2231... | Line 2230... | ||
2231 | cairo_path_fixed_t *path, |
2230 | cairo_antialias_t antialias, |
- | 2231 | const cairo_clip_t *clip) |
|
2232 | cairo_fill_rule_t fill_rule, |
2232 | { |
Line 2233... | Line -... | ||
2233 | double tolerance, |
- | |
2234 | cairo_antialias_t antialias, |
2233 | cairo_int_status_t status; |
2235 | cairo_clip_t *clip) |
- | |
2236 | { |
2234 | |
2237 | cairo_status_t status; |
- | |
Line 2238... | Line 2235... | ||
2238 | 2235 | TRACE ((stderr, "%s\n", __FUNCTION__)); |
|
2239 | if (unlikely (surface->status)) |
2236 | if (unlikely (surface->status)) |
2240 | return surface->status; |
2237 | return surface->status; |
Line 2241... | Line -... | ||
2241 | - | ||
2242 | if (clip && clip->all_clipped) |
- | |
2243 | return CAIRO_STATUS_SUCCESS; |
- | |
2244 | 2238 | if (unlikely (surface->finished)) |
|
2245 | if (op == CAIRO_OPERATOR_CLEAR && surface->is_clear) |
2239 | return _cairo_surface_set_error (surface, _cairo_error (CAIRO_STATUS_SURFACE_FINISHED)); |
2246 | return CAIRO_STATUS_SUCCESS; |
2240 | |
2247 | 2241 | if (_cairo_clip_is_all_clipped (clip)) |
|
2248 | if (op == CAIRO_OPERATOR_OVER && |
- | |
2249 | _cairo_pattern_is_clear (source)) |
2242 | return CAIRO_STATUS_SUCCESS; |
2250 | { |
- | |
2251 | return CAIRO_STATUS_SUCCESS; |
- | |
2252 | } |
- | |
2253 | - | ||
2254 | status = _pattern_has_error (source); |
- | |
2255 | if (unlikely (status)) |
- | |
2256 | return status; |
- | |
2257 | - | ||
2258 | _cairo_surface_begin_modification (surface); |
- | |
2259 | 2243 | ||
2260 | if (surface->backend->fill != NULL) { |
- | |
2261 | status = surface->backend->fill (surface, op, source, |
2244 | status = _pattern_has_error (source); |
2262 | path, fill_rule, |
2245 | if (unlikely (status)) |
Line 2263... | Line -... | ||
2263 | tolerance, antialias, |
- | |
2264 | clip); |
- | |
2265 | - | ||
2266 | if (status != CAIRO_INT_STATUS_UNSUPPORTED) |
- | |
2267 | goto FINISH; |
- | |
2268 | } |
- | |
2269 | - | ||
2270 | status = _cairo_surface_fallback_fill (surface, op, source, |
- | |
2271 | path, fill_rule, |
- | |
2272 | tolerance, antialias, |
- | |
2273 | clip); |
- | |
2274 | - | ||
2275 | FINISH: |
- | |
2276 | surface->is_clear = FALSE; |
- | |
2277 | - | ||
2278 | return _cairo_surface_set_error (surface, status); |
- | |
2279 | } |
- | |
2280 | - | ||
2281 | cairo_status_t |
- | |
2282 | _cairo_surface_composite_trapezoids (cairo_operator_t op, |
- | |
2283 | const cairo_pattern_t *pattern, |
- | |
2284 | cairo_surface_t *dst, |
- | |
2285 | cairo_antialias_t antialias, |
- | |
2286 | int src_x, |
- | |
2287 | int src_y, |
- | |
2288 | int dst_x, |
- | |
2289 | int dst_y, |
- | |
2290 | unsigned int width, |
- | |
2291 | unsigned int height, |
- | |
2292 | cairo_trapezoid_t *traps, |
- | |
2293 | int num_traps, |
- | |
2294 | cairo_region_t *clip_region) |
- | |
2295 | { |
- | |
2296 | cairo_int_status_t status; |
- | |
2297 | - | ||
2298 | if (dst->status) |
- | |
2299 | return dst->status; |
- | |
2300 | 2246 | return status; |
|
2301 | assert (_cairo_surface_is_writable (dst)); |
- | |
2302 | - | ||
2303 | /* These operators aren't interpreted the same way by the backends; |
- | |
2304 | * they are implemented in terms of other operators in cairo-gstate.c |
- | |
2305 | */ |
- | |
2306 | assert (op != CAIRO_OPERATOR_SOURCE && op != CAIRO_OPERATOR_CLEAR); |
- | |
2307 | - | ||
2308 | if (dst->backend->composite_trapezoids) { |
- | |
2309 | status = dst->backend->composite_trapezoids (op, |
- | |
2310 | pattern, dst, |
- | |
2311 | antialias, |
- | |
2312 | src_x, src_y, |
- | |
2313 | dst_x, dst_y, |
- | |
2314 | width, height, |
- | |
2315 | traps, num_traps, |
- | |
2316 | clip_region); |
- | |
2317 | if (status != CAIRO_INT_STATUS_UNSUPPORTED) |
- | |
2318 | return _cairo_surface_set_error (dst, status); |
- | |
2319 | } |
- | |
2320 | - | ||
2321 | return _cairo_surface_set_error (dst, |
- | |
2322 | _cairo_surface_fallback_composite_trapezoids (op, pattern, dst, |
- | |
2323 | antialias, |
- | |
2324 | src_x, src_y, |
- | |
2325 | dst_x, dst_y, |
- | |
2326 | width, height, |
- | |
2327 | traps, num_traps, |
- | |
2328 | clip_region)); |
- | |
2329 | } |
- | |
2330 | - | ||
2331 | cairo_span_renderer_t * |
- | |
2332 | _cairo_surface_create_span_renderer (cairo_operator_t op, |
- | |
2333 | const cairo_pattern_t *pattern, |
- | |
2334 | cairo_surface_t *dst, |
- | |
2335 | cairo_antialias_t antialias, |
- | |
2336 | const cairo_composite_rectangles_t *rects, |
- | |
2337 | cairo_region_t *clip_region) |
- | |
2338 | { |
- | |
2339 | assert (dst->snapshot_of == NULL); |
- | |
2340 | - | ||
2341 | if (unlikely (dst->status)) |
- | |
2342 | return _cairo_span_renderer_create_in_error (dst->status); |
- | |
2343 | - | ||
2344 | if (unlikely (dst->finished)) |
- | |
2345 | return _cairo_span_renderer_create_in_error (CAIRO_STATUS_SURFACE_FINISHED); |
- | |
2346 | - | ||
2347 | if (dst->backend->create_span_renderer) { |
- | |
2348 | return dst->backend->create_span_renderer (op, |
- | |
2349 | pattern, dst, |
- | |
2350 | antialias, |
- | |
2351 | rects, |
- | |
2352 | clip_region); |
- | |
2353 | } |
- | |
2354 | ASSERT_NOT_REACHED; |
- | |
2355 | return _cairo_span_renderer_create_in_error (CAIRO_INT_STATUS_UNSUPPORTED); |
- | |
2356 | } |
- | |
2357 | - | ||
2358 | cairo_bool_t |
2247 | |
Line 2359... | Line 2248... | ||
2359 | _cairo_surface_check_span_renderer (cairo_operator_t op, |
2248 | if (nothing_to_do (surface, op, source)) |
2360 | const cairo_pattern_t *pattern, |
2249 | return CAIRO_STATUS_SUCCESS; |
2361 | cairo_surface_t *dst, |
2250 | |
Line 2386... | Line 2275... | ||
2386 | * |
2275 | * |
2387 | * There is a convenience function for this that takes a #cairo_t, |
2276 | * There is a convenience function for this that takes a #cairo_t, |
2388 | * namely cairo_copy_page(). |
2277 | * namely cairo_copy_page(). |
2389 | * |
2278 | * |
2390 | * Since: 1.6 |
2279 | * Since: 1.6 |
2391 | */ |
2280 | **/ |
2392 | void |
2281 | void |
2393 | cairo_surface_copy_page (cairo_surface_t *surface) |
2282 | cairo_surface_copy_page (cairo_surface_t *surface) |
2394 | { |
2283 | { |
2395 | cairo_status_t status_ignored; |
- | |
2396 | - | ||
2397 | if (surface->status) |
2284 | if (unlikely (surface->status)) |
2398 | return; |
2285 | return; |
Line 2399... | Line 2286... | ||
2399 | 2286 | ||
Line 2400... | Line 2287... | ||
2400 | assert (surface->snapshot_of == NULL); |
2287 | assert (surface->snapshot_of == NULL); |
2401 | - | ||
2402 | if (surface->finished) { |
2288 | |
2403 | status_ignored = _cairo_surface_set_error (surface, |
2289 | if (unlikely (surface->finished)) { |
2404 | CAIRO_STATUS_SURFACE_FINISHED); |
2290 | _cairo_surface_set_error (surface, CAIRO_STATUS_SURFACE_FINISHED); |
Line 2405... | Line 2291... | ||
2405 | return; |
2291 | return; |
2406 | } |
2292 | } |
2407 | 2293 | ||
Line 2408... | Line -... | ||
2408 | /* It's fine if some backends don't implement copy_page */ |
- | |
2409 | if (surface->backend->copy_page == NULL) |
2294 | /* It's fine if some backends don't implement copy_page */ |
2410 | return; |
2295 | if (surface->backend->copy_page == NULL) |
2411 | 2296 | return; |
|
Line 2412... | Line 2297... | ||
2412 | status_ignored = _cairo_surface_set_error (surface, |
2297 | |
2413 | surface->backend->copy_page (surface)); |
2298 | _cairo_surface_set_error (surface, surface->backend->copy_page (surface)); |
Line 2427... | Line 2312... | ||
2427 | * Since: 1.6 |
2312 | * Since: 1.6 |
2428 | **/ |
2313 | **/ |
2429 | void |
2314 | void |
2430 | cairo_surface_show_page (cairo_surface_t *surface) |
2315 | cairo_surface_show_page (cairo_surface_t *surface) |
2431 | { |
2316 | { |
2432 | cairo_status_t status_ignored; |
2317 | cairo_status_t status; |
Line 2433... | Line 2318... | ||
2433 | 2318 | ||
2434 | if (surface->status) |
2319 | if (unlikely (surface->status)) |
Line 2435... | Line 2320... | ||
2435 | return; |
2320 | return; |
2436 | - | ||
2437 | if (surface->finished) { |
2321 | |
2438 | status_ignored = _cairo_surface_set_error (surface, |
2322 | if (unlikely (surface->finished)) { |
2439 | CAIRO_STATUS_SURFACE_FINISHED); |
2323 | _cairo_surface_set_error (surface, CAIRO_STATUS_SURFACE_FINISHED); |
Line 2440... | Line 2324... | ||
2440 | return; |
2324 | return; |
- | 2325 | } |
|
- | 2326 | ||
- | 2327 | status = _cairo_surface_begin_modification (surface); |
|
- | 2328 | if (unlikely (status)) { |
|
Line 2441... | Line 2329... | ||
2441 | } |
2329 | _cairo_surface_set_error (surface, status); |
2442 | 2330 | return; |
|
2443 | _cairo_surface_begin_modification (surface); |
2331 | } |
Line 2444... | Line -... | ||
2444 | - | ||
2445 | /* It's fine if some backends don't implement show_page */ |
2332 | |
2446 | if (surface->backend->show_page == NULL) |
2333 | /* It's fine if some backends don't implement show_page */ |
2447 | return; |
2334 | if (surface->backend->show_page == NULL) |
Line 2448... | Line 2335... | ||
2448 | 2335 | return; |
|
2449 | status_ignored = _cairo_surface_set_error (surface, |
2336 | |
Line 2472... | Line 2359... | ||
2472 | * current callers are within the surface layer where backend space is |
2359 | * current callers are within the surface layer where backend space is |
2473 | * desired. |
2360 | * desired. |
2474 | * |
2361 | * |
2475 | * This behavior would have to be changed is we ever exported a public |
2362 | * This behavior would have to be changed is we ever exported a public |
2476 | * variant of this function. |
2363 | * variant of this function. |
2477 | */ |
2364 | **/ |
2478 | cairo_bool_t |
2365 | cairo_bool_t |
2479 | _cairo_surface_get_extents (cairo_surface_t *surface, |
2366 | _cairo_surface_get_extents (cairo_surface_t *surface, |
2480 | cairo_rectangle_int_t *extents) |
2367 | cairo_rectangle_int_t *extents) |
2481 | { |
2368 | { |
2482 | cairo_bool_t bounded; |
2369 | cairo_bool_t bounded; |
Line -... | Line 2370... | ||
- | 2370 | ||
- | 2371 | if (unlikely (surface->status)) |
|
- | 2372 | goto zero_extents; |
|
- | 2373 | if (unlikely (surface->finished)) { |
|
- | 2374 | _cairo_surface_set_error(surface, CAIRO_STATUS_SURFACE_FINISHED); |
|
- | 2375 | goto zero_extents; |
|
- | 2376 | } |
|
2483 | 2377 | ||
2484 | bounded = FALSE; |
2378 | bounded = FALSE; |
2485 | if (surface->backend->get_extents != NULL) |
2379 | if (surface->backend->get_extents != NULL) |
Line 2486... | Line 2380... | ||
2486 | bounded = surface->backend->get_extents (surface, extents); |
2380 | bounded = surface->backend->get_extents (surface, extents); |
2487 | 2381 | ||
Line 2488... | Line 2382... | ||
2488 | if (! bounded) |
2382 | if (! bounded) |
- | 2383 | _cairo_unbounded_rectangle_init (extents); |
|
- | 2384 | ||
- | 2385 | return bounded; |
|
- | 2386 | ||
- | 2387 | zero_extents: |
|
2489 | _cairo_unbounded_rectangle_init (extents); |
2388 | extents->x = extents->y = 0; |
Line 2490... | Line 2389... | ||
2490 | 2389 | extents->width = extents->height = 0; |
|
2491 | return bounded; |
2390 | return TRUE; |
2492 | } |
2391 | } |
Line 2513... | Line 2412... | ||
2513 | * Since: 1.8 |
2412 | * Since: 1.8 |
2514 | **/ |
2413 | **/ |
2515 | cairo_bool_t |
2414 | cairo_bool_t |
2516 | cairo_surface_has_show_text_glyphs (cairo_surface_t *surface) |
2415 | cairo_surface_has_show_text_glyphs (cairo_surface_t *surface) |
2517 | { |
2416 | { |
2518 | cairo_status_t status_ignored; |
- | |
2519 | - | ||
2520 | if (surface->status) |
2417 | if (unlikely (surface->status)) |
2521 | return FALSE; |
2418 | return FALSE; |
Line 2522... | Line 2419... | ||
2522 | 2419 | ||
2523 | if (surface->finished) { |
- | |
2524 | status_ignored = _cairo_surface_set_error (surface, |
2420 | if (unlikely (surface->finished)) { |
2525 | CAIRO_STATUS_SURFACE_FINISHED); |
2421 | _cairo_surface_set_error (surface, CAIRO_STATUS_SURFACE_FINISHED); |
2526 | return FALSE; |
2422 | return FALSE; |
Line 2527... | Line 2423... | ||
2527 | } |
2423 | } |
2528 | 2424 | ||
Line 2558... | Line 2454... | ||
2558 | int num_glyphs, |
2454 | int num_glyphs, |
2559 | const cairo_text_cluster_t *clusters, |
2455 | const cairo_text_cluster_t *clusters, |
2560 | int num_clusters, |
2456 | int num_clusters, |
2561 | cairo_text_cluster_flags_t cluster_flags, |
2457 | cairo_text_cluster_flags_t cluster_flags, |
2562 | cairo_scaled_font_t *scaled_font, |
2458 | cairo_scaled_font_t *scaled_font, |
2563 | cairo_clip_t *clip) |
2459 | const cairo_clip_t *clip) |
2564 | { |
2460 | { |
2565 | cairo_status_t status; |
2461 | cairo_int_status_t status; |
2566 | cairo_scaled_font_t *dev_scaled_font = scaled_font; |
2462 | cairo_scaled_font_t *dev_scaled_font = scaled_font; |
Line -... | Line 2463... | ||
- | 2463 | ||
2567 | 2464 | TRACE ((stderr, "%s\n", __FUNCTION__)); |
|
2568 | if (unlikely (surface->status)) |
2465 | if (unlikely (surface->status)) |
- | 2466 | return surface->status; |
|
- | 2467 | if (unlikely (surface->finished)) |
|
Line 2569... | Line 2468... | ||
2569 | return surface->status; |
2468 | return _cairo_surface_set_error (surface, _cairo_error (CAIRO_STATUS_SURFACE_FINISHED)); |
2570 | 2469 | ||
Line 2571... | Line 2470... | ||
2571 | if (num_glyphs == 0 && utf8_len == 0) |
2470 | if (num_glyphs == 0 && utf8_len == 0) |
2572 | return CAIRO_STATUS_SUCCESS; |
- | |
2573 | - | ||
2574 | if (clip && clip->all_clipped) |
- | |
2575 | return CAIRO_STATUS_SUCCESS; |
2471 | return CAIRO_STATUS_SUCCESS; |
Line 2576... | Line 2472... | ||
2576 | 2472 | ||
2577 | if (op == CAIRO_OPERATOR_CLEAR && surface->is_clear) |
2473 | if (_cairo_clip_is_all_clipped (clip)) |
2578 | return CAIRO_STATUS_SUCCESS; |
2474 | return CAIRO_STATUS_SUCCESS; |
Line -... | Line 2475... | ||
- | 2475 | ||
- | 2476 | status = _pattern_has_error (source); |
|
- | 2477 | if (unlikely (status)) |
|
2579 | 2478 | return status; |
|
- | 2479 | ||
- | 2480 | if (nothing_to_do (surface, op, source)) |
|
Line 2580... | Line 2481... | ||
2580 | status = _pattern_has_error (source); |
2481 | return CAIRO_STATUS_SUCCESS; |
2581 | if (unlikely (status)) |
2482 | |
2582 | return status; |
2483 | status = _cairo_surface_begin_modification (surface); |
2583 | 2484 | if (unlikely (status)) |
|
Line 2619... | Line 2520... | ||
2619 | clip); |
2520 | clip); |
2620 | } |
2521 | } |
2621 | if (status == CAIRO_INT_STATUS_UNSUPPORTED && |
2522 | if (status == CAIRO_INT_STATUS_UNSUPPORTED && |
2622 | surface->backend->show_glyphs) |
2523 | surface->backend->show_glyphs) |
2623 | { |
2524 | { |
2624 | int remaining_glyphs = num_glyphs; |
- | |
2625 | status = surface->backend->show_glyphs (surface, op, |
2525 | status = surface->backend->show_glyphs (surface, op, |
2626 | source, |
2526 | source, |
2627 | glyphs, num_glyphs, |
2527 | glyphs, num_glyphs, |
2628 | dev_scaled_font, |
2528 | dev_scaled_font, |
2629 | clip, |
2529 | clip); |
2630 | &remaining_glyphs); |
- | |
2631 | glyphs += num_glyphs - remaining_glyphs; |
- | |
2632 | num_glyphs = remaining_glyphs; |
- | |
2633 | if (status == CAIRO_INT_STATUS_UNSUPPORTED && remaining_glyphs == 0) |
- | |
2634 | status = CAIRO_STATUS_SUCCESS; |
- | |
2635 | } |
2530 | } |
2636 | } else { |
2531 | } else { |
2637 | /* A mere show_glyphs call. Try show_glyphs backend method first */ |
2532 | /* A mere show_glyphs call. Try show_glyphs backend method first */ |
2638 | if (surface->backend->show_glyphs != NULL) { |
2533 | if (surface->backend->show_glyphs != NULL) { |
2639 | int remaining_glyphs = num_glyphs; |
- | |
2640 | status = surface->backend->show_glyphs (surface, op, |
2534 | status = surface->backend->show_glyphs (surface, op, |
2641 | source, |
2535 | source, |
2642 | glyphs, num_glyphs, |
2536 | glyphs, num_glyphs, |
2643 | dev_scaled_font, |
2537 | dev_scaled_font, |
2644 | clip, |
2538 | clip); |
2645 | &remaining_glyphs); |
- | |
2646 | glyphs += num_glyphs - remaining_glyphs; |
- | |
2647 | num_glyphs = remaining_glyphs; |
- | |
2648 | if (status == CAIRO_INT_STATUS_UNSUPPORTED && remaining_glyphs == 0) |
- | |
2649 | status = CAIRO_STATUS_SUCCESS; |
- | |
2650 | } else if (surface->backend->show_text_glyphs != NULL) { |
2539 | } else if (surface->backend->show_text_glyphs != NULL) { |
2651 | /* Intentionally only try show_text_glyphs method for show_glyphs |
2540 | /* Intentionally only try show_text_glyphs method for show_glyphs |
2652 | * calls if backend does not have show_glyphs. If backend has |
2541 | * calls if backend does not have show_glyphs. If backend has |
2653 | * both methods implemented, we don't fallback from show_glyphs to |
2542 | * both methods implemented, we don't fallback from show_glyphs to |
2654 | * show_text_glyphs, and hence the backend can assume in its |
2543 | * show_text_glyphs, and hence the backend can assume in its |
Line 2664... | Line 2553... | ||
2664 | dev_scaled_font, |
2553 | dev_scaled_font, |
2665 | clip); |
2554 | clip); |
2666 | } |
2555 | } |
2667 | } |
2556 | } |
Line 2668... | Line -... | ||
2668 | - | ||
2669 | if (status == CAIRO_INT_STATUS_UNSUPPORTED) { |
- | |
2670 | status = _cairo_surface_fallback_show_glyphs (surface, op, |
- | |
2671 | source, |
- | |
2672 | glyphs, num_glyphs, |
- | |
2673 | dev_scaled_font, |
- | |
2674 | clip); |
- | |
2675 | } |
- | |
2676 | 2557 | ||
2677 | if (dev_scaled_font != scaled_font) |
2558 | if (dev_scaled_font != scaled_font) |
Line -... | Line 2559... | ||
- | 2559 | cairo_scaled_font_destroy (dev_scaled_font); |
|
2678 | cairo_scaled_font_destroy (dev_scaled_font); |
2560 | |
2679 | - | ||
2680 | surface->is_clear = FALSE; |
2561 | if (status != CAIRO_INT_STATUS_NOTHING_TO_DO) { |
2681 | 2562 | surface->is_clear = FALSE; |
|
Line 2682... | Line -... | ||
2682 | return _cairo_surface_set_error (surface, status); |
- | |
2683 | } |
- | |
2684 | - | ||
2685 | /* XXX: Previously, we had a function named _cairo_surface_show_glyphs |
- | |
2686 | * with not-so-useful semantics. We've now got a |
- | |
2687 | * _cairo_surface_show_text_glyphs with the proper semantics, and its |
- | |
2688 | * fallback still uses this old function (which still needs to be |
- | |
2689 | * cleaned up in terms of both semantics and naming). */ |
- | |
2690 | cairo_status_t |
- | |
2691 | _cairo_surface_old_show_glyphs (cairo_scaled_font_t *scaled_font, |
- | |
2692 | cairo_operator_t op, |
- | |
2693 | const cairo_pattern_t *pattern, |
- | |
2694 | cairo_surface_t *dst, |
- | |
2695 | int source_x, |
- | |
2696 | int source_y, |
- | |
2697 | int dest_x, |
- | |
2698 | int dest_y, |
- | |
2699 | unsigned int width, |
- | |
2700 | unsigned int height, |
- | |
2701 | cairo_glyph_t *glyphs, |
- | |
2702 | int num_glyphs, |
- | |
2703 | cairo_region_t *clip_region) |
- | |
2704 | { |
- | |
2705 | cairo_status_t status; |
- | |
2706 | - | ||
2707 | if (dst->status) |
- | |
2708 | return dst->status; |
- | |
2709 | - | ||
2710 | assert (_cairo_surface_is_writable (dst)); |
- | |
2711 | - | ||
2712 | if (dst->backend->old_show_glyphs) { |
- | |
2713 | status = dst->backend->old_show_glyphs (scaled_font, |
- | |
2714 | op, pattern, dst, |
- | |
2715 | source_x, source_y, |
- | |
2716 | dest_x, dest_y, |
- | |
2717 | width, height, |
- | |
2718 | glyphs, num_glyphs, |
- | |
2719 | clip_region); |
- | |
2720 | } else |
- | |
2721 | status = CAIRO_INT_STATUS_UNSUPPORTED; |
- | |
2722 | - | ||
2723 | return _cairo_surface_set_error (dst, status); |
- | |
2724 | } |
- | |
2725 | - | ||
2726 | static cairo_status_t |
- | |
2727 | _cairo_surface_composite_fixup_unbounded_internal (cairo_surface_t *dst, |
- | |
2728 | cairo_rectangle_int_t *src_rectangle, |
- | |
2729 | cairo_rectangle_int_t *mask_rectangle, |
- | |
2730 | int dst_x, |
- | |
2731 | int dst_y, |
- | |
2732 | unsigned int width, |
- | |
2733 | unsigned int height, |
- | |
2734 | cairo_region_t *clip_region) |
- | |
2735 | { |
- | |
2736 | cairo_rectangle_int_t dst_rectangle; |
- | |
2737 | cairo_region_t clear_region; |
- | |
2738 | cairo_status_t status; |
- | |
2739 | - | ||
2740 | /* The area that was drawn is the area in the destination rectangle but |
- | |
2741 | * not within the source or the mask. |
- | |
2742 | */ |
- | |
2743 | dst_rectangle.x = dst_x; |
- | |
2744 | dst_rectangle.y = dst_y; |
- | |
2745 | dst_rectangle.width = width; |
- | |
2746 | dst_rectangle.height = height; |
- | |
2747 | - | ||
2748 | _cairo_region_init_rectangle (&clear_region, &dst_rectangle); |
- | |
2749 | - | ||
2750 | if (clip_region != NULL) { |
- | |
2751 | status = cairo_region_intersect (&clear_region, clip_region); |
- | |
2752 | if (unlikely (status)) |
- | |
2753 | goto CLEANUP_REGIONS; |
- | |
2754 | } |
- | |
2755 | - | ||
2756 | if (src_rectangle != NULL) { |
- | |
2757 | if (! _cairo_rectangle_intersect (&dst_rectangle, src_rectangle)) |
- | |
2758 | goto EMPTY; |
- | |
2759 | } |
- | |
2760 | - | ||
2761 | if (mask_rectangle != NULL) { |
- | |
2762 | if (! _cairo_rectangle_intersect (&dst_rectangle, mask_rectangle)) |
- | |
2763 | goto EMPTY; |
- | |
2764 | } |
- | |
2765 | - | ||
2766 | /* Now compute the area that is in dst but not drawn */ |
- | |
2767 | status = cairo_region_subtract_rectangle (&clear_region, &dst_rectangle); |
- | |
2768 | if (unlikely (status) || cairo_region_is_empty (&clear_region)) |
- | |
2769 | goto CLEANUP_REGIONS; |
- | |
2770 | - | ||
2771 | EMPTY: |
- | |
2772 | status = _cairo_surface_fill_region (dst, CAIRO_OPERATOR_CLEAR, |
- | |
2773 | CAIRO_COLOR_TRANSPARENT, |
- | |
2774 | &clear_region); |
- | |
2775 | - | ||
2776 | CLEANUP_REGIONS: |
2563 | surface->serial++; |
2777 | _cairo_region_fini (&clear_region); |
- | |
2778 | - | ||
2779 | return _cairo_surface_set_error (dst, status); |
- | |
2780 | } |
- | |
2781 | - | ||
2782 | /** |
- | |
2783 | * _cairo_surface_composite_fixup_unbounded: |
- | |
2784 | * @dst: the destination surface |
- | |
2785 | * @src_attr: source surface attributes (from _cairo_pattern_acquire_surface()) |
- | |
2786 | * @src_width: width of source surface |
- | |
2787 | * @src_height: height of source surface |
- | |
2788 | * @mask_attr: mask surface attributes or %NULL if no mask |
- | |
2789 | * @mask_width: width of mask surface |
- | |
2790 | * @mask_height: height of mask surface |
- | |
2791 | * @src_x: @src_x from _cairo_surface_composite() |
- | |
2792 | * @src_y: @src_y from _cairo_surface_composite() |
- | |
2793 | * @mask_x: @mask_x from _cairo_surface_composite() |
- | |
2794 | * @mask_y: @mask_y from _cairo_surface_composite() |
- | |
2795 | * @dst_x: @dst_x from _cairo_surface_composite() |
- | |
2796 | * @dst_y: @dst_y from _cairo_surface_composite() |
- | |
2797 | * @width: @width from _cairo_surface_composite() |
- | |
2798 | * @height: @height_x from _cairo_surface_composite() |
- | |
2799 | * |
- | |
2800 | * Eeek! Too many parameters! This is a helper function to take care of fixing |
- | |
2801 | * up for bugs in libpixman and RENDER where, when asked to composite an |
- | |
2802 | * untransformed surface with an unbounded operator (like CLEAR or SOURCE) |
- | |
2803 | * only the region inside both the source and the mask is affected. |
- | |
2804 | * This function clears the region that should have been drawn but was wasn't. |
- | |
2805 | **/ |
- | |
2806 | cairo_status_t |
- | |
2807 | _cairo_surface_composite_fixup_unbounded (cairo_surface_t *dst, |
- | |
2808 | cairo_surface_attributes_t *src_attr, |
- | |
2809 | int src_width, |
- | |
2810 | int src_height, |
- | |
2811 | cairo_surface_attributes_t *mask_attr, |
- | |
2812 | int mask_width, |
- | |
2813 | int mask_height, |
- | |
2814 | int src_x, |
- | |
2815 | int src_y, |
- | |
2816 | int mask_x, |
- | |
2817 | int mask_y, |
- | |
2818 | int dst_x, |
- | |
2819 | int dst_y, |
- | |
2820 | unsigned int width, |
- | |
2821 | unsigned int height, |
- | |
2822 | cairo_region_t *clip_region) |
- | |
2823 | { |
- | |
2824 | cairo_rectangle_int_t src_tmp, mask_tmp; |
- | |
2825 | cairo_rectangle_int_t *src_rectangle = NULL; |
- | |
2826 | cairo_rectangle_int_t *mask_rectangle = NULL; |
- | |
2827 | - | ||
2828 | if (unlikely (dst->status)) |
- | |
2829 | return dst->status; |
- | |
2830 | - | ||
2831 | assert (_cairo_surface_is_writable (dst)); |
- | |
2832 | - | ||
2833 | /* The RENDER/libpixman operators are clipped to the bounds of the untransformed, |
- | |
2834 | * non-repeating sources and masks. Other sources and masks can be ignored. |
- | |
2835 | */ |
- | |
2836 | if (_cairo_matrix_is_integer_translation (&src_attr->matrix, NULL, NULL) && |
- | |
2837 | src_attr->extend == CAIRO_EXTEND_NONE) |
- | |
2838 | { |
- | |
2839 | src_tmp.x = (dst_x - (src_x + src_attr->x_offset)); |
- | |
2840 | src_tmp.y = (dst_y - (src_y + src_attr->y_offset)); |
- | |
2841 | src_tmp.width = src_width; |
- | |
2842 | src_tmp.height = src_height; |
- | |
2843 | - | ||
2844 | src_rectangle = &src_tmp; |
- | |
2845 | } |
- | |
2846 | - | ||
2847 | if (mask_attr && |
- | |
2848 | _cairo_matrix_is_integer_translation (&mask_attr->matrix, NULL, NULL) && |
- | |
2849 | mask_attr->extend == CAIRO_EXTEND_NONE) |
- | |
2850 | { |
- | |
2851 | mask_tmp.x = (dst_x - (mask_x + mask_attr->x_offset)); |
- | |
2852 | mask_tmp.y = (dst_y - (mask_y + mask_attr->y_offset)); |
- | |
2853 | mask_tmp.width = mask_width; |
- | |
2854 | mask_tmp.height = mask_height; |
- | |
2855 | - | ||
2856 | mask_rectangle = &mask_tmp; |
- | |
2857 | } |
- | |
2858 | - | ||
2859 | return _cairo_surface_composite_fixup_unbounded_internal (dst, src_rectangle, mask_rectangle, |
- | |
2860 | dst_x, dst_y, width, height, |
- | |
2861 | clip_region); |
- | |
2862 | } |
- | |
2863 | - | ||
2864 | /** |
- | |
2865 | * _cairo_surface_composite_shape_fixup_unbounded: |
- | |
2866 | * @dst: the destination surface |
- | |
2867 | * @src_attr: source surface attributes (from _cairo_pattern_acquire_surface()) |
- | |
2868 | * @src_width: width of source surface |
- | |
2869 | * @src_height: height of source surface |
- | |
2870 | * @mask_width: width of mask surface |
- | |
2871 | * @mask_height: height of mask surface |
- | |
2872 | * @src_x: @src_x from _cairo_surface_composite() |
- | |
2873 | * @src_y: @src_y from _cairo_surface_composite() |
- | |
2874 | * @mask_x: @mask_x from _cairo_surface_composite() |
- | |
2875 | * @mask_y: @mask_y from _cairo_surface_composite() |
- | |
2876 | * @dst_x: @dst_x from _cairo_surface_composite() |
- | |
2877 | * @dst_y: @dst_y from _cairo_surface_composite() |
- | |
2878 | * @width: @width from _cairo_surface_composite() |
- | |
2879 | * @height: @height_x from _cairo_surface_composite() |
- | |
2880 | * |
- | |
2881 | * Like _cairo_surface_composite_fixup_unbounded(), but instead of |
- | |
2882 | * handling the case where we have a source pattern and a mask |
- | |
2883 | * pattern, handle the case where we are compositing a source pattern |
- | |
2884 | * using a mask we create ourselves, as in |
- | |
2885 | * _cairo_surface_composite_glyphs() or _cairo_surface_composite_trapezoids() |
- | |
2886 | **/ |
- | |
2887 | cairo_status_t |
- | |
2888 | _cairo_surface_composite_shape_fixup_unbounded (cairo_surface_t *dst, |
- | |
2889 | cairo_surface_attributes_t *src_attr, |
- | |
2890 | int src_width, |
- | |
2891 | int src_height, |
- | |
2892 | int mask_width, |
- | |
2893 | int mask_height, |
- | |
2894 | int src_x, |
- | |
2895 | int src_y, |
- | |
2896 | int mask_x, |
- | |
2897 | int mask_y, |
- | |
2898 | int dst_x, |
- | |
2899 | int dst_y, |
- | |
2900 | unsigned int width, |
- | |
2901 | unsigned int height, |
- | |
2902 | cairo_region_t *clip_region) |
- | |
2903 | { |
- | |
2904 | cairo_rectangle_int_t src_tmp, *src= NULL; |
- | |
2905 | cairo_rectangle_int_t mask; |
- | |
2906 | - | ||
2907 | if (dst->status) |
- | |
2908 | return dst->status; |
- | |
2909 | - | ||
2910 | assert (_cairo_surface_is_writable (dst)); |
- | |
2911 | - | ||
2912 | /* The RENDER/libpixman operators are clipped to the bounds of the untransformed, |
- | |
2913 | * non-repeating sources and masks. Other sources and masks can be ignored. |
- | |
2914 | */ |
- | |
2915 | if (_cairo_matrix_is_integer_translation (&src_attr->matrix, NULL, NULL) && |
- | |
2916 | src_attr->extend == CAIRO_EXTEND_NONE) |
- | |
2917 | { |
- | |
2918 | src_tmp.x = (dst_x - (src_x + src_attr->x_offset)); |
- | |
2919 | src_tmp.y = (dst_y - (src_y + src_attr->y_offset)); |
- | |
2920 | src_tmp.width = src_width; |
- | |
2921 | src_tmp.height = src_height; |
- | |
2922 | - | ||
2923 | src = &src_tmp; |
- | |
2924 | } |
- | |
2925 | - | ||
2926 | mask.x = dst_x - mask_x; |
- | |
2927 | mask.y = dst_y - mask_y; |
- | |
2928 | mask.width = mask_width; |
- | |
2929 | mask.height = mask_height; |
- | |
2930 | - | ||
2931 | return _cairo_surface_composite_fixup_unbounded_internal (dst, src, &mask, |
2564 | } |
Line 2932... | Line 2565... | ||
2932 | dst_x, dst_y, width, height, |
2565 | |
2933 | clip_region); |
2566 | return _cairo_surface_set_error (surface, status); |
2934 | } |
2567 | } |
2935 | 2568 | ||
2936 | /** |
2569 | /** |
2937 | * _cairo_surface_set_resolution |
2570 | * _cairo_surface_set_resolution: |
2938 | * @surface: the surface |
2571 | * @surface: the surface |
2939 | * @x_res: x resolution, in dpi |
2572 | * @x_res: x resolution, in dpi |
2940 | * @y_res: y resolution, in dpi |
2573 | * @y_res: y resolution, in dpi |
2941 | * |
2574 | * |
2942 | * Set the actual surface resolution of @surface to the given x and y DPI. |
2575 | * Set the actual surface resolution of @surface to the given x and y DPI. |
2943 | * Mainly used for correctly computing the scale factor when fallback |
2576 | * Mainly used for correctly computing the scale factor when fallback |
2944 | * rendering needs to take place in the paginated surface. |
2577 | * rendering needs to take place in the paginated surface. |
2945 | */ |
2578 | **/ |
2946 | void |
2579 | void |
Line 2953... | Line 2586... | ||
2953 | 2586 | ||
2954 | surface->x_resolution = x_res; |
2587 | surface->x_resolution = x_res; |
2955 | surface->y_resolution = y_res; |
2588 | surface->y_resolution = y_res; |
Line 2956... | Line -... | ||
2956 | } |
- | |
2957 | - | ||
2958 | /* Generic methods for determining operation extents. */ |
- | |
2959 | - | ||
2960 | static void |
- | |
2961 | _rectangle_intersect_clip (cairo_rectangle_int_t *extents, cairo_clip_t *clip) |
- | |
2962 | { |
- | |
2963 | const cairo_rectangle_int_t *clip_extents; |
- | |
2964 | cairo_bool_t is_empty; |
- | |
2965 | - | ||
2966 | clip_extents = NULL; |
- | |
2967 | if (clip != NULL) |
- | |
2968 | clip_extents = _cairo_clip_get_extents (clip); |
- | |
2969 | - | ||
2970 | if (clip_extents != NULL) |
- | |
2971 | is_empty = _cairo_rectangle_intersect (extents, clip_extents); |
- | |
2972 | } |
- | |
2973 | - | ||
2974 | static void |
- | |
2975 | _cairo_surface_operation_extents (cairo_surface_t *surface, |
- | |
2976 | cairo_operator_t op, |
- | |
2977 | const cairo_pattern_t *source, |
- | |
2978 | cairo_clip_t *clip, |
- | |
2979 | cairo_rectangle_int_t *extents) |
- | |
2980 | { |
- | |
2981 | cairo_bool_t is_empty; |
- | |
2982 | - | ||
2983 | is_empty = _cairo_surface_get_extents (surface, extents); |
- | |
2984 | - | ||
2985 | if (_cairo_operator_bounded_by_source (op)) { |
- | |
2986 | cairo_rectangle_int_t source_extents; |
- | |
2987 | - | ||
2988 | _cairo_pattern_get_extents (source, &source_extents); |
- | |
2989 | is_empty = _cairo_rectangle_intersect (extents, &source_extents); |
- | |
2990 | } |
- | |
2991 | - | ||
2992 | _rectangle_intersect_clip (extents, clip); |
- | |
2993 | } |
- | |
2994 | - | ||
2995 | cairo_status_t |
- | |
2996 | _cairo_surface_paint_extents (cairo_surface_t *surface, |
- | |
2997 | cairo_operator_t op, |
- | |
2998 | const cairo_pattern_t *source, |
- | |
2999 | cairo_clip_t *clip, |
- | |
3000 | cairo_rectangle_int_t *extents) |
- | |
3001 | { |
- | |
3002 | _cairo_surface_operation_extents (surface, op, source, clip, extents); |
- | |
3003 | return CAIRO_STATUS_SUCCESS; |
- | |
3004 | } |
- | |
3005 | - | ||
3006 | cairo_status_t |
- | |
3007 | _cairo_surface_mask_extents (cairo_surface_t *surface, |
- | |
3008 | cairo_operator_t op, |
- | |
3009 | const cairo_pattern_t *source, |
- | |
3010 | const cairo_pattern_t *mask, |
- | |
3011 | cairo_clip_t *clip, |
- | |
3012 | cairo_rectangle_int_t *extents) |
- | |
3013 | { |
- | |
3014 | cairo_bool_t is_empty; |
- | |
3015 | - | ||
3016 | _cairo_surface_operation_extents (surface, op, source, clip, extents); |
- | |
3017 | - | ||
3018 | if (_cairo_operator_bounded_by_mask (op)) { |
- | |
3019 | cairo_rectangle_int_t mask_extents; |
- | |
3020 | - | ||
3021 | _cairo_pattern_get_extents (mask, &mask_extents); |
- | |
3022 | is_empty = _cairo_rectangle_intersect (extents, &mask_extents); |
- | |
3023 | } |
- | |
3024 | - | ||
3025 | return CAIRO_STATUS_SUCCESS; |
- | |
3026 | } |
- | |
3027 | - | ||
3028 | cairo_status_t |
- | |
3029 | _cairo_surface_stroke_extents (cairo_surface_t *surface, |
- | |
3030 | cairo_operator_t op, |
- | |
3031 | const cairo_pattern_t *source, |
- | |
3032 | cairo_path_fixed_t *path, |
- | |
3033 | const cairo_stroke_style_t *style, |
- | |
3034 | const cairo_matrix_t *ctm, |
- | |
3035 | const cairo_matrix_t *ctm_inverse, |
- | |
3036 | double tolerance, |
- | |
3037 | cairo_antialias_t antialias, |
- | |
3038 | cairo_clip_t *clip, |
- | |
3039 | cairo_rectangle_int_t *extents) |
- | |
3040 | { |
- | |
3041 | cairo_status_t status; |
- | |
3042 | cairo_bool_t is_empty; |
- | |
3043 | - | ||
3044 | _cairo_surface_operation_extents (surface, op, source, clip, extents); |
- | |
3045 | - | ||
3046 | if (_cairo_operator_bounded_by_mask (op)) { |
- | |
3047 | cairo_rectangle_int_t mask_extents; |
- | |
3048 | - | ||
3049 | status = _cairo_path_fixed_stroke_extents (path, style, |
- | |
3050 | ctm, ctm_inverse, |
- | |
3051 | tolerance, |
- | |
3052 | &mask_extents); |
- | |
3053 | if (unlikely (status)) |
- | |
3054 | return status; |
- | |
3055 | - | ||
3056 | is_empty = _cairo_rectangle_intersect (extents, &mask_extents); |
- | |
3057 | } |
- | |
3058 | - | ||
3059 | return CAIRO_STATUS_SUCCESS; |
- | |
3060 | } |
- | |
3061 | - | ||
3062 | cairo_status_t |
- | |
3063 | _cairo_surface_fill_extents (cairo_surface_t *surface, |
- | |
3064 | cairo_operator_t op, |
- | |
3065 | const cairo_pattern_t *source, |
- | |
3066 | cairo_path_fixed_t *path, |
- | |
3067 | cairo_fill_rule_t fill_rule, |
- | |
3068 | double tolerance, |
- | |
3069 | cairo_antialias_t antialias, |
- | |
3070 | cairo_clip_t *clip, |
- | |
3071 | cairo_rectangle_int_t *extents) |
- | |
3072 | { |
- | |
3073 | cairo_bool_t is_empty; |
- | |
3074 | - | ||
3075 | _cairo_surface_operation_extents (surface, op, source, clip, extents); |
- | |
3076 | - | ||
3077 | if (_cairo_operator_bounded_by_mask (op)) { |
- | |
3078 | cairo_rectangle_int_t mask_extents; |
- | |
3079 | - | ||
3080 | _cairo_path_fixed_fill_extents (path, fill_rule, tolerance, |
- | |
3081 | &mask_extents); |
- | |
3082 | is_empty = _cairo_rectangle_intersect (extents, &mask_extents); |
- | |
3083 | } |
- | |
3084 | - | ||
3085 | return CAIRO_STATUS_SUCCESS; |
- | |
3086 | } |
- | |
3087 | - | ||
3088 | cairo_status_t |
- | |
3089 | _cairo_surface_glyphs_extents (cairo_surface_t *surface, |
- | |
3090 | cairo_operator_t op, |
- | |
3091 | const cairo_pattern_t *source, |
- | |
3092 | cairo_glyph_t *glyphs, |
- | |
3093 | int num_glyphs, |
- | |
3094 | cairo_scaled_font_t *scaled_font, |
- | |
3095 | cairo_clip_t *clip, |
- | |
3096 | cairo_rectangle_int_t *extents) |
- | |
3097 | { |
- | |
3098 | cairo_status_t status; |
- | |
3099 | cairo_bool_t is_empty; |
- | |
3100 | - | ||
3101 | _cairo_surface_operation_extents (surface, op, source, clip, extents); |
- | |
3102 | - | ||
3103 | if (_cairo_operator_bounded_by_mask (op)) { |
- | |
3104 | cairo_rectangle_int_t glyph_extents; |
- | |
3105 | - | ||
3106 | status = _cairo_scaled_font_glyph_device_extents (scaled_font, |
- | |
3107 | glyphs, |
- | |
3108 | num_glyphs, |
- | |
3109 | &glyph_extents, |
- | |
3110 | NULL); |
- | |
3111 | if (unlikely (status)) |
- | |
3112 | return status; |
- | |
3113 | - | ||
3114 | is_empty = _cairo_rectangle_intersect (extents, &glyph_extents); |
- | |
3115 | } |
- | |
3116 | - | ||
3117 | return CAIRO_STATUS_SUCCESS; |
- | |
3118 | } |
2589 | } |
3119 | 2590 | ||
3120 | cairo_surface_t * |
2591 | cairo_surface_t * |
- | 2592 | _cairo_surface_create_in_error (cairo_status_t status) |
|
3121 | _cairo_surface_create_in_error (cairo_status_t status) |
2593 | { |
3122 | { |
2594 | assert (status < CAIRO_STATUS_LAST_STATUS); |
3123 | switch (status) { |
2595 | switch (status) { |
3124 | case CAIRO_STATUS_NO_MEMORY: |
2596 | case CAIRO_STATUS_NO_MEMORY: |
3125 | return (cairo_surface_t *) &_cairo_surface_nil; |
2597 | return (cairo_surface_t *) &_cairo_surface_nil; |
Line 3172... | Line 2644... | ||
3172 | case CAIRO_STATUS_NEGATIVE_COUNT: |
2644 | case CAIRO_STATUS_NEGATIVE_COUNT: |
3173 | case CAIRO_STATUS_INVALID_CLUSTERS: |
2645 | case CAIRO_STATUS_INVALID_CLUSTERS: |
3174 | case CAIRO_STATUS_INVALID_SLANT: |
2646 | case CAIRO_STATUS_INVALID_SLANT: |
3175 | case CAIRO_STATUS_INVALID_WEIGHT: |
2647 | case CAIRO_STATUS_INVALID_WEIGHT: |
3176 | case CAIRO_STATUS_USER_FONT_NOT_IMPLEMENTED: |
2648 | case CAIRO_STATUS_USER_FONT_NOT_IMPLEMENTED: |
- | 2649 | case CAIRO_STATUS_INVALID_MESH_CONSTRUCTION: |
|
- | 2650 | case CAIRO_STATUS_DEVICE_FINISHED: |
|
- | 2651 | default: |
|
- | 2652 | _cairo_error_throw (CAIRO_STATUS_NO_MEMORY); |
|
- | 2653 | return (cairo_surface_t *) &_cairo_surface_nil; |
|
- | 2654 | } |
|
- | 2655 | } |
|
- | 2656 | ||
- | 2657 | cairo_surface_t * |
|
- | 2658 | _cairo_int_surface_create_in_error (cairo_int_status_t status) |
|
- | 2659 | { |
|
- | 2660 | if (status < CAIRO_INT_STATUS_LAST_STATUS) |
|
- | 2661 | return _cairo_surface_create_in_error (status); |
|
- | 2662 | ||
- | 2663 | switch ((int)status) { |
|
- | 2664 | case CAIRO_INT_STATUS_UNSUPPORTED: |
|
- | 2665 | return (cairo_surface_t *) &_cairo_surface_nil_unsupported; |
|
- | 2666 | case CAIRO_INT_STATUS_NOTHING_TO_DO: |
|
- | 2667 | return (cairo_surface_t *) &_cairo_surface_nil_nothing_to_do; |
|
3177 | default: |
2668 | default: |
3178 | _cairo_error_throw (CAIRO_STATUS_NO_MEMORY); |
2669 | _cairo_error_throw (CAIRO_STATUS_NO_MEMORY); |
3179 | return (cairo_surface_t *) &_cairo_surface_nil; |
2670 | return (cairo_surface_t *) &_cairo_surface_nil; |
3180 | } |
2671 | } |
3181 | } |
2672 | } |