📄 cairo-surface.c
字号:
/* cairo - a vector graphics library with display and print output * * Copyright © 2002 University of Southern California * Copyright © 2005 Red Hat, Inc. * * This library is free software; you can redistribute it and/or * modify it either under the terms of the GNU Lesser General Public * License version 2.1 as published by the Free Software Foundation * (the "LGPL") or, at your option, under the terms of the Mozilla * Public License Version 1.1 (the "MPL"). If you do not alter this * notice, a recipient may use your version of this file under either * the MPL or the LGPL. * * You should have received a copy of the LGPL along with this library * in the file COPYING-LGPL-2.1; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * You should have received a copy of the MPL along with this library * in the file COPYING-MPL-1.1 * * The contents of this file are subject to the Mozilla Public License * Version 1.1 (the "License"); you may not use this file except in * compliance with the License. You may obtain a copy of the License at * http://www.mozilla.org/MPL/ * * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY * OF ANY KIND, either express or implied. See the LGPL or the MPL for * the specific language governing rights and limitations. * * The Original Code is the cairo graphics library. * * The Initial Developer of the Original Code is University of Southern * California. * * Contributor(s): * Carl D. Worth <cworth@cworth.org> */#include <stdlib.h>#include "cairoint.h"#include "cairo-surface-fallback-private.h"#include "cairo-clip-private.h"const cairo_surface_t _cairo_surface_nil = { &cairo_image_surface_backend, /* backend */ CAIRO_CONTENT_COLOR, CAIRO_SURFACE_TYPE_IMAGE, -1, /* ref_count */ CAIRO_STATUS_NO_MEMORY, /* status */ FALSE, /* finished */ { 0, /* size */ 0, /* num_elements */ 0, /* element_size */ NULL, /* elements */ }, /* user_data */ { 1.0, 0.0, 0.0, 1.0, 0.0, 0.0 }, /* device_transform */ { 1.0, 0.0, 0.0, 1.0, 0.0, 0.0 }, /* device_transform_inverse */ 0.0, /* x_fallback_resolution */ 0.0, /* y_fallback_resolution */ 0, /* next_clip_serial */ 0 /* current_clip_serial */};const cairo_surface_t _cairo_surface_nil_file_not_found = { &cairo_image_surface_backend, /* backend */ CAIRO_CONTENT_COLOR, CAIRO_SURFACE_TYPE_IMAGE, -1, /* ref_count */ CAIRO_STATUS_FILE_NOT_FOUND, /* status */ FALSE, /* finished */ { 0, /* size */ 0, /* num_elements */ 0, /* element_size */ NULL, /* elements */ }, /* user_data */ { 1.0, 0.0, 0.0, 1.0, 0.0, 0.0 }, /* device_transform */ { 1.0, 0.0, 0.0, 1.0, 0.0, 0.0 }, /* device_transform_inverse */ 0.0, /* x_fallback_resolution */ 0.0, /* y_fallback_resolution */ 0, /* next_clip_serial */ 0 /* current_clip_serial */};const cairo_surface_t _cairo_surface_nil_read_error = { &cairo_image_surface_backend, /* backend */ CAIRO_CONTENT_COLOR, CAIRO_SURFACE_TYPE_IMAGE, -1, /* ref_count */ CAIRO_STATUS_READ_ERROR, /* status */ FALSE, /* finished */ { 0, /* size */ 0, /* num_elements */ 0, /* element_size */ NULL, /* elements */ }, /* user_data */ { 1.0, 0.0, 0.0, 1.0, 0.0, 0.0 }, /* device_transform */ { 1.0, 0.0, 0.0, 1.0, 0.0, 0.0 }, /* device_transform_inverse */ 0.0, /* x_fallback_resolution */ 0.0, /* y_fallback_resolution */ 0, /* next_clip_serial */ 0 /* current_clip_serial */};static void_cairo_surface_copy_pattern_for_destination (const cairo_pattern_t *pattern, cairo_surface_t *destination, cairo_pattern_t *pattern_out);/** * _cairo_surface_set_error: * @surface: a surface * @status: a status value indicating an error, (eg. not * CAIRO_STATUS_SUCCESS) * * Sets surface->status to @status and calls _cairo_error; * * All assignments of an error status to surface->status should happen * through _cairo_surface_set_error() or else _cairo_error() should be * called immediately after the assignment. * * The purpose of this function is to allow the user to set a * breakpoint in _cairo_error() to generate a stack trace for when the * user causes cairo to detect an error. **/void_cairo_surface_set_error (cairo_surface_t *surface, cairo_status_t status){ /* Don't overwrite an existing error. This preserves the first * error, which is the most significant. It also avoids attempting * to write to read-only data (eg. from a nil surface). */ if (surface->status == CAIRO_STATUS_SUCCESS) surface->status = status; _cairo_error (status);}/** * cairo_surface_get_type: * @surface: a #cairo_surface_t * * Return value: The type of @surface. See #cairo_surface_type_t. * * Since: 1.2 **/cairo_surface_type_tcairo_surface_get_type (cairo_surface_t *surface){ /* We don't use surface->backend->type here so that some of the * special "wrapper" surfaces such as cairo_paginated_surface_t * can override surface->type with the type of the "child" * surface. */ return surface->type;}/** * cairo_surface_get_content: * @surface: a #cairo_surface_t * * Return value: The content type of @surface which indicates whether * the surface contains color and/or alpha information. See * #cairo_content_t. * * Since: 1.2 **/cairo_content_tcairo_surface_get_content (cairo_surface_t *surface){ return surface->content;}slim_hidden_def(cairo_surface_get_content);/** * cairo_surface_status: * @surface: a #cairo_surface_t * * Checks whether an error has previously occurred for this * surface. * * Return value: %CAIRO_STATUS_SUCCESS, %CAIRO_STATUS_NULL_POINTER, * %CAIRO_STATUS_NO_MEMORY, %CAIRO_STATUS_READ_ERROR, * %CAIRO_STATUS_INVALID_CONTENT, %CAIRO_STATUS_INVALUE_FORMAT, or * %CAIRO_STATUS_INVALID_VISUAL. **/cairo_status_tcairo_surface_status (cairo_surface_t *surface){ return surface->status;}void_cairo_surface_init (cairo_surface_t *surface, const cairo_surface_backend_t *backend, cairo_content_t content){ surface->backend = backend; surface->content = content; surface->type = backend->type; surface->ref_count = 1; surface->status = CAIRO_STATUS_SUCCESS; surface->finished = FALSE; _cairo_user_data_array_init (&surface->user_data); cairo_matrix_init_identity (&surface->device_transform); cairo_matrix_init_identity (&surface->device_transform_inverse); surface->x_fallback_resolution = CAIRO_SURFACE_FALLBACK_RESOLUTION_DEFAULT; surface->y_fallback_resolution = CAIRO_SURFACE_FALLBACK_RESOLUTION_DEFAULT; surface->clip = NULL; surface->next_clip_serial = 0; surface->current_clip_serial = 0; surface->is_snapshot = FALSE;}cairo_surface_t *_cairo_surface_create_similar_scratch (cairo_surface_t *other, cairo_content_t content, int width, int height){ cairo_format_t format = _cairo_format_from_content (content); if (other->status) return (cairo_surface_t*) &_cairo_surface_nil; if (other->backend->create_similar) return other->backend->create_similar (other, content, width, height); else return cairo_image_surface_create (format, width, height);}/** * cairo_surface_create_similar: * @other: an existing surface used to select the backend of the new surface * @content: the content for the new surface * @width: width of the new surface, (in device-space units) * @height: height of the new surface (in device-space units) * * Create a new surface that is as compatible as possible with an * existing surface. The new surface will use the same backend as * @other unless that is not possible for some reason. The type of the * returned surface may be examined with cairo_surface_get_type(). * Initially the surface contents are all 0 (transparent if contents * have transparency, black otherwise.) * * Return value: a pointer to the newly allocated surface. The caller * owns the surface and should call cairo_surface_destroy when done * with it. * * This function always returns a valid pointer, but it will return a * pointer to a "nil" surface if @other is already in an error state * or any other error occurs. **/cairo_surface_t *cairo_surface_create_similar (cairo_surface_t *other, cairo_content_t content, int width, int height){ if (other->status) return (cairo_surface_t*) &_cairo_surface_nil; if (! CAIRO_CONTENT_VALID (content)) { _cairo_error (CAIRO_STATUS_INVALID_CONTENT); return (cairo_surface_t*) &_cairo_surface_nil; } return _cairo_surface_create_similar_solid (other, content, width, height, CAIRO_COLOR_TRANSPARENT);}cairo_surface_t *_cairo_surface_create_similar_solid (cairo_surface_t *other, cairo_content_t content, int width, int height, const cairo_color_t *color){ cairo_status_t status; cairo_surface_t *surface; cairo_pattern_t *source; surface = _cairo_surface_create_similar_scratch (other, content, width, height); if (surface->status) { _cairo_error (CAIRO_STATUS_NO_MEMORY); return (cairo_surface_t*) &_cairo_surface_nil; } source = _cairo_pattern_create_solid (color); if (source->status) { cairo_surface_destroy (surface); _cairo_error (CAIRO_STATUS_NO_MEMORY); return (cairo_surface_t*) &_cairo_surface_nil; } status = _cairo_surface_paint (surface, color == CAIRO_COLOR_TRANSPARENT ? CAIRO_OPERATOR_CLEAR : CAIRO_OPERATOR_SOURCE, source); cairo_pattern_destroy (source); if (status) { cairo_surface_destroy (surface); _cairo_error (status); return (cairo_surface_t*) &_cairo_surface_nil; } return surface;}cairo_clip_mode_t_cairo_surface_get_clip_mode (cairo_surface_t *surface){ if (surface->backend->intersect_clip_path != NULL) return CAIRO_CLIP_MODE_PATH; else if (surface->backend->set_clip_region != NULL) return CAIRO_CLIP_MODE_REGION; else return CAIRO_CLIP_MODE_MASK;}/** * cairo_surface_reference: * @surface: a #cairo_surface_t * * Increases the reference count on @surface by one. This prevents * @surface from being destroyed until a matching call to * cairo_surface_destroy() is made. * * Return value: the referenced #cairo_surface_t. **/cairo_surface_t *cairo_surface_reference (cairo_surface_t *surface){ if (surface == NULL) return NULL; if (surface->ref_count == (unsigned int)-1) return surface; assert (surface->ref_count > 0); surface->ref_count++; return surface;}/** * cairo_surface_destroy: * @surface: a #cairo_t * * Decreases the reference count on @surface by one. If the result is * zero, then @surface and all associated resources are freed. See * cairo_surface_reference(). **/voidcairo_surface_destroy (cairo_surface_t *surface){ if (surface == NULL) return; if (surface->ref_count == (unsigned int)-1) return; assert (surface->ref_count > 0); surface->ref_count--; if (surface->ref_count) return; cairo_surface_finish (surface); _cairo_user_data_array_fini (&surface->user_data); free (surface);}slim_hidden_def(cairo_surface_destroy);/** * cairo_surface_finish: * @surface: the #cairo_surface_t to finish * * This function finishes the surface and drops all references to * external resources. For example, for the Xlib backend it means * that cairo will no longer access the drawable, which can be freed.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -