mirror of
https://gitlab.freedesktop.org/cairo/cairo.git
synced 2026-05-02 02:38:07 +02:00
Finish implementing correct paints in transformed recording patterns
This commit is contained in:
parent
c5b24a3e12
commit
ceae137ba6
6 changed files with 223 additions and 75 deletions
|
|
@ -71,6 +71,7 @@ typedef struct cairo_svg_surface {
|
|||
unsigned int clip_level;
|
||||
|
||||
cairo_bool_t paint_used;
|
||||
cairo_bool_t transitive_paint_used;
|
||||
|
||||
cairo_paginated_mode_t paginated_mode;
|
||||
|
||||
|
|
|
|||
|
|
@ -152,13 +152,24 @@ typedef struct _cairo_svg_source_surface {
|
|||
unsigned int id;
|
||||
unsigned char *unique_id;
|
||||
unsigned long unique_id_length;
|
||||
cairo_bool_t paint_used;
|
||||
cairo_bool_t transitive_paint_used;
|
||||
} cairo_svg_source_surface_t;
|
||||
|
||||
/*
|
||||
* _cairo_svg_paint_element and _cairo_svg_paint are used to implement paints in transformed recording patterns.
|
||||
*/
|
||||
|
||||
typedef struct _cairo_svg_paint_element {
|
||||
unsigned int source_id;
|
||||
cairo_matrix_t matrix;
|
||||
} cairo_svg_paint_element_t;
|
||||
|
||||
typedef struct _cairo_svg_paint {
|
||||
cairo_hash_entry_t base;
|
||||
unsigned int source_id;
|
||||
cairo_output_stream_t *xml_node;
|
||||
cairo_bool_t paint_used;
|
||||
cairo_array_t paint_elements;
|
||||
cairo_box_double_t box;
|
||||
} cairo_svg_paint_t;
|
||||
|
||||
typedef struct cairo_svg_page {
|
||||
|
|
@ -559,21 +570,65 @@ _cairo_svg_paint_pluck (void *entry, void *closure)
|
|||
cairo_hash_table_t *patterns = closure;
|
||||
|
||||
_cairo_hash_table_remove (patterns, &paint->base);
|
||||
(void) _cairo_output_stream_destroy (paint->xml_node);
|
||||
_cairo_array_fini (&paint->paint_elements);
|
||||
free (paint);
|
||||
}
|
||||
|
||||
static void
|
||||
_cairo_svg_paint_emit (void *entry, void *closure)
|
||||
_cairo_svg_paint_compute (cairo_svg_document_t *document, cairo_svg_paint_t *paint) {
|
||||
for (unsigned int i = 0; i < paint->paint_elements.num_elements; i++) {
|
||||
cairo_svg_paint_element_t *paint_element = _cairo_array_index (&paint->paint_elements, i);
|
||||
|
||||
cairo_svg_paint_t paint_key;
|
||||
paint_key.source_id = paint_element->source_id;
|
||||
_cairo_svg_paint_init_key (&paint_key);
|
||||
|
||||
cairo_svg_paint_t *found_paint_entry = _cairo_hash_table_lookup (document->paints,
|
||||
&paint_key.base);
|
||||
assert (found_paint_entry);
|
||||
|
||||
_cairo_svg_paint_compute (document, found_paint_entry);
|
||||
|
||||
cairo_box_double_t box = found_paint_entry->box;
|
||||
_cairo_matrix_transform_bounding_box (&paint_element->matrix,
|
||||
&box.p1.x, &box.p1.y,
|
||||
&box.p2.x, &box.p2.y,
|
||||
NULL);
|
||||
|
||||
if (i == 0) {
|
||||
paint->box = box;
|
||||
} else {
|
||||
paint->box.p1.x = MIN (paint->box.p1.x, box.p1.x);
|
||||
paint->box.p1.y = MIN (paint->box.p1.y, box.p1.y);
|
||||
paint->box.p2.x = MAX (paint->box.p2.x, box.p2.x);
|
||||
paint->box.p2.y = MAX (paint->box.p2.y, box.p2.y);
|
||||
}
|
||||
}
|
||||
_cairo_array_truncate (&paint->paint_elements, 0);
|
||||
}
|
||||
|
||||
static void
|
||||
_cairo_svg_paint_compute_func (void *entry, void *closure)
|
||||
{
|
||||
cairo_svg_paint_t *paint = entry;
|
||||
cairo_svg_document_t *document = closure;
|
||||
|
||||
_cairo_svg_paint_compute (document, paint);
|
||||
}
|
||||
|
||||
static void
|
||||
_cairo_svg_paint_emit_func (void *entry, void *closure)
|
||||
{
|
||||
cairo_svg_paint_t *paint = entry;
|
||||
cairo_output_stream_t *output = closure;
|
||||
|
||||
_cairo_output_stream_printf (output,
|
||||
"<g id=\"paint-%d\">\n",
|
||||
paint->source_id);
|
||||
_cairo_memory_stream_copy (paint->xml_node, output);
|
||||
_cairo_output_stream_printf (output, "</g>\n");
|
||||
if (paint->paint_used) {
|
||||
_cairo_output_stream_printf (output,
|
||||
"<rect id=\"paint-%d\" x=\"%f\" y=\"%f\" width=\"%f\" height=\"%f\"/>\n",
|
||||
paint->source_id,
|
||||
paint->box.p1.x, paint->box.p1.y,
|
||||
paint->box.p2.x - paint->box.p1.x, paint->box.p2.y - paint->box.p1.y);
|
||||
}
|
||||
}
|
||||
|
||||
static cairo_status_t
|
||||
|
|
@ -768,6 +823,7 @@ _cairo_svg_surface_create_for_document (cairo_svg_document_t *document,
|
|||
surface->current_clipper_output_stream = NULL;
|
||||
surface->clip_level = 0;
|
||||
surface->paint_used = FALSE;
|
||||
surface->transitive_paint_used = FALSE;
|
||||
|
||||
surface->paginated_mode = CAIRO_PAGINATED_MODE_ANALYZE;
|
||||
|
||||
|
|
@ -1285,31 +1341,31 @@ _cairo_svg_surface_emit_static_filter (cairo_svg_document_t *document, enum cair
|
|||
|
||||
#define _CAIRO_SVG_SURFACE_OUTPUT_FE_COMPOSITE_FILTER(operation) \
|
||||
_cairo_output_stream_printf (document->xml_node_filters, \
|
||||
"<filter id=\"filter-%d\" filterUnits=\"userSpaceOnUse\" " \
|
||||
"x=\"0%%\" y=\"0%%\" width=\"100%%\" height=\"100%%\">\n" \
|
||||
"<feImage xlink:href=\"#compositing-group-%d\" result=\"source\"/>\n" \
|
||||
"<feImage xlink:href=\"#compositing-group-%d\" result=\"destination\"/>\n" \
|
||||
"<feComposite in=\"source\" in2=\"destination\" " \
|
||||
"operator=\"" operation "\" " \
|
||||
"color-interpolation-filters=\"sRGB\"/>\n" \
|
||||
"</filter>\n", \
|
||||
filter_id, \
|
||||
source_compositing_group_id, \
|
||||
destination_compositing_group_id)
|
||||
"<filter id=\"filter-%d\" filterUnits=\"userSpaceOnUse\" " \
|
||||
"x=\"0%%\" y=\"0%%\" width=\"100%%\" height=\"100%%\">\n" \
|
||||
"<feImage xlink:href=\"#compositing-group-%d\" result=\"source\"/>\n" \
|
||||
"<feImage xlink:href=\"#compositing-group-%d\" result=\"destination\"/>\n" \
|
||||
"<feComposite in=\"source\" in2=\"destination\" " \
|
||||
"operator=\"" operation "\" " \
|
||||
"color-interpolation-filters=\"sRGB\"/>\n" \
|
||||
"</filter>\n", \
|
||||
filter_id, \
|
||||
source_compositing_group_id, \
|
||||
destination_compositing_group_id)
|
||||
|
||||
#define _CAIRO_SVG_SURFACE_OUTPUT_FE_BLEND_FILTER(mode) \
|
||||
_cairo_output_stream_printf (document->xml_node_filters, \
|
||||
"<filter id=\"filter-%d\" filterUnits=\"userSpaceOnUse\" " \
|
||||
"x=\"0%%\" y=\"0%%\" width=\"100%%\" height=\"100%%\">\n" \
|
||||
"<feImage xlink:href=\"#compositing-group-%d\" result=\"source\"/>\n" \
|
||||
"<feImage xlink:href=\"#compositing-group-%d\" result=\"destination\"/>\n" \
|
||||
"<feBlend in=\"source\" in2=\"destination\" " \
|
||||
"mode=\"" mode "\" " \
|
||||
"color-interpolation-filters=\"sRGB\"/>\n" \
|
||||
"</filter>\n", \
|
||||
filter_id, \
|
||||
source_compositing_group_id, \
|
||||
destination_compositing_group_id)
|
||||
"<filter id=\"filter-%d\" filterUnits=\"userSpaceOnUse\" " \
|
||||
"x=\"0%%\" y=\"0%%\" width=\"100%%\" height=\"100%%\">\n" \
|
||||
"<feImage xlink:href=\"#compositing-group-%d\" result=\"source\"/>\n" \
|
||||
"<feImage xlink:href=\"#compositing-group-%d\" result=\"destination\"/>\n" \
|
||||
"<feBlend in=\"source\" in2=\"destination\" " \
|
||||
"mode=\"" mode "\" " \
|
||||
"color-interpolation-filters=\"sRGB\"/>\n" \
|
||||
"</filter>\n", \
|
||||
filter_id, \
|
||||
source_compositing_group_id, \
|
||||
destination_compositing_group_id)
|
||||
|
||||
static unsigned int
|
||||
_cairo_svg_surface_emit_parametric_filter (cairo_svg_document_t *document,
|
||||
|
|
@ -1335,7 +1391,7 @@ _cairo_svg_surface_emit_parametric_filter (cairo_svg_document_t *document,
|
|||
_CAIRO_SVG_SURFACE_OUTPUT_FE_COMPOSITE_FILTER ("xor");
|
||||
break;
|
||||
case CAIRO_SVG_FILTER_ADD:
|
||||
// This can also be done with <feComposite operator="lighter"/>, but it is not from SVG 1.1
|
||||
// This can also be done with <feComposite operator="lighter"/>, but it is not from SVG 1.1
|
||||
_cairo_output_stream_printf (document->xml_node_filters,
|
||||
"<filter id=\"filter-%d\" filterUnits=\"userSpaceOnUse\" "
|
||||
"x=\"0%%\" y=\"0%%\" width=\"100%%\" height=\"100%%\">\n"
|
||||
|
|
@ -1395,7 +1451,7 @@ _cairo_svg_surface_emit_parametric_filter (cairo_svg_document_t *document,
|
|||
_CAIRO_SVG_SURFACE_OUTPUT_FE_BLEND_FILTER ("luminosity");
|
||||
break;
|
||||
default:
|
||||
printf("%d\n", filter);
|
||||
printf ("%d\n", filter);
|
||||
ASSERT_NOT_REACHED;
|
||||
}
|
||||
return filter_id;
|
||||
|
|
@ -1742,7 +1798,8 @@ static cairo_status_t
|
|||
_cairo_svg_surface_emit_recording_surface (cairo_svg_document_t *document,
|
||||
cairo_recording_surface_t *source,
|
||||
unsigned int source_id,
|
||||
cairo_bool_t *paint_used)
|
||||
cairo_bool_t *paint_used,
|
||||
cairo_bool_t *transitive_paint_used)
|
||||
{
|
||||
cairo_status_t status;
|
||||
|
||||
|
|
@ -1827,6 +1884,7 @@ _cairo_svg_surface_emit_recording_surface (cairo_svg_document_t *document,
|
|||
_cairo_output_stream_printf (document->xml_node_defs, "</g>\n");
|
||||
|
||||
*paint_used = svg_surface->paint_used;
|
||||
*transitive_paint_used = svg_surface->transitive_paint_used;
|
||||
|
||||
status = cairo_surface_status (paginated_surface);
|
||||
cairo_surface_destroy (paginated_surface);
|
||||
|
|
@ -1846,7 +1904,8 @@ _cairo_svg_surface_to_recording_surface (const cairo_surface_pattern_t *pattern)
|
|||
}
|
||||
|
||||
static cairo_bool_t
|
||||
_cairo_svg_surface_svg_pattern_should_be_used (const cairo_pattern_t *pattern) {
|
||||
_cairo_svg_surface_svg_pattern_should_be_used (const cairo_pattern_t *pattern)
|
||||
{
|
||||
cairo_rectangle_int_t extents;
|
||||
return pattern->type == CAIRO_PATTERN_TYPE_SURFACE &&
|
||||
pattern->extend == CAIRO_EXTEND_REPEAT &&
|
||||
|
|
@ -1854,7 +1913,8 @@ _cairo_svg_surface_svg_pattern_should_be_used (const cairo_pattern_t *pattern) {
|
|||
}
|
||||
|
||||
static cairo_bool_t
|
||||
_cairo_svg_surface_svg_clip_or_svg_mask_should_be_used (const cairo_pattern_t *pattern) {
|
||||
_cairo_svg_surface_svg_clip_or_svg_mask_should_be_used (const cairo_pattern_t *pattern)
|
||||
{
|
||||
return pattern->type == CAIRO_PATTERN_TYPE_SURFACE && !_cairo_svg_surface_svg_pattern_should_be_used (pattern);
|
||||
}
|
||||
|
||||
|
|
@ -1886,30 +1946,34 @@ _cairo_svg_surface_emit_composite_recording_pattern (cairo_output_stream_t *outp
|
|||
|
||||
cairo_recording_surface_t *recording_surface = _cairo_svg_surface_to_recording_surface (pattern);
|
||||
if (is_new) {
|
||||
cairo_bool_t paint_used;
|
||||
|
||||
status = _cairo_svg_surface_emit_recording_surface (document,
|
||||
recording_surface,
|
||||
source_id,
|
||||
&source_surface->paint_used);
|
||||
&paint_used,
|
||||
&source_surface->transitive_paint_used);
|
||||
if (unlikely (status)) {
|
||||
return status;
|
||||
}
|
||||
}
|
||||
|
||||
if (is_new && source_surface->paint_used) {
|
||||
cairo_svg_paint_t *paint_entry = malloc (sizeof (cairo_svg_paint_t));
|
||||
if (paint_entry == NULL) {
|
||||
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
}
|
||||
paint_entry->source_id = source_id;
|
||||
paint_entry->xml_node = _cairo_memory_stream_create();
|
||||
_cairo_svg_paint_init_key (paint_entry);
|
||||
status = _cairo_hash_table_insert (document->paints, &paint_entry->base);
|
||||
if (unlikely (status)) {
|
||||
return status;
|
||||
if (source_surface->transitive_paint_used) {
|
||||
cairo_svg_paint_t *paint_entry = malloc (sizeof (cairo_svg_paint_t));
|
||||
if (paint_entry == NULL) {
|
||||
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
}
|
||||
paint_entry->source_id = source_id;
|
||||
paint_entry->paint_used = paint_used;
|
||||
_cairo_array_init (&paint_entry->paint_elements, sizeof (cairo_svg_paint_element_t));
|
||||
_cairo_svg_paint_init_key (paint_entry);
|
||||
status = _cairo_hash_table_insert (document->paints, &paint_entry->base);
|
||||
if (unlikely (status)) {
|
||||
return status;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (source_surface->paint_used) {
|
||||
if (source_surface->transitive_paint_used) {
|
||||
cairo_svg_paint_t paint_key;
|
||||
paint_key.source_id = source_id;
|
||||
_cairo_svg_paint_init_key (&paint_key);
|
||||
|
|
@ -1918,25 +1982,26 @@ _cairo_svg_surface_emit_composite_recording_pattern (cairo_output_stream_t *outp
|
|||
&paint_key.base);
|
||||
assert (found_paint_entry);
|
||||
|
||||
_cairo_output_stream_printf (found_paint_entry->xml_node,
|
||||
"<use xlink:href=\"#paint-%d\"",
|
||||
surface->source_id);
|
||||
cairo_matrix_t matrix = pattern->base.matrix;
|
||||
cairo_svg_paint_element_t paint_element;
|
||||
paint_element.source_id = surface->source_id;
|
||||
paint_element.matrix = pattern->base.matrix;
|
||||
if (parent_matrix != NULL) {
|
||||
cairo_matrix_t parent_matrix_inverse = *parent_matrix;
|
||||
status = cairo_matrix_invert (&parent_matrix_inverse);
|
||||
/* cairo_pattern_set_matrix ensures the matrix is invertible */
|
||||
assert (status == CAIRO_STATUS_SUCCESS);
|
||||
cairo_matrix_multiply (&matrix, &parent_matrix_inverse, &matrix);
|
||||
cairo_matrix_multiply (&paint_element.matrix, &parent_matrix_inverse, &paint_element.matrix);
|
||||
}
|
||||
status = _cairo_array_append (&found_paint_entry->paint_elements, &paint_element);
|
||||
if (unlikely (status)) {
|
||||
return status;
|
||||
}
|
||||
_cairo_svg_surface_emit_transform (found_paint_entry->xml_node, "transform", &matrix, NULL);
|
||||
_cairo_output_stream_printf (found_paint_entry->xml_node, "/>\n");
|
||||
|
||||
surface->paint_used = TRUE;
|
||||
surface->transitive_paint_used = TRUE;
|
||||
}
|
||||
|
||||
if (pattern_id != invalid_pattern_id) {
|
||||
assert (!recording_surface->unbounded);
|
||||
assert (!recording_surface->unbounded);
|
||||
_cairo_output_stream_printf (output,
|
||||
"<pattern id=\"pattern-%d\" "
|
||||
"patternUnits=\"userSpaceOnUse\" "
|
||||
|
|
@ -2559,6 +2624,8 @@ _cairo_svg_surface_emit_paint (cairo_output_stream_t *output,
|
|||
}
|
||||
|
||||
surface->paint_used = TRUE;
|
||||
surface->transitive_paint_used = TRUE;
|
||||
|
||||
_cairo_output_stream_printf (output,
|
||||
"<use xlink:href=\"#paint-%d\"",
|
||||
surface->source_id);
|
||||
|
|
@ -2584,10 +2651,10 @@ _cairo_svg_surface_do_operator (cairo_output_stream_t *output,
|
|||
cairo_svg_document_t *document = surface->document;
|
||||
|
||||
if (op == CAIRO_OPERATOR_CLEAR) {
|
||||
/*
|
||||
* The result is the same as one of the SOURCE operation application with the same arguments,
|
||||
* but with an empty source.
|
||||
*/
|
||||
/*
|
||||
* The result is the same as one of the SOURCE operation application with the same arguments,
|
||||
* but with an empty source.
|
||||
*/
|
||||
|
||||
status = _cairo_output_stream_destroy (source_stream);
|
||||
if (unlikely (status)) {
|
||||
|
|
@ -2704,9 +2771,9 @@ _cairo_svg_surface_do_operator (cairo_output_stream_t *output,
|
|||
}
|
||||
|
||||
if (op == CAIRO_OPERATOR_DEST) {
|
||||
/*
|
||||
* The result is the destination.
|
||||
*/
|
||||
/*
|
||||
* The result is the destination.
|
||||
*/
|
||||
|
||||
_cairo_memory_stream_copy (destination_stream, surface->xml_node);
|
||||
status = _cairo_output_stream_destroy (destination_stream);
|
||||
|
|
@ -3750,13 +3817,33 @@ _cairo_svg_document_finish (cairo_svg_document_t *document)
|
|||
final_status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
}
|
||||
}
|
||||
|
||||
if (surface->transitive_paint_used) {
|
||||
cairo_svg_paint_t *paint_entry = malloc (sizeof (cairo_svg_paint_t));
|
||||
if (paint_entry == NULL) {
|
||||
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
}
|
||||
paint_entry->source_id = surface->source_id;
|
||||
paint_entry->paint_used = surface->paint_used;
|
||||
paint_entry->box.p1.x = 0;
|
||||
paint_entry->box.p1.y = 0;
|
||||
paint_entry->box.p2.x = document->width;
|
||||
paint_entry->box.p2.y = document->height;
|
||||
_cairo_array_init (&paint_entry->paint_elements, sizeof (cairo_svg_paint_element_t));
|
||||
_cairo_svg_paint_init_key (paint_entry);
|
||||
status = _cairo_hash_table_insert (document->paints, &paint_entry->base);
|
||||
if (unlikely (status)) {
|
||||
return status;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
_cairo_hash_table_foreach (document->paints, _cairo_svg_paint_compute_func, document);
|
||||
|
||||
if (_cairo_memory_stream_length (document->xml_node_filters) > 0 ||
|
||||
_cairo_memory_stream_length (document->xml_node_glyphs) > 0 ||
|
||||
_cairo_memory_stream_length (document->xml_node_defs) > 0 ||
|
||||
_cairo_hash_table_size (document->paints) != 0 ||
|
||||
(surface != NULL && surface->paint_used)) {
|
||||
_cairo_hash_table_size (document->paints) != 0) {
|
||||
_cairo_output_stream_printf (output, "<defs>\n");
|
||||
_cairo_memory_stream_copy (document->xml_node_filters, output);
|
||||
if (_cairo_memory_stream_length (document->xml_node_glyphs) > 0) {
|
||||
|
|
@ -3765,13 +3852,7 @@ _cairo_svg_document_finish (cairo_svg_document_t *document)
|
|||
_cairo_output_stream_printf (output, "</g>\n");
|
||||
}
|
||||
_cairo_memory_stream_copy (document->xml_node_defs, output);
|
||||
_cairo_hash_table_foreach (document->paints, _cairo_svg_paint_emit, output);
|
||||
if (surface != NULL && surface->paint_used) {
|
||||
_cairo_output_stream_printf (output,
|
||||
"<rect id=\"paint-%d\" x=\"0\" y=\"0\" width=\"%f\" height=\"%f\"/>\n",
|
||||
surface->source_id,
|
||||
document->width, document->height);
|
||||
}
|
||||
_cairo_hash_table_foreach (document->paints, _cairo_svg_paint_emit_func, output);
|
||||
_cairo_output_stream_printf (output, "</defs>\n");
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -281,6 +281,7 @@ test_sources = \
|
|||
record-neg-extents.c \
|
||||
record-mesh.c \
|
||||
record-replay-extend.c \
|
||||
record-transform-paint.c \
|
||||
recording-ink-extents.c \
|
||||
recording-surface-pattern.c \
|
||||
recording-surface-extend.c \
|
||||
|
|
|
|||
|
|
@ -281,6 +281,7 @@ test_sources = [
|
|||
'record-neg-extents.c',
|
||||
'record-mesh.c',
|
||||
'record-replay-extend.c',
|
||||
'record-transform-paint.c',
|
||||
'recording-ink-extents.c',
|
||||
'recording-surface-pattern.c',
|
||||
'recording-surface-extend.c',
|
||||
|
|
|
|||
64
test/record-transform-paint.c
Normal file
64
test/record-transform-paint.c
Normal file
|
|
@ -0,0 +1,64 @@
|
|||
/*
|
||||
* Copyright © 2021 Anton Danilkin
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person
|
||||
* obtaining a copy of this software and associated documentation
|
||||
* files (the "Software"), to deal in the Software without
|
||||
* restriction, including without limitation the rights to use, copy,
|
||||
* modify, merge, publish, distribute, sublicense, and/or sell copies
|
||||
* of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be
|
||||
* included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
|
||||
* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "cairo-test.h"
|
||||
|
||||
static cairo_test_status_t
|
||||
draw (cairo_t *cr, int width, int height)
|
||||
{
|
||||
cairo_surface_t *surface2 = cairo_recording_surface_create (CAIRO_CONTENT_COLOR_ALPHA, NULL);
|
||||
{
|
||||
cairo_t *cr2 = cairo_create (surface2);
|
||||
cairo_surface_t *surface3 = cairo_recording_surface_create (CAIRO_CONTENT_COLOR_ALPHA, NULL);
|
||||
{
|
||||
cairo_t *cr3 = cairo_create (surface3);
|
||||
cairo_pattern_t *pattern4 = cairo_pattern_create_linear (0.0, 0.0, width, height);
|
||||
cairo_pattern_add_color_stop_rgb (pattern4, 0, 0, 1, 0);
|
||||
cairo_pattern_add_color_stop_rgb (pattern4, 1, 0, 0, 1);
|
||||
cairo_set_source (cr3, pattern4);
|
||||
cairo_paint (cr3);
|
||||
}
|
||||
cairo_pattern_t *pattern3 = cairo_pattern_create_for_surface (surface3);
|
||||
cairo_matrix_t matrix3;
|
||||
cairo_matrix_init_scale (&matrix3, 2, 2);
|
||||
cairo_pattern_set_matrix (pattern3, &matrix3);
|
||||
cairo_set_source (cr2, pattern3);
|
||||
cairo_paint (cr2);
|
||||
}
|
||||
cairo_pattern_t *pattern2 = cairo_pattern_create_for_surface (surface2);
|
||||
cairo_matrix_t matrix2;
|
||||
cairo_matrix_init_scale (&matrix2, 5, 5);
|
||||
cairo_pattern_set_matrix (pattern2, &matrix2);
|
||||
cairo_set_source (cr, pattern2);
|
||||
cairo_paint (cr);
|
||||
|
||||
return CAIRO_TEST_SUCCESS;
|
||||
}
|
||||
|
||||
CAIRO_TEST (record_transform_paint,
|
||||
"Tests paint in nested transformed recording patterns",
|
||||
"record, paint", /* keywords */
|
||||
NULL, /* requirements */
|
||||
512, 512,
|
||||
NULL, draw)
|
||||
BIN
test/reference/record-transform-paint.ref.png
Normal file
BIN
test/reference/record-transform-paint.ref.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 2.1 KiB |
Loading…
Add table
Reference in a new issue