b=838960, ugprade cairo to 1.5.x; and b=377336, printing page from win32 results in hung app, r=stuart

This commit is contained in:
vladimir%pobox.com 2007-09-20 19:24:52 +00:00
Родитель b9e18d1646
Коммит 9237056d87
77 изменённых файлов: 6007 добавлений и 2018 удалений

Просмотреть файл

@ -7,8 +7,8 @@ http://www.cairographics.org/.
VERSIONS:
cairo (1.5.x - c0a7d33ac6c81dd74ee2a9daaa3749a346ef4897)
pixman (0.9.3 - 0c80a0cd84f30616563cef5910df9deb4f8ed687)
cairo (1.5.x - d8b0de01d67cdf73d8266a73f54ba1ac42fee3c9)
pixman (0.9.x - 3be35594c99b7abd2af43b66349ca53bfa1462d6)
glitz 0.5.2 (cvs - 2006-01-10)
***** NOTE FOR VISUAL C++ 6.0 *****
@ -17,34 +17,11 @@ VC6 is not supported. Please upgrade to VC8.
==== Patches ====
All patches in the cairo tree are surrounded by "MOZILLA_CAIRO_NOT_DEFINED"
(which should obviously not be defined).
Some specific things:
max-font-size.patch: Clamp freetype font size to 1000 to avoid overflow issues
win32-scaled-font-size.patch: Add cairo_win32_font_face_create_for_logfontw_hfont,
allow win32 scaled_fonts to rescale themselves properly to the required CTM
and only use the font_face's hfont if we're sure it's appropriate
win32-logical-font-scale.patch: set CAIRO_WIN32_LOGICAL_FONT_SCALE to 1
win32-no-printer-bitblt.patch: If we need to BitBlt from a DC (to do
fallback), only bother trying if the IS_DISPLAY flag is set -- many
printers lie about their support for BitBlt, and we end up getting
black instead of what we want.
nonfatal-assertions.patch: Make assertions non-fatal
clone-similar-fallback.patch: Implement fallback for clone_similar.
scaled-font-create-deadlock.patch: the "poor man's mutex" that is provided
for CAIRO_NO_MUTEX will deadlock if a recursive mutex lock occurs.
It's also just a bunch of useless assignments for applications that makes
all cairo calls from a single thread. An example of where a deadlock occurs
is the cairo_scaled_font_destroy() call from win32_scaled_font_create(),
which is a bug, but it illustrates the dangers of that "poor man's mutex".
The patch makes all mutex operations do nothing under CAIRO_NO_MUTEX and
it fixes the bug in win32_scaled_font_create().
See https://bugzilla.mozilla.org/show_bug.cgi?id=378716

Просмотреть файл

@ -123,7 +123,8 @@ EXPORTS = cairo.h cairo-features.h cairo-platform.h cairo-deprecated.h cairo-ren
ifeq ($(MOZ_WIDGET_TOOLKIT),windows)
CSRCS += cairo-win32-font.c \
cairo-win32-surface.c
cairo-win32-surface.c \
cairo-win32-printing-surface.c
EXPORTS += cairo-win32.h
CSRCS += cairo-base85-stream.c \
cairo-pdf-surface.c \

Просмотреть файл

@ -1,5 +1,4 @@
/* $Id: cairo-analysis-surface-private.h,v 1.12 2007-08-09 18:54:18 vladimir%pobox.com Exp $
*
/*
* Copyright © 2005 Keith Packard
*
* This library is free software; you can redistribute it and/or
@ -49,6 +48,9 @@ _cairo_analysis_surface_get_supported (cairo_surface_t *surface);
cairo_private cairo_region_t *
_cairo_analysis_surface_get_unsupported (cairo_surface_t *unsupported);
cairo_private cairo_bool_t
_cairo_analysis_surface_has_supported (cairo_surface_t *unsupported);
cairo_private cairo_bool_t
_cairo_analysis_surface_has_unsupported (cairo_surface_t *unsupported);

Просмотреть файл

@ -1,5 +1,6 @@
/*
* Copyright © 2006 Keith Packard
* Copyright © 2007 Adrian Johnson
*
* This library is free software; you can redistribute it and/or
* modify it either under the terms of the GNU Lesser General Public
@ -30,12 +31,15 @@
*
* Contributor(s):
* Keith Packard <keithp@keithp.com>
* Adrian Johnson <ajohnson@redneon.com>
*/
#include "cairoint.h"
#include "cairo-analysis-surface-private.h"
#include "cairo-paginated-private.h"
#include "cairo-region-private.h"
#include "cairo-meta-surface-private.h"
typedef struct {
cairo_surface_t base;
@ -44,9 +48,148 @@ typedef struct {
cairo_surface_t *target;
cairo_bool_t fallback;
cairo_bool_t has_supported;
cairo_bool_t has_unsupported;
cairo_region_t supported_region;
cairo_region_t fallback_region;
cairo_rectangle_int_t current_clip;
} cairo_analysis_surface_t;
static cairo_int_status_t
_cairo_analysis_surface_analyze_meta_surface_pattern (cairo_analysis_surface_t *surface,
cairo_pattern_t *pattern)
{
cairo_surface_pattern_t *surface_pattern;
cairo_surface_t *meta_surface;
cairo_surface_t *analysis;
cairo_status_t status;
assert (pattern->type == CAIRO_PATTERN_TYPE_SURFACE);
surface_pattern = (cairo_surface_pattern_t *) pattern;
assert (_cairo_surface_is_meta (surface_pattern->surface));
meta_surface = surface_pattern->surface;
analysis = _cairo_analysis_surface_create (surface->target,
surface->width, surface->height);
if (analysis == NULL)
return CAIRO_STATUS_NO_MEMORY;
status = _cairo_meta_surface_replay_analyze_meta_pattern (meta_surface, analysis);
if (status == CAIRO_STATUS_SUCCESS)
status = analysis->status;
cairo_surface_destroy (analysis);
return status;
}
static cairo_int_status_t
_cairo_analysis_surface_add_operation (cairo_analysis_surface_t *surface,
cairo_rectangle_int_t *rect,
cairo_int_status_t backend_status)
{
cairo_int_status_t status;
if (rect->width == 0 || rect->height == 0)
return CAIRO_STATUS_SUCCESS;
/* If the operation is completely enclosed within the fallback
* region there is no benefit in emitting a native operation as
* the fallback image will be painted on top.
*/
if (_cairo_region_contains_rectangle (&surface->fallback_region, rect) == PIXMAN_REGION_IN)
return CAIRO_INT_STATUS_IMAGE_FALLBACK;
if (backend_status == CAIRO_INT_STATUS_FLATTEN_TRANSPARENCY) {
/* A status of CAIRO_INT_STATUS_FLATTEN_TRANSPARENCY indicates
* that the backend only supports this operation if the
* transparency removed. If the extents of this operation does
* not intersect any other native operation, the operation is
* natively supported and the backend will blend the
* transparency into the white background.
*/
if (_cairo_region_contains_rectangle (&surface->supported_region, rect) == PIXMAN_REGION_OUT)
backend_status = CAIRO_STATUS_SUCCESS;
}
if (backend_status == CAIRO_STATUS_SUCCESS) {
/* Add the operation to the supported region. Operations in
* this region will be emitted as native operations.
*/
surface->has_supported = TRUE;
status = _cairo_region_union_rect (&surface->supported_region,
&surface->supported_region,
rect);
return status;
}
/* Add the operation to the unsupported region. This region will
* be painted as an image after all native operations have been
* emitted.
*/
surface->has_unsupported = TRUE;
status = _cairo_region_union_rect (&surface->fallback_region,
&surface->fallback_region,
rect);
/* The status CAIRO_INT_STATUS_IMAGE_FALLBACK is used to indicate
* unsupported operations to the meta surface as using
* CAIRO_INT_STATUS_UNSUPPORTED would cause cairo-surface to
* invoke the cairo-surface-fallback path then return
* CAIRO_STATUS_SUCCESS.
*/
if (status == CAIRO_STATUS_SUCCESS)
return CAIRO_INT_STATUS_IMAGE_FALLBACK;
else
return status;
}
static cairo_status_t
_cairo_analysis_surface_finish (void *abstract_surface)
{
cairo_analysis_surface_t *surface = (cairo_analysis_surface_t *) abstract_surface;
_cairo_region_fini (&surface->supported_region);
_cairo_region_fini (&surface->fallback_region);
return CAIRO_STATUS_SUCCESS;
}
static cairo_int_status_t
_cairo_analysis_surface_intersect_clip_path (void *abstract_surface,
cairo_path_fixed_t *path,
cairo_fill_rule_t fill_rule,
double tolerance,
cairo_antialias_t antialias)
{
cairo_analysis_surface_t *surface = abstract_surface;
double x1, y1, x2, y2;
cairo_rectangle_int_t extent;
cairo_status_t status;
if (path == NULL) {
surface->current_clip.x = 0;
surface->current_clip.y = 0;
surface->current_clip.width = surface->width;
surface->current_clip.height = surface->height;
status = CAIRO_STATUS_SUCCESS;
} else {
status = _cairo_path_fixed_bounds (path, &x1, &y1, &x2, &y2);
if (status)
return status;
extent.x = floor (x1);
extent.y = floor (y1);
extent.width = ceil (x2) - extent.x;
extent.height = ceil (y2) - extent.y;
_cairo_rectangle_intersect (&surface->current_clip, &extent);
}
return status;
}
static cairo_int_status_t
_cairo_analysis_surface_get_extents (void *abstract_surface,
cairo_rectangle_int_t *rectangle)
@ -62,17 +205,36 @@ _cairo_analysis_surface_paint (void *abstract_surface,
cairo_pattern_t *source)
{
cairo_analysis_surface_t *surface = abstract_surface;
cairo_status_t status;
cairo_status_t status, backend_status;
cairo_rectangle_int_t extents;
if (!surface->target->backend->paint)
status = CAIRO_INT_STATUS_UNSUPPORTED;
backend_status = CAIRO_INT_STATUS_UNSUPPORTED;
else
status = (*surface->target->backend->paint) (surface->target, op,
source);
if (status == CAIRO_INT_STATUS_UNSUPPORTED) {
surface->fallback = TRUE;
status = CAIRO_STATUS_SUCCESS;
backend_status = (*surface->target->backend->paint) (surface->target, op,
source);
if (backend_status == CAIRO_INT_STATUS_ANALYZE_META_SURFACE_PATTERN)
backend_status = _cairo_analysis_surface_analyze_meta_surface_pattern (surface,
source);
status = _cairo_surface_get_extents (&surface->base, &extents);
if (status)
return status;
if (_cairo_operator_bounded_by_source (op)) {
cairo_rectangle_int_t source_extents;
status = _cairo_pattern_get_extents (source, &source_extents);
if (status)
return status;
_cairo_rectangle_intersect (&extents, &source_extents);
}
_cairo_rectangle_intersect (&extents, &surface->current_clip);
status = _cairo_analysis_surface_add_operation (surface, &extents, backend_status);
return status;
}
@ -83,17 +245,60 @@ _cairo_analysis_surface_mask (void *abstract_surface,
cairo_pattern_t *mask)
{
cairo_analysis_surface_t *surface = abstract_surface;
cairo_status_t status;
cairo_status_t status, backend_status;
cairo_rectangle_int_t extents;
if (!surface->target->backend->mask)
status = CAIRO_INT_STATUS_UNSUPPORTED;
backend_status = CAIRO_INT_STATUS_UNSUPPORTED;
else
status = (*surface->target->backend->mask) (surface->target, op,
source, mask);
if (status == CAIRO_INT_STATUS_UNSUPPORTED) {
surface->fallback = TRUE;
status = CAIRO_STATUS_SUCCESS;
backend_status = (*surface->target->backend->mask) (surface->target, op,
source, mask);
if (backend_status == CAIRO_INT_STATUS_ANALYZE_META_SURFACE_PATTERN) {
if (source->type == CAIRO_PATTERN_TYPE_SURFACE) {
cairo_surface_pattern_t *surface_pattern = (cairo_surface_pattern_t *) source;
if (_cairo_surface_is_meta (surface_pattern->surface))
backend_status = _cairo_analysis_surface_analyze_meta_surface_pattern (surface,
source);
if (backend_status != CAIRO_STATUS_SUCCESS &&
backend_status != CAIRO_INT_STATUS_IMAGE_FALLBACK)
return backend_status;
}
if (mask->type == CAIRO_PATTERN_TYPE_SURFACE) {
cairo_surface_pattern_t *surface_pattern = (cairo_surface_pattern_t *) mask;
if (_cairo_surface_is_meta (surface_pattern->surface))
backend_status = _cairo_analysis_surface_analyze_meta_surface_pattern (surface,
mask);
if (backend_status != CAIRO_STATUS_SUCCESS &&
backend_status != CAIRO_INT_STATUS_IMAGE_FALLBACK)
return backend_status;
}
}
status = _cairo_surface_get_extents (&surface->base, &extents);
if (status)
return status;
if (_cairo_operator_bounded_by_source (op)) {
cairo_rectangle_int_t source_extents;
status = _cairo_pattern_get_extents (source, &source_extents);
if (status)
return status;
_cairo_rectangle_intersect (&extents, &source_extents);
status = _cairo_pattern_get_extents (mask, &source_extents);
if (status)
return status;
_cairo_rectangle_intersect (&extents, &source_extents);
}
_cairo_rectangle_intersect (&extents, &surface->current_clip);
status = _cairo_analysis_surface_add_operation (surface, &extents, backend_status);
return status;
}
@ -109,19 +314,67 @@ _cairo_analysis_surface_stroke (void *abstract_surface,
cairo_antialias_t antialias)
{
cairo_analysis_surface_t *surface = abstract_surface;
cairo_status_t status;
cairo_status_t status, backend_status;
cairo_traps_t traps;
cairo_box_t box;
cairo_rectangle_int_t extents;
if (!surface->target->backend->stroke)
status = CAIRO_INT_STATUS_UNSUPPORTED;
backend_status = CAIRO_INT_STATUS_UNSUPPORTED;
else
status = (*surface->target->backend->stroke) (surface->target, op,
source, path, style,
ctm, ctm_inverse,
tolerance, antialias);
if (status == CAIRO_INT_STATUS_UNSUPPORTED) {
surface->fallback = TRUE;
status = CAIRO_STATUS_SUCCESS;
backend_status = (*surface->target->backend->stroke) (surface->target, op,
source, path, style,
ctm, ctm_inverse,
tolerance, antialias);
if (backend_status == CAIRO_INT_STATUS_ANALYZE_META_SURFACE_PATTERN)
backend_status = _cairo_analysis_surface_analyze_meta_surface_pattern (surface,
source);
status = _cairo_surface_get_extents (&surface->base, &extents);
if (status)
return status;
if (_cairo_operator_bounded_by_source (op)) {
cairo_rectangle_int_t source_extents;
status = _cairo_pattern_get_extents (source, &source_extents);
if (status)
return status;
_cairo_rectangle_intersect (&extents, &source_extents);
}
_cairo_rectangle_intersect (&extents, &surface->current_clip);
if (_cairo_operator_bounded_by_mask (op)) {
box.p1.x = _cairo_fixed_from_int (extents.x);
box.p1.y = _cairo_fixed_from_int (extents.y);
box.p2.x = _cairo_fixed_from_int (extents.x + extents.width);
box.p2.y = _cairo_fixed_from_int (extents.y + extents.height);
_cairo_traps_init (&traps);
_cairo_traps_limit (&traps, &box);
status = _cairo_path_fixed_stroke_to_traps (path,
style,
ctm, ctm_inverse,
tolerance,
&traps);
if (status) {
_cairo_traps_fini (&traps);
return status;
}
_cairo_traps_extents (&traps, &box);
extents.x = _cairo_fixed_integer_floor (box.p1.x);
extents.y = _cairo_fixed_integer_floor (box.p1.y);
extents.width = _cairo_fixed_integer_ceil (box.p2.x) - extents.x;
extents.height = _cairo_fixed_integer_ceil (box.p2.y) - extents.y;
_cairo_traps_fini (&traps);
}
status = _cairo_analysis_surface_add_operation (surface, &extents, backend_status);
return status;
}
@ -135,18 +388,66 @@ _cairo_analysis_surface_fill (void *abstract_surface,
cairo_antialias_t antialias)
{
cairo_analysis_surface_t *surface = abstract_surface;
cairo_status_t status;
cairo_status_t status, backend_status;
cairo_traps_t traps;
cairo_box_t box;
cairo_rectangle_int_t extents;
if (!surface->target->backend->fill)
status = CAIRO_INT_STATUS_UNSUPPORTED;
backend_status = CAIRO_INT_STATUS_UNSUPPORTED;
else
status = (*surface->target->backend->fill) (surface->target, op,
backend_status = (*surface->target->backend->fill) (surface->target, op,
source, path, fill_rule,
tolerance, antialias);
if (status == CAIRO_INT_STATUS_UNSUPPORTED) {
surface->fallback = TRUE;
status = CAIRO_STATUS_SUCCESS;
if (backend_status == CAIRO_INT_STATUS_ANALYZE_META_SURFACE_PATTERN)
backend_status = _cairo_analysis_surface_analyze_meta_surface_pattern (surface,
source);
status = _cairo_surface_get_extents (&surface->base, &extents);
if (status)
return status;
if (_cairo_operator_bounded_by_source (op)) {
cairo_rectangle_int_t source_extents;
status = _cairo_pattern_get_extents (source, &source_extents);
if (status)
return status;
_cairo_rectangle_intersect (&extents, &source_extents);
}
_cairo_rectangle_intersect (&extents, &surface->current_clip);
if (_cairo_operator_bounded_by_mask (op)) {
box.p1.x = _cairo_fixed_from_int (extents.x);
box.p1.y = _cairo_fixed_from_int (extents.y);
box.p2.x = _cairo_fixed_from_int (extents.x + extents.width);
box.p2.y = _cairo_fixed_from_int (extents.y + extents.height);
_cairo_traps_init (&traps);
_cairo_traps_limit (&traps, &box);
status = _cairo_path_fixed_fill_to_traps (path,
fill_rule,
tolerance,
&traps);
if (status) {
_cairo_traps_fini (&traps);
return status;
}
_cairo_traps_extents (&traps, &box);
extents.x = _cairo_fixed_integer_floor (box.p1.x);
extents.y = _cairo_fixed_integer_floor (box.p1.y);
extents.width = _cairo_fixed_integer_ceil (box.p2.x) - extents.x;
extents.height = _cairo_fixed_integer_ceil (box.p2.y) - extents.y;
_cairo_traps_fini (&traps);
}
status = _cairo_analysis_surface_add_operation (surface, &extents, backend_status);
return status;
}
@ -159,26 +460,56 @@ _cairo_analysis_surface_show_glyphs (void *abstract_surface,
cairo_scaled_font_t *scaled_font)
{
cairo_analysis_surface_t *surface = abstract_surface;
cairo_status_t status;
cairo_status_t status, backend_status;
cairo_rectangle_int_t extents, glyph_extents;
if (!surface->target->backend->show_glyphs)
status = CAIRO_INT_STATUS_UNSUPPORTED;
backend_status = CAIRO_INT_STATUS_UNSUPPORTED;
else
status = (*surface->target->backend->show_glyphs) (surface->target, op,
backend_status = (*surface->target->backend->show_glyphs) (surface->target, op,
source,
glyphs, num_glyphs,
scaled_font);
if (status == CAIRO_INT_STATUS_UNSUPPORTED) {
surface->fallback = TRUE;
status = CAIRO_STATUS_SUCCESS;
if (backend_status == CAIRO_INT_STATUS_ANALYZE_META_SURFACE_PATTERN)
backend_status = _cairo_analysis_surface_analyze_meta_surface_pattern (surface,
source);
status = _cairo_surface_get_extents (&surface->base, &extents);
if (status)
return status;
if (_cairo_operator_bounded_by_source (op)) {
cairo_rectangle_int_t source_extents;
status = _cairo_pattern_get_extents (source, &source_extents);
if (status)
return status;
_cairo_rectangle_intersect (&extents, &source_extents);
}
_cairo_rectangle_intersect (&extents, &surface->current_clip);
if (_cairo_operator_bounded_by_mask (op)) {
status = _cairo_scaled_font_glyph_device_extents (scaled_font,
glyphs,
num_glyphs,
&glyph_extents);
if (status)
return status;
_cairo_rectangle_intersect (&extents, &glyph_extents);
}
status = _cairo_analysis_surface_add_operation (surface, &extents, backend_status);
return status;
}
static const cairo_surface_backend_t cairo_analysis_surface_backend = {
CAIRO_INTERNAL_SURFACE_TYPE_ANALYSIS,
NULL, /* create_similar */
NULL, /* finish_surface */
_cairo_analysis_surface_finish,
NULL, /* acquire_source_image */
NULL, /* release_source_image */
NULL, /* acquire_dest_image */
@ -190,7 +521,7 @@ static const cairo_surface_backend_t cairo_analysis_surface_backend = {
NULL, /* copy_page */
NULL, /* show_page */
NULL, /* set_clip_region */
NULL, /* clip_path */
_cairo_analysis_surface_intersect_clip_path,
_cairo_analysis_surface_get_extents,
NULL, /* old_show_glyphs */
NULL, /* get_font_options */
@ -206,7 +537,7 @@ static const cairo_surface_backend_t cairo_analysis_surface_backend = {
NULL, /* snapshot */
};
cairo_private cairo_surface_t *
cairo_surface_t *
_cairo_analysis_surface_create (cairo_surface_t *target,
int width,
int height)
@ -226,7 +557,15 @@ _cairo_analysis_surface_create (cairo_surface_t *target,
surface->height = height;
surface->target = target;
surface->fallback = FALSE;
surface->has_supported = FALSE;
surface->has_unsupported = FALSE;
_cairo_region_init (&surface->supported_region);
_cairo_region_init (&surface->fallback_region);
surface->current_clip.x = 0;
surface->current_clip.y = 0;
surface->current_clip.width = width;
surface->current_clip.height = height;
return &surface->base;
FAIL:
@ -234,24 +573,34 @@ FAIL:
return NULL;
}
cairo_private cairo_region_t *
cairo_region_t *
_cairo_analysis_surface_get_supported (cairo_surface_t *abstract_surface)
{
/* XXX */
return NULL;
cairo_analysis_surface_t *surface = (cairo_analysis_surface_t *) abstract_surface;
return &surface->supported_region;
}
cairo_private cairo_region_t *
cairo_region_t *
_cairo_analysis_surface_get_unsupported (cairo_surface_t *abstract_surface)
{
/* XXX */
return NULL;
cairo_analysis_surface_t *surface = (cairo_analysis_surface_t *) abstract_surface;
return &surface->fallback_region;
}
cairo_private cairo_bool_t
cairo_bool_t
_cairo_analysis_surface_has_supported (cairo_surface_t *abstract_surface)
{
cairo_analysis_surface_t *surface = (cairo_analysis_surface_t *) abstract_surface;
return surface->has_supported;
}
cairo_bool_t
_cairo_analysis_surface_has_unsupported (cairo_surface_t *abstract_surface)
{
cairo_analysis_surface_t *surface = (cairo_analysis_surface_t *) abstract_surface;
return surface->fallback;
return surface->has_unsupported;
}

Просмотреть файл

@ -730,8 +730,8 @@ _cairo_atsui_scaled_font_init_glyph_surface (cairo_atsui_font_t *scaled_font,
/* correct for difference between cairo and quartz
* coordinate systems.
*/
cairo_surface_set_device_offset ((cairo_surface_t *)surface, left,
-bbox.size.height - bottom);
cairo_surface_set_device_offset ((cairo_surface_t *)surface,
-left, (bbox.size.height + bottom));
_cairo_scaled_glyph_set_surface (scaled_glyph,
&base,
surface);

Просмотреть файл

@ -158,7 +158,7 @@ encode_integer (unsigned char *p, int i)
i = -i - 108;
*p++ = (i >> 8)+ 251;
*p++ = i & 0xff;
} else if (i >= -1131 && i <= -108) {
} else if (i >= -32768 && i <= 32767) {
*p++ = 28;
*p++ = (i >> 8) & 0xff;
*p++ = i & 0xff;

Просмотреть файл

@ -654,7 +654,6 @@ _cairo_clip_copy_rectangle_list (cairo_clip_t *clip, cairo_gstate_t *gstate)
}
_cairo_region_boxes_fini (&clip->region, boxes);
} else {
cairo_rectangle_int_t extents;

Просмотреть файл

@ -1284,8 +1284,8 @@ _directfb_acquire_font_cache (cairo_directfb_surface_t *surface,
return CAIRO_INT_STATUS_UNSUPPORTED;
}
points[n].x = _cairo_lround (glyphs[i].x + img->base.device_transform.x0);
points[n].y = _cairo_lround (glyphs[i].y + img->base.device_transform.y0);
points[n].x = _cairo_lround (glyphs[i].x - img->base.device_transform.x0);
points[n].y = _cairo_lround (glyphs[i].y - img->base.device_transform.y0);
if (points[n].x >= surface->width ||
points[n].y >= surface->height ||

Просмотреть файл

@ -556,6 +556,7 @@ _cairo_ft_unscaled_font_lock_face (cairo_ft_unscaled_font_t *unscaled)
unscaled->id,
&face) != FT_Err_Ok)
{
unscaled->lock_count--;
CAIRO_MUTEX_UNLOCK (unscaled->mutex);
_cairo_error (CAIRO_STATUS_NO_MEMORY);
return NULL;
@ -587,7 +588,6 @@ _compute_transform (cairo_ft_font_transform_t *sf,
cairo_matrix_t *scale)
{
cairo_matrix_t normalized = *scale;
double tx, ty;
/* The font matrix has x and y "scale" components which we extract and
* use as character scale values. These influence the way freetype
@ -606,7 +606,7 @@ _compute_transform (cairo_ft_font_transform_t *sf,
_cairo_matrix_get_affine (&normalized,
&sf->shape[0][0], &sf->shape[0][1],
&sf->shape[1][0], &sf->shape[1][1],
&tx, &ty);
NULL, NULL);
} else {
sf->shape[0][0] = sf->shape[1][1] = 1.0;
sf->shape[0][1] = sf->shape[1][0] = 0.0;
@ -748,6 +748,12 @@ _get_bitmap_surface (FT_Bitmap *bitmap,
width = bitmap->width;
height = bitmap->rows;
if (width == 0 || height == 0) {
*surface = (cairo_image_surface_t *)
cairo_image_surface_create_for_data (NULL, format, 0, 0, 0);
return (*surface)->base.status;
}
switch (bitmap->pixel_mode) {
case FT_PIXEL_MODE_MONO:
stride = (((width + 31) & ~31) >> 3);
@ -1070,11 +1076,13 @@ _render_glyph_outline (FT_Face face,
/*
* Note: the font's coordinate system is upside down from ours, so the
* Y coordinate of the control box needs to be negated.
* Y coordinate of the control box needs to be negated. Moreover, device
* offsets are position of glyph origin relative to top left while xMin
* and yMax are offsets of top left relative to origin. Another negation.
*/
cairo_surface_set_device_offset (&(*surface)->base,
floor ((double) cbox.xMin / 64.0),
floor (-(double) cbox.yMax / 64.0));
floor (-(double) cbox.xMin / 64.0),
floor (+(double) cbox.yMax / 64.0));
return CAIRO_STATUS_SUCCESS;
}
@ -1097,7 +1105,9 @@ _render_glyph_bitmap (FT_Face face,
* we avoid the FT_LOAD_NO_RECURSE flag.
*/
error = FT_Render_Glyph (glyphslot, FT_RENDER_MODE_NORMAL);
if (error) {
/* XXX ignoring all other errors for now. They are not fatal, typically
* just a glyph-not-found. */
if (error == FT_Err_Out_Of_Memory) {
_cairo_error (CAIRO_STATUS_NO_MEMORY);
return CAIRO_STATUS_NO_MEMORY;
}
@ -1108,11 +1118,14 @@ _render_glyph_bitmap (FT_Face face,
/*
* Note: the font's coordinate system is upside down from ours, so the
* Y coordinate of the control box needs to be negated.
* Y coordinate of the control box needs to be negated. Moreover, device
* offsets are position of glyph origin relative to top left while
* bitmap_left and bitmap_top are offsets of top left relative to origin.
* Another negation.
*/
cairo_surface_set_device_offset (&(*surface)->base,
glyphslot->bitmap_left,
-glyphslot->bitmap_top);
-glyphslot->bitmap_left,
+glyphslot->bitmap_top);
return status;
}
@ -1127,7 +1140,7 @@ _transform_glyph_bitmap (cairo_matrix_t * shape,
cairo_surface_t *image;
double x[4], y[4];
double origin_x, origin_y;
int origin_width, origin_height;
int orig_width, orig_height;
int i;
int x_min, y_min, x_max, y_max;
int width, height;
@ -1141,19 +1154,19 @@ _transform_glyph_bitmap (cairo_matrix_t * shape,
original_to_transformed = *shape;
cairo_surface_get_device_offset (&(*surface)->base, &origin_x, &origin_y);
origin_width = cairo_image_surface_get_width (&(*surface)->base);
origin_height = cairo_image_surface_get_height (&(*surface)->base);
orig_width = cairo_image_surface_get_width (&(*surface)->base);
orig_height = cairo_image_surface_get_height (&(*surface)->base);
cairo_matrix_translate (&original_to_transformed,
origin_x, origin_y);
-origin_x, -origin_y);
/* Find the bounding box of the original bitmap under that
* transform
*/
x[0] = 0; y[0] = 0;
x[1] = origin_width; y[1] = 0;
x[2] = origin_width; y[2] = origin_height;
x[3] = 0; y[3] = origin_height;
x[0] = 0; y[0] = 0;
x[1] = orig_width; y[1] = 0;
x[2] = orig_width; y[2] = orig_height;
x[3] = 0; y[3] = orig_height;
for (i = 0; i < 4; i++)
cairo_matrix_transform_point (&original_to_transformed,
@ -1165,11 +1178,11 @@ _transform_glyph_bitmap (cairo_matrix_t * shape,
for (i = 1; i < 4; i++) {
if (x[i] < x_min)
x_min = floor (x[i]);
if (x[i] > x_max)
else if (x[i] > x_max)
x_max = ceil (x[i]);
if (y[i] < y_min)
y_min = floor (y[i]);
if (y[i] > y_max)
else if (y[i] > y_max)
y_max = ceil (y[i]);
}
@ -1228,8 +1241,6 @@ _transform_glyph_bitmap (cairo_matrix_t * shape,
/* Now update the cache entry for the new bitmap, recomputing
* the origin based on the final transform.
*/
origin_x = - origin_x;
origin_y = - origin_y;
cairo_matrix_transform_point (&original_to_transformed,
&origin_x, &origin_y);
@ -1238,8 +1249,8 @@ _transform_glyph_bitmap (cairo_matrix_t * shape,
cairo_surface_destroy (&old_image->base);
cairo_surface_set_device_offset (&(*surface)->base,
- _cairo_lround (origin_x),
- _cairo_lround (origin_y));
_cairo_lround (origin_x),
_cairo_lround (origin_y));
return status;
}
@ -1891,8 +1902,9 @@ _cairo_ft_scaled_glyph_init (void *abstract_font,
error = FT_Load_Glyph (scaled_font->unscaled->face,
_cairo_scaled_glyph_index(scaled_glyph),
load_flags);
if (error) {
/* XXX ignoring all other errors for now. They are not fatal, typically
* just a glyph-not-found. */
if (error == FT_Err_Out_Of_Memory) {
status = CAIRO_STATUS_NO_MEMORY;
goto FAIL;
}
@ -2042,8 +2054,9 @@ _cairo_ft_scaled_glyph_init (void *abstract_font,
error = FT_Load_Glyph (face,
_cairo_scaled_glyph_index(scaled_glyph),
load_flags | FT_LOAD_NO_BITMAP);
if (error) {
/* XXX ignoring all other errors for now. They are not fatal, typically
* just a glyph-not-found. */
if (error == FT_Err_Out_Of_Memory) {
_cairo_ft_unscaled_font_unlock_face (unscaled);
_cairo_error (CAIRO_STATUS_NO_MEMORY);
return CAIRO_STATUS_NO_MEMORY;

Просмотреть файл

@ -157,7 +157,7 @@ _cairo_glitz_get_boxes_from_region (cairo_region_t *region, int *nboxes)
glitz_box_t *gboxes;
int n, i;
if (_cairo_region_get_boxes (&surface->clip, &n, &cboxes) != CAIRO_STATUS_SUCCESS)
if (_cairo_region_get_boxes (region, &n, &cboxes) != CAIRO_STATUS_SUCCESS)
return NULL;
*nboxes = n;
@ -176,7 +176,7 @@ _cairo_glitz_get_boxes_from_region (cairo_region_t *region, int *nboxes)
}
done:
_cairo_region_boxes_fini (&sruface->clip, &cboxes);
_cairo_region_boxes_fini (region, cboxes);
return gboxes;
}
@ -803,10 +803,10 @@ _cairo_glitz_pattern_acquire_surface (cairo_pattern_t *pattern,
for (i = 0; i < gradient->n_stops; i++)
{
pixels[i] =
(((int) (gradient->stops[i].color.alpha >> 8)) << 24) |
(((int) (gradient->stops[i].color.red >> 8)) << 16) |
(((int) (gradient->stops[i].color.green >> 8)) << 8) |
(((int) (gradient->stops[i].color.blue >> 8)));
(((int) (gradient->stops[i].color.alpha_short >> 8)) << 24) |
(((int) (gradient->stops[i].color.red_short >> 8)) << 16) |
(((int) (gradient->stops[i].color.green_short >> 8)) << 8) |
(((int) (gradient->stops[i].color.blue_short >> 8)));
params[n_base_params + 3 * i + 0] = gradient->stops[i].x;
params[n_base_params + 3 * i + 1] = i << 16;
@ -834,10 +834,10 @@ _cairo_glitz_pattern_acquire_surface (cairo_pattern_t *pattern,
params[0] = grad->c1.x;
params[1] = grad->c1.y;
params[2] = grad->radius1;
params[2] = grad->r1;
params[3] = grad->c2.x;
params[4] = grad->c2.y;
params[5] = grad->radius2;
params[5] = grad->r2;
attr->filter = GLITZ_FILTER_RADIAL_GRADIENT;
}
@ -1430,12 +1430,11 @@ _cairo_glitz_surface_composite_trapezoids (cairo_operator_t op,
static cairo_int_status_t
_cairo_glitz_surface_set_clip_region (void *abstract_surface,
cairo_region_t *region);
cairo_region_t *region)
{
cairo_glitz_surface_t *surface = abstract_surface;
if (region)
{
glitz_box_t *box;
int n;
@ -2203,8 +2202,8 @@ _cairo_glitz_surface_old_show_glyphs (cairo_scaled_font_t *scaled_font,
x_offset = scaled_glyphs[i]->surface->base.device_transform.x0;
y_offset = scaled_glyphs[i]->surface->base.device_transform.y0;
x1 = _cairo_lround (glyphs[i].x) + x_offset;
y1 = _cairo_lround (glyphs[i].y) + y_offset;
x1 = _cairo_lround (glyphs[i].x - x_offset);
y1 = _cairo_lround (glyphs[i].y - y_offset);
x2 = x1 + glyph_private->area->width;
y2 = y1 + glyph_private->area->height;
@ -2247,8 +2246,8 @@ _cairo_glitz_surface_old_show_glyphs (cairo_scaled_font_t *scaled_font,
x_offset = scaled_glyphs[i]->surface->base.device_transform.x0;
y_offset = scaled_glyphs[i]->surface->base.device_transform.y0;
x1 = _cairo_lround (glyphs[i].x) + x_offset;
y1 = _cairo_lround (glyphs[i].y) + y_offset;
x1 = _cairo_lround (glyphs[i].x - x_offset);
y1 = _cairo_lround (glyphs[i].y - y_offset);
glitz_composite (_glitz_operator (op),
src->surface,

Просмотреть файл

@ -747,8 +747,9 @@ _cairo_gstate_backend_to_user_rectangle (cairo_gstate_t *gstate,
{
cairo_matrix_t matrix_inverse;
cairo_matrix_multiply (&matrix_inverse, &gstate->ctm_inverse,
&gstate->target->device_transform_inverse);
cairo_matrix_multiply (&matrix_inverse,
&gstate->target->device_transform_inverse,
&gstate->ctm_inverse);
_cairo_matrix_transform_bounding_box (&matrix_inverse,
x1, y1, x2, y2, is_tight);
}
@ -1086,13 +1087,13 @@ BAIL:
cairo_status_t
_cairo_gstate_copy_page (cairo_gstate_t *gstate)
{
return _cairo_surface_copy_page (gstate->target);
return cairo_surface_copy_page (gstate->target);
}
cairo_status_t
_cairo_gstate_show_page (cairo_gstate_t *gstate)
{
return _cairo_surface_show_page (gstate->target);
return cairo_surface_show_page (gstate->target);
}
static void
@ -1396,13 +1397,14 @@ _cairo_gstate_get_scaled_font (cairo_gstate_t *gstate,
*
* [ 12.0, 0.0, 0.0, 12.0, 0.0, 0.0 ]
*
* It is an affine matrix, like all cairo matrices, but its tx and ty
* components are always set to zero; we don't permit "nudging" fonts
* around.
* It is an affine matrix, like all cairo matrices, where its tx and ty
* components are used to "nudging" fonts around and are handled in gstate
* and then ignored by the "scaled-font" layer.
*
* In order to perform any action on a font, we must build an object
* called a cairo_font_scale_t; this contains the central 2x2 matrix
* resulting from "font matrix * CTM".
* resulting from "font matrix * CTM" (sans the font matrix translation
* components as stated in the previous paragraph).
*
* We pass this to the font when making requests of it, which causes it to
* reply for a particular [user request, device] combination, under the CTM

Просмотреть файл

@ -58,6 +58,8 @@ static const cairo_image_surface_t _cairo_image_surface_nil_invalid_format = {
0.0, 1.0,
0.0, 0.0
}, /* device_transform_inverse */
0.0, /* x_resolution */
0.0, /* y_resolution */
0.0, /* x_fallback_resolution */
0.0, /* y_fallback_resolution */
NULL, /* clip */
@ -71,6 +73,7 @@ static const cairo_image_surface_t _cairo_image_surface_nil_invalid_format = {
CAIRO_HINT_METRICS_DEFAULT
} /* font_options */
}, /* base */
PIXMAN_a8r8g8b8, /* pixman_format */
CAIRO_FORMAT_ARGB32, /* format */
NULL, /* data */
FALSE, /* owns_data */
@ -82,10 +85,83 @@ static const cairo_image_surface_t _cairo_image_surface_nil_invalid_format = {
NULL /* pixman_image */
};
static cairo_format_t
_cairo_format_from_pixman_format (pixman_format_code_t pixman_format)
{
switch (pixman_format) {
case PIXMAN_a8r8g8b8:
return CAIRO_FORMAT_ARGB32;
case PIXMAN_x8r8g8b8:
return CAIRO_FORMAT_RGB24;
case PIXMAN_a8:
return CAIRO_FORMAT_A8;
case PIXMAN_a1:
return CAIRO_FORMAT_A1;
case PIXMAN_a8b8g8r8: case PIXMAN_x8b8g8r8: case PIXMAN_r8g8b8:
case PIXMAN_b8g8r8: case PIXMAN_r5g6b5: case PIXMAN_b5g6r5:
case PIXMAN_a1r5g5b5: case PIXMAN_x1r5g5b5: case PIXMAN_a1b5g5r5:
case PIXMAN_x1b5g5r5: case PIXMAN_a4r4g4b4: case PIXMAN_x4r4g4b4:
case PIXMAN_a4b4g4r4: case PIXMAN_x4b4g4r4: case PIXMAN_r3g3b2:
case PIXMAN_b2g3r3: case PIXMAN_a2r2g2b2: case PIXMAN_a2b2g2r2:
case PIXMAN_c8: case PIXMAN_g8: case PIXMAN_x4a4:
case PIXMAN_a4: case PIXMAN_r1g2b1: case PIXMAN_b1g2r1:
case PIXMAN_a1r1g1b1: case PIXMAN_a1b1g1r1: case PIXMAN_c4:
case PIXMAN_g4: case PIXMAN_g1:
default:
return CAIRO_FORMAT_INVALID;
}
return CAIRO_FORMAT_INVALID;
}
static cairo_content_t
_cairo_content_from_pixman_format (pixman_format_code_t pixman_format)
{
switch (pixman_format) {
case PIXMAN_a8r8g8b8:
case PIXMAN_a8b8g8r8:
case PIXMAN_a1r5g5b5:
case PIXMAN_a1b5g5r5:
case PIXMAN_a4r4g4b4:
case PIXMAN_a4b4g4r4:
case PIXMAN_a2r2g2b2:
case PIXMAN_a2b2g2r2:
case PIXMAN_a1r1g1b1:
case PIXMAN_a1b1g1r1:
return CAIRO_CONTENT_COLOR_ALPHA;
case PIXMAN_x8r8g8b8:
case PIXMAN_x8b8g8r8:
case PIXMAN_r8g8b8:
case PIXMAN_b8g8r8:
case PIXMAN_r5g6b5:
case PIXMAN_b5g6r5:
case PIXMAN_x1r5g5b5:
case PIXMAN_x1b5g5r5:
case PIXMAN_x4r4g4b4:
case PIXMAN_x4b4g4r4:
case PIXMAN_r3g3b2:
case PIXMAN_b2g3r3:
case PIXMAN_c8:
case PIXMAN_g8:
case PIXMAN_r1g2b1:
case PIXMAN_b1g2r1:
case PIXMAN_c4:
case PIXMAN_g4:
case PIXMAN_g1:
return CAIRO_CONTENT_COLOR;
case PIXMAN_a8:
case PIXMAN_a1:
case PIXMAN_x4a4:
case PIXMAN_a4:
return CAIRO_CONTENT_ALPHA;
}
return CAIRO_CONTENT_COLOR_ALPHA;
}
cairo_surface_t *
_cairo_image_surface_create_for_pixman_image (pixman_image_t *pixman_image,
cairo_format_t format)
_cairo_image_surface_create_for_pixman_image (pixman_image_t *pixman_image,
pixman_format_code_t pixman_format)
{
cairo_image_surface_t *surface;
@ -96,11 +172,12 @@ _cairo_image_surface_create_for_pixman_image (pixman_image_t *pixman_image,
}
_cairo_surface_init (&surface->base, &cairo_image_surface_backend,
_cairo_content_from_format (format));
_cairo_content_from_pixman_format (pixman_format));
surface->pixman_image = pixman_image;
surface->format = format;
surface->pixman_format = pixman_format;
surface->format = _cairo_format_from_pixman_format (pixman_format);
surface->data = (unsigned char *) pixman_image_get_data (pixman_image);
surface->owns_data = FALSE;
surface->has_clip = FALSE;
@ -113,49 +190,143 @@ _cairo_image_surface_create_for_pixman_image (pixman_image_t *pixman_image,
return &surface->base;
}
static cairo_bool_t
_CAIRO_MASK_FORMAT (cairo_format_masks_t *masks, cairo_format_t *format)
/* XXX: This function should really live inside pixman. */
pixman_format_code_t
_pixman_format_from_masks (cairo_format_masks_t *masks)
{
/* XXX: many formats are simply not supported by pixman, so this function
* converts the masks into something we know will be supported.
*/
switch (masks->bpp) {
case 32:
if (masks->alpha_mask == 0xff000000 &&
masks->red_mask == 0x00ff0000 &&
masks->red_mask == 0x00ff0000 &&
masks->green_mask == 0x0000ff00 &&
masks->blue_mask == 0x000000ff)
masks->blue_mask == 0x000000ff)
{
*format = CAIRO_FORMAT_ARGB32;
return TRUE;
return PIXMAN_a8r8g8b8;
}
if (masks->alpha_mask == 0x00000000 &&
masks->red_mask == 0x00ff0000 &&
masks->red_mask == 0x00ff0000 &&
masks->green_mask == 0x0000ff00 &&
masks->blue_mask == 0x000000ff)
masks->blue_mask == 0x000000ff)
{
*format = CAIRO_FORMAT_RGB24;
return TRUE;
return PIXMAN_x8r8g8b8;
}
if (masks->alpha_mask == 0xff000000 &&
masks->red_mask == 0x000000ff &&
masks->green_mask == 0x0000ff00 &&
masks->blue_mask == 0x00ff0000)
{
return PIXMAN_a8b8g8r8;
}
if (masks->alpha_mask == 0x00000000 &&
masks->red_mask == 0x000000ff &&
masks->green_mask == 0x0000ff00 &&
masks->blue_mask == 0x00ff0000)
{
return PIXMAN_x8b8g8r8;
}
break;
case 16:
if (masks->alpha_mask == 0x0000 &&
masks->red_mask == 0xf800 &&
masks->green_mask == 0x07e0 &&
masks->blue_mask == 0x001f)
{
return PIXMAN_r5g6b5;
}
if (masks->alpha_mask == 0x0000 &&
masks->red_mask == 0x7c00 &&
masks->green_mask == 0x03e0 &&
masks->blue_mask == 0x001f)
{
return PIXMAN_x1r5g5b5;
}
break;
case 8:
if (masks->alpha_mask == 0xff)
{
*format = CAIRO_FORMAT_A8;
return TRUE;
return PIXMAN_a8;
}
break;
case 1:
if (masks->alpha_mask == 0x1)
{
*format = CAIRO_FORMAT_A1;
return TRUE;
return PIXMAN_a1;
}
break;
}
return FALSE;
fprintf (stderr,
"Error: Cairo " PACKAGE_VERSION " does not yet support the requested image format:\n"
"\tDepth: %d\n"
"\tAlpha mask: 0x%08lx\n"
"\tRed mask: 0x%08lx\n"
"\tGreen mask: 0x%08lx\n"
"\tBlue mask: 0x%08lx\n"
"Please file an enhancement request (quoting the above) at:\n"
PACKAGE_BUGREPORT "\n",
masks->bpp, masks->alpha_mask,
masks->red_mask, masks->green_mask, masks->blue_mask);
ASSERT_NOT_REACHED;
return 0;
}
/* XXX: This function should really live inside pixman. */
void
_pixman_format_to_masks (pixman_format_code_t pixman_format,
uint32_t *bpp,
uint32_t *red,
uint32_t *green,
uint32_t *blue)
{
*red = 0x0;
*green = 0x0;
*blue = 0x0;
switch (pixman_format)
{
case PIXMAN_a8r8g8b8:
case PIXMAN_x8r8g8b8:
default:
*bpp = 32;
*red = 0x00ff0000;
*green = 0x0000ff00;
*blue = 0x000000ff;
break;
case PIXMAN_a8b8g8r8:
case PIXMAN_x8b8g8r8:
*bpp = 32;
*red = 0x000000ff;
*green = 0x0000ff00;
*blue = 0x00ff0000;
break;
case PIXMAN_r5g6b5:
*bpp = 16;
*red = 0xf800;
*green = 0x07e0;
*blue = 0x001f;
break;
case PIXMAN_x1r5g5b5:
*bpp = 16;
*red = 0x7c00;
*green = 0x03e0;
*blue = 0x001f;
break;
case PIXMAN_a8:
*bpp = 8;
break;
case PIXMAN_a1:
*bpp = 1;
break;
}
}
/* XXX: This function really should be eliminated. We don't really
* want to advertise a cairo image surface that supports any possible
* format. A minimal step would be to replace this function with one
@ -167,18 +338,15 @@ _cairo_image_surface_create_with_masks (unsigned char *data,
int height,
int stride)
{
cairo_format_t format;
pixman_format_code_t pixman_format;
if (!_CAIRO_MASK_FORMAT (masks, &format)) {
_cairo_error (CAIRO_STATUS_INVALID_FORMAT);
return (cairo_surface_t*) &_cairo_surface_nil;
}
pixman_format = _pixman_format_from_masks (masks);
return cairo_image_surface_create_for_data (data,
format,
width,
height,
stride);
return _cairo_image_surface_create_with_pixman_format (data,
pixman_format,
width,
height,
stride);
}
static pixman_format_code_t
@ -204,6 +372,33 @@ _cairo_format_to_pixman_format_code (cairo_format_t format)
return ret;
}
cairo_surface_t *
_cairo_image_surface_create_with_pixman_format (unsigned char *data,
pixman_format_code_t pixman_format,
int width,
int height,
int stride)
{
cairo_surface_t *surface;
pixman_image_t *pixman_image;
pixman_image = pixman_image_create_bits (pixman_format, width, height,
(uint32_t *) data, stride);
if (pixman_image == NULL) {
_cairo_error (CAIRO_STATUS_NO_MEMORY);
return (cairo_surface_t*) &_cairo_surface_nil;
}
surface = _cairo_image_surface_create_for_pixman_image (pixman_image,
pixman_format);
if (cairo_surface_status (surface)) {
pixman_image_unref (pixman_image);
}
return surface;
}
/**
* cairo_image_surface_create:
* @format: format of pixels in the surface to create
@ -231,7 +426,6 @@ cairo_image_surface_create (cairo_format_t format,
{
cairo_surface_t *surface;
pixman_format_code_t pixman_format;
pixman_image_t *pixman_image;
if (! CAIRO_FORMAT_VALID (format)) {
_cairo_error (CAIRO_STATUS_INVALID_FORMAT);
@ -239,18 +433,9 @@ cairo_image_surface_create (cairo_format_t format,
}
pixman_format = _cairo_format_to_pixman_format_code (format);
pixman_image = pixman_image_create_bits (pixman_format, width, height,
NULL, -1);
if (pixman_image == NULL) {
_cairo_error (CAIRO_STATUS_NO_MEMORY);
return (cairo_surface_t*) &_cairo_surface_nil;
}
surface = _cairo_image_surface_create_for_pixman_image (pixman_image, format);
if (cairo_surface_status (surface)) {
pixman_image_unref (pixman_image);
}
return _cairo_image_surface_create_with_pixman_format (NULL, pixman_format,
width, height, -1);
return surface;
}
@ -305,29 +490,15 @@ cairo_image_surface_create_for_data (unsigned char *data,
int height,
int stride)
{
cairo_surface_t *surface;
pixman_format_code_t pixman_format;
pixman_image_t *pixman_image;
if (! CAIRO_FORMAT_VALID (format))
return (cairo_surface_t*) &_cairo_surface_nil;
pixman_format = _cairo_format_to_pixman_format_code (format);
pixman_image = pixman_image_create_bits (pixman_format, width, height,
(uint32_t *) data, stride);
if (pixman_image == NULL) {
_cairo_error (CAIRO_STATUS_NO_MEMORY);
return (cairo_surface_t*) &_cairo_surface_nil;
}
surface = _cairo_image_surface_create_for_pixman_image (pixman_image, format);
if (cairo_surface_status (surface)) {
pixman_image_unref (pixman_image);
}
return surface;
return _cairo_image_surface_create_with_pixman_format (data, pixman_format,
width, height, stride);
}
slim_hidden_def (cairo_image_surface_create_for_data);
@ -486,20 +657,10 @@ _cairo_format_from_content (cairo_content_t content)
cairo_content_t
_cairo_content_from_format (cairo_format_t format)
{
/* XXX: Use an int to avoid the warnings from mixed cairo_format_t
* and cairo_internal_format_t values. The warnings are extremely
* valuable since mixing enums can lead to subtle bugs. It's just
* that cairo_internal_format_t is an interim approach to getting
* bug #7294 fixed so we can release cairo 1.2.2 . */
int f = format;
switch (f) {
switch (format) {
case CAIRO_FORMAT_ARGB32:
case CAIRO_INTERNAL_FORMAT_ABGR32:
return CAIRO_CONTENT_COLOR_ALPHA;
case CAIRO_FORMAT_RGB24:
case CAIRO_INTERNAL_FORMAT_RGB16_565:
case CAIRO_INTERNAL_FORMAT_BGR24:
return CAIRO_CONTENT_COLOR;
case CAIRO_FORMAT_A8:
case CAIRO_FORMAT_A1:
@ -627,7 +788,7 @@ _cairo_image_surface_set_matrix (cairo_image_surface_t *surface,
return CAIRO_STATUS_SUCCESS;
}
static cairo_status_t
static void
_cairo_image_surface_set_filter (cairo_image_surface_t *surface, cairo_filter_t filter)
{
pixman_filter_t pixman_filter;
@ -659,11 +820,9 @@ _cairo_image_surface_set_filter (cairo_image_surface_t *surface, cairo_filter_t
}
pixman_image_set_filter (surface->pixman_image, pixman_filter, NULL, 0);
return CAIRO_STATUS_SUCCESS;
}
static cairo_int_status_t
static cairo_status_t
_cairo_image_surface_set_attributes (cairo_image_surface_t *surface,
cairo_surface_attributes_t *attributes)
{
@ -688,9 +847,9 @@ _cairo_image_surface_set_attributes (cairo_image_surface_t *surface,
break;
}
status = _cairo_image_surface_set_filter (surface, attributes->filter);
_cairo_image_surface_set_filter (surface, attributes->filter);
return status;
return CAIRO_STATUS_SUCCESS;
}
/* XXX: I think we should fix pixman to match the names/order of the
@ -903,6 +1062,9 @@ _cairo_image_surface_composite_trapezoids (cairo_operator_t op,
int mask_bpp;
int ret, i;
if (height == 0 || width == 0)
return CAIRO_STATUS_SUCCESS;
/* Convert traps to pixman traps */
if (num_traps > ARRAY_LENGTH(stack_traps)) {
pixman_traps = _cairo_malloc_ab (num_traps, sizeof(pixman_trapezoid_t));
@ -924,7 +1086,7 @@ _cairo_image_surface_composite_trapezoids (cairo_operator_t op,
}
/* Special case adding trapezoids onto a mask surface; we want to avoid
* creating an intermediate temporary mask unecessarily.
* creating an intermediate temporary mask unnecessarily.
*
* We make the assumption here that the portion of the trapezoids
* contained within the surface is bounded by [dst_x,dst_y,width,height];
@ -1074,8 +1236,7 @@ _cairo_image_surface_reset (void *abstract_surface)
cairo_status_t status;
status = _cairo_image_surface_set_clip_region (surface, NULL);
if (status)
return status;
assert (status == CAIRO_STATUS_SUCCESS);
return CAIRO_STATUS_SUCCESS;
}
@ -1115,15 +1276,15 @@ const cairo_surface_backend_t cairo_image_surface_backend = {
_cairo_image_surface_get_font_options,
NULL, /* flush */
NULL, /* mark_dirty_rectangle */
NULL, //* font_fini */
NULL, //* glyph_fini */
NULL, /* font_fini */
NULL, /* glyph_fini */
NULL, /* paint */
NULL, /* mask */
NULL, /* stroke */
NULL, /* fill */
NULL, /* show_glyphs */
NULL, /* snapshot */
NULL, /* snapshot */
NULL, /* is_similar */
_cairo_image_surface_reset
@ -1143,15 +1304,15 @@ _cairo_image_surface_clone (cairo_image_surface_t *surface,
cairo_image_surface_create (format,
surface->width, surface->height);
/* Use _cairo_surface_composite directly */
cr = cairo_create (&clone->base);
cairo_surface_get_device_offset (&surface->base, &x, &y);
cairo_set_source_surface (cr, &surface->base, x, y);
cairo_surface_set_device_offset (&clone->base, x, y);
/* XXX Use _cairo_surface_composite directly */
cr = cairo_create (&clone->base);
cairo_set_source_surface (cr, &surface->base, 0, 0);
cairo_set_operator (cr, CAIRO_OPERATOR_SOURCE);
cairo_paint (cr);
cairo_destroy (cr);
cairo_surface_set_device_offset (&clone->base, x, y);
return clone;
}

Просмотреть файл

@ -39,27 +39,12 @@
#include "cairo-wideint-private.h"
/**
* _cairo_malloc:
* @size: size in bytes
*
* Allocate @size memory using malloc().
* The memory should be freed using free().
* malloc is skipped, if 0 bytes are requested, and %NULL will be returned.
*
* Return value: A pointer to the newly allocated memory, or %NULL in
* case of malloc() failure or size is 0.
*/
#define _cairo_malloc(size) \
((size) ? malloc((unsigned) (size)) : NULL)
/**
* _cairo_malloc_ab:
* @n: number of elements to allocate
* @size: size of each element
*
* Allocates @a*@size memory using _cairo_malloc(), taking care to not
* Allocates @a*@size memory using malloc(), taking care to not
* overflow when doing the multiplication. Behaves much like
* calloc(), except that the returned memory is not set to zero.
* The memory should be freed using free().
@ -72,8 +57,8 @@
*/
#define _cairo_malloc_ab(a, size) \
((size) && (unsigned) (a) >= INT32_MAX / (unsigned) (size) ? NULL : \
_cairo_malloc((unsigned) (a) * (unsigned) (size)))
((unsigned) (a) >= INT32_MAX / (unsigned) (size) ? NULL : \
malloc((unsigned) (a) * (unsigned) (size)))
/**
* _cairo_malloc_abc:
@ -81,7 +66,7 @@
* @b: second factor of number of elements to allocate
* @size: size of each element
*
* Allocates @a*@b*@size memory using _cairo_malloc(), taking care to not
* Allocates @a*@b*@size memory using malloc(), taking care to not
* overflow when doing the multiplication. Behaves like
* _cairo_malloc_ab(). The memory should be freed using free().
*
@ -93,9 +78,9 @@
*/
#define _cairo_malloc_abc(a, b, size) \
((b) && (unsigned) (a) >= INT32_MAX / (unsigned) (b) ? NULL : \
(size) && (unsigned) ((a)*(b)) >= INT32_MAX / (unsigned) (size) ? NULL : \
_cairo_malloc((unsigned) (a) * (unsigned) (b) * (unsigned) (size)))
((unsigned) (a) >= INT32_MAX / (unsigned) (b) ? NULL : \
(unsigned) ((a)*(b)) >= INT32_MAX / (unsigned) (size) ? NULL : \
malloc((unsigned) (a) * (unsigned) (b) * (unsigned) size))
/**
* _cairo_malloc_ab_plus_c:
@ -103,7 +88,7 @@
* @size: size of each element
* @k: additional size to allocate
*
* Allocates @a*@ksize+@k memory using _cairo_malloc(), taking care to not
* Allocates @a*@ksize+@k memory using malloc(), taking care to not
* overflow when doing the arithmetic. Behaves like
* _cairo_malloc_ab(). The memory should be freed using free().
*
@ -112,8 +97,8 @@
*/
#define _cairo_malloc_ab_plus_c(n, size, k) \
((size) && (unsigned) (n) >= INT32_MAX / (unsigned) (size) ? NULL : \
((unsigned) (n) >= INT32_MAX / (unsigned) (size) ? NULL : \
(unsigned) (k) >= INT32_MAX - (unsigned) (n) * (unsigned) (size) ? NULL : \
_cairo_malloc((unsigned) (n) * (unsigned) (size) + (unsigned) (k)))
malloc((unsigned) (n) * (unsigned) (size) + (unsigned) (k)))
#endif /* CAIRO_MALLOC_PRIVATE_H */

Просмотреть файл

@ -31,6 +31,7 @@
*
* Contributor(s):
* Kristian Høgsberg <krh@redhat.com>
* Adrian Johnson <ajohnson@redneon.com>
*/
#ifndef CAIRO_META_SURFACE_H
@ -57,21 +58,32 @@ typedef enum {
} cairo_command_type_t;
typedef struct _cairo_command_paint {
typedef enum {
CAIRO_META_REGION_ALL,
CAIRO_META_REGION_NATIVE,
CAIRO_META_REGION_IMAGE_FALLBACK,
} cairo_meta_region_type_t;
typedef struct _cairo_command_header {
cairo_command_type_t type;
cairo_meta_region_type_t region;
} cairo_command_header_t;
typedef struct _cairo_command_paint {
cairo_command_header_t header;
cairo_operator_t op;
cairo_pattern_union_t source;
} cairo_command_paint_t;
typedef struct _cairo_command_mask {
cairo_command_type_t type;
cairo_command_header_t header;
cairo_operator_t op;
cairo_pattern_union_t source;
cairo_pattern_union_t mask;
} cairo_command_mask_t;
typedef struct _cairo_command_stroke {
cairo_command_type_t type;
cairo_command_header_t header;
cairo_operator_t op;
cairo_pattern_union_t source;
cairo_path_fixed_t path;
@ -83,7 +95,7 @@ typedef struct _cairo_command_stroke {
} cairo_command_stroke_t;
typedef struct _cairo_command_fill {
cairo_command_type_t type;
cairo_command_header_t header;
cairo_operator_t op;
cairo_pattern_union_t source;
cairo_path_fixed_t path;
@ -93,7 +105,7 @@ typedef struct _cairo_command_fill {
} cairo_command_fill_t;
typedef struct _cairo_command_show_glyphs {
cairo_command_type_t type;
cairo_command_header_t header;
cairo_operator_t op;
cairo_pattern_union_t source;
cairo_glyph_t *glyphs;
@ -102,7 +114,7 @@ typedef struct _cairo_command_show_glyphs {
} cairo_command_show_glyphs_t;
typedef struct _cairo_command_intersect_clip_path {
cairo_command_type_t type;
cairo_command_header_t header;
cairo_path_fixed_t *path_pointer;
cairo_path_fixed_t path;
cairo_fill_rule_t fill_rule;
@ -111,7 +123,7 @@ typedef struct _cairo_command_intersect_clip_path {
} cairo_command_intersect_clip_path_t;
typedef union _cairo_command {
cairo_command_type_t type;
cairo_command_header_t header;
/* The 5 basic drawing operations. */
cairo_command_paint_t paint;
@ -151,6 +163,18 @@ cairo_private cairo_status_t
_cairo_meta_surface_replay (cairo_surface_t *surface,
cairo_surface_t *target);
cairo_private cairo_status_t
_cairo_meta_surface_replay_analyze_meta_pattern (cairo_surface_t *surface,
cairo_surface_t *target);
cairo_private cairo_status_t
_cairo_meta_surface_replay_and_create_regions (cairo_surface_t *surface,
cairo_surface_t *target);
cairo_private cairo_status_t
_cairo_meta_surface_replay_region (cairo_surface_t *surface,
cairo_surface_t *target,
cairo_meta_region_type_t region);
cairo_private cairo_bool_t
_cairo_surface_is_meta (const cairo_surface_t *surface);

Просмотреть файл

@ -1,6 +1,7 @@
/* cairo - a vector graphics library with display and print output
*
* Copyright © 2005 Red Hat, Inc
* Copyright © 2007 Adrian Johnson
*
* This library is free software; you can redistribute it and/or
* modify it either under the terms of the GNU Lesser General Public
@ -32,6 +33,7 @@
* Contributor(s):
* Kristian Høgsberg <krh@redhat.com>
* Carl Worth <cworth@cworth.org>
* Adrian Johnson <ajohnson@redneon.com>
*/
/* A meta surface is a surface that records all drawing operations at
@ -57,6 +59,12 @@
#include "cairo-meta-surface-private.h"
#include "cairo-clip-private.h"
typedef enum {
CAIRO_META_REPLAY,
CAIRO_META_CREATE_REGIONS,
CAIRO_META_ANALYZE_META_PATTERN
} cairo_meta_replay_type_t;
static const cairo_surface_backend_t cairo_meta_surface_backend;
/* Currently all meta surfaces do have a size which should be passed
@ -123,7 +131,7 @@ _cairo_meta_surface_finish (void *abstract_surface)
elements = _cairo_array_index (&meta->commands, 0);
for (i = 0; i < num_elements; i++) {
command = elements[i];
switch (command->type) {
switch (command->header.type) {
/* 5 basic drawing operations */
@ -184,9 +192,9 @@ _cairo_meta_surface_acquire_source_image (void *abstract_surface,
cairo_meta_surface_t *surface = abstract_surface;
cairo_surface_t *image;
image = cairo_image_surface_create (CAIRO_FORMAT_ARGB32,
surface->width_pixels,
surface->height_pixels);
image = _cairo_image_surface_create_with_content (surface->content,
surface->width_pixels,
surface->height_pixels);
status = _cairo_meta_surface_replay (&surface->base, image);
if (status) {
@ -243,17 +251,12 @@ _cairo_meta_surface_paint (void *abstract_surface,
cairo_meta_surface_t *meta = abstract_surface;
cairo_command_paint_t *command;
/* An optimisation that takes care to not replay what was done
* before surface is cleared. We don't erase recorded commands
* since we may have earlier snapshots of this surface. */
if (op == CAIRO_OPERATOR_CLEAR && !meta->is_clipped)
meta->replay_start_idx = meta->commands.num_elements;
command = malloc (sizeof (cairo_command_paint_t));
if (command == NULL)
return CAIRO_STATUS_NO_MEMORY;
command->type = CAIRO_COMMAND_PAINT;
command->header.type = CAIRO_COMMAND_PAINT;
command->header.region = CAIRO_META_REGION_ALL;
command->op = op;
status = _init_pattern_with_snapshot (&command->source.base, source);
@ -264,6 +267,12 @@ _cairo_meta_surface_paint (void *abstract_surface,
if (status)
goto CLEANUP_SOURCE;
/* An optimisation that takes care to not replay what was done
* before surface is cleared. We don't erase recorded commands
* since we may have earlier snapshots of this surface. */
if (op == CAIRO_OPERATOR_CLEAR && !meta->is_clipped)
meta->replay_start_idx = meta->commands.num_elements;
return CAIRO_STATUS_SUCCESS;
CLEANUP_SOURCE:
@ -287,7 +296,8 @@ _cairo_meta_surface_mask (void *abstract_surface,
if (command == NULL)
return CAIRO_STATUS_NO_MEMORY;
command->type = CAIRO_COMMAND_MASK;
command->header.type = CAIRO_COMMAND_MASK;
command->header.region = CAIRO_META_REGION_ALL;
command->op = op;
status = _init_pattern_with_snapshot (&command->source.base, source);
@ -332,7 +342,8 @@ _cairo_meta_surface_stroke (void *abstract_surface,
if (command == NULL)
return CAIRO_STATUS_NO_MEMORY;
command->type = CAIRO_COMMAND_STROKE;
command->header.type = CAIRO_COMMAND_STROKE;
command->header.region = CAIRO_META_REGION_ALL;
command->op = op;
status = _init_pattern_with_snapshot (&command->source.base, source);
@ -386,7 +397,8 @@ _cairo_meta_surface_fill (void *abstract_surface,
if (command == NULL)
return CAIRO_STATUS_NO_MEMORY;
command->type = CAIRO_COMMAND_FILL;
command->header.type = CAIRO_COMMAND_FILL;
command->header.region = CAIRO_META_REGION_ALL;
command->op = op;
status = _init_pattern_with_snapshot (&command->source.base, source);
@ -432,7 +444,8 @@ _cairo_meta_surface_show_glyphs (void *abstract_surface,
if (command == NULL)
return CAIRO_STATUS_NO_MEMORY;
command->type = CAIRO_COMMAND_SHOW_GLYPHS;
command->header.type = CAIRO_COMMAND_SHOW_GLYPHS;
command->header.region = CAIRO_META_REGION_ALL;
command->op = op;
status = _init_pattern_with_snapshot (&command->source.base, source);
@ -521,7 +534,8 @@ _cairo_meta_surface_intersect_clip_path (void *dst,
if (command == NULL)
return CAIRO_STATUS_NO_MEMORY;
command->type = CAIRO_COMMAND_INTERSECT_CLIP_PATH;
command->header.type = CAIRO_COMMAND_INTERSECT_CLIP_PATH;
command->header.region = CAIRO_META_REGION_ALL;
if (path) {
status = _cairo_path_fixed_init_copy (&command->path, path);
@ -622,7 +636,7 @@ static const cairo_surface_backend_t cairo_meta_surface_backend = {
static cairo_path_fixed_t *
_cairo_command_get_path (cairo_command_t *command)
{
switch (command->type) {
switch (command->header.type) {
case CAIRO_COMMAND_PAINT:
case CAIRO_COMMAND_MASK:
case CAIRO_COMMAND_SHOW_GLYPHS:
@ -639,9 +653,11 @@ _cairo_command_get_path (cairo_command_t *command)
return NULL;
}
cairo_status_t
_cairo_meta_surface_replay (cairo_surface_t *surface,
cairo_surface_t *target)
static cairo_status_t
_cairo_meta_surface_replay_internal (cairo_surface_t *surface,
cairo_surface_t *target,
cairo_meta_replay_type_t type,
cairo_meta_region_type_t region)
{
cairo_meta_surface_t *meta;
cairo_command_t *command, **elements;
@ -665,9 +681,14 @@ _cairo_meta_surface_replay (cairo_surface_t *surface,
for (i = meta->replay_start_idx; i < num_elements; i++) {
command = elements[i];
if (type == CAIRO_META_REPLAY && region != CAIRO_META_REGION_ALL) {
if (command->header.region != region)
continue;
}
/* For all commands except intersect_clip_path, we have to
* ensure the current clip gets set on the surface. */
if (command->type != CAIRO_COMMAND_INTERSECT_CLIP_PATH) {
if (command->header.type != CAIRO_COMMAND_INTERSECT_CLIP_PATH) {
status = _cairo_surface_set_clip (target, &clip);
if (status)
break;
@ -682,7 +703,7 @@ _cairo_meta_surface_replay (cairo_surface_t *surface,
dev_path = &path_copy;
}
switch (command->type) {
switch (command->header.type) {
case CAIRO_COMMAND_PAINT:
status = _cairo_surface_paint (target,
command->paint.op,
@ -720,14 +741,54 @@ _cairo_meta_surface_replay (cairo_surface_t *surface,
break;
}
case CAIRO_COMMAND_FILL:
status = _cairo_surface_fill (target,
command->fill.op,
&command->fill.source.base,
dev_path,
command->fill.fill_rule,
command->fill.tolerance,
command->fill.antialias);
{
cairo_command_t *stroke_command;
stroke_command = (i < num_elements - 1) ? elements[i + 1] : NULL;
if (stroke_command != NULL &&
stroke_command->header.type == CAIRO_COMMAND_STROKE &&
_cairo_path_fixed_is_equal (dev_path, _cairo_command_get_path (stroke_command))) {
cairo_matrix_t dev_ctm;
cairo_matrix_t dev_ctm_inverse;
cairo_matrix_t tmp;
dev_ctm = stroke_command->stroke.ctm;
dev_ctm_inverse = stroke_command->stroke.ctm_inverse;
if (has_device_transform) {
cairo_matrix_multiply (&dev_ctm, &dev_ctm, device_transform);
tmp = surface->device_transform;
status = cairo_matrix_invert (&tmp);
assert (status == CAIRO_STATUS_SUCCESS);
cairo_matrix_multiply (&dev_ctm_inverse, &tmp, &dev_ctm_inverse);
}
status = _cairo_surface_fill_stroke (target,
command->fill.op,
&command->fill.source.base,
command->fill.fill_rule,
command->fill.tolerance,
command->fill.antialias,
dev_path,
stroke_command->stroke.op,
&stroke_command->stroke.source.base,
&stroke_command->stroke.style,
&dev_ctm,
&dev_ctm_inverse,
stroke_command->stroke.tolerance,
stroke_command->stroke.antialias);
i++;
} else
status = _cairo_surface_fill (target,
command->fill.op,
&command->fill.source.base,
dev_path,
command->fill.fill_rule,
command->fill.tolerance,
command->fill.antialias);
break;
}
case CAIRO_COMMAND_SHOW_GLYPHS:
{
cairo_glyph_t *glyphs = command->show_glyphs.glyphs;
@ -770,6 +831,7 @@ _cairo_meta_surface_replay (cairo_surface_t *surface,
command->intersect_clip_path.tolerance,
command->intersect_clip_path.antialias,
target);
assert (status == 0);
break;
default:
ASSERT_NOT_REACHED;
@ -778,6 +840,20 @@ _cairo_meta_surface_replay (cairo_surface_t *surface,
if (dev_path == &path_copy)
_cairo_path_fixed_fini (&path_copy);
if (type == CAIRO_META_CREATE_REGIONS) {
if (status == CAIRO_STATUS_SUCCESS) {
command->header.region = CAIRO_META_REGION_NATIVE;
} else if (status == CAIRO_INT_STATUS_IMAGE_FALLBACK) {
command->header.region = CAIRO_META_REGION_IMAGE_FALLBACK;
status = CAIRO_STATUS_SUCCESS;
}
}
if (type == CAIRO_META_ANALYZE_META_PATTERN) {
if (status == CAIRO_INT_STATUS_FLATTEN_TRANSPARENCY)
status = CAIRO_STATUS_SUCCESS;
}
if (status)
break;
}
@ -786,3 +862,50 @@ _cairo_meta_surface_replay (cairo_surface_t *surface,
return status;
}
cairo_status_t
_cairo_meta_surface_replay (cairo_surface_t *surface,
cairo_surface_t *target)
{
return _cairo_meta_surface_replay_internal (surface,
target,
CAIRO_META_REPLAY,
CAIRO_META_REGION_ALL);
}
cairo_status_t
_cairo_meta_surface_replay_analyze_meta_pattern (cairo_surface_t *surface,
cairo_surface_t *target)
{
return _cairo_meta_surface_replay_internal (surface,
target,
CAIRO_META_ANALYZE_META_PATTERN,
CAIRO_META_REGION_ALL);
}
/* Replay meta to surface. When the return status of each operation is
* one of CAIRO_STATUS_SUCCESS, CAIRO_INT_STATUS_UNSUPPORTED, or
* CAIRO_INT_STATUS_FLATTEN_TRANSPARENCY the status of each operation
* will be stored in the meta surface. Any other status will abort the
* replay and return the status.
*/
cairo_status_t
_cairo_meta_surface_replay_and_create_regions (cairo_surface_t *surface,
cairo_surface_t *target)
{
return _cairo_meta_surface_replay_internal (surface,
target,
CAIRO_META_CREATE_REGIONS,
CAIRO_META_REGION_ALL);
}
cairo_status_t
_cairo_meta_surface_replay_region (cairo_surface_t *surface,
cairo_surface_t *target,
cairo_meta_region_type_t region)
{
return _cairo_meta_surface_replay_internal (surface,
target,
CAIRO_META_REPLAY,
region);
}

Просмотреть файл

@ -49,9 +49,6 @@
CAIRO_BEGIN_DECLS
#ifndef MOZILLA_CAIRO_NOT_DEFINED
#define CAIRO_NO_MUTEX 1
#endif
/* A fully qualified no-operation statement */
#define CAIRO_MUTEX_NOOP do {/*no-op*/} while (0)
@ -144,24 +141,13 @@ CAIRO_BEGIN_DECLS
#if CAIRO_NO_MUTEX
/* No mutex at all */
/* No mutexes */
typedef int cairo_mutex_t;
# define CAIRO_MUTEX_INITIALIZE() CAIRO_MUTEX_NOOP
# define CAIRO_MUTEX_LOCK(mutex) CAIRO_MUTEX_NOOP
# define CAIRO_MUTEX_UNLOCK(mutex) CAIRO_MUTEX_NOOP
# define CAIRO_MUTEX_NIL_INITIALIZER 0
#elif CAIRO_POOR_MAN_MUTEX
/* A poor man's mutex */
typedef int cairo_mutex_t;
# define CAIRO_MUTEX_INITIALIZE() CAIRO_MUTEX_NOOP
# define CAIRO_MUTEX_LOCK(mutex) do { while (mutex) ; (mutex) = 1; } while (0)
# define CAIRO_MUTEX_UNLOCK(mutex) (mutex) = 0
# define CAIRO_MUTEX_LOCK(mutex) CAIRO_MUTEX_NOOP1(mutex)
# define CAIRO_MUTEX_UNLOCK(mutex) CAIRO_MUTEX_NOOP1(mutex)
# define CAIRO_MUTEX_NIL_INITIALIZER 0
#elif HAVE_PTHREAD_H /*******************************************************/

Просмотреть файл

@ -50,7 +50,7 @@
#endif
#include <cairo-os2.h>
#include <cairoint.h>
#include "cairoint.h"
typedef struct _cairo_os2_surface
{

Просмотреть файл

@ -133,4 +133,9 @@ _cairo_paginated_surface_get_target (cairo_surface_t *surface);
cairo_private cairo_bool_t
_cairo_surface_is_paginated (cairo_surface_t *surface);
cairo_private cairo_status_t
_cairo_paginated_surface_set_size (cairo_surface_t *surface,
int width,
int height);
#endif /* CAIRO_PAGINATED_H */

Просмотреть файл

@ -1,6 +1,7 @@
/* cairo - a vector graphics library with display and print output
*
* Copyright © 2005 Red Hat, Inc
* Copyright © 2007 Adrian Johnson
*
* This library is free software; you can redistribute it and/or
* modify it either under the terms of the GNU Lesser General Public
@ -32,6 +33,7 @@
* Contributor(s):
* Carl Worth <cworth@cworth.org>
* Keith Packard <keithp@keithp.com>
* Adrian Johnson <ajohnson@redneon.com>
*/
/* The paginated surface layer exists to provide as much code sharing
@ -63,6 +65,7 @@ _cairo_paginated_surface_create_similar (void *abstract_surface,
width, height);
}
/* XXX The integer width,height here should be doubles and all uses updated */
cairo_surface_t *
_cairo_paginated_surface_create (cairo_surface_t *target,
cairo_content_t content,
@ -125,6 +128,29 @@ _cairo_paginated_surface_get_target (cairo_surface_t *surface)
return paginated_surface->target;
}
cairo_status_t
_cairo_paginated_surface_set_size (cairo_surface_t *surface,
int width,
int height)
{
cairo_paginated_surface_t *paginated_surface;
assert (_cairo_surface_is_paginated (surface));
paginated_surface = (cairo_paginated_surface_t *) surface;
paginated_surface->width = width;
paginated_surface->height = height;
cairo_surface_destroy (paginated_surface->meta);
paginated_surface->meta = _cairo_meta_surface_create (paginated_surface->content,
width, height);
if (cairo_surface_status (paginated_surface->meta))
return cairo_surface_status (paginated_surface->meta);
return CAIRO_STATUS_SUCCESS;
}
static cairo_status_t
_cairo_paginated_surface_finish (void *abstract_surface)
{
@ -208,13 +234,55 @@ _cairo_paginated_surface_release_source_image (void *abstract_surface,
cairo_surface_destroy (&image->base);
}
static cairo_int_status_t
_paint_fallback_image (cairo_paginated_surface_t *surface,
cairo_box_int_t *box)
{
double x_scale = surface->base.x_fallback_resolution / surface->base.x_resolution;
double y_scale = surface->base.y_fallback_resolution / surface->base.y_resolution;
cairo_matrix_t matrix;
int x, y, width, height;
cairo_status_t status;
cairo_surface_t *image;
cairo_pattern_t *pattern;
x = box->p1.x;
y = box->p1.y;
width = box->p2.x - x;
height = box->p2.y - y;
image = _cairo_paginated_surface_create_image_surface (surface,
width * x_scale,
height * y_scale);
_cairo_surface_set_device_scale (image, x_scale, y_scale);
/* set_device_offset just sets the x0/y0 components of the matrix;
* so we have to do the scaling manually. */
cairo_surface_set_device_offset (image, -x*x_scale, -y*y_scale);
status = _cairo_meta_surface_replay (surface->meta, image);
if (status)
goto CLEANUP_IMAGE;
pattern = cairo_pattern_create_for_surface (image);
cairo_matrix_init (&matrix, x_scale, 0, 0, y_scale, -x*x_scale, -y*y_scale);
cairo_pattern_set_matrix (pattern, &matrix);
status = _cairo_surface_paint (surface->target,
CAIRO_OPERATOR_SOURCE,
pattern);
cairo_pattern_destroy (pattern);
CLEANUP_IMAGE:
cairo_surface_destroy (image);
return status;
}
static cairo_int_status_t
_paint_page (cairo_paginated_surface_t *surface)
{
cairo_surface_t *analysis;
cairo_surface_t *image;
cairo_pattern_t *pattern;
cairo_status_t status;
cairo_bool_t has_supported, has_page_fallback, has_finegrained_fallback;
analysis = _cairo_analysis_surface_create (surface->target,
surface->width, surface->height);
@ -222,7 +290,7 @@ _paint_page (cairo_paginated_surface_t *surface)
return CAIRO_STATUS_NO_MEMORY;
surface->backend->set_paginated_mode (surface->target, CAIRO_PAGINATED_MODE_ANALYZE);
status = _cairo_meta_surface_replay (surface->meta, analysis);
status = _cairo_meta_surface_replay_and_create_regions (surface->meta, analysis);
surface->backend->set_paginated_mode (surface->target, CAIRO_PAGINATED_MODE_RENDER);
if (status || analysis->status) {
@ -232,35 +300,77 @@ _paint_page (cairo_paginated_surface_t *surface)
return status;
}
if (_cairo_analysis_surface_has_unsupported (analysis))
{
double x_scale = surface->base.x_fallback_resolution / 72.0;
double y_scale = surface->base.y_fallback_resolution / 72.0;
cairo_matrix_t matrix;
/* Finer grained fallbacks are currently only supported for some
* surface types */
switch (surface->target->type) {
case CAIRO_SURFACE_TYPE_PDF:
case CAIRO_SURFACE_TYPE_PS:
case CAIRO_SURFACE_TYPE_WIN32_PRINTING:
has_supported = _cairo_analysis_surface_has_supported (analysis);
has_page_fallback = FALSE;
has_finegrained_fallback = _cairo_analysis_surface_has_unsupported (analysis);
break;
image = _cairo_paginated_surface_create_image_surface (surface,
surface->width * x_scale,
surface->height * y_scale);
_cairo_surface_set_device_scale (image, x_scale, y_scale);
status = _cairo_meta_surface_replay (surface->meta, image);
if (status)
goto CLEANUP_IMAGE;
pattern = cairo_pattern_create_for_surface (image);
cairo_matrix_init_scale (&matrix, x_scale, y_scale);
cairo_pattern_set_matrix (pattern, &matrix);
status = _cairo_surface_paint (surface->target, CAIRO_OPERATOR_SOURCE, pattern);
cairo_pattern_destroy (pattern);
CLEANUP_IMAGE:
cairo_surface_destroy (image);
default:
if (_cairo_analysis_surface_has_unsupported (analysis)) {
has_supported = FALSE;
has_page_fallback = TRUE;
} else {
has_supported = TRUE;
has_page_fallback = FALSE;
}
has_finegrained_fallback = FALSE;
break;
}
else
if (has_supported) {
status = _cairo_meta_surface_replay_region (surface->meta,
surface->target,
CAIRO_META_REGION_NATIVE);
if (status)
return status;
}
if (has_page_fallback)
{
status = _cairo_meta_surface_replay (surface->meta, surface->target);
cairo_box_int_t box;
box.p1.x = 0;
box.p1.y = 0;
box.p2.x = surface->width;
box.p2.y = surface->height;
status = _paint_fallback_image (surface, &box);
if (status)
return status;
}
if (has_finegrained_fallback)
{
cairo_region_t *region;
cairo_box_int_t *boxes;
int num_boxes, i;
/* Reset clip region before drawing the fall back images */
status = _cairo_surface_intersect_clip_path (surface->target,
NULL,
CAIRO_FILL_RULE_WINDING,
CAIRO_GSTATE_TOLERANCE_DEFAULT,
CAIRO_ANTIALIAS_DEFAULT);
if (status)
return status;
region = _cairo_analysis_surface_get_unsupported (analysis);
status = _cairo_region_get_boxes (region, &num_boxes, &boxes);
if (status)
return status;
for (i = 0; i < num_boxes; i++) {
status = _paint_fallback_image (surface, &boxes[i]);
if (status) {
_cairo_region_boxes_fini (region, boxes);
return status;
}
}
_cairo_region_boxes_fini (region, boxes);
}
cairo_surface_destroy (analysis);
@ -294,14 +404,13 @@ _cairo_paginated_surface_copy_page (void *abstract_surface)
surface->page_num++;
/* XXX: It might make sense to add some suport here for calling
* _cairo_surface_copy_page on the target surface. It would be an
* optimization for the output, (so that PostScript could include
* copypage, for example), but the interaction with image
* cairo_surface_copy_page on the target surface. It would be an
* optimization for the output, but the interaction with image
* fallbacks gets tricky. For now, we just let the target see a
* show_page and we implement the copying by simply not destroying
* the meta-surface. */
return _cairo_surface_show_page (surface->target);
return cairo_surface_show_page (surface->target);
}
static cairo_int_status_t
@ -318,7 +427,7 @@ _cairo_paginated_surface_show_page (void *abstract_surface)
if (status)
return status;
status = _cairo_surface_show_page (surface->target);
status = cairo_surface_show_page (surface->target);
if (status)
return status;

Просмотреть файл

@ -36,13 +36,14 @@
#ifndef CAIRO_PATH_FIXED_PRIVATE_H
#define CAIRO_PATH_FIXED_PRIVATE_H
typedef enum cairo_path_op {
enum cairo_path_op {
CAIRO_PATH_OP_MOVE_TO = 0,
CAIRO_PATH_OP_LINE_TO = 1,
CAIRO_PATH_OP_CURVE_TO = 2,
CAIRO_PATH_OP_CLOSE_PATH = 3
} __attribute__ ((packed)) cairo_path_op_t; /* Don't want 32 bits if we can avoid it. */
/* XXX Shall we just not use char instead of hoping for __attribute__ working? */
};
/* we want to make sure a single byte is used for thie enum */
typedef char cairo_path_op_t;
/* make cairo_path_fixed fit a 512 bytes. about 50 items */
#define CAIRO_PATH_BUF_SIZE ((512 - 12 * sizeof (void*)) \

Просмотреть файл

@ -513,17 +513,13 @@ _cairo_path_fixed_offset_and_scale (cairo_path_fixed_t *path,
while (buf) {
for (i = 0; i < buf->num_points; i++) {
if (scalex == CAIRO_FIXED_ONE) {
buf->points[i].x += offx;
} else {
buf->points[i].x = _cairo_fixed_mul (buf->points[i].x + offx, scalex);
}
if (scalex != CAIRO_FIXED_ONE)
buf->points[i].x = _cairo_fixed_mul (buf->points[i].x, scalex);
buf->points[i].x += offx;
if (scaley == CAIRO_FIXED_ONE) {
buf->points[i].y += offy;
} else {
buf->points[i].y = _cairo_fixed_mul (buf->points[i].y + offy, scaley);
}
if (scaley != CAIRO_FIXED_ONE)
buf->points[i].y = _cairo_fixed_mul (buf->points[i].y, scaley);
buf->points[i].y += offy;
}
buf = buf->next;
@ -546,13 +542,38 @@ _cairo_path_fixed_device_transform (cairo_path_fixed_t *path,
cairo_matrix_t *device_transform)
{
assert (device_transform->yx == 0.0 && device_transform->xy == 0.0);
/* XXX: FRAGILE: I'm not really sure whether we're doing the
* "right" thing here if there is both scaling and translation in
* the matrix. But for now, the internals guarantee that we won't
* really ever have both going on. */
/* XXX: Support freeform matrices someday (right now, only translation and scale
* work. */
_cairo_path_fixed_offset_and_scale (path,
_cairo_fixed_from_double (device_transform->x0),
_cairo_fixed_from_double (device_transform->y0),
_cairo_fixed_from_double (device_transform->xx),
_cairo_fixed_from_double (device_transform->yy));
}
cairo_bool_t
_cairo_path_fixed_is_equal (cairo_path_fixed_t *path,
cairo_path_fixed_t *other)
{
cairo_path_buf_t *path_buf, *other_buf;
if (path->current_point.x != other->current_point.x ||
path->current_point.y != other->current_point.y ||
path->has_current_point != other->has_current_point ||
path->has_curve_to != other->has_curve_to ||
path->last_move_point.x != other->last_move_point.x ||
path->last_move_point.y != other->last_move_point.y)
return FALSE;
other_buf = other->buf_head;
for (path_buf = path->buf_head; path_buf != NULL; path_buf = path_buf->next) {
if (other_buf == NULL ||
path_buf->num_ops != other_buf->num_ops ||
path_buf->num_points != other_buf->num_points ||
memcmp (path_buf->op, other_buf->op, path_buf->num_ops) != 0 ||
memcmp (path_buf->points, other_buf->points, path_buf->num_points != 0))
return FALSE;
other_buf = other_buf->next;
}
return TRUE;
}

Просмотреть файл

@ -237,21 +237,13 @@ _cairo_stroker_join (cairo_stroker_t *stroker, cairo_stroke_face_t *in, cairo_st
tri[0] = in->point;
if (clockwise) {
status = _cairo_pen_find_active_ccw_vertex_index (pen, &in->dev_vector, &start);
if (status)
return status;
_cairo_pen_find_active_ccw_vertex_index (pen, &in->dev_vector, &start);
step = -1;
status = _cairo_pen_find_active_ccw_vertex_index (pen, &out->dev_vector, &stop);
if (status)
return status;
_cairo_pen_find_active_ccw_vertex_index (pen, &out->dev_vector, &stop);
} else {
status = _cairo_pen_find_active_cw_vertex_index (pen, &in->dev_vector, &start);
if (status)
return status;
_cairo_pen_find_active_cw_vertex_index (pen, &in->dev_vector, &start);
step = +1;
status = _cairo_pen_find_active_cw_vertex_index (pen, &out->dev_vector, &stop);
if (status)
return status;
_cairo_pen_find_active_cw_vertex_index (pen, &out->dev_vector, &stop);
}
i = start;
@ -394,14 +386,10 @@ _cairo_stroker_add_cap (cairo_stroker_t *stroker, cairo_stroke_face_t *f)
cairo_pen_t *pen = &stroker->pen;
slope = f->dev_vector;
status = _cairo_pen_find_active_cw_vertex_index (pen, &slope, &start);
if (status)
return status;
_cairo_pen_find_active_cw_vertex_index (pen, &slope, &start);
slope.dx = -slope.dx;
slope.dy = -slope.dy;
status = _cairo_pen_find_active_cw_vertex_index (pen, &slope, &stop);
if (status)
return status;
_cairo_pen_find_active_cw_vertex_index (pen, &slope, &stop);
tri[0] = f->point;
tri[1] = f->cw;

Просмотреть файл

@ -185,7 +185,9 @@ _cairo_pattern_init_copy (cairo_pattern_t *pattern,
} break;
}
/* The reference count and user_data array are unique to the copy. */
pattern->ref_count = 1;
_cairo_user_data_array_init (&pattern->user_data);
return CAIRO_STATUS_SUCCESS;
}
@ -1210,7 +1212,7 @@ _cairo_pattern_acquire_surface_for_gradient (cairo_gradient_pattern_t *pattern,
{
image = (cairo_image_surface_t *)
_cairo_image_surface_create_for_pixman_image (pixman_image,
CAIRO_FORMAT_ARGB32);
PIXMAN_a8r8g8b8);
if (image->base.status)
{
pixman_image_unref (pixman_image);
@ -1675,38 +1677,6 @@ _cairo_pattern_acquire_surface_for_surface (cairo_surface_pattern_t *pattern,
status = _cairo_surface_clone_similar (dst, pattern->surface,
x, y, width, height, out);
if (status == CAIRO_INT_STATUS_UNSUPPORTED) {
cairo_t *cr;
*out = cairo_surface_create_similar (dst, dst->content,
width, height);
status = cairo_surface_status (*out);
if (status) {
cairo_surface_destroy (*out);
*out = NULL;
return status;
}
(*out)->device_transform = pattern->surface->device_transform;
(*out)->device_transform_inverse = pattern->surface->device_transform_inverse;
/* XXX Use _cairo_surface_composite directly */
cr = cairo_create (*out);
cairo_set_operator (cr, CAIRO_OPERATOR_SOURCE);
cairo_set_source_surface (cr, pattern->surface, -x, -y);
cairo_paint (cr);
status = cairo_status (cr);
cairo_destroy (cr);
if (status) {
cairo_surface_destroy (*out);
*out = NULL;
}
}
}
return status;
@ -1977,8 +1947,8 @@ _cairo_pattern_get_extents (cairo_pattern_t *pattern,
imatrix = pattern->matrix;
status = cairo_matrix_invert (&imatrix);
if (status)
return status;
/* cairo_pattern_set_matrix ensures the matrix is invertible */
assert (status == CAIRO_STATUS_SUCCESS);
/* XXX Use _cairo_matrix_transform_bounding_box here */
for (sy = 0; sy <= 1; sy++) {

Просмотреть файл

@ -2,6 +2,7 @@
*
* Copyright © 2004 Red Hat, Inc
* Copyright © 2006 Red Hat, Inc
* Copyright © 2007 Adrian Johnson
*
* This library is free software; you can redistribute it and/or
* modify it either under the terms of the GNU Lesser General Public
@ -34,6 +35,7 @@
* Contributor(s):
* Kristian Høgsberg <krh@redhat.com>
* Carl Worth <cworth@cworth.org>
* Adrian Johnson <ajohnson@redneon.com>
*/
#ifndef CAIRO_PDF_SURFACE_PRIVATE_H
@ -47,6 +49,14 @@ typedef struct _cairo_pdf_resource {
unsigned int id;
} cairo_pdf_resource_t;
typedef struct _cairo_pdf_group_resources {
cairo_array_t alphas;
cairo_array_t smasks;
cairo_array_t patterns;
cairo_array_t xobjects;
cairo_array_t fonts;
} cairo_pdf_group_resources_t;
typedef struct _cairo_pdf_surface cairo_pdf_surface_t;
struct _cairo_pdf_surface {
@ -62,13 +72,10 @@ struct _cairo_pdf_surface {
cairo_array_t objects;
cairo_array_t pages;
cairo_array_t patterns;
cairo_array_t xobjects;
cairo_array_t streams;
cairo_array_t alphas;
cairo_array_t smasks;
cairo_array_t rgb_linear_functions;
cairo_array_t alpha_linear_functions;
cairo_array_t knockout_group;
cairo_array_t content_group;
cairo_scaled_font_subsets_t *font_subsets;
cairo_array_t fonts;
@ -81,25 +88,44 @@ struct _cairo_pdf_surface {
cairo_pdf_resource_t self;
cairo_pdf_resource_t length;
long start_offset;
cairo_bool_t compressed;
cairo_output_stream_t *old_output;
} current_stream;
cairo_bool_t compressed;
cairo_output_stream_t *old_output;
} pdf_stream;
struct {
cairo_pattern_type_t type;
double red;
double green;
double blue;
int alpha;
cairo_pdf_resource_t smask;
cairo_pdf_resource_t pattern;
cairo_bool_t active;
cairo_output_stream_t *stream;
cairo_output_stream_t *old_output;
cairo_pdf_group_resources_t resources;
cairo_bool_t is_knockout;
cairo_pdf_resource_t first_object;
} group_stream;
struct {
cairo_bool_t active;
cairo_output_stream_t *stream;
cairo_output_stream_t *old_output;
cairo_pdf_group_resources_t resources;
} content_stream;
struct {
cairo_pattern_type_t type;
double red;
double green;
double blue;
double alpha;
cairo_pdf_resource_t smask;
cairo_pdf_resource_t pattern;
} emitted_pattern;
cairo_bool_t has_clip;
cairo_array_t *current_group;
cairo_pdf_group_resources_t *current_resources;
cairo_paginated_mode_t paginated_mode;
cairo_bool_t force_fallbacks;
cairo_surface_t *paginated_surface;
};
#endif /* CAIRO_PDF_SURFACE_PRIVATE_H */

Разница между файлами не показана из-за своего большого размера Загрузить разницу

Просмотреть файл

@ -42,7 +42,7 @@ _cairo_pen_vertices_needed (double tolerance, double radius, cairo_matrix_t *mat
static void
_cairo_pen_compute_slopes (cairo_pen_t *pen);
static cairo_status_t
static void
_cairo_pen_stroke_spline_half (cairo_pen_t *pen, cairo_spline_t *spline, cairo_direction_t dir, cairo_polygon_t *polygon);
void
@ -308,7 +308,7 @@ _cairo_pen_compute_slopes (cairo_pen_t *pen)
* counterclockwise order. However, for this function, we care
* strongly about which vertex is returned.
*/
cairo_status_t
void
_cairo_pen_find_active_cw_vertex_index (cairo_pen_t *pen,
cairo_slope_t *slope,
int *active)
@ -324,8 +324,6 @@ _cairo_pen_find_active_cw_vertex_index (cairo_pen_t *pen,
assert (i < pen->num_vertices);
*active = i;
return CAIRO_STATUS_SUCCESS;
}
/* Find active pen vertex for counterclockwise edge of stroke at the given slope.
@ -333,7 +331,7 @@ _cairo_pen_find_active_cw_vertex_index (cairo_pen_t *pen,
* NOTE: The behavior of this function is sensitive to the sense of
* the inequality within _cairo_slope_clockwise/_cairo_slope_counter_clockwise.
*/
cairo_status_t
void
_cairo_pen_find_active_ccw_vertex_index (cairo_pen_t *pen,
cairo_slope_t *slope,
int *active)
@ -352,18 +350,15 @@ _cairo_pen_find_active_ccw_vertex_index (cairo_pen_t *pen,
}
*active = i;
return CAIRO_STATUS_SUCCESS;
}
static cairo_status_t
static void
_cairo_pen_stroke_spline_half (cairo_pen_t *pen,
cairo_spline_t *spline,
cairo_direction_t dir,
cairo_polygon_t *polygon)
{
int i;
cairo_status_t status;
int start, stop, step;
int active = 0;
cairo_point_t hull_point;
@ -389,11 +384,9 @@ _cairo_pen_stroke_spline_half (cairo_pen_t *pen,
final_slope.dy = -final_slope.dy;
}
status = _cairo_pen_find_active_cw_vertex_index (pen,
&initial_slope,
&active);
if (status)
return status;
_cairo_pen_find_active_cw_vertex_index (pen,
&initial_slope,
&active);
i = start;
while (i != stop) {
@ -416,8 +409,6 @@ _cairo_pen_stroke_spline_half (cairo_pen_t *pen,
i += step;
}
}
return CAIRO_STATUS_SUCCESS;
}
/* Compute outline of a given spline using the pen.
@ -443,13 +434,9 @@ _cairo_pen_stroke_spline (cairo_pen_t *pen,
if (status)
goto BAIL;
status = _cairo_pen_stroke_spline_half (pen, spline, CAIRO_DIRECTION_FORWARD, &polygon);
if (status)
goto BAIL;
_cairo_pen_stroke_spline_half (pen, spline, CAIRO_DIRECTION_FORWARD, &polygon);
status = _cairo_pen_stroke_spline_half (pen, spline, CAIRO_DIRECTION_REVERSE, &polygon);
if (status)
goto BAIL;
_cairo_pen_stroke_spline_half (pen, spline, CAIRO_DIRECTION_REVERSE, &polygon);
_cairo_polygon_close (&polygon);
status = _cairo_polygon_status (&polygon);

Просмотреть файл

@ -93,4 +93,6 @@
#define FLOAT_WORDS_BIGENDIAN
#endif
#define CAIRO_NO_MUTEX 1
#endif /* CAIRO_PLATFORM_H */

Просмотреть файл

@ -114,7 +114,7 @@ write_png (cairo_surface_t *surface,
png_struct *png;
png_info *info;
png_time pt;
png_byte **rows;
png_byte **rows = NULL;
png_color_16 white;
int png_color_type;
int depth;
@ -128,14 +128,16 @@ write_png (cairo_surface_t *surface,
else if (status != CAIRO_STATUS_SUCCESS)
return CAIRO_STATUS_SURFACE_TYPE_MISMATCH;
rows = _cairo_malloc_ab (image->height, sizeof(png_byte*));
if (rows == NULL) {
status = CAIRO_STATUS_NO_MEMORY;
goto BAIL1;
}
if (image->height && image->width) {
rows = _cairo_malloc_ab (image->height, sizeof(png_byte*));
if (rows == NULL) {
status = CAIRO_STATUS_NO_MEMORY;
goto BAIL1;
}
for (i = 0; i < image->height; i++)
rows[i] = (png_byte *) image->data + i * image->stride;
for (i = 0; i < image->height; i++)
rows[i] = (png_byte *) image->data + i * image->stride;
}
png = png_create_write_struct (PNG_LIBPNG_VER_STRING, NULL,
png_simple_error_callback,
@ -208,7 +210,8 @@ write_png (cairo_surface_t *surface,
if (image->format == CAIRO_FORMAT_RGB24)
png_set_filler (png, 0, PNG_FILLER_AFTER);
png_write_image (png, rows);
if (rows)
png_write_image (png, rows);
png_write_end (png, info);
BAIL3:

Просмотреть файл

@ -75,6 +75,8 @@ typedef struct cairo_ps_surface {
cairo_array_t dsc_page_setup_comments;
cairo_array_t *dsc_comment_target;
cairo_surface_t *paginated_surface;
} cairo_ps_surface_t;
#endif /* CAIRO_PS_SURFACE_PRIVATE_H */

Просмотреть файл

@ -49,6 +49,8 @@
#include <time.h>
#include <zlib.h>
#define DEBUG_PS 0
static const cairo_surface_backend_t cairo_ps_surface_backend;
static const cairo_paginated_surface_backend_t cairo_ps_surface_paginated_backend;
@ -178,7 +180,7 @@ _cairo_ps_surface_path_move_to (void *closure, cairo_point_t *point)
path_info->has_sub_path = FALSE;
_cairo_output_stream_printf (path_info->stream,
"%f %f moveto ",
"%f %f M ",
_cairo_fixed_to_double (point->x),
_cairo_fixed_to_double (point->y));
@ -201,7 +203,7 @@ _cairo_ps_surface_path_line_to (void *closure, cairo_point_t *point)
path_info->has_sub_path = TRUE;
_cairo_output_stream_printf (path_info->stream,
"%f %f lineto ",
"%f %f L ",
_cairo_fixed_to_double (point->x),
_cairo_fixed_to_double (point->y));
@ -219,7 +221,7 @@ _cairo_ps_surface_path_curve_to (void *closure,
path_info->has_sub_path = TRUE;
_cairo_output_stream_printf (path_info->stream,
"%f %f %f %f %f %f curveto ",
"%f %f %f %f %f %f C ",
_cairo_fixed_to_double (b->x),
_cairo_fixed_to_double (b->y),
_cairo_fixed_to_double (c->x),
@ -242,7 +244,7 @@ _cairo_ps_surface_path_close_path (void *closure)
}
_cairo_output_stream_printf (path_info->stream,
"closepath\n");
"P\n");
return CAIRO_STATUS_SUCCESS;
}
@ -379,8 +381,10 @@ _cairo_ps_surface_emit_type1_font_subset (cairo_ps_surface_t *surface,
/* FIXME: Figure out document structure convention for fonts */
#if DEBUG_PS
_cairo_output_stream_printf (surface->final_stream,
"%% _cairo_ps_surface_emit_type1_font_subset\n");
#endif
length = subset.header_length + subset.data_length + subset.trailer_length;
_cairo_output_stream_write (surface->final_stream, subset.data, length);
@ -408,8 +412,10 @@ _cairo_ps_surface_emit_type1_font_fallback (cairo_ps_surface_t *surface,
/* FIXME: Figure out document structure convention for fonts */
#if DEBUG_PS
_cairo_output_stream_printf (surface->final_stream,
"%% _cairo_ps_surface_emit_type1_font_fallback\n");
#endif
length = subset.header_length + subset.data_length + subset.trailer_length;
_cairo_output_stream_write (surface->final_stream, subset.data, length);
@ -435,8 +441,10 @@ _cairo_ps_surface_emit_truetype_font_subset (cairo_ps_surface_t *surface,
/* FIXME: Figure out document structure convention for fonts */
#if DEBUG_PS
_cairo_output_stream_printf (surface->final_stream,
"%% _cairo_ps_surface_emit_truetype_font_subset\n");
#endif
_cairo_output_stream_printf (surface->final_stream,
"11 dict begin\n"
@ -574,12 +582,12 @@ _cairo_ps_surface_emit_bitmap_glyph_data (cairo_ps_surface_t *surface,
" /BitsPerComponent 1\n",
image->width,
image->height,
image->base.device_transform_inverse.xx,
image->base.device_transform_inverse.yx,
image->base.device_transform_inverse.xy,
image->base.device_transform_inverse.yy,
image->base.device_transform_inverse.x0,
image->base.device_transform_inverse.y0);
image->base.device_transform.xx,
image->base.device_transform.yx,
image->base.device_transform.xy,
image->base.device_transform.yy,
image->base.device_transform.x0,
image->base.device_transform.y0);
_cairo_output_stream_printf (surface->final_stream,
" /DataSource {<");
@ -642,8 +650,10 @@ _cairo_ps_surface_emit_type3_font_subset (cairo_ps_surface_t *surface,
cairo_matrix_t matrix;
unsigned int i;
#if DEBUG_PS
_cairo_output_stream_printf (surface->final_stream,
"%% _cairo_ps_surface_emit_type3_font_subset\n");
#endif
_cairo_output_stream_printf (surface->final_stream,
"/CairoFont-%d-%d <<\n",
@ -724,8 +734,10 @@ _cairo_ps_surface_emit_font_subsets (cairo_ps_surface_t *surface)
{
cairo_status_t status;
#if DEBUG_PS
_cairo_output_stream_printf (surface->final_stream,
"%% _cairo_ps_surface_emit_font_subsets\n");
#endif
status = _cairo_scaled_font_subsets_foreach_unscaled (surface->font_subsets,
_cairo_ps_surface_emit_unscaled_font_subset,
@ -805,10 +817,11 @@ _cairo_ps_surface_create_for_stream_internal (cairo_output_stream_t *stream,
surface->dsc_comment_target = &surface->dsc_header_comments;
return _cairo_paginated_surface_create (&surface->base,
CAIRO_CONTENT_COLOR_ALPHA,
width, height,
&cairo_ps_surface_paginated_backend);
surface->paginated_surface = _cairo_paginated_surface_create (&surface->base,
CAIRO_CONTENT_COLOR_ALPHA,
width, height,
&cairo_ps_surface_paginated_backend);
return surface->paginated_surface;
CLEANUP_OUTPUT_STREAM:
status = _cairo_output_stream_destroy (surface->stream);
@ -976,6 +989,11 @@ cairo_ps_surface_set_size (cairo_surface_t *surface,
ps_surface->width = width_in_points;
ps_surface->height = height_in_points;
status = _cairo_paginated_surface_set_size (ps_surface->paginated_surface,
width_in_points,
height_in_points);
if (status)
_cairo_surface_set_error (surface, status);
}
/**
@ -1255,7 +1273,7 @@ _cairo_ps_surface_start_page (void *abstract_surface)
(int) ceil (surface->height));
_cairo_output_stream_printf (surface->stream,
"gsave %f %f translate 1.0 -1.0 scale \n",
"gsave %f %f translate 1.0 -1.0 scale gsave\n",
0.0, surface->height);
_cairo_output_stream_printf (surface->stream,
@ -1273,19 +1291,7 @@ static void
_cairo_ps_surface_end_page (cairo_ps_surface_t *surface)
{
_cairo_output_stream_printf (surface->stream,
"grestore\n");
}
static cairo_int_status_t
_cairo_ps_surface_copy_page (void *abstract_surface)
{
cairo_ps_surface_t *surface = abstract_surface;
_cairo_ps_surface_end_page (surface);
_cairo_output_stream_printf (surface->stream, "copypage\n");
return CAIRO_STATUS_SUCCESS;
"grestore grestore\n");
}
static cairo_int_status_t
@ -1359,34 +1365,53 @@ pattern_supported (const cairo_pattern_t *pattern)
}
static cairo_int_status_t
_cairo_ps_surface_operation_supported (cairo_ps_surface_t *surface,
cairo_operator_t op,
const cairo_pattern_t *pattern)
_cairo_ps_surface_analyze_operation (cairo_ps_surface_t *surface,
cairo_operator_t op,
const cairo_pattern_t *pattern)
{
if (surface->force_fallbacks)
return FALSE;
if (surface->force_fallbacks && surface->paginated_mode == CAIRO_PAGINATED_MODE_ANALYZE)
return CAIRO_INT_STATUS_UNSUPPORTED;
if (! pattern_supported (pattern))
return FALSE;
return CAIRO_INT_STATUS_UNSUPPORTED;
if (op == CAIRO_OPERATOR_SOURCE)
return CAIRO_STATUS_SUCCESS;
if (op != CAIRO_OPERATOR_OVER)
return CAIRO_INT_STATUS_UNSUPPORTED;
/* CAIRO_OPERATOR_OVER is only supported for opaque patterns. If
* the pattern contains transparency, we return
* CAIRO_INT_STATUS_FLATTEN_TRANSPARENCY to the analysis
* surface. If the analysis surface determines that there is
* anything drawn under this operation, a fallback image will be
* used. Otherwise the operation will be replayed during the
* render stage and we blend the transarency into the white
* background to convert the pattern to opaque.
*/
if (_cairo_operator_always_opaque (op))
return TRUE;
return CAIRO_STATUS_SUCCESS;
if (_cairo_operator_always_translucent (op))
return FALSE;
return CAIRO_INT_STATUS_FLATTEN_TRANSPARENCY;
return _cairo_pattern_is_opaque (pattern);
}
static cairo_int_status_t
_cairo_ps_surface_analyze_operation (cairo_ps_surface_t *surface,
cairo_operator_t op,
const cairo_pattern_t *pattern)
{
if (_cairo_ps_surface_operation_supported (surface, op, pattern))
if (_cairo_pattern_is_opaque (pattern))
return CAIRO_STATUS_SUCCESS;
else
return CAIRO_INT_STATUS_UNSUPPORTED;
return CAIRO_INT_STATUS_FLATTEN_TRANSPARENCY;
}
static cairo_bool_t
_cairo_ps_surface_operation_supported (cairo_ps_surface_t *surface,
cairo_operator_t op,
const cairo_pattern_t *pattern)
{
if (_cairo_ps_surface_analyze_operation (surface, op, pattern) != CAIRO_INT_STATUS_UNSUPPORTED)
return TRUE;
else
return FALSE;
}
/* The "standard" implementation limit for PostScript string sizes is
@ -1514,8 +1539,8 @@ _string_array_stream_create (cairo_output_stream_t *output)
static cairo_status_t
_cairo_ps_surface_emit_image (cairo_ps_surface_t *surface,
cairo_image_surface_t *image,
const char *name)
cairo_image_surface_t *image,
const char *name)
{
cairo_status_t status, status2;
unsigned char *rgb, *compressed;
@ -1659,24 +1684,37 @@ _cairo_ps_surface_emit_image (cairo_ps_surface_t *surface,
}
static void
_cairo_ps_surface_emit_solid_pattern (cairo_ps_surface_t *surface,
cairo_solid_pattern_t *pattern)
_cairo_ps_surface_emit_solid_pattern (cairo_ps_surface_t *surface,
cairo_solid_pattern_t *pattern)
{
if (color_is_gray (&pattern->color))
cairo_color_t *color = &pattern->color;
double red, green, blue;
red = color->red;
green = color->green;
blue = color->blue;
if (!CAIRO_COLOR_IS_OPAQUE(color)) {
uint8_t one_minus_alpha = 255 - (color->alpha_short >> 8);
red = ((color->red_short >> 8) + one_minus_alpha) / 255.0;
green = ((color->green_short >> 8) + one_minus_alpha) / 255.0;
blue = ((color->blue_short >> 8) + one_minus_alpha) / 255.0;
}
if (color_is_gray (color))
_cairo_output_stream_printf (surface->stream,
"%f G\n",
pattern->color.red);
red);
else
_cairo_output_stream_printf (surface->stream,
"%f %f %f R\n",
pattern->color.red,
pattern->color.green,
pattern->color.blue);
red, green, blue);
}
static cairo_status_t
_cairo_ps_surface_emit_surface_pattern (cairo_ps_surface_t *surface,
cairo_surface_pattern_t *pattern)
_cairo_ps_surface_emit_surface_pattern (cairo_ps_surface_t *surface,
cairo_surface_pattern_t *pattern)
{
cairo_status_t status;
double bbox_width, bbox_height;
@ -1846,11 +1884,13 @@ _cairo_ps_surface_intersect_clip_path (void *abstract_surface,
if (surface->paginated_mode == CAIRO_PAGINATED_MODE_ANALYZE)
return CAIRO_STATUS_SUCCESS;
#if DEBUG_PS
_cairo_output_stream_printf (stream,
"%% _cairo_ps_surface_intersect_clip_path\n");
#endif
if (path == NULL) {
_cairo_output_stream_printf (stream, "initclip\n");
_cairo_output_stream_printf (stream, "grestore gsave\n");
return CAIRO_STATUS_SUCCESS;
}
@ -1919,18 +1959,12 @@ _cairo_ps_surface_paint (void *abstract_surface,
if (surface->paginated_mode == CAIRO_PAGINATED_MODE_ANALYZE)
return _cairo_ps_surface_analyze_operation (surface, op, source);
/* XXX: It would be nice to be able to assert this condition
* here. But, we actually allow one 'cheat' that is used when
* painting the final image-based fallbacks. The final fallbacks
* do have alpha which we support by blending with white. This is
* possible only because there is nothing between the fallback
* images and the paper, nor is anything painted above. */
/*
assert (_cairo_ps_surface_operation_supported (op, source));
*/
assert (_cairo_ps_surface_operation_supported (surface, op, source));
#if DEBUG_PS
_cairo_output_stream_printf (stream,
"%% _cairo_ps_surface_paint\n");
#endif
status = _cairo_surface_get_extents (&surface->base, &extents);
if (status)
@ -2017,9 +2051,10 @@ _cairo_ps_surface_stroke (void *abstract_surface,
assert (_cairo_ps_surface_operation_supported (surface, op, source));
#if DEBUG_PS
_cairo_output_stream_printf (stream,
"%% _cairo_ps_surface_stroke\n");
#endif
/* PostScript has "special needs" when it comes to zero-length
* dash segments with butt caps. It apparently (at least
@ -2148,8 +2183,10 @@ _cairo_ps_surface_fill (void *abstract_surface,
assert (_cairo_ps_surface_operation_supported (surface, op, source));
#if DEBUG_PS
_cairo_output_stream_printf (stream,
"%% _cairo_ps_surface_fill\n");
#endif
_cairo_ps_surface_emit_pattern (surface, source);
@ -2206,8 +2243,10 @@ _cairo_ps_surface_show_glyphs (void *abstract_surface,
assert (_cairo_ps_surface_operation_supported (surface, op, source));
#if DEBUG_PS
_cairo_output_stream_printf (stream,
"%% _cairo_ps_surface_show_glyphs\n");
#endif
if (num_glyphs <= 0)
return CAIRO_STATUS_SUCCESS;
@ -2233,9 +2272,8 @@ _cairo_ps_surface_show_glyphs (void *abstract_surface,
while (i < num_glyphs_unsigned) {
if (glyph_ids[i].subset_id != current_subset_id) {
_cairo_output_stream_printf (surface->stream,
"/CairoFont-%d-%d findfont\n"
"[ %f %f %f %f 0 0 ] makefont\n"
"setfont\n",
"/CairoFont-%d-%d "
"[ %f %f %f %f 0 0 ] selectfont\n",
subset_glyph.font_id,
glyph_ids[i].subset_id,
scaled_font->scale.xx,
@ -2343,7 +2381,7 @@ static const cairo_surface_backend_t cairo_ps_surface_backend = {
NULL, /* composite */
NULL, /* fill_rectangles */
NULL, /* composite_trapezoids */
_cairo_ps_surface_copy_page,
NULL, /* cairo_ps_surface_copy_page */
_cairo_ps_surface_show_page,
NULL, /* set_clip_region */
_cairo_ps_surface_intersect_clip_path,

Просмотреть файл

@ -38,7 +38,7 @@
#ifndef CAIRO_QUARTZ_PRIVATE_H
#define CAIRO_QUARTZ_PRIVATE_H
#include <cairoint.h>
#include "cairoint.h"
#ifdef CAIRO_HAS_QUARTZ_SURFACE
#include <cairo-quartz.h>

Просмотреть файл

@ -1681,14 +1681,6 @@ cairo_quartz_surface_create (cairo_format_t format,
int stride;
int bitsPerComponent;
unsigned int realWidth = width;
unsigned int realHeight = height;
if (width == 0)
width = 1;
if (height == 0)
height = 1;
if (format == CAIRO_FORMAT_ARGB32) {
cgColorspace = CGColorSpaceCreateDeviceRGB();
stride = width * 4;
@ -1745,7 +1737,7 @@ cairo_quartz_surface_create (cairo_format_t format,
CGContextScaleCTM (cgc, 1.0, -1.0);
surf = _cairo_quartz_surface_create_internal (cgc, _cairo_content_from_format (format),
realWidth, realHeight);
width, height);
if (!surf) {
CGContextRelease (cgc);
// create_internal will have set an error

Просмотреть файл

@ -37,11 +37,7 @@
#ifndef CAIRO_REGION_PRIVATE_H
#define CAIRO_REGION_PRIVATE_H
#ifdef MOZ_TREE_CAIRO
#include "pixman.h"
#else
#include <pixman/pixman.h>
#endif
#include <pixman.h>
/* cairo_region_t is defined in cairoint.h */
@ -106,4 +102,8 @@ cairo_private void
_cairo_region_translate (cairo_region_t *region,
int x, int y);
cairo_private pixman_region_overlap_t
_cairo_region_contains_rectangle (cairo_region_t *region, cairo_rectangle_int_t *box);
#endif /* CAIRO_REGION_PRIVATE_H */

Просмотреть файл

@ -207,3 +207,16 @@ _cairo_region_translate (cairo_region_t *region,
{
pixman_region_translate (&region->rgn, x, y);
}
pixman_region_overlap_t
_cairo_region_contains_rectangle (cairo_region_t *region, cairo_rectangle_int_t *rect)
{
pixman_box16_t pbox;
pbox.x1 = rect->x;
pbox.y1 = rect->y;
pbox.x2 = rect->x + rect->width;
pbox.y2 = rect->y + rect->height;
return pixman_region_contains_rectangle (&region->rgn, &pbox);
}

Просмотреть файл

@ -1,4 +1,3 @@
#define _cairo_image_surface_nil_invalid_format __moz__cairo_image_surface_nil_invalid_format
#define cairo_append_path _moz_cairo_append_path
#define cairo_arc _moz_cairo_arc
#define cairo_arc_negative _moz_cairo_arc_negative
@ -220,6 +219,7 @@
#define cairo_stroke_extents _moz_cairo_stroke_extents
#define cairo_stroke_preserve _moz_cairo_stroke_preserve
#define cairo_stroke_to_path _moz_cairo_stroke_to_path
#define cairo_surface_copy_page _moz_cairo_surface_copy_page
#define cairo_surface_create_similar _moz_cairo_surface_create_similar
#define cairo_surface_destroy _moz_cairo_surface_destroy
#define cairo_surface_finish _moz_cairo_surface_finish
@ -236,6 +236,7 @@
#define cairo_surface_set_device_offset _moz_cairo_surface_set_device_offset
#define cairo_surface_set_fallback_resolution _moz_cairo_surface_set_fallback_resolution
#define cairo_surface_set_user_data _moz_cairo_surface_set_user_data
#define cairo_surface_show_page _moz_cairo_surface_show_page
#define cairo_surface_status _moz_cairo_surface_status
#define cairo_surface_write_to_png _moz_cairo_surface_write_to_png
#define cairo_surface_write_to_png_stream _moz_cairo_surface_write_to_png_stream

Просмотреть файл

@ -34,11 +34,117 @@
* Carl D. Worth <cworth@cworth.org>
* Graydon Hoare <graydon@redhat.com>
* Owen Taylor <otaylor@redhat.com>
* Behdad Esfahbod <behdad@behdad.org>
*/
#include "cairoint.h"
#include "cairo-scaled-font-private.h"
/*
* NOTES:
*
* To store rasterizations of glyphs, we use an image surface and the
* device offset to represent the glyph origin.
*
* A device_transform converts from device space (a conceptual space) to
* surface space. For simple cases of translation only, it's called a
* device_offset and is public API (cairo_surface_[gs]et_device_offset).
* A possibly better name for those functions could have been
* cairo_surface_[gs]et_origing. So, that's what they do: they set where
* the device-space origin (0,0) is in the surface. If the origin is inside
* the surface, device_offset values are positive. It may look like this:
*
* Device space:
* (-x,-y) <-- negative numbers
* +----------------+
* | . |
* | . |
* |......(0,0) <---|-- device-space origin
* | |
* | |
* +----------------+
* (width-x,height-y)
*
* Surface space:
* (0,0) <-- surface-space origin
* +---------------+
* | . |
* | . |
* |......(x,y) <--|-- device_offset
* | |
* | |
* +---------------+
* (width,height)
*
* In other words: device_offset is the coordinates of the device-space
* origin relative to the top-left of the surface.
*
* We use device offsets in a couple of places:
*
* - Public API: To let toolkits like Gtk+ give user a surface that
* only represents part of the final destination (say, the expose
* area), but has the same device space as the destination. In these
* cases device_offset is typically negative. Example:
*
* application window
* +---------------+
* | . |
* | (x,y). |
* |......+---+ |
* | | | <--|-- expose area
* | +---+ |
* +---------------+
*
* In this case, the user of cairo API can set the device_space on
* the expose area to (-x,-y) to move the device space origin to that
* of the application window, such that drawing in the expose area
* surface and painting it in the application window has the same
* effect as drawing in the application window directly. Gtk+ has
* been using this feature.
*
* - Glyph surfaces: In most font rendering systems, glyph surfaces
* have an origin at (0,0) and a bounding box that is typically
* represented as (x_bearing,y_bearing,width,height). Depending on
* which way y progresses in the system, y_bearing may typically be
* negative (for systems similar to cairo, with origin at top left),
* or be positive (in systems like PDF with origin at bottom left).
* No matter which is the case, it is important to note that
* (x_bearing,y_bearing) is the coordinates of top-left of the glyph
* relative to the glyph origin. That is, for example:
*
* Scaled-glyph space:
*
* (x_bearing,y_bearing) <-- negative numbers
* +----------------+
* | . |
* | . |
* |......(0,0) <---|-- glyph origin
* | |
* | |
* +----------------+
* (width+x_bearing,height+y_bearing)
*
* Note the similarity of the origin to the device space. That is
* exactly how we use the device_offset to represent scaled glyphs:
* to use the device-space origin as the glyph origin.
*
* Now compare the scaled-glyph space to device-space and surface-space
* and convince yourself that:
*
* (x_bearing,y_bearing) = (-x,-y) = - device_offset
*
* That's right. If you are not convinced yet, contrast the definition
* of the two:
*
* "(x_bearing,y_bearing) is the coordinates of top-left of the
* glyph relative to the glyph origin."
*
* "In other words: device_offset is the coordinates of the
* device-space origin relative to the top-left of the surface."
*
* and note that glyph origin = device-space origin.
*/
static cairo_bool_t
_cairo_scaled_glyph_keys_equal (const void *abstract_key_a, const void *abstract_key_b)
{
@ -297,14 +403,16 @@ _cairo_scaled_font_init_key (cairo_scaled_font_t *scaled_font,
scaled_font->font_face = font_face;
scaled_font->font_matrix = *font_matrix;
scaled_font->ctm = *ctm;
/* ignore translation values in the ctm */
scaled_font->ctm.x0 = 0.;
scaled_font->ctm.y0 = 0.;
scaled_font->options = *options;
/* We do a bytewise hash on the font matrices, ignoring the
* translation values in the ctm */
/* We do a bytewise hash on the font matrices */
hash = _hash_bytes_fnv ((unsigned char *)(&scaled_font->font_matrix.xx),
sizeof(cairo_matrix_t), hash);
hash = _hash_bytes_fnv ((unsigned char *)(&scaled_font->ctm.xx),
sizeof(double) * 4, hash);
sizeof(cairo_matrix_t), hash);
hash ^= (unsigned long) scaled_font->font_face;
@ -1108,10 +1216,8 @@ _cairo_scaled_font_show_glyphs (cairo_scaled_font_t *scaled_font,
/* round glyph locations to the nearest pixel */
/* XXX: FRAGILE: We're ignoring device_transform scaling here. A bug? */
x = _cairo_lround (glyphs[i].x +
glyph_surface->base.device_transform.x0);
y = _cairo_lround (glyphs[i].y +
glyph_surface->base.device_transform.y0);
x = _cairo_lround (glyphs[i].x - glyph_surface->base.device_transform.x0);
y = _cairo_lround (glyphs[i].y - glyph_surface->base.device_transform.y0);
_cairo_pattern_init_for_surface (&glyph_pattern, &glyph_surface->base);
@ -1286,7 +1392,7 @@ _trace_mask_to_path (cairo_image_surface_t *mask,
for (bit = 7; bit >= 0 && x < a1_mask->width; bit--, x++) {
if (byte & (1 << bit)) {
status = _add_unit_rectangle_to_path (path,
x + xoff, y + yoff);
x - xoff, y - yoff);
if (status)
return status;
}

Просмотреть файл

@ -1071,7 +1071,7 @@ _cairo_surface_fallback_snapshot (cairo_surface_t *surface)
}
_cairo_surface_release_source_image (surface,
image, &image_extra);
image, image_extra);
snapshot->device_transform = surface->device_transform;
snapshot->device_transform_inverse = surface->device_transform_inverse;
@ -1264,8 +1264,8 @@ _cairo_surface_fallback_clone_similar (cairo_surface_t *surface,
cairo_surface_t **clone_out)
{
cairo_status_t status;
cairo_pattern_union_t src_pattern;
cairo_surface_t *new_surface = NULL;
cairo_t *cr;
new_surface = _cairo_surface_create_similar_scratch (surface,
cairo_surface_get_content (src),
@ -1273,22 +1273,26 @@ _cairo_surface_fallback_clone_similar (cairo_surface_t *surface,
if (new_surface->status)
return new_surface->status;
_cairo_pattern_init_for_surface (&src_pattern.surface, src);
/* We have to copy these here, so that the coordinate spaces are correct */
new_surface->device_transform = src->device_transform;
new_surface->device_transform_inverse = src->device_transform_inverse;
status = _cairo_surface_composite (CAIRO_OPERATOR_SOURCE,
&src_pattern.base,
NULL,
new_surface,
src_x, src_y,
0, 0,
0, 0,
width, height);
_cairo_pattern_fini (&src_pattern.base);
/* We can't use _cairo_composite directly, because backends that
* implement the "high-level" API may not have it implemented.
* (For example, SVG.) We can fix this by either checking if the
* destination supports composite first, or we can make clone a
* required "high-level" operation.
*/
cr = cairo_create (new_surface);
cairo_set_operator (cr, CAIRO_OPERATOR_SOURCE);
cairo_set_source_surface (cr, src, -src_x, -src_y);
cairo_paint (cr);
status = cairo_status (cr);
cairo_destroy (cr);
if (status == CAIRO_STATUS_SUCCESS)
*clone_out = new_surface;
else if (new_surface)
else
cairo_surface_destroy (new_surface);
return status;

Просмотреть файл

@ -60,6 +60,14 @@ struct _cairo_surface {
cairo_matrix_t device_transform;
cairo_matrix_t device_transform_inverse;
/* The actual resolution of the device, in dots per inch. */
double x_resolution;
double y_resolution;
/* The resolution that should be used when generating image-based
* fallback; generally only used by the analysis/paginated
* surfaces
*/
double x_fallback_resolution;
double y_fallback_resolution;

Просмотреть файл

@ -62,6 +62,8 @@ const cairo_surface_t name = { \
0.0, 1.0, \
0.0, 0.0 \
}, /* device_transform_inverse */ \
0.0, /* x_resolution */ \
0.0, /* y_resolution */ \
0.0, /* x_fallback_resolution */ \
0.0, /* y_fallback_resolution */ \
NULL, /* clip */ \
@ -195,6 +197,9 @@ _cairo_surface_init (cairo_surface_t *surface,
cairo_matrix_init_identity (&surface->device_transform);
cairo_matrix_init_identity (&surface->device_transform_inverse);
surface->x_resolution = CAIRO_SURFACE_RESOLUTION_DEFAULT;
surface->y_resolution = CAIRO_SURFACE_RESOLUTION_DEFAULT;
surface->x_fallback_resolution = CAIRO_SURFACE_FALLBACK_RESOLUTION_DEFAULT;
surface->y_fallback_resolution = CAIRO_SURFACE_FALLBACK_RESOLUTION_DEFAULT;
@ -1024,46 +1029,49 @@ _cairo_surface_clone_similar (cairo_surface_t *surface,
int height,
cairo_surface_t **clone_out)
{
cairo_status_t status;
cairo_status_t status = CAIRO_INT_STATUS_UNSUPPORTED;
cairo_image_surface_t *image;
void *image_extra;
if (surface->finished)
return CAIRO_STATUS_SURFACE_FINISHED;
if (surface->backend->clone_similar == NULL)
return (cairo_int_status_t)
_cairo_surface_fallback_clone_similar (surface, src,
src_x, src_y,
width, height,
clone_out);
if (surface->backend->clone_similar) {
status = surface->backend->clone_similar (surface, src, src_x, src_y,
width, height, clone_out);
status = surface->backend->clone_similar (surface, src, src_x, src_y,
width, height, clone_out);
if (status == CAIRO_STATUS_SUCCESS && *clone_out != src)
(*clone_out)->device_transform = src->device_transform;
if (status == CAIRO_INT_STATUS_UNSUPPORTED) {
/* If we failed, try again with an image surface */
status = _cairo_surface_acquire_source_image (src, &image, &image_extra);
if (status == CAIRO_STATUS_SUCCESS) {
status =
surface->backend->clone_similar (surface, &image->base,
src_x, src_y,
width, height,
clone_out);
if (status != CAIRO_INT_STATUS_UNSUPPORTED)
return status;
status = _cairo_surface_acquire_source_image (src, &image, &image_extra);
if (status != CAIRO_STATUS_SUCCESS)
return status;
status = surface->backend->clone_similar (surface, &image->base, src_x,
src_y, width, height, clone_out);
if (status == CAIRO_STATUS_SUCCESS && *clone_out != src) {
(*clone_out)->device_transform = src->device_transform;
(*clone_out)->device_transform_inverse = src->device_transform_inverse;
_cairo_surface_release_source_image (src, image, image_extra);
}
}
}
/* If the above failed point, we could implement a full fallback
* using acquire_dest_image, but that's going to be very
* inefficient compared to a backend-specific implementation of
* clone_similar() with an image source. So we don't bother
*/
/* If we're still unsupported, hit our fallback path to get a clone */
if (status == CAIRO_INT_STATUS_UNSUPPORTED)
status =
_cairo_surface_fallback_clone_similar (surface, src, src_x, src_y,
width, height, clone_out);
/* We should never get UNSUPPORTED here, so if we have an error, bail. */
if (status)
return status;
/* Update the clone's device_transform (which the underlying surface
* backend knows nothing about) */
if (*clone_out != src) {
(*clone_out)->device_transform = src->device_transform;
(*clone_out)->device_transform_inverse = src->device_transform_inverse;
}
_cairo_surface_release_source_image (src, image, image_extra);
return status;
}
@ -1390,6 +1398,65 @@ _cairo_surface_mask (cairo_surface_t *surface,
return status;
}
cairo_status_t
_cairo_surface_fill_stroke (cairo_surface_t *surface,
cairo_operator_t fill_op,
cairo_pattern_t *fill_source,
cairo_fill_rule_t fill_rule,
double fill_tolerance,
cairo_antialias_t fill_antialias,
cairo_path_fixed_t *path,
cairo_operator_t stroke_op,
cairo_pattern_t *stroke_source,
cairo_stroke_style_t *stroke_style,
cairo_matrix_t *stroke_ctm,
cairo_matrix_t *stroke_ctm_inverse,
double stroke_tolerance,
cairo_antialias_t stroke_antialias)
{
cairo_status_t status;
if (surface->backend->fill_stroke) {
cairo_pattern_union_t dev_stroke_source;
cairo_pattern_union_t dev_fill_source;
cairo_matrix_t dev_ctm = *stroke_ctm;
cairo_matrix_t dev_ctm_inverse = *stroke_ctm_inverse;
status = _cairo_surface_copy_pattern_for_destination (stroke_source, surface, &dev_stroke_source.base);
if (status)
return status;
status = _cairo_surface_copy_pattern_for_destination (fill_source, surface, &dev_fill_source.base);
if (status) {
_cairo_pattern_fini (&dev_stroke_source.base);
return status;
}
status = surface->backend->fill_stroke (surface, fill_op, &dev_fill_source.base,
fill_rule, fill_tolerance, fill_antialias,
path, stroke_op, &dev_stroke_source.base, stroke_style,
&dev_ctm, &dev_ctm_inverse, stroke_tolerance,
stroke_antialias);
_cairo_pattern_fini (&dev_stroke_source.base);
_cairo_pattern_fini (&dev_fill_source.base);
if (status != CAIRO_INT_STATUS_UNSUPPORTED)
return status;
}
status = _cairo_surface_fill (surface, fill_op, fill_source, path,
fill_rule, fill_tolerance, fill_antialias);
if (status)
return status;
status = _cairo_surface_stroke (surface, stroke_op, stroke_source, path,
stroke_style, stroke_ctm, stroke_ctm_inverse,
stroke_tolerance, stroke_antialias);
return status;
}
cairo_status_t
_cairo_surface_stroke (cairo_surface_t *surface,
cairo_operator_t op,
@ -1523,8 +1590,19 @@ _cairo_surface_composite_trapezoids (cairo_operator_t op,
traps, num_traps);
}
/**
* cairo_surface_copy_page:
* @suface: a #cairo_surface_t
*
* Emits the current page for backends that support multiple pages,
* but doesn't clear it, so that the contents of the current page will
* be retained for the next page. Use cairo_surface_show_page() if you
* want to get an empty page after the emission.
*
* Since: 1.6
*/
cairo_status_t
_cairo_surface_copy_page (cairo_surface_t *surface)
cairo_surface_copy_page (cairo_surface_t *surface)
{
assert (! surface->is_snapshot);
@ -1540,9 +1618,20 @@ _cairo_surface_copy_page (cairo_surface_t *surface)
return surface->backend->copy_page (surface);
}
slim_hidden_def (cairo_surface_copy_page);
/**
* cairo_surface_show_page:
* @surface: a #cairo_Surface_t
*
* Emits and clears the current page for backends that support multiple
* pages. Use cairo_surface_copy_page() if you don't want to clear the page.
*
* Since: 1.6
**/
cairo_status_t
_cairo_surface_show_page (cairo_surface_t *surface)
cairo_surface_show_page (cairo_surface_t *surface)
{
assert (! surface->is_snapshot);
@ -1558,6 +1647,7 @@ _cairo_surface_show_page (cairo_surface_t *surface)
return surface->backend->show_page (surface);
}
slim_hidden_def (cairo_surface_show_page);
/**
* _cairo_surface_get_current_clip_serial:
@ -1835,6 +1925,14 @@ _cairo_surface_get_extents (cairo_surface_t *surface,
return surface->backend->get_extents (surface, rectangle);
}
/* Note: the backends may modify the contents of the glyph array as long as
* they do not return CAIRO_STATUS_UNSUPPORTED. This makes it possible to
* avoid copying the array again and again, and edit it in-place.
* Backends are in fact free to use the array as a generic buffer as they
* see fit.
* See commits 5a9642c5746fd677aed35ce620ce90b1029b1a0c and
* 1781e6018c17909311295a9cc74b70500c6b4d0a for the rationale.
*/
cairo_status_t
_cairo_surface_show_glyphs (cairo_surface_t *surface,
cairo_operator_t op,
@ -2193,5 +2291,24 @@ _cairo_surface_copy_pattern_for_destination (const cairo_pattern_t *pattern,
return CAIRO_STATUS_SUCCESS;
}
/**
* _cairo_surface_set_resolution
* @surface: the surface
* @x_res: x resolution, in dpi
* @y_res: y resolution, in dpi
*
* Set the actual surface resolution of @surface to the given x and y DPI.
* Mainly used for correctly computing the scale factor when fallback
* rendering needs to take place in the paginated surface.
*/
void
_cairo_surface_set_resolution (cairo_surface_t *surface,
double x_res,
double y_res)
{
surface->x_resolution = x_res;
surface->y_resolution = y_res;
}
/* LocalWords: rasterized
*/

Просмотреть файл

@ -1,4 +1,4 @@
/* -*- Mode: c; tab-width: 8; c-basic-offset: 4; indent-tabs-mode: t; -*- */
/* vim: set sw=4 sts=4: -*- Mode: c; tab-width: 8; c-basic-offset: 4; indent-tabs-mode: t; -*- */
/* cairo - a vector graphics library with display and print output
*
* Copyright © 2004 Red Hat, Inc
@ -451,16 +451,15 @@ _cairo_svg_surface_show_page (void *abstract_surface)
static void
_cairo_svg_surface_emit_transform (cairo_output_stream_t *output,
char const *attribute_str,
char const *trailer,
cairo_matrix_t *matrix)
{
_cairo_output_stream_printf (output,
"%s=\"matrix(%f,%f,%f,%f,%f,%f)\"%s",
attribute_str,
matrix->xx, matrix->yx,
matrix->xy, matrix->yy,
matrix->x0, matrix->y0,
trailer);
if (!_cairo_matrix_is_identity (matrix))
_cairo_output_stream_printf (output,
"%s=\"matrix(%f,%f,%f,%f,%f,%f)\"",
attribute_str,
matrix->xx, matrix->yx,
matrix->xy, matrix->yy,
matrix->x0, matrix->y0);
}
typedef struct
@ -616,7 +615,8 @@ _cairo_svg_document_emit_bitmap_glyph_data (cairo_svg_document_t *document,
}
_cairo_output_stream_printf (document->xml_node_glyphs, "<g");
_cairo_svg_surface_emit_transform (document->xml_node_glyphs, " transform", ">/n", &image->base.device_transform);
_cairo_svg_surface_emit_transform (document->xml_node_glyphs, " transform", &image->base.device_transform_inverse);
_cairo_output_stream_printf (document->xml_node_glyphs, ">/n");
for (y = 0, row = image->data, rows = image->height; rows; row += image->stride, rows--, y++) {
for (x = 0, byte = row, cols = (image->width + 7) / 8; cols; byte++, cols--) {
@ -917,7 +917,8 @@ _cairo_svg_surface_emit_composite_image_pattern (cairo_output_stream_t *outp
"width=\"%d\" height=\"%d\"",
pattern_id,
extents.width, extents.height);
_cairo_svg_surface_emit_transform (output, " patternTransform", ">\n", &p2u);
_cairo_svg_surface_emit_transform (output, " patternTransform", &p2u);
_cairo_output_stream_printf (output, ">\n");
}
_cairo_output_stream_printf (output,
@ -925,7 +926,7 @@ _cairo_svg_surface_emit_composite_image_pattern (cairo_output_stream_t *outp
extents.width, extents.height);
if (pattern_id == invalid_pattern_id)
_cairo_svg_surface_emit_transform (output, " transform", "", &p2u);
_cairo_svg_surface_emit_transform (output, " transform", &p2u);
if (extra_attributes)
_cairo_output_stream_printf (output, " %s", extra_attributes);
@ -990,7 +991,7 @@ _cairo_svg_surface_emit_meta_surface (cairo_svg_document_t *document,
return status;
}
status = _cairo_surface_show_page (paginated_surface);
status = cairo_surface_show_page (paginated_surface);
if (status) {
cairo_surface_destroy (&meta->base);
return status;
@ -1092,7 +1093,8 @@ _cairo_svg_surface_emit_composite_meta_pattern (cairo_output_stream_t *output,
pattern_id,
meta_surface->width_pixels,
meta_surface->height_pixels);
_cairo_svg_surface_emit_transform (output, " patternTransform", ">\n", &p2u);
_cairo_svg_surface_emit_transform (output, " patternTransform", &p2u);
_cairo_output_stream_printf (output, ">\n");
}
_cairo_output_stream_printf (output,
@ -1100,7 +1102,7 @@ _cairo_svg_surface_emit_composite_meta_pattern (cairo_output_stream_t *output,
id);
if (pattern_id == invalid_pattern_id)
_cairo_svg_surface_emit_transform (output, " transform", "", &p2u);
_cairo_svg_surface_emit_transform (output, " transform", &p2u);
if (extra_attributes)
_cairo_output_stream_printf (output, " %s", extra_attributes);
@ -1399,7 +1401,8 @@ _cairo_svg_surface_emit_linear_pattern (cairo_svg_surface_t *surface,
x0, y0, x1, y1);
_cairo_svg_surface_emit_pattern_extend (document->xml_node_defs, &pattern->base.base),
_cairo_svg_surface_emit_transform (document->xml_node_defs, "gradientTransform", ">\n", &p2u);
_cairo_svg_surface_emit_transform (document->xml_node_defs, "gradientTransform", &p2u);
_cairo_output_stream_printf (document->xml_node_defs, ">\n");
_cairo_svg_surface_emit_pattern_stops (document->xml_node_defs ,&pattern->base, 0.0, FALSE, FALSE);
@ -1469,8 +1472,8 @@ _cairo_svg_surface_emit_radial_pattern (cairo_svg_surface_t *surface,
document->radial_pattern_id,
x1, y1,
x1, y1, r1);
_cairo_svg_surface_emit_transform (document->xml_node_defs, "gradientTransform", ">\n", &p2u);
_cairo_svg_surface_emit_transform (document->xml_node_defs, "gradientTransform", &p2u);
_cairo_output_stream_printf (document->xml_node_defs, ">\n");
if (extend == CAIRO_EXTEND_NONE ||
pattern->base.n_stops < 1)
@ -1554,7 +1557,8 @@ _cairo_svg_surface_emit_radial_pattern (cairo_svg_surface_t *surface,
_cairo_output_stream_printf (document->xml_node_defs, "spreadMethod=\"repeat\" ");
else
_cairo_svg_surface_emit_pattern_extend (document->xml_node_defs, &pattern->base.base);
_cairo_svg_surface_emit_transform (document->xml_node_defs, "gradientTransform", ">\n", &p2u);
_cairo_svg_surface_emit_transform (document->xml_node_defs, "gradientTransform", &p2u);
_cairo_output_stream_printf (document->xml_node_defs, ">\n");
/* To support cairo's EXTEND_NONE, (for which SVG has no similar
* notion), we add transparent color stops on either end of the
@ -1613,6 +1617,124 @@ _cairo_svg_surface_emit_pattern (cairo_svg_surface_t *surface, cairo_pattern_t *
return CAIRO_STATUS_SUCCESS;
}
static void
_cairo_svg_surface_emit_fill_style (cairo_output_stream_t *output,
cairo_svg_surface_t *surface,
cairo_operator_t op,
cairo_pattern_t *source,
cairo_fill_rule_t fill_rule)
{
_cairo_output_stream_printf (output,
"fill-rule: %s; ",
fill_rule == CAIRO_FILL_RULE_EVEN_ODD ?
"evenodd" : "nonzero");
_cairo_svg_surface_emit_operator (output, surface, op);
_cairo_svg_surface_emit_pattern (surface, source, output, FALSE);
}
static void
_cairo_svg_surface_emit_stroke_style (cairo_output_stream_t *output,
cairo_svg_surface_t *surface,
cairo_operator_t op,
cairo_pattern_t *source,
cairo_stroke_style_t *stroke_style)
{
const char *line_cap, *line_join;
unsigned int i;
switch (stroke_style->line_cap) {
case CAIRO_LINE_CAP_BUTT:
line_cap = "butt";
break;
case CAIRO_LINE_CAP_ROUND:
line_cap = "round";
break;
case CAIRO_LINE_CAP_SQUARE:
line_cap = "square";
break;
default:
ASSERT_NOT_REACHED;
}
switch (stroke_style->line_join) {
case CAIRO_LINE_JOIN_MITER:
line_join = "miter";
break;
case CAIRO_LINE_JOIN_ROUND:
line_join = "round";
break;
case CAIRO_LINE_JOIN_BEVEL:
line_join = "bevel";
break;
default:
ASSERT_NOT_REACHED;
}
_cairo_output_stream_printf (output,
"stroke-width: %f; "
"stroke-linecap: %s; "
"stroke-linejoin: %s; ",
stroke_style->line_width,
line_cap,
line_join);
_cairo_svg_surface_emit_pattern (surface, source, output, TRUE);
_cairo_svg_surface_emit_operator (output, surface, op);
if (stroke_style->num_dashes > 0) {
_cairo_output_stream_printf (output, "stroke-dasharray: ");
for (i = 0; i < stroke_style->num_dashes; i++) {
_cairo_output_stream_printf (output, "%f",
stroke_style->dash[i]);
if (i + 1 < stroke_style->num_dashes)
_cairo_output_stream_printf (output, ",");
else
_cairo_output_stream_printf (output, "; ");
}
if (stroke_style->dash_offset != 0.0) {
_cairo_output_stream_printf (output,
"stroke-dashoffset: %f; ",
stroke_style->dash_offset);
}
}
_cairo_output_stream_printf (output,
"stroke-miterlimit: %f; ",
stroke_style->miter_limit);
}
static cairo_int_status_t
_cairo_svg_surface_fill_stroke (void *abstract_surface,
cairo_operator_t fill_op,
cairo_pattern_t *fill_source,
cairo_fill_rule_t fill_rule,
double fill_tolerance,
cairo_antialias_t fill_antialias,
cairo_path_fixed_t *path,
cairo_operator_t stroke_op,
cairo_pattern_t *stroke_source,
cairo_stroke_style_t *stroke_style,
cairo_matrix_t *stroke_ctm,
cairo_matrix_t *stroke_ctm_inverse,
double stroke_tolerance,
cairo_antialias_t stroke_antialias)
{
cairo_svg_surface_t *surface = abstract_surface;
cairo_status_t status;
_cairo_output_stream_printf (surface->xml_node, "<path style=\"");
_cairo_svg_surface_emit_fill_style (surface->xml_node, surface, fill_op, fill_source, fill_rule);
_cairo_svg_surface_emit_stroke_style (surface->xml_node, surface, stroke_op, stroke_source, stroke_style);
_cairo_output_stream_printf (surface->xml_node, "\" ");
status = _cairo_svg_surface_emit_path (surface->xml_node, path, stroke_ctm_inverse);
_cairo_svg_surface_emit_transform (surface->xml_node, " transform", stroke_ctm);
_cairo_output_stream_printf (surface->xml_node, "/>\n");
return status;
}
static cairo_int_status_t
_cairo_svg_surface_fill (void *abstract_surface,
cairo_operator_t op,
@ -1630,13 +1752,8 @@ _cairo_svg_surface_fill (void *abstract_surface,
assert (_cairo_svg_surface_operation_supported (surface, op, source));
_cairo_output_stream_printf (surface->xml_node,
"<path style=\"stroke: none; "
"fill-rule: %s; ",
fill_rule == CAIRO_FILL_RULE_EVEN_ODD ?
"evenodd" : "nonzero");
_cairo_svg_surface_emit_operator (surface->xml_node, surface, op);
_cairo_svg_surface_emit_pattern (surface, source, surface->xml_node, FALSE);
_cairo_output_stream_printf (surface->xml_node, "<path style=\" stroke:none;");
_cairo_svg_surface_emit_fill_style (surface->xml_node, surface, op, source, fill_rule);
_cairo_output_stream_printf (surface->xml_node, "\" ");
status = _cairo_svg_surface_emit_path (surface->xml_node, path, NULL);
@ -1815,78 +1932,20 @@ _cairo_svg_surface_stroke (void *abstract_dst,
{
cairo_svg_surface_t *surface = abstract_dst;
cairo_status_t status;
const char *line_cap, *line_join;
unsigned int i;
if (surface->paginated_mode == CAIRO_PAGINATED_MODE_ANALYZE)
return _cairo_svg_surface_analyze_operation (surface, op, source);
assert (_cairo_svg_surface_operation_supported (surface, op, source));
switch (stroke_style->line_cap) {
case CAIRO_LINE_CAP_BUTT:
line_cap = "butt";
break;
case CAIRO_LINE_CAP_ROUND:
line_cap = "round";
break;
case CAIRO_LINE_CAP_SQUARE:
line_cap = "square";
break;
default:
ASSERT_NOT_REACHED;
}
switch (stroke_style->line_join) {
case CAIRO_LINE_JOIN_MITER:
line_join = "miter";
break;
case CAIRO_LINE_JOIN_ROUND:
line_join = "round";
break;
case CAIRO_LINE_JOIN_BEVEL:
line_join = "bevel";
break;
default:
ASSERT_NOT_REACHED;
}
_cairo_output_stream_printf (surface->xml_node,
"<path style=\"fill: none; "
"stroke-width: %f; "
"stroke-linecap: %s; "
"stroke-linejoin: %s; ",
stroke_style->line_width,
line_cap,
line_join);
_cairo_svg_surface_emit_pattern (surface, source, surface->xml_node, TRUE);
_cairo_svg_surface_emit_operator (surface->xml_node, surface, op);
if (stroke_style->num_dashes > 0) {
_cairo_output_stream_printf (surface->xml_node, "stroke-dasharray: ");
for (i = 0; i < stroke_style->num_dashes; i++) {
_cairo_output_stream_printf (surface->xml_node, "%f",
stroke_style->dash[i]);
if (i + 1 < stroke_style->num_dashes)
_cairo_output_stream_printf (surface->xml_node, ",");
else
_cairo_output_stream_printf (surface->xml_node, "; ");
}
if (stroke_style->dash_offset != 0.0) {
_cairo_output_stream_printf (surface->xml_node,
"stroke-dashoffset: %f; ",
stroke_style->dash_offset);
}
}
_cairo_output_stream_printf (surface->xml_node,
"stroke-miterlimit: %f;\" ",
stroke_style->miter_limit);
_cairo_output_stream_printf (surface->xml_node, "<path style=\"fill: none; ");
_cairo_svg_surface_emit_stroke_style (surface->xml_node, surface, op, source, stroke_style);
_cairo_output_stream_printf (surface->xml_node, "\" ");
status = _cairo_svg_surface_emit_path (surface->xml_node, path, ctm_inverse);
_cairo_svg_surface_emit_transform (surface->xml_node, " transform", "/>\n", ctm);
_cairo_svg_surface_emit_transform (surface->xml_node, " transform", ctm);
_cairo_output_stream_printf (surface->xml_node, "/>\n");
return status;
}
@ -2043,7 +2102,11 @@ static const cairo_surface_backend_t cairo_svg_surface_backend = {
_cairo_svg_surface_mask,
_cairo_svg_surface_stroke,
_cairo_svg_surface_fill,
_cairo_svg_surface_show_glyphs
_cairo_svg_surface_show_glyphs,
NULL, /* snapshot */
NULL, /* is_similar */
NULL, /* reset */
_cairo_svg_surface_fill_stroke
};
static cairo_svg_document_t *

Просмотреть файл

@ -931,13 +931,16 @@ _cairo_truetype_subset_init (cairo_truetype_subset_t *truetype_subset,
truetype_subset->ascent = (double)font->base.ascent/font->base.units_per_em;
truetype_subset->descent = (double)font->base.descent/font->base.units_per_em;
truetype_subset->data = malloc (length);
if (truetype_subset->data == NULL) {
status = CAIRO_STATUS_NO_MEMORY;
goto fail3;
}
if (length) {
truetype_subset->data = malloc (length);
if (truetype_subset->data == NULL) {
status = CAIRO_STATUS_NO_MEMORY;
goto fail3;
}
memcpy (truetype_subset->data, data, length);
memcpy (truetype_subset->data, data, length);
} else
truetype_subset->data = NULL;
truetype_subset->data_length = length;
if (num_strings) {

Просмотреть файл

@ -38,37 +38,24 @@
#ifndef CAIRO_TYPES_PRIVATE_H
#define CAIRO_TYPES_PRIVATE_H
/* This is the only header file not including cairoint.h. It only contains
* typedefs.*/
#include "cairo.h"
typedef struct _cairo_array cairo_array_t;
struct _cairo_array {
unsigned int size;
unsigned int num_elements;
unsigned int element_size;
char **elements;
cairo_bool_t is_snapshot;
};
typedef cairo_array_t cairo_user_data_array_t;
struct _cairo_font_options {
cairo_antialias_t antialias;
cairo_subpixel_order_t subpixel_order;
cairo_hint_style_t hint_style;
cairo_hint_metrics_t hint_metrics;
};
typedef struct _cairo_hash_table cairo_hash_table_t;
typedef struct _cairo_cache {
cairo_hash_table_t *hash_table;
cairo_destroy_func_t entry_destroy;
unsigned long max_size;
unsigned long size;
int freeze_count;
} cairo_cache_t;
typedef struct _cairo_cache cairo_cache_t;
typedef struct _cairo_hash_entry cairo_hash_entry_t;
typedef struct _cairo_surface_backend cairo_surface_backend_t;
typedef struct _cairo_clip cairo_clip_t;
typedef struct _cairo_output_stream cairo_output_stream_t;
typedef struct _cairo_scaled_font_subsets cairo_scaled_font_subsets_t;
typedef struct _cairo_paginated_surface_backend cairo_paginated_surface_backend_t;
typedef struct _cairo_scaled_font_backend cairo_scaled_font_backend_t;
typedef struct _cairo_font_face_backend cairo_font_face_backend_t;
typedef struct _cairo_xlib_screen_info cairo_xlib_screen_info_t;
typedef enum _cairo_paginated_mode cairo_paginated_mode_t;
typedef cairo_array_t cairo_user_data_array_t;
/**
* cairo_hash_entry_t:
@ -104,25 +91,62 @@ typedef struct _cairo_cache {
* parameter name of key). In these cases, the value-related fields of
* the entry need not be initialized if so desired.
**/
typedef struct _cairo_hash_entry {
struct _cairo_hash_entry {
unsigned long hash;
} cairo_hash_entry_t;
};
struct _cairo_array {
unsigned int size;
unsigned int num_elements;
unsigned int element_size;
char **elements;
typedef struct _cairo_surface_backend cairo_surface_backend_t;
typedef struct _cairo_clip cairo_clip_t;
typedef struct _cairo_output_stream cairo_output_stream_t;
typedef struct _cairo_scaled_font_subsets cairo_scaled_font_subsets_t;
typedef struct _cairo_paginated_surface_backend cairo_paginated_surface_backend_t;
typedef struct _cairo_scaled_font_backend cairo_scaled_font_backend_t;
typedef struct _cairo_font_face_backend cairo_font_face_backend_t;
cairo_bool_t is_snapshot;
};
struct _cairo_font_options {
cairo_antialias_t antialias;
cairo_subpixel_order_t subpixel_order;
cairo_hint_style_t hint_style;
cairo_hint_metrics_t hint_metrics;
};
typedef struct _cairo_xlib_screen_info cairo_xlib_screen_info_t;
struct _cairo_cache {
cairo_hash_table_t *hash_table;
typedef enum {
cairo_destroy_func_t entry_destroy;
unsigned long max_size;
unsigned long size;
int freeze_count;
};
enum _cairo_paginated_mode {
CAIRO_PAGINATED_MODE_ANALYZE, /* analyze page regions */
CAIRO_PAGINATED_MODE_RENDER /* render page contents */
} cairo_paginated_mode_t;
};
/* Sure wish C had a real enum type so that this would be distinct
from cairo_status_t. Oh well, without that, I'll use this bogus 1000
offset */
typedef enum _cairo_int_status {
CAIRO_INT_STATUS_DEGENERATE = 1000,
CAIRO_INT_STATUS_UNSUPPORTED,
CAIRO_INT_STATUS_NOTHING_TO_DO,
CAIRO_INT_STATUS_CACHE_EMPTY,
CAIRO_INT_STATUS_FLATTEN_TRANSPARENCY,
CAIRO_INT_STATUS_IMAGE_FALLBACK,
CAIRO_INT_STATUS_ANALYZE_META_SURFACE_PATTERN,
} cairo_int_status_t;
typedef enum _cairo_internal_surface_type {
CAIRO_INTERNAL_SURFACE_TYPE_META = 0x1000,
CAIRO_INTERNAL_SURFACE_TYPE_PAGINATED,
CAIRO_INTERNAL_SURFACE_TYPE_ANALYSIS,
CAIRO_INTERNAL_SURFACE_TYPE_TEST_META,
CAIRO_INTERNAL_SURFACE_TYPE_TEST_FALLBACK,
CAIRO_INTERNAL_SURFACE_TYPE_TEST_PAGINATED
} cairo_internal_surface_type_t;
#endif /* CAIRO_TYPES_PRIVATE_H */

Просмотреть файл

@ -303,19 +303,21 @@ _win32_scaled_font_create (LOGFONTW *logfont,
status = _cairo_scaled_font_init (&f->base, font_face,
font_matrix, ctm, options,
&cairo_win32_scaled_font_backend);
if (status) {
free (f);
return NULL;
}
if (status)
goto FAIL;
status = _cairo_win32_scaled_font_set_metrics (f);
if (status) {
_cairo_scaled_font_fini (f);
free (f);
return NULL;
_cairo_scaled_font_fini (&f->base);
goto FAIL;
}
return &f->base;
FAIL:
free (f);
return NULL;
}
static cairo_status_t
@ -324,12 +326,7 @@ _win32_scaled_font_set_world_transform (cairo_win32_scaled_font_t *scaled_font,
{
XFORM xform;
xform.eM11 = scaled_font->logical_to_device.xx;
xform.eM21 = scaled_font->logical_to_device.xy;
xform.eM12 = scaled_font->logical_to_device.yx;
xform.eM22 = scaled_font->logical_to_device.yy;
xform.eDx = scaled_font->logical_to_device.x0;
xform.eDy = scaled_font->logical_to_device.y0;
_cairo_matrix_to_win32_xform (&scaled_font->logical_to_device, &xform);
if (!SetWorldTransform (hdc, &xform))
return _cairo_win32_print_gdi_error ("_win32_scaled_font_set_world_transform");

Разница между файлами не показана из-за своего большого размера Загрузить разницу

Просмотреть файл

@ -79,10 +79,18 @@ typedef struct _cairo_win32_surface {
/* Surface DC flags */
uint32_t flags;
/* printing surface bits */
cairo_paginated_mode_t paginated_mode;
int clip_saved_dc;
HBRUSH brush, old_brush;
} cairo_win32_surface_t;
/* Surface DC flag values */
enum {
/* If this is a surface created for printing or not */
CAIRO_WIN32_SURFACE_FOR_PRINTING = (1<<0),
/* Whether the DC is a display DC or not */
CAIRO_WIN32_SURFACE_IS_DISPLAY = (1<<1),
@ -96,7 +104,15 @@ enum {
CAIRO_WIN32_SURFACE_CAN_STRETCHBLT = (1<<4),
/* Whether we can use StretchDIBits with this surface */
CAIRO_WIN32_SURFACE_CAN_STRETCHDIB = (1<<5)
CAIRO_WIN32_SURFACE_CAN_STRETCHDIB = (1<<5),
/* Whether we can use GradientFill rectangles with this surface */
CAIRO_WIN32_SURFACE_CAN_RECT_GRADIENT = (1<<6),
/* If we should treat all operators other than CLEAR and OVER
* like SOURCE to avoid hitting fallback. Ignored except
* for printing. */
CAIRO_WIN32_SURFACE_IGNORE_OPERATORS = (1<<7)
};
cairo_status_t
@ -105,4 +121,52 @@ _cairo_win32_print_gdi_error (const char *context);
cairo_bool_t
_cairo_surface_is_win32 (cairo_surface_t *surface);
cairo_bool_t
_cairo_surface_is_win32_printing (cairo_surface_t *surface);
cairo_status_t
_cairo_win32_surface_finish (void *abstract_surface);
cairo_int_status_t
_cairo_win32_surface_get_extents (void *abstract_surface,
cairo_rectangle_int16_t *rectangle);
uint32_t
_cairo_win32_flags_for_dc (HDC dc);
cairo_int_status_t
_cairo_win32_surface_show_glyphs (void *surface,
cairo_operator_t op,
cairo_pattern_t *source,
cairo_glyph_t *glyphs,
int num_glyphs,
cairo_scaled_font_t *scaled_font);
cairo_surface_t *
_cairo_win32_surface_create_similar (void *abstract_src,
cairo_content_t content,
int width,
int height);
cairo_status_t
_cairo_win32_surface_clone_similar (void *abstract_surface,
cairo_surface_t *src,
int src_x,
int src_y,
int width,
int height,
cairo_surface_t **clone_out);
static inline void
_cairo_matrix_to_win32_xform (const cairo_matrix_t *m,
XFORM *xform)
{
xform->eM11 = (FLOAT) m->xx;
xform->eM21 = (FLOAT) m->xy;
xform->eM12 = (FLOAT) m->yx;
xform->eM22 = (FLOAT) m->yy;
xform->eDx = (FLOAT) m->x0;
xform->eDy = (FLOAT) m->y0;
}
#endif /* CAIRO_WIN32_PRIVATE_H */

Просмотреть файл

@ -108,7 +108,7 @@ _cairo_win32_print_gdi_error (const char *context)
return CAIRO_STATUS_NO_MEMORY;
}
static uint32_t
uint32_t
_cairo_win32_flags_for_dc (HDC dc)
{
uint32_t flags = 0;
@ -426,7 +426,7 @@ _cairo_win32_surface_create_similar_internal (void *abstract_src,
return (cairo_surface_t*) new_surf;
}
static cairo_surface_t *
cairo_surface_t *
_cairo_win32_surface_create_similar (void *abstract_src,
cairo_content_t content,
int width,
@ -435,7 +435,50 @@ _cairo_win32_surface_create_similar (void *abstract_src,
return _cairo_win32_surface_create_similar_internal (abstract_src, content, width, height, FALSE);
}
static cairo_status_t
cairo_status_t
_cairo_win32_surface_clone_similar (void *abstract_surface,
cairo_surface_t *src,
int src_x,
int src_y,
int width,
int height,
cairo_surface_t **clone_out)
{
cairo_content_t src_content;
cairo_surface_t *new_surface;
cairo_status_t status;
cairo_pattern_union_t pattern;
src_content = cairo_surface_get_content(src);
new_surface =
_cairo_win32_surface_create_similar_internal (abstract_surface, src_content, width, height, FALSE);
if (cairo_surface_status(new_surface))
return cairo_surface_status(new_surface);
_cairo_pattern_init_for_surface (&pattern.surface, src);
status = _cairo_surface_composite (CAIRO_OPERATOR_SOURCE,
&pattern.base,
NULL,
new_surface,
src_x, src_y,
0, 0,
0, 0,
width, height);
_cairo_pattern_fini (&pattern.base);
if (status == CAIRO_STATUS_SUCCESS)
*clone_out = new_surface;
else
cairo_surface_destroy (new_surface);
return status;
}
cairo_status_t
_cairo_win32_surface_finish (void *abstract_surface)
{
cairo_win32_surface_t *surface = abstract_surface;
@ -476,12 +519,8 @@ _cairo_win32_surface_get_subimage (cairo_win32_surface_t *surface,
status = CAIRO_INT_STATUS_UNSUPPORTED;
/* Check for SURFACE_IS_DISPLAY here, because there are a lot
* of printer drivers that lie and say they can BitBlt, but
* just spit out black instead.
*/
if ((local->flags & CAIRO_WIN32_SURFACE_IS_DISPLAY) &&
(local->flags & CAIRO_WIN32_SURFACE_CAN_BITBLT) &&
/* Only BitBlt if the source surface supports it. */
if ((surface->flags & CAIRO_WIN32_SURFACE_CAN_BITBLT) &&
BitBlt (local->dc,
0, 0,
width, height,
@ -1476,7 +1515,7 @@ _cairo_win32_surface_set_clip_region (void *abstract_surface,
}
}
static cairo_int_status_t
cairo_int_status_t
_cairo_win32_surface_get_extents (void *abstract_surface,
cairo_rectangle_int_t *rectangle)
{
@ -1495,7 +1534,7 @@ _cairo_win32_surface_flush (void *abstract_surface)
#define STACK_GLYPH_SIZE 256
static cairo_int_status_t
cairo_int_status_t
_cairo_win32_surface_show_glyphs (void *surface,
cairo_operator_t op,
cairo_pattern_t *source,
@ -1538,8 +1577,10 @@ _cairo_win32_surface_show_glyphs (void *surface,
return CAIRO_INT_STATUS_UNSUPPORTED;
/* If we have a fallback mask clip set on the dst, we have
* to go through the fallback path */
if (dst->base.clip &&
* to go through the fallback path, but only if we're not
* doing this for printing */
if (dst->base.clip &&
!(dst->flags & CAIRO_WIN32_SURFACE_FOR_PRINTING) &&
(dst->base.clip->mode != CAIRO_CLIP_MODE_REGION ||
dst->base.clip->surface != NULL))
return CAIRO_INT_STATUS_UNSUPPORTED;
@ -1694,6 +1735,8 @@ cairo_win32_surface_create (HDC hdc)
surface->bitmap = NULL;
surface->is_dib = FALSE;
surface->saved_dc_bitmap = NULL;
surface->brush = NULL;
surface->old_brush = NULL;
surface->clip_rect.x = (int16_t) rect.left;
surface->clip_rect.y = (int16_t) rect.top;
@ -1715,6 +1758,7 @@ cairo_win32_surface_create (HDC hdc)
surface->extents = surface->clip_rect;
surface->flags = _cairo_win32_flags_for_dc (surface->dc);
surface->clip_saved_dc = 0;
_cairo_surface_init (&surface->base, &cairo_win32_surface_backend,
_cairo_content_from_format (format));
@ -1809,7 +1853,9 @@ cairo_win32_surface_create_with_ddb (HDC hdc,
* _cairo_surface_is_win32:
* @surface: a #cairo_surface_t
*
* Checks if a surface is an #cairo_win32_surface_t
* Checks if a surface is a win32 surface. This will
* return False if this is a win32 printing surface; use
* _cairo_surface_is_win32_printing() to check for that.
*
* Return value: True if the surface is an win32 surface
**/
@ -1835,10 +1881,8 @@ cairo_win32_surface_get_dc (cairo_surface_t *surface)
{
cairo_win32_surface_t *winsurf;
if (surface == NULL)
return NULL;
if (!_cairo_surface_is_win32(surface))
if (!_cairo_surface_is_win32(surface) &&
!_cairo_surface_is_win32_printing(surface))
return NULL;
winsurf = (cairo_win32_surface_t *) surface;
@ -1900,7 +1944,7 @@ static const cairo_surface_backend_t cairo_win32_surface_backend = {
_cairo_win32_surface_release_source_image,
_cairo_win32_surface_acquire_dest_image,
_cairo_win32_surface_release_dest_image,
NULL, /* clone_similar */
_cairo_win32_surface_clone_similar,
_cairo_win32_surface_composite,
_cairo_win32_surface_fill_rectangles,
NULL, /* composite_trapezoids */

Просмотреть файл

@ -47,6 +47,9 @@ CAIRO_BEGIN_DECLS
cairo_public cairo_surface_t *
cairo_win32_surface_create (HDC hdc);
cairo_public cairo_surface_t *
cairo_win32_printing_surface_create (HDC hdc, cairo_bool_t ignore_operators);
cairo_public cairo_surface_t *
cairo_win32_surface_create_with_ddb (HDC hdc,
cairo_format_t format,

Просмотреть файл

@ -2087,45 +2087,9 @@ _cairo_xcb_surface_add_glyph (xcb_connection_t *dpy,
goto BAIL;
}
/*
* Most of the font rendering system thinks of glyph tiles as having
* an origin at (0,0) and an x and y bounding box "offset" which
* extends possibly off into negative coordinates, like so:
*
*
* (x,y) <-- probably negative numbers
* +----------------+
* | . |
* | . |
* |......(0,0) |
* | |
* | |
* +----------------+
* (width+x,height+y)
*
* This is a postscript-y model, where each glyph has its own
* coordinate space, so it's what we expose in terms of metrics. It's
* apparently what everyone's expecting. Everyone except the Render
* extension. Render wants to see a glyph tile starting at (0,0), with
* an origin offset inside, like this:
*
* (0,0)
* +---------------+
* | . |
* | . |
* |......(x,y) |
* | |
* | |
* +---------------+
* (width,height)
*
* Luckily, this is just the negation of the numbers we already have
* sitting around for x and y.
*/
/* XXX: FRAGILE: We're ignore device_transform scaling here. A bug? */
glyph_info.x = - _cairo_lround (glyph_surface->base.device_transform.x0);
glyph_info.y = - _cairo_lround (glyph_surface->base.device_transform.y0);
glyph_info.x = _cairo_lround (glyph_surface->base.device_transform.x0);
glyph_info.y = _cairo_lround (glyph_surface->base.device_transform.y0);
glyph_info.width = glyph_surface->width;
glyph_info.height = glyph_surface->height;
glyph_info.x_off = 0;

Просмотреть файл

@ -38,7 +38,6 @@
#include <fontconfig/fontconfig.h>
#include <X11/Xlibint.h> /* For XESetCloseDisplay */
#include <X11/extensions/Xrender.h>
typedef int (*cairo_xlib_error_func_t) (Display *display,
XErrorEvent *event);
@ -226,6 +225,7 @@ _cairo_xlib_display_get (Display *dpy)
cairo_xlib_display_t *display;
cairo_xlib_display_t **prev;
XExtCodes *codes;
int major_unused, minor_unused;
/* There is an apparent deadlock between this mutex and the
* mutex for the display, but it's actually safe. For the
@ -260,6 +260,14 @@ _cairo_xlib_display_get (Display *dpy)
if (display == NULL)
goto UNLOCK;
/* Xlib calls out to the extension close_display hooks in LIFO
* order. So we have to ensure that all extensions that we depend
* on in our close_display hook are properly initialized before we
* add our hook. For now, that means Render, so we call into its
* QueryVersion function to ensure it gets initialized.
*/
XRenderQueryVersion (dpy, &major_unused, &minor_unused);
codes = XAddExtension (dpy);
if (codes == NULL) {
free (display);

Просмотреть файл

@ -35,8 +35,11 @@
#include "cairoint.h"
#include "cairo-xlib.h"
#include "cairo-xlib-xrender-private.h"
#include "cairo-freelist-private.h"
#include <X11/Xutil.h> /* for XDestroyImage */
typedef struct _cairo_xlib_display cairo_xlib_display_t;
typedef struct _cairo_xlib_hook cairo_xlib_hook_t;
typedef struct _cairo_xlib_job cairo_xlib_job_t;
@ -121,11 +124,4 @@ _cairo_xlib_screen_get_gc (cairo_xlib_screen_info_t *info, int depth);
cairo_private cairo_status_t
_cairo_xlib_screen_put_gc (cairo_xlib_screen_info_t *info, int depth, GC gc, cairo_bool_t reset_clip);
#if 1 /* CAIRO_HAS_XLIB_XRENDER_SURFACE */
#include "cairo-xlib-xrender.h"
slim_hidden_proto (cairo_xlib_surface_create_with_xrender_format);
#endif
#endif /* CAIRO_XLIB_PRIVATE_H */

Просмотреть файл

@ -58,8 +58,6 @@
#include <fontconfig/fontconfig.h>
#include <X11/extensions/Xrender.h>
static int
parse_boolean (const char *v)
{

Просмотреть файл

@ -37,13 +37,10 @@
*/
#include "cairoint.h"
#include "cairo-xlib.h"
#include "cairo-xlib-xrender.h"
#include "cairo-xlib-private.h"
#include "cairo-xlib-surface-private.h"
#include "cairo-clip-private.h"
#include <X11/extensions/Xrender.h>
#include <X11/extensions/renderproto.h>
/* Xlib doesn't define a typedef, so define one ourselves */
typedef int (*cairo_xlib_error_func_t) (Display *display,
@ -344,46 +341,6 @@ _noop_error_handler (Display *display,
return False; /* return value is ignored */
}
static cairo_bool_t
_CAIRO_MASK_FORMAT (cairo_format_masks_t *masks, cairo_format_t *format)
{
switch (masks->bpp) {
case 32:
if (masks->alpha_mask == 0xff000000 &&
masks->red_mask == 0x00ff0000 &&
masks->green_mask == 0x0000ff00 &&
masks->blue_mask == 0x000000ff)
{
*format = CAIRO_FORMAT_ARGB32;
return True;
}
if (masks->alpha_mask == 0x00000000 &&
masks->red_mask == 0x00ff0000 &&
masks->green_mask == 0x0000ff00 &&
masks->blue_mask == 0x000000ff)
{
*format = CAIRO_FORMAT_RGB24;
return True;
}
break;
case 8:
if (masks->alpha_mask == 0xff)
{
*format = CAIRO_FORMAT_A8;
return True;
}
break;
case 1:
if (masks->alpha_mask == 0x1)
{
*format = CAIRO_FORMAT_A1;
return True;
}
break;
}
return False;
}
static void
_swap_ximage_2bytes (XImage *ximage)
{
@ -504,7 +461,7 @@ _get_image_surface (cairo_xlib_surface_t *surface,
XImage *ximage;
short x1, y1, x2, y2;
cairo_format_masks_t masks;
cairo_format_t format;
pixman_format_code_t pixman_format;
x1 = 0;
y1 = 0;
@ -638,38 +595,15 @@ _get_image_surface (cairo_xlib_surface_t *surface,
masks.alpha_mask = 0xffffffff;
}
/*
* Prefer to use a standard pixman format instead of the
* general masks case.
*/
if (_CAIRO_MASK_FORMAT (&masks, &format))
{
image = (cairo_image_surface_t*)
cairo_image_surface_create_for_data ((unsigned char *) ximage->data,
format,
ximage->width,
ximage->height,
ximage->bytes_per_line);
if (image->base.status)
goto FAIL;
}
else
{
/*
* XXX This can't work. We must convert the data to one of the
* supported pixman formats. Pixman needs another function
* which takes data in an arbitrary format and converts it
* to something supported by that library.
*/
image = (cairo_image_surface_t*)
_cairo_image_surface_create_with_masks ((unsigned char *) ximage->data,
&masks,
ximage->width,
ximage->height,
ximage->bytes_per_line);
if (image->base.status)
goto FAIL;
}
pixman_format = _pixman_format_from_masks (&masks);
image = (cairo_image_surface_t*)
_cairo_image_surface_create_with_pixman_format ((unsigned char *) ximage->data,
pixman_format,
ximage->width,
ximage->height,
ximage->bytes_per_line);
if (image->base.status)
goto FAIL;
/* Let the surface take ownership of the data */
_cairo_image_surface_assume_ownership_of_data (image);
@ -770,38 +704,6 @@ _cairo_xlib_surface_ensure_gc (cairo_xlib_surface_t *surface)
return CAIRO_STATUS_SUCCESS;
}
static void
cairo_format_get_masks (cairo_format_t format,
uint32_t *bpp,
uint32_t *red,
uint32_t *green,
uint32_t *blue)
{
*red = 0x0;
*green = 0x0;
*blue = 0x0;
switch (format)
{
case CAIRO_FORMAT_ARGB32:
case CAIRO_FORMAT_RGB24:
default:
*bpp = 32;
*red = 0x00ff0000;
*green = 0x0000ff00;
*blue = 0x000000ff;
break;
case CAIRO_FORMAT_A8:
*bpp = 8;
break;
case CAIRO_FORMAT_A1:
*bpp = 1;
break;
}
}
static cairo_status_t
_draw_image_surface (cairo_xlib_surface_t *surface,
cairo_image_surface_t *image,
@ -817,7 +719,7 @@ _draw_image_surface (cairo_xlib_surface_t *surface,
int native_byte_order = _native_byte_order_lsb () ? LSBFirst : MSBFirst;
cairo_status_t status;
cairo_format_get_masks (image->format, &bpp, &red, &green, &blue);
_pixman_format_to_masks (image->pixman_format, &bpp, &red, &green, &blue);
ximage.width = image->width;
ximage.height = image->height;
@ -1626,11 +1528,14 @@ _create_trapezoid_mask (cairo_xlib_surface_t *dst,
* the servers that have XRenderAddTraps().
*/
mask_picture = _create_a8_picture (dst, &transparent, width, height, FALSE);
solid_picture = _create_a8_picture (dst, &solid, width, height, TRUE);
if (num_traps == 0)
return mask_picture;
offset_traps = _cairo_malloc_ab (num_traps, sizeof (XTrapezoid));
if (!offset_traps)
if (!offset_traps) {
XRenderFreePicture (dst->dpy, mask_picture);
return None;
}
for (i = 0; i < num_traps; i++) {
offset_traps[i].top = _cairo_fixed_to_16_16(traps[i].top) - 0x10000 * dst_y;
@ -1645,6 +1550,8 @@ _create_trapezoid_mask (cairo_xlib_surface_t *dst,
offset_traps[i].right.p2.y = _cairo_fixed_to_16_16(traps[i].right.p2.y) - 0x10000 * dst_y;
}
solid_picture = _create_a8_picture (dst, &solid, width, height, TRUE);
XRenderCompositeTrapezoids (dst->dpy, PictOpAdd,
solid_picture, mask_picture,
pict_format,
@ -2216,6 +2123,7 @@ cairo_xlib_surface_create_for_bitmap (Display *dpy,
NULL, NULL, width, height, 1);
}
#if CAIRO_HAS_XLIB_XRENDER_SURFACE
/**
* cairo_xlib_surface_create_with_xrender_format:
* @dpy: an X Display
@ -2248,6 +2156,7 @@ cairo_xlib_surface_create_with_xrender_format (Display *dpy,
NULL, format, width, height, 0);
}
slim_hidden_def (cairo_xlib_surface_create_with_xrender_format);
#endif
/**
* cairo_xlib_surface_set_size:
@ -2686,45 +2595,9 @@ _cairo_xlib_surface_add_glyph (Display *dpy,
goto BAIL;
}
/*
* Most of the font rendering system thinks of glyph tiles as having
* an origin at (0,0) and an x and y bounding box "offset" which
* extends possibly off into negative coordinates, like so:
*
*
* (x,y) <-- probably negative numbers
* +----------------+
* | . |
* | . |
* |......(0,0) |
* | |
* | |
* +----------------+
* (width+x,height+y)
*
* This is a postscript-y model, where each glyph has its own
* coordinate space, so it's what we expose in terms of metrics. It's
* apparently what everyone's expecting. Everyone except the Render
* extension. Render wants to see a glyph tile starting at (0,0), with
* an origin offset inside, like this:
*
* (0,0)
* +---------------+
* | . |
* | . |
* |......(x,y) |
* | |
* | |
* +---------------+
* (width,height)
*
* Luckily, this is just the negation of the numbers we already have
* sitting around for x and y.
*/
/* XXX: FRAGILE: We're ignore device_transform scaling here. A bug? */
glyph_info.x = - _cairo_lround (glyph_surface->base.device_transform.x0);
glyph_info.y = - _cairo_lround (glyph_surface->base.device_transform.y0);
glyph_info.x = _cairo_lround (glyph_surface->base.device_transform.x0);
glyph_info.y = _cairo_lround (glyph_surface->base.device_transform.y0);
glyph_info.width = glyph_surface->width;
glyph_info.height = glyph_surface->height;
glyph_info.xOff = scaled_glyph->x_advance;

Разница между файлами не показана из-за своего большого размера Загрузить разницу

Просмотреть файл

@ -480,8 +480,6 @@ cairo_push_group_with_content (cairo_t *cr, cairo_content_t content)
cairo_status_t status;
cairo_rectangle_int_t extents;
cairo_surface_t *parent_surface, *group_surface = NULL;
int width;
int height;
if (cr->status)
return;
@ -495,15 +493,10 @@ cairo_push_group_with_content (cairo_t *cr, cairo_content_t content)
if (status)
goto bail;
width = extents.width;
height = extents.height;
if (width == 0 || height == 0)
width = height = 1;
group_surface = cairo_surface_create_similar (_cairo_gstate_get_target (cr->gstate),
content,
width, height);
extents.width,
extents.height);
status = cairo_surface_status (group_surface);
if (status)
goto bail;
@ -556,11 +549,11 @@ cairo_pattern_t *
cairo_pop_group (cairo_t *cr)
{
cairo_surface_t *group_surface, *parent_target;
cairo_pattern_t *group_pattern = NULL;
cairo_pattern_t *group_pattern = (cairo_pattern_t*) &_cairo_pattern_nil.base;
cairo_matrix_t group_matrix;
if (cr->status)
return (cairo_pattern_t*) &_cairo_pattern_nil.base;
return group_pattern;
/* Grab the active surfaces */
group_surface = _cairo_gstate_get_target (cr->gstate);
@ -569,7 +562,7 @@ cairo_pop_group (cairo_t *cr)
/* Verify that we are at the right nesting level */
if (parent_target == NULL) {
_cairo_set_error (cr, CAIRO_STATUS_INVALID_POP_GROUP);
return (cairo_pattern_t*) &_cairo_pattern_nil.base;
return group_pattern;
}
/* We need to save group_surface before we restore; we don't need
@ -2114,6 +2107,9 @@ slim_hidden_def(cairo_fill_preserve);
* doesn't clear it, so, the contents of the current page will be retained
* for the next page too. Use cairo_show_page() if you want to get an
* empty page after the emission.
*
* This is a convenience function that simply calls
* cairo_surface_copy_page() on @cr's target.
**/
void
cairo_copy_page (cairo_t *cr)
@ -2134,6 +2130,9 @@ cairo_copy_page (cairo_t *cr)
*
* Emits and clears the current page for backends that support multiple
* pages. Use cairo_copy_page() if you don't want to clear the page.
*
* This is a convenience function that simply calls
* cairo_surface_show_page() on @cr's target.
**/
void
cairo_show_page (cairo_t *cr)

Просмотреть файл

@ -1435,6 +1435,7 @@ cairo_surface_status (cairo_surface_t *surface);
* @CAIRO_SURFACE_TYPE_DIRECTFB: The surface is of type directfb
* @CAIRO_SURFACE_TYPE_SVG: The surface is of type svg
* @CAIRO_SURFACE_TYPE_OS2: The surface is of type os2
* @CAIRO_SURFACE_TYPE_WIN32_PRINTING: The surface is a win32 printing surface
*
* #cairo_surface_type_t is used to describe the type of a given
* surface. The surface types are also known as "backends" or "surface
@ -1471,7 +1472,8 @@ typedef enum _cairo_surface_type {
CAIRO_SURFACE_TYPE_BEOS,
CAIRO_SURFACE_TYPE_DIRECTFB,
CAIRO_SURFACE_TYPE_SVG,
CAIRO_SURFACE_TYPE_OS2
CAIRO_SURFACE_TYPE_OS2,
CAIRO_SURFACE_TYPE_WIN32_PRINTING
} cairo_surface_type_t;
cairo_public cairo_surface_type_t
@ -1535,6 +1537,12 @@ cairo_surface_set_fallback_resolution (cairo_surface_t *surface,
double x_pixels_per_inch,
double y_pixels_per_inch);
cairo_public cairo_status_t
cairo_surface_copy_page (cairo_surface_t *surface);
cairo_public cairo_status_t
cairo_surface_show_page (cairo_surface_t *surface);
/* Image-surface functions */
/**

Просмотреть файл

@ -64,11 +64,7 @@
#include <stdio.h>
#include "cairo.h"
#ifdef MOZ_TREE_CAIRO
#include "pixman.h"
#else
#include <pixman/pixman.h>
#endif
#include <pixman.h>
#ifdef _MSC_VER
#define snprintf _snprintf
@ -190,11 +186,6 @@ do { \
#define CAIRO_REF_COUNT_INVALID ((unsigned int) -1)
#include "cairo-mutex-private.h"
#include "cairo-wideint-private.h"
#include "cairo-malloc-private.h"
#include "cairo-fixed-private.h"
#define CAIRO_ALPHA_IS_OPAQUE(alpha) ((alpha) >= ((double)0xff00 / (double)0xffff))
#define CAIRO_ALPHA_SHORT_IS_OPAQUE(alpha) ((alpha) >= 0xff00)
#define CAIRO_ALPHA_IS_ZERO(alpha) ((alpha) <= 0.0)
@ -249,8 +240,8 @@ be32_to_cpu(uint32_t v)
#endif
#include "cairo-types-private.h"
#include "cairo-hash-private.h"
#include "cairo-cache-private.h"
#include "cairo-fixed-private.h"
typedef struct _cairo_region cairo_region_t;
@ -329,65 +320,7 @@ typedef cairo_box_int32_t cairo_box_int_t;
#error Not sure how to pick a cairo_rectangle_int_t for your CAIRO_FIXED_BITS!
#endif
/* Sure wish C had a real enum type so that this would be distinct
from cairo_status_t. Oh well, without that, I'll use this bogus 1000
offset */
typedef enum cairo_int_status {
CAIRO_INT_STATUS_DEGENERATE = 1000,
CAIRO_INT_STATUS_UNSUPPORTED,
CAIRO_INT_STATUS_NOTHING_TO_DO,
CAIRO_INT_STATUS_CACHE_EMPTY
} cairo_int_status_t;
typedef enum cairo_internal_surface_type {
CAIRO_INTERNAL_SURFACE_TYPE_META = 0x1000,
CAIRO_INTERNAL_SURFACE_TYPE_PAGINATED,
CAIRO_INTERNAL_SURFACE_TYPE_ANALYSIS,
CAIRO_INTERNAL_SURFACE_TYPE_TEST_META,
CAIRO_INTERNAL_SURFACE_TYPE_TEST_FALLBACK,
CAIRO_INTERNAL_SURFACE_TYPE_TEST_PAGINATED
} cairo_internal_surface_type_t;
/* For xlib fallbacks, we need image surfaces with formats that match
* the visual of the X server. There are a few common X server visuals
* for which we do not have corresponding public cairo_format_t
* values, since we do not plan on always guaranteeing that cairo will
* be able to draw to these formats.
*
* Currently pixman does advertise support for these formats, (with an
* interface to construct a format from a set of masks---but pixman
* may not actually have code to support any arbitrary set of
* maskes). So we lodge a cairo_internal_format_t in the internal
* cairo image surface to indicate what's going on. The value isn't
* actually used for much, since it is the set of pixman masks that
* control the rendering.
*
* But even though the value isn't used, it's still useful to maintain
* this list, as it indicates to use visual formats that have been
* encountered in practice. We can take advantage of this for future
* rewrites of pixman that might support a limited set of formats
* instead of general mask-based rendering, (or at least optimized
* rendering for a limited set of formats).
*
* Another approach that could be taken here is to convert the data at
* the time of the fallback to a supported format. This is similar to
* what needs to be done to support PseudoColor visuals, for example.
*
* NOTE: The implementation of CAIRO_FORMAT_VALID *must* *not*
* consider these internal formats as valid.
*
* NOTE: When adding a value to this list, be sure to add it to
* _cairo_format_from_pixman_format, (which is probably the assert
* failure you're wanting to eliminate), but also don't forget to add
* it to cairo_content_from_format.
*/
typedef enum cairo_internal_format {
CAIRO_INTERNAL_FORMAT_ABGR32 = 0x1000,
CAIRO_INTERNAL_FORMAT_BGR24,
CAIRO_INTERNAL_FORMAT_RGB16_565
} cairo_internal_format_t;
typedef enum cairo_direction {
typedef enum _cairo_direction {
CAIRO_DIRECTION_FORWARD,
CAIRO_DIRECTION_REVERSE
} cairo_direction_t;
@ -948,6 +881,22 @@ struct _cairo_surface_backend {
cairo_warn cairo_status_t
(*reset) (void *surface);
cairo_warn cairo_int_status_t
(*fill_stroke) (void *surface,
cairo_operator_t fill_op,
cairo_pattern_t *fill_source,
cairo_fill_rule_t fill_rule,
double fill_tolerance,
cairo_antialias_t fill_antialias,
cairo_path_fixed_t *path,
cairo_operator_t stroke_op,
cairo_pattern_t *stroke_source,
cairo_stroke_style_t *stroke_style,
cairo_matrix_t *stroke_ctm,
cairo_matrix_t *stroke_ctm_inverse,
double stroke_tolerance,
cairo_antialias_t stroke_antialias);
};
typedef struct _cairo_format_masks {
@ -963,7 +912,7 @@ typedef struct _cairo_format_masks {
struct _cairo_image_surface {
cairo_surface_t base;
/* libic-specific fields */
pixman_format_code_t pixman_format;
cairo_format_t format;
unsigned char *data;
cairo_bool_t owns_data;
@ -1135,6 +1084,7 @@ typedef struct _cairo_traps {
#define CAIRO_GSTATE_MITER_LIMIT_DEFAULT 10.0
#define CAIRO_GSTATE_DEFAULT_FONT_SIZE 10.0
#define CAIRO_SURFACE_RESOLUTION_DEFAULT 72.0
#define CAIRO_SURFACE_FALLBACK_RESOLUTION_DEFAULT 300.0
typedef struct _cairo_gstate cairo_gstate_t;
@ -1543,6 +1493,10 @@ cairo_private cairo_status_t
_cairo_path_fixed_init_copy (cairo_path_fixed_t *path,
cairo_path_fixed_t *other);
cairo_private cairo_bool_t
_cairo_path_fixed_is_equal (cairo_path_fixed_t *path,
cairo_path_fixed_t *other);
cairo_private cairo_path_fixed_t *
_cairo_path_fixed_create (void);
@ -1748,6 +1702,11 @@ cairo_private void
_cairo_surface_set_error (cairo_surface_t *surface,
cairo_status_t status);
cairo_private void
_cairo_surface_set_resolution (cairo_surface_t *surface,
double x_res,
double y_res);
cairo_private cairo_surface_t *
_cairo_surface_create_similar_scratch (cairo_surface_t *other,
cairo_content_t content,
@ -1824,6 +1783,22 @@ _cairo_surface_mask (cairo_surface_t *surface,
cairo_pattern_t *source,
cairo_pattern_t *mask);
cairo_private cairo_status_t
_cairo_surface_fill_stroke (cairo_surface_t *surface,
cairo_operator_t fill_op,
cairo_pattern_t *fill_source,
cairo_fill_rule_t fill_rule,
double fill_tolerance,
cairo_antialias_t fill_antialias,
cairo_path_fixed_t *path,
cairo_operator_t stroke_op,
cairo_pattern_t *stroke_source,
cairo_stroke_style_t *stroke_style,
cairo_matrix_t *stroke_ctm,
cairo_matrix_t *stroke_ctm_inverse,
double stroke_tolerance,
cairo_antialias_t stroke_antialias);
cairo_private cairo_status_t
_cairo_surface_stroke (cairo_surface_t *surface,
cairo_operator_t op,
@ -1866,12 +1841,6 @@ _cairo_surface_composite_trapezoids (cairo_operator_t op,
cairo_trapezoid_t *traps,
int ntraps);
cairo_private cairo_status_t
_cairo_surface_copy_page (cairo_surface_t *surface);
cairo_private cairo_status_t
_cairo_surface_show_page (cairo_surface_t *surface);
cairo_private cairo_status_t
_cairo_surface_acquire_source_image (cairo_surface_t *surface,
cairo_image_surface_t **image_out,
@ -2034,6 +2003,7 @@ _cairo_surface_has_device_transform (cairo_surface_t *surface);
* to support it (at least cairo_surface_write_to_png and a few spots
* in cairo-xlib-surface.c--again see -Wswitch-enum).
*/
#define CAIRO_FORMAT_INVALID ((unsigned int) -1)
#define CAIRO_FORMAT_VALID(format) ((format) <= CAIRO_FORMAT_A1)
#define CAIRO_CONTENT_VALID(content) ((content) && \
@ -2049,8 +2019,25 @@ cairo_private cairo_content_t
_cairo_content_from_format (cairo_format_t format);
cairo_private cairo_surface_t *
_cairo_image_surface_create_for_pixman_image (pixman_image_t *pixman_image,
cairo_format_t format);
_cairo_image_surface_create_for_pixman_image (pixman_image_t *pixman_image,
pixman_format_code_t pixman_format);
cairo_private pixman_format_code_t
_pixman_format_from_masks (cairo_format_masks_t *masks);
void
_pixman_format_to_masks (pixman_format_code_t pixman_format,
uint32_t *bpp,
uint32_t *red,
uint32_t *green,
uint32_t *blue);
cairo_private cairo_surface_t *
_cairo_image_surface_create_with_pixman_format (unsigned char *data,
pixman_format_code_t pixman_format,
int width,
int height,
int stride);
cairo_private cairo_surface_t *
_cairo_image_surface_create_with_masks (unsigned char *data,
@ -2123,12 +2110,12 @@ _cairo_pen_add_points_for_slopes (cairo_pen_t *pen,
cairo_point_t *c,
cairo_point_t *d);
cairo_private cairo_status_t
cairo_private void
_cairo_pen_find_active_cw_vertex_index (cairo_pen_t *pen,
cairo_slope_t *slope,
int *active);
cairo_private cairo_status_t
cairo_private void
_cairo_pen_find_active_ccw_vertex_index (cairo_pen_t *pen,
cairo_slope_t *slope,
int *active);
@ -2475,6 +2462,8 @@ slim_hidden_proto (cairo_surface_mark_dirty_rectangle);
slim_hidden_proto_no_warn (cairo_surface_reference);
slim_hidden_proto (cairo_surface_set_device_offset);
slim_hidden_proto (cairo_surface_set_fallback_resolution);
slim_hidden_proto (cairo_surface_copy_page);
slim_hidden_proto (cairo_surface_show_page);
slim_hidden_proto (cairo_surface_status);
slim_hidden_proto (cairo_version_string);
@ -2486,4 +2475,9 @@ slim_hidden_proto (cairo_surface_write_to_png_stream);
CAIRO_END_DECLS
#include "cairo-mutex-private.h"
#include "cairo-wideint-private.h"
#include "cairo-malloc-private.h"
#include "cairo-hash-private.h"
#endif

Просмотреть файл

@ -16,5 +16,4 @@ BEGIN { state = "public"; }
# catch some one-off things
END {
print "#define _cairo_image_surface_nil_invalid_format __moz__cairo_image_surface_nil_invalid_format";
}

Просмотреть файл

@ -1,150 +0,0 @@
Index: gfx/cairo/cairo/src/cairo-analysis-surface-private.h
===================================================================
RCS file: /cvsroot/mozilla/gfx/cairo/cairo/src/cairo-analysis-surface-private.h,v
retrieving revision 1.11
diff -u -8 -p -r1.11 cairo-analysis-surface-private.h
--- gfx/cairo/cairo/src/cairo-analysis-surface-private.h 2 Aug 2007 06:58:47 -0000 1.11
+++ gfx/cairo/cairo/src/cairo-analysis-surface-private.h 7 Aug 2007 22:50:37 -0000
@@ -1,9 +1,9 @@
-/* $Id: clone-similar-fallback.patch,v 1.1 2007-08-09 18:54:17 vladimir%pobox.com Exp $
+/* $Id: clone-similar-fallback.patch,v 1.1 2007-08-09 18:54:17 vladimir%pobox.com Exp $
*
* Copyright © 2005 Keith Packard
*
* 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
Index: gfx/cairo/cairo/src/cairo-surface-fallback-private.h
===================================================================
RCS file: /cvsroot/mozilla/gfx/cairo/cairo/src/cairo-surface-fallback-private.h,v
retrieving revision 1.7
diff -u -8 -p -r1.7 cairo-surface-fallback-private.h
--- gfx/cairo/cairo/src/cairo-surface-fallback-private.h 2 Aug 2007 06:58:47 -0000 1.7
+++ gfx/cairo/cairo/src/cairo-surface-fallback-private.h 7 Aug 2007 22:50:37 -0000
@@ -1,8 +1,9 @@
+/* -*- Mode: c; tab-width: 8; c-basic-offset: 4; indent-tabs-mode: t; -*- */
/* 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
@@ -111,9 +112,18 @@ _cairo_surface_fallback_composite_trapez
int src_y,
int dst_x,
int dst_y,
unsigned int width,
unsigned int height,
cairo_trapezoid_t *traps,
int num_traps);
+cairo_private cairo_status_t
+_cairo_surface_fallback_clone_similar (cairo_surface_t *surface,
+ cairo_surface_t *src,
+ int src_x,
+ int src_y,
+ int width,
+ int height,
+ cairo_surface_t **clone_out);
+
#endif
Index: gfx/cairo/cairo/src/cairo-surface-fallback.c
===================================================================
RCS file: /cvsroot/mozilla/gfx/cairo/cairo/src/cairo-surface-fallback.c,v
retrieving revision 1.18
diff -u -8 -p -r1.18 cairo-surface-fallback.c
--- gfx/cairo/cairo/src/cairo-surface-fallback.c 2 Aug 2007 06:58:47 -0000 1.18
+++ gfx/cairo/cairo/src/cairo-surface-fallback.c 7 Aug 2007 22:50:37 -0000
@@ -1,8 +1,9 @@
+/* -*- Mode: c; tab-width: 8; c-basic-offset: 4; indent-tabs-mode: t; -*- */
/* 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
@@ -1247,8 +1248,48 @@ _cairo_surface_fallback_composite_trapez
if (offset_traps)
free (offset_traps);
DONE:
_fallback_fini (&state);
return status;
}
+
+cairo_status_t
+_cairo_surface_fallback_clone_similar (cairo_surface_t *surface,
+ cairo_surface_t *src,
+ int src_x,
+ int src_y,
+ int width,
+ int height,
+ cairo_surface_t **clone_out)
+{
+ cairo_status_t status;
+ cairo_pattern_union_t src_pattern;
+ cairo_surface_t *new_surface = NULL;
+
+ new_surface = _cairo_surface_create_similar_scratch (surface,
+ cairo_surface_get_content (src),
+ width, height);
+ if (new_surface->status)
+ return new_surface->status;
+
+ _cairo_pattern_init_for_surface (&src_pattern.surface, src);
+
+ status = _cairo_surface_composite (CAIRO_OPERATOR_SOURCE,
+ &src_pattern.base,
+ NULL,
+ new_surface,
+ src_x, src_y,
+ 0, 0,
+ 0, 0,
+ width, height);
+
+ _cairo_pattern_fini (&src_pattern.base);
+
+ if (status == CAIRO_STATUS_SUCCESS)
+ *clone_out = new_surface;
+ else if (new_surface)
+ cairo_surface_destroy (new_surface);
+
+ return status;
+}
Index: gfx/cairo/cairo/src/cairo-surface.c
===================================================================
RCS file: /cvsroot/mozilla/gfx/cairo/cairo/src/cairo-surface.c,v
retrieving revision 1.27
diff -u -8 -p -r1.27 cairo-surface.c
--- gfx/cairo/cairo/src/cairo-surface.c 2 Aug 2007 06:58:47 -0000 1.27
+++ gfx/cairo/cairo/src/cairo-surface.c 7 Aug 2007 22:50:37 -0000
@@ -1027,17 +1027,21 @@ _cairo_surface_clone_similar (cairo_surf
cairo_status_t status;
cairo_image_surface_t *image;
void *image_extra;
if (surface->finished)
return CAIRO_STATUS_SURFACE_FINISHED;
if (surface->backend->clone_similar == NULL)
- return CAIRO_INT_STATUS_UNSUPPORTED;
+ return (cairo_int_status_t)
+ _cairo_surface_fallback_clone_similar (surface, src,
+ src_x, src_y,
+ width, height,
+ clone_out);
status = surface->backend->clone_similar (surface, src, src_x, src_y,
width, height, clone_out);
if (status == CAIRO_STATUS_SUCCESS && *clone_out != src)
(*clone_out)->device_transform = src->device_transform;
if (status != CAIRO_INT_STATUS_UNSUPPORTED)
return status;

Просмотреть файл

@ -64,11 +64,11 @@ endif
endif
CSRCS = \
pixman-compose.c \
pixman-compose-accessors.c \
pixman-compose-noaccessors.c \
pixman-compute-region.c \
pixman-edge.c \
pixman-edge-accessors.c \
pixman-edge-noaccessors.c \
pixman-image.c \
pixman-pict.c \
pixman-region.c \

Просмотреть файл

@ -23,7 +23,7 @@
* SOFTWARE.
*/
#if HAVE_CONFIG_H
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
@ -136,7 +136,7 @@ fbFetch_x8r8g8b8 (pixman_image_t *image,
const uint32_t *pixel = (const uint32_t *)bits + x;
const uint32_t *end = pixel + width;
while (pixel < end) {
WRITE(buffer++, READ(pixel++) | 0xff000000);
*buffer++ = READ(pixel++) | 0xff000000;
}
}
@ -147,10 +147,10 @@ fbFetch_a8b8g8r8 (pixman_image_t *image,
const uint32_t *pixel = (uint32_t *)bits + x;
const uint32_t *end = pixel + width;
while (pixel < end) {
WRITE(buffer++, ((READ(pixel) & 0xff00ff00) |
((READ(pixel) >> 16) & 0xff) |
((READ(pixel) & 0xff) << 16)));
++pixel;
uint32_t p = READ(pixel++);
*buffer++ = (p & 0xff00ff00) |
((p >> 16) & 0xff) |
((p & 0xff) << 16);
}
}
@ -161,11 +161,11 @@ fbFetch_x8b8g8r8 (pixman_image_t *image,
const uint32_t *pixel = (uint32_t *)bits + x;
const uint32_t *end = pixel + width;
while (pixel < end) {
WRITE(buffer++, 0xff000000 |
((READ(pixel) & 0x0000ff00) |
((READ(pixel) >> 16) & 0xff) |
((READ(pixel) & 0xff) << 16)));
++pixel;
uint32_t p = READ(pixel++);
*buffer++ = 0xff000000 |
(p & 0x0000ff00) |
((p >> 16) & 0xff) |
((p & 0xff) << 16);
}
}
@ -178,7 +178,7 @@ fbFetch_r8g8b8 (pixman_image_t *image,
while (pixel < end) {
uint32_t b = Fetch24(pixel) | 0xff000000;
pixel += 3;
WRITE(buffer++, b);
*buffer++ = b;
}
}
@ -199,7 +199,7 @@ fbFetch_b8g8r8 (pixman_image_t *image,
b |= (READ(pixel++) << 8);
b |= (READ(pixel++));
#endif
WRITE(buffer++, b);
*buffer++ = b;
}
}
@ -211,13 +211,13 @@ fbFetch_r5g6b5 (pixman_image_t *image,
const uint16_t *pixel = (const uint16_t *)bits + x;
const uint16_t *end = pixel + width;
while (pixel < end) {
uint32_t p = READ(pixel++);
uint32_t p = READ(pixel++);
uint32_t r = (((p) << 3) & 0xf8) |
(((p) << 5) & 0xfc00) |
(((p) << 8) & 0xf80000);
r |= (r >> 5) & 0x70007;
r |= (r >> 6) & 0x300;
WRITE(buffer++, 0xff000000 | r);
*buffer++ = 0xff000000 | r;
}
}
@ -235,7 +235,7 @@ fbFetch_b5g6r5 (pixman_image_t *image,
b = ((p & 0xf800) | ((p & 0xe000) >> 5)) >> 8;
g = ((p & 0x07e0) | ((p & 0x0600) >> 6)) << 5;
r = ((p & 0x001c) | ((p & 0x001f) << 5)) << 14;
WRITE(buffer++, (0xff000000 | r | g | b));
*buffer++ = 0xff000000 | r | g | b;
}
}
@ -254,7 +254,7 @@ fbFetch_a1r5g5b5 (pixman_image_t *image,
r = ((p & 0x7c00) | ((p & 0x7000) >> 5)) << 9;
g = ((p & 0x03e0) | ((p & 0x0380) >> 5)) << 6;
b = ((p & 0x001c) | ((p & 0x001f) << 5)) >> 2;
WRITE(buffer++, (a | r | g | b));
*buffer++ = a | r | g | b;
}
}
@ -272,7 +272,7 @@ fbFetch_x1r5g5b5 (pixman_image_t *image,
r = ((p & 0x7c00) | ((p & 0x7000) >> 5)) << 9;
g = ((p & 0x03e0) | ((p & 0x0380) >> 5)) << 6;
b = ((p & 0x001c) | ((p & 0x001f) << 5)) >> 2;
WRITE(buffer++, (0xff000000 | r | g | b));
*buffer++ = 0xff000000 | r | g | b;
}
}
@ -291,7 +291,7 @@ fbFetch_a1b5g5r5 (pixman_image_t *image,
b = ((p & 0x7c00) | ((p & 0x7000) >> 5)) >> 7;
g = ((p & 0x03e0) | ((p & 0x0380) >> 5)) << 6;
r = ((p & 0x001c) | ((p & 0x001f) << 5)) << 14;
WRITE(buffer++, (a | r | g | b));
*buffer++ = a | r | g | b;
}
}
@ -309,7 +309,7 @@ fbFetch_x1b5g5r5 (pixman_image_t *image,
b = ((p & 0x7c00) | ((p & 0x7000) >> 5)) >> 7;
g = ((p & 0x03e0) | ((p & 0x0380) >> 5)) << 6;
r = ((p & 0x001c) | ((p & 0x001f) << 5)) << 14;
WRITE(buffer++, (0xff000000 | r | g | b));
*buffer++ = 0xff000000 | r | g | b;
}
}
@ -327,7 +327,7 @@ fbFetch_a4r4g4b4 (pixman_image_t *image,
r = ((p & 0x0f00) | ((p & 0x0f00) >> 4)) << 12;
g = ((p & 0x00f0) | ((p & 0x00f0) >> 4)) << 8;
b = ((p & 0x000f) | ((p & 0x000f) << 4));
WRITE(buffer++, (a | r | g | b));
*buffer++ = a | r | g | b;
}
}
@ -345,7 +345,7 @@ fbFetch_x4r4g4b4 (pixman_image_t *image,
r = ((p & 0x0f00) | ((p & 0x0f00) >> 4)) << 12;
g = ((p & 0x00f0) | ((p & 0x00f0) >> 4)) << 8;
b = ((p & 0x000f) | ((p & 0x000f) << 4));
WRITE(buffer++, (0xff000000 | r | g | b));
*buffer++ = 0xff000000 | r | g | b;
}
}
@ -364,7 +364,7 @@ fbFetch_a4b4g4r4 (pixman_image_t *image,
b = ((p & 0x0f00) | ((p & 0x0f00) >> 4)) >> 4;
g = ((p & 0x00f0) | ((p & 0x00f0) >> 4)) << 8;
r = ((p & 0x000f) | ((p & 0x000f) << 4)) << 16;
WRITE(buffer++, (a | r | g | b));
*buffer++ = a | r | g | b;
}
}
@ -382,7 +382,7 @@ fbFetch_x4b4g4r4 (pixman_image_t *image,
b = ((p & 0x0f00) | ((p & 0x0f00) >> 4)) >> 4;
g = ((p & 0x00f0) | ((p & 0x00f0) >> 4)) << 8;
r = ((p & 0x000f) | ((p & 0x000f) << 4)) << 16;
WRITE(buffer++, (0xff000000 | r | g | b));
*buffer++ = 0xff000000 | r | g | b;
}
}
@ -393,7 +393,7 @@ fbFetch_a8 (pixman_image_t *image,
const uint8_t *pixel = (const uint8_t *)bits + x;
const uint8_t *end = pixel + width;
while (pixel < end) {
WRITE(buffer++, READ(pixel++) << 24);
*buffer++ = READ(pixel++) << 24;
}
}
@ -414,7 +414,7 @@ fbFetch_r3g3b2 (pixman_image_t *image,
((p & 0x03) << 2) |
((p & 0x03) << 4) |
((p & 0x03) << 6));
WRITE(buffer++, (0xff000000 | r | g | b));
*buffer++ = 0xff000000 | r | g | b;
}
}
@ -437,7 +437,7 @@ fbFetch_b2g3r3 (pixman_image_t *image,
r = (((p & 0x07) ) |
((p & 0x07) << 3) |
((p & 0x06) << 6)) << 16;
WRITE(buffer++, (0xff000000 | r | g | b));
*buffer++ = 0xff000000 | r | g | b;
}
}
@ -455,7 +455,7 @@ fbFetch_a2r2g2b2 (pixman_image_t *image,
r = ((p & 0x30) * 0x55) << 12;
g = ((p & 0x0c) * 0x55) << 6;
b = ((p & 0x03) * 0x55);
WRITE(buffer++, a|r|g|b);
*buffer++ = a|r|g|b;
}
}
@ -473,7 +473,7 @@ fbFetch_a2b2g2r2 (pixman_image_t *image,
b = ((p & 0x30) * 0x55) >> 6;
g = ((p & 0x0c) * 0x55) << 6;
r = ((p & 0x03) * 0x55) << 16;
WRITE(buffer++, a|r|g|b);
*buffer++ = a|r|g|b;
}
}
@ -485,7 +485,7 @@ fbFetch_c8 (pixman_image_t *image,
const uint8_t *end = pixel + width;
while (pixel < end) {
uint32_t p = READ(pixel++);
WRITE(buffer++, indexed->rgba[p]);
*buffer++ = indexed->rgba[p];
}
}
@ -497,11 +497,11 @@ fbFetch_x4a4 (pixman_image_t *image,
const uint8_t *end = pixel + width;
while (pixel < end) {
uint8_t p = READ(pixel++) & 0xf;
WRITE(buffer++, (p | (p << 4)) << 24);
*buffer++ = (p | (p << 4)) << 24;
}
}
#define Fetch8(l,o) (((uint8_t *) (l))[(o) >> 2])
#define Fetch8(l,o) (READ((uint8_t *)(l) + ((o) >> 2)))
#if IMAGE_BYTE_ORDER == MSBFirst
#define Fetch4(l,o) ((o) & 2 ? Fetch8(l,o) & 0xf : Fetch8(l,o) >> 4)
#else
@ -517,7 +517,7 @@ fbFetch_a4 (pixman_image_t *image,
uint32_t p = Fetch4(bits, i + x);
p |= p << 4;
WRITE(buffer++, p << 24);
*buffer++ = p << 24;
}
}
@ -533,7 +533,7 @@ fbFetch_r1g2b1 (pixman_image_t *image,
r = ((p & 0x8) * 0xff) << 13;
g = ((p & 0x6) * 0x55) << 7;
b = ((p & 0x1) * 0xff);
WRITE(buffer++, 0xff000000|r|g|b);
*buffer++ = 0xff000000|r|g|b;
}
}
@ -549,7 +549,7 @@ fbFetch_b1g2r1 (pixman_image_t *image,
b = ((p & 0x8) * 0xff) >> 3;
g = ((p & 0x6) * 0x55) << 7;
r = ((p & 0x1) * 0xff) << 16;
WRITE(buffer++, 0xff000000|r|g|b);
*buffer++ = 0xff000000|r|g|b;
}
}
@ -566,7 +566,7 @@ fbFetch_a1r1g1b1 (pixman_image_t *image,
r = ((p & 0x4) * 0xff) << 14;
g = ((p & 0x2) * 0xff) << 7;
b = ((p & 0x1) * 0xff);
WRITE(buffer++, a|r|g|b);
*buffer++ = a|r|g|b;
}
}
@ -583,7 +583,7 @@ fbFetch_a1b1g1r1 (pixman_image_t *image,
r = ((p & 0x4) * 0xff) >> 3;
g = ((p & 0x2) * 0xff) << 7;
b = ((p & 0x1) * 0xff) << 16;
WRITE(buffer++, a|r|g|b);
*buffer++ = a|r|g|b;
}
}
@ -595,7 +595,7 @@ fbFetch_c4 (pixman_image_t *image,
for (i = 0; i < width; ++i) {
uint32_t p = Fetch4(bits, i + x);
WRITE(buffer++, indexed->rgba[p]);
*buffer++ = indexed->rgba[p];
}
}
@ -606,7 +606,7 @@ fbFetch_a1 (pixman_image_t *image,
{
int i;
for (i = 0; i < width; ++i) {
uint32_t p = ((uint32_t *)bits)[(i + x) >> 5];
uint32_t p = READ(bits + ((i + x) >> 5));
uint32_t a;
#if BITMAP_BIT_ORDER == MSBFirst
a = p >> (0x1f - ((i+x) & 0x1f));
@ -617,7 +617,7 @@ fbFetch_a1 (pixman_image_t *image,
a |= a << 1;
a |= a << 2;
a |= a << 4;
WRITE(buffer++, a << 24);
*buffer++ = a << 24;
}
}
@ -627,7 +627,7 @@ fbFetch_g1 (pixman_image_t *image,
{
int i;
for (i = 0; i < width; ++i) {
uint32_t p = ((uint32_t *)bits)[(i+x) >> 5];
uint32_t p = READ(bits + ((i+x) >> 5));
uint32_t a;
#if BITMAP_BIT_ORDER == MSBFirst
a = p >> (0x1f - ((i+x) & 0x1f));
@ -635,7 +635,7 @@ fbFetch_g1 (pixman_image_t *image,
a = p >> ((i+x) & 0x1f);
#endif
a = a & 1;
WRITE(buffer++, indexed->rgba[a]);
*buffer++ = indexed->rgba[a];
}
}
@ -995,13 +995,6 @@ fbFetchPixel_x4a4 (pixman_image_t *image,
return ((pixel & 0xf) | ((pixel & 0xf) << 4)) << 24;
}
#define Fetch8(l,o) (((uint8_t *) (l))[(o) >> 2])
#if IMAGE_BYTE_ORDER == MSBFirst
#define Fetch4(l,o) ((o) & 2 ? Fetch8(l,o) & 0xf : Fetch8(l,o) >> 4)
#else
#define Fetch4(l,o) ((o) & 2 ? Fetch8(l,o) >> 4 : Fetch8(l,o) & 0xf)
#endif
static FASTCALL uint32_t
fbFetchPixel_a4 (pixman_image_t *image,
const uint32_t *bits, int offset, const pixman_indexed_t * indexed)
@ -1080,7 +1073,7 @@ static FASTCALL uint32_t
fbFetchPixel_a1 (pixman_image_t *image,
const uint32_t *bits, int offset, const pixman_indexed_t * indexed)
{
uint32_t pixel = ((uint32_t *)bits)[offset >> 5];
uint32_t pixel = READ(bits + (offset >> 5));
uint32_t a;
#if BITMAP_BIT_ORDER == MSBFirst
a = pixel >> (0x1f - (offset & 0x1f));
@ -1098,7 +1091,7 @@ static FASTCALL uint32_t
fbFetchPixel_g1 (pixman_image_t *image,
const uint32_t *bits, int offset, const pixman_indexed_t * indexed)
{
uint32_t pixel = ((uint32_t *)bits)[offset >> 5];
uint32_t pixel = READ(bits + (offset >> 5));
uint32_t a;
#if BITMAP_BIT_ORDER == MSBFirst
a = pixel >> (0x1f - (offset & 0x1f));
@ -1187,7 +1180,7 @@ fbStore_x8r8g8b8 (pixman_image_t *image,
int i;
uint32_t *pixel = (uint32_t *)bits + x;
for (i = 0; i < width; ++i)
WRITE(pixel++, READ(values + i) & 0xffffff);
WRITE(pixel++, values[i] & 0xffffff);
}
static FASTCALL void
@ -1197,7 +1190,7 @@ fbStore_a8b8g8r8 (pixman_image_t *image,
int i;
uint32_t *pixel = (uint32_t *)bits + x;
for (i = 0; i < width; ++i)
WRITE(pixel++, (READ(values + i) & 0xff00ff00) | ((READ(values + i) >> 16) & 0xff) | ((READ(values + i) & 0xff) << 16));
WRITE(pixel++, (values[i] & 0xff00ff00) | ((values[i] >> 16) & 0xff) | ((values[i] & 0xff) << 16));
}
static FASTCALL void
@ -1207,7 +1200,7 @@ fbStore_x8b8g8r8 (pixman_image_t *image,
int i;
uint32_t *pixel = (uint32_t *)bits + x;
for (i = 0; i < width; ++i)
WRITE(pixel++, (READ(values + i) & 0x0000ff00) | ((READ(values + i) >> 16) & 0xff) | ((READ(values + i) & 0xff) << 16));
WRITE(pixel++, (values[i] & 0x0000ff00) | ((values[i] >> 16) & 0xff) | ((values[i] & 0xff) << 16));
}
static FASTCALL void
@ -1218,7 +1211,7 @@ fbStore_r8g8b8 (pixman_image_t *image,
int i;
uint8_t *pixel = ((uint8_t *) bits) + 3*x;
for (i = 0; i < width; ++i) {
Store24(pixel, READ(values + i));
Store24(pixel, values[i]);
pixel += 3;
}
}
@ -1230,7 +1223,7 @@ fbStore_b8g8r8 (pixman_image_t *image,
int i;
uint8_t *pixel = ((uint8_t *) bits) + 3*x;
for (i = 0; i < width; ++i) {
uint32_t val = READ(values + i);
uint32_t val = values[i];
#if IMAGE_BYTE_ORDER == MSBFirst
WRITE(pixel++, Blue(val));
WRITE(pixel++, Green(val));
@ -1250,7 +1243,7 @@ fbStore_r5g6b5 (pixman_image_t *image,
int i;
uint16_t *pixel = ((uint16_t *) bits) + x;
for (i = 0; i < width; ++i) {
uint32_t s = READ(values + i);
uint32_t s = values[i];
WRITE(pixel++, ((s >> 3) & 0x001f) |
((s >> 5) & 0x07e0) |
((s >> 8) & 0xf800));
@ -1264,7 +1257,7 @@ fbStore_b5g6r5 (pixman_image_t *image,
int i;
uint16_t *pixel = ((uint16_t *) bits) + x;
for (i = 0; i < width; ++i) {
Split(READ(values + i));
Split(values[i]);
WRITE(pixel++, ((b << 8) & 0xf800) |
((g << 3) & 0x07e0) |
((r >> 3) ));
@ -1278,7 +1271,7 @@ fbStore_a1r5g5b5 (pixman_image_t *image,
int i;
uint16_t *pixel = ((uint16_t *) bits) + x;
for (i = 0; i < width; ++i) {
Splita(READ(values + i));
Splita(values[i]);
WRITE(pixel++, ((a << 8) & 0x8000) |
((r << 7) & 0x7c00) |
((g << 2) & 0x03e0) |
@ -1293,7 +1286,7 @@ fbStore_x1r5g5b5 (pixman_image_t *image,
int i;
uint16_t *pixel = ((uint16_t *) bits) + x;
for (i = 0; i < width; ++i) {
Split(READ(values + i));
Split(values[i]);
WRITE(pixel++, ((r << 7) & 0x7c00) |
((g << 2) & 0x03e0) |
((b >> 3) ));
@ -1307,7 +1300,7 @@ fbStore_a1b5g5r5 (pixman_image_t *image,
int i;
uint16_t *pixel = ((uint16_t *) bits) + x;
for (i = 0; i < width; ++i) {
Splita(READ(values + i));
Splita(values[i]);
WRITE(pixel++, ((a << 8) & 0x8000) |
((b << 7) & 0x7c00) |
((g << 2) & 0x03e0) |
@ -1322,7 +1315,7 @@ fbStore_x1b5g5r5 (pixman_image_t *image,
int i;
uint16_t *pixel = ((uint16_t *) bits) + x;
for (i = 0; i < width; ++i) {
Split(READ(values + i));
Split(values[i]);
WRITE(pixel++, ((b << 7) & 0x7c00) |
((g << 2) & 0x03e0) |
((r >> 3) ));
@ -1336,7 +1329,7 @@ fbStore_a4r4g4b4 (pixman_image_t *image,
int i;
uint16_t *pixel = ((uint16_t *) bits) + x;
for (i = 0; i < width; ++i) {
Splita(READ(values + i));
Splita(values[i]);
WRITE(pixel++, ((a << 8) & 0xf000) |
((r << 4) & 0x0f00) |
((g ) & 0x00f0) |
@ -1351,7 +1344,7 @@ fbStore_x4r4g4b4 (pixman_image_t *image,
int i;
uint16_t *pixel = ((uint16_t *) bits) + x;
for (i = 0; i < width; ++i) {
Split(READ(values + i));
Split(values[i]);
WRITE(pixel++, ((r << 4) & 0x0f00) |
((g ) & 0x00f0) |
((b >> 4) ));
@ -1365,7 +1358,7 @@ fbStore_a4b4g4r4 (pixman_image_t *image,
int i;
uint16_t *pixel = ((uint16_t *) bits) + x;
for (i = 0; i < width; ++i) {
Splita(READ(values + i));
Splita(values[i]);
WRITE(pixel++, ((a << 8) & 0xf000) |
((b << 4) & 0x0f00) |
((g ) & 0x00f0) |
@ -1380,7 +1373,7 @@ fbStore_x4b4g4r4 (pixman_image_t *image,
int i;
uint16_t *pixel = ((uint16_t *) bits) + x;
for (i = 0; i < width; ++i) {
Split(READ(values + i));
Split(values[i]);
WRITE(pixel++, ((b << 4) & 0x0f00) |
((g ) & 0x00f0) |
((r >> 4) ));
@ -1394,7 +1387,7 @@ fbStore_a8 (pixman_image_t *image,
int i;
uint8_t *pixel = ((uint8_t *) bits) + x;
for (i = 0; i < width; ++i) {
WRITE(pixel++, READ(values + i) >> 24);
WRITE(pixel++, values[i] >> 24);
}
}
@ -1405,7 +1398,7 @@ fbStore_r3g3b2 (pixman_image_t *image,
int i;
uint8_t *pixel = ((uint8_t *) bits) + x;
for (i = 0; i < width; ++i) {
Split(READ(values + i));
Split(values[i]);
WRITE(pixel++,
((r ) & 0xe0) |
((g >> 3) & 0x1c) |
@ -1420,7 +1413,7 @@ fbStore_b2g3r3 (pixman_image_t *image,
int i;
uint8_t *pixel = ((uint8_t *) bits) + x;
for (i = 0; i < width; ++i) {
Split(READ(values + i));
Split(values[i]);
WRITE(pixel++,
((b ) & 0xc0) |
((g >> 2) & 0x1c) |
@ -1435,7 +1428,7 @@ fbStore_a2r2g2b2 (pixman_image_t *image,
int i;
uint8_t *pixel = ((uint8_t *) bits) + x;
for (i = 0; i < width; ++i) {
Splita(READ(values + i));
Splita(values[i]);
WRITE(pixel++, ((a ) & 0xc0) |
((r >> 2) & 0x30) |
((g >> 4) & 0x0c) |
@ -1450,7 +1443,7 @@ fbStore_c8 (pixman_image_t *image,
int i;
uint8_t *pixel = ((uint8_t *) bits) + x;
for (i = 0; i < width; ++i) {
WRITE(pixel++, miIndexToEnt24(indexed,READ(values + i)));
WRITE(pixel++, miIndexToEnt24(indexed,values[i]));
}
}
@ -1461,11 +1454,11 @@ fbStore_x4a4 (pixman_image_t *image,
int i;
uint8_t *pixel = ((uint8_t *) bits) + x;
for (i = 0; i < width; ++i) {
WRITE(pixel++, READ(values + i) >> 28);
WRITE(pixel++, values[i] >> 28);
}
}
#define Store8(l,o,v) (((uint8_t *) l)[(o) >> 3] = (v))
#define Store8(l,o,v) (WRITE((uint8_t *)(l) + ((o) >> 3), (v)))
#if IMAGE_BYTE_ORDER == MSBFirst
#define Store4(l,o,v) Store8(l,o,((o) & 4 ? \
(Fetch8(l,o) & 0xf0) | (v) : \
@ -1482,7 +1475,7 @@ fbStore_a4 (pixman_image_t *image,
{
int i;
for (i = 0; i < width; ++i) {
Store4(bits, i + x, READ(values + i)>>28);
Store4(bits, i + x, values[i]>>28);
}
}
@ -1494,7 +1487,7 @@ fbStore_r1g2b1 (pixman_image_t *image,
for (i = 0; i < width; ++i) {
uint32_t pixel;
Split(READ(values + i));
Split(values[i]);
pixel = (((r >> 4) & 0x8) |
((g >> 5) & 0x6) |
((b >> 7) ));
@ -1510,7 +1503,7 @@ fbStore_b1g2r1 (pixman_image_t *image,
for (i = 0; i < width; ++i) {
uint32_t pixel;
Split(READ(values + i));
Split(values[i]);
pixel = (((b >> 4) & 0x8) |
((g >> 5) & 0x6) |
((r >> 7) ));
@ -1525,7 +1518,7 @@ fbStore_a1r1g1b1 (pixman_image_t *image,
int i;
for (i = 0; i < width; ++i) {
uint32_t pixel;
Splita(READ(values + i));
Splita(values[i]);
pixel = (((a >> 4) & 0x8) |
((r >> 5) & 0x4) |
((g >> 6) & 0x2) |
@ -1541,7 +1534,7 @@ fbStore_a1b1g1r1 (pixman_image_t *image,
int i;
for (i = 0; i < width; ++i) {
uint32_t pixel;
Splita(READ(values + i));
Splita(values[i]);
pixel = (((a >> 4) & 0x8) |
((b >> 5) & 0x4) |
((g >> 6) & 0x2) |
@ -1558,7 +1551,7 @@ fbStore_c4 (pixman_image_t *image,
for (i = 0; i < width; ++i) {
uint32_t pixel;
pixel = miIndexToEnt24(indexed, READ(values + i));
pixel = miIndexToEnt24(indexed, values[i]);
Store4(bits, i + x, pixel);
}
}
@ -1572,7 +1565,7 @@ fbStore_a1 (pixman_image_t *image,
uint32_t *pixel = ((uint32_t *) bits) + ((i+x) >> 5);
uint32_t mask = FbStipMask((i+x) & 0x1f, 1);
uint32_t v = READ(values + i) & 0x80000000 ? mask : 0;
uint32_t v = values[i] & 0x80000000 ? mask : 0;
WRITE(pixel, (READ(pixel) & ~mask) | v);
}
}
@ -1586,7 +1579,7 @@ fbStore_g1 (pixman_image_t *image,
uint32_t *pixel = ((uint32_t *) bits) + ((i+x) >> 5);
uint32_t mask = FbStipMask((i+x) & 0x1f, 1);
uint32_t v = miIndexToEntY24(indexed,READ(values + i)) ? mask : 0;
uint32_t v = miIndexToEntY24(indexed,values[i]) ? mask : 0;
WRITE(pixel, (READ(pixel) & ~mask) | v);
}
}
@ -3303,10 +3296,10 @@ static void pixmanFetchSourcePict(source_image_t * pict, int x, int y, int width
* · r
* p ·
* θ
*
*
* r · c
* θ ·
*
*
* c
*
* Given (c,r), (c,r) and p, we must find an angle θ such that two
@ -3354,7 +3347,7 @@ static void pixmanFetchSourcePict(source_image_t * pict, int x, int y, int width
* c
* r ·
* · cdy
*
*
* c pdx cdx
*
* cdx = (cx - cx)
@ -3393,7 +3386,7 @@ static void pixmanFetchSourcePict(source_image_t * pict, int x, int y, int width
* precomputed. From here we just use the quadratic formula to solve
* for t:
*
* t = (-2·B ± (B² - 4·A·C)) / 2·A
* t = (-2·B ± (B² - 4·A·C)) / 2·A
*/
/* radial or conical */
pixman_bool_t affine = TRUE;
@ -4259,6 +4252,7 @@ PIXMAN_COMPOSITE_RECT_GENERAL (const FbComposeData *data,
case PIXMAN_OP_CLEAR:
case PIXMAN_OP_SRC:
fetchDest = NULL;
#ifndef PIXMAN_FB_ACCESSORS
/* fall-through */
case PIXMAN_OP_ADD:
case PIXMAN_OP_OVER:
@ -4270,6 +4264,7 @@ PIXMAN_COMPOSITE_RECT_GENERAL (const FbComposeData *data,
default:
break;
}
#endif
break;
}
}

Просмотреть файл

@ -21,7 +21,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
#if HAVE_CONFIG_H
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif

Просмотреть файл

@ -1,4 +1,5 @@
/*
* $Id: pixman-edge-imp.h,v 1.7 2007-09-20 19:24:51 vladimir%pobox.com Exp $
*
* Copyright © 2004 Keith Packard
*

Просмотреть файл

@ -1,4 +1,5 @@
/*
* $Id: pixman-edge.c,v 1.9 2007-09-20 19:24:51 vladimir%pobox.com Exp $
*
* Copyright © 2004 Keith Packard
*
@ -21,7 +22,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
#if HAVE_CONFIG_H
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif

Просмотреть файл

@ -20,7 +20,7 @@
* CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#if HAVE_CONFIG_H
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
@ -108,7 +108,8 @@ pixman_image_ref (pixman_image_t *image)
return image;
}
void
/* returns TRUE when the image is freed */
pixman_bool_t
pixman_image_unref (pixman_image_t *image)
{
image_common_t *common = (image_common_t *)image;
@ -148,7 +149,11 @@ pixman_image_unref (pixman_image_t *image)
free (image->bits.free_me);
free (image);
return TRUE;
}
return FALSE;
}
/* Constructors */
@ -400,25 +405,17 @@ pixman_image_set_transform (pixman_image_t *image,
if (memcmp (&id, transform, sizeof (pixman_transform_t)) == 0)
{
free(common->transform);
common->transform = NULL;
return TRUE;
}
if (common->transform)
free (common->transform);
if (transform)
{
if (common->transform == NULL)
common->transform = malloc (sizeof (pixman_transform_t));
if (!common->transform)
return FALSE;
if (common->transform == NULL)
return FALSE;
*common->transform = *transform;
}
else
{
common->transform = NULL;
}
memcpy(common->transform, transform, sizeof(pixman_transform_t));
return TRUE;
}
@ -463,6 +460,18 @@ pixman_image_set_filter (pixman_image_t *image,
return TRUE;
}
void
pixman_image_set_source_clipping (pixman_image_t *image,
pixman_bool_t source_clipping)
{
image_common_t *common = &image->common;
if (source_clipping)
common->src_clip = &common->clip_region;
else
common->src_clip = &common->full_region;
}
/* Unlike all the other property setters, this function does not
* copy the content of indexed. Doing this copying is simply
* way, way too expensive.

Просмотреть файл

@ -1,4 +1,3 @@
/* -*- Mode: c; tab-width: 8; c-basic-offset: 4; indent-tabs-mode: t; -*- */
/*
* Copyright © 2004, 2005 Red Hat, Inc.
* Copyright © 2004 Nicholas Miell
@ -30,7 +29,7 @@
* Based on work by Owen Taylor
*/
#if HAVE_CONFIG_H
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
@ -160,11 +159,6 @@ static const MMXData c =
#define MC(x) c.mmx_##x
#endif
/* cast to void* in the middle to shut gcc up warning about
* "dereferencing type-punned pointers".
*/
#define M64(x) (*(__m64*)(void*)(&(x)))
static inline __m64
shift (__m64 v, int s)
{
@ -1050,9 +1044,9 @@ fbCompositeSolid_nx0565mmx (pixman_op_t op,
while (w && (unsigned long)dst & 7)
{
ullong d = *dst;
__m64 vdest = expand565 (M64(d), 0);
__m64 vdest = expand565 ((__m64)d, 0);
vdest = pack565(over(vsrc, vsrca, vdest), vdest, 0);
*dst = _mm_cvtsi64_si32(vdest);
*dst = (ullong)vdest;
w--;
dst++;
@ -1080,9 +1074,9 @@ fbCompositeSolid_nx0565mmx (pixman_op_t op,
while (w)
{
ullong d = *dst;
__m64 vdest = expand565 (M64(d), 0);
__m64 vdest = expand565 ((__m64)d, 0);
vdest = pack565(over(vsrc, vsrca, vdest), vdest, 0);
*dst = _mm_cvtsi64_si32(vdest);
*dst = (ullong)vdest;
w--;
dst++;
@ -1508,11 +1502,11 @@ fbCompositeSrc_8888x0565mmx (pixman_op_t op,
{
__m64 vsrc = load8888 (*src);
ullong d = *dst;
__m64 vdest = expand565 (M64(d), 0);
__m64 vdest = expand565 ((__m64)d, 0);
vdest = pack565(over(vsrc, expand_alpha(vsrc), vdest), vdest, 0);
*dst = _mm_cvtsi64_si32(vdest);
*dst = (ullong)vdest;
w--;
dst++;
@ -1551,11 +1545,11 @@ fbCompositeSrc_8888x0565mmx (pixman_op_t op,
{
__m64 vsrc = load8888 (*src);
ullong d = *dst;
__m64 vdest = expand565 (M64(d), 0);
__m64 vdest = expand565 ((__m64)d, 0);
vdest = pack565(over(vsrc, expand_alpha(vsrc), vdest), vdest, 0);
*dst = _mm_cvtsi64_si32(vdest);
*dst = (ullong)vdest;
w--;
dst++;
@ -1620,7 +1614,7 @@ fbCompositeSolidMask_nx8x8888mmx (pixman_op_t op,
if (m)
{
__m64 vdest = in_over(vsrc, vsrca, expand_alpha_rev (M64(m)), load8888(*dst));
__m64 vdest = in_over(vsrc, vsrca, expand_alpha_rev ((__m64)m), load8888(*dst));
*dst = store8888(vdest);
}
@ -1648,8 +1642,8 @@ fbCompositeSolidMask_nx8x8888mmx (pixman_op_t op,
vdest = *(__m64 *)dst;
dest0 = in_over(vsrc, vsrca, expand_alpha_rev (M64(m0)), expand8888(vdest, 0));
dest1 = in_over(vsrc, vsrca, expand_alpha_rev (M64(m1)), expand8888(vdest, 1));
dest0 = in_over(vsrc, vsrca, expand_alpha_rev ((__m64)m0), expand8888(vdest, 0));
dest1 = in_over(vsrc, vsrca, expand_alpha_rev ((__m64)m1), expand8888(vdest, 1));
*(__m64 *)dst = pack8888(dest0, dest1);
}
@ -1668,7 +1662,7 @@ fbCompositeSolidMask_nx8x8888mmx (pixman_op_t op,
if (m)
{
__m64 vdest = load8888(*dst);
vdest = in_over(vsrc, vsrca, expand_alpha_rev (M64(m)), vdest);
vdest = in_over(vsrc, vsrca, expand_alpha_rev ((__m64)m), vdest);
*dst = store8888(vdest);
}
@ -1721,7 +1715,7 @@ pixman_fill_mmx (uint32_t *bits,
}
fill = ((ullong)xor << 32) | xor;
vfill = M64(fill);
vfill = (__m64)fill;
#ifdef __GNUC__
__asm__ (
@ -1867,7 +1861,7 @@ fbCompositeSolidMaskSrc_nx8x8888mmx (pixman_op_t op,
if (m)
{
__m64 vdest = in(vsrc, expand_alpha_rev (M64(m)));
__m64 vdest = in(vsrc, expand_alpha_rev ((__m64)m));
*dst = store8888(vdest);
}
else
@ -1899,8 +1893,8 @@ fbCompositeSolidMaskSrc_nx8x8888mmx (pixman_op_t op,
vdest = *(__m64 *)dst;
dest0 = in(vsrc, expand_alpha_rev (M64(m0)));
dest1 = in(vsrc, expand_alpha_rev (M64(m1)));
dest0 = in(vsrc, expand_alpha_rev ((__m64)m0));
dest1 = in(vsrc, expand_alpha_rev ((__m64)m1));
*(__m64 *)dst = pack8888(dest0, dest1);
}
@ -1923,7 +1917,7 @@ fbCompositeSolidMaskSrc_nx8x8888mmx (pixman_op_t op,
if (m)
{
__m64 vdest = load8888(*dst);
vdest = in(vsrc, expand_alpha_rev (M64(m)));
vdest = in(vsrc, expand_alpha_rev ((__m64)m));
*dst = store8888(vdest);
}
else
@ -1976,7 +1970,7 @@ fbCompositeSolidMask_nx8x0565mmx (pixman_op_t op,
vsrc = load8888 (src);
vsrca = expand_alpha (vsrc);
*(__m64*)(&src16) = pack565(vsrc, _mm_setzero_si64(), 0);
src16 = (ullong)pack565(vsrc, _mm_setzero_si64(), 0);
srcsrcsrcsrc = (ullong)src16 << 48 | (ullong)src16 << 32 |
(ullong)src16 << 16 | (ullong)src16;
@ -1998,8 +1992,9 @@ fbCompositeSolidMask_nx8x0565mmx (pixman_op_t op,
if (m)
{
ullong d = *dst;
__m64 vdest = in_over(vsrc, vsrca, expand_alpha_rev (M64(m)), expand565(M64(d), 0));
*dst = _mm_cvtsi64_si32(pack565(vdest, _mm_setzero_si64(), 0));
__m64 vd = (__m64)d;
__m64 vdest = in_over(vsrc, vsrca, expand_alpha_rev ((__m64)m), expand565(vd, 0));
*dst = (ullong)pack565(vdest, _mm_setzero_si64(), 0);
}
w--;
@ -2024,13 +2019,18 @@ fbCompositeSolidMask_nx8x0565mmx (pixman_op_t op,
else if (m0 | m1 | m2 | m3)
{
__m64 vdest;
__m64 vm0, vm1, vm2, vm3;
vdest = *(__m64 *)dst;
vdest = pack565(in_over(vsrc, vsrca, expand_alpha_rev(M64(m0)), expand565(vdest, 0)), vdest, 0);
vdest = pack565(in_over(vsrc, vsrca, expand_alpha_rev(M64(m1)), expand565(vdest, 1)), vdest, 1);
vdest = pack565(in_over(vsrc, vsrca, expand_alpha_rev(M64(m2)), expand565(vdest, 2)), vdest, 2);
vdest = pack565(in_over(vsrc, vsrca, expand_alpha_rev(M64(m3)), expand565(vdest, 3)), vdest, 3);
vm0 = (__m64)m0;
vdest = pack565(in_over(vsrc, vsrca, expand_alpha_rev(vm0), expand565(vdest, 0)), vdest, 0);
vm1 = (__m64)m1;
vdest = pack565(in_over(vsrc, vsrca, expand_alpha_rev(vm1), expand565(vdest, 1)), vdest, 1);
vm2 = (__m64)m2;
vdest = pack565(in_over(vsrc, vsrca, expand_alpha_rev(vm2), expand565(vdest, 2)), vdest, 2);
vm3 = (__m64)m3;
vdest = pack565(in_over(vsrc, vsrca, expand_alpha_rev(vm3), expand565(vdest, 3)), vdest, 3);
*(__m64 *)dst = vdest;
}
@ -2049,8 +2049,9 @@ fbCompositeSolidMask_nx8x0565mmx (pixman_op_t op,
if (m)
{
ullong d = *dst;
__m64 vdest = in_over(vsrc, vsrca, expand_alpha_rev (M64(m)), expand565(M64(d), 0));
*dst = _mm_cvtsi64_si32(pack565(vdest, _mm_setzero_si64(), 0));
__m64 vd = (__m64)d;
__m64 vdest = in_over(vsrc, vsrca, expand_alpha_rev ((__m64)m), expand565(vd, 0));
*dst = (ullong)pack565(vdest, _mm_setzero_si64(), 0);
}
w--;
@ -2105,11 +2106,11 @@ fbCompositeSrc_8888RevNPx0565mmx (pixman_op_t op,
{
__m64 vsrc = load8888 (*src);
ullong d = *dst;
__m64 vdest = expand565 (M64(d), 0);
__m64 vdest = expand565 ((__m64)d, 0);
vdest = pack565(over_rev_non_pre(vsrc, vdest), vdest, 0);
*dst = _mm_cvtsi64_si32(vdest);
*dst = (ullong)vdest;
w--;
dst++;
@ -2166,11 +2167,11 @@ fbCompositeSrc_8888RevNPx0565mmx (pixman_op_t op,
{
__m64 vsrc = load8888 (*src);
ullong d = *dst;
__m64 vdest = expand565 (M64(d), 0);
__m64 vdest = expand565 ((__m64)d, 0);
vdest = pack565(over_rev_non_pre(vsrc, vdest), vdest, 0);
*dst = _mm_cvtsi64_si32(vdest);
*dst = (ullong)vdest;
w--;
dst++;
@ -2329,9 +2330,9 @@ fbCompositeSolidMask_nx8888x0565Cmmx (pixman_op_t op,
if (m)
{
ullong d = *q;
__m64 vdest = expand565 (M64(d), 0);
__m64 vdest = expand565 ((__m64)d, 0);
vdest = pack565 (in_over (vsrc, vsrca, load8888 (m), vdest), vdest, 0);
*q = _mm_cvtsi64_si32(vdest);
*q = (ullong)vdest;
}
twidth--;
@ -2372,9 +2373,9 @@ fbCompositeSolidMask_nx8888x0565Cmmx (pixman_op_t op,
if (m)
{
ullong d = *q;
__m64 vdest = expand565(M64(d), 0);
__m64 vdest = expand565((__m64)d, 0);
vdest = pack565 (in_over(vsrc, vsrca, load8888(m), vdest), vdest, 0);
*q = _mm_cvtsi64_si32(vdest);
*q = (ullong)vdest;
}
twidth--;
@ -2730,7 +2731,7 @@ fbCompositeSrcAdd_8888x8888mmx (pixman_op_t op,
while (w >= 2)
{
*(__m64*)dst = _mm_adds_pu8(*(__m64*)src, *(__m64*)dst);
*(ullong*)dst = (ullong) _mm_adds_pu8(*(__m64*)src, *(__m64*)dst);
dst += 2;
src += 2;
w -= 2;
@ -2956,7 +2957,7 @@ fbCompositeOver_x888x8x8888mmx (pixman_op_t op,
else
{
__m64 sa = expand_alpha (s);
__m64 vm = expand_alpha_rev (M64(m));
__m64 vm = expand_alpha_rev ((__m64)m);
__m64 vdest = in_over(s, sa, vm, load8888 (*dst));
*dst = store8888 (vdest);

Просмотреть файл

@ -22,7 +22,7 @@
* Author: Keith Packard, SuSE, Inc.
*/
#if HAVE_CONFIG_H
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
@ -1781,7 +1781,6 @@ pixman_image_composite (pixman_op_t op,
break;
case PIXMAN_x8r8g8b8:
switch (pDst->bits.format) {
case PIXMAN_a8r8g8b8:
case PIXMAN_x8r8g8b8:
#ifdef USE_MMX
if (pixman_have_mmx())
@ -1793,7 +1792,6 @@ pixman_image_composite (pixman_op_t op,
}
case PIXMAN_x8b8g8r8:
switch (pDst->bits.format) {
case PIXMAN_a8b8g8r8:
case PIXMAN_x8b8g8r8:
#ifdef USE_MMX
if (pixman_have_mmx())

Просмотреть файл

@ -5,8 +5,6 @@
#ifndef PIXMAN_PRIVATE_H
#define PIXMAN_PRIVATE_H
#include "cairo-platform.h"
#include "pixman.h"
#include <time.h>
@ -18,30 +16,6 @@
#define TRUE 1
#endif
#ifdef _MSC_VER
#define snprintf _snprintf
#undef inline
#define inline __inline
# ifndef INT16_MIN
# define INT16_MIN (-32767-1)
# endif
# ifndef INT16_MAX
# define INT16_MAX (32767)
# endif
# ifndef INT32_MIN
# define INT32_MIN (-2147483647-1)
# endif
# ifndef INT32_MAX
# define INT32_MAX (2147483647)
# endif
# ifndef UINT32_MAX
# define UINT32_MAX (4294967295)
# endif
#endif
#define MSBFirst 0
#define LSBFirst 1
@ -53,9 +27,7 @@
# define BITMAP_BIT_ORDER LSBFirst
#endif
#ifndef DEBUG
#define DEBUG 0
#endif
#if defined (__GNUC__)
# define FUNC ((const char*) (__PRETTY_FUNCTION__))
@ -65,6 +37,28 @@
# define FUNC ((const char*) ("???"))
#endif
#ifndef INT16_MIN
# define INT16_MIN (-32767-1)
# define INT16_MAX (32767)
#endif
#ifndef INT32_MIN
# define INT32_MIN (-2147483647-1)
# define INT32_MAX (2147483647)
#endif
#ifndef UINT32_MIN
# define UINT32_MIN (0)
# define UINT32_MAX (4294967295U)
#endif
#ifndef M_PI
# define M_PI 3.14159265358979323846
#endif
#ifdef _MSC_VER
#define inline __inline
#endif
#define FB_SHIFT 5
#define FB_UNIT (1 << FB_SHIFT)
@ -664,8 +658,8 @@ union pixman_image
} while (0)
/* FIXME */
#define fbPrepareAccess(x) do { } while (0)
#define fbFinishAccess(x) do { } while (0)
#define fbPrepareAccess(x)
#define fbFinishAccess(x)
#else
@ -675,8 +669,8 @@ union pixman_image
memcpy(dst, src, size)
#define MEMSET_WRAPPED(dst, val, size) \
memset(dst, val, size)
#define fbPrepareAccess(x) do { } while (0)
#define fbFinishAccess(x) do { } while (0)
#define fbPrepareAccess(x)
#define fbFinishAccess(x)
#endif
#define fbComposeGetSolid(img, res, fmt) \
@ -802,7 +796,7 @@ pixman_rasterize_edges_accessors (pixman_image_t *image,
pixman_fixed_t b);
#ifndef MOZILLA_CLIENT
#ifdef PIXMAN_TIMING
/* Timing */
static inline uint64_t
@ -847,6 +841,6 @@ void pixman_timer_register (PixmanTimer *timer);
timer##tname.total += OIL_STAMP() - begin##tname; \
}
#endif /* MOZILLA_CLIENT */
#endif /* PIXMAN_TIMING */
#endif /* PIXMAN_PRIVATE_H */

Просмотреть файл

@ -45,7 +45,7 @@ SOFTWARE.
******************************************************************/
#if HAVE_CONFIG_H
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
@ -1510,6 +1510,8 @@ pixman_region_validate(pixman_region16_t * badreg,
box = PIXREGION_BOXPTR(&ri[0].reg);
ri[0].reg.extents = *box;
ri[0].reg.data->numRects = 1;
badreg->extents = *pixman_region_emptyBox;
badreg->data = pixman_region_emptyData;
/* Now scatter rectangles into the minimum set of valid regions. If the
next rectangle to be added to a region would force an existing rectangle
@ -1623,6 +1625,8 @@ NextRect: ;
freeData(hreg);
}
numRI -= half;
if (!ret)
goto bail;
}
*badreg = ri[0].reg;
free(ri);
@ -1632,6 +1636,7 @@ bail:
for (i = 0; i < numRI; i++)
freeData(&ri[i].reg);
free (ri);
return pixman_break (badreg);
}
@ -2513,6 +2518,8 @@ pixman_region_init_rects (pixman_region16_t *region,
{
int overlap;
/* if it's 1, then we just want to set the extents, so call
* the existing method. */
if (count == 1) {
pixman_region_init_rect(region,
boxes[0].x1,
@ -2523,8 +2530,15 @@ pixman_region_init_rects (pixman_region16_t *region,
}
pixman_region_init(region);
/* if it's 0, don't call pixman_rect_alloc -- 0 rectangles is
* a special case, and causing pixman_rect_alloc would cause
* us to leak memory (because the 0-rect case should be the
* static pixman_region_emptyData data).
*/
if (count == 0)
return TRUE;
return TRUE;
if (!pixman_rect_alloc(region, count))
return FALSE;

Просмотреть файл

@ -19,7 +19,7 @@
* CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#if HAVE_CONFIG_H
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
@ -27,6 +27,8 @@
#include <stdio.h>
#include "pixman-private.h"
#ifdef PIXMAN_TIMER
static PixmanTimer *timers;
static void
@ -60,3 +62,5 @@ pixman_timer_register (PixmanTimer *timer)
timer->next = timers;
timers = timer;
}
#endif

Просмотреть файл

@ -1,4 +1,5 @@
/*
* $Id: pixman-trap.c,v 1.9 2007-09-20 19:24:51 vladimir%pobox.com Exp $
*
* Copyright © 2004 Keith Packard
*
@ -21,7 +22,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
#if HAVE_CONFIG_H
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif

Просмотреть файл

@ -21,7 +21,7 @@
* Author: Keith Packard, SuSE, Inc.
*/
#if HAVE_CONFIG_H
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif

Просмотреть файл

@ -69,8 +69,6 @@ SOFTWARE.
#ifndef PIXMAN_H__
#define PIXMAN_H__
#include "pixman-remap.h"
/*
* Standard integers
*/
@ -184,20 +182,46 @@ typedef enum
typedef enum
{
PIXMAN_OP_CLEAR,
PIXMAN_OP_SRC,
PIXMAN_OP_DST,
PIXMAN_OP_OVER,
PIXMAN_OP_OVER_REVERSE,
PIXMAN_OP_IN,
PIXMAN_OP_IN_REVERSE,
PIXMAN_OP_OUT,
PIXMAN_OP_OUT_REVERSE,
PIXMAN_OP_ATOP,
PIXMAN_OP_ATOP_REVERSE,
PIXMAN_OP_XOR,
PIXMAN_OP_ADD,
PIXMAN_OP_SATURATE
PIXMAN_OP_CLEAR = 0x00,
PIXMAN_OP_SRC = 0x01,
PIXMAN_OP_DST = 0x02,
PIXMAN_OP_OVER = 0x03,
PIXMAN_OP_OVER_REVERSE = 0x04,
PIXMAN_OP_IN = 0x05,
PIXMAN_OP_IN_REVERSE = 0x06,
PIXMAN_OP_OUT = 0x07,
PIXMAN_OP_OUT_REVERSE = 0x08,
PIXMAN_OP_ATOP = 0x09,
PIXMAN_OP_ATOP_REVERSE = 0x0a,
PIXMAN_OP_XOR = 0x0b,
PIXMAN_OP_ADD = 0x0c,
PIXMAN_OP_SATURATE = 0x0d,
PIXMAN_OP_DISJOINT_CLEAR = 0x10,
PIXMAN_OP_DISJOINT_SRC = 0x11,
PIXMAN_OP_DISJOINT_DST = 0x12,
PIXMAN_OP_DISJOINT_OVER = 0x13,
PIXMAN_OP_DISJOINT_OVER_REVERSE = 0x14,
PIXMAN_OP_DISJOINT_IN = 0x15,
PIXMAN_OP_DISJOINT_IN_REVERSE = 0x16,
PIXMAN_OP_DISJOINT_OUT = 0x17,
PIXMAN_OP_DISJOINT_OUT_REVERSE = 0x18,
PIXMAN_OP_DISJOINT_ATOP = 0x19,
PIXMAN_OP_DISJOINT_ATOP_REVERSE = 0x1a,
PIXMAN_OP_DISJOINT_XOR = 0x1b,
PIXMAN_OP_CONJOINT_CLEAR = 0x20,
PIXMAN_OP_CONJOINT_SRC = 0x21,
PIXMAN_OP_CONJOINT_DST = 0x22,
PIXMAN_OP_CONJOINT_OVER = 0x23,
PIXMAN_OP_CONJOINT_OVER_REVERSE = 0x24,
PIXMAN_OP_CONJOINT_IN = 0x25,
PIXMAN_OP_CONJOINT_IN_REVERSE = 0x26,
PIXMAN_OP_CONJOINT_OUT = 0x27,
PIXMAN_OP_CONJOINT_OUT_REVERSE = 0x28,
PIXMAN_OP_CONJOINT_ATOP = 0x29,
PIXMAN_OP_CONJOINT_ATOP_REVERSE = 0x2a,
PIXMAN_OP_CONJOINT_XOR = 0x2b
} pixman_op_t;
/*
@ -280,8 +304,10 @@ pixman_bool_t pixman_region_subtract (pixman_region16_t *regD,
pixman_bool_t pixman_region_inverse (pixman_region16_t *newReg,
pixman_region16_t *reg1,
pixman_box16_t *invRect);
pixman_bool_t pixman_region_contains_point (pixman_region16_t *region, int x, int y, pixman_box16_t *box);
pixman_region_overlap_t pixman_region_contains_rectangle (pixman_region16_t *pixman_region16_t, pixman_box16_t *prect);
pixman_bool_t pixman_region_contains_point (pixman_region16_t *region,
int x, int y, pixman_box16_t *box);
pixman_region_overlap_t pixman_region_contains_rectangle (pixman_region16_t *pixman_region16_t,
pixman_box16_t *prect);
pixman_bool_t pixman_region_not_empty (pixman_region16_t *region);
pixman_box16_t * pixman_region_extents (pixman_region16_t *region);
int pixman_region_n_rects (pixman_region16_t *region);
@ -290,7 +316,7 @@ pixman_box16_t * pixman_region_rectangles (pixman_region16_t *region,
pixman_bool_t pixman_region_equal (pixman_region16_t *region1,
pixman_region16_t *region2);
pixman_bool_t pixman_region_selfcheck (pixman_region16_t *region);
void pixman_region_reset(pixman_region16_t *region, pixman_box16_t *box);
void pixman_region_reset (pixman_region16_t *region, pixman_box16_t *box);
pixman_bool_t pixman_region_init_rects (pixman_region16_t *region,
pixman_box16_t *boxes, int count);
@ -453,7 +479,7 @@ pixman_image_t *pixman_image_create_bits (pixman_format_code_t
/* Destructor */
pixman_image_t *pixman_image_ref (pixman_image_t *image);
void pixman_image_unref (pixman_image_t *image);
pixman_bool_t pixman_image_unref (pixman_image_t *image);
/* Set properties */
@ -472,6 +498,8 @@ pixman_bool_t pixman_image_set_filter (pixman_image_t
void pixman_image_set_filter_params (pixman_image_t *image,
pixman_fixed_t *params,
int n_params);
void pixman_image_set_source_cliping (pixman_image_t *image,
pixman_bool_t source_clipping);
void pixman_image_set_alpha_map (pixman_image_t *image,
pixman_image_t *alpha_map,
int16_t x,

Просмотреть файл

Просмотреть файл

Просмотреть файл

Просмотреть файл

@ -58,7 +58,7 @@ CPPSRCS += gfxWindowsFonts.cpp \
$(NULL)
CPPSRCS += gfxPDFSurface.cpp
_OS_LIBS = usp10
_OS_LIBS = usp10 msimg32
ifdef GNU_CXX
_OS_LIBS += uuid
endif

Просмотреть файл

@ -227,7 +227,7 @@ EXTRA_DSO_LDOPTS += -lbe -ltracker
endif
ifeq ($(OS_ARCH),WINNT)
EXTRA_DSO_LDOPTS += $(call EXPAND_LIBNAME,shell32 ole32 uuid version winspool comdlg32 imm32 winmm wsock32)
EXTRA_DSO_LDOPTS += $(call EXPAND_LIBNAME,shell32 ole32 uuid version winspool comdlg32 imm32 winmm wsock32 msimg32)
ifneq (,$(MOZ_DEBUG)$(NS_TRACE_MALLOC))
EXTRA_DSO_LDOPTS += $(call EXPAND_LIBNAME,imagehlp)
endif