コード例 #1
0
ファイル: cairo-tee-surface.c プロジェクト: lofter2011/Icefox
void
cairo_tee_surface_add (cairo_surface_t *abstract_surface,
		       cairo_surface_t *target)
{
    cairo_tee_surface_t *surface;
    cairo_surface_wrapper_t slave;
    cairo_status_t status;

    if (unlikely (abstract_surface->status))
	return;

    if (abstract_surface->backend != &cairo_tee_surface_backend) {
	status = _cairo_surface_set_error (abstract_surface,
					   _cairo_error (CAIRO_STATUS_SURFACE_TYPE_MISMATCH));
	return;
    }

    if (unlikely (target->status)) {
	status = _cairo_surface_set_error (abstract_surface, target->status);
	return;
    }

    surface = (cairo_tee_surface_t *) abstract_surface;

    _cairo_surface_wrapper_init (&slave, target);
    status = _cairo_array_append (&surface->slaves, &slave);
    if (unlikely (status)) {
	_cairo_surface_wrapper_fini (&slave);
	status = _cairo_surface_set_error (&surface->base, status);
    }
}
コード例 #2
0
ファイル: cairo-tee-surface.c プロジェクト: lofter2011/Icefox
cairo_surface_t *
cairo_tee_surface_create (cairo_surface_t *master)
{
    cairo_tee_surface_t *surface;

    if (unlikely (master->status))
	return _cairo_surface_create_in_error (master->status);

    surface = malloc (sizeof (cairo_tee_surface_t));
    if (unlikely (surface == NULL))
	return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_NO_MEMORY));

    _cairo_surface_init (&surface->base,
			 &cairo_tee_surface_backend,
			 master->content);

    _cairo_surface_wrapper_init (&surface->master, master);
    /* we trust that these are already set and remain constant */
    surface->base.device_transform = master->device_transform;
    surface->base.device_transform_inverse = master->device_transform_inverse;

    _cairo_array_init (&surface->slaves, sizeof (cairo_surface_wrapper_t));

    return &surface->base;
}
コード例 #3
0
cairo_surface_t *
_cairo_test_wrapping_surface_create (cairo_surface_t *target)
{
    test_wrapping_surface_t *surface;

    if (unlikely (target->status))
	return _cairo_surface_create_in_error (target->status);

    surface = malloc (sizeof (test_wrapping_surface_t));
    if (unlikely (surface == NULL))
	return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_NO_MEMORY));

    _cairo_surface_init (&surface->base,
			 &test_wrapping_surface_backend,
			 target->content);

    _cairo_surface_wrapper_init (&surface->wrapper, target);

    return &surface->base;
}
コード例 #4
0
cairo_surface_t *
cairo_tee_surface_create (cairo_surface_t *master)
{
    cairo_tee_surface_t *surface;

    if (unlikely (master->status))
	return _cairo_surface_create_in_error (master->status);

    surface = malloc (sizeof (cairo_tee_surface_t));
    if (unlikely (surface == NULL))
	return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_NO_MEMORY));

    _cairo_surface_init (&surface->base,
			 &cairo_tee_surface_backend,
			 master->device,
			 master->content,
			 TRUE); /* is_vector */

    _cairo_surface_wrapper_init (&surface->master, master);

    _cairo_array_init (&surface->slaves, sizeof (cairo_surface_wrapper_t));

    return &surface->base;
}
コード例 #5
0
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);
}