static cairo_int_status_t _cairo_tee_surface_fill (void *abstract_surface, cairo_operator_t op, const cairo_pattern_t *source, const cairo_path_fixed_t *path, cairo_fill_rule_t fill_rule, double tolerance, cairo_antialias_t antialias, const cairo_clip_t *clip) { cairo_tee_surface_t *surface = abstract_surface; cairo_surface_wrapper_t *slaves; cairo_int_status_t status; int n, num_slaves; num_slaves = _cairo_array_num_elements (&surface->slaves); slaves = _cairo_array_index (&surface->slaves, 0); for (n = 0; n < num_slaves; n++) { status = _cairo_surface_wrapper_fill (&slaves[n], op, source, path, fill_rule, tolerance, antialias, clip); if (unlikely (status)) return status; } return _cairo_surface_wrapper_fill (&surface->master, op, source, path, fill_rule, tolerance, antialias, clip); }
static cairo_int_status_t _cairo_tee_surface_fill (void *abstract_surface, cairo_operator_t op, const cairo_pattern_t *source, cairo_path_fixed_t *path, cairo_fill_rule_t fill_rule, double tolerance, cairo_antialias_t antialias, cairo_clip_t *clip) { cairo_tee_surface_t *surface = abstract_surface; cairo_surface_wrapper_t *slaves; int n, num_slaves; cairo_status_t status; const cairo_pattern_t *matched_source; cairo_surface_pattern_t temp; matched_source = _cairo_tee_surface_match_source (surface, source, 0, &surface->master, &temp); status = _cairo_surface_wrapper_fill (&surface->master, op, matched_source, path, fill_rule, tolerance, antialias, clip); if (matched_source == &temp.base) { _cairo_pattern_fini (&temp.base); } if (unlikely (status)) return status; num_slaves = _cairo_array_num_elements (&surface->slaves); slaves = _cairo_array_index (&surface->slaves, 0); for (n = 0; n < num_slaves; n++) { matched_source = _cairo_tee_surface_match_source (surface, source, n + 1, &slaves[n], &temp); status = _cairo_surface_wrapper_fill (&slaves[n], op, matched_source, path, fill_rule, tolerance, antialias, clip); if (matched_source == &temp.base) { _cairo_pattern_fini (&temp.base); } if (unlikely (status)) return status; } return CAIRO_STATUS_SUCCESS; }
static cairo_int_status_t _test_wrapping_surface_fill (void *abstract_surface, cairo_operator_t op, const cairo_pattern_t *source, cairo_path_fixed_t *path, cairo_fill_rule_t fill_rule, double tolerance, cairo_antialias_t antialias, cairo_clip_t *clip) { test_wrapping_surface_t *surface = abstract_surface; return _cairo_surface_wrapper_fill (&surface->wrapper, op, source, path, fill_rule, tolerance, antialias, clip); }
static cairo_status_t _cairo_recording_surface_replay_internal (cairo_surface_t *surface, const cairo_rectangle_int_t *surface_extents, cairo_surface_t *target, cairo_recording_replay_type_t type, cairo_recording_region_type_t region) { cairo_recording_surface_t *recording_surface; cairo_command_t **elements; int i, num_elements; cairo_int_status_t status; cairo_surface_wrapper_t wrapper; if (unlikely (surface->status)) return surface->status; if (unlikely (target->status)) return target->status; if (unlikely (surface->finished)) return _cairo_error (CAIRO_STATUS_SURFACE_FINISHED); if (surface->is_clear) return CAIRO_STATUS_SUCCESS; assert (_cairo_surface_is_recording (surface)); _cairo_surface_wrapper_init (&wrapper, target); _cairo_surface_wrapper_set_extents (&wrapper, surface_extents); recording_surface = (cairo_recording_surface_t *) surface; status = CAIRO_STATUS_SUCCESS; num_elements = recording_surface->commands.num_elements; elements = _cairo_array_index (&recording_surface->commands, 0); for (i = recording_surface->replay_start_idx; i < num_elements; i++) { cairo_command_t *command = elements[i]; if (type == CAIRO_RECORDING_REPLAY && region != CAIRO_RECORDING_REGION_ALL) { if (command->header.region != region) continue; } switch (command->header.type) { case CAIRO_COMMAND_PAINT: status = _cairo_surface_wrapper_paint (&wrapper, command->header.op, &command->paint.source.base, _clip (command)); break; case CAIRO_COMMAND_MASK: status = _cairo_surface_wrapper_mask (&wrapper, command->header.op, &command->mask.source.base, &command->mask.mask.base, _clip (command)); break; case CAIRO_COMMAND_STROKE: { status = _cairo_surface_wrapper_stroke (&wrapper, command->header.op, &command->stroke.source.base, &command->stroke.path, &command->stroke.style, &command->stroke.ctm, &command->stroke.ctm_inverse, command->stroke.tolerance, command->stroke.antialias, _clip (command)); break; } case CAIRO_COMMAND_FILL: { cairo_command_t *stroke_command; stroke_command = NULL; if (type != CAIRO_RECORDING_CREATE_REGIONS && i < num_elements - 1) stroke_command = elements[i + 1]; if (stroke_command != NULL && type == CAIRO_RECORDING_REPLAY && region != CAIRO_RECORDING_REGION_ALL) { if (stroke_command->header.region != region) stroke_command = NULL; } if (stroke_command != NULL && stroke_command->header.type == CAIRO_COMMAND_STROKE && _cairo_path_fixed_is_equal (&command->fill.path, &stroke_command->stroke.path)) { status = _cairo_surface_wrapper_fill_stroke (&wrapper, command->header.op, &command->fill.source.base, command->fill.fill_rule, command->fill.tolerance, command->fill.antialias, &command->fill.path, stroke_command->header.op, &stroke_command->stroke.source.base, &stroke_command->stroke.style, &stroke_command->stroke.ctm, &stroke_command->stroke.ctm_inverse, stroke_command->stroke.tolerance, stroke_command->stroke.antialias, _clip (command)); i++; } else { status = _cairo_surface_wrapper_fill (&wrapper, command->header.op, &command->fill.source.base, &command->fill.path, command->fill.fill_rule, command->fill.tolerance, command->fill.antialias, _clip (command)); } break; } case CAIRO_COMMAND_SHOW_TEXT_GLYPHS: { cairo_glyph_t *glyphs = command->show_text_glyphs.glyphs; cairo_glyph_t *glyphs_copy; int num_glyphs = command->show_text_glyphs.num_glyphs; /* show_text_glyphs is special because _cairo_surface_show_text_glyphs is allowed * to modify the glyph array that's passed in. We must always * copy the array before handing it to the backend. */ glyphs_copy = _cairo_malloc_ab (num_glyphs, sizeof (cairo_glyph_t)); if (unlikely (glyphs_copy == NULL)) { status = _cairo_error (CAIRO_STATUS_NO_MEMORY); break; } memcpy (glyphs_copy, glyphs, sizeof (cairo_glyph_t) * num_glyphs); status = _cairo_surface_wrapper_show_text_glyphs (&wrapper, command->header.op, &command->show_text_glyphs.source.base, command->show_text_glyphs.utf8, command->show_text_glyphs.utf8_len, glyphs_copy, num_glyphs, command->show_text_glyphs.clusters, command->show_text_glyphs.num_clusters, command->show_text_glyphs.cluster_flags, command->show_text_glyphs.scaled_font, _clip (command)); free (glyphs_copy); break; } default: ASSERT_NOT_REACHED; } if (type == CAIRO_RECORDING_CREATE_REGIONS) { if (status == CAIRO_STATUS_SUCCESS) { command->header.region = CAIRO_RECORDING_REGION_NATIVE; } else if (status == CAIRO_INT_STATUS_IMAGE_FALLBACK) { command->header.region = CAIRO_RECORDING_REGION_IMAGE_FALLBACK; status = CAIRO_STATUS_SUCCESS; } else { assert (_cairo_status_is_error (status)); } } if (unlikely (status)) break; } /* free up any caches */ for (i = recording_surface->replay_start_idx; i < num_elements; i++) { cairo_command_t *command = elements[i]; _cairo_clip_drop_cache (&command->header.clip); } _cairo_surface_wrapper_fini (&wrapper); return _cairo_surface_set_error (surface, status); }