b=340452, update cairo on trunk to 2006-06-03, r=stuart
git-svn-id: svn://10.0.0.236/trunk@199075 18797224-902f-48f8-a5cc-f745e15eee43
This commit is contained in:
parent
d21958870c
commit
b53474a3a1
@ -12,88 +12,10 @@ http://www.cairographics.org/.
|
||||
|
||||
VERSIONS:
|
||||
|
||||
cairo 1.1.1 (cvs - 2006-03-31)
|
||||
cairo 1.1.1 (cvs - 2006-06-03)
|
||||
glitz 0.5.2 (cvs - 2006-01-10)
|
||||
|
||||
***** NOTE FOR VISUAL C++ 6.0 *****
|
||||
|
||||
VC6 cannot build pixman from cairo. Therefore, VC6 builds are not supported
|
||||
if cairo is enabled. Please upgrade to VC7.1/8.
|
||||
VC6 is not supported. Please upgrade to VC8.
|
||||
|
||||
==== Patches ====
|
||||
|
||||
[somewhat obsolete, see git repository history for patch info]
|
||||
|
||||
Last update: 23 Feb 2006
|
||||
|
||||
mozilla-misc.patch
|
||||
- Misc compilation fixes for pixman (submitted upstream)
|
||||
- temporary moz_cairo_set_target API (not for upstream)
|
||||
- mac compilation fix for cairo-atsui-font.c for 10.2 SDK (maybe should
|
||||
be upstream?)
|
||||
- cairo-features.h.in - add cairo-platform.h include and hard-code the
|
||||
cairo version (not for upstream)
|
||||
- #if 0'ing out DllMain in win32-surface.c -- not needed, since
|
||||
we don't use cairo multithreaded, and DllMain interferes
|
||||
with libxul's DllMain. (not for usptream)
|
||||
- #if 0'ing out bits to get rid of multithreaded stuff in cairoint.h
|
||||
(not for upstream)
|
||||
|
||||
cairo-debug-helpers.patch
|
||||
- some stuff for cairo-debug.[ch]
|
||||
|
||||
fbcompose-bandaid.patch (Updated 7 Feb 06)
|
||||
- Workaround for https://bugs.freedesktop.org/show_bug.cgi?id=5777
|
||||
|
||||
cairo-win32-clip.patch
|
||||
- Make mark_dirty() reset a surface's clip, so that we can call it
|
||||
when we RestoreDC() after native win32 drawing (submitted upstream)
|
||||
- Rework win32 surface clip and extents handling for correctness
|
||||
(submitted upstream)
|
||||
|
||||
cairo-win32-expose-dc-and-dib.patch (Updated 10 Feb 06)
|
||||
- Expose cairo_win32_surface_create_dib() and add
|
||||
cairo_win32_surface_get_dc() to get at a surface's HDC
|
||||
|
||||
cairo-win32-alphablend.patch (Updated 10 Feb 06)
|
||||
- Use AlphaBlend if the dst surface is either RGB24 or ARGB32, not
|
||||
just RGB24
|
||||
- Removed src->format == dst->format restriction for deciding when
|
||||
to use BitBlt; it's valid for ARGB32->RGB24 and vice-versa with operator
|
||||
SOURCE
|
||||
- Remove RGB24 format check in fast win32-font.c path (we can still use
|
||||
GDI with ARGB32)
|
||||
- Add GdiFlush() calls before each image surface get
|
||||
(Submitted upstream: https://bugs.freedesktop.org/show_bug.cgi?id=5845)
|
||||
|
||||
device-offset-scale.patch (Updated 7 Feb 06)
|
||||
- Move device offset/scale handling into surface layer; large rework
|
||||
of device offset/scale. (submitted upstream)
|
||||
|
||||
push-pop-group.patch (Updated 9 Feb 06)
|
||||
- Implementation of push/pop group API; depends on device-offset-scale.
|
||||
(submitted upstream)
|
||||
- Add push_group_with_content() to select COLOR/COLOR_ALPHA/ALPHA
|
||||
|
||||
cairo-win32-composite-coord.patch
|
||||
- Fix up coordinates before calling BitBlt/AlphaBlend, so that windows
|
||||
doesn't get mad at us if we ask it to blit regions outside of the source
|
||||
DC (NOT SUBMITTED UPSTREAM YET)
|
||||
|
||||
cairo-win32-expose-dc-and-dib.patch
|
||||
- Expose cairo_win32_surface_get_dc() to return the HDC for a win32 surface
|
||||
- Expose cairo_win32_surface_create_dib() for creating a DIB-backed surface
|
||||
(NOT SUBMITTED UPSTREAM YET)
|
||||
|
||||
cairo-win32-creation-format.patch
|
||||
- Have cairo_win32_surface_create inspect the DC and set up the appropriate
|
||||
cairo_format_t
|
||||
|
||||
cairo-xlib-create-similar.patch (Updated 21 Feb 06)
|
||||
- _cairo_xlib_surface_create_similar should not create a 24-bit
|
||||
surface for a 16-bit target; fix it to emulate the target surface
|
||||
as closely as possible (submitted upstream, not accepted yet)
|
||||
|
||||
cairo-xlib-getters.patch (Updated 23 Feb 06)
|
||||
- Add cairo_xlib_get_(display,drawable,screen,visual,depth)
|
||||
(submitted upstream, not accepted yet)
|
||||
|
||||
@ -60,6 +60,7 @@ REQUIRES = $(PNG_REQUIRES) \
|
||||
|
||||
CSRCS = \
|
||||
cairo.c \
|
||||
cairo-analysis-surface.c \
|
||||
cairo-arc.c \
|
||||
cairo-array.c \
|
||||
cairo-cache.c \
|
||||
@ -68,16 +69,17 @@ CSRCS = \
|
||||
cairo-debug.c \
|
||||
cairo-fixed.c \
|
||||
cairo-font.c \
|
||||
cairo-font-options.c \
|
||||
cairo-font-options.c \
|
||||
cairo-gstate.c \
|
||||
cairo-hash.c \
|
||||
cairo-hash.c \
|
||||
cairo-hull.c \
|
||||
cairo-image-surface.c \
|
||||
cairo-lzw.c \
|
||||
cairo-lzw.c \
|
||||
cairo-matrix.c \
|
||||
cairo-meta-surface.c \
|
||||
cairo-meta-surface.c \
|
||||
cairo-operator.c \
|
||||
cairo-output-stream.c \
|
||||
cairo-paginated-surface.c \
|
||||
cairo-paginated-surface.c \
|
||||
cairo-path.c \
|
||||
cairo-path-bounds.c \
|
||||
cairo-path-data.c \
|
||||
@ -86,13 +88,14 @@ CSRCS = \
|
||||
cairo-pattern.c \
|
||||
cairo-pen.c \
|
||||
cairo-polygon.c \
|
||||
cairo-region.c \
|
||||
cairo-scaled-font.c \
|
||||
cairo-region.c \
|
||||
cairo-scaled-font.c \
|
||||
cairo-scaled-font-subsets.c \
|
||||
cairo-slope.c \
|
||||
cairo-spline.c \
|
||||
cairo-stroke-style.c \
|
||||
cairo-stroke-style.c \
|
||||
cairo-surface.c \
|
||||
cairo-surface-fallback.c \
|
||||
cairo-surface-fallback.c \
|
||||
cairo-traps.c \
|
||||
cairo-unicode.c \
|
||||
cairo-wideint.c \
|
||||
@ -129,6 +132,7 @@ endif
|
||||
|
||||
ifeq ($(MOZ_WIDGET_TOOLKIT),gtk2)
|
||||
CSRCS += cairo-font-subset.c \
|
||||
cairo-base85-stream.c \
|
||||
cairo-pdf-surface.c \
|
||||
cairo-ps-surface.c
|
||||
EXPORTS += cairo-ps.h cairo-pdf.h
|
||||
|
||||
55
mozilla/gfx/cairo/cairo/src/cairo-analysis-surface-private.h
Normal file
55
mozilla/gfx/cairo/cairo/src/cairo-analysis-surface-private.h
Normal file
@ -0,0 +1,55 @@
|
||||
/* $Id: cairo-analysis-surface-private.h,v 1.1 2006-06-05 23:16:24 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
|
||||
* notice, a recipient may use your version of this file under either
|
||||
* the MPL or the LGPL.
|
||||
*
|
||||
* You should have received a copy of the LGPL along with this library
|
||||
* in the file COPYING-LGPL-2.1; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
* You should have received a copy of the MPL along with this library
|
||||
* in the file COPYING-MPL-1.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License
|
||||
* Version 1.1 (the "License"); you may not use this file except in
|
||||
* compliance with the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY
|
||||
* OF ANY KIND, either express or implied. See the LGPL or the MPL for
|
||||
* the specific language governing rights and limitations.
|
||||
*
|
||||
* The Original Code is the cairo graphics library.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Keith Packard
|
||||
*
|
||||
* Contributor(s):
|
||||
* Keith Packard <keithp@keithp.com>
|
||||
*/
|
||||
|
||||
#ifndef CAIRO_ANALYSIS_SURFACE_H
|
||||
#define CAIRO_ANALYSIS_SURFACE_H
|
||||
|
||||
#include "cairoint.h"
|
||||
|
||||
cairo_private cairo_surface_t *
|
||||
_cairo_analysis_surface_create (cairo_surface_t *target,
|
||||
int width,
|
||||
int height);
|
||||
|
||||
cairo_private pixman_region16_t *
|
||||
_cairo_analysis_surface_get_supported (cairo_surface_t *surface);
|
||||
|
||||
cairo_private pixman_region16_t *
|
||||
_cairo_analysis_surface_get_unsupported (cairo_surface_t *unsupported);
|
||||
|
||||
cairo_private cairo_bool_t
|
||||
_cairo_analysis_surface_has_unsupported (cairo_surface_t *unsupported);
|
||||
|
||||
#endif /* CAIRO_ANALYSIS_SURFACE_H */
|
||||
259
mozilla/gfx/cairo/cairo/src/cairo-analysis-surface.c
Normal file
259
mozilla/gfx/cairo/cairo/src/cairo-analysis-surface.c
Normal file
@ -0,0 +1,259 @@
|
||||
/*
|
||||
* Copyright © 2006 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
|
||||
* notice, a recipient may use your version of this file under either
|
||||
* the MPL or the LGPL.
|
||||
*
|
||||
* You should have received a copy of the LGPL along with this library
|
||||
* in the file COPYING-LGPL-2.1; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
* You should have received a copy of the MPL along with this library
|
||||
* in the file COPYING-MPL-1.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License
|
||||
* Version 1.1 (the "License"); you may not use this file except in
|
||||
* compliance with the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY
|
||||
* OF ANY KIND, either express or implied. See the LGPL or the MPL for
|
||||
* the specific language governing rights and limitations.
|
||||
*
|
||||
* The Original Code is the cairo graphics library.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Keith Packard
|
||||
*
|
||||
* Contributor(s):
|
||||
* Keith Packard <keithp@keithp.com>
|
||||
*/
|
||||
|
||||
#include "cairoint.h"
|
||||
|
||||
#include "cairo-analysis-surface-private.h"
|
||||
#include "cairo-paginated-surface-private.h"
|
||||
|
||||
typedef struct {
|
||||
cairo_surface_t base;
|
||||
int width;
|
||||
int height;
|
||||
|
||||
cairo_surface_t *target;
|
||||
|
||||
cairo_bool_t fallback;
|
||||
} cairo_analysis_surface_t;
|
||||
|
||||
static cairo_int_status_t
|
||||
_cairo_analysis_surface_get_extents (void *abstract_surface,
|
||||
cairo_rectangle_fixed_t *rectangle)
|
||||
{
|
||||
cairo_analysis_surface_t *surface = abstract_surface;
|
||||
|
||||
return _cairo_surface_get_extents (surface->target, rectangle);
|
||||
}
|
||||
|
||||
static cairo_int_status_t
|
||||
_cairo_analysis_surface_paint (void *abstract_surface,
|
||||
cairo_operator_t op,
|
||||
cairo_pattern_t *source)
|
||||
{
|
||||
cairo_analysis_surface_t *surface = abstract_surface;
|
||||
cairo_status_t status;
|
||||
|
||||
if (!surface->target->backend->paint)
|
||||
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;
|
||||
}
|
||||
return status;
|
||||
}
|
||||
|
||||
static cairo_int_status_t
|
||||
_cairo_analysis_surface_mask (void *abstract_surface,
|
||||
cairo_operator_t op,
|
||||
cairo_pattern_t *source,
|
||||
cairo_pattern_t *mask)
|
||||
{
|
||||
cairo_analysis_surface_t *surface = abstract_surface;
|
||||
cairo_status_t status;
|
||||
|
||||
if (!surface->target->backend->mask)
|
||||
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;
|
||||
}
|
||||
return status;
|
||||
}
|
||||
|
||||
static cairo_int_status_t
|
||||
_cairo_analysis_surface_stroke (void *abstract_surface,
|
||||
cairo_operator_t op,
|
||||
cairo_pattern_t *source,
|
||||
cairo_path_fixed_t *path,
|
||||
cairo_stroke_style_t *style,
|
||||
cairo_matrix_t *ctm,
|
||||
cairo_matrix_t *ctm_inverse,
|
||||
double tolerance,
|
||||
cairo_antialias_t antialias)
|
||||
{
|
||||
cairo_analysis_surface_t *surface = abstract_surface;
|
||||
cairo_status_t status;
|
||||
|
||||
if (!surface->target->backend->stroke)
|
||||
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;
|
||||
}
|
||||
return status;
|
||||
}
|
||||
|
||||
static cairo_int_status_t
|
||||
_cairo_analysis_surface_fill (void *abstract_surface,
|
||||
cairo_operator_t op,
|
||||
cairo_pattern_t *source,
|
||||
cairo_path_fixed_t *path,
|
||||
cairo_fill_rule_t fill_rule,
|
||||
double tolerance,
|
||||
cairo_antialias_t antialias)
|
||||
{
|
||||
cairo_analysis_surface_t *surface = abstract_surface;
|
||||
cairo_status_t status;
|
||||
|
||||
if (!surface->target->backend->fill)
|
||||
status = CAIRO_INT_STATUS_UNSUPPORTED;
|
||||
else
|
||||
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;
|
||||
}
|
||||
return status;
|
||||
}
|
||||
|
||||
static cairo_int_status_t
|
||||
_cairo_analysis_surface_show_glyphs (void *abstract_surface,
|
||||
cairo_operator_t op,
|
||||
cairo_pattern_t *source,
|
||||
const cairo_glyph_t *glyphs,
|
||||
int num_glyphs,
|
||||
cairo_scaled_font_t *scaled_font)
|
||||
{
|
||||
cairo_analysis_surface_t *surface = abstract_surface;
|
||||
cairo_status_t status;
|
||||
|
||||
if (!surface->target->backend->show_glyphs)
|
||||
status = CAIRO_INT_STATUS_UNSUPPORTED;
|
||||
else
|
||||
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;
|
||||
}
|
||||
return status;
|
||||
}
|
||||
|
||||
static const cairo_surface_backend_t cairo_analysis_surface_backend = {
|
||||
CAIRO_INTERNAL_SURFACE_TYPE_ANALYSIS,
|
||||
NULL, /* create_similar */
|
||||
NULL, /* finish_surface */
|
||||
NULL, /* acquire_source_image */
|
||||
NULL, /* release_source_image */
|
||||
NULL, /* acquire_dest_image */
|
||||
NULL, /* release_dest_image */
|
||||
NULL, /* clone_similar */
|
||||
NULL, /* composite */
|
||||
NULL, /* fill_rectangles */
|
||||
NULL, /* composite_trapezoids */
|
||||
NULL, /* copy_page */
|
||||
NULL, /* show_page */
|
||||
NULL, /* set_clip_region */
|
||||
NULL, /* clip_path */
|
||||
_cairo_analysis_surface_get_extents,
|
||||
NULL, /* old_show_glyphs */
|
||||
NULL, /* get_font_options */
|
||||
NULL, /* flush */
|
||||
NULL, /* mark_dirty_rectangle */
|
||||
NULL, /* scaled_font_fini */
|
||||
NULL, /* scaled_glyph_fini */
|
||||
_cairo_analysis_surface_paint,
|
||||
_cairo_analysis_surface_mask,
|
||||
_cairo_analysis_surface_stroke,
|
||||
_cairo_analysis_surface_fill,
|
||||
_cairo_analysis_surface_show_glyphs,
|
||||
NULL, /* snapshot */
|
||||
};
|
||||
|
||||
cairo_private cairo_surface_t *
|
||||
_cairo_analysis_surface_create (cairo_surface_t *target,
|
||||
int width,
|
||||
int height)
|
||||
{
|
||||
cairo_analysis_surface_t *surface;
|
||||
|
||||
surface = malloc (sizeof (cairo_analysis_surface_t));
|
||||
if (surface == NULL)
|
||||
goto FAIL;
|
||||
|
||||
/* I believe the content type here is truly arbitrary. I'm quite
|
||||
* sure nothing will ever use this value. */
|
||||
_cairo_surface_init (&surface->base, &cairo_analysis_surface_backend,
|
||||
CAIRO_CONTENT_COLOR_ALPHA);
|
||||
|
||||
surface->width = width;
|
||||
surface->height = height;
|
||||
|
||||
surface->target = target;
|
||||
surface->fallback = FALSE;
|
||||
|
||||
return &surface->base;
|
||||
FAIL:
|
||||
_cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
cairo_private pixman_region16_t *
|
||||
_cairo_analysis_surface_get_supported (cairo_surface_t *abstract_surface)
|
||||
{
|
||||
/* XXX */
|
||||
return NULL;
|
||||
}
|
||||
|
||||
cairo_private pixman_region16_t *
|
||||
_cairo_analysis_surface_get_unsupported (cairo_surface_t *abstract_surface)
|
||||
{
|
||||
/* XXX */
|
||||
return NULL;
|
||||
}
|
||||
|
||||
cairo_private 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;
|
||||
}
|
||||
|
||||
|
||||
@ -200,10 +200,8 @@ _cairo_array_index (cairo_array_t *array, int index)
|
||||
* which in the num_elements==0 case gets the NULL pointer here,
|
||||
* but never dereferences it.
|
||||
*/
|
||||
if (array->elements == NULL) {
|
||||
assert (index == 0);
|
||||
if (index == 0 && array->num_elements == 0)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
assert (0 <= index && index < array->num_elements);
|
||||
|
||||
|
||||
@ -218,6 +218,8 @@ _cairo_atsui_font_create_scaled (cairo_font_face_t *font_face,
|
||||
cairo_status_t status;
|
||||
|
||||
font = malloc(sizeof(cairo_atsui_font_t));
|
||||
if (font == NULL)
|
||||
return CAIRO_STATUS_NO_MEMORY;
|
||||
|
||||
_cairo_scaled_font_init(&font->base, font_face, font_matrix, ctm, options,
|
||||
&cairo_atsui_scaled_font_backend);
|
||||
@ -594,105 +596,134 @@ _cairo_atsui_font_old_show_glyphs (void *abstract_font,
|
||||
int num_glyphs)
|
||||
{
|
||||
cairo_atsui_font_t *font = abstract_font;
|
||||
CGContextRef myBitmapContext;
|
||||
CGColorSpaceRef colorSpace;
|
||||
CGContextRef myBitmapContext = 0, drawingContext;
|
||||
cairo_image_surface_t *destImageSurface;
|
||||
int i, bits_per_comp, alpha;
|
||||
int i;
|
||||
void *extra = NULL;
|
||||
cairo_bool_t can_draw_directly;
|
||||
cairo_rectangle_fixed_t rect;
|
||||
|
||||
cairo_rectangle_t rect = {dest_x, dest_y, width, height};
|
||||
_cairo_surface_acquire_dest_image(generic_surface,
|
||||
&rect,
|
||||
&destImageSurface,
|
||||
&rect,
|
||||
&extra);
|
||||
/* Check if we can draw directly to the destination surface */
|
||||
can_draw_directly = _cairo_surface_is_quartz (generic_surface) &&
|
||||
_cairo_pattern_is_opaque_solid (pattern) &&
|
||||
op == CAIRO_OPERATOR_OVER;
|
||||
|
||||
/* Create a CGBitmapContext for the dest surface for drawing into */
|
||||
if (destImageSurface->depth == 1) {
|
||||
colorSpace = CGColorSpaceCreateDeviceGray();
|
||||
bits_per_comp = 1;
|
||||
alpha = kCGImageAlphaNone;
|
||||
} else if (destImageSurface->depth == 8) {
|
||||
colorSpace = CGColorSpaceCreateDeviceGray();
|
||||
bits_per_comp = 8;
|
||||
alpha = kCGImageAlphaNone;
|
||||
} else if (destImageSurface->depth == 24) {
|
||||
colorSpace = CGColorSpaceCreateDeviceRGB();
|
||||
bits_per_comp = 8;
|
||||
alpha = kCGImageAlphaNoneSkipFirst | kCGBitmapByteOrder32Host;
|
||||
} else if (destImageSurface->depth == 32) {
|
||||
colorSpace = CGColorSpaceCreateDeviceRGB();
|
||||
bits_per_comp = 8;
|
||||
alpha = kCGImageAlphaPremultipliedFirst | kCGBitmapByteOrder32Host;
|
||||
if (!can_draw_directly) {
|
||||
CGColorSpaceRef colorSpace = 0;
|
||||
int bits_per_comp, alpha;
|
||||
|
||||
rect.x = dest_x;
|
||||
rect.y = dest_y;
|
||||
rect.width = width;
|
||||
rect.height = height;
|
||||
|
||||
_cairo_surface_acquire_dest_image(generic_surface,
|
||||
&rect,
|
||||
&destImageSurface,
|
||||
&rect,
|
||||
&extra);
|
||||
|
||||
/* Create a CGBitmapContext for the dest surface for drawing into */
|
||||
if (destImageSurface->depth == 1) {
|
||||
colorSpace = CGColorSpaceCreateDeviceGray();
|
||||
bits_per_comp = 1;
|
||||
alpha = kCGImageAlphaNone;
|
||||
} else if (destImageSurface->depth == 8) {
|
||||
colorSpace = CGColorSpaceCreateDeviceGray();
|
||||
bits_per_comp = 8;
|
||||
alpha = kCGImageAlphaNone;
|
||||
} else if (destImageSurface->depth == 24) {
|
||||
colorSpace = CGColorSpaceCreateDeviceRGB();
|
||||
bits_per_comp = 8;
|
||||
alpha = kCGImageAlphaNoneSkipFirst | kCGBitmapByteOrder32Host;
|
||||
} else if (destImageSurface->depth == 32) {
|
||||
colorSpace = CGColorSpaceCreateDeviceRGB();
|
||||
bits_per_comp = 8;
|
||||
alpha = kCGImageAlphaPremultipliedFirst | kCGBitmapByteOrder32Host;
|
||||
} else {
|
||||
// not reached
|
||||
return CAIRO_INT_STATUS_UNSUPPORTED;
|
||||
}
|
||||
|
||||
/* Create a CGBitmapContext for the dest surface for drawing into */
|
||||
colorSpace = CGColorSpaceCreateDeviceRGB();
|
||||
|
||||
myBitmapContext = CGBitmapContextCreate(destImageSurface->data,
|
||||
destImageSurface->width,
|
||||
destImageSurface->height,
|
||||
bits_per_comp,
|
||||
destImageSurface->stride,
|
||||
colorSpace,
|
||||
alpha);
|
||||
CGColorSpaceRelease(colorSpace);
|
||||
|
||||
CGContextTranslateCTM(myBitmapContext, 0, destImageSurface->height);
|
||||
CGContextScaleCTM(myBitmapContext, 1.0f, -1.0f);
|
||||
|
||||
drawingContext = myBitmapContext;
|
||||
} else {
|
||||
// not reached
|
||||
return CAIRO_INT_STATUS_UNSUPPORTED;
|
||||
drawingContext = ((cairo_quartz_surface_t *)generic_surface)->context;
|
||||
CGContextSaveGState (drawingContext);
|
||||
}
|
||||
|
||||
myBitmapContext = CGBitmapContextCreate(destImageSurface->data,
|
||||
destImageSurface->width,
|
||||
destImageSurface->height,
|
||||
bits_per_comp,
|
||||
destImageSurface->stride,
|
||||
colorSpace,
|
||||
alpha);
|
||||
CGContextTranslateCTM(myBitmapContext, 0, destImageSurface->height);
|
||||
CGContextScaleCTM(myBitmapContext, 1.0f, -1.0f);
|
||||
|
||||
ATSFontRef atsFont = FMGetATSFontRefFromFont(font->fontID);
|
||||
CGFontRef cgFont = CGFontCreateWithPlatformFont(&atsFont);
|
||||
|
||||
CGContextSetFont(myBitmapContext, cgFont);
|
||||
CGContextSetFont(drawingContext, cgFont);
|
||||
|
||||
CGAffineTransform textTransform =
|
||||
CGAffineTransformMakeWithCairoFontScale(&font->base.scale);
|
||||
|
||||
textTransform = CGAffineTransformScale(textTransform, 1.0f, -1.0f);
|
||||
|
||||
CGContextSetFontSize(myBitmapContext, 1.0);
|
||||
CGContextSetTextMatrix(myBitmapContext, textTransform);
|
||||
CGContextSetFontSize(drawingContext, 1.0);
|
||||
CGContextSetTextMatrix(drawingContext, textTransform);
|
||||
|
||||
if (pattern->type == CAIRO_PATTERN_TYPE_SOLID &&
|
||||
_cairo_pattern_is_opaque_solid(pattern))
|
||||
{
|
||||
cairo_solid_pattern_t *solid = (cairo_solid_pattern_t *)pattern;
|
||||
CGContextSetRGBFillColor(myBitmapContext,
|
||||
CGContextSetRGBFillColor(drawingContext,
|
||||
solid->color.red,
|
||||
solid->color.green,
|
||||
solid->color.blue, 1.0f);
|
||||
} else {
|
||||
CGContextSetRGBFillColor(myBitmapContext, 0.0f, 0.0f, 0.0f, 0.0f);
|
||||
CGContextSetRGBFillColor(drawingContext, 0.0f, 0.0f, 0.0f, 0.0f);
|
||||
}
|
||||
|
||||
if (_cairo_surface_is_quartz (generic_surface)) {
|
||||
cairo_quartz_surface_t *surface = (cairo_quartz_surface_t *)generic_surface;
|
||||
if (surface->clip_region) {
|
||||
pixman_box16_t *boxes = pixman_region_rects (surface->clip_region);
|
||||
int num_boxes = pixman_region_num_rects (surface->clip_region);
|
||||
CGRect stack_rects[10];
|
||||
CGRect *rects;
|
||||
int i;
|
||||
|
||||
if (num_boxes > 10)
|
||||
rects = malloc (sizeof (CGRect) * num_boxes);
|
||||
else
|
||||
rects = stack_rects;
|
||||
|
||||
for (i = 0; i < num_boxes; i++) {
|
||||
rects[i].origin.x = boxes[i].x1;
|
||||
rects[i].origin.y = boxes[i].y1;
|
||||
rects[i].size.width = boxes[i].x2 - boxes[i].x1;
|
||||
rects[i].size.height = boxes[i].y2 - boxes[i].y1;
|
||||
}
|
||||
|
||||
CGContextClipToRects (myBitmapContext, rects, num_boxes);
|
||||
|
||||
if (rects != stack_rects)
|
||||
free(rects);
|
||||
}
|
||||
} else {
|
||||
/* XXX: Need to get the text clipped */
|
||||
if (_cairo_surface_is_quartz (generic_surface)) {
|
||||
cairo_quartz_surface_t *surface = (cairo_quartz_surface_t *)generic_surface;
|
||||
if (surface->clip_region) {
|
||||
pixman_box16_t *boxes = pixman_region_rects (surface->clip_region);
|
||||
int num_boxes = pixman_region_num_rects (surface->clip_region);
|
||||
CGRect stack_rects[10];
|
||||
CGRect *rects;
|
||||
int i;
|
||||
|
||||
/* XXX: Return-value of malloc needs to be checked for
|
||||
* NULL. Can someone fix this who is more familiar with
|
||||
* the cleanup needed in this function?
|
||||
*/
|
||||
if (num_boxes > 10)
|
||||
rects = malloc (sizeof (CGRect) * num_boxes);
|
||||
else
|
||||
rects = stack_rects;
|
||||
|
||||
for (i = 0; i < num_boxes; i++) {
|
||||
rects[i].origin.x = boxes[i].x1;
|
||||
rects[i].origin.y = boxes[i].y1;
|
||||
rects[i].size.width = boxes[i].x2 - boxes[i].x1;
|
||||
rects[i].size.height = boxes[i].y2 - boxes[i].y1;
|
||||
}
|
||||
|
||||
CGContextClipToRects (drawingContext, rects, num_boxes);
|
||||
|
||||
if (rects != stack_rects)
|
||||
free(rects);
|
||||
}
|
||||
} else {
|
||||
/* XXX: Need to get the text clipped */
|
||||
}
|
||||
|
||||
/* TODO - bold and italic text
|
||||
*
|
||||
@ -705,21 +736,24 @@ _cairo_atsui_font_old_show_glyphs (void *abstract_font,
|
||||
for (i = 0; i < num_glyphs; i++) {
|
||||
CGGlyph theGlyph = glyphs[i].index;
|
||||
|
||||
CGContextShowGlyphsAtPoint(myBitmapContext,
|
||||
CGContextShowGlyphsAtPoint(drawingContext,
|
||||
glyphs[i].x,
|
||||
glyphs[i].y,
|
||||
&theGlyph, 1);
|
||||
}
|
||||
|
||||
|
||||
CGColorSpaceRelease(colorSpace);
|
||||
CGContextRelease(myBitmapContext);
|
||||
|
||||
_cairo_surface_release_dest_image(generic_surface,
|
||||
&rect,
|
||||
destImageSurface,
|
||||
&rect,
|
||||
extra);
|
||||
if (!can_draw_directly) {
|
||||
CGColorSpaceRelease(colorSpace);
|
||||
CGContextRelease(myBitmapContext);
|
||||
|
||||
_cairo_surface_release_dest_image(generic_surface,
|
||||
&rect,
|
||||
destImageSurface,
|
||||
&rect,
|
||||
extra);
|
||||
} else {
|
||||
CGContextRestoreGState (drawingContext);
|
||||
}
|
||||
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
130
mozilla/gfx/cairo/cairo/src/cairo-base85-stream.c
Normal file
130
mozilla/gfx/cairo/cairo/src/cairo-base85-stream.c
Normal file
@ -0,0 +1,130 @@
|
||||
/* cairo_output_stream.c: Output stream abstraction
|
||||
*
|
||||
* Copyright © 2005 Red Hat, Inc
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it either under the terms of the GNU Lesser General Public
|
||||
* License version 2.1 as published by the Free Software Foundation
|
||||
* (the "LGPL") or, at your option, under the terms of the Mozilla
|
||||
* Public License Version 1.1 (the "MPL"). If you do not alter this
|
||||
* notice, a recipient may use your version of this file under either
|
||||
* the MPL or the LGPL.
|
||||
*
|
||||
* You should have received a copy of the LGPL along with this library
|
||||
* in the file COPYING-LGPL-2.1; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
* You should have received a copy of the MPL along with this library
|
||||
* in the file COPYING-MPL-1.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License
|
||||
* Version 1.1 (the "License"); you may not use this file except in
|
||||
* compliance with the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY
|
||||
* OF ANY KIND, either express or implied. See the LGPL or the MPL for
|
||||
* the specific language governing rights and limitations.
|
||||
*
|
||||
* The Original Code is cairo_output_stream.c as distributed with the
|
||||
* cairo graphics library.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Red Hat, Inc.
|
||||
*
|
||||
* Author(s):
|
||||
* Kristian Høgsberg <krh@redhat.com>
|
||||
*/
|
||||
|
||||
#include "cairoint.h"
|
||||
|
||||
typedef struct _cairo_base85_stream {
|
||||
cairo_output_stream_t *output;
|
||||
unsigned char four_tuple[4];
|
||||
int pending;
|
||||
} cairo_base85_stream_t;
|
||||
|
||||
static void
|
||||
_expand_four_tuple_to_five (unsigned char four_tuple[4],
|
||||
unsigned char five_tuple[5],
|
||||
cairo_bool_t *all_zero)
|
||||
{
|
||||
uint32_t value;
|
||||
int digit, i;
|
||||
|
||||
value = four_tuple[0] << 24 | four_tuple[1] << 16 | four_tuple[2] << 8 | four_tuple[3];
|
||||
if (all_zero)
|
||||
*all_zero = TRUE;
|
||||
for (i = 0; i < 5; i++) {
|
||||
digit = value % 85;
|
||||
if (digit != 0 && all_zero)
|
||||
*all_zero = FALSE;
|
||||
five_tuple[4-i] = digit + 33;
|
||||
value = value / 85;
|
||||
}
|
||||
}
|
||||
|
||||
static cairo_status_t
|
||||
_cairo_base85_stream_write (void *closure,
|
||||
const unsigned char *data,
|
||||
unsigned int length)
|
||||
{
|
||||
cairo_base85_stream_t *stream = closure;
|
||||
const unsigned char *ptr = data;
|
||||
unsigned char five_tuple[5];
|
||||
cairo_bool_t is_zero;
|
||||
|
||||
while (length) {
|
||||
stream->four_tuple[stream->pending++] = *ptr++;
|
||||
length--;
|
||||
if (stream->pending == 4) {
|
||||
_expand_four_tuple_to_five (stream->four_tuple, five_tuple, &is_zero);
|
||||
if (is_zero)
|
||||
_cairo_output_stream_write (stream->output, "z", 1);
|
||||
else
|
||||
_cairo_output_stream_write (stream->output, five_tuple, 5);
|
||||
stream->pending = 0;
|
||||
}
|
||||
}
|
||||
|
||||
return _cairo_output_stream_get_status (stream->output);
|
||||
}
|
||||
|
||||
static cairo_status_t
|
||||
_cairo_base85_stream_close (void *closure)
|
||||
{
|
||||
cairo_status_t status;
|
||||
cairo_base85_stream_t *stream = closure;
|
||||
unsigned char five_tuple[5];
|
||||
|
||||
if (stream->pending) {
|
||||
memset (stream->four_tuple + stream->pending, 0, 4 - stream->pending);
|
||||
_expand_four_tuple_to_five (stream->four_tuple, five_tuple, NULL);
|
||||
_cairo_output_stream_write (stream->output, five_tuple, stream->pending + 1);
|
||||
}
|
||||
|
||||
/* Mark end of base85 data */
|
||||
_cairo_output_stream_printf (stream->output, "~>");
|
||||
|
||||
status = _cairo_output_stream_get_status (stream->output);
|
||||
|
||||
free (stream);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
cairo_output_stream_t *
|
||||
_cairo_base85_stream_create (cairo_output_stream_t *output)
|
||||
{
|
||||
cairo_base85_stream_t *stream;
|
||||
|
||||
stream = malloc (sizeof (cairo_base85_stream_t));
|
||||
if (stream == NULL)
|
||||
return (cairo_output_stream_t *) &cairo_output_stream_nil;
|
||||
|
||||
stream->output = output;
|
||||
stream->pending = 0;
|
||||
|
||||
return _cairo_output_stream_create (_cairo_base85_stream_write,
|
||||
_cairo_base85_stream_close,
|
||||
stream);
|
||||
}
|
||||
|
||||
@ -70,6 +70,9 @@ struct cairo_beos_surface_t {
|
||||
BBitmap* bitmap;
|
||||
|
||||
|
||||
// If true, surface and view should be deleted when this surface is
|
||||
// destroyed
|
||||
bool owns_bitmap_view;
|
||||
};
|
||||
|
||||
class AutoLockView {
|
||||
@ -92,18 +95,23 @@ class AutoLockView {
|
||||
bool mOK;
|
||||
};
|
||||
|
||||
static cairo_surface_t *
|
||||
_cairo_beos_surface_create_internal (BView* view,
|
||||
BBitmap* bmp,
|
||||
bool owns_bitmap_view = false);
|
||||
|
||||
static BRect
|
||||
_cairo_rect_to_brect (const cairo_rectangle_t* rect)
|
||||
_cairo_rect_to_brect (const cairo_rectangle_fixed_t* rect)
|
||||
{
|
||||
// A BRect is one pixel wider than you'd think
|
||||
return BRect(rect->x, rect->y, rect->x + rect->width - 1,
|
||||
rect->y + rect->height - 1);
|
||||
}
|
||||
|
||||
static cairo_rectangle_t
|
||||
static cairo_rectangle_fixed_t
|
||||
_brect_to_cairo_rect (const BRect& rect)
|
||||
{
|
||||
cairo_rectangle_t retval;
|
||||
cairo_rectangle_fixed_t retval;
|
||||
retval.x = int(rect.left + 0.5);
|
||||
retval.y = int(rect.top + 0.5);
|
||||
retval.width = rect.IntegerWidth() + 1;
|
||||
@ -359,6 +367,7 @@ _cairo_image_surface_to_bitmap (cairo_image_surface_t* surface)
|
||||
return data;
|
||||
}
|
||||
default:
|
||||
assert(0);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
@ -414,10 +423,76 @@ _cairo_op_to_be_op (cairo_operator_t cairo_op,
|
||||
};
|
||||
}
|
||||
|
||||
static cairo_surface_t *
|
||||
_cairo_beos_surface_create_similar (void *abstract_surface,
|
||||
cairo_content_t content,
|
||||
int width,
|
||||
int height)
|
||||
{
|
||||
fprintf(stderr, "Creating similar\n");
|
||||
|
||||
cairo_beos_surface_t *surface = reinterpret_cast<cairo_beos_surface_t*>(
|
||||
abstract_surface);
|
||||
|
||||
if (width <= 0)
|
||||
width = 1;
|
||||
if (height <= 0)
|
||||
height = 1;
|
||||
|
||||
BRect rect(0.0, 0.0, width - 1, height - 1);
|
||||
BBitmap* bmp;
|
||||
switch (content) {
|
||||
case CAIRO_CONTENT_ALPHA:
|
||||
// Can't support this natively
|
||||
return _cairo_image_surface_create_with_content(content, width,
|
||||
height);
|
||||
case CAIRO_CONTENT_COLOR_ALPHA:
|
||||
bmp = new BBitmap(rect, B_RGBA32, true);
|
||||
break;
|
||||
case CAIRO_CONTENT_COLOR:
|
||||
// Match the color depth
|
||||
if (surface->bitmap) {
|
||||
color_space space = surface->bitmap->ColorSpace();
|
||||
// No alpha was requested -> make sure not to return
|
||||
// a surface with alpha
|
||||
if (space == B_RGBA32)
|
||||
space = B_RGB32;
|
||||
if (space == B_RGBA15)
|
||||
space = B_RGB15;
|
||||
bmp = new BBitmap(rect, space, true);
|
||||
} else {
|
||||
BScreen scr(surface->view->Window());
|
||||
color_space space = B_RGB32;
|
||||
if (scr.IsValid())
|
||||
space = scr.ColorSpace();
|
||||
bmp = new BBitmap(rect, space, true);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
assert(0);
|
||||
return NULL;
|
||||
|
||||
};
|
||||
BView* view = new BView(rect, "Cairo bitmap view", B_FOLLOW_ALL_SIDES, 0);
|
||||
bmp->AddChild(view);
|
||||
return _cairo_beos_surface_create_internal(view, bmp, true);
|
||||
}
|
||||
|
||||
static cairo_status_t
|
||||
_cairo_beos_surface_finish (void *abstract_surface)
|
||||
{
|
||||
// Nothing to do
|
||||
cairo_beos_surface_t *surface = reinterpret_cast<cairo_beos_surface_t*>(
|
||||
abstract_surface);
|
||||
if (surface->owns_bitmap_view) {
|
||||
if (surface->bitmap)
|
||||
surface->bitmap->RemoveChild(surface->view);
|
||||
|
||||
delete surface->view;
|
||||
delete surface->bitmap;
|
||||
|
||||
surface->view = NULL;
|
||||
surface->bitmap = NULL;
|
||||
}
|
||||
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
}
|
||||
@ -474,11 +549,11 @@ _cairo_beos_surface_release_source_image (void *abstract_surfac
|
||||
|
||||
|
||||
static cairo_status_t
|
||||
_cairo_beos_surface_acquire_dest_image (void *abstract_surface,
|
||||
cairo_rectangle_t *interest_rect,
|
||||
cairo_image_surface_t **image_out,
|
||||
cairo_rectangle_t *image_rect,
|
||||
void **image_extra)
|
||||
_cairo_beos_surface_acquire_dest_image (void *abstract_surface,
|
||||
cairo_rectangle_fixed_t *interest_rect,
|
||||
cairo_image_surface_t **image_out,
|
||||
cairo_rectangle_fixed_t *image_rect,
|
||||
void **image_extra)
|
||||
{
|
||||
cairo_beos_surface_t *surface = reinterpret_cast<cairo_beos_surface_t*>(
|
||||
abstract_surface);
|
||||
@ -539,23 +614,22 @@ _cairo_beos_surface_acquire_dest_image (void *abstract_surface
|
||||
|
||||
|
||||
static void
|
||||
_cairo_beos_surface_release_dest_image (void *abstract_surface,
|
||||
cairo_rectangle_t *intersect_rect,
|
||||
cairo_image_surface_t *image,
|
||||
cairo_rectangle_t *image_rect,
|
||||
void *image_extra)
|
||||
_cairo_beos_surface_release_dest_image (void *abstract_surface,
|
||||
cairo_rectangle_fixed_t *intersect_rect,
|
||||
cairo_image_surface_t *image,
|
||||
cairo_rectangle_fixed_t *image_rect,
|
||||
void *image_extra)
|
||||
{
|
||||
fprintf(stderr, "Fallback drawing\n");
|
||||
|
||||
cairo_beos_surface_t *surface = reinterpret_cast<cairo_beos_surface_t*>(
|
||||
abstract_surface);
|
||||
|
||||
AutoLockView locker(surface->view);
|
||||
if (!locker)
|
||||
return;
|
||||
|
||||
|
||||
BBitmap* bitmap_to_draw = _cairo_image_surface_to_bitmap(image);
|
||||
|
||||
surface->view->PushState();
|
||||
|
||||
surface->view->SetDrawingMode(B_OP_COPY);
|
||||
@ -570,18 +644,18 @@ _cairo_beos_surface_release_dest_image (void *abstract_surface,
|
||||
}
|
||||
|
||||
static cairo_int_status_t
|
||||
_cairo_beos_composite (cairo_operator_t op,
|
||||
cairo_pattern_t *src,
|
||||
cairo_pattern_t *mask,
|
||||
void *dst,
|
||||
int src_x,
|
||||
int src_y,
|
||||
int mask_x,
|
||||
int mask_y,
|
||||
int dst_x,
|
||||
int dst_y,
|
||||
unsigned int width,
|
||||
unsigned int height)
|
||||
_cairo_beos_surface_composite (cairo_operator_t op,
|
||||
cairo_pattern_t *src,
|
||||
cairo_pattern_t *mask,
|
||||
void *dst,
|
||||
int src_x,
|
||||
int src_y,
|
||||
int mask_x,
|
||||
int mask_y,
|
||||
int dst_x,
|
||||
int dst_y,
|
||||
unsigned int width,
|
||||
unsigned int height)
|
||||
{
|
||||
cairo_beos_surface_t *surface = reinterpret_cast<cairo_beos_surface_t*>(
|
||||
dst);
|
||||
@ -617,63 +691,95 @@ _cairo_beos_composite (cairo_operator_t op,
|
||||
|
||||
cairo_surface_t* src_surface = reinterpret_cast<cairo_surface_pattern_t*>(src)->
|
||||
surface;
|
||||
if (_cairo_surface_is_image(src_surface)) {
|
||||
fprintf(stderr, "Composite\n");
|
||||
|
||||
// Draw it on screen.
|
||||
// Get a bitmap
|
||||
BBitmap* bmp = NULL;
|
||||
bool free_bmp = false;
|
||||
if (_cairo_surface_is_image(src_surface)) {
|
||||
cairo_image_surface_t* img_surface =
|
||||
reinterpret_cast<cairo_image_surface_t*>(src_surface);
|
||||
|
||||
BBitmap* bmp = _cairo_image_surface_to_bitmap(img_surface);
|
||||
surface->view->PushState();
|
||||
|
||||
// If our image rect is only a subrect of the desired size, and we
|
||||
// aren't using B_OP_ALPHA, then we need to fill the rect first.
|
||||
if (mode == B_OP_COPY && !bmp->Bounds().Contains(srcRect)) {
|
||||
rgb_color black = { 0, 0, 0, 0 };
|
||||
|
||||
surface->view->SetDrawingMode(mode);
|
||||
surface->view->SetHighColor(black);
|
||||
surface->view->FillRect(dstRect);
|
||||
}
|
||||
|
||||
if (mode == B_OP_ALPHA && img_surface->format != CAIRO_FORMAT_ARGB32) {
|
||||
mode = B_OP_COPY;
|
||||
|
||||
}
|
||||
surface->view->SetDrawingMode(mode);
|
||||
|
||||
if (surface->bitmap && surface->bitmap->ColorSpace() == B_RGBA32)
|
||||
surface->view->SetBlendingMode(B_PIXEL_ALPHA, B_ALPHA_COMPOSITE);
|
||||
else
|
||||
surface->view->SetBlendingMode(B_PIXEL_ALPHA, B_ALPHA_OVERLAY);
|
||||
|
||||
surface->view->DrawBitmap(bmp, srcRect, dstRect);
|
||||
|
||||
surface->view->PopState();
|
||||
delete bmp;
|
||||
|
||||
return CAIRO_INT_STATUS_SUCCESS;
|
||||
bmp = _cairo_image_surface_to_bitmap(img_surface);
|
||||
free_bmp = true;
|
||||
} else if (src_surface->backend == surface->base.backend) {
|
||||
cairo_beos_surface_t *beos_surface =
|
||||
reinterpret_cast<cairo_beos_surface_t*>(src_surface);
|
||||
if (beos_surface->bitmap) {
|
||||
AutoLockView locker(beos_surface->view);
|
||||
if (locker)
|
||||
beos_surface->view->Sync();
|
||||
bmp = beos_surface->bitmap;
|
||||
} else {
|
||||
_cairo_beos_view_to_bitmap(surface->view, &bmp);
|
||||
free_bmp = true;
|
||||
}
|
||||
}
|
||||
|
||||
return CAIRO_INT_STATUS_UNSUPPORTED;
|
||||
if (!bmp)
|
||||
return CAIRO_INT_STATUS_UNSUPPORTED;
|
||||
|
||||
// So, BeOS seems to screw up painting an opaque bitmap onto a
|
||||
// translucent one (it makes them partly transparent). Just return
|
||||
// unsupported.
|
||||
if (bmp->ColorSpace() == B_RGB32 && surface->bitmap &&
|
||||
surface->bitmap->ColorSpace() == B_RGBA32 &&
|
||||
(mode == B_OP_COPY || mode == B_OP_ALPHA))
|
||||
{
|
||||
if (free_bmp)
|
||||
delete bmp;
|
||||
return CAIRO_INT_STATUS_UNSUPPORTED;
|
||||
}
|
||||
|
||||
fprintf(stderr, "Composite\n");
|
||||
|
||||
// Draw it on screen.
|
||||
surface->view->PushState();
|
||||
|
||||
// If our image rect is only a subrect of the desired size, and we
|
||||
// aren't using B_OP_ALPHA, then we need to fill the rect first.
|
||||
if (mode == B_OP_COPY && !bmp->Bounds().Contains(srcRect)) {
|
||||
rgb_color black = { 0, 0, 0, 0 };
|
||||
|
||||
surface->view->SetDrawingMode(mode);
|
||||
surface->view->SetHighColor(black);
|
||||
surface->view->FillRect(dstRect);
|
||||
}
|
||||
|
||||
if (mode == B_OP_ALPHA && bmp->ColorSpace() == B_RGB32) {
|
||||
mode = B_OP_COPY;
|
||||
}
|
||||
surface->view->SetDrawingMode(mode);
|
||||
|
||||
if (surface->bitmap && surface->bitmap->ColorSpace() == B_RGBA32)
|
||||
surface->view->SetBlendingMode(B_PIXEL_ALPHA, B_ALPHA_COMPOSITE);
|
||||
else
|
||||
surface->view->SetBlendingMode(B_PIXEL_ALPHA, B_ALPHA_OVERLAY);
|
||||
|
||||
surface->view->DrawBitmap(bmp, srcRect, dstRect);
|
||||
|
||||
surface->view->PopState();
|
||||
|
||||
if (free_bmp)
|
||||
delete bmp;
|
||||
|
||||
return CAIRO_INT_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
_cairo_beos_fill_rectangle (cairo_beos_surface_t *surface,
|
||||
cairo_rectangle_t *rect)
|
||||
_cairo_beos_surface_fill_rectangle (cairo_beos_surface_t *surface,
|
||||
cairo_rectangle_fixed_t *rect)
|
||||
{
|
||||
BRect brect(_cairo_rect_to_brect(rect));
|
||||
surface->view->FillRect(brect);
|
||||
}
|
||||
|
||||
static cairo_int_status_t
|
||||
_cairo_beos_fill_rectangles (void *abstract_surface,
|
||||
cairo_operator_t op,
|
||||
const cairo_color_t *color,
|
||||
cairo_rectangle_t *rects,
|
||||
int num_rects)
|
||||
_cairo_beos_surface_fill_rectangles (void *abstract_surface,
|
||||
cairo_operator_t op,
|
||||
const cairo_color_t *color,
|
||||
cairo_rectangle_fixed_t *rects,
|
||||
int num_rects)
|
||||
{
|
||||
fprintf(stderr, "Drawing %i rectangles\n", num_rects);
|
||||
cairo_beos_surface_t *surface = reinterpret_cast<cairo_beos_surface_t*>(
|
||||
@ -716,7 +822,7 @@ _cairo_beos_fill_rectangles (void *abstract_surface,
|
||||
surface->view->SetBlendingMode(B_CONSTANT_ALPHA, B_ALPHA_OVERLAY);
|
||||
|
||||
for (int i = 0; i < num_rects; ++i) {
|
||||
_cairo_beos_fill_rectangle(surface, &rects[i]);
|
||||
_cairo_beos_surface_fill_rectangle(surface, &rects[i]);
|
||||
}
|
||||
|
||||
surface->view->PopState();
|
||||
@ -756,8 +862,8 @@ _cairo_beos_surface_set_clip_region (void *abstract_surface,
|
||||
}
|
||||
|
||||
static cairo_int_status_t
|
||||
_cairo_beos_surface_get_extents (void *abstract_surface,
|
||||
cairo_rectangle_t *rectangle)
|
||||
_cairo_beos_surface_get_extents (void *abstract_surface,
|
||||
cairo_rectangle_fixed_t *rectangle)
|
||||
{
|
||||
cairo_beos_surface_t *surface = reinterpret_cast<cairo_beos_surface_t*>(
|
||||
abstract_surface);
|
||||
@ -778,15 +884,15 @@ _cairo_beos_surface_get_extents (void *abstract_surface,
|
||||
|
||||
static const struct _cairo_surface_backend cairo_beos_surface_backend = {
|
||||
CAIRO_SURFACE_TYPE_BEOS,
|
||||
NULL, /* create_similar */
|
||||
_cairo_beos_surface_create_similar,
|
||||
_cairo_beos_surface_finish,
|
||||
_cairo_beos_surface_acquire_source_image,
|
||||
_cairo_beos_surface_release_source_image,
|
||||
_cairo_beos_surface_acquire_dest_image,
|
||||
_cairo_beos_surface_release_dest_image,
|
||||
NULL, /* clone_similar */
|
||||
_cairo_beos_composite, /* composite */
|
||||
_cairo_beos_fill_rectangles,
|
||||
_cairo_beos_surface_composite, /* composite */
|
||||
_cairo_beos_surface_fill_rectangles,
|
||||
NULL, /* composite_trapezoids */
|
||||
NULL, /* copy_page */
|
||||
NULL, /* show_page */
|
||||
@ -807,6 +913,31 @@ static const struct _cairo_surface_backend cairo_beos_surface_backend = {
|
||||
NULL /* show_glyphs */
|
||||
};
|
||||
|
||||
static cairo_surface_t *
|
||||
_cairo_beos_surface_create_internal (BView* view,
|
||||
BBitmap* bmp,
|
||||
bool owns_bitmap_view)
|
||||
{
|
||||
// Must use malloc, because cairo code will use free() on the surface
|
||||
cairo_beos_surface_t *surface = static_cast<cairo_beos_surface_t*>(
|
||||
malloc(sizeof(cairo_beos_surface_t)));
|
||||
if (surface == NULL) {
|
||||
_cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
return const_cast<cairo_surface_t*>(&_cairo_surface_nil);
|
||||
}
|
||||
|
||||
cairo_content_t content = CAIRO_CONTENT_COLOR;
|
||||
if (bmp && (bmp->ColorSpace() == B_RGBA32 || bmp->ColorSpace() == B_RGBA15))
|
||||
content = CAIRO_CONTENT_COLOR_ALPHA;
|
||||
_cairo_surface_init(&surface->base, &cairo_beos_surface_backend, content);
|
||||
|
||||
surface->view = view;
|
||||
surface->bitmap = bmp;
|
||||
surface->owns_bitmap_view = owns_bitmap_view;
|
||||
|
||||
return (cairo_surface_t *) surface;
|
||||
}
|
||||
|
||||
/**
|
||||
* cairo_beos_surface_create:
|
||||
* @view: The view to draw on
|
||||
@ -843,20 +974,7 @@ cairo_surface_t *
|
||||
cairo_beos_surface_create_for_bitmap (BView* view,
|
||||
BBitmap* bmp)
|
||||
{
|
||||
// Must use malloc, because cairo code will use free() on the surface
|
||||
cairo_beos_surface_t *surface = static_cast<cairo_beos_surface_t*>(
|
||||
malloc(sizeof(cairo_beos_surface_t)));
|
||||
if (surface == NULL) {
|
||||
_cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
return const_cast<cairo_surface_t*>(&_cairo_surface_nil);
|
||||
}
|
||||
|
||||
_cairo_surface_init(&surface->base, &cairo_beos_surface_backend);
|
||||
|
||||
surface->view = view;
|
||||
surface->bitmap = bmp;
|
||||
|
||||
return (cairo_surface_t *) surface;
|
||||
return _cairo_beos_surface_create_internal(view, bmp);
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
@ -88,7 +88,7 @@ typedef struct _cairo_cache_entry {
|
||||
} cairo_cache_entry_t;
|
||||
|
||||
typedef cairo_bool_t
|
||||
(*cairo_cache_keys_equal_func_t) (void *key_a, void *key_b);
|
||||
(*cairo_cache_keys_equal_func_t) (const void *key_a, const void *key_b);
|
||||
|
||||
typedef void
|
||||
(*cairo_cache_callback_func_t) (void *entry,
|
||||
|
||||
@ -61,7 +61,7 @@ struct _cairo_clip {
|
||||
* clip paths
|
||||
*/
|
||||
cairo_surface_t *surface;
|
||||
cairo_rectangle_t surface_rect;
|
||||
cairo_rectangle_fixed_t surface_rect;
|
||||
/*
|
||||
* Surface clip serial number to store
|
||||
* in the surface when this clip is set
|
||||
@ -104,20 +104,25 @@ _cairo_clip_clip (cairo_clip_t *clip,
|
||||
cairo_surface_t *target);
|
||||
|
||||
cairo_private cairo_status_t
|
||||
_cairo_clip_intersect_to_rectangle (cairo_clip_t *clip,
|
||||
cairo_rectangle_t *rectangle);
|
||||
_cairo_clip_intersect_to_rectangle (cairo_clip_t *clip,
|
||||
cairo_rectangle_fixed_t *rectangle);
|
||||
|
||||
cairo_private cairo_status_t
|
||||
_cairo_clip_intersect_to_region (cairo_clip_t *clip,
|
||||
pixman_region16_t *region);
|
||||
|
||||
cairo_private cairo_status_t
|
||||
_cairo_clip_combine_to_surface (cairo_clip_t *clip,
|
||||
cairo_operator_t op,
|
||||
cairo_surface_t *dst,
|
||||
int dst_x,
|
||||
int dst_y,
|
||||
const cairo_rectangle_t *extents);
|
||||
_cairo_clip_combine_to_surface (cairo_clip_t *clip,
|
||||
cairo_operator_t op,
|
||||
cairo_surface_t *dst,
|
||||
int dst_x,
|
||||
int dst_y,
|
||||
const cairo_rectangle_fixed_t *extents);
|
||||
|
||||
cairo_private void
|
||||
_cairo_clip_translate (cairo_clip_t *clip,
|
||||
cairo_fixed_t tx,
|
||||
cairo_fixed_t ty);
|
||||
|
||||
cairo_private cairo_bool_t
|
||||
_cairo_clip_has_clip (cairo_clip_t *clip);
|
||||
|
||||
@ -119,8 +119,8 @@ _cairo_clip_reset (cairo_clip_t *clip)
|
||||
}
|
||||
|
||||
cairo_status_t
|
||||
_cairo_clip_intersect_to_rectangle (cairo_clip_t *clip,
|
||||
cairo_rectangle_t *rectangle)
|
||||
_cairo_clip_intersect_to_rectangle (cairo_clip_t *clip,
|
||||
cairo_rectangle_fixed_t *rectangle)
|
||||
{
|
||||
if (!clip)
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
@ -201,12 +201,12 @@ _cairo_clip_intersect_to_region (cairo_clip_t *clip,
|
||||
* which has its origin at dst_x, dst_y in backend coordinates
|
||||
*/
|
||||
cairo_status_t
|
||||
_cairo_clip_combine_to_surface (cairo_clip_t *clip,
|
||||
cairo_operator_t op,
|
||||
cairo_surface_t *dst,
|
||||
int dst_x,
|
||||
int dst_y,
|
||||
const cairo_rectangle_t *extents)
|
||||
_cairo_clip_combine_to_surface (cairo_clip_t *clip,
|
||||
cairo_operator_t op,
|
||||
cairo_surface_t *dst,
|
||||
int dst_x,
|
||||
int dst_y,
|
||||
const cairo_rectangle_fixed_t *extents)
|
||||
{
|
||||
cairo_pattern_union_t pattern;
|
||||
cairo_status_t status;
|
||||
@ -336,7 +336,7 @@ _cairo_clip_intersect_mask (cairo_clip_t *clip,
|
||||
{
|
||||
cairo_pattern_union_t pattern;
|
||||
cairo_box_t extents;
|
||||
cairo_rectangle_t surface_rect, target_rect;
|
||||
cairo_rectangle_fixed_t surface_rect, target_rect;
|
||||
cairo_surface_t *surface;
|
||||
cairo_status_t status;
|
||||
|
||||
|
||||
@ -72,6 +72,7 @@ cairo_debug_reset_static_data (void)
|
||||
#endif
|
||||
}
|
||||
|
||||
#if 0
|
||||
/*
|
||||
* clip dumper
|
||||
*/
|
||||
@ -261,3 +262,4 @@ cairo_debug_dump_trapezoid_array (cairo_trapezoid_t *traps,
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@ -235,10 +235,10 @@ static IDirectFBSurface *cairo_directfb_buffer_surface_create(IDirectFB *dfb,voi
|
||||
|
||||
static cairo_status_t
|
||||
_cairo_directfb_surface_get_image (cairo_directfb_surface_t *surface,
|
||||
cairo_rectangle_t *interest,
|
||||
cairo_image_surface_t **image_out,
|
||||
cairo_rectangle_t *rect_out,
|
||||
DFBSurfaceLockFlags flags)
|
||||
cairo_rectangle_fixed_t *interest,
|
||||
cairo_image_surface_t **image_out,
|
||||
cairo_rectangle_fixed_t *rect_out,
|
||||
DFBSurfaceLockFlags flags)
|
||||
{
|
||||
int pitch;
|
||||
void *data;
|
||||
@ -395,11 +395,11 @@ _cairo_directfb_surface_release_source_image (void *abstract_surface,
|
||||
}
|
||||
|
||||
static cairo_status_t
|
||||
_cairo_directfb_surface_acquire_dest_image (void *abstract_surface,
|
||||
cairo_rectangle_t *interest_rect,
|
||||
cairo_image_surface_t **image_out,
|
||||
cairo_rectangle_t *image_rect_out,
|
||||
void **image_extra)
|
||||
_cairo_directfb_surface_acquire_dest_image (void *abstract_surface,
|
||||
cairo_rectangle_fixed_t *interest_rect,
|
||||
cairo_image_surface_t **image_out,
|
||||
cairo_rectangle_fixed_t *image_rect_out,
|
||||
void **image_extra)
|
||||
{
|
||||
cairo_directfb_surface_t *surface = abstract_surface;
|
||||
*image_extra = interest_rect;
|
||||
@ -408,11 +408,11 @@ _cairo_directfb_surface_acquire_dest_image (void *abstract_surfac
|
||||
}
|
||||
|
||||
static void
|
||||
_cairo_directfb_surface_release_dest_image (void *abstract_surface,
|
||||
cairo_rectangle_t *interest_rect,
|
||||
cairo_image_surface_t *image,
|
||||
cairo_rectangle_t *image_rect,
|
||||
void *image_extra)
|
||||
_cairo_directfb_surface_release_dest_image (void *abstract_surface,
|
||||
cairo_rectangle_fixed_t *interest_rect,
|
||||
cairo_image_surface_t *image,
|
||||
cairo_rectangle_fixed_t *image_rect,
|
||||
void *image_extra)
|
||||
{
|
||||
cairo_directfb_surface_t *surface = abstract_surface;
|
||||
IDirectFBSurface *buffer=surface->buffer;
|
||||
@ -519,11 +519,11 @@ _cairo_directfb_surface_composite (cairo_operator_t op,
|
||||
#endif
|
||||
|
||||
static cairo_int_status_t
|
||||
_cairo_directfb_surface_fill_rectangles (void *abstract_surface,
|
||||
cairo_operator_t op,
|
||||
const cairo_color_t *color,
|
||||
cairo_rectangle_t *rects,
|
||||
int n_rects)
|
||||
_cairo_directfb_surface_fill_rectangles (void *abstract_surface,
|
||||
cairo_operator_t op,
|
||||
const cairo_color_t *color,
|
||||
cairo_rectangle_fixed_t *rects,
|
||||
int n_rects)
|
||||
{
|
||||
int i,k;
|
||||
cairo_directfb_surface_t *surface = abstract_surface;
|
||||
@ -590,8 +590,8 @@ _cairo_directfb_surface_set_clip_region (void *abstract_surface,
|
||||
}
|
||||
|
||||
static cairo_int_status_t
|
||||
_cairo_directfb_abstract_surface_get_extents (void *abstract_surface,
|
||||
cairo_rectangle_t *rectangle)
|
||||
_cairo_directfb_abstract_surface_get_extents (void *abstract_surface,
|
||||
cairo_rectangle_fixed_t *rectangle)
|
||||
{
|
||||
if( rectangle ) {
|
||||
cairo_directfb_surface_t *surface = abstract_surface;
|
||||
@ -790,7 +790,9 @@ cairo_directfb_surface_create (IDirectFB *dfb,IDirectFBSurface *dfbsurface)
|
||||
cairo_directfb_surface_t *surface = calloc(1,sizeof(cairo_directfb_surface_t));
|
||||
if( surface == NULL )
|
||||
return NULL;
|
||||
_cairo_surface_init (&surface->base, &cairo_directfb_surface_backend);
|
||||
/* XXX: The content value here might be totally wrong. */
|
||||
_cairo_surface_init (&surface->base, &cairo_directfb_surface_backend,
|
||||
CAIRO_CONTENT_COLOR_ALPHA);
|
||||
/*Reference the surface */
|
||||
dfb->AddRef(dfb);
|
||||
dfbsurface->AddRef(dfbsurface);
|
||||
|
||||
@ -210,8 +210,8 @@ cairo_font_face_set_user_data (cairo_font_face_t *font_face,
|
||||
static const cairo_font_face_backend_t _cairo_toy_font_face_backend;
|
||||
|
||||
static int
|
||||
_cairo_toy_font_face_keys_equal (void *key_a,
|
||||
void *key_b);
|
||||
_cairo_toy_font_face_keys_equal (const void *key_a,
|
||||
const void *key_b);
|
||||
|
||||
/* We maintain a hash table from family/weight/slant =>
|
||||
* cairo_font_face_t for cairo_toy_font_t. The primary purpose of
|
||||
@ -312,11 +312,11 @@ _cairo_toy_font_face_fini (cairo_toy_font_face_t *font_face)
|
||||
}
|
||||
|
||||
static int
|
||||
_cairo_toy_font_face_keys_equal (void *key_a,
|
||||
void *key_b)
|
||||
_cairo_toy_font_face_keys_equal (const void *key_a,
|
||||
const void *key_b)
|
||||
{
|
||||
cairo_toy_font_face_t *face_a = key_a;
|
||||
cairo_toy_font_face_t *face_b = key_b;
|
||||
const cairo_toy_font_face_t *face_a = key_a;
|
||||
const cairo_toy_font_face_t *face_b = key_b;
|
||||
|
||||
return (strcmp (face_a->family, face_b->family) == 0 &&
|
||||
face_a->slant == face_b->slant &&
|
||||
|
||||
@ -103,8 +103,8 @@ struct _cairo_ft_unscaled_font {
|
||||
};
|
||||
|
||||
static int
|
||||
_cairo_ft_unscaled_font_keys_equal (void *key_a,
|
||||
void *key_b);
|
||||
_cairo_ft_unscaled_font_keys_equal (const void *key_a,
|
||||
const void *key_b);
|
||||
|
||||
static void
|
||||
_cairo_ft_unscaled_font_fini (cairo_ft_unscaled_font_t *unscaled);
|
||||
@ -365,11 +365,11 @@ _cairo_ft_unscaled_font_fini (cairo_ft_unscaled_font_t *unscaled)
|
||||
}
|
||||
|
||||
static int
|
||||
_cairo_ft_unscaled_font_keys_equal (void *key_a,
|
||||
void *key_b)
|
||||
_cairo_ft_unscaled_font_keys_equal (const void *key_a,
|
||||
const void *key_b)
|
||||
{
|
||||
cairo_ft_unscaled_font_t *unscaled_a = key_a;
|
||||
cairo_ft_unscaled_font_t *unscaled_b = key_b;
|
||||
const cairo_ft_unscaled_font_t *unscaled_a = key_a;
|
||||
const cairo_ft_unscaled_font_t *unscaled_b = key_b;
|
||||
|
||||
return (strcmp (unscaled_a->filename, unscaled_b->filename) == 0 &&
|
||||
unscaled_a->id == unscaled_b->id);
|
||||
@ -1227,7 +1227,9 @@ const cairo_scaled_font_backend_t cairo_ft_scaled_font_backend;
|
||||
static cairo_ft_options_t
|
||||
_get_pattern_ft_options (FcPattern *pattern)
|
||||
{
|
||||
FcBool antialias, vertical_layout, hinting, autohint;
|
||||
FcBool antialias, vertical_layout, hinting, autohint, bitmap;
|
||||
FcBool transform;
|
||||
FcMatrix *font_matrix;
|
||||
cairo_ft_options_t ft_options;
|
||||
int rgba;
|
||||
#ifdef FC_HINT_STYLE
|
||||
@ -1237,15 +1239,31 @@ _get_pattern_ft_options (FcPattern *pattern)
|
||||
|
||||
ft_options.load_flags = 0;
|
||||
ft_options.extra_flags = 0;
|
||||
|
||||
#ifndef FC_EMBEDDED_BITMAP
|
||||
#define FC_EMBEDDED_BITMAP "embeddedbitmap"
|
||||
#endif
|
||||
|
||||
if (FcPatternGetMatrix (pattern,
|
||||
FC_MATRIX, 0, &font_matrix) != FcResultMatch)
|
||||
font_matrix = NULL;
|
||||
|
||||
transform = (font_matrix && (font_matrix->xx != 1 || font_matrix->xy != 0 ||
|
||||
font_matrix->yx != 0 || font_matrix->yy != 1));
|
||||
|
||||
/* Check whether to force use of embedded bitmaps */
|
||||
if (FcPatternGetBool (pattern,
|
||||
FC_EMBEDDED_BITMAP, 0, &bitmap) != FcResultMatch)
|
||||
bitmap = FcFalse;
|
||||
|
||||
/* disable antialiasing if requested */
|
||||
if (FcPatternGetBool (pattern,
|
||||
FC_ANTIALIAS, 0, &antialias) != FcResultMatch)
|
||||
antialias = FcTrue;
|
||||
|
||||
if (antialias)
|
||||
if ((!bitmap && antialias) || transform)
|
||||
ft_options.load_flags |= FT_LOAD_NO_BITMAP;
|
||||
else
|
||||
else if (!antialias)
|
||||
ft_options.load_flags |= FT_LOAD_MONOCHROME;
|
||||
|
||||
/* disable hinting if requested */
|
||||
@ -2145,9 +2163,10 @@ cairo_ft_font_options_substitute (const cairo_font_options_t *options,
|
||||
*
|
||||
* Creates a new font face for the FreeType font backend based on a
|
||||
* fontconfig pattern. This font can then be used with
|
||||
* cairo_set_font_face() or cairo_font_create(). The #cairo_scaled_font_t
|
||||
* returned from cairo_font_create() is also for the FreeType backend
|
||||
* and can be used with functions such as cairo_ft_font_lock_face().
|
||||
* cairo_set_font_face() or cairo_scaled_font_create(). The
|
||||
* #cairo_scaled_font_t returned from cairo_scaled_font_create() is
|
||||
* also for the FreeType backend and can be used with functions such
|
||||
* as cairo_ft_font_lock_face().
|
||||
*
|
||||
* Font rendering options are representated both here and when you
|
||||
* call cairo_scaled_font_create(). Font options that have a representation
|
||||
@ -2198,11 +2217,12 @@ cairo_ft_font_face_create_for_pattern (FcPattern *pattern)
|
||||
* are useful. You should not pass any of the flags affecting
|
||||
* the load target, such as %FT_LOAD_TARGET_LIGHT.
|
||||
*
|
||||
* Creates a new font face for the FreeType font backend from a pre-opened
|
||||
* FreeType face. This font can then be used with
|
||||
* cairo_set_font_face() or cairo_font_create(). The #cairo_scaled_font_t
|
||||
* returned from cairo_font_create() is also for the FreeType backend
|
||||
* and can be used with functions such as cairo_ft_font_lock_face().
|
||||
* Creates a new font face for the FreeType font backend from a
|
||||
* pre-opened FreeType face. This font can then be used with
|
||||
* cairo_set_font_face() or cairo_scaled_font_create(). The
|
||||
* #cairo_scaled_font_t returned from cairo_scaled_font_create() is
|
||||
* also for the FreeType backend and can be used with functions such
|
||||
* as cairo_ft_font_lock_face().
|
||||
*
|
||||
* Return value: a newly created #cairo_font_face_t. Free with
|
||||
* cairo_font_face_destroy() when you are done using it.
|
||||
|
||||
@ -110,10 +110,10 @@ _cairo_glitz_surface_create_similar (void *abstract_src,
|
||||
}
|
||||
|
||||
static cairo_status_t
|
||||
_cairo_glitz_surface_get_image (cairo_glitz_surface_t *surface,
|
||||
cairo_rectangle_t *interest,
|
||||
cairo_image_surface_t **image_out,
|
||||
cairo_rectangle_t *rect_out)
|
||||
_cairo_glitz_surface_get_image (cairo_glitz_surface_t *surface,
|
||||
cairo_rectangle_fixed_t *interest,
|
||||
cairo_image_surface_t **image_out,
|
||||
cairo_rectangle_fixed_t *rect_out)
|
||||
{
|
||||
cairo_image_surface_t *image;
|
||||
int x1, y1, x2, y2;
|
||||
@ -317,11 +317,11 @@ _cairo_glitz_surface_release_source_image (void *abstract_surface,
|
||||
}
|
||||
|
||||
static cairo_status_t
|
||||
_cairo_glitz_surface_acquire_dest_image (void *abstract_surface,
|
||||
cairo_rectangle_t *interest_rect,
|
||||
cairo_image_surface_t **image_out,
|
||||
cairo_rectangle_t *image_rect_out,
|
||||
void **image_extra)
|
||||
_cairo_glitz_surface_acquire_dest_image (void *abstract_surface,
|
||||
cairo_rectangle_fixed_t *interest_rect,
|
||||
cairo_image_surface_t **image_out,
|
||||
cairo_rectangle_fixed_t *image_rect_out,
|
||||
void **image_extra)
|
||||
{
|
||||
cairo_glitz_surface_t *surface = abstract_surface;
|
||||
cairo_image_surface_t *image;
|
||||
@ -339,11 +339,11 @@ _cairo_glitz_surface_acquire_dest_image (void *abstract_surface,
|
||||
}
|
||||
|
||||
static void
|
||||
_cairo_glitz_surface_release_dest_image (void *abstract_surface,
|
||||
cairo_rectangle_t *interest_rect,
|
||||
cairo_image_surface_t *image,
|
||||
cairo_rectangle_t *image_rect,
|
||||
void *image_extra)
|
||||
_cairo_glitz_surface_release_dest_image (void *abstract_surface,
|
||||
cairo_rectangle_fixed_t *interest_rect,
|
||||
cairo_image_surface_t *image,
|
||||
cairo_rectangle_fixed_t *image_rect,
|
||||
void *image_extra)
|
||||
{
|
||||
cairo_glitz_surface_t *surface = abstract_surface;
|
||||
|
||||
@ -918,11 +918,11 @@ _cairo_glitz_surface_composite (cairo_operator_t op,
|
||||
}
|
||||
|
||||
static cairo_int_status_t
|
||||
_cairo_glitz_surface_fill_rectangles (void *abstract_dst,
|
||||
cairo_operator_t op,
|
||||
const cairo_color_t *color,
|
||||
cairo_rectangle_t *rects,
|
||||
int n_rects)
|
||||
_cairo_glitz_surface_fill_rectangles (void *abstract_dst,
|
||||
cairo_operator_t op,
|
||||
const cairo_color_t *color,
|
||||
cairo_rectangle_fixed_t *rects,
|
||||
int n_rects)
|
||||
{
|
||||
cairo_glitz_surface_t *dst = abstract_dst;
|
||||
|
||||
@ -1140,7 +1140,7 @@ _cairo_glitz_surface_composite_trapezoids (cairo_operator_t op,
|
||||
int stride;
|
||||
|
||||
stride = (width + 3) & -4;
|
||||
data = malloc (stride * height);
|
||||
data = calloc (stride * height, 1);
|
||||
if (!data)
|
||||
{
|
||||
_cairo_glitz_pattern_release_surface (src_pattern, src, &attributes);
|
||||
@ -1149,8 +1149,6 @@ _cairo_glitz_surface_composite_trapezoids (cairo_operator_t op,
|
||||
return CAIRO_STATUS_NO_MEMORY;
|
||||
}
|
||||
|
||||
memset (data, 0, stride * height);
|
||||
|
||||
/* using negative stride */
|
||||
ptr = (unsigned char *) data + stride * (height - 1);
|
||||
|
||||
@ -1258,8 +1256,8 @@ _cairo_glitz_surface_set_clip_region (void *abstract_surface,
|
||||
}
|
||||
|
||||
static cairo_int_status_t
|
||||
_cairo_glitz_surface_get_extents (void *abstract_surface,
|
||||
cairo_rectangle_t *rectangle)
|
||||
_cairo_glitz_surface_get_extents (void *abstract_surface,
|
||||
cairo_rectangle_fixed_t *rectangle)
|
||||
{
|
||||
cairo_glitz_surface_t *surface = abstract_surface;
|
||||
|
||||
@ -2165,7 +2163,9 @@ cairo_glitz_surface_create (glitz_surface_t *surface)
|
||||
return (cairo_surface_t*) &_cairo_surface_nil;
|
||||
}
|
||||
|
||||
_cairo_surface_init (&crsurface->base, &cairo_glitz_surface_backend);
|
||||
/* XXX: The content value here might be totally wrong. */
|
||||
_cairo_surface_init (&crsurface->base, &cairo_glitz_surface_backend,
|
||||
CAIRO_CONTENT_COLOR_ALPHA);
|
||||
|
||||
glitz_surface_reference (surface);
|
||||
|
||||
|
||||
@ -371,51 +371,6 @@ _cairo_gstate_get_original_target (cairo_gstate_t *gstate)
|
||||
return gstate->original_target;
|
||||
}
|
||||
|
||||
/**
|
||||
* _cairo_gstate_get_target_offsets_from_original
|
||||
* @gstate: a #cairo_gstate_t
|
||||
* @dx: device offset from gstate original target
|
||||
* @dy: device offset from gstate original target
|
||||
*
|
||||
* Return the device offsets in dx, dy for the current group target
|
||||
* from the original target at the top of the gstate chain.
|
||||
**/
|
||||
void
|
||||
_cairo_gstate_get_target_offsets_from_original (cairo_gstate_t *gstate,
|
||||
double *dx,
|
||||
double *dy)
|
||||
{
|
||||
/* Because the device offsets for the current group target are
|
||||
* always relative to its parent, we have to walk up the gstate
|
||||
* stack to figure out the actual device offsets. */
|
||||
|
||||
double x = 0.0, y = 0.0;
|
||||
double prevx = 0.0, prevy = 0.0;
|
||||
while (gstate) {
|
||||
if (gstate->parent_target) {
|
||||
/* The device offset on a group surface is relative to its
|
||||
* parent; we need to recover the offset to the actual
|
||||
* top-level surface origin. So we increase the offsets
|
||||
* by the difference between the previous (child) and the
|
||||
* current (parent). We only check for
|
||||
* gstate->parent_target to catch the actual redirection
|
||||
* levels; we then use the target field in the gstate,
|
||||
* which is the actual group target at that point.*/
|
||||
x += (prevx - gstate->target->device_x_offset);
|
||||
y += (prevy - gstate->target->device_y_offset);
|
||||
|
||||
prevx = gstate->target->device_x_offset;
|
||||
prevy = gstate->target->device_y_offset;
|
||||
}
|
||||
gstate = gstate->next;
|
||||
}
|
||||
|
||||
if (dx)
|
||||
*dx = x;
|
||||
if (dy)
|
||||
*dy = y;
|
||||
}
|
||||
|
||||
/**
|
||||
* _cairo_gstate_get_clip:
|
||||
* @gstate: a #cairo_gstate_t
|
||||
@ -1007,19 +962,19 @@ BAIL:
|
||||
/* XXX We currently have a confusing mix of boxes and rectangles as
|
||||
* exemplified by this function. A cairo_box_t is a rectangular area
|
||||
* represented by the coordinates of the upper left and lower right
|
||||
* corners, expressed in fixed point numbers. A cairo_rectangle_t is
|
||||
* corners, expressed in fixed point numbers. A cairo_rectangle_fixed_t is
|
||||
* also a rectangular area, but represented by the upper left corner
|
||||
* and the width and the height, as integer numbers.
|
||||
*
|
||||
* This function converts a cairo_box_t to a cairo_rectangle_t by
|
||||
* This function converts a cairo_box_t to a cairo_rectangle_fixed_t by
|
||||
* increasing the area to the nearest integer coordinates. We should
|
||||
* standardize on cairo_rectangle_t and cairo_rectangle_fixed_t, and
|
||||
* standardize on cairo_rectangle_fixed_t and cairo_rectangle_fixed_t, and
|
||||
* this function could be renamed to the more reasonable
|
||||
* _cairo_rectangle_fixed_round.
|
||||
*/
|
||||
|
||||
void
|
||||
_cairo_box_round_to_rectangle (cairo_box_t *box, cairo_rectangle_t *rectangle)
|
||||
_cairo_box_round_to_rectangle (cairo_box_t *box, cairo_rectangle_fixed_t *rectangle)
|
||||
{
|
||||
rectangle->x = _cairo_fixed_integer_floor (box->p1.x);
|
||||
rectangle->y = _cairo_fixed_integer_floor (box->p1.y);
|
||||
@ -1028,7 +983,7 @@ _cairo_box_round_to_rectangle (cairo_box_t *box, cairo_rectangle_t *rectangle)
|
||||
}
|
||||
|
||||
void
|
||||
_cairo_rectangle_intersect (cairo_rectangle_t *dest, cairo_rectangle_t *src)
|
||||
_cairo_rectangle_intersect (cairo_rectangle_fixed_t *dest, cairo_rectangle_fixed_t *src)
|
||||
{
|
||||
int x1, y1, x2, y2;
|
||||
|
||||
|
||||
@ -85,7 +85,7 @@ typedef struct _cairo_hash_entry {
|
||||
} cairo_hash_entry_t;
|
||||
|
||||
typedef cairo_bool_t
|
||||
(*cairo_hash_keys_equal_func_t) (void *key_a, void *key_b);
|
||||
(*cairo_hash_keys_equal_func_t) (const void *key_a, const void *key_b);
|
||||
|
||||
typedef cairo_bool_t
|
||||
(*cairo_hash_predicate_func_t) (void *entry);
|
||||
|
||||
@ -124,6 +124,7 @@ struct _cairo_hash_table {
|
||||
cairo_hash_entry_t **entries;
|
||||
|
||||
unsigned long live_entries;
|
||||
unsigned long iterating; /* Iterating, no insert, no resize */
|
||||
};
|
||||
|
||||
/**
|
||||
@ -163,6 +164,7 @@ _cairo_hash_table_create (cairo_hash_keys_equal_func_t keys_equal)
|
||||
}
|
||||
|
||||
hash_table->live_entries = 0;
|
||||
hash_table->iterating = 0;
|
||||
|
||||
return hash_table;
|
||||
}
|
||||
@ -179,6 +181,10 @@ _cairo_hash_table_create (cairo_hash_keys_equal_func_t keys_equal)
|
||||
* and this function will halt. The rationale for this behavior is to
|
||||
* avoid memory leaks and to avoid needless complication of the API
|
||||
* with destroy notifiy callbacks.
|
||||
*
|
||||
* WARNING: The hash_table must have no running iterators in it when
|
||||
* _cairo_hash_table_destroy is called. It is a fatal error otherwise,
|
||||
* and this function will halt.
|
||||
**/
|
||||
void
|
||||
_cairo_hash_table_destroy (cairo_hash_table_t *hash_table)
|
||||
@ -188,6 +194,8 @@ _cairo_hash_table_destroy (cairo_hash_table_t *hash_table)
|
||||
|
||||
/* The hash table must be empty. Otherwise, halt. */
|
||||
assert (hash_table->live_entries == 0);
|
||||
/* No iterators can be running. Otherwise, halt. */
|
||||
assert (hash_table->iterating == 0);
|
||||
|
||||
free (hash_table->entries);
|
||||
hash_table->entries = NULL;
|
||||
@ -440,6 +448,9 @@ _cairo_hash_table_random_entry (cairo_hash_table_t *hash_table,
|
||||
* WARNING: It is a fatal error if an entry exists in the hash table
|
||||
* with a matching key, (this function will halt).
|
||||
*
|
||||
* WARNING: It is a fatal error to insert an element while
|
||||
* an iterator is running
|
||||
*
|
||||
* Instead of using insert to replace an entry, consider just editing
|
||||
* the entry obtained with _cairo_hash_table_lookup. Or if absolutely
|
||||
* necessary, use _cairo_hash_table_remove first.
|
||||
@ -454,6 +465,9 @@ _cairo_hash_table_insert (cairo_hash_table_t *hash_table,
|
||||
cairo_status_t status;
|
||||
cairo_hash_entry_t **entry;
|
||||
|
||||
/* Insert is illegal while an iterator is running. */
|
||||
assert (hash_table->iterating == 0);
|
||||
|
||||
entry = _cairo_hash_table_lookup_internal (hash_table,
|
||||
key_and_value, FALSE);
|
||||
|
||||
@ -498,11 +512,16 @@ _cairo_hash_table_remove (cairo_hash_table_t *hash_table,
|
||||
*entry = DEAD_ENTRY;
|
||||
hash_table->live_entries--;
|
||||
|
||||
/* This call _can_ fail, but only in failing to allocate new
|
||||
* memory to shrink the hash table. It does leave the table in a
|
||||
* consistent state, and we've already succeeded in removing the
|
||||
* entry, so we don't examine the failure status of this call. */
|
||||
_cairo_hash_table_resize (hash_table);
|
||||
/* Check for table resize. Don't do this when iterating as this will
|
||||
* reorder elements of the table and cause the iteration to potentially
|
||||
* skip some elements. */
|
||||
if (hash_table->iterating == 0) {
|
||||
/* This call _can_ fail, but only in failing to allocate new
|
||||
* memory to shrink the hash table. It does leave the table in a
|
||||
* consistent state, and we've already succeeded in removing the
|
||||
* entry, so we don't examine the failure status of this call. */
|
||||
_cairo_hash_table_resize (hash_table);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@ -513,6 +532,12 @@ _cairo_hash_table_remove (cairo_hash_table_t *hash_table,
|
||||
*
|
||||
* Call @hash_callback for each live entry in the hash table, in a
|
||||
* non-specified order.
|
||||
*
|
||||
* Entries in @hash_table may be removed by code executed from @hash_callback.
|
||||
*
|
||||
* Entries may not be inserted to @hash_table, nor may @hash_table
|
||||
* be destroyed by code executed from @hash_callback. The relevant
|
||||
* functions will halt in these cases.
|
||||
**/
|
||||
void
|
||||
_cairo_hash_table_foreach (cairo_hash_table_t *hash_table,
|
||||
@ -525,9 +550,17 @@ _cairo_hash_table_foreach (cairo_hash_table_t *hash_table,
|
||||
if (hash_table == NULL)
|
||||
return;
|
||||
|
||||
/* Mark the table for iteration */
|
||||
++hash_table->iterating;
|
||||
for (i = 0; i < hash_table->arrangement->size; i++) {
|
||||
entry = hash_table->entries[i];
|
||||
if (ENTRY_IS_LIVE(entry))
|
||||
hash_callback (entry, closure);
|
||||
}
|
||||
/* If some elements were deleted during the iteration,
|
||||
* the table may need resizing. Just do this every time
|
||||
* as the check is inexpensive.
|
||||
*/
|
||||
if (--hash_table->iterating == 0)
|
||||
_cairo_hash_table_resize (hash_table);
|
||||
}
|
||||
|
||||
@ -63,7 +63,8 @@ _cairo_image_surface_create_for_pixman_image (pixman_image_t *pixman_image,
|
||||
return (cairo_surface_t*) &_cairo_surface_nil;
|
||||
}
|
||||
|
||||
_cairo_surface_init (&surface->base, &cairo_image_surface_backend);
|
||||
_cairo_surface_init (&surface->base, &cairo_image_surface_backend,
|
||||
_cairo_content_from_format (format));
|
||||
|
||||
surface->pixman_image = pixman_image;
|
||||
|
||||
@ -188,9 +189,10 @@ _create_pixman_format (cairo_format_t format)
|
||||
* @height: height of the surface, in pixels
|
||||
*
|
||||
* Creates an image surface of the specified format and
|
||||
* dimensions. The initial contents of the surface is undefined; you
|
||||
* must explicitly initialize the surface contents, using, for
|
||||
* example, cairo_paint().
|
||||
* dimensions. Initially the surface contents are all
|
||||
* 0. (Specifically, within each pixel, each color or alpha channel
|
||||
* belonging to format will be 0. The contents of bits within a pixel,
|
||||
* but not belonging to the given format are undefined).
|
||||
*
|
||||
* Return value: a pointer to the newly created surface. The caller
|
||||
* owns the surface and should call cairo_surface_destroy when done
|
||||
@ -270,6 +272,9 @@ _cairo_image_surface_create_with_content (cairo_content_t content,
|
||||
* This function always returns a valid pointer, but it will return a
|
||||
* pointer to a "nil" surface if an error such as out of memory
|
||||
* occurs. You can use cairo_surface_status() to check for this.
|
||||
*
|
||||
* See cairo_surface_set_user_data() for a means of attaching a
|
||||
* destroy-notification fallback to the surface if necessary.
|
||||
**/
|
||||
cairo_surface_t *
|
||||
cairo_image_surface_create_for_data (unsigned char *data,
|
||||
@ -454,9 +459,9 @@ _cairo_image_surface_release_source_image (void *abstract_surf
|
||||
|
||||
static cairo_status_t
|
||||
_cairo_image_surface_acquire_dest_image (void *abstract_surface,
|
||||
cairo_rectangle_t *interest_rect,
|
||||
cairo_rectangle_fixed_t *interest_rect,
|
||||
cairo_image_surface_t **image_out,
|
||||
cairo_rectangle_t *image_rect_out,
|
||||
cairo_rectangle_fixed_t *image_rect_out,
|
||||
void **image_extra)
|
||||
{
|
||||
cairo_image_surface_t *surface = abstract_surface;
|
||||
@ -473,11 +478,11 @@ _cairo_image_surface_acquire_dest_image (void *abstract_surfa
|
||||
}
|
||||
|
||||
static void
|
||||
_cairo_image_surface_release_dest_image (void *abstract_surface,
|
||||
cairo_rectangle_t *interest_rect,
|
||||
cairo_image_surface_t *image,
|
||||
cairo_rectangle_t *image_rect,
|
||||
void *image_extra)
|
||||
_cairo_image_surface_release_dest_image (void *abstract_surface,
|
||||
cairo_rectangle_fixed_t *interest_rect,
|
||||
cairo_image_surface_t *image,
|
||||
cairo_rectangle_fixed_t *image_rect,
|
||||
void *image_extra)
|
||||
{
|
||||
}
|
||||
|
||||
@ -700,11 +705,11 @@ _cairo_image_surface_composite (cairo_operator_t op,
|
||||
}
|
||||
|
||||
static cairo_int_status_t
|
||||
_cairo_image_surface_fill_rectangles (void *abstract_surface,
|
||||
cairo_operator_t op,
|
||||
const cairo_color_t *color,
|
||||
cairo_rectangle_t *rects,
|
||||
int num_rects)
|
||||
_cairo_image_surface_fill_rectangles (void *abstract_surface,
|
||||
cairo_operator_t op,
|
||||
const cairo_color_t *color,
|
||||
cairo_rectangle_fixed_t *rects,
|
||||
int num_rects)
|
||||
{
|
||||
cairo_image_surface_t *surface = abstract_surface;
|
||||
|
||||
@ -861,7 +866,7 @@ _cairo_image_surface_composite_trapezoids (cairo_operator_t op,
|
||||
return status;
|
||||
}
|
||||
|
||||
static cairo_int_status_t
|
||||
cairo_int_status_t
|
||||
_cairo_image_surface_set_clip_region (void *abstract_surface,
|
||||
pixman_region16_t *region)
|
||||
{
|
||||
@ -875,8 +880,8 @@ _cairo_image_surface_set_clip_region (void *abstract_surface,
|
||||
}
|
||||
|
||||
static cairo_int_status_t
|
||||
_cairo_image_surface_get_extents (void *abstract_surface,
|
||||
cairo_rectangle_t *rectangle)
|
||||
_cairo_image_surface_get_extents (void *abstract_surface,
|
||||
cairo_rectangle_fixed_t *rectangle)
|
||||
{
|
||||
cairo_image_surface_t *surface = abstract_surface;
|
||||
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
/* cairo - a vector graphics library with display and print output
|
||||
*
|
||||
* Copyright © 2006 Red Hat, Inc
|
||||
* Copyright © 2006 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
|
||||
@ -27,472 +27,374 @@
|
||||
*
|
||||
* The Original Code is the cairo graphics library.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Alexander Larsson <alexl@redhat.com>
|
||||
* The Initial Developer of the Original Code is University of Southern
|
||||
* California.
|
||||
*
|
||||
* This code is derived from tif_lzw.c in libtiff 3.8.0.
|
||||
* The original copyright notice appears below in its entirety.
|
||||
* Contributor(s):
|
||||
* Carl D. Worth <cworth@cworth.org>
|
||||
*/
|
||||
|
||||
#include "cairoint.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <stdarg.h>
|
||||
#include <assert.h>
|
||||
#include <string.h>
|
||||
typedef struct _lzw_buf {
|
||||
cairo_status_t status;
|
||||
|
||||
/*
|
||||
* Copyright (c) 1988-1997 Sam Leffler
|
||||
* Copyright (c) 1991-1997 Silicon Graphics, Inc.
|
||||
unsigned char *data;
|
||||
int data_size;
|
||||
int num_data;
|
||||
uint32_t pending;
|
||||
int pending_bits;
|
||||
} lzw_buf_t;
|
||||
|
||||
/* An lzw_buf_t is a simple, growable chunk of memory for holding
|
||||
* variable-size objects of up to 16 bits each.
|
||||
*
|
||||
* Permission to use, copy, modify, distribute, and sell this software and
|
||||
* its documentation for any purpose is hereby granted without fee, provided
|
||||
* that (i) the above copyright notices and this permission notice appear in
|
||||
* all copies of the software and related documentation, and (ii) the names of
|
||||
* Sam Leffler and Silicon Graphics may not be used in any advertising or
|
||||
* publicity relating to the software without the specific, prior written
|
||||
* permission of Sam Leffler and Silicon Graphics.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY
|
||||
* WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
|
||||
*
|
||||
* IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR
|
||||
* ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND,
|
||||
* OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
|
||||
* WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF
|
||||
* LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
|
||||
* OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
/*
|
||||
* TIFF Library.
|
||||
* Rev 5.0 Lempel-Ziv & Welch Compression Support
|
||||
* Initialize an lzw_buf_t to the given size in bytes.
|
||||
*
|
||||
* This code is derived from the compress program whose code is
|
||||
* derived from software contributed to Berkeley by James A. Woods,
|
||||
* derived from original work by Spencer Thomas and Joseph Orost.
|
||||
* To store objects into the lzw_buf_t, call _lzw_buf_store_bits and
|
||||
* when finished, call _lzw_buf_store_pending, (which flushes out the
|
||||
* last few bits that hadn't yet made a complete byte yet).
|
||||
*
|
||||
* The original Berkeley copyright notice appears below in its entirety.
|
||||
*/
|
||||
|
||||
#define MAXCODE(n) ((1L<<(n))-1)
|
||||
/*
|
||||
* The TIFF spec specifies that encoded bit
|
||||
* strings range from 9 to 12 bits.
|
||||
*/
|
||||
#define BITS_MIN 9 /* start with 9 bits */
|
||||
#define BITS_MAX 12 /* max of 12 bit strings */
|
||||
/* predefined codes */
|
||||
#define CODE_CLEAR 256 /* code to clear string table */
|
||||
#define CODE_EOI 257 /* end-of-information code */
|
||||
#define CODE_FIRST 258 /* first free code entry */
|
||||
#define CODE_MAX MAXCODE(BITS_MAX)
|
||||
#define HSIZE 9001L /* 91% occupancy */
|
||||
#define HSHIFT (13-8)
|
||||
#ifdef LZW_COMPAT
|
||||
/* NB: +1024 is for compatibility with old files */
|
||||
#define CSIZE (MAXCODE(BITS_MAX)+1024L)
|
||||
#else
|
||||
#define CSIZE (MAXCODE(BITS_MAX)+1L)
|
||||
#endif
|
||||
|
||||
typedef uint16_t hcode_t; /* codes fit in 16 bits */
|
||||
typedef struct {
|
||||
long hash;
|
||||
hcode_t code;
|
||||
} hash_t;
|
||||
|
||||
typedef struct {
|
||||
/* Out buffer */
|
||||
unsigned char *out_buffer; /* compressed out buffer */
|
||||
size_t out_buffer_size; /* # of allocated bytes in out buffer */
|
||||
unsigned char *out_buffer_pos; /* current spot in out buffer */
|
||||
size_t out_buffer_bytes; /* # of data bytes in out buffer */
|
||||
unsigned char *out_buffer_end; /* bound on out_buffer */
|
||||
|
||||
unsigned short nbits; /* # of bits/code */
|
||||
unsigned short maxcode; /* maximum code for lzw_nbits */
|
||||
unsigned short free_ent; /* next free entry in hash table */
|
||||
long nextdata; /* next bits of i/o */
|
||||
long nextbits; /* # of valid bits in lzw_nextdata */
|
||||
|
||||
int enc_oldcode; /* last code encountered */
|
||||
long enc_checkpoint; /* point at which to clear table */
|
||||
#define CHECK_GAP 10000 /* enc_ratio check interval */
|
||||
long enc_ratio; /* current compression ratio */
|
||||
long enc_incount; /* (input) data bytes encoded */
|
||||
long enc_outcount; /* encoded (output) bytes */
|
||||
hash_t* enc_hashtab; /* kept separate for small machines */
|
||||
} LZWCodecState;
|
||||
|
||||
static void cl_hash(LZWCodecState*);
|
||||
|
||||
/*
|
||||
* LZW Encoding.
|
||||
*/
|
||||
|
||||
static unsigned char *
|
||||
grow_out_buffer (LZWCodecState *sp, unsigned char *op)
|
||||
{
|
||||
size_t cc;
|
||||
|
||||
cc = (size_t)(op - sp->out_buffer);
|
||||
|
||||
sp->out_buffer_size = sp->out_buffer_size * 2;
|
||||
sp->out_buffer = realloc (sp->out_buffer, sp->out_buffer_size);
|
||||
/*
|
||||
* The 4 here insures there is space for 2 max-sized
|
||||
* codes in LZWEncode and LZWPostDecode.
|
||||
*/
|
||||
sp->out_buffer_end = sp->out_buffer + sp->out_buffer_size-1 - 4;
|
||||
|
||||
return sp->out_buffer + cc;
|
||||
}
|
||||
|
||||
static int
|
||||
LZWSetupEncode (LZWCodecState* sp)
|
||||
{
|
||||
memset (sp, 0, sizeof (LZWCodecState));
|
||||
sp->enc_hashtab = (hash_t*) malloc (HSIZE * sizeof (hash_t));
|
||||
if (sp->enc_hashtab == NULL)
|
||||
return 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void
|
||||
LZWFreeEncode (LZWCodecState* sp)
|
||||
{
|
||||
if (sp->enc_hashtab)
|
||||
free (sp->enc_hashtab);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Reset encoding state at the start of a strip.
|
||||
* Instead of returning failure from any functions, lzw_buf_t provides
|
||||
* a status value that the caller can query, (and should query at
|
||||
* least once when done with the object). The status value will be
|
||||
* either CAIRO_STATUS_SUCCESS or CAIRO_STATUS_NO_MEMORY;
|
||||
*/
|
||||
static void
|
||||
LZWPreEncode (LZWCodecState *sp)
|
||||
_lzw_buf_init (lzw_buf_t *buf, int size)
|
||||
{
|
||||
sp->nbits = BITS_MIN;
|
||||
sp->maxcode = MAXCODE(BITS_MIN);
|
||||
sp->free_ent = CODE_FIRST;
|
||||
sp->nextbits = 0;
|
||||
sp->nextdata = 0;
|
||||
sp->enc_checkpoint = CHECK_GAP;
|
||||
sp->enc_ratio = 0;
|
||||
sp->enc_incount = 0;
|
||||
sp->enc_outcount = 0;
|
||||
/*
|
||||
* The 4 here insures there is space for 2 max-sized
|
||||
* codes in LZWEncode and LZWPostDecode.
|
||||
*/
|
||||
sp->out_buffer_end = sp->out_buffer + sp->out_buffer_size-1 - 4;
|
||||
cl_hash(sp); /* clear hash table */
|
||||
sp->enc_oldcode = (hcode_t) -1; /* generates CODE_CLEAR in LZWEncode */
|
||||
}
|
||||
if (size == 0)
|
||||
size = 16;
|
||||
|
||||
#define CALCRATIO(sp, rat) { \
|
||||
if (incount > 0x007fffff) { /* NB: shift will overflow */ \
|
||||
rat = outcount >> 8; \
|
||||
rat = (rat == 0 ? 0x7fffffff : incount/rat); \
|
||||
} else \
|
||||
rat = (incount << 8) / outcount; \
|
||||
}
|
||||
#define PutNextCode(op, c) { \
|
||||
nextdata = (nextdata << nbits) | c; \
|
||||
nextbits += nbits; \
|
||||
*op++ = (unsigned char)(nextdata >> (nextbits-8)); \
|
||||
nextbits -= 8; \
|
||||
if (nextbits >= 8) { \
|
||||
*op++ = (unsigned char)(nextdata >> (nextbits-8)); \
|
||||
nextbits -= 8; \
|
||||
} \
|
||||
outcount += nbits; \
|
||||
}
|
||||
buf->status = CAIRO_STATUS_SUCCESS;
|
||||
|
||||
/*
|
||||
* Encode a chunk of pixels.
|
||||
*
|
||||
* Uses an open addressing double hashing (no chaining) on the
|
||||
* prefix code/next character combination. We do a variant of
|
||||
* Knuth's algorithm D (vol. 3, sec. 6.4) along with G. Knott's
|
||||
* relatively-prime secondary probe. Here, the modular division
|
||||
* first probe is gives way to a faster exclusive-or manipulation.
|
||||
* Also do block compression with an adaptive reset, whereby the
|
||||
* code table is cleared when the compression ratio decreases,
|
||||
* but after the table fills. The variable-length output codes
|
||||
* are re-sized at this point, and a CODE_CLEAR is generated
|
||||
* for the decoder.
|
||||
*/
|
||||
static int
|
||||
LZWEncode (LZWCodecState *sp,
|
||||
unsigned char *bp,
|
||||
size_t cc)
|
||||
{
|
||||
register long fcode;
|
||||
register hash_t *hp;
|
||||
register int h, c;
|
||||
hcode_t ent;
|
||||
long disp;
|
||||
long incount, outcount, checkpoint;
|
||||
long nextdata, nextbits;
|
||||
int free_ent, maxcode, nbits;
|
||||
unsigned char *op;
|
||||
|
||||
/*
|
||||
* Load local state.
|
||||
*/
|
||||
incount = sp->enc_incount;
|
||||
outcount = sp->enc_outcount;
|
||||
checkpoint = sp->enc_checkpoint;
|
||||
nextdata = sp->nextdata;
|
||||
nextbits = sp->nextbits;
|
||||
free_ent = sp->free_ent;
|
||||
maxcode = sp->maxcode;
|
||||
nbits = sp->nbits;
|
||||
op = sp->out_buffer_pos;
|
||||
ent = sp->enc_oldcode;
|
||||
|
||||
if (ent == (hcode_t) -1 && cc > 0) {
|
||||
/*
|
||||
* NB: This is safe because it can only happen
|
||||
* at the start of a strip where we know there
|
||||
* is space in the data buffer.
|
||||
*/
|
||||
PutNextCode(op, CODE_CLEAR);
|
||||
ent = *bp++; cc--; incount++;
|
||||
buf->data = malloc (size);
|
||||
if (buf->data == NULL) {
|
||||
buf->data_size = 0;
|
||||
buf->status = CAIRO_STATUS_NO_MEMORY;
|
||||
return;
|
||||
}
|
||||
while (cc > 0) {
|
||||
c = *bp++; cc--; incount++;
|
||||
fcode = ((long)c << BITS_MAX) + ent;
|
||||
h = (c << HSHIFT) ^ ent; /* xor hashing */
|
||||
#ifdef _WINDOWS
|
||||
/*
|
||||
* Check hash index for an overflow.
|
||||
*/
|
||||
if (h >= HSIZE)
|
||||
h -= HSIZE;
|
||||
#endif
|
||||
hp = &sp->enc_hashtab[h];
|
||||
if (hp->hash == fcode) {
|
||||
ent = hp->code;
|
||||
continue;
|
||||
|
||||
buf->data_size = size;
|
||||
buf->num_data = 0;
|
||||
buf->pending = 0;
|
||||
buf->pending_bits = 0;
|
||||
}
|
||||
|
||||
/* Increase the buffer size by doubling.
|
||||
*
|
||||
* Returns CAIRO_STATUS_SUCCESS or CAIRO_STATUS_NO_MEMORY
|
||||
*/
|
||||
static cairo_status_t
|
||||
_lzw_buf_grow (lzw_buf_t *buf)
|
||||
{
|
||||
int new_size = buf->data_size * 2;
|
||||
unsigned char *new_data;
|
||||
|
||||
if (buf->status)
|
||||
return buf->status;
|
||||
|
||||
new_data = realloc (buf->data, new_size);
|
||||
if (new_data == NULL) {
|
||||
free (buf->data);
|
||||
buf->data_size = 0;
|
||||
buf->status = CAIRO_STATUS_NO_MEMORY;
|
||||
return buf->status;
|
||||
}
|
||||
|
||||
buf->data = new_data;
|
||||
buf->data_size = new_size;
|
||||
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
/* Store the lowest num_bits bits of values into buf.
|
||||
*
|
||||
* NOTE: The bits of value above size_in_bits must be 0, (so don't lie
|
||||
* about the size).
|
||||
*
|
||||
* See also _lzw_buf_store_pending which must be called after the last
|
||||
* call to _lzw_buf_store_bits.
|
||||
*
|
||||
* Sets buf->status to either CAIRO_STATUS_SUCCESS or CAIRO_STATUS_NO_MEMORY.
|
||||
*/
|
||||
static void
|
||||
_lzw_buf_store_bits (lzw_buf_t *buf, uint16_t value, int num_bits)
|
||||
{
|
||||
cairo_status_t status;
|
||||
|
||||
assert (value <= (1 << num_bits) - 1);
|
||||
|
||||
if (buf->status)
|
||||
return;
|
||||
|
||||
buf->pending = (buf->pending << num_bits) | value;
|
||||
buf->pending_bits += num_bits;
|
||||
|
||||
while (buf->pending_bits >= 8) {
|
||||
if (buf->num_data >= buf->data_size) {
|
||||
status = _lzw_buf_grow (buf);
|
||||
if (status)
|
||||
return;
|
||||
}
|
||||
if (hp->hash >= 0) {
|
||||
/*
|
||||
* Primary hash failed, check secondary hash.
|
||||
*/
|
||||
disp = HSIZE - h;
|
||||
if (h == 0)
|
||||
disp = 1;
|
||||
do {
|
||||
/*
|
||||
* Avoid pointer arithmetic 'cuz of
|
||||
* wraparound problems with segments.
|
||||
*/
|
||||
if ((h -= disp) < 0)
|
||||
h += HSIZE;
|
||||
hp = &sp->enc_hashtab[h];
|
||||
if (hp->hash == fcode) {
|
||||
ent = hp->code;
|
||||
goto hit;
|
||||
}
|
||||
} while (hp->hash >= 0);
|
||||
buf->data[buf->num_data++] = buf->pending >> (buf->pending_bits - 8);
|
||||
buf->pending_bits -= 8;
|
||||
}
|
||||
}
|
||||
|
||||
/* Store the last remaining pending bits into the buffer.
|
||||
*
|
||||
* NOTE: This function must be called after the last call to
|
||||
* _lzw_buf_store_bits.
|
||||
*
|
||||
* Sets buf->status to either CAIRO_STATUS_SUCCESS or CAIRO_STATUS_NO_MEMORY.
|
||||
*/
|
||||
static void
|
||||
_lzw_buf_store_pending (lzw_buf_t *buf)
|
||||
{
|
||||
cairo_status_t status;
|
||||
|
||||
if (buf->status)
|
||||
return;
|
||||
|
||||
if (buf->pending_bits == 0)
|
||||
return;
|
||||
|
||||
assert (buf->pending_bits < 8);
|
||||
|
||||
if (buf->num_data >= buf->data_size) {
|
||||
status = _lzw_buf_grow (buf);
|
||||
if (status)
|
||||
return;
|
||||
}
|
||||
|
||||
buf->data[buf->num_data++] = buf->pending << (8 - buf->pending_bits);
|
||||
buf->pending_bits = 0;
|
||||
}
|
||||
|
||||
/* LZW defines a few magic code values */
|
||||
#define LZW_CODE_CLEAR_TABLE 256
|
||||
#define LZW_CODE_EOD 257
|
||||
#define LZW_CODE_FIRST 258
|
||||
|
||||
/* We pack three separate values into a symbol as follows:
|
||||
*
|
||||
* 12 bits (31 down to 20): CODE: code value used to represent this symbol
|
||||
* 12 bits (19 down to 8): PREV: previous code value in chain
|
||||
* 8 bits ( 7 down to 0): NEXT: next byte value in chain
|
||||
*/
|
||||
typedef uint32_t lzw_symbol_t;
|
||||
|
||||
#define LZW_SYMBOL_SET(sym, prev, next) ((sym) = ((prev) << 8)|(next))
|
||||
#define LZW_SYMBOL_SET_CODE(sym, code, prev, next) ((sym) = ((code << 20)|(prev) << 8)|(next))
|
||||
#define LZW_SYMBOL_GET_CODE(sym) (((sym) >> 20))
|
||||
#define LZW_SYMBOL_GET_PREV(sym) (((sym) >> 8) & 0x7ff)
|
||||
#define LZW_SYMBOL_GET_BYTE(sym) (((sym) >> 0) & 0x0ff)
|
||||
|
||||
/* The PREV+NEXT fields can be seen as the key used to fetch values
|
||||
* from the hash table, while the code is the value fetched.
|
||||
*/
|
||||
#define LZW_SYMBOL_KEY_MASK 0x000fffff
|
||||
|
||||
/* Since code values are only stored starting with 258 we can safely
|
||||
* use a zero value to represent free slots in the hash table. */
|
||||
#define LZW_SYMBOL_FREE 0x00000000
|
||||
|
||||
/* These really aren't very free for modifying. First, the PostScript
|
||||
* specification sets the 9-12 bit range. Second, the encoding of
|
||||
* lzw_symbol_t above also relies on 2 of LZW_BITS_MAX plus one byte
|
||||
* fitting within 32 bits.
|
||||
*
|
||||
* But other than that, the LZW compression scheme could function with
|
||||
* more bits per code.
|
||||
*/
|
||||
#define LZW_BITS_MIN 9
|
||||
#define LZW_BITS_MAX 12
|
||||
#define LZW_BITS_BOUNDARY(bits) ((1<<(bits))-1)
|
||||
#define LZW_MAX_SYMBOLS (1<<LZW_BITS_MAX)
|
||||
|
||||
#define LZW_SYMBOL_TABLE_SIZE 9013
|
||||
#define LZW_SYMBOL_MOD1 LZW_SYMBOL_TABLE_SIZE
|
||||
#define LZW_SYMBOL_MOD2 9011
|
||||
|
||||
typedef struct _lzw_symbol_table {
|
||||
lzw_symbol_t table[LZW_SYMBOL_TABLE_SIZE];
|
||||
} lzw_symbol_table_t;
|
||||
|
||||
/* Initialize the hash table to entirely empty */
|
||||
static void
|
||||
_lzw_symbol_table_init (lzw_symbol_table_t *table)
|
||||
{
|
||||
memset (table->table, 0, LZW_SYMBOL_TABLE_SIZE * sizeof (lzw_symbol_t));
|
||||
}
|
||||
|
||||
/* Lookup a symbol in the symbol table. The PREV and NEXT fields of
|
||||
* symbol form the key for the lookup.
|
||||
*
|
||||
* If succesful, then this function returns TRUE and slot_ret will be
|
||||
* left pointing at the result that will have the CODE field of
|
||||
* interest.
|
||||
*
|
||||
* If the lookup fails, then this function returns FALSE and slot_ret
|
||||
* will be pointing at the location in the table to which a new CODE
|
||||
* value should be stored along with PREV and NEXT.
|
||||
*/
|
||||
static cairo_bool_t
|
||||
_lzw_symbol_table_lookup (lzw_symbol_table_t *table,
|
||||
lzw_symbol_t symbol,
|
||||
lzw_symbol_t **slot_ret)
|
||||
{
|
||||
/* The algorithm here is identical to that in cairo-hash.c. We
|
||||
* copy it here to allow for a rather more efficient
|
||||
* implementation due to several circumstances that do not apply
|
||||
* to the more general case:
|
||||
*
|
||||
* 1) We have a known bound on the total number of symbols, so we
|
||||
* have a fixed-size table without any copying when growing
|
||||
*
|
||||
* 2) We never delete any entries, so we don't need to
|
||||
* support/check for DEAD entries during lookup.
|
||||
*
|
||||
* 3) The object fits in 32 bits so we store each object in its
|
||||
* entirety within the table rather than storing objects
|
||||
* externally and putting pointers in the table, (which here
|
||||
* would just double the storage requirements and have negative
|
||||
* impacts on memory locality).
|
||||
*/
|
||||
int i, idx, step, hash = symbol & LZW_SYMBOL_KEY_MASK;
|
||||
lzw_symbol_t candidate;
|
||||
|
||||
idx = hash % LZW_SYMBOL_MOD1;
|
||||
step = 0;
|
||||
|
||||
*slot_ret = NULL;
|
||||
for (i = 0; i < LZW_SYMBOL_TABLE_SIZE; i++)
|
||||
{
|
||||
candidate = table->table[idx];
|
||||
if (candidate == LZW_SYMBOL_FREE)
|
||||
{
|
||||
*slot_ret = &table->table[idx];
|
||||
return FALSE;
|
||||
}
|
||||
/*
|
||||
* New entry, emit code and add to table.
|
||||
*/
|
||||
/*
|
||||
* Verify there is space in the buffer for the code
|
||||
* and any potential Clear code that might be emitted
|
||||
* below. The value of limit is setup so that there
|
||||
* are at least 4 bytes free--room for 2 codes.
|
||||
*/
|
||||
if (op > sp->out_buffer_end) {
|
||||
op = grow_out_buffer (sp, op);
|
||||
if (sp->out_buffer == NULL) {
|
||||
return 0;
|
||||
else /* candidate is LIVE */
|
||||
{
|
||||
if ((candidate & LZW_SYMBOL_KEY_MASK) ==
|
||||
(symbol & LZW_SYMBOL_KEY_MASK))
|
||||
{
|
||||
*slot_ret = &table->table[idx];
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
PutNextCode(op, ent);
|
||||
ent = c;
|
||||
hp->code = free_ent++;
|
||||
hp->hash = fcode;
|
||||
if (free_ent == CODE_MAX-1) {
|
||||
/* table is full, emit clear code and reset */
|
||||
cl_hash(sp);
|
||||
sp->enc_ratio = 0;
|
||||
incount = 0;
|
||||
outcount = 0;
|
||||
free_ent = CODE_FIRST;
|
||||
PutNextCode(op, CODE_CLEAR);
|
||||
nbits = BITS_MIN;
|
||||
maxcode = MAXCODE(BITS_MIN);
|
||||
} else {
|
||||
/*
|
||||
* If the next entry is going to be too big for
|
||||
* the code size, then increase it, if possible.
|
||||
*/
|
||||
if (free_ent > maxcode) {
|
||||
nbits++;
|
||||
assert(nbits <= BITS_MAX);
|
||||
maxcode = (int) MAXCODE(nbits);
|
||||
} else if (incount >= checkpoint) {
|
||||
long rat;
|
||||
/*
|
||||
* Check compression ratio and, if things seem
|
||||
* to be slipping, clear the hash table and
|
||||
* reset state. The compression ratio is a
|
||||
* 24+8-bit fractional number.
|
||||
*/
|
||||
checkpoint = incount+CHECK_GAP;
|
||||
CALCRATIO(sp, rat);
|
||||
if (rat <= sp->enc_ratio) {
|
||||
cl_hash(sp);
|
||||
sp->enc_ratio = 0;
|
||||
incount = 0;
|
||||
outcount = 0;
|
||||
free_ent = CODE_FIRST;
|
||||
PutNextCode(op, CODE_CLEAR);
|
||||
nbits = BITS_MIN;
|
||||
maxcode = MAXCODE(BITS_MIN);
|
||||
} else
|
||||
sp->enc_ratio = rat;
|
||||
|
||||
if (step == 0) {
|
||||
step = hash % LZW_SYMBOL_MOD2;
|
||||
if (step == 0)
|
||||
step = 1;
|
||||
}
|
||||
|
||||
idx += step;
|
||||
if (idx >= LZW_SYMBOL_TABLE_SIZE)
|
||||
idx -= LZW_SYMBOL_TABLE_SIZE;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* Compress a bytestream using the LZW algorithm.
|
||||
*
|
||||
* This is an original implementation based on reading the
|
||||
* specification of the LZWDecode filter in the PostScript Language
|
||||
* Reference. The free parameters in the LZW algorithm are set to the
|
||||
* values mandated by PostScript, (symbols encoded with widths from 9
|
||||
* to 12 bits).
|
||||
*
|
||||
* This function returns a pointer to a newly allocated buffer holding
|
||||
* the compressed data, or NULL if an out-of-memory situation
|
||||
* occurs.
|
||||
*
|
||||
* Notice that any one of the _lzw_buf functions called here could
|
||||
* trigger an out-of-memory condition. But lzw_buf_t uses cairo's
|
||||
* shutdown-on-error idiom, so it's safe to continue to call into
|
||||
* lzw_buf without having to check for errors, (until a final check at
|
||||
* the end).
|
||||
*/
|
||||
unsigned char *
|
||||
_cairo_lzw_compress (unsigned char *data, unsigned long *size_in_out)
|
||||
{
|
||||
int bytes_remaining = *size_in_out;
|
||||
lzw_buf_t buf;
|
||||
lzw_symbol_table_t table;
|
||||
lzw_symbol_t symbol, *slot = NULL; /* just to squelch a warning */
|
||||
int code_next = LZW_CODE_FIRST;
|
||||
int code_bits = LZW_BITS_MIN;
|
||||
int prev, next = 0; /* just to squelch a warning */
|
||||
|
||||
if (*size_in_out == 0)
|
||||
return NULL;
|
||||
|
||||
_lzw_buf_init (&buf, *size_in_out);
|
||||
|
||||
_lzw_symbol_table_init (&table);
|
||||
|
||||
/* The LZW header is a clear table code. */
|
||||
_lzw_buf_store_bits (&buf, LZW_CODE_CLEAR_TABLE, code_bits);
|
||||
|
||||
while (1) {
|
||||
|
||||
/* Find the longest existing code in the symbol table that
|
||||
* matches the current input, if any. */
|
||||
prev = *data++;
|
||||
bytes_remaining--;
|
||||
if (bytes_remaining) {
|
||||
do
|
||||
{
|
||||
next = *data++;
|
||||
bytes_remaining--;
|
||||
LZW_SYMBOL_SET (symbol, prev, next);
|
||||
if (_lzw_symbol_table_lookup (&table, symbol, &slot))
|
||||
prev = LZW_SYMBOL_GET_CODE (*slot);
|
||||
} while (bytes_remaining && *slot != LZW_SYMBOL_FREE);
|
||||
if (*slot == LZW_SYMBOL_FREE) {
|
||||
data--;
|
||||
bytes_remaining++;
|
||||
}
|
||||
}
|
||||
hit:
|
||||
;
|
||||
}
|
||||
|
||||
/*
|
||||
* Restore global state.
|
||||
*/
|
||||
sp->enc_incount = incount;
|
||||
sp->enc_outcount = outcount;
|
||||
sp->enc_checkpoint = checkpoint;
|
||||
sp->enc_oldcode = ent;
|
||||
sp->nextdata = nextdata;
|
||||
sp->nextbits = nextbits;
|
||||
sp->free_ent = free_ent;
|
||||
sp->maxcode = maxcode;
|
||||
sp->nbits = nbits;
|
||||
sp->out_buffer_pos = op;
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* Finish off an encoded strip by flushing the last
|
||||
* string and tacking on an End Of Information code.
|
||||
*/
|
||||
static int
|
||||
LZWPostEncode (LZWCodecState *sp)
|
||||
{
|
||||
unsigned char *op = sp->out_buffer_pos;
|
||||
long nextbits = sp->nextbits;
|
||||
long nextdata = sp->nextdata;
|
||||
long outcount = sp->enc_outcount;
|
||||
int nbits = sp->nbits;
|
||||
|
||||
if (op > sp->out_buffer_end) {
|
||||
op = grow_out_buffer (sp, op);
|
||||
if (sp->out_buffer == NULL) {
|
||||
return 0;
|
||||
/* Write the code into the output. This is either a byte read
|
||||
* directly from the input, or a code from the last successful
|
||||
* lookup. */
|
||||
_lzw_buf_store_bits (&buf, prev, code_bits);
|
||||
|
||||
if (bytes_remaining == 0)
|
||||
break;
|
||||
|
||||
LZW_SYMBOL_SET_CODE (*slot, code_next++, prev, next);
|
||||
|
||||
if (code_next > LZW_BITS_BOUNDARY(code_bits))
|
||||
{
|
||||
code_bits++;
|
||||
if (code_bits > LZW_BITS_MAX) {
|
||||
_lzw_symbol_table_init (&table);
|
||||
_lzw_buf_store_bits (&buf, LZW_CODE_CLEAR_TABLE, code_bits - 1);
|
||||
code_bits = LZW_BITS_MIN;
|
||||
code_next = LZW_CODE_FIRST;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (sp->enc_oldcode != (hcode_t) -1) {
|
||||
PutNextCode(op, sp->enc_oldcode);
|
||||
sp->enc_oldcode = (hcode_t) -1;
|
||||
|
||||
/* The LZW footer is an end-of-data code. */
|
||||
_lzw_buf_store_bits (&buf, LZW_CODE_EOD, code_bits);
|
||||
|
||||
_lzw_buf_store_pending (&buf);
|
||||
|
||||
/* See if we ever ran out of memory while writing to buf. */
|
||||
if (buf.status == CAIRO_STATUS_NO_MEMORY) {
|
||||
*size_in_out = 0;
|
||||
return NULL;
|
||||
}
|
||||
PutNextCode(op, CODE_EOI);
|
||||
if (nextbits > 0)
|
||||
*op++ = (unsigned char)(nextdata << (8-nextbits));
|
||||
sp->out_buffer_bytes = (size_t)(op - sp->out_buffer);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* Reset encoding hash table.
|
||||
*/
|
||||
static void
|
||||
cl_hash (LZWCodecState* sp)
|
||||
{
|
||||
register hash_t *hp = &sp->enc_hashtab[HSIZE-1];
|
||||
register long i = HSIZE-8;
|
||||
|
||||
do {
|
||||
i -= 8;
|
||||
hp[-7].hash = -1;
|
||||
hp[-6].hash = -1;
|
||||
hp[-5].hash = -1;
|
||||
hp[-4].hash = -1;
|
||||
hp[-3].hash = -1;
|
||||
hp[-2].hash = -1;
|
||||
hp[-1].hash = -1;
|
||||
hp[ 0].hash = -1;
|
||||
hp -= 8;
|
||||
} while (i >= 0);
|
||||
for (i += 8; i > 0; i--, hp--)
|
||||
hp->hash = -1;
|
||||
}
|
||||
|
||||
/*
|
||||
* Copyright (c) 1985, 1986 The Regents of the University of California.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This code is derived from software contributed to Berkeley by
|
||||
* James A. Woods, derived from original work by Spencer Thomas
|
||||
* and Joseph Orost.
|
||||
*
|
||||
* Redistribution and use in source and binary forms are permitted
|
||||
* provided that the above copyright notice and this paragraph are
|
||||
* duplicated in all such forms and that any documentation,
|
||||
* advertising materials, and other materials related to such
|
||||
* distribution and use acknowledge that the software was developed
|
||||
* by the University of California, Berkeley. The name of the
|
||||
* University may not be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
|
||||
*/
|
||||
|
||||
void *
|
||||
_cairo_compress_lzw (void *data, unsigned long data_size, unsigned long *compressed_size)
|
||||
{
|
||||
LZWCodecState state;
|
||||
|
||||
if (!LZWSetupEncode (&state))
|
||||
goto bail0;
|
||||
|
||||
state.out_buffer_size = data_size/4;
|
||||
/* We need *some* space at least */
|
||||
if (state.out_buffer_size < 256)
|
||||
state.out_buffer_size = 256;
|
||||
state.out_buffer = malloc (state.out_buffer_size);
|
||||
if (state.out_buffer == NULL)
|
||||
goto bail1;
|
||||
|
||||
state.out_buffer_pos = state.out_buffer;
|
||||
state.out_buffer_bytes = 0;
|
||||
|
||||
LZWPreEncode (&state);
|
||||
if (!LZWEncode (&state, data, data_size))
|
||||
goto bail2;
|
||||
if (!LZWPostEncode(&state))
|
||||
goto bail2;
|
||||
|
||||
LZWFreeEncode(&state);
|
||||
|
||||
*compressed_size = state.out_buffer_bytes;
|
||||
return state.out_buffer;
|
||||
|
||||
bail2:
|
||||
if (state.out_buffer)
|
||||
free (state.out_buffer);
|
||||
bail1:
|
||||
LZWFreeEncode(&state);
|
||||
bail0:
|
||||
return NULL;
|
||||
|
||||
assert (buf.status == CAIRO_STATUS_SUCCESS);
|
||||
|
||||
*size_in_out = buf.num_data;
|
||||
return buf.data;
|
||||
}
|
||||
|
||||
@ -556,6 +556,38 @@ _cairo_matrix_is_integer_translation(const cairo_matrix_t *m,
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
cairo_bool_t
|
||||
_cairo_matrix_is_integer_translation_and_scale(const cairo_matrix_t *m,
|
||||
int *itx, int *ity, int *sx, int *sy)
|
||||
{
|
||||
cairo_fixed_t x0_fixed, y0_fixed, xx_fixed, yy_fixed;
|
||||
|
||||
if ((m->yx != 0.0) || (m->yy != 0.0))
|
||||
return FALSE;
|
||||
|
||||
x0_fixed = _cairo_fixed_from_double (m->x0);
|
||||
y0_fixed = _cairo_fixed_from_double (m->y0);
|
||||
xx_fixed = _cairo_fixed_from_double (m->xx);
|
||||
yy_fixed = _cairo_fixed_from_double (m->yy);
|
||||
|
||||
if (!_cairo_fixed_is_integer(x0_fixed) ||
|
||||
!_cairo_fixed_is_integer(y0_fixed) ||
|
||||
!_cairo_fixed_is_integer(xx_fixed) ||
|
||||
!_cairo_fixed_is_integer(yy_fixed))
|
||||
return FALSE;
|
||||
|
||||
if (itx)
|
||||
*itx = _cairo_fixed_integer_part(x0_fixed);
|
||||
if (ity)
|
||||
*ity = _cairo_fixed_integer_part(y0_fixed);
|
||||
if (sx)
|
||||
*sx = _cairo_fixed_integer_part(xx_fixed);
|
||||
if (sy)
|
||||
*sy = _cairo_fixed_integer_part(yy_fixed);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/*
|
||||
A circle in user space is transformed into an ellipse in device space.
|
||||
|
||||
|
||||
@ -137,6 +137,9 @@ typedef struct _cairo_meta_surface {
|
||||
|
||||
cairo_array_t commands;
|
||||
cairo_surface_t *commands_owner;
|
||||
|
||||
cairo_bool_t is_clipped;
|
||||
int replay_start_idx;
|
||||
} cairo_meta_surface_t;
|
||||
|
||||
cairo_private cairo_surface_t *
|
||||
|
||||
@ -72,7 +72,8 @@ _cairo_meta_surface_create (cairo_content_t content,
|
||||
return (cairo_surface_t*) &_cairo_surface_nil;
|
||||
}
|
||||
|
||||
_cairo_surface_init (&meta->base, &cairo_meta_surface_backend);
|
||||
_cairo_surface_init (&meta->base, &cairo_meta_surface_backend,
|
||||
content);
|
||||
|
||||
meta->content = content;
|
||||
meta->width_pixels = width_pixels;
|
||||
@ -81,6 +82,9 @@ _cairo_meta_surface_create (cairo_content_t content,
|
||||
_cairo_array_init (&meta->commands, sizeof (cairo_command_t *));
|
||||
meta->commands_owner = NULL;
|
||||
|
||||
meta->is_clipped = FALSE;
|
||||
meta->replay_start_idx = 0;
|
||||
|
||||
return &meta->base;
|
||||
}
|
||||
|
||||
@ -226,6 +230,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;
|
||||
@ -468,11 +478,14 @@ _cairo_meta_surface_snapshot (void *abstract_other)
|
||||
return (cairo_surface_t*) &_cairo_surface_nil;
|
||||
}
|
||||
|
||||
_cairo_surface_init (&meta->base, &cairo_meta_surface_backend);
|
||||
_cairo_surface_init (&meta->base, &cairo_meta_surface_backend,
|
||||
other->base.content);
|
||||
meta->base.is_snapshot = TRUE;
|
||||
|
||||
meta->width_pixels = other->width_pixels;
|
||||
meta->height_pixels = other->height_pixels;
|
||||
meta->replay_start_idx = other->replay_start_idx;
|
||||
meta->content = other->content;
|
||||
|
||||
_cairo_array_init_snapshot (&meta->commands, &other->commands);
|
||||
meta->commands_owner = cairo_surface_reference (&other->base);
|
||||
@ -504,8 +517,10 @@ _cairo_meta_surface_intersect_clip_path (void *dst,
|
||||
return status;
|
||||
}
|
||||
command->path_pointer = &command->path;
|
||||
meta->is_clipped = TRUE;
|
||||
} else {
|
||||
command->path_pointer = NULL;
|
||||
meta->is_clipped = FALSE;
|
||||
}
|
||||
command->fill_rule = fill_rule;
|
||||
command->tolerance = tolerance;
|
||||
@ -531,8 +546,8 @@ _cairo_meta_surface_intersect_clip_path (void *dst,
|
||||
* added to it.
|
||||
*/
|
||||
static cairo_int_status_t
|
||||
_cairo_meta_surface_get_extents (void *abstract_surface,
|
||||
cairo_rectangle_t *rectangle)
|
||||
_cairo_meta_surface_get_extents (void *abstract_surface,
|
||||
cairo_rectangle_fixed_t *rectangle)
|
||||
{
|
||||
rectangle->x = 0;
|
||||
rectangle->y = 0;
|
||||
@ -610,7 +625,7 @@ _cairo_meta_surface_replay (cairo_surface_t *surface,
|
||||
|
||||
num_elements = meta->commands.num_elements;
|
||||
elements = _cairo_array_index (&meta->commands, 0);
|
||||
for (i = 0; i < num_elements; i++) {
|
||||
for (i = meta->replay_start_idx; i < num_elements; i++) {
|
||||
command = elements[i];
|
||||
switch (command->type) {
|
||||
case CAIRO_COMMAND_PAINT:
|
||||
|
||||
119
mozilla/gfx/cairo/cairo/src/cairo-operator.c
Normal file
119
mozilla/gfx/cairo/cairo/src/cairo-operator.c
Normal file
@ -0,0 +1,119 @@
|
||||
/* cairo - a vector graphics library with display and print output
|
||||
*
|
||||
* Copyright © 2006 Keith Packard
|
||||
* Copyright © 2006 Red Hat, Inc
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it either under the terms of the GNU Lesser General Public
|
||||
* License version 2.1 as published by the Free Software Foundation
|
||||
* (the "LGPL") or, at your option, under the terms of the Mozilla
|
||||
* Public License Version 1.1 (the "MPL"). If you do not alter this
|
||||
* notice, a recipient may use your version of this file under either
|
||||
* the MPL or the LGPL.
|
||||
*
|
||||
* You should have received a copy of the LGPL along with this library
|
||||
* in the file COPYING-LGPL-2.1; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
* You should have received a copy of the MPL along with this library
|
||||
* in the file COPYING-MPL-1.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License
|
||||
* Version 1.1 (the "License"); you may not use this file except in
|
||||
* compliance with the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY
|
||||
* OF ANY KIND, either express or implied. See the LGPL or the MPL for
|
||||
* the specific language governing rights and limitations.
|
||||
*
|
||||
* The Original Code is the cairo graphics library.
|
||||
*
|
||||
* The Initial Developer of the Original Code is University of Southern
|
||||
* California.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Carl D. Worth <cworth@cworth.org>
|
||||
* Keith Packard <keithp@keithp.com>
|
||||
*/
|
||||
|
||||
#include "cairoint.h"
|
||||
|
||||
/* The analysis here assumes destination alpha semantics (that is
|
||||
* CAIRO_CONTENT_COLOR_ALPHA). More things can be considered opaque
|
||||
* otherwise (CAIRO_CONTENT_COLOR) so we'll probably want to add a
|
||||
* cairo_content_t parameter to this function
|
||||
*
|
||||
* We also need a definition of what "opaque" means. Is it, "does not
|
||||
* requiring 'knowing' the original contents of destination, nor does
|
||||
* it set the destination alpha to anything but 1.0" ?
|
||||
*/
|
||||
cairo_bool_t
|
||||
_cairo_operator_always_opaque (cairo_operator_t op)
|
||||
{
|
||||
switch (op) {
|
||||
case CAIRO_OPERATOR_CLEAR:
|
||||
return FALSE;
|
||||
|
||||
case CAIRO_OPERATOR_SOURCE:
|
||||
return FALSE;
|
||||
|
||||
case CAIRO_OPERATOR_OVER:
|
||||
case CAIRO_OPERATOR_IN:
|
||||
case CAIRO_OPERATOR_OUT:
|
||||
case CAIRO_OPERATOR_ATOP:
|
||||
return FALSE;
|
||||
|
||||
case CAIRO_OPERATOR_DEST:
|
||||
return TRUE;
|
||||
|
||||
case CAIRO_OPERATOR_DEST_OVER:
|
||||
case CAIRO_OPERATOR_DEST_IN:
|
||||
case CAIRO_OPERATOR_DEST_OUT:
|
||||
case CAIRO_OPERATOR_DEST_ATOP:
|
||||
return FALSE;
|
||||
|
||||
case CAIRO_OPERATOR_XOR:
|
||||
case CAIRO_OPERATOR_ADD:
|
||||
case CAIRO_OPERATOR_SATURATE:
|
||||
return FALSE;
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* As above, we'll probably want to add a cairo_content_t parameter to
|
||||
* this function
|
||||
*
|
||||
* We also need a definition of what "translucent" means.
|
||||
*/
|
||||
cairo_bool_t
|
||||
_cairo_operator_always_translucent (cairo_operator_t op)
|
||||
{
|
||||
switch (op) {
|
||||
case CAIRO_OPERATOR_CLEAR:
|
||||
return TRUE;
|
||||
|
||||
case CAIRO_OPERATOR_SOURCE:
|
||||
return FALSE;
|
||||
|
||||
case CAIRO_OPERATOR_OVER:
|
||||
case CAIRO_OPERATOR_IN:
|
||||
case CAIRO_OPERATOR_OUT:
|
||||
case CAIRO_OPERATOR_ATOP:
|
||||
return FALSE;
|
||||
|
||||
case CAIRO_OPERATOR_DEST:
|
||||
return FALSE;
|
||||
|
||||
case CAIRO_OPERATOR_DEST_OVER:
|
||||
case CAIRO_OPERATOR_DEST_IN:
|
||||
case CAIRO_OPERATOR_DEST_OUT:
|
||||
case CAIRO_OPERATOR_DEST_ATOP:
|
||||
return FALSE;
|
||||
|
||||
case CAIRO_OPERATOR_XOR:
|
||||
case CAIRO_OPERATOR_ADD:
|
||||
case CAIRO_OPERATOR_SATURATE:
|
||||
return TRUE;
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
@ -44,54 +44,98 @@
|
||||
#endif /* _MSC_VER */
|
||||
|
||||
struct _cairo_output_stream {
|
||||
cairo_write_func_t write_data;
|
||||
cairo_write_func_t write_func;
|
||||
cairo_close_func_t close_func;
|
||||
void *closure;
|
||||
cairo_bool_t owns_closure_is_file;
|
||||
unsigned long position;
|
||||
cairo_status_t status;
|
||||
cairo_bool_t closed;
|
||||
};
|
||||
|
||||
const cairo_output_stream_t cairo_output_stream_nil = {
|
||||
NULL, /* write_func */
|
||||
NULL, /* close_func */
|
||||
NULL, /* closure */
|
||||
0, /* position */
|
||||
CAIRO_STATUS_NO_MEMORY,
|
||||
FALSE /* closed */
|
||||
};
|
||||
|
||||
static const cairo_output_stream_t cairo_output_stream_nil_write_error = {
|
||||
NULL, /* write_func */
|
||||
NULL, /* close_func */
|
||||
NULL, /* closure */
|
||||
0, /* position */
|
||||
CAIRO_STATUS_WRITE_ERROR,
|
||||
FALSE /* closed */
|
||||
};
|
||||
|
||||
cairo_output_stream_t *
|
||||
_cairo_output_stream_create (cairo_write_func_t write_data,
|
||||
_cairo_output_stream_create (cairo_write_func_t write_func,
|
||||
cairo_close_func_t close_func,
|
||||
void *closure)
|
||||
{
|
||||
cairo_output_stream_t *stream;
|
||||
|
||||
stream = malloc (sizeof (cairo_output_stream_t));
|
||||
if (stream == NULL)
|
||||
return NULL;
|
||||
return (cairo_output_stream_t *) &cairo_output_stream_nil;
|
||||
|
||||
stream->write_data = write_data;
|
||||
stream->write_func = write_func;
|
||||
stream->close_func = close_func;
|
||||
stream->closure = closure;
|
||||
stream->owns_closure_is_file = FALSE;
|
||||
stream->position = 0;
|
||||
stream->status = CAIRO_STATUS_SUCCESS;
|
||||
stream->closed = FALSE;
|
||||
|
||||
return stream;
|
||||
}
|
||||
|
||||
void
|
||||
_cairo_output_stream_close (cairo_output_stream_t *stream)
|
||||
{
|
||||
cairo_status_t status;
|
||||
|
||||
if (stream->closed)
|
||||
return;
|
||||
|
||||
if (stream == &cairo_output_stream_nil ||
|
||||
stream == &cairo_output_stream_nil_write_error)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (stream->close_func) {
|
||||
status = stream->close_func (stream->closure);
|
||||
if (status)
|
||||
stream->status = status;
|
||||
}
|
||||
|
||||
stream->closed = TRUE;
|
||||
}
|
||||
|
||||
void
|
||||
_cairo_output_stream_destroy (cairo_output_stream_t *stream)
|
||||
{
|
||||
if (stream->owns_closure_is_file) {
|
||||
FILE *file = stream->closure;
|
||||
fflush (file);
|
||||
fclose (file);
|
||||
}
|
||||
if (stream == NULL)
|
||||
return;
|
||||
|
||||
_cairo_output_stream_close (stream);
|
||||
free (stream);
|
||||
}
|
||||
|
||||
cairo_status_t
|
||||
void
|
||||
_cairo_output_stream_write (cairo_output_stream_t *stream,
|
||||
const void *data, size_t length)
|
||||
{
|
||||
if (length == 0)
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
return;
|
||||
|
||||
stream->status = stream->write_data (stream->closure, data, length);
|
||||
if (stream->status)
|
||||
return;
|
||||
|
||||
stream->status = stream->write_func (stream->closure, data, length);
|
||||
stream->position += length;
|
||||
|
||||
return stream->status;
|
||||
}
|
||||
|
||||
void
|
||||
@ -103,6 +147,9 @@ _cairo_output_stream_write_hex_string (cairo_output_stream_t *stream,
|
||||
char buffer[2];
|
||||
int i, column;
|
||||
|
||||
if (stream->status)
|
||||
return;
|
||||
|
||||
for (i = 0, column = 0; i < length; i++, column++) {
|
||||
if (column == 38) {
|
||||
_cairo_output_stream_write (stream, "\n", 1);
|
||||
@ -114,72 +161,13 @@ _cairo_output_stream_write_hex_string (cairo_output_stream_t *stream,
|
||||
}
|
||||
}
|
||||
|
||||
static cairo_bool_t
|
||||
convert_four_tuple (const unsigned char *four_tuple, char five_tuple[5])
|
||||
{
|
||||
cairo_bool_t all_zero;
|
||||
uint32_t value;
|
||||
int digit, i;
|
||||
|
||||
value = four_tuple[0] << 24 | four_tuple[1] << 16 | four_tuple[2] << 8 | four_tuple[3];
|
||||
all_zero = TRUE;
|
||||
for (i = 0; i < 5; i++) {
|
||||
digit = value % 85;
|
||||
if (digit != 0)
|
||||
all_zero = FALSE;
|
||||
five_tuple[4-i] = digit + 33;
|
||||
value = value / 85;
|
||||
}
|
||||
return all_zero;
|
||||
}
|
||||
|
||||
void
|
||||
_cairo_output_stream_write_base85_string (cairo_output_stream_t *stream,
|
||||
const char *data,
|
||||
size_t length)
|
||||
{
|
||||
unsigned char *ptr;
|
||||
unsigned char four_tuple[4];
|
||||
char five_tuple[5];
|
||||
int column;
|
||||
|
||||
ptr = (unsigned char *)data;
|
||||
column = 0;
|
||||
while (length > 0) {
|
||||
if (length >= 4) {
|
||||
if (convert_four_tuple (ptr, five_tuple)) {
|
||||
column += 1;
|
||||
_cairo_output_stream_write (stream, "z", 1);
|
||||
} else {
|
||||
column += 5;
|
||||
_cairo_output_stream_write (stream, five_tuple, 5);
|
||||
}
|
||||
length -= 4;
|
||||
ptr += 4;
|
||||
} else { /* length < 4 */
|
||||
memset (four_tuple, 0, 4);
|
||||
memcpy (four_tuple, ptr, length);
|
||||
convert_four_tuple (four_tuple, five_tuple);
|
||||
column += length + 1;
|
||||
_cairo_output_stream_write (stream, five_tuple, length + 1);
|
||||
length = 0;
|
||||
}
|
||||
if (column >= 72) {
|
||||
_cairo_output_stream_write (stream, "\n", 1);
|
||||
column = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (column > 0) {
|
||||
_cairo_output_stream_write (stream, "\n", 1);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* Format a double in a locale independent way and trim trailing
|
||||
* zeros. Based on code from Alex Larson <alexl@redhat.com>.
|
||||
* http://mail.gnome.org/archives/gtk-devel-list/2001-October/msg00087.html
|
||||
*
|
||||
* The code in the patch is copyright Red Hat, Inc under the LGPL, but
|
||||
* has been relicensed under the LGPL/MPL dual license for inclusion
|
||||
* into cairo (see COPYING). -- Kristian Høgsberg <krh@redhat.com>
|
||||
*/
|
||||
|
||||
int
|
||||
@ -238,8 +226,7 @@ enum {
|
||||
* formatting. This functionality is only for internal use and we
|
||||
* only implement the formats we actually use.
|
||||
*/
|
||||
|
||||
cairo_status_t
|
||||
void
|
||||
_cairo_output_stream_vprintf (cairo_output_stream_t *stream,
|
||||
const char *fmt, va_list ap)
|
||||
{
|
||||
@ -248,6 +235,9 @@ _cairo_output_stream_vprintf (cairo_output_stream_t *stream,
|
||||
const char *f;
|
||||
int length_modifier;
|
||||
|
||||
if (stream->status)
|
||||
return;
|
||||
|
||||
f = fmt;
|
||||
p = buffer;
|
||||
while (*f != '\0') {
|
||||
@ -310,24 +300,19 @@ _cairo_output_stream_vprintf (cairo_output_stream_t *stream,
|
||||
}
|
||||
|
||||
_cairo_output_stream_write (stream, buffer, p - buffer);
|
||||
|
||||
return stream->status;
|
||||
}
|
||||
|
||||
cairo_status_t
|
||||
void
|
||||
_cairo_output_stream_printf (cairo_output_stream_t *stream,
|
||||
const char *fmt, ...)
|
||||
{
|
||||
va_list ap;
|
||||
cairo_status_t status;
|
||||
|
||||
va_start (ap, fmt);
|
||||
|
||||
status = _cairo_output_stream_vprintf (stream, fmt, ap);
|
||||
_cairo_output_stream_vprintf (stream, fmt, ap);
|
||||
|
||||
va_end (ap);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
long
|
||||
@ -349,30 +334,57 @@ _cairo_output_stream_get_status (cairo_output_stream_t *stream)
|
||||
static cairo_status_t
|
||||
stdio_write (void *closure, const unsigned char *data, unsigned int length)
|
||||
{
|
||||
FILE *fp = closure;
|
||||
FILE *file = closure;
|
||||
|
||||
if (fwrite (data, 1, length, fp) == length)
|
||||
if (fwrite (data, 1, length, file) != length)
|
||||
return CAIRO_STATUS_WRITE_ERROR;
|
||||
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
static cairo_status_t
|
||||
stdio_flush (void *closure)
|
||||
{
|
||||
FILE *file = closure;
|
||||
|
||||
fflush (file);
|
||||
|
||||
if (ferror (file))
|
||||
return CAIRO_STATUS_WRITE_ERROR;
|
||||
else
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
return CAIRO_STATUS_WRITE_ERROR;
|
||||
static cairo_status_t
|
||||
stdio_close (void *closure)
|
||||
{
|
||||
cairo_status_t status;
|
||||
FILE *file = closure;
|
||||
|
||||
status = stdio_flush (closure);
|
||||
|
||||
fclose (file);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
cairo_output_stream_t *
|
||||
_cairo_output_stream_create_for_file (const char *filename)
|
||||
_cairo_output_stream_create_for_file (FILE *file)
|
||||
{
|
||||
FILE *fp;
|
||||
cairo_output_stream_t *stream;
|
||||
if (file == NULL)
|
||||
return (cairo_output_stream_t *) &cairo_output_stream_nil_write_error;
|
||||
|
||||
fp = fopen (filename, "wb");
|
||||
if (fp == NULL)
|
||||
return NULL;
|
||||
|
||||
stream = _cairo_output_stream_create (stdio_write, fp);
|
||||
|
||||
if (stream)
|
||||
stream->owns_closure_is_file = TRUE;
|
||||
else
|
||||
fclose (fp);
|
||||
|
||||
return stream;
|
||||
return _cairo_output_stream_create (stdio_write, stdio_flush, file);
|
||||
}
|
||||
|
||||
cairo_output_stream_t *
|
||||
_cairo_output_stream_create_for_filename (const char *filename)
|
||||
{
|
||||
FILE *file;
|
||||
|
||||
file = fopen (filename, "wb");
|
||||
if (file == NULL)
|
||||
return (cairo_output_stream_t *) &cairo_output_stream_nil_write_error;
|
||||
|
||||
return _cairo_output_stream_create (stdio_write, stdio_close, file);
|
||||
}
|
||||
|
||||
@ -38,11 +38,99 @@
|
||||
|
||||
#include "cairoint.h"
|
||||
|
||||
typedef enum {
|
||||
CAIRO_PAGINATED_MODE_ANALYZE, /* analyze page regions */
|
||||
CAIRO_PAGINATED_MODE_RENDER /* render page contents */
|
||||
} cairo_paginated_mode_t;
|
||||
|
||||
typedef struct _cairo_paginated_surface_backend {
|
||||
/* Optional. Will be called once for each page.
|
||||
*
|
||||
* NOTE: With respect to the order of drawing operations as seen
|
||||
* by the target, this call will occur before any drawing
|
||||
* operations for the relevant page. However, with respect to the
|
||||
* function calls as made by the user, this call will be *after*
|
||||
* any drawing operations for the page, (that is, it will occur
|
||||
* during the user's call to cairo_show_page or cairo_copy_page).
|
||||
*/
|
||||
cairo_int_status_t
|
||||
(*start_page) (void *surface);
|
||||
|
||||
/* Required. Will be called twice for each page, once with an
|
||||
* argument of CAIRO_PAGINATED_MODE_ANALYZE and once with
|
||||
* CAIRO_PAGINATED_MODE_RENDER. See more details in the
|
||||
* documentation for _cairo_paginated_surface_create below.
|
||||
*/
|
||||
void
|
||||
(*set_paginated_mode) (void *surface,
|
||||
cairo_paginated_mode_t mode);
|
||||
} cairo_paginated_surface_backend_t;
|
||||
|
||||
/* A cairo_paginated_surface provides a very convenient wrapper that
|
||||
* is well-suited for doing the analysis common to most surfaces that
|
||||
* have paginated output, (that is, things directed at printers, or
|
||||
* for saving content in files such as PostScript or PDF files).
|
||||
*
|
||||
* To use the paginated surface, you'll first need to create your
|
||||
* 'real' surface using _cairo_surface_init and the standard
|
||||
* cairo_surface_backend_t. Then you also call
|
||||
* _cairo_paginated_surface_create which takes its own, much simpler,
|
||||
* cairo_paginated_surface_backend. You are free to return the result
|
||||
* of _cairo_paginated_surface_create from your public
|
||||
* cairo_<foo>_surface_create. The paginated backend will be careful
|
||||
* to not let the user see that they really got a "wrapped"
|
||||
* surface. See test-paginated-surface.c for a fairly minimal example
|
||||
* of a paginated-using surface. That should be a reasonable example
|
||||
* to follow.
|
||||
*
|
||||
* What the paginated surface does is first save all drawing
|
||||
* operations for a page into a meta-surface. Then when the user calls
|
||||
* cairo_show_page, the paginated surface performs the following
|
||||
* sequence of operations (using the backend functions passed to
|
||||
* cairo_paginated_surface_create):
|
||||
*
|
||||
* 1. Calls start_page (if non NULL). At this point, it is appropriate
|
||||
* for the target to emit any page-specific header information into
|
||||
* its output.
|
||||
*
|
||||
* 2. Calls set_paginated_mode with an argument of CAIRO_PAGINATED_MODE_ANALYZE
|
||||
*
|
||||
* 3. Replays the meta-surface to the target surface, (with an
|
||||
* analysis surface inserted between which watches the return value
|
||||
* from each operation). This analysis stage is used to decide which
|
||||
* operations will require fallbacks.
|
||||
*
|
||||
* 4. Calls set_paginated_mode with an argument of CAIRO_PAGINATED_MODE_RENDER
|
||||
*
|
||||
* 5. Replays a subset of the meta-surface operations to the target surface
|
||||
*
|
||||
* 6. Replays the remaining operations to an image surface, sets an
|
||||
* appropriate clip on the target, then paints the resulting image
|
||||
* surface to the target.
|
||||
*
|
||||
* So, the target will see drawing operations during two separate
|
||||
* stages, (ANALYZE and RENDER). During the ANALYZE phase the target
|
||||
* should not actually perform any rendering, (for example, if
|
||||
* performing output to a file, no output should be generated during
|
||||
* this stage). Instead the drawing functions simply need to return
|
||||
* CAIRO_STATUS_SUCCESS or CAIRO_INT_STATUS_UNSUPPORTED to indicate
|
||||
* whether rendering would be supported. And it should do this as
|
||||
* quickly as possible.
|
||||
*
|
||||
* NOTE: The paginated surface layer assumes that the target surface
|
||||
* is "blank" by default at the beginning of each page, without any
|
||||
* need for an explicit erasea operation, (as opposed to an image
|
||||
* surface, for example, which might have uninitialized content
|
||||
* originally). As such, it optimizes away CLEAR operations that
|
||||
* happen at the beginning of each page---the target surface will not
|
||||
* even see these operations.
|
||||
*/
|
||||
cairo_private cairo_surface_t *
|
||||
_cairo_paginated_surface_create (cairo_surface_t *target,
|
||||
cairo_content_t content,
|
||||
int width,
|
||||
int height);
|
||||
_cairo_paginated_surface_create (cairo_surface_t *target,
|
||||
cairo_content_t content,
|
||||
int width,
|
||||
int height,
|
||||
const cairo_paginated_surface_backend_t *backend);
|
||||
|
||||
cairo_private cairo_surface_t *
|
||||
_cairo_paginated_surface_get_target (cairo_surface_t *surface);
|
||||
|
||||
@ -31,47 +31,27 @@
|
||||
*
|
||||
* Contributor(s):
|
||||
* Carl Worth <cworth@cworth.org>
|
||||
* Keith Packard <keithp@keithp.com>
|
||||
*/
|
||||
|
||||
/* The paginated surface layer exists to provide as much code sharing
|
||||
* as possible for the various paginated surface backends in cairo
|
||||
* (PostScript, PDF, etc.).
|
||||
*
|
||||
* The concept is that a surface which uses a paginated surface merely
|
||||
* needs to implement backend operations which it can accurately
|
||||
* provide, (and return CAIRO_INT_STATUS_UNSUPPORTED or leave backend
|
||||
* function pointers NULL otherwise). The paginated surface is the
|
||||
* responsible for collecting operations that aren't supported,
|
||||
* replaying them against the image surface, and then supplying the
|
||||
* resulting images to the target surface.
|
||||
*
|
||||
* When created, a paginated surface accepts the target surface to
|
||||
* which the final drawing will eventually be performed. The paginated
|
||||
* surface then uses cairo_meta_surface_t to record all drawing
|
||||
* operations up until each show_page operation.
|
||||
*
|
||||
* At the time of show_page, the paginated surface replays the meta
|
||||
* surface against the target surface and maintains regions of the
|
||||
* result that will come from the nativ surface and regions that will
|
||||
* need to come from image fallbacks. It then replays the necessary
|
||||
* portions against image surface and provides those results to the
|
||||
* target surface through existing interfaces.
|
||||
*
|
||||
* This way the target surface is never even aware of any distinction
|
||||
* between native drawing operations vs. results that are supplied by
|
||||
* image fallbacks. Instead the surface need only implement as much of
|
||||
* the surface backend interface as it can do correctly, and let the
|
||||
* paginated surface take care of all the messy details.
|
||||
* (PostScript, PDF, etc.). See cairo-paginated-surface-private.h for
|
||||
* more details on how it works and how to use it.
|
||||
*/
|
||||
|
||||
#include "cairoint.h"
|
||||
|
||||
#include "cairo-paginated-surface-private.h"
|
||||
#include "cairo-meta-surface-private.h"
|
||||
#include "cairo-analysis-surface-private.h"
|
||||
|
||||
typedef struct _cairo_paginated_surface {
|
||||
cairo_surface_t base;
|
||||
|
||||
/* The target surface to hold the final result. */
|
||||
cairo_surface_t *target;
|
||||
|
||||
cairo_content_t content;
|
||||
|
||||
/* XXX: These shouldn't actually exist. We inherit this ugliness
|
||||
@ -82,14 +62,16 @@ typedef struct _cairo_paginated_surface {
|
||||
int width;
|
||||
int height;
|
||||
|
||||
/* The target surface to hold the final result. */
|
||||
cairo_surface_t *target;
|
||||
/* Paginated-surface specific functions for the target */
|
||||
const cairo_paginated_surface_backend_t *backend;
|
||||
|
||||
/* A cairo_meta_surface to record all operations. To be replayed
|
||||
* against target, and also against image surface as necessary for
|
||||
* fallbacks. */
|
||||
cairo_surface_t *meta;
|
||||
|
||||
cairo_bool_t page_is_blank;
|
||||
|
||||
} cairo_paginated_surface_t;
|
||||
|
||||
const cairo_private cairo_surface_backend_t cairo_paginated_surface_backend;
|
||||
@ -97,12 +79,6 @@ const cairo_private cairo_surface_backend_t cairo_paginated_surface_backend;
|
||||
static cairo_int_status_t
|
||||
_cairo_paginated_surface_show_page (void *abstract_surface);
|
||||
|
||||
/* XXX: This would seem the natural thing to do here. But currently,
|
||||
* PDF and PS surfaces do not yet work as source surfaces. So instead,
|
||||
* we don't implement create_similar for the paginate_surface which
|
||||
* means that any create_similar() call on a paginated_surfacae will
|
||||
* result in a new image surface. */
|
||||
#if 0
|
||||
static cairo_surface_t *
|
||||
_cairo_paginated_surface_create_similar (void *abstract_surface,
|
||||
cairo_content_t content,
|
||||
@ -113,13 +89,13 @@ _cairo_paginated_surface_create_similar (void *abstract_surface,
|
||||
return cairo_surface_create_similar (surface->target, content,
|
||||
width, height);
|
||||
}
|
||||
#endif
|
||||
|
||||
cairo_surface_t *
|
||||
_cairo_paginated_surface_create (cairo_surface_t *target,
|
||||
cairo_content_t content,
|
||||
int width,
|
||||
int height)
|
||||
_cairo_paginated_surface_create (cairo_surface_t *target,
|
||||
cairo_content_t content,
|
||||
int width,
|
||||
int height,
|
||||
const cairo_paginated_surface_backend_t *backend)
|
||||
{
|
||||
cairo_paginated_surface_t *surface;
|
||||
|
||||
@ -127,22 +103,27 @@ _cairo_paginated_surface_create (cairo_surface_t *target,
|
||||
if (surface == NULL)
|
||||
goto FAIL;
|
||||
|
||||
_cairo_surface_init (&surface->base, &cairo_paginated_surface_backend);
|
||||
_cairo_surface_init (&surface->base, &cairo_paginated_surface_backend,
|
||||
content);
|
||||
|
||||
/* Override surface->base.type with target's type so we don't leak
|
||||
* evidence of the paginated wrapper out to the user. */
|
||||
surface->base.type = cairo_surface_get_type (target);
|
||||
|
||||
surface->target = target;
|
||||
|
||||
surface->content = content;
|
||||
surface->width = width;
|
||||
surface->height = height;
|
||||
|
||||
surface->target = target;
|
||||
surface->backend = backend;
|
||||
|
||||
surface->meta = _cairo_meta_surface_create (content, width, height);
|
||||
if (cairo_surface_status (surface->meta))
|
||||
goto FAIL_CLEANUP_SURFACE;
|
||||
|
||||
surface->page_is_blank = TRUE;
|
||||
|
||||
return &surface->base;
|
||||
|
||||
FAIL_CLEANUP_SURFACE:
|
||||
@ -189,7 +170,7 @@ _cairo_paginated_surface_acquire_source_image (void *abstract_surface,
|
||||
{
|
||||
cairo_paginated_surface_t *surface = abstract_surface;
|
||||
cairo_surface_t *image;
|
||||
cairo_rectangle_t extents;
|
||||
cairo_rectangle_fixed_t extents;
|
||||
|
||||
_cairo_surface_get_extents (surface->target, &extents);
|
||||
|
||||
@ -213,32 +194,72 @@ _cairo_paginated_surface_release_source_image (void *abstract_surface,
|
||||
cairo_surface_destroy (&image->base);
|
||||
}
|
||||
|
||||
static void
|
||||
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;
|
||||
|
||||
image = _cairo_image_surface_create_with_content (surface->content,
|
||||
surface->width,
|
||||
surface->height);
|
||||
analysis = _cairo_analysis_surface_create (surface->target,
|
||||
surface->width, surface->height);
|
||||
|
||||
_cairo_meta_surface_replay (surface->meta, image);
|
||||
surface->backend->set_paginated_mode (surface->target, CAIRO_PAGINATED_MODE_ANALYZE);
|
||||
_cairo_meta_surface_replay (surface->meta, analysis);
|
||||
surface->backend->set_paginated_mode (surface->target, CAIRO_PAGINATED_MODE_RENDER);
|
||||
|
||||
pattern = cairo_pattern_create_for_surface (image);
|
||||
if (analysis->status) {
|
||||
status = analysis->status;
|
||||
cairo_surface_destroy (analysis);
|
||||
return status;
|
||||
}
|
||||
|
||||
if (_cairo_analysis_surface_has_unsupported (analysis))
|
||||
{
|
||||
image = _cairo_image_surface_create_with_content (surface->content,
|
||||
surface->width,
|
||||
surface->height);
|
||||
|
||||
_cairo_surface_paint (surface->target, CAIRO_OPERATOR_SOURCE, pattern);
|
||||
_cairo_meta_surface_replay (surface->meta, image);
|
||||
|
||||
cairo_pattern_destroy (pattern);
|
||||
pattern = cairo_pattern_create_for_surface (image);
|
||||
|
||||
cairo_surface_destroy (image);
|
||||
_cairo_surface_paint (surface->target, CAIRO_OPERATOR_SOURCE, pattern);
|
||||
|
||||
cairo_pattern_destroy (pattern);
|
||||
|
||||
cairo_surface_destroy (image);
|
||||
}
|
||||
else
|
||||
{
|
||||
_cairo_meta_surface_replay (surface->meta, surface->target);
|
||||
}
|
||||
|
||||
cairo_surface_destroy (analysis);
|
||||
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
static cairo_status_t
|
||||
_start_page (cairo_paginated_surface_t *surface)
|
||||
{
|
||||
if (! surface->backend->start_page)
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
|
||||
return (surface->backend->start_page) (surface->target);
|
||||
}
|
||||
|
||||
static cairo_int_status_t
|
||||
_cairo_paginated_surface_copy_page (void *abstract_surface)
|
||||
{
|
||||
cairo_status_t status;
|
||||
cairo_paginated_surface_t *surface = abstract_surface;
|
||||
|
||||
status = _start_page (surface);
|
||||
if (status)
|
||||
return status;
|
||||
|
||||
_paint_page (surface);
|
||||
|
||||
/* XXX: It might make sense to add some suport here for calling
|
||||
@ -257,8 +278,13 @@ _cairo_paginated_surface_copy_page (void *abstract_surface)
|
||||
static cairo_int_status_t
|
||||
_cairo_paginated_surface_show_page (void *abstract_surface)
|
||||
{
|
||||
cairo_status_t status;
|
||||
cairo_paginated_surface_t *surface = abstract_surface;
|
||||
|
||||
status = _start_page (surface);
|
||||
if (status)
|
||||
return status;
|
||||
|
||||
_paint_page (surface);
|
||||
|
||||
_cairo_surface_show_page (surface->target);
|
||||
@ -270,6 +296,8 @@ _cairo_paginated_surface_show_page (void *abstract_surface)
|
||||
if (cairo_surface_status (surface->meta))
|
||||
return cairo_surface_status (surface->meta);
|
||||
|
||||
surface->page_is_blank = TRUE;
|
||||
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
@ -288,14 +316,23 @@ _cairo_paginated_surface_intersect_clip_path (void *abstract_surface,
|
||||
}
|
||||
|
||||
static cairo_int_status_t
|
||||
_cairo_paginated_surface_get_extents (void *abstract_surface,
|
||||
cairo_rectangle_t *rectangle)
|
||||
_cairo_paginated_surface_get_extents (void *abstract_surface,
|
||||
cairo_rectangle_fixed_t *rectangle)
|
||||
{
|
||||
cairo_paginated_surface_t *surface = abstract_surface;
|
||||
|
||||
return _cairo_surface_get_extents (surface->target, rectangle);
|
||||
}
|
||||
|
||||
static void
|
||||
_cairo_paginated_surface_get_font_options (void *abstract_surface,
|
||||
cairo_font_options_t *options)
|
||||
{
|
||||
cairo_paginated_surface_t *surface = abstract_surface;
|
||||
|
||||
cairo_surface_get_font_options (surface->target, options);
|
||||
}
|
||||
|
||||
static cairo_int_status_t
|
||||
_cairo_paginated_surface_paint (void *abstract_surface,
|
||||
cairo_operator_t op,
|
||||
@ -303,6 +340,12 @@ _cairo_paginated_surface_paint (void *abstract_surface,
|
||||
{
|
||||
cairo_paginated_surface_t *surface = abstract_surface;
|
||||
|
||||
/* Optimize away erasing of nothing. */
|
||||
if (surface->page_is_blank && op == CAIRO_OPERATOR_CLEAR)
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
|
||||
surface->page_is_blank = FALSE;
|
||||
|
||||
return _cairo_surface_paint (surface->meta, op, source);
|
||||
}
|
||||
|
||||
@ -330,6 +373,12 @@ _cairo_paginated_surface_stroke (void *abstract_surface,
|
||||
{
|
||||
cairo_paginated_surface_t *surface = abstract_surface;
|
||||
|
||||
/* Optimize away erasing of nothing. */
|
||||
if (surface->page_is_blank && op == CAIRO_OPERATOR_CLEAR)
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
|
||||
surface->page_is_blank = FALSE;
|
||||
|
||||
return _cairo_surface_stroke (surface->meta, op, source,
|
||||
path, style,
|
||||
ctm, ctm_inverse,
|
||||
@ -347,6 +396,12 @@ _cairo_paginated_surface_fill (void *abstract_surface,
|
||||
{
|
||||
cairo_paginated_surface_t *surface = abstract_surface;
|
||||
|
||||
/* Optimize away erasing of nothing. */
|
||||
if (surface->page_is_blank && op == CAIRO_OPERATOR_CLEAR)
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
|
||||
surface->page_is_blank = FALSE;
|
||||
|
||||
return _cairo_surface_fill (surface->meta, op, source,
|
||||
path, fill_rule,
|
||||
tolerance, antialias);
|
||||
@ -362,6 +417,12 @@ _cairo_paginated_surface_show_glyphs (void *abstract_surface,
|
||||
{
|
||||
cairo_paginated_surface_t *surface = abstract_surface;
|
||||
|
||||
/* Optimize away erasing of nothing. */
|
||||
if (surface->page_is_blank && op == CAIRO_OPERATOR_CLEAR)
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
|
||||
surface->page_is_blank = FALSE;
|
||||
|
||||
return _cairo_surface_show_glyphs (surface->meta, op, source,
|
||||
glyphs, num_glyphs,
|
||||
scaled_font);
|
||||
@ -387,7 +448,7 @@ _cairo_paginated_surface_snapshot (void *abstract_other)
|
||||
#if 0
|
||||
return _cairo_surface_snapshot (other->meta);
|
||||
#else
|
||||
cairo_rectangle_t extents;
|
||||
cairo_rectangle_fixed_t extents;
|
||||
cairo_surface_t *surface;
|
||||
|
||||
_cairo_surface_get_extents (other->target, &extents);
|
||||
@ -404,7 +465,7 @@ _cairo_paginated_surface_snapshot (void *abstract_other)
|
||||
|
||||
const cairo_surface_backend_t cairo_paginated_surface_backend = {
|
||||
CAIRO_INTERNAL_SURFACE_TYPE_PAGINATED,
|
||||
NULL, /* create_similar --- see note for _cairo_paginated_surface_create_similar */
|
||||
_cairo_paginated_surface_create_similar,
|
||||
_cairo_paginated_surface_finish,
|
||||
_cairo_paginated_surface_acquire_source_image,
|
||||
_cairo_paginated_surface_release_source_image,
|
||||
@ -420,7 +481,7 @@ const cairo_surface_backend_t cairo_paginated_surface_backend = {
|
||||
_cairo_paginated_surface_intersect_clip_path,
|
||||
_cairo_paginated_surface_get_extents,
|
||||
NULL, /* old_show_glyphs */
|
||||
NULL, /* get_font_options */
|
||||
_cairo_paginated_surface_get_font_options,
|
||||
NULL, /* flush */
|
||||
NULL, /* mark_dirty_rectangle */
|
||||
NULL, /* scaled_font_fini */
|
||||
|
||||
@ -47,7 +47,6 @@ typedef struct cairo_stroker {
|
||||
|
||||
cairo_pen_t pen;
|
||||
|
||||
cairo_bool_t has_current_point;
|
||||
cairo_point_t current_point;
|
||||
cairo_point_t first_point;
|
||||
|
||||
@ -116,7 +115,11 @@ _cairo_stroker_start_dash (cairo_stroker_t *stroker)
|
||||
int i = 0;
|
||||
|
||||
offset = stroker->style->dash_offset;
|
||||
while (offset >= stroker->style->dash[i]) {
|
||||
|
||||
/* We stop searching for a starting point as soon as the
|
||||
offset reaches zero. Otherwise when an initial dash
|
||||
segment shrinks to zero it will be skipped over. */
|
||||
while (offset > 0.0 && offset >= stroker->style->dash[i]) {
|
||||
offset -= stroker->style->dash[i];
|
||||
on = 1-on;
|
||||
if (++i == stroker->style->num_dashes)
|
||||
@ -159,7 +162,6 @@ _cairo_stroker_init (cairo_stroker_t *stroker,
|
||||
stroke_style->line_width / 2.0,
|
||||
tolerance, ctm);
|
||||
|
||||
stroker->has_current_point = FALSE;
|
||||
stroker->has_current_face = FALSE;
|
||||
stroker->has_first_face = FALSE;
|
||||
|
||||
@ -548,11 +550,18 @@ _compute_face (cairo_point_t *point, cairo_slope_t *slope, cairo_stroker_t *stro
|
||||
|
||||
static cairo_status_t
|
||||
_cairo_stroker_add_sub_edge (cairo_stroker_t *stroker, cairo_point_t *p1, cairo_point_t *p2,
|
||||
cairo_stroke_face_t *start, cairo_stroke_face_t *end)
|
||||
cairo_slope_t *slope, cairo_stroke_face_t *start,
|
||||
cairo_stroke_face_t *end)
|
||||
{
|
||||
cairo_status_t status;
|
||||
cairo_polygon_t polygon;
|
||||
cairo_slope_t slope;
|
||||
|
||||
_compute_face (p1, slope, stroker, start);
|
||||
|
||||
/* XXX: This could be optimized slightly by not calling
|
||||
_compute_face again but rather translating the relevant
|
||||
fields from start. */
|
||||
_compute_face (p2, slope, stroker, end);
|
||||
|
||||
if (p1->x == p2->x && p1->y == p2->y) {
|
||||
/* XXX: Need to rethink how this case should be handled, (both
|
||||
@ -561,14 +570,6 @@ _cairo_stroker_add_sub_edge (cairo_stroker_t *stroker, cairo_point_t *p1, cairo_
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
_cairo_slope_init (&slope, p1, p2);
|
||||
_compute_face (p1, &slope, stroker, start);
|
||||
|
||||
/* XXX: This could be optimized slightly by not calling
|
||||
_compute_face again but rather translating the relevant
|
||||
fields from start. */
|
||||
_compute_face (p2, &slope, stroker, end);
|
||||
|
||||
/* XXX: I should really check the return value of the
|
||||
move_to/line_to functions here to catch out of memory
|
||||
conditions. But since that would be ugly, I'd prefer to add a
|
||||
@ -607,7 +608,6 @@ _cairo_stroker_move_to (void *closure, cairo_point_t *point)
|
||||
|
||||
stroker->first_point = *point;
|
||||
stroker->current_point = *point;
|
||||
stroker->has_current_point = 1;
|
||||
|
||||
stroker->has_first_face = 0;
|
||||
stroker->has_current_face = 0;
|
||||
@ -615,6 +615,16 @@ _cairo_stroker_move_to (void *closure, cairo_point_t *point)
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
static cairo_status_t
|
||||
_cairo_stroker_move_to_dashed (void *closure, cairo_point_t *point)
|
||||
{
|
||||
/* reset the dash pattern for new sub paths */
|
||||
cairo_stroker_t *stroker = closure;
|
||||
_cairo_stroker_start_dash (stroker);
|
||||
|
||||
return _cairo_stroker_move_to (closure, point);
|
||||
}
|
||||
|
||||
static cairo_status_t
|
||||
_cairo_stroker_line_to (void *closure, cairo_point_t *point)
|
||||
{
|
||||
@ -623,9 +633,7 @@ _cairo_stroker_line_to (void *closure, cairo_point_t *point)
|
||||
cairo_stroke_face_t start, end;
|
||||
cairo_point_t *p1 = &stroker->current_point;
|
||||
cairo_point_t *p2 = point;
|
||||
|
||||
if (!stroker->has_current_point)
|
||||
return _cairo_stroker_move_to (stroker, point);
|
||||
cairo_slope_t slope;
|
||||
|
||||
if (p1->x == p2->x && p1->y == p2->y) {
|
||||
/* XXX: Need to rethink how this case should be handled, (both
|
||||
@ -634,8 +642,10 @@ _cairo_stroker_line_to (void *closure, cairo_point_t *point)
|
||||
as possible. */
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
_cairo_slope_init (&slope, p1, p2);
|
||||
|
||||
status = _cairo_stroker_add_sub_edge (stroker, p1, p2, &start, &end);
|
||||
status = _cairo_stroker_add_sub_edge (stroker, p1, p2, &slope, &start, &end);
|
||||
if (status)
|
||||
return status;
|
||||
|
||||
@ -673,10 +683,18 @@ _cairo_stroker_line_to_dashed (void *closure, cairo_point_t *point)
|
||||
cairo_stroke_face_t sub_start, sub_end;
|
||||
cairo_point_t *p1 = &stroker->current_point;
|
||||
cairo_point_t *p2 = point;
|
||||
cairo_slope_t slope;
|
||||
|
||||
if (p1->x == p2->x && p1->y == p2->y) {
|
||||
/* XXX: Need to rethink how this case should be handled, (both
|
||||
here and in cairo_stroker_add_sub_edge and in _compute_face). The
|
||||
key behavior is that degenerate paths should draw as much
|
||||
as possible. */
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
_cairo_slope_init (&slope, p1, p2);
|
||||
|
||||
if (!stroker->has_current_point)
|
||||
return _cairo_stroker_move_to (stroker, point);
|
||||
|
||||
dx = _cairo_fixed_to_double (p2->x - p1->x);
|
||||
dy = _cairo_fixed_to_double (p2->y - p1->y);
|
||||
|
||||
@ -701,7 +719,7 @@ _cairo_stroker_line_to_dashed (void *closure, cairo_point_t *point)
|
||||
* XXX simplify this case analysis
|
||||
*/
|
||||
if (stroker->dash_on) {
|
||||
status = _cairo_stroker_add_sub_edge (stroker, &fd1, &fd2, &sub_start, &sub_end);
|
||||
status = _cairo_stroker_add_sub_edge (stroker, &fd1, &fd2, &slope, &sub_start, &sub_end);
|
||||
if (status)
|
||||
return status;
|
||||
if (!first) {
|
||||
@ -914,14 +932,12 @@ _cairo_stroker_close_path (void *closure)
|
||||
cairo_status_t status;
|
||||
cairo_stroker_t *stroker = closure;
|
||||
|
||||
if (stroker->has_current_point) {
|
||||
if (stroker->dashed)
|
||||
status = _cairo_stroker_line_to_dashed (stroker, &stroker->first_point);
|
||||
else
|
||||
status = _cairo_stroker_line_to (stroker, &stroker->first_point);
|
||||
if (status)
|
||||
return status;
|
||||
}
|
||||
if (stroker->dashed)
|
||||
status = _cairo_stroker_line_to_dashed (stroker, &stroker->first_point);
|
||||
else
|
||||
status = _cairo_stroker_line_to (stroker, &stroker->first_point);
|
||||
if (status)
|
||||
return status;
|
||||
|
||||
if (stroker->has_first_face && stroker->has_current_face) {
|
||||
status = _cairo_stroker_join (stroker, &stroker->current_face, &stroker->first_face);
|
||||
@ -931,7 +947,6 @@ _cairo_stroker_close_path (void *closure)
|
||||
|
||||
stroker->has_first_face = 0;
|
||||
stroker->has_current_face = 0;
|
||||
stroker->has_current_point = 0;
|
||||
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
}
|
||||
@ -954,7 +969,7 @@ _cairo_path_fixed_stroke_to_traps (cairo_path_fixed_t *path,
|
||||
if (stroker.style->dash)
|
||||
status = _cairo_path_fixed_interpret (path,
|
||||
CAIRO_DIRECTION_FORWARD,
|
||||
_cairo_stroker_move_to,
|
||||
_cairo_stroker_move_to_dashed,
|
||||
_cairo_stroker_line_to_dashed,
|
||||
_cairo_stroker_curve_to_dashed,
|
||||
_cairo_stroker_close_path,
|
||||
|
||||
@ -87,7 +87,7 @@ _cairo_path_fixed_init (cairo_path_fixed_t *path)
|
||||
|
||||
path->current_point.x = 0;
|
||||
path->current_point.y = 0;
|
||||
path->has_current_point = 0;
|
||||
path->has_current_point = FALSE;
|
||||
path->last_move_point = path->current_point;
|
||||
}
|
||||
|
||||
@ -163,7 +163,7 @@ _cairo_path_fixed_fini (cairo_path_fixed_t *path)
|
||||
}
|
||||
path->arg_buf_tail = NULL;
|
||||
|
||||
path->has_current_point = 0;
|
||||
path->has_current_point = FALSE;
|
||||
}
|
||||
|
||||
void
|
||||
@ -189,12 +189,18 @@ _cairo_path_fixed_move_to (cairo_path_fixed_t *path,
|
||||
return status;
|
||||
|
||||
path->current_point = point;
|
||||
path->has_current_point = 1;
|
||||
path->has_current_point = TRUE;
|
||||
path->last_move_point = path->current_point;
|
||||
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
void
|
||||
_cairo_path_fixed_new_sub_path (cairo_path_fixed_t *path)
|
||||
{
|
||||
path->has_current_point = FALSE;
|
||||
}
|
||||
|
||||
cairo_status_t
|
||||
_cairo_path_fixed_rel_move_to (cairo_path_fixed_t *path,
|
||||
cairo_fixed_t dx,
|
||||
@ -202,7 +208,7 @@ _cairo_path_fixed_rel_move_to (cairo_path_fixed_t *path,
|
||||
{
|
||||
cairo_fixed_t x, y;
|
||||
|
||||
if (!path->has_current_point)
|
||||
if (! path->has_current_point)
|
||||
return CAIRO_STATUS_NO_CURRENT_POINT;
|
||||
|
||||
x = path->current_point.x + dx;
|
||||
@ -222,12 +228,16 @@ _cairo_path_fixed_line_to (cairo_path_fixed_t *path,
|
||||
point.x = x;
|
||||
point.y = y;
|
||||
|
||||
status = _cairo_path_fixed_add (path, CAIRO_PATH_OP_LINE_TO, &point, 1);
|
||||
if (! path->has_current_point)
|
||||
status = _cairo_path_fixed_add (path, CAIRO_PATH_OP_MOVE_TO, &point, 1);
|
||||
else
|
||||
status = _cairo_path_fixed_add (path, CAIRO_PATH_OP_LINE_TO, &point, 1);
|
||||
|
||||
if (status)
|
||||
return status;
|
||||
|
||||
path->current_point = point;
|
||||
path->has_current_point = 1;
|
||||
path->has_current_point = TRUE;
|
||||
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
}
|
||||
@ -239,7 +249,7 @@ _cairo_path_fixed_rel_line_to (cairo_path_fixed_t *path,
|
||||
{
|
||||
cairo_fixed_t x, y;
|
||||
|
||||
if (!path->has_current_point)
|
||||
if (! path->has_current_point)
|
||||
return CAIRO_STATUS_NO_CURRENT_POINT;
|
||||
|
||||
x = path->current_point.x + dx;
|
||||
@ -261,12 +271,19 @@ _cairo_path_fixed_curve_to (cairo_path_fixed_t *path,
|
||||
point[1].x = x1; point[1].y = y1;
|
||||
point[2].x = x2; point[2].y = y2;
|
||||
|
||||
if (! path->has_current_point) {
|
||||
status = _cairo_path_fixed_add (path, CAIRO_PATH_OP_MOVE_TO,
|
||||
&point[0], 1);
|
||||
if (status)
|
||||
return status;
|
||||
}
|
||||
|
||||
status = _cairo_path_fixed_add (path, CAIRO_PATH_OP_CURVE_TO, point, 3);
|
||||
if (status)
|
||||
return status;
|
||||
|
||||
path->current_point = point[2];
|
||||
path->has_current_point = 1;
|
||||
path->has_current_point = TRUE;
|
||||
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
}
|
||||
@ -281,7 +298,7 @@ _cairo_path_fixed_rel_curve_to (cairo_path_fixed_t *path,
|
||||
cairo_fixed_t x1, y1;
|
||||
cairo_fixed_t x2, y2;
|
||||
|
||||
if (!path->has_current_point)
|
||||
if (! path->has_current_point)
|
||||
return CAIRO_STATUS_NO_CURRENT_POINT;
|
||||
|
||||
x0 = path->current_point.x + dx0;
|
||||
@ -304,13 +321,16 @@ _cairo_path_fixed_close_path (cairo_path_fixed_t *path)
|
||||
{
|
||||
cairo_status_t status;
|
||||
|
||||
if (! path->has_current_point)
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
|
||||
status = _cairo_path_fixed_add (path, CAIRO_PATH_OP_CLOSE_PATH, NULL, 0);
|
||||
if (status)
|
||||
return status;
|
||||
|
||||
path->current_point.x = path->last_move_point.x;
|
||||
path->current_point.y = path->last_move_point.y;
|
||||
path->has_current_point = 1;
|
||||
path->has_current_point = TRUE;
|
||||
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
@ -1050,7 +1050,6 @@ _cairo_pattern_acquire_surface_for_solid (cairo_solid_pattern_t *pattern,
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* _cairo_pattern_is_opaque_solid
|
||||
*
|
||||
@ -1063,7 +1062,7 @@ _cairo_pattern_acquire_surface_for_solid (cairo_solid_pattern_t *pattern,
|
||||
* Return value: %TRUE if the pattern is an opaque, solid color.
|
||||
**/
|
||||
cairo_bool_t
|
||||
_cairo_pattern_is_opaque_solid (cairo_pattern_t *pattern)
|
||||
_cairo_pattern_is_opaque_solid (const cairo_pattern_t *pattern)
|
||||
{
|
||||
cairo_solid_pattern_t *solid;
|
||||
|
||||
@ -1075,6 +1074,47 @@ _cairo_pattern_is_opaque_solid (cairo_pattern_t *pattern)
|
||||
return CAIRO_ALPHA_IS_OPAQUE (solid->color.alpha);
|
||||
}
|
||||
|
||||
static cairo_bool_t
|
||||
_gradient_is_opaque (const cairo_gradient_pattern_t *gradient)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < gradient->n_stops; i++)
|
||||
if (! CAIRO_ALPHA_IS_OPAQUE (gradient->stops[i].color.alpha))
|
||||
return FALSE;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* _cairo_pattern_is_opaque
|
||||
*
|
||||
* Convenience function to determine whether a pattern is an opaque
|
||||
* pattern (of any type). The same caveats that apply to
|
||||
* _cairo_pattern_is_opaque_solid apply here as well.
|
||||
*
|
||||
* Return value: %TRUE if the pattern is a opaque.
|
||||
**/
|
||||
cairo_bool_t
|
||||
_cairo_pattern_is_opaque (const cairo_pattern_t *abstract_pattern)
|
||||
{
|
||||
const cairo_pattern_union_t *pattern;
|
||||
|
||||
pattern = (cairo_pattern_union_t *) abstract_pattern;
|
||||
switch (pattern->base.type) {
|
||||
case CAIRO_PATTERN_TYPE_SOLID:
|
||||
return _cairo_pattern_is_opaque_solid (abstract_pattern);
|
||||
case CAIRO_PATTERN_TYPE_SURFACE:
|
||||
return _cairo_surface_is_opaque (pattern->surface.surface);
|
||||
case CAIRO_PATTERN_TYPE_LINEAR:
|
||||
case CAIRO_PATTERN_TYPE_RADIAL:
|
||||
return _gradient_is_opaque (&pattern->gradient.base);
|
||||
}
|
||||
|
||||
ASSERT_NOT_REACHED;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static cairo_int_status_t
|
||||
_cairo_pattern_acquire_surface_for_surface (cairo_surface_pattern_t *pattern,
|
||||
cairo_surface_t *dst,
|
||||
@ -1354,14 +1394,14 @@ _cairo_pattern_acquire_surfaces (cairo_pattern_t *src,
|
||||
* with a little more work.
|
||||
**/
|
||||
cairo_status_t
|
||||
_cairo_pattern_get_extents (cairo_pattern_t *pattern,
|
||||
cairo_rectangle_t *extents)
|
||||
_cairo_pattern_get_extents (cairo_pattern_t *pattern,
|
||||
cairo_rectangle_fixed_t *extents)
|
||||
{
|
||||
if (pattern->extend == CAIRO_EXTEND_NONE &&
|
||||
pattern->type == CAIRO_PATTERN_TYPE_SURFACE)
|
||||
{
|
||||
cairo_status_t status;
|
||||
cairo_rectangle_t surface_extents;
|
||||
cairo_rectangle_fixed_t surface_extents;
|
||||
cairo_surface_pattern_t *surface_pattern =
|
||||
(cairo_surface_pattern_t *) pattern;
|
||||
cairo_surface_t *surface = surface_pattern->surface;
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
76
mozilla/gfx/cairo/cairo/src/cairo-pdf-test.h
Executable file
76
mozilla/gfx/cairo/cairo/src/cairo-pdf-test.h
Executable file
@ -0,0 +1,76 @@
|
||||
/* cairo - a vector graphics library with display and print output
|
||||
*
|
||||
* Copyright © 2006 Red Hat, Inc.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it either under the terms of the GNU Lesser General Public
|
||||
* License version 2.1 as published by the Free Software Foundation
|
||||
* (the "LGPL") or, at your option, under the terms of the Mozilla
|
||||
* Public License Version 1.1 (the "MPL"). If you do not alter this
|
||||
* notice, a recipient may use your version of this file under either
|
||||
* the MPL or the LGPL.
|
||||
*
|
||||
* You should have received a copy of the LGPL along with this library
|
||||
* in the file COPYING-LGPL-2.1; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
* You should have received a copy of the MPL along with this library
|
||||
* in the file COPYING-MPL-1.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License
|
||||
* Version 1.1 (the "License"); you may not use this file except in
|
||||
* compliance with the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY
|
||||
* OF ANY KIND, either express or implied. See the LGPL or the MPL for
|
||||
* the specific language governing rights and limitations.
|
||||
*
|
||||
* The Original Code is the cairo graphics library.
|
||||
*
|
||||
* The Initial Developer of the Original Code is University of Southern
|
||||
* California.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Carl D. Worth <cworth@cworth.org>
|
||||
*/
|
||||
|
||||
#ifndef CAIRO_PDF_TEST_H
|
||||
#define CAIRO_PDF_TEST_H
|
||||
|
||||
#include <cairo.h>
|
||||
|
||||
#if CAIRO_HAS_PDF_SURFACE
|
||||
|
||||
#include <cairo-pdf.h>
|
||||
|
||||
CAIRO_BEGIN_DECLS
|
||||
|
||||
struct _cairo_path_fixed;
|
||||
struct _cairo_traps;
|
||||
struct _cairo_trapezoid;
|
||||
struct _cairo_clip;
|
||||
|
||||
void
|
||||
cairo_pdf_test_force_fallbacks (void);
|
||||
|
||||
void
|
||||
cairo_debug_dump_clip (struct _cairo_clip *clip,
|
||||
FILE *fp);
|
||||
void
|
||||
cairo_debug_dump_path (struct _cairo_path_fixed *path,
|
||||
FILE *fp);
|
||||
|
||||
void
|
||||
cairo_debug_dump_traps (struct _cairo_traps *traps,
|
||||
FILE *fp);
|
||||
|
||||
void
|
||||
cairo_debug_dump_trapezoid_array (struct _cairo_trapezoid *traps,
|
||||
int num_traps,
|
||||
FILE *fp);
|
||||
|
||||
CAIRO_END_DECLS
|
||||
|
||||
#endif /* CAIRO_HAS_PDF_SURFACE */
|
||||
#endif /* CAIRO_PDF_TEST_H */
|
||||
|
||||
@ -59,6 +59,11 @@ cairo_pdf_surface_set_dpi (cairo_surface_t *surface,
|
||||
double x_dpi,
|
||||
double y_dpi);
|
||||
|
||||
void
|
||||
cairo_pdf_surface_set_size (cairo_surface_t *surface,
|
||||
double width_in_points,
|
||||
double height_in_points);
|
||||
|
||||
CAIRO_END_DECLS
|
||||
|
||||
#else /* CAIRO_HAS_PDF_SURFACE */
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@ -58,6 +58,21 @@ cairo_ps_surface_create_for_stream (cairo_write_func_t write_func,
|
||||
double width_in_points,
|
||||
double height_in_points);
|
||||
|
||||
cairo_public void
|
||||
cairo_ps_surface_set_size (cairo_surface_t *surface,
|
||||
double width_in_points,
|
||||
double height_in_points);
|
||||
|
||||
cairo_public void
|
||||
cairo_ps_surface_dsc_comment (cairo_surface_t *surface,
|
||||
const char *comment);
|
||||
|
||||
cairo_public void
|
||||
cairo_ps_surface_dsc_begin_setup (cairo_surface_t *surface);
|
||||
|
||||
cairo_public void
|
||||
cairo_ps_surface_dsc_begin_page_setup (cairo_surface_t *surface);
|
||||
|
||||
cairo_public void
|
||||
cairo_ps_surface_set_dpi (cairo_surface_t *surface,
|
||||
double x_dpi,
|
||||
|
||||
@ -44,15 +44,11 @@ typedef struct cairo_quartz_surface {
|
||||
|
||||
CGContextRef context;
|
||||
|
||||
cairo_bool_t flipped;
|
||||
cairo_bool_t y_grows_down;
|
||||
|
||||
int width;
|
||||
int height;
|
||||
cairo_rectangle_fixed_t extents;
|
||||
|
||||
cairo_image_surface_t *image;
|
||||
pixman_region16_t *clip_region;
|
||||
|
||||
CGImageRef cgImage;
|
||||
pixman_region16_t *clip_region;
|
||||
} cairo_quartz_surface_t;
|
||||
|
||||
cairo_bool_t
|
||||
|
||||
@ -37,27 +37,13 @@
|
||||
#include "cairo-private.h"
|
||||
#include "cairo-quartz-private.h"
|
||||
|
||||
static void
|
||||
ImageDataReleaseFunc(void *info, const void *data, size_t size)
|
||||
{
|
||||
if (data != NULL) {
|
||||
free((void *) data);
|
||||
}
|
||||
}
|
||||
|
||||
static cairo_status_t
|
||||
_cairo_quartz_surface_finish(void *abstract_surface)
|
||||
{
|
||||
cairo_quartz_surface_t *surface = abstract_surface;
|
||||
|
||||
if (surface->image)
|
||||
cairo_surface_destroy(&surface->image->base);
|
||||
|
||||
if (surface->cgImage)
|
||||
CGImageRelease(surface->cgImage);
|
||||
|
||||
if (surface->clip_region)
|
||||
pixman_region_destroy (surface->clip_region);
|
||||
if (surface->clip_region)
|
||||
pixman_region_destroy (surface->clip_region);
|
||||
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
}
|
||||
@ -67,117 +53,127 @@ _cairo_quartz_surface_acquire_source_image(void *abstract_surface,
|
||||
cairo_image_surface_t **image_out,
|
||||
void **image_extra)
|
||||
{
|
||||
cairo_quartz_surface_t *surface = abstract_surface;
|
||||
CGColorSpaceRef colorSpace;
|
||||
void *imageData;
|
||||
UInt32 imageDataSize, rowBytes;
|
||||
CGDataProviderRef dataProvider;
|
||||
cairo_quartz_surface_t *surface = abstract_surface;
|
||||
|
||||
/* We keep a cached (cairo_image_surface_t *) in the cairo_quartz_surface_t
|
||||
* struct. If the window is ever drawn to without going through Cairo, then
|
||||
* we would need to refetch the pixel data from the window into the cached
|
||||
* image surface.
|
||||
*/
|
||||
if (surface->image) {
|
||||
cairo_surface_reference(&surface->image->base);
|
||||
if (CGBitmapContextGetBitmapInfo (surface->context) != 0) {
|
||||
/* XXX: We can create an image out of the bitmap here */
|
||||
}
|
||||
|
||||
*image_out = surface->image;
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
colorSpace = CGColorSpaceCreateDeviceRGB();
|
||||
|
||||
|
||||
rowBytes = surface->width * 4;
|
||||
imageDataSize = rowBytes * surface->height;
|
||||
imageData = malloc(imageDataSize);
|
||||
|
||||
dataProvider =
|
||||
CGDataProviderCreateWithData(NULL, imageData, imageDataSize,
|
||||
ImageDataReleaseFunc);
|
||||
|
||||
surface->cgImage = CGImageCreate(surface->width,
|
||||
surface->height,
|
||||
8,
|
||||
32,
|
||||
rowBytes,
|
||||
colorSpace,
|
||||
kCGImageAlphaPremultipliedFirst,
|
||||
dataProvider,
|
||||
NULL,
|
||||
false, kCGRenderingIntentDefault);
|
||||
|
||||
CGColorSpaceRelease(colorSpace);
|
||||
CGDataProviderRelease(dataProvider);
|
||||
|
||||
surface->image = (cairo_image_surface_t *)
|
||||
cairo_image_surface_create_for_data(imageData,
|
||||
CAIRO_FORMAT_ARGB32,
|
||||
surface->width,
|
||||
surface->height, rowBytes);
|
||||
if (surface->image->base.status) {
|
||||
if (surface->cgImage)
|
||||
CGImageRelease(surface->cgImage);
|
||||
return CAIRO_STATUS_NO_MEMORY;
|
||||
}
|
||||
|
||||
*image_out = surface->image;
|
||||
*image_extra = NULL;
|
||||
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
return CAIRO_INT_STATUS_UNSUPPORTED;
|
||||
}
|
||||
|
||||
static cairo_status_t
|
||||
_cairo_quartz_surface_acquire_dest_image(void *abstract_surface,
|
||||
cairo_rectangle_t * interest_rect,
|
||||
cairo_image_surface_t **
|
||||
image_out,
|
||||
cairo_rectangle_t * image_rect,
|
||||
void **image_extra)
|
||||
_cairo_quartz_surface_acquire_dest_image(void *abstract_surface,
|
||||
cairo_rectangle_fixed_t *interest_rect,
|
||||
cairo_image_surface_t **image_out,
|
||||
cairo_rectangle_fixed_t *image_rect,
|
||||
void **image_extra)
|
||||
{
|
||||
cairo_quartz_surface_t *surface = abstract_surface;
|
||||
cairo_surface_t *image_surface;
|
||||
unsigned char *data;
|
||||
int x1, y1, x2, y2;
|
||||
|
||||
image_rect->x = 0;
|
||||
image_rect->y = 0;
|
||||
image_rect->width = surface->image->width;
|
||||
image_rect->height = surface->image->height;
|
||||
x1 = surface->extents.x;
|
||||
x2 = surface->extents.x + surface->extents.width;
|
||||
y1 = surface->extents.y;
|
||||
y2 = surface->extents.y + surface->extents.height;
|
||||
|
||||
*image_out = surface->image;
|
||||
if (image_extra)
|
||||
if (interest_rect->x > x1)
|
||||
x1 = interest_rect->x;
|
||||
if (interest_rect->y > y1)
|
||||
y1 = interest_rect->y;
|
||||
if (interest_rect->x + interest_rect->width < x2)
|
||||
x2 = interest_rect->x + interest_rect->width;
|
||||
if (interest_rect->y + interest_rect->height < y2)
|
||||
y2 = interest_rect->y + interest_rect->height;
|
||||
|
||||
if (x1 >= x2 || y1 >= y2) {
|
||||
*image_out = NULL;
|
||||
*image_extra = NULL;
|
||||
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
image_rect->x = x1;
|
||||
image_rect->y = y1;
|
||||
image_rect->width = x2 - x1;
|
||||
image_rect->height = y2 - y1;
|
||||
|
||||
data = calloc (image_rect->width * image_rect->height * 4, 1);
|
||||
image_surface = cairo_image_surface_create_for_data (data,
|
||||
CAIRO_FORMAT_ARGB32,
|
||||
image_rect->width,
|
||||
image_rect->height,
|
||||
image_rect->width * 4);
|
||||
|
||||
*image_out = (cairo_image_surface_t *)image_surface;
|
||||
*image_extra = data;
|
||||
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
|
||||
return CAIRO_INT_STATUS_UNSUPPORTED;
|
||||
}
|
||||
|
||||
static CGImageRef
|
||||
create_image_from_surface (cairo_image_surface_t *image_surface, void *data)
|
||||
{
|
||||
CGImageRef image;
|
||||
CGColorSpaceRef color_space;
|
||||
CGDataProviderRef data_provider;
|
||||
int width, height;
|
||||
|
||||
width = cairo_image_surface_get_width ((cairo_surface_t *)image_surface);
|
||||
height = cairo_image_surface_get_height ((cairo_surface_t *)image_surface);
|
||||
|
||||
color_space = CGColorSpaceCreateDeviceRGB();
|
||||
data_provider = CGDataProviderCreateWithData (NULL, data,
|
||||
width * height * 4, NULL);
|
||||
image = CGImageCreate (width, height,
|
||||
8, 32,
|
||||
width * 4,
|
||||
color_space,
|
||||
kCGImageAlphaPremultipliedFirst,
|
||||
data_provider,
|
||||
NULL,
|
||||
FALSE, kCGRenderingIntentDefault);
|
||||
|
||||
CGColorSpaceRelease (color_space);
|
||||
CGDataProviderRelease (data_provider);
|
||||
|
||||
return image;
|
||||
}
|
||||
|
||||
static void
|
||||
_cairo_quartz_surface_release_dest_image(void *abstract_surface,
|
||||
cairo_rectangle_t *
|
||||
intersect_rect,
|
||||
cairo_image_surface_t * image,
|
||||
cairo_rectangle_t * image_rect,
|
||||
void *image_extra)
|
||||
_cairo_quartz_surface_release_dest_image(void *abstract_surface,
|
||||
cairo_rectangle_fixed_t *intersect_rect,
|
||||
cairo_image_surface_t *image,
|
||||
cairo_rectangle_fixed_t *image_rect,
|
||||
void *image_extra)
|
||||
{
|
||||
cairo_quartz_surface_t *surface = abstract_surface;
|
||||
CGImageRef image_ref;
|
||||
CGRect rect;
|
||||
|
||||
image_ref = create_image_from_surface (image, image_extra);
|
||||
|
||||
if (surface->image == image) {
|
||||
CGRect rect;
|
||||
rect = CGRectMake (image_rect->x, image_rect->y, image_rect->width, image_rect->height);
|
||||
|
||||
rect = CGRectMake(0, 0, surface->width, surface->height);
|
||||
|
||||
if (surface->flipped) {
|
||||
CGContextSaveGState (surface->context);
|
||||
CGContextTranslateCTM (surface->context, 0, surface->height);
|
||||
CGContextScaleCTM (surface->context, 1, -1);
|
||||
}
|
||||
|
||||
CGContextDrawImage(surface->context, rect, surface->cgImage);
|
||||
|
||||
if (surface->flipped)
|
||||
CGContextRestoreGState (surface->context);
|
||||
|
||||
memset(surface->image->data, 0, surface->width * surface->height * 4);
|
||||
if (surface->y_grows_down) {
|
||||
CGContextSaveGState (surface->context);
|
||||
CGContextTranslateCTM (surface->context, 0, image_rect->height + 2 * image_rect->y);
|
||||
CGContextScaleCTM (surface->context, 1, -1);
|
||||
}
|
||||
|
||||
CGContextDrawImage(surface->context, rect, image_ref);
|
||||
CFRelease (image_ref);
|
||||
|
||||
if (surface->y_grows_down) {
|
||||
CGContextRestoreGState (surface->context);
|
||||
}
|
||||
|
||||
cairo_surface_destroy ((cairo_surface_t *)image);
|
||||
free (image_extra);
|
||||
}
|
||||
|
||||
static cairo_int_status_t
|
||||
@ -185,33 +181,26 @@ _cairo_quartz_surface_set_clip_region(void *abstract_surface,
|
||||
pixman_region16_t * region)
|
||||
{
|
||||
cairo_quartz_surface_t *surface = abstract_surface;
|
||||
unsigned int serial;
|
||||
|
||||
serial = _cairo_surface_allocate_clip_serial (&surface->image->base);
|
||||
if (surface->clip_region)
|
||||
pixman_region_destroy (surface->clip_region);
|
||||
|
||||
if (region) {
|
||||
surface->clip_region = pixman_region_create ();
|
||||
pixman_region_copy (surface->clip_region, region);
|
||||
} else
|
||||
surface->clip_region = NULL;
|
||||
|
||||
if (surface->clip_region)
|
||||
pixman_region_destroy (surface->clip_region);
|
||||
|
||||
if (region) {
|
||||
surface->clip_region = pixman_region_create ();
|
||||
pixman_region_copy (surface->clip_region, region);
|
||||
} else
|
||||
surface->clip_region = NULL;
|
||||
|
||||
return _cairo_surface_set_clip_region(&surface->image->base,
|
||||
region, serial);
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
static cairo_int_status_t
|
||||
_cairo_quartz_surface_get_extents (void *abstract_surface,
|
||||
cairo_rectangle_t * rectangle)
|
||||
_cairo_quartz_surface_get_extents (void *abstract_surface,
|
||||
cairo_rectangle_fixed_t *rectangle)
|
||||
{
|
||||
cairo_quartz_surface_t *surface = abstract_surface;
|
||||
|
||||
rectangle->x = 0;
|
||||
rectangle->y = 0;
|
||||
rectangle->width = surface->width;
|
||||
rectangle->height = surface->height;
|
||||
*rectangle = surface->extents;
|
||||
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
}
|
||||
@ -238,10 +227,12 @@ static const struct _cairo_surface_backend cairo_quartz_surface_backend = {
|
||||
|
||||
|
||||
cairo_surface_t *cairo_quartz_surface_create(CGContextRef context,
|
||||
cairo_bool_t flipped,
|
||||
int width, int height)
|
||||
int width,
|
||||
int height,
|
||||
cairo_bool_t y_grows_down)
|
||||
{
|
||||
cairo_quartz_surface_t *surface;
|
||||
CGRect clip_box;
|
||||
|
||||
surface = malloc(sizeof(cairo_quartz_surface_t));
|
||||
if (surface == NULL) {
|
||||
@ -249,19 +240,19 @@ cairo_surface_t *cairo_quartz_surface_create(CGContextRef context,
|
||||
return (cairo_surface_t*) &_cairo_surface_nil;
|
||||
}
|
||||
|
||||
_cairo_surface_init(&surface->base, &cairo_quartz_surface_backend);
|
||||
/* XXX: The content value here might be totally wrong. */
|
||||
_cairo_surface_init(&surface->base, &cairo_quartz_surface_backend,
|
||||
CAIRO_CONTENT_COLOR_ALPHA);
|
||||
|
||||
surface->context = context;
|
||||
surface->width = width;
|
||||
surface->height = height;
|
||||
surface->image = NULL;
|
||||
surface->cgImage = NULL;
|
||||
surface->clip_region = NULL;
|
||||
surface->flipped = flipped;
|
||||
surface->clip_region = NULL;
|
||||
surface->y_grows_down = y_grows_down;
|
||||
|
||||
/* Set up the image surface which Cairo draws into and we blit to & from. */
|
||||
void *foo;
|
||||
_cairo_quartz_surface_acquire_source_image(surface, &surface->image, &foo);
|
||||
clip_box = CGContextGetClipBoundingBox (context);
|
||||
surface->extents.x = clip_box.origin.x;
|
||||
surface->extents.y = clip_box.origin.y;
|
||||
surface->extents.width = clip_box.size.width;
|
||||
surface->extents.height = clip_box.size.height;
|
||||
|
||||
return (cairo_surface_t *) surface;
|
||||
}
|
||||
|
||||
@ -47,9 +47,9 @@ CAIRO_BEGIN_DECLS
|
||||
|
||||
cairo_public cairo_surface_t *
|
||||
cairo_quartz_surface_create (CGContextRef context,
|
||||
cairo_bool_t flipped,
|
||||
int width,
|
||||
int height);
|
||||
int height,
|
||||
cairo_bool_t y_grows_down);
|
||||
|
||||
CAIRO_END_DECLS
|
||||
|
||||
|
||||
@ -37,7 +37,7 @@
|
||||
|
||||
/**
|
||||
* _cairo_region_create_from_rectangle:
|
||||
* @rect: a #cairo_rectangle_t
|
||||
* @rect: a #cairo_rectangle_fixed_t
|
||||
*
|
||||
* Creates a region with extents initialized from the given
|
||||
* rectangle.
|
||||
@ -46,7 +46,7 @@
|
||||
* memory couldn't a allocated.
|
||||
**/
|
||||
pixman_region16_t *
|
||||
_cairo_region_create_from_rectangle (cairo_rectangle_t *rect)
|
||||
_cairo_region_create_from_rectangle (cairo_rectangle_fixed_t *rect)
|
||||
{
|
||||
/* We can't use pixman_region_create_simple(), because it doesn't
|
||||
* have an error return
|
||||
@ -67,11 +67,11 @@ _cairo_region_create_from_rectangle (cairo_rectangle_t *rect)
|
||||
* @region: a #pixman_region16_t
|
||||
* @rect: rectangle into which to store the extents
|
||||
*
|
||||
* Gets the bounding box of a region as a cairo_rectangle_t
|
||||
* Gets the bounding box of a region as a cairo_rectangle_fixed_t
|
||||
**/
|
||||
void
|
||||
_cairo_region_extents_rectangle (pixman_region16_t *region,
|
||||
cairo_rectangle_t *rect)
|
||||
_cairo_region_extents_rectangle (pixman_region16_t *region,
|
||||
cairo_rectangle_fixed_t *rect)
|
||||
{
|
||||
pixman_box16_t *region_extents = pixman_region_extents (region);
|
||||
|
||||
|
||||
@ -1,228 +1,246 @@
|
||||
#define cairo_append_path _moz_cairo_append_path
|
||||
#define cairo_arc _moz_cairo_arc
|
||||
#define cairo_arc_negative _moz_cairo_arc_negative
|
||||
#define cairo_arc_to _moz_cairo_arc_to
|
||||
#define cairo_atsui_font_face_create_for_atsu_font_id _moz_cairo_atsui_font_face_create_for_atsu_font_id
|
||||
#define cairo_beos_surface_create _moz_cairo_beos_surface_create
|
||||
#define cairo_beos_surface_create_for_bitmap _moz_cairo_beos_surface_create_for_bitmap
|
||||
#define cairo_debug_reset_static_data _moz_cairo_debug_reset_static_data
|
||||
#define cairo_clip _moz_cairo_clip
|
||||
#define cairo_clip_preserve _moz_cairo_clip_preserve
|
||||
#define cairo_close_path _moz_cairo_close_path
|
||||
#define cairo_copy_page _moz_cairo_copy_page
|
||||
#define cairo_copy_path _moz_cairo_copy_path
|
||||
#define cairo_copy_path_flat _moz_cairo_copy_path_flat
|
||||
#define cairo_create _moz_cairo_create
|
||||
#define cairo_curve_to _moz_cairo_curve_to
|
||||
#define cairo_debug_dump_clip _moz_cairo_debug_dump_clip
|
||||
#define cairo_debug_dump_path _moz_cairo_debug_dump_path
|
||||
#define cairo_debug_dump_traps _moz_cairo_debug_dump_traps
|
||||
#define cairo_debug_dump_trapezoid_array _moz_cairo_debug_dump_trapezoid_array
|
||||
#define cairo_debug_dump_traps _moz_cairo_debug_dump_traps
|
||||
#define cairo_debug_reset_static_data _moz_cairo_debug_reset_static_data
|
||||
#define cairo_debug_reset_static_data _moz_cairo_debug_reset_static_data
|
||||
#define cairo_destroy _moz_cairo_destroy
|
||||
#define cairo_device_to_user _moz_cairo_device_to_user
|
||||
#define cairo_device_to_user_distance _moz_cairo_device_to_user_distance
|
||||
#define cairo_extract_clip_rectangles _moz_cairo_extract_clip_rectangles
|
||||
#define cairo_fill _moz_cairo_fill
|
||||
#define cairo_fill_extents _moz_cairo_fill_extents
|
||||
#define cairo_fill_preserve _moz_cairo_fill_preserve
|
||||
#define cairo_font_extents _moz_cairo_font_extents
|
||||
#define cairo_font_face_destroy _moz_cairo_font_face_destroy
|
||||
#define cairo_font_face_get_type _moz_cairo_font_face_get_type
|
||||
#define cairo_font_face_get_user_data _moz_cairo_font_face_get_user_data
|
||||
#define cairo_font_face_reference _moz_cairo_font_face_reference
|
||||
#define cairo_font_face_set_user_data _moz_cairo_font_face_set_user_data
|
||||
#define cairo_font_face_status _moz_cairo_font_face_status
|
||||
#define cairo_font_options_copy _moz_cairo_font_options_copy
|
||||
#define cairo_font_options_create _moz_cairo_font_options_create
|
||||
#define cairo_font_options_destroy _moz_cairo_font_options_destroy
|
||||
#define cairo_font_options_equal _moz_cairo_font_options_equal
|
||||
#define cairo_font_options_get_antialias _moz_cairo_font_options_get_antialias
|
||||
#define cairo_font_options_get_hint_metrics _moz_cairo_font_options_get_hint_metrics
|
||||
#define cairo_font_options_get_hint_style _moz_cairo_font_options_get_hint_style
|
||||
#define cairo_font_options_get_subpixel_order _moz_cairo_font_options_get_subpixel_order
|
||||
#define cairo_font_options_hash _moz_cairo_font_options_hash
|
||||
#define cairo_font_options_merge _moz_cairo_font_options_merge
|
||||
#define cairo_font_options_set_antialias _moz_cairo_font_options_set_antialias
|
||||
#define cairo_font_options_set_hint_metrics _moz_cairo_font_options_set_hint_metrics
|
||||
#define cairo_font_options_set_hint_style _moz_cairo_font_options_set_hint_style
|
||||
#define cairo_font_options_set_subpixel_order _moz_cairo_font_options_set_subpixel_order
|
||||
#define cairo_font_options_status _moz_cairo_font_options_status
|
||||
#define cairo_ft_font_face_create_for_ft_face _moz_cairo_ft_font_face_create_for_ft_face
|
||||
#define cairo_ft_font_face_create_for_pattern _moz_cairo_ft_font_face_create_for_pattern
|
||||
#define cairo_ft_font_options_substitute _moz_cairo_ft_font_options_substitute
|
||||
#define cairo_ft_font_face_create_for_ft_face _moz_cairo_ft_font_face_create_for_ft_face
|
||||
#define cairo_ft_scaled_font_lock_face _moz_cairo_ft_scaled_font_lock_face
|
||||
#define cairo_ft_scaled_font_unlock_face _moz_cairo_ft_scaled_font_unlock_face
|
||||
#define cairo_get_antialias _moz_cairo_get_antialias
|
||||
#define cairo_get_current_point _moz_cairo_get_current_point
|
||||
#define cairo_get_fill_rule _moz_cairo_get_fill_rule
|
||||
#define cairo_get_font_face _moz_cairo_get_font_face
|
||||
#define cairo_get_font_matrix _moz_cairo_get_font_matrix
|
||||
#define cairo_get_font_options _moz_cairo_get_font_options
|
||||
#define cairo_get_group_target _moz_cairo_get_group_target
|
||||
#define cairo_get_line_cap _moz_cairo_get_line_cap
|
||||
#define cairo_get_line_join _moz_cairo_get_line_join
|
||||
#define cairo_get_line_width _moz_cairo_get_line_width
|
||||
#define cairo_get_matrix _moz_cairo_get_matrix
|
||||
#define cairo_get_miter_limit _moz_cairo_get_miter_limit
|
||||
#define cairo_get_operator _moz_cairo_get_operator
|
||||
#define cairo_get_source _moz_cairo_get_source
|
||||
#define cairo_get_target _moz_cairo_get_target
|
||||
#define cairo_get_tolerance _moz_cairo_get_tolerance
|
||||
#define cairo_glitz_surface_create _moz_cairo_glitz_surface_create
|
||||
#define cairo_glyph_extents _moz_cairo_glyph_extents
|
||||
#define cairo_glyph_path _moz_cairo_glyph_path
|
||||
#define cairo_has_clip _moz_cairo_has_clip
|
||||
#define cairo_identity_matrix _moz_cairo_identity_matrix
|
||||
#define cairo_image_surface_create _moz_cairo_image_surface_create
|
||||
#define cairo_image_surface_create_for_data _moz_cairo_image_surface_create_for_data
|
||||
#define cairo_image_surface_create_from_png _moz_cairo_image_surface_create_from_png
|
||||
#define cairo_image_surface_create_from_png_stream _moz_cairo_image_surface_create_from_png_stream
|
||||
#define cairo_image_surface_get_height _moz_cairo_image_surface_get_height
|
||||
#define cairo_image_surface_get_width _moz_cairo_image_surface_get_width
|
||||
#define cairo_in_fill _moz_cairo_in_fill
|
||||
#define cairo_in_stroke _moz_cairo_in_stroke
|
||||
#define cairo_line_to _moz_cairo_line_to
|
||||
#define cairo_mask _moz_cairo_mask
|
||||
#define cairo_mask_surface _moz_cairo_mask_surface
|
||||
#define cairo_matrix_init _moz_cairo_matrix_init
|
||||
#define cairo_matrix_init_identity _moz_cairo_matrix_init_identity
|
||||
#define cairo_matrix_init_rotate _moz_cairo_matrix_init_rotate
|
||||
#define cairo_matrix_init_scale _moz_cairo_matrix_init_scale
|
||||
#define cairo_matrix_init_translate _moz_cairo_matrix_init_translate
|
||||
#define cairo_matrix_invert _moz_cairo_matrix_invert
|
||||
#define cairo_matrix_multiply _moz_cairo_matrix_multiply
|
||||
#define cairo_matrix_rotate _moz_cairo_matrix_rotate
|
||||
#define cairo_matrix_scale _moz_cairo_matrix_scale
|
||||
#define cairo_matrix_transform_distance _moz_cairo_matrix_transform_distance
|
||||
#define cairo_matrix_transform_point _moz_cairo_matrix_transform_point
|
||||
#define cairo_matrix_translate _moz_cairo_matrix_translate
|
||||
#define cairo_move_to _moz_cairo_move_to
|
||||
#define cairo_new_path _moz_cairo_new_path
|
||||
#define cairo_new_sub_path _moz_cairo_new_sub_path
|
||||
#define cairo_paint _moz_cairo_paint
|
||||
#define cairo_paint_with_alpha _moz_cairo_paint_with_alpha
|
||||
#define cairo_path_destroy _moz_cairo_path_destroy
|
||||
#define cairo_pattern_add_color_stop_rgb _moz_cairo_pattern_add_color_stop_rgb
|
||||
#define cairo_pattern_add_color_stop_rgba _moz_cairo_pattern_add_color_stop_rgba
|
||||
#define cairo_pattern_create_for_surface _moz_cairo_pattern_create_for_surface
|
||||
#define cairo_pattern_create_linear _moz_cairo_pattern_create_linear
|
||||
#define cairo_pattern_create_radial _moz_cairo_pattern_create_radial
|
||||
#define cairo_pattern_create_rgb _moz_cairo_pattern_create_rgb
|
||||
#define cairo_pattern_create_rgba _moz_cairo_pattern_create_rgba
|
||||
#define cairo_pattern_destroy _moz_cairo_pattern_destroy
|
||||
#define cairo_pattern_get_extend _moz_cairo_pattern_get_extend
|
||||
#define cairo_pattern_get_filter _moz_cairo_pattern_get_filter
|
||||
#define cairo_pattern_get_matrix _moz_cairo_pattern_get_matrix
|
||||
#define cairo_pattern_get_type _moz_cairo_pattern_get_type
|
||||
#define cairo_pattern_reference _moz_cairo_pattern_reference
|
||||
#define cairo_pattern_set_extend _moz_cairo_pattern_set_extend
|
||||
#define cairo_pattern_set_filter _moz_cairo_pattern_set_filter
|
||||
#define cairo_pattern_set_matrix _moz_cairo_pattern_set_matrix
|
||||
#define cairo_pattern_status _moz_cairo_pattern_status
|
||||
#define cairo_pdf_surface_create _moz_cairo_pdf_surface_create
|
||||
#define cairo_pdf_surface_create_for_stream _moz_cairo_pdf_surface_create_for_stream
|
||||
#define cairo_pdf_surface_set_dpi _moz_cairo_pdf_surface_set_dpi
|
||||
#define cairo_ps_surface_create _moz_cairo_ps_surface_create
|
||||
#define cairo_ps_surface_create_for_stream _moz_cairo_ps_surface_create_for_stream
|
||||
#define cairo_ps_surface_set_dpi _moz_cairo_ps_surface_set_dpi
|
||||
#define cairo_quartz_surface_create _moz_cairo_quartz_surface_create
|
||||
#define cairo_win32_surface_create _moz_cairo_win32_surface_create
|
||||
#define cairo_win32_surface_create_with_dib _moz_cairo_win32_surface_create_with_dib
|
||||
#define cairo_win32_surface_get_dc _moz_cairo_win32_surface_get_dc
|
||||
#define cairo_win32_font_face_create_for_logfontw _moz_cairo_win32_font_face_create_for_logfontw
|
||||
#define cairo_win32_font_face_create_for_hfont _moz_cairo_win32_font_face_create_for_hfont
|
||||
#define cairo_win32_scaled_font_select_font _moz_cairo_win32_scaled_font_select_font
|
||||
#define cairo_win32_scaled_font_done_font _moz_cairo_win32_scaled_font_done_font
|
||||
#define cairo_win32_scaled_font_get_metrics_factor _moz_cairo_win32_scaled_font_get_metrics_factor
|
||||
#define cairo_xcb_surface_create_with_xrender_format _moz_cairo_xcb_surface_create_with_xrender_format
|
||||
#define cairo_xcb_surface_create _moz_cairo_xcb_surface_create
|
||||
#define cairo_xcb_surface_create_for_bitmap _moz_cairo_xcb_surface_create_for_bitmap
|
||||
#define cairo_xcb_surface_set_size _moz_cairo_xcb_surface_set_size
|
||||
#define cairo_test_xlib_disable_render _moz_cairo_test_xlib_disable_render
|
||||
#define cairo_xlib_surface_create_with_xrender_format _moz_cairo_xlib_surface_create_with_xrender_format
|
||||
#define cairo_xlib_surface_create _moz_cairo_xlib_surface_create
|
||||
#define cairo_xlib_surface_create_for_bitmap _moz_cairo_xlib_surface_create_for_bitmap
|
||||
#define cairo_xlib_surface_set_size _moz_cairo_xlib_surface_set_size
|
||||
#define cairo_xlib_surface_set_drawable _moz_cairo_xlib_surface_set_drawable
|
||||
#define cairo_xlib_surface_get_drawable _moz_cairo_xlib_surface_get_drawable
|
||||
#define cairo_xlib_surface_get_display _moz_cairo_xlib_surface_get_display
|
||||
#define cairo_xlib_surface_get_screen _moz_cairo_xlib_surface_get_screen
|
||||
#define cairo_xlib_surface_get_visual _moz_cairo_xlib_surface_get_visual
|
||||
#define cairo_xlib_surface_get_depth _moz_cairo_xlib_surface_get_depth
|
||||
#define cairo_version _moz_cairo_version
|
||||
#define cairo_version_string _moz_cairo_version_string
|
||||
#define cairo_create _moz_cairo_create
|
||||
#define cairo_reference _moz_cairo_reference
|
||||
#define cairo_destroy _moz_cairo_destroy
|
||||
#define cairo_save _moz_cairo_save
|
||||
#define cairo_restore _moz_cairo_restore
|
||||
#define cairo_push_group _moz_cairo_push_group
|
||||
#define cairo_push_group_with_content _moz_cairo_push_group_with_content
|
||||
#define cairo_pop_group _moz_cairo_pop_group
|
||||
#define cairo_pop_group_to_source _moz_cairo_pop_group_to_source
|
||||
#define cairo_profile_surface_create _moz_cairo_profile_surface_create
|
||||
#define cairo_profile_surface_get_profile_data _moz_cairo_profile_surface_get_profile_data
|
||||
#define cairo_ps_surface_create _moz_cairo_ps_surface_create
|
||||
#define cairo_ps_surface_create_for_stream _moz_cairo_ps_surface_create_for_stream
|
||||
#define cairo_ps_surface_dsc_begin_page_setup _moz_cairo_ps_surface_dsc_begin_page_setup
|
||||
#define cairo_ps_surface_dsc_begin_setup _moz_cairo_ps_surface_dsc_begin_setup
|
||||
#define cairo_ps_surface_dsc_comment _moz_cairo_ps_surface_dsc_comment
|
||||
#define cairo_ps_surface_set_dpi _moz_cairo_ps_surface_set_dpi
|
||||
#define cairo_ps_surface_set_size _moz_cairo_ps_surface_set_size
|
||||
#define cairo_push_group _moz_cairo_push_group
|
||||
#define cairo_push_group_with_content _moz_cairo_push_group_with_content
|
||||
#define cairo_quartz_surface_create _moz_cairo_quartz_surface_create
|
||||
#define cairo_rectangle _moz_cairo_rectangle
|
||||
#define cairo_reference _moz_cairo_reference
|
||||
#define cairo_rel_curve_to _moz_cairo_rel_curve_to
|
||||
#define cairo_rel_line_to _moz_cairo_rel_line_to
|
||||
#define cairo_rel_move_to _moz_cairo_rel_move_to
|
||||
#define cairo_reset_clip _moz_cairo_reset_clip
|
||||
#define cairo_restore _moz_cairo_restore
|
||||
#define cairo_rotate _moz_cairo_rotate
|
||||
#define cairo_save _moz_cairo_save
|
||||
#define cairo_scale _moz_cairo_scale
|
||||
#define cairo_scaled_font_create _moz_cairo_scaled_font_create
|
||||
#define cairo_scaled_font_destroy _moz_cairo_scaled_font_destroy
|
||||
#define cairo_scaled_font_extents _moz_cairo_scaled_font_extents
|
||||
#define cairo_scaled_font_get_ctm _moz_cairo_scaled_font_get_ctm
|
||||
#define cairo_scaled_font_get_font_face _moz_cairo_scaled_font_get_font_face
|
||||
#define cairo_scaled_font_get_font_matrix _moz_cairo_scaled_font_get_font_matrix
|
||||
#define cairo_scaled_font_get_font_options _moz_cairo_scaled_font_get_font_options
|
||||
#define cairo_scaled_font_get_type _moz_cairo_scaled_font_get_type
|
||||
#define cairo_scaled_font_glyph_extents _moz_cairo_scaled_font_glyph_extents
|
||||
#define cairo_scaled_font_reference _moz_cairo_scaled_font_reference
|
||||
#define cairo_scaled_font_status _moz_cairo_scaled_font_status
|
||||
#define cairo_scaled_font_text_extents _moz_cairo_scaled_font_text_extents
|
||||
#define cairo_select_font_face _moz_cairo_select_font_face
|
||||
#define cairo_set_antialias _moz_cairo_set_antialias
|
||||
#define cairo_set_dash _moz_cairo_set_dash
|
||||
#define cairo_set_fill_rule _moz_cairo_set_fill_rule
|
||||
#define cairo_set_font_face _moz_cairo_set_font_face
|
||||
#define cairo_set_font_matrix _moz_cairo_set_font_matrix
|
||||
#define cairo_set_font_options _moz_cairo_set_font_options
|
||||
#define cairo_set_font_size _moz_cairo_set_font_size
|
||||
#define cairo_set_line_cap _moz_cairo_set_line_cap
|
||||
#define cairo_set_line_join _moz_cairo_set_line_join
|
||||
#define cairo_set_line_width _moz_cairo_set_line_width
|
||||
#define cairo_set_matrix _moz_cairo_set_matrix
|
||||
#define cairo_set_miter_limit _moz_cairo_set_miter_limit
|
||||
#define cairo_set_operator _moz_cairo_set_operator
|
||||
#define cairo_set_scaled_font _moz_cairo_set_scaled_font
|
||||
#define cairo_set_source _moz_cairo_set_source
|
||||
#define cairo_set_source_rgb _moz_cairo_set_source_rgb
|
||||
#define cairo_set_source_rgba _moz_cairo_set_source_rgba
|
||||
#define cairo_set_source_surface _moz_cairo_set_source_surface
|
||||
#define cairo_set_tolerance _moz_cairo_set_tolerance
|
||||
#define cairo_set_antialias _moz_cairo_set_antialias
|
||||
#define cairo_set_fill_rule _moz_cairo_set_fill_rule
|
||||
#define cairo_set_line_width _moz_cairo_set_line_width
|
||||
#define cairo_set_line_cap _moz_cairo_set_line_cap
|
||||
#define cairo_set_line_join _moz_cairo_set_line_join
|
||||
#define cairo_set_dash _moz_cairo_set_dash
|
||||
#define cairo_set_miter_limit _moz_cairo_set_miter_limit
|
||||
#define cairo_translate _moz_cairo_translate
|
||||
#define cairo_scale _moz_cairo_scale
|
||||
#define cairo_rotate _moz_cairo_rotate
|
||||
#define cairo_transform _moz_cairo_transform
|
||||
#define cairo_set_matrix _moz_cairo_set_matrix
|
||||
#define cairo_identity_matrix _moz_cairo_identity_matrix
|
||||
#define cairo_user_to_device _moz_cairo_user_to_device
|
||||
#define cairo_user_to_device_distance _moz_cairo_user_to_device_distance
|
||||
#define cairo_device_to_user _moz_cairo_device_to_user
|
||||
#define cairo_device_to_user_distance _moz_cairo_device_to_user_distance
|
||||
#define cairo_new_path _moz_cairo_new_path
|
||||
#define cairo_move_to _moz_cairo_move_to
|
||||
#define cairo_line_to _moz_cairo_line_to
|
||||
#define cairo_curve_to _moz_cairo_curve_to
|
||||
#define cairo_arc _moz_cairo_arc
|
||||
#define cairo_arc_negative _moz_cairo_arc_negative
|
||||
#define cairo_arc_to _moz_cairo_arc_to
|
||||
#define cairo_rel_move_to _moz_cairo_rel_move_to
|
||||
#define cairo_rel_line_to _moz_cairo_rel_line_to
|
||||
#define cairo_rel_curve_to _moz_cairo_rel_curve_to
|
||||
#define cairo_rectangle _moz_cairo_rectangle
|
||||
#define cairo_stroke_to_path _moz_cairo_stroke_to_path
|
||||
#define cairo_close_path _moz_cairo_close_path
|
||||
#define cairo_paint _moz_cairo_paint
|
||||
#define cairo_paint_with_alpha _moz_cairo_paint_with_alpha
|
||||
#define cairo_mask _moz_cairo_mask
|
||||
#define cairo_mask_surface _moz_cairo_mask_surface
|
||||
#define cairo_stroke _moz_cairo_stroke
|
||||
#define cairo_stroke_preserve _moz_cairo_stroke_preserve
|
||||
#define cairo_fill _moz_cairo_fill
|
||||
#define cairo_fill_preserve _moz_cairo_fill_preserve
|
||||
#define cairo_copy_page _moz_cairo_copy_page
|
||||
#define cairo_show_page _moz_cairo_show_page
|
||||
#define cairo_in_stroke _moz_cairo_in_stroke
|
||||
#define cairo_in_fill _moz_cairo_in_fill
|
||||
#define cairo_stroke_extents _moz_cairo_stroke_extents
|
||||
#define cairo_fill_extents _moz_cairo_fill_extents
|
||||
#define cairo_reset_clip _moz_cairo_reset_clip
|
||||
#define cairo_clip _moz_cairo_clip
|
||||
#define cairo_clip_preserve _moz_cairo_clip_preserve
|
||||
#define cairo_font_options_create _moz_cairo_font_options_create
|
||||
#define cairo_font_options_copy _moz_cairo_font_options_copy
|
||||
#define cairo_font_options_destroy _moz_cairo_font_options_destroy
|
||||
#define cairo_font_options_status _moz_cairo_font_options_status
|
||||
#define cairo_font_options_merge _moz_cairo_font_options_merge
|
||||
#define cairo_font_options_equal _moz_cairo_font_options_equal
|
||||
#define cairo_font_options_hash _moz_cairo_font_options_hash
|
||||
#define cairo_font_options_set_antialias _moz_cairo_font_options_set_antialias
|
||||
#define cairo_font_options_get_antialias _moz_cairo_font_options_get_antialias
|
||||
#define cairo_font_options_set_subpixel_order _moz_cairo_font_options_set_subpixel_order
|
||||
#define cairo_font_options_get_subpixel_order _moz_cairo_font_options_get_subpixel_order
|
||||
#define cairo_font_options_set_hint_style _moz_cairo_font_options_set_hint_style
|
||||
#define cairo_font_options_get_hint_style _moz_cairo_font_options_get_hint_style
|
||||
#define cairo_font_options_set_hint_metrics _moz_cairo_font_options_set_hint_metrics
|
||||
#define cairo_font_options_get_hint_metrics _moz_cairo_font_options_get_hint_metrics
|
||||
#define cairo_select_font_face _moz_cairo_select_font_face
|
||||
#define cairo_set_font_size _moz_cairo_set_font_size
|
||||
#define cairo_set_font_matrix _moz_cairo_set_font_matrix
|
||||
#define cairo_get_font_matrix _moz_cairo_get_font_matrix
|
||||
#define cairo_set_font_options _moz_cairo_set_font_options
|
||||
#define cairo_get_font_options _moz_cairo_get_font_options
|
||||
#define cairo_show_text _moz_cairo_show_text
|
||||
#define cairo_show_glyphs _moz_cairo_show_glyphs
|
||||
#define cairo_get_font_face _moz_cairo_get_font_face
|
||||
#define cairo_font_extents _moz_cairo_font_extents
|
||||
#define cairo_set_font_face _moz_cairo_set_font_face
|
||||
#define cairo_text_extents _moz_cairo_text_extents
|
||||
#define cairo_glyph_extents _moz_cairo_glyph_extents
|
||||
#define cairo_text_path _moz_cairo_text_path
|
||||
#define cairo_glyph_path _moz_cairo_glyph_path
|
||||
#define cairo_font_face_reference _moz_cairo_font_face_reference
|
||||
#define cairo_font_face_destroy _moz_cairo_font_face_destroy
|
||||
#define cairo_font_face_status _moz_cairo_font_face_status
|
||||
#define cairo_font_face_get_type _moz_cairo_font_face_get_type
|
||||
#define cairo_font_face_get_user_data _moz_cairo_font_face_get_user_data
|
||||
#define cairo_font_face_set_user_data _moz_cairo_font_face_set_user_data
|
||||
#define cairo_scaled_font_create _moz_cairo_scaled_font_create
|
||||
#define cairo_scaled_font_reference _moz_cairo_scaled_font_reference
|
||||
#define cairo_scaled_font_destroy _moz_cairo_scaled_font_destroy
|
||||
#define cairo_scaled_font_status _moz_cairo_scaled_font_status
|
||||
#define cairo_scaled_font_get_type _moz_cairo_scaled_font_get_type
|
||||
#define cairo_scaled_font_extents _moz_cairo_scaled_font_extents
|
||||
#define cairo_scaled_font_text_extents _moz_cairo_scaled_font_text_extents
|
||||
#define cairo_scaled_font_glyph_extents _moz_cairo_scaled_font_glyph_extents
|
||||
#define cairo_scaled_font_get_font_face _moz_cairo_scaled_font_get_font_face
|
||||
#define cairo_scaled_font_get_font_matrix _moz_cairo_scaled_font_get_font_matrix
|
||||
#define cairo_scaled_font_get_ctm _moz_cairo_scaled_font_get_ctm
|
||||
#define cairo_scaled_font_get_font_options _moz_cairo_scaled_font_get_font_options
|
||||
#define cairo_get_operator _moz_cairo_get_operator
|
||||
#define cairo_get_source _moz_cairo_get_source
|
||||
#define cairo_get_tolerance _moz_cairo_get_tolerance
|
||||
#define cairo_get_antialias _moz_cairo_get_antialias
|
||||
#define cairo_get_current_point _moz_cairo_get_current_point
|
||||
#define cairo_get_fill_rule _moz_cairo_get_fill_rule
|
||||
#define cairo_get_line_width _moz_cairo_get_line_width
|
||||
#define cairo_get_line_cap _moz_cairo_get_line_cap
|
||||
#define cairo_get_line_join _moz_cairo_get_line_join
|
||||
#define cairo_get_miter_limit _moz_cairo_get_miter_limit
|
||||
#define cairo_get_matrix _moz_cairo_get_matrix
|
||||
#define cairo_get_target _moz_cairo_get_target
|
||||
#define cairo_get_group_target _moz_cairo_get_group_target
|
||||
#define cairo_copy_path _moz_cairo_copy_path
|
||||
#define cairo_copy_path_flat _moz_cairo_copy_path_flat
|
||||
#define cairo_append_path _moz_cairo_append_path
|
||||
#define cairo_path_destroy _moz_cairo_path_destroy
|
||||
#define cairo_has_clip _moz_cairo_has_clip
|
||||
#define cairo_extract_clip_rectangles _moz_cairo_extract_clip_rectangles
|
||||
#define cairo_show_page _moz_cairo_show_page
|
||||
#define cairo_show_text _moz_cairo_show_text
|
||||
#define cairo_status _moz_cairo_status
|
||||
#define cairo_status_to_string _moz_cairo_status_to_string
|
||||
#define cairo_stroke _moz_cairo_stroke
|
||||
#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_create_similar _moz_cairo_surface_create_similar
|
||||
#define cairo_surface_reference _moz_cairo_surface_reference
|
||||
#define cairo_surface_finish _moz_cairo_surface_finish
|
||||
#define cairo_surface_destroy _moz_cairo_surface_destroy
|
||||
#define cairo_surface_status _moz_cairo_surface_status
|
||||
#define cairo_surface_get_type _moz_cairo_surface_get_type
|
||||
#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
|
||||
#define cairo_surface_get_user_data _moz_cairo_surface_get_user_data
|
||||
#define cairo_surface_set_user_data _moz_cairo_surface_set_user_data
|
||||
#define cairo_surface_get_font_options _moz_cairo_surface_get_font_options
|
||||
#define cairo_surface_finish _moz_cairo_surface_finish
|
||||
#define cairo_surface_flush _moz_cairo_surface_flush
|
||||
#define cairo_surface_get_content _moz_cairo_surface_get_content
|
||||
#define cairo_surface_get_device_offset _moz_cairo_surface_get_device_offset
|
||||
#define cairo_surface_get_font_options _moz_cairo_surface_get_font_options
|
||||
#define cairo_surface_get_type _moz_cairo_surface_get_type
|
||||
#define cairo_surface_get_user_data _moz_cairo_surface_get_user_data
|
||||
#define cairo_surface_is_profile _moz_cairo_surface_is_profile
|
||||
#define cairo_surface_mark_dirty _moz_cairo_surface_mark_dirty
|
||||
#define cairo_surface_mark_dirty_rectangle _moz_cairo_surface_mark_dirty_rectangle
|
||||
#define cairo_surface_reference _moz_cairo_surface_reference
|
||||
#define cairo_surface_set_device_offset _moz_cairo_surface_set_device_offset
|
||||
#define cairo_surface_get_device_offset _moz_cairo_surface_get_device_offset
|
||||
#define cairo_image_surface_create _moz_cairo_image_surface_create
|
||||
#define cairo_image_surface_create_for_data _moz_cairo_image_surface_create_for_data
|
||||
#define cairo_image_surface_get_width _moz_cairo_image_surface_get_width
|
||||
#define cairo_image_surface_get_height _moz_cairo_image_surface_get_height
|
||||
#define cairo_image_surface_create_from_png _moz_cairo_image_surface_create_from_png
|
||||
#define cairo_image_surface_create_from_png_stream _moz_cairo_image_surface_create_from_png_stream
|
||||
#define cairo_pattern_create_rgb _moz_cairo_pattern_create_rgb
|
||||
#define cairo_pattern_create_rgba _moz_cairo_pattern_create_rgba
|
||||
#define cairo_pattern_create_for_surface _moz_cairo_pattern_create_for_surface
|
||||
#define cairo_pattern_create_linear _moz_cairo_pattern_create_linear
|
||||
#define cairo_pattern_create_radial _moz_cairo_pattern_create_radial
|
||||
#define cairo_pattern_reference _moz_cairo_pattern_reference
|
||||
#define cairo_pattern_destroy _moz_cairo_pattern_destroy
|
||||
#define cairo_pattern_status _moz_cairo_pattern_status
|
||||
#define cairo_pattern_get_type _moz_cairo_pattern_get_type
|
||||
#define cairo_pattern_add_color_stop_rgb _moz_cairo_pattern_add_color_stop_rgb
|
||||
#define cairo_pattern_add_color_stop_rgba _moz_cairo_pattern_add_color_stop_rgba
|
||||
#define cairo_pattern_set_matrix _moz_cairo_pattern_set_matrix
|
||||
#define cairo_pattern_get_matrix _moz_cairo_pattern_get_matrix
|
||||
#define cairo_pattern_set_extend _moz_cairo_pattern_set_extend
|
||||
#define cairo_pattern_get_extend _moz_cairo_pattern_get_extend
|
||||
#define cairo_pattern_set_filter _moz_cairo_pattern_set_filter
|
||||
#define cairo_pattern_get_filter _moz_cairo_pattern_get_filter
|
||||
#define cairo_matrix_init _moz_cairo_matrix_init
|
||||
#define cairo_matrix_init_identity _moz_cairo_matrix_init_identity
|
||||
#define cairo_matrix_init_translate _moz_cairo_matrix_init_translate
|
||||
#define cairo_matrix_init_scale _moz_cairo_matrix_init_scale
|
||||
#define cairo_matrix_init_rotate _moz_cairo_matrix_init_rotate
|
||||
#define cairo_matrix_translate _moz_cairo_matrix_translate
|
||||
#define cairo_matrix_scale _moz_cairo_matrix_scale
|
||||
#define cairo_matrix_rotate _moz_cairo_matrix_rotate
|
||||
#define cairo_matrix_invert _moz_cairo_matrix_invert
|
||||
#define cairo_matrix_multiply _moz_cairo_matrix_multiply
|
||||
#define cairo_matrix_transform_distance _moz_cairo_matrix_transform_distance
|
||||
#define cairo_matrix_transform_point _moz_cairo_matrix_transform_point
|
||||
#define cairo_surface_set_user_data _moz_cairo_surface_set_user_data
|
||||
#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
|
||||
#define cairo_svg_get_versions _moz_cairo_svg_get_versions
|
||||
#define cairo_svg_surface_create _moz_cairo_svg_surface_create
|
||||
#define cairo_svg_surface_create_for_stream _moz_cairo_svg_surface_create_for_stream
|
||||
#define cairo_svg_surface_restrict_to_version _moz_cairo_svg_surface_restrict_to_version
|
||||
#define cairo_svg_surface_set_dpi _moz_cairo_svg_surface_set_dpi
|
||||
#define cairo_svg_version_to_string _moz_cairo_svg_version_to_string
|
||||
#define cairo_text_extents _moz_cairo_text_extents
|
||||
#define cairo_text_path _moz_cairo_text_path
|
||||
#define cairo_transform _moz_cairo_transform
|
||||
#define cairo_translate _moz_cairo_translate
|
||||
#define cairo_user_to_device _moz_cairo_user_to_device
|
||||
#define cairo_user_to_device_distance _moz_cairo_user_to_device_distance
|
||||
#define cairo_version _moz_cairo_version
|
||||
#define cairo_version_string _moz_cairo_version_string
|
||||
#define cairo_win32_font_face_create_for_hfont _moz_cairo_win32_font_face_create_for_hfont
|
||||
#define cairo_win32_font_face_create_for_logfontw _moz_cairo_win32_font_face_create_for_logfontw
|
||||
#define cairo_win32_scaled_font_done_font _moz_cairo_win32_scaled_font_done_font
|
||||
#define cairo_win32_scaled_font_get_device_to_logical _moz_cairo_win32_scaled_font_get_device_to_logical
|
||||
#define cairo_win32_scaled_font_get_logical_to_device _moz_cairo_win32_scaled_font_get_logical_to_device
|
||||
#define cairo_win32_scaled_font_get_metrics_factor _moz_cairo_win32_scaled_font_get_metrics_factor
|
||||
#define cairo_win32_scaled_font_select_font _moz_cairo_win32_scaled_font_select_font
|
||||
#define cairo_win32_surface_create _moz_cairo_win32_surface_create
|
||||
#define cairo_win32_surface_create_with_dib _moz_cairo_win32_surface_create_with_dib
|
||||
#define cairo_win32_surface_get_dc _moz_cairo_win32_surface_get_dc
|
||||
#define cairo_xcb_surface_create _moz_cairo_xcb_surface_create
|
||||
#define cairo_xcb_surface_create_for_bitmap _moz_cairo_xcb_surface_create_for_bitmap
|
||||
#define cairo_xcb_surface_create_with_xrender_format _moz_cairo_xcb_surface_create_with_xrender_format
|
||||
#define cairo_xcb_surface_set_size _moz_cairo_xcb_surface_set_size
|
||||
#define cairo_xlib_surface_create _moz_cairo_xlib_surface_create
|
||||
#define cairo_xlib_surface_create_for_bitmap _moz_cairo_xlib_surface_create_for_bitmap
|
||||
#define cairo_xlib_surface_create_with_xrender_format _moz_cairo_xlib_surface_create_with_xrender_format
|
||||
#define cairo_xlib_surface_get_depth _moz_cairo_xlib_surface_get_depth
|
||||
#define cairo_xlib_surface_get_display _moz_cairo_xlib_surface_get_display
|
||||
#define cairo_xlib_surface_get_drawable _moz_cairo_xlib_surface_get_drawable
|
||||
#define cairo_xlib_surface_get_screen _moz_cairo_xlib_surface_get_screen
|
||||
#define cairo_xlib_surface_get_visual _moz_cairo_xlib_surface_get_visual
|
||||
#define cairo_xlib_surface_set_drawable _moz_cairo_xlib_surface_set_drawable
|
||||
#define cairo_xlib_surface_set_size _moz_cairo_xlib_surface_set_size
|
||||
|
||||
182
mozilla/gfx/cairo/cairo/src/cairo-scaled-font-subsets-private.h
Normal file
182
mozilla/gfx/cairo/cairo/src/cairo-scaled-font-subsets-private.h
Normal file
@ -0,0 +1,182 @@
|
||||
/* cairo - a vector graphics library with display and print output
|
||||
*
|
||||
* Copyright © 2006 Red Hat, Inc
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it either under the terms of the GNU Lesser General Public
|
||||
* License version 2.1 as published by the Free Software Foundation
|
||||
* (the "LGPL") or, at your option, under the terms of the Mozilla
|
||||
* Public License Version 1.1 (the "MPL"). If you do not alter this
|
||||
* notice, a recipient may use your version of this file under either
|
||||
* the MPL or the LGPL.
|
||||
*
|
||||
* You should have received a copy of the LGPL along with this library
|
||||
* in the file COPYING-LGPL-2.1; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
* You should have received a copy of the MPL along with this library
|
||||
* in the file COPYING-MPL-1.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License
|
||||
* Version 1.1 (the "License"); you may not use this file except in
|
||||
* compliance with the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY
|
||||
* OF ANY KIND, either express or implied. See the LGPL or the MPL for
|
||||
* the specific language governing rights and limitations.
|
||||
*
|
||||
* The Original Code is the cairo graphics library.
|
||||
*
|
||||
* The Initial Developer of the Original Code is University of Southern
|
||||
* California.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Carl D. Worth <cworth@cworth.org>
|
||||
*/
|
||||
|
||||
#ifndef CAIRO_SCALED_FONT_SUBSETS_PRIVATE_H
|
||||
#define CAIRO_SCALED_FONT_SUBSETS_PRIVATE_H
|
||||
|
||||
#include "cairoint.h"
|
||||
|
||||
typedef struct _cairo_scaled_font_subsets cairo_scaled_font_subsets_t;
|
||||
|
||||
typedef struct _cairo_scaled_font_subset {
|
||||
cairo_scaled_font_t *scaled_font;
|
||||
unsigned int font_id;
|
||||
unsigned int subset_id;
|
||||
|
||||
/* Index of glyphs array is subset_glyph_index.
|
||||
* Value of glyphs array is scaled_font_glyph_index.
|
||||
*/
|
||||
unsigned long *glyphs;
|
||||
int num_glyphs;
|
||||
} cairo_scaled_font_subset_t;
|
||||
|
||||
/**
|
||||
* _cairo_scaled_font_subsets_create:
|
||||
* @max_glyphs_per_subset: the maximum number of glyphs that should
|
||||
* appear in any subset. A value of 0 indicates that there is no limit
|
||||
* to the number of glyphs per subset.
|
||||
*
|
||||
* Create a new #cairo_scaled_font_subsets_t object which can be used
|
||||
* to create subsets of any number of cairo_scaled_font_t
|
||||
* objects. This allows the (arbitrarily large and sparse) glyph
|
||||
* indices of a cairo_scaled_font to be mapped to one or more font
|
||||
* subsets with glyph indices packed into the range
|
||||
* [0 .. max_glyphs_per_subset).
|
||||
*
|
||||
* Return value: a pointer to the newly creates font subsets. The
|
||||
* caller owns this object and should call
|
||||
* _cairo_scaled_font_subsets_destroy() when done with it.
|
||||
**/
|
||||
cairo_private cairo_scaled_font_subsets_t *
|
||||
_cairo_scaled_font_subsets_create (int max_glyphs_per_subset);
|
||||
|
||||
/**
|
||||
* _cairo_scaled_font_subsets_destroy:
|
||||
* @font_subsets: a #cairo_scaled_font_subsets_t object to be destroyed
|
||||
*
|
||||
* Destroys @font_subsets and all resources associated with it.
|
||||
**/
|
||||
cairo_private void
|
||||
_cairo_scaled_font_subsets_destroy (cairo_scaled_font_subsets_t *font_subsets);
|
||||
|
||||
/**
|
||||
* _cairo_scaled_font_subsets_map_glyph:
|
||||
* @font_subsets: a #cairo_scaled_font_subsets_t
|
||||
* @scaled_font: the font of the glyph to be mapped
|
||||
* @scaled_font_glyph_index: the index of the glyph to be mapped
|
||||
* @font_id_ret: return value giving the font ID of the mapped glyph
|
||||
* @subset_id_ret: return value giving the subset ID of the mapped glyph within the @font_id_ret
|
||||
* @subset_glyph_index_ret: return value giving the index of the mapped glyph within the @subset_id_ret subset
|
||||
*
|
||||
* Map a glyph from a #cairo_scaled_font to a new index within a
|
||||
* subset of that font. The mapping performed is from the tuple:
|
||||
*
|
||||
* (scaled_font, scaled_font_glyph_index)
|
||||
*
|
||||
* to the tuple:
|
||||
*
|
||||
* (font_id, subset_id, subset_glyph_index)
|
||||
*
|
||||
* This mapping is 1:1. If the input tuple has previously mapped, the
|
||||
* the output tuple previously returned will be returned again.
|
||||
*
|
||||
* Otherwise, the return tuple will be constructed as follows:
|
||||
*
|
||||
* 1) There is a 1:1 correspondence between the input scaled_font
|
||||
* value and the output font_id value. If no mapping has been
|
||||
* previously performed with the scaled_font value then the
|
||||
* smallest unused font_id value will be returned.
|
||||
*
|
||||
* 2) Within the set of output tuples of the same font_id value the
|
||||
* smallest value of subset_id will be returned such that
|
||||
* subset_glyph_index does not exceed max_glyphs_per_subset (as
|
||||
* passed to _cairo_scaled_font_subsets_create()) and that the
|
||||
* resulting tuple is unique.
|
||||
*
|
||||
* 3) The smallest value of subset_glyph_index is returned such that
|
||||
* the resulting tuple is unique.
|
||||
*
|
||||
* The net result is that any #cairo_scaled_font_t will be represented
|
||||
* by one or more font subsets. Each subset is effectively a tuple of
|
||||
* (scaled_font, font_id, subset_id) and within each subset there
|
||||
* exists a mapping of scaled_glyph_font_index to subset_glyph_index.
|
||||
*
|
||||
* This final description of a font subset is the same representation
|
||||
* used by #cairo_scaled_font_subset_t as provided by
|
||||
* _cairo_scaled_font_subsets_foreach.
|
||||
*
|
||||
* Return value: CAIRO_STATUS_SUCCESS if successful, or a non-zero
|
||||
* value indicating an error. Possible errors include
|
||||
* CAIRO_STATUS_NO_MEMORY.
|
||||
**/
|
||||
cairo_private cairo_status_t
|
||||
_cairo_scaled_font_subsets_map_glyph (cairo_scaled_font_subsets_t *font_subsets,
|
||||
cairo_scaled_font_t *scaled_font,
|
||||
unsigned long scaled_font_glyph_index,
|
||||
unsigned int *font_id_ret,
|
||||
unsigned int *subset_id_ret,
|
||||
unsigned int *subset_glyph_index_ret);
|
||||
|
||||
typedef void
|
||||
(*cairo_scaled_font_subset_callback_func_t) (cairo_scaled_font_subset_t *font_subset,
|
||||
void *closure);
|
||||
|
||||
/**
|
||||
* _cairo_scaled_font_subsets_foreach:
|
||||
* @font_subsets: a #cairo_scaled_font_subsets_t
|
||||
* @font_subset_callback: a function to be called for each font subset
|
||||
* @closure: closure data for the callback function
|
||||
*
|
||||
* Iterate over each unique font subset as created by calls to
|
||||
* _cairo_scaled_font_subsets_map_glyph(). A subset is determined by
|
||||
* unique pairs of (font_id, subset_id) as returned by
|
||||
* _cairo_scaled_font_subsets_map_glyph().
|
||||
*
|
||||
* For each subset, @font_subset_callback will be called and will be
|
||||
* provided with both a #cairo_scaled_font_subset_t object containing
|
||||
* all the glyphs in the subset as well as the value of @closure.
|
||||
*
|
||||
* The #cairo_scaled_font_subset_t object contains the scaled_font,
|
||||
* the font_id, and the subset_id corresponding to all glyphs
|
||||
* belonging to the subset. In addition, it contains an array providing
|
||||
* a mapping between subset glyph indices and the original scaled font
|
||||
* glyph indices.
|
||||
*
|
||||
* The index of the array corresponds to subset_glyph_index values
|
||||
* returned by _cairo_scaled_font_subsets_map_glyph() while the
|
||||
* values of the array correspond to the scaled_font_glyph_index
|
||||
* values passed as input to the same function.
|
||||
*
|
||||
* Return value: CAIRO_STATUS_SUCCESS if successful, or a non-zero
|
||||
* value indicating an error. Possible errors include
|
||||
* CAIRO_STATUS_NO_MEMORY.
|
||||
**/
|
||||
cairo_private cairo_status_t
|
||||
_cairo_scaled_font_subsets_foreach (cairo_scaled_font_subsets_t *font_subsets,
|
||||
cairo_scaled_font_subset_callback_func_t font_subset_callback,
|
||||
void *closure);
|
||||
|
||||
#endif /* CAIRO_SCALED_FONT_SUBSETS_PRIVATE_H */
|
||||
385
mozilla/gfx/cairo/cairo/src/cairo-scaled-font-subsets.c
Normal file
385
mozilla/gfx/cairo/cairo/src/cairo-scaled-font-subsets.c
Normal file
@ -0,0 +1,385 @@
|
||||
/* cairo - a vector graphics library with display and print output
|
||||
*
|
||||
* Copyright © 2003 University of Southern California
|
||||
* Copyright © 2005 Red Hat, Inc
|
||||
* Copyright © 2006 Keith Packard
|
||||
* Copyright © 2006 Red Hat, Inc
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it either under the terms of the GNU Lesser General Public
|
||||
* License version 2.1 as published by the Free Software Foundation
|
||||
* (the "LGPL") or, at your option, under the terms of the Mozilla
|
||||
* Public License Version 1.1 (the "MPL"). If you do not alter this
|
||||
* notice, a recipient may use your version of this file under either
|
||||
* the MPL or the LGPL.
|
||||
*
|
||||
* You should have received a copy of the LGPL along with this library
|
||||
* in the file COPYING-LGPL-2.1; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
* You should have received a copy of the MPL along with this library
|
||||
* in the file COPYING-MPL-1.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License
|
||||
* Version 1.1 (the "License"); you may not use this file except in
|
||||
* compliance with the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY
|
||||
* OF ANY KIND, either express or implied. See the LGPL or the MPL for
|
||||
* the specific language governing rights and limitations.
|
||||
*
|
||||
* The Original Code is the cairo graphics library.
|
||||
*
|
||||
* The Initial Developer of the Original Code is University of Southern
|
||||
* California.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Carl D. Worth <cworth@cworth.org>
|
||||
* Kristian Høgsberg <krh@redhat.com>
|
||||
* Keith Packard <keithp@keithp.com>
|
||||
*/
|
||||
|
||||
|
||||
#include "cairoint.h"
|
||||
#include "cairo-scaled-font-subsets-private.h"
|
||||
|
||||
struct _cairo_scaled_font_subsets {
|
||||
int max_glyphs_per_subset_limit;
|
||||
int max_glyphs_per_subset_used;
|
||||
int num_sub_fonts;
|
||||
|
||||
cairo_hash_table_t *sub_fonts;
|
||||
};
|
||||
|
||||
typedef struct _cairo_sub_font {
|
||||
cairo_hash_entry_t base;
|
||||
|
||||
cairo_scaled_font_subsets_t *parent;
|
||||
cairo_scaled_font_t *scaled_font;
|
||||
unsigned int font_id;
|
||||
|
||||
int current_subset;
|
||||
int num_glyphs_in_current_subset;
|
||||
int max_glyphs_per_subset;
|
||||
|
||||
cairo_hash_table_t *sub_font_glyphs;
|
||||
} cairo_sub_font_t;
|
||||
|
||||
typedef struct _cairo_sub_font_glyph {
|
||||
cairo_hash_entry_t base;
|
||||
|
||||
unsigned int subset_id;
|
||||
unsigned int subset_glyph_index;
|
||||
} cairo_sub_font_glyph_t;
|
||||
|
||||
typedef struct _cairo_sub_font_collection {
|
||||
unsigned long *glyphs; /* scaled_font_glyph_index */
|
||||
int glyphs_size;
|
||||
int max_glyph;
|
||||
int num_glyphs;
|
||||
|
||||
unsigned int subset_id;
|
||||
|
||||
cairo_scaled_font_subset_callback_func_t font_subset_callback;
|
||||
void *font_subset_callback_closure;
|
||||
} cairo_sub_font_collection_t;
|
||||
|
||||
static void
|
||||
_cairo_sub_font_glyph_init_key (cairo_sub_font_glyph_t *sub_font_glyph,
|
||||
unsigned long scaled_font_glyph_index)
|
||||
{
|
||||
sub_font_glyph->base.hash = scaled_font_glyph_index;
|
||||
}
|
||||
|
||||
static cairo_bool_t
|
||||
_cairo_sub_font_glyphs_equal (const void *key_a, const void *key_b)
|
||||
{
|
||||
const cairo_sub_font_glyph_t *sub_font_glyph_a = key_a;
|
||||
const cairo_sub_font_glyph_t *sub_font_glyph_b = key_b;
|
||||
|
||||
return sub_font_glyph_a->base.hash == sub_font_glyph_b->base.hash;
|
||||
}
|
||||
|
||||
static cairo_sub_font_glyph_t *
|
||||
_cairo_sub_font_glyph_create (unsigned long scaled_font_glyph_index,
|
||||
unsigned int subset_id,
|
||||
unsigned int subset_glyph_index)
|
||||
{
|
||||
cairo_sub_font_glyph_t *sub_font_glyph;
|
||||
|
||||
sub_font_glyph = malloc (sizeof (cairo_sub_font_glyph_t));
|
||||
if (sub_font_glyph == NULL)
|
||||
return NULL;
|
||||
|
||||
_cairo_sub_font_glyph_init_key (sub_font_glyph, scaled_font_glyph_index);
|
||||
sub_font_glyph->subset_id = subset_id;
|
||||
sub_font_glyph->subset_glyph_index = subset_glyph_index;
|
||||
|
||||
return sub_font_glyph;
|
||||
}
|
||||
|
||||
static void
|
||||
_cairo_sub_font_glyph_destroy (cairo_sub_font_glyph_t *sub_font_glyph)
|
||||
{
|
||||
free (sub_font_glyph);
|
||||
}
|
||||
|
||||
static void
|
||||
_cairo_sub_font_glyph_pluck (void *entry, void *closure)
|
||||
{
|
||||
cairo_sub_font_glyph_t *sub_font_glyph = entry;
|
||||
cairo_hash_table_t *sub_font_glyphs = closure;
|
||||
|
||||
_cairo_hash_table_remove (sub_font_glyphs, &sub_font_glyph->base);
|
||||
_cairo_sub_font_glyph_destroy (sub_font_glyph);
|
||||
}
|
||||
|
||||
static void
|
||||
_cairo_sub_font_glyph_collect (void *entry, void *closure)
|
||||
{
|
||||
cairo_sub_font_glyph_t *sub_font_glyph = entry;
|
||||
cairo_sub_font_collection_t *collection = closure;
|
||||
unsigned long scaled_font_glyph_index;
|
||||
unsigned int subset_glyph_index;
|
||||
|
||||
if (sub_font_glyph->subset_id != collection->subset_id)
|
||||
return;
|
||||
|
||||
scaled_font_glyph_index = sub_font_glyph->base.hash;
|
||||
subset_glyph_index = sub_font_glyph->subset_glyph_index;
|
||||
|
||||
/* Ensure we don't exceed the allocated bounds. */
|
||||
assert (subset_glyph_index < collection->glyphs_size);
|
||||
|
||||
collection->glyphs[subset_glyph_index] = scaled_font_glyph_index;
|
||||
if (subset_glyph_index > collection->max_glyph)
|
||||
collection->max_glyph = subset_glyph_index;
|
||||
|
||||
collection->num_glyphs++;
|
||||
}
|
||||
|
||||
static cairo_bool_t
|
||||
_cairo_sub_fonts_equal (const void *key_a, const void *key_b)
|
||||
{
|
||||
const cairo_sub_font_t *sub_font_a = key_a;
|
||||
const cairo_sub_font_t *sub_font_b = key_b;
|
||||
|
||||
return sub_font_a->scaled_font == sub_font_b->scaled_font;
|
||||
}
|
||||
|
||||
static void
|
||||
_cairo_sub_font_init_key (cairo_sub_font_t *sub_font,
|
||||
cairo_scaled_font_t *scaled_font)
|
||||
{
|
||||
sub_font->base.hash = (unsigned long) scaled_font;
|
||||
sub_font->scaled_font = scaled_font;
|
||||
}
|
||||
|
||||
static cairo_sub_font_t *
|
||||
_cairo_sub_font_create (cairo_scaled_font_subsets_t *parent,
|
||||
cairo_scaled_font_t *scaled_font,
|
||||
unsigned int font_id,
|
||||
int max_glyphs_per_subset)
|
||||
{
|
||||
cairo_sub_font_t *sub_font;
|
||||
|
||||
sub_font = malloc (sizeof (cairo_sub_font_t));
|
||||
if (sub_font == NULL)
|
||||
return NULL;
|
||||
|
||||
_cairo_sub_font_init_key (sub_font, scaled_font);
|
||||
|
||||
sub_font->parent = parent;
|
||||
sub_font->scaled_font = cairo_scaled_font_reference (scaled_font);
|
||||
sub_font->font_id = font_id;
|
||||
|
||||
sub_font->current_subset = 0;
|
||||
sub_font->num_glyphs_in_current_subset = 0;
|
||||
sub_font->max_glyphs_per_subset = max_glyphs_per_subset;
|
||||
|
||||
sub_font->sub_font_glyphs = _cairo_hash_table_create (_cairo_sub_font_glyphs_equal);
|
||||
if (! sub_font->sub_font_glyphs) {
|
||||
free (sub_font);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return sub_font;
|
||||
}
|
||||
|
||||
static void
|
||||
_cairo_sub_font_destroy (cairo_sub_font_t *sub_font)
|
||||
{
|
||||
_cairo_hash_table_foreach (sub_font->sub_font_glyphs,
|
||||
_cairo_sub_font_glyph_pluck,
|
||||
sub_font->sub_font_glyphs);
|
||||
_cairo_hash_table_destroy (sub_font->sub_font_glyphs);
|
||||
cairo_scaled_font_destroy (sub_font->scaled_font);
|
||||
free (sub_font);
|
||||
}
|
||||
|
||||
static void
|
||||
_cairo_sub_font_pluck (void *entry, void *closure)
|
||||
{
|
||||
cairo_sub_font_t *sub_font = entry;
|
||||
cairo_hash_table_t *sub_fonts = closure;
|
||||
|
||||
_cairo_hash_table_remove (sub_fonts, &sub_font->base);
|
||||
_cairo_sub_font_destroy (sub_font);
|
||||
}
|
||||
|
||||
static cairo_status_t
|
||||
_cairo_sub_font_map_glyph (cairo_sub_font_t *sub_font,
|
||||
unsigned long scaled_font_glyph_index,
|
||||
unsigned int *subset_id,
|
||||
unsigned int *subset_glyph_index)
|
||||
{
|
||||
cairo_sub_font_glyph_t key, *sub_font_glyph;
|
||||
cairo_status_t status;
|
||||
|
||||
_cairo_sub_font_glyph_init_key (&key, scaled_font_glyph_index);
|
||||
if (! _cairo_hash_table_lookup (sub_font->sub_font_glyphs, &key.base,
|
||||
(cairo_hash_entry_t **) &sub_font_glyph))
|
||||
{
|
||||
if (sub_font->max_glyphs_per_subset &&
|
||||
sub_font->num_glyphs_in_current_subset == sub_font->max_glyphs_per_subset)
|
||||
{
|
||||
sub_font->current_subset++;
|
||||
sub_font->num_glyphs_in_current_subset = 0;
|
||||
}
|
||||
|
||||
sub_font_glyph = _cairo_sub_font_glyph_create (scaled_font_glyph_index,
|
||||
sub_font->current_subset,
|
||||
sub_font->num_glyphs_in_current_subset++);
|
||||
if (sub_font_glyph == NULL)
|
||||
return CAIRO_STATUS_NO_MEMORY;
|
||||
|
||||
if (sub_font->num_glyphs_in_current_subset > sub_font->parent->max_glyphs_per_subset_used)
|
||||
sub_font->parent->max_glyphs_per_subset_used = sub_font->num_glyphs_in_current_subset;
|
||||
|
||||
status = _cairo_hash_table_insert (sub_font->sub_font_glyphs, &sub_font_glyph->base);
|
||||
if (status)
|
||||
return status;
|
||||
}
|
||||
|
||||
*subset_id = sub_font_glyph->subset_id;
|
||||
*subset_glyph_index = sub_font_glyph->subset_glyph_index;
|
||||
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
static void
|
||||
_cairo_sub_font_collect (void *entry, void *closure)
|
||||
{
|
||||
cairo_sub_font_t *sub_font = entry;
|
||||
cairo_sub_font_collection_t *collection = closure;
|
||||
cairo_scaled_font_subset_t subset;
|
||||
int i;
|
||||
|
||||
for (i = 0; i <= sub_font->current_subset; i++) {
|
||||
collection->subset_id = i;
|
||||
|
||||
collection->num_glyphs = 0;
|
||||
collection->max_glyph = 0;
|
||||
|
||||
_cairo_hash_table_foreach (sub_font->sub_font_glyphs,
|
||||
_cairo_sub_font_glyph_collect, collection);
|
||||
|
||||
/* Ensure the resulting array has no uninitialized holes */
|
||||
assert (collection->num_glyphs == collection->max_glyph + 1);
|
||||
|
||||
subset.scaled_font = sub_font->scaled_font;
|
||||
subset.font_id = sub_font->font_id;
|
||||
subset.subset_id = i;
|
||||
subset.glyphs = collection->glyphs;
|
||||
subset.num_glyphs = collection->num_glyphs;
|
||||
|
||||
(collection->font_subset_callback) (&subset,
|
||||
collection->font_subset_callback_closure);
|
||||
}
|
||||
}
|
||||
|
||||
cairo_scaled_font_subsets_t *
|
||||
_cairo_scaled_font_subsets_create (int max_glyphs_per_subset)
|
||||
{
|
||||
cairo_scaled_font_subsets_t *subsets;
|
||||
|
||||
subsets = malloc (sizeof (cairo_scaled_font_subsets_t));
|
||||
if (subsets == NULL)
|
||||
return NULL;
|
||||
|
||||
subsets->max_glyphs_per_subset_limit = max_glyphs_per_subset;
|
||||
subsets->max_glyphs_per_subset_used = 0;
|
||||
subsets->num_sub_fonts = 0;
|
||||
|
||||
subsets->sub_fonts = _cairo_hash_table_create (_cairo_sub_fonts_equal);
|
||||
if (! subsets->sub_fonts) {
|
||||
free (subsets);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return subsets;
|
||||
}
|
||||
|
||||
void
|
||||
_cairo_scaled_font_subsets_destroy (cairo_scaled_font_subsets_t *subsets)
|
||||
{
|
||||
_cairo_hash_table_foreach (subsets->sub_fonts, _cairo_sub_font_pluck, subsets->sub_fonts);
|
||||
_cairo_hash_table_destroy (subsets->sub_fonts);
|
||||
free (subsets);
|
||||
}
|
||||
|
||||
cairo_private cairo_status_t
|
||||
_cairo_scaled_font_subsets_map_glyph (cairo_scaled_font_subsets_t *subsets,
|
||||
cairo_scaled_font_t *scaled_font,
|
||||
unsigned long scaled_font_glyph_index,
|
||||
unsigned int *font_id,
|
||||
unsigned int *subset_id,
|
||||
unsigned int *subset_glyph_index)
|
||||
{
|
||||
cairo_sub_font_t key, *sub_font;
|
||||
cairo_status_t status;
|
||||
|
||||
_cairo_sub_font_init_key (&key, scaled_font);
|
||||
if (! _cairo_hash_table_lookup (subsets->sub_fonts, &key.base,
|
||||
(cairo_hash_entry_t **) &sub_font))
|
||||
{
|
||||
sub_font = _cairo_sub_font_create (subsets, scaled_font,
|
||||
subsets->num_sub_fonts++,
|
||||
subsets->max_glyphs_per_subset_limit);
|
||||
if (sub_font == NULL)
|
||||
return CAIRO_STATUS_NO_MEMORY;
|
||||
|
||||
status = _cairo_hash_table_insert (subsets->sub_fonts,
|
||||
&sub_font->base);
|
||||
if (status)
|
||||
return status;
|
||||
}
|
||||
|
||||
*font_id = sub_font->font_id;
|
||||
|
||||
return _cairo_sub_font_map_glyph (sub_font, scaled_font_glyph_index,
|
||||
subset_id, subset_glyph_index);
|
||||
}
|
||||
|
||||
cairo_private cairo_status_t
|
||||
_cairo_scaled_font_subsets_foreach (cairo_scaled_font_subsets_t *font_subsets,
|
||||
cairo_scaled_font_subset_callback_func_t font_subset_callback,
|
||||
void *closure)
|
||||
{
|
||||
cairo_sub_font_collection_t collection;
|
||||
|
||||
collection.glyphs_size = font_subsets->max_glyphs_per_subset_used;
|
||||
collection.glyphs = malloc (collection.glyphs_size * sizeof(unsigned long));
|
||||
if (collection.glyphs == NULL)
|
||||
return CAIRO_STATUS_NO_MEMORY;
|
||||
|
||||
collection.font_subset_callback = font_subset_callback;
|
||||
collection.font_subset_callback_closure = closure;
|
||||
|
||||
_cairo_hash_table_foreach (font_subsets->sub_fonts,
|
||||
_cairo_sub_font_collect, &collection);
|
||||
|
||||
free (collection.glyphs);
|
||||
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
}
|
||||
@ -1,4 +1,4 @@
|
||||
/* $Id: cairo-scaled-font.c,v 1.8 2006-04-01 00:36:09 vladimir%pobox.com Exp $
|
||||
/* $Id: cairo-scaled-font.c,v 1.9 2006-06-05 23:16:24 vladimir%pobox.com Exp $
|
||||
*
|
||||
* Copyright © 2005 Keith Packard
|
||||
*
|
||||
@ -39,10 +39,10 @@
|
||||
#include "cairoint.h"
|
||||
|
||||
static cairo_bool_t
|
||||
_cairo_scaled_glyph_keys_equal (void *abstract_key_a, void *abstract_key_b)
|
||||
_cairo_scaled_glyph_keys_equal (const void *abstract_key_a, const void *abstract_key_b)
|
||||
{
|
||||
cairo_scaled_glyph_t *key_a = abstract_key_a;
|
||||
cairo_scaled_glyph_t *key_b = abstract_key_b;
|
||||
const cairo_scaled_glyph_t *key_a = abstract_key_a;
|
||||
const cairo_scaled_glyph_t *key_b = abstract_key_b;
|
||||
|
||||
return (_cairo_scaled_glyph_index (key_a) ==
|
||||
_cairo_scaled_glyph_index (key_b));
|
||||
@ -180,7 +180,7 @@ static cairo_scaled_font_map_t *cairo_scaled_font_map = NULL;
|
||||
CAIRO_MUTEX_DECLARE (cairo_scaled_font_map_mutex);
|
||||
|
||||
static int
|
||||
_cairo_scaled_font_keys_equal (void *abstract_key_a, void *abstract_key_b);
|
||||
_cairo_scaled_font_keys_equal (const void *abstract_key_a, const void *abstract_key_b);
|
||||
|
||||
static cairo_scaled_font_map_t *
|
||||
_cairo_scaled_font_map_lock (void)
|
||||
@ -298,10 +298,10 @@ _cairo_scaled_font_init_key (cairo_scaled_font_t *scaled_font,
|
||||
}
|
||||
|
||||
static cairo_bool_t
|
||||
_cairo_scaled_font_keys_equal (void *abstract_key_a, void *abstract_key_b)
|
||||
_cairo_scaled_font_keys_equal (const void *abstract_key_a, const void *abstract_key_b)
|
||||
{
|
||||
cairo_scaled_font_t *key_a = abstract_key_a;
|
||||
cairo_scaled_font_t *key_b = abstract_key_b;
|
||||
const cairo_scaled_font_t *key_a = abstract_key_a;
|
||||
const cairo_scaled_font_t *key_b = abstract_key_b;
|
||||
|
||||
return (key_a->font_face == key_b->font_face &&
|
||||
memcmp ((unsigned char *)(&key_a->font_matrix.xx),
|
||||
@ -782,10 +782,10 @@ _cairo_scaled_font_text_to_glyphs (cairo_scaled_font_t *scaled_font,
|
||||
* Compute a device-space bounding box for the glyphs.
|
||||
*/
|
||||
cairo_status_t
|
||||
_cairo_scaled_font_glyph_device_extents (cairo_scaled_font_t *scaled_font,
|
||||
const cairo_glyph_t *glyphs,
|
||||
int num_glyphs,
|
||||
cairo_rectangle_t *extents)
|
||||
_cairo_scaled_font_glyph_device_extents (cairo_scaled_font_t *scaled_font,
|
||||
const cairo_glyph_t *glyphs,
|
||||
int num_glyphs,
|
||||
cairo_rectangle_fixed_t *extents)
|
||||
{
|
||||
cairo_status_t status = CAIRO_STATUS_SUCCESS;
|
||||
int i;
|
||||
@ -920,11 +920,11 @@ _cairo_scaled_font_show_glyphs (cairo_scaled_font_t *scaled_font,
|
||||
|
||||
/* round glyph locations to the nearest pixel */
|
||||
x = (int) floor (glyphs[i].x +
|
||||
glyph_surface->base.device_x_offset +
|
||||
0.5);
|
||||
glyph_surface->base.device_x_offset +
|
||||
0.5);
|
||||
y = (int) floor (glyphs[i].y +
|
||||
glyph_surface->base.device_y_offset +
|
||||
0.5);
|
||||
glyph_surface->base.device_y_offset +
|
||||
0.5);
|
||||
|
||||
_cairo_pattern_init_for_surface (&glyph_pattern, &glyph_surface->base);
|
||||
|
||||
@ -1020,7 +1020,7 @@ _scaled_glyph_path_close_path (void *abstract_closure)
|
||||
|
||||
cairo_status_t
|
||||
_cairo_scaled_font_glyph_path (cairo_scaled_font_t *scaled_font,
|
||||
cairo_glyph_t *glyphs,
|
||||
const cairo_glyph_t *glyphs,
|
||||
int num_glyphs,
|
||||
cairo_path_fixed_t *path)
|
||||
{
|
||||
@ -1211,13 +1211,18 @@ _cairo_scaled_glyph_lookup (cairo_scaled_font_t *scaled_font,
|
||||
/* ask backend to initialize metrics and shape fields */
|
||||
status = (*scaled_font->backend->
|
||||
scaled_glyph_init) (scaled_font, scaled_glyph, info);
|
||||
if (status)
|
||||
if (status) {
|
||||
_cairo_scaled_glyph_destroy (scaled_glyph);
|
||||
goto CLEANUP;
|
||||
}
|
||||
|
||||
/* on success, the cache takes ownership of the scaled_glyph */
|
||||
status = _cairo_cache_insert (scaled_font->glyphs,
|
||||
&scaled_glyph->cache_entry);
|
||||
if (status)
|
||||
if (status) {
|
||||
_cairo_scaled_glyph_destroy (scaled_glyph);
|
||||
goto CLEANUP;
|
||||
}
|
||||
}
|
||||
/*
|
||||
* Check and see if the glyph, as provided,
|
||||
@ -1242,8 +1247,6 @@ _cairo_scaled_glyph_lookup (cairo_scaled_font_t *scaled_font,
|
||||
CLEANUP:
|
||||
if (status) {
|
||||
_cairo_scaled_font_set_error (scaled_font, status);
|
||||
if (scaled_glyph)
|
||||
_cairo_scaled_glyph_destroy (scaled_glyph);
|
||||
*scaled_glyph_ret = NULL;
|
||||
} else {
|
||||
*scaled_glyph_ret = scaled_glyph;
|
||||
|
||||
@ -96,10 +96,10 @@ _cairo_surface_fallback_composite (cairo_operator_t op,
|
||||
unsigned int height);
|
||||
|
||||
cairo_private cairo_status_t
|
||||
_cairo_surface_fallback_fill_rectangles (cairo_surface_t *surface,
|
||||
_cairo_surface_fallback_fill_rectangles (cairo_surface_t *surface,
|
||||
cairo_operator_t op,
|
||||
const cairo_color_t *color,
|
||||
cairo_rectangle_t *rects,
|
||||
const cairo_color_t *color,
|
||||
cairo_rectangle_fixed_t *rects,
|
||||
int num_rects);
|
||||
|
||||
cairo_private cairo_status_t
|
||||
|
||||
@ -40,9 +40,9 @@
|
||||
|
||||
typedef struct {
|
||||
cairo_surface_t *dst;
|
||||
cairo_rectangle_t extents;
|
||||
cairo_rectangle_fixed_t extents;
|
||||
cairo_image_surface_t *image;
|
||||
cairo_rectangle_t image_rect;
|
||||
cairo_rectangle_fixed_t image_rect;
|
||||
void *image_extra;
|
||||
} fallback_state_t;
|
||||
|
||||
@ -98,21 +98,21 @@ _fallback_fini (fallback_state_t *state)
|
||||
state->image_extra);
|
||||
}
|
||||
|
||||
typedef cairo_status_t (*cairo_draw_func_t) (void *closure,
|
||||
cairo_operator_t op,
|
||||
cairo_pattern_t *src,
|
||||
cairo_surface_t *dst,
|
||||
int dst_x,
|
||||
int dst_y,
|
||||
const cairo_rectangle_t *extents);
|
||||
typedef cairo_status_t (*cairo_draw_func_t) (void *closure,
|
||||
cairo_operator_t op,
|
||||
cairo_pattern_t *src,
|
||||
cairo_surface_t *dst,
|
||||
int dst_x,
|
||||
int dst_y,
|
||||
const cairo_rectangle_fixed_t *extents);
|
||||
|
||||
static cairo_status_t
|
||||
_create_composite_mask_pattern (cairo_surface_pattern_t *mask_pattern,
|
||||
cairo_clip_t *clip,
|
||||
cairo_draw_func_t draw_func,
|
||||
void *draw_closure,
|
||||
cairo_surface_t *dst,
|
||||
const cairo_rectangle_t *extents)
|
||||
_create_composite_mask_pattern (cairo_surface_pattern_t *mask_pattern,
|
||||
cairo_clip_t *clip,
|
||||
cairo_draw_func_t draw_func,
|
||||
void *draw_closure,
|
||||
cairo_surface_t *dst,
|
||||
const cairo_rectangle_fixed_t *extents)
|
||||
{
|
||||
cairo_surface_t *mask;
|
||||
cairo_status_t status;
|
||||
@ -151,13 +151,13 @@ _create_composite_mask_pattern (cairo_surface_pattern_t *mask_pattern,
|
||||
* us to combine the clip with the mask
|
||||
*/
|
||||
static cairo_status_t
|
||||
_clip_and_composite_with_mask (cairo_clip_t *clip,
|
||||
cairo_operator_t op,
|
||||
cairo_pattern_t *src,
|
||||
cairo_draw_func_t draw_func,
|
||||
void *draw_closure,
|
||||
cairo_surface_t *dst,
|
||||
const cairo_rectangle_t *extents)
|
||||
_clip_and_composite_with_mask (cairo_clip_t *clip,
|
||||
cairo_operator_t op,
|
||||
cairo_pattern_t *src,
|
||||
cairo_draw_func_t draw_func,
|
||||
void *draw_closure,
|
||||
cairo_surface_t *dst,
|
||||
const cairo_rectangle_fixed_t *extents)
|
||||
{
|
||||
cairo_surface_pattern_t mask_pattern;
|
||||
cairo_status_t status;
|
||||
@ -185,13 +185,13 @@ _clip_and_composite_with_mask (cairo_clip_t *clip,
|
||||
* in two pieces and combine them together.
|
||||
*/
|
||||
static cairo_status_t
|
||||
_clip_and_composite_combine (cairo_clip_t *clip,
|
||||
cairo_operator_t op,
|
||||
cairo_pattern_t *src,
|
||||
cairo_draw_func_t draw_func,
|
||||
void *draw_closure,
|
||||
cairo_surface_t *dst,
|
||||
const cairo_rectangle_t *extents)
|
||||
_clip_and_composite_combine (cairo_clip_t *clip,
|
||||
cairo_operator_t op,
|
||||
cairo_pattern_t *src,
|
||||
cairo_draw_func_t draw_func,
|
||||
void *draw_closure,
|
||||
cairo_surface_t *dst,
|
||||
const cairo_rectangle_fixed_t *extents)
|
||||
{
|
||||
cairo_surface_t *intermediate;
|
||||
cairo_surface_pattern_t dst_pattern;
|
||||
@ -274,12 +274,12 @@ _clip_and_composite_combine (cairo_clip_t *clip,
|
||||
* defined as (src IN mask IN clip) ADD (dst OUT (mask IN clip))
|
||||
*/
|
||||
static cairo_status_t
|
||||
_clip_and_composite_source (cairo_clip_t *clip,
|
||||
cairo_pattern_t *src,
|
||||
cairo_draw_func_t draw_func,
|
||||
void *draw_closure,
|
||||
cairo_surface_t *dst,
|
||||
const cairo_rectangle_t *extents)
|
||||
_clip_and_composite_source (cairo_clip_t *clip,
|
||||
cairo_pattern_t *src,
|
||||
cairo_draw_func_t draw_func,
|
||||
void *draw_closure,
|
||||
cairo_surface_t *dst,
|
||||
const cairo_rectangle_fixed_t *extents)
|
||||
{
|
||||
cairo_surface_pattern_t mask_pattern;
|
||||
cairo_status_t status;
|
||||
@ -320,7 +320,7 @@ _clip_and_composite_source (cairo_clip_t *clip,
|
||||
}
|
||||
|
||||
static int
|
||||
_cairo_rectangle_empty (const cairo_rectangle_t *rect)
|
||||
_cairo_rectangle_empty (const cairo_rectangle_fixed_t *rect)
|
||||
{
|
||||
return rect->width == 0 || rect->height == 0;
|
||||
}
|
||||
@ -347,13 +347,13 @@ _cairo_rectangle_empty (const cairo_rectangle_t *rect)
|
||||
* Return value: %CAIRO_STATUS_SUCCESS if the drawing succeeded.
|
||||
**/
|
||||
static cairo_status_t
|
||||
_clip_and_composite (cairo_clip_t *clip,
|
||||
cairo_operator_t op,
|
||||
cairo_pattern_t *src,
|
||||
cairo_draw_func_t draw_func,
|
||||
void *draw_closure,
|
||||
cairo_surface_t *dst,
|
||||
const cairo_rectangle_t *extents)
|
||||
_clip_and_composite (cairo_clip_t *clip,
|
||||
cairo_operator_t op,
|
||||
cairo_pattern_t *src,
|
||||
cairo_draw_func_t draw_func,
|
||||
void *draw_closure,
|
||||
cairo_surface_t *dst,
|
||||
const cairo_rectangle_fixed_t *extents)
|
||||
{
|
||||
cairo_pattern_union_t solid_pattern;
|
||||
cairo_status_t status;
|
||||
@ -403,12 +403,12 @@ _clip_and_composite (cairo_clip_t *clip,
|
||||
/* Composites a region representing a set of trapezoids.
|
||||
*/
|
||||
static cairo_status_t
|
||||
_composite_trap_region (cairo_clip_t *clip,
|
||||
cairo_pattern_t *src,
|
||||
cairo_operator_t op,
|
||||
cairo_surface_t *dst,
|
||||
pixman_region16_t *trap_region,
|
||||
cairo_rectangle_t *extents)
|
||||
_composite_trap_region (cairo_clip_t *clip,
|
||||
cairo_pattern_t *src,
|
||||
cairo_operator_t op,
|
||||
cairo_surface_t *dst,
|
||||
pixman_region16_t *trap_region,
|
||||
cairo_rectangle_fixed_t *extents)
|
||||
{
|
||||
cairo_status_t status;
|
||||
cairo_pattern_union_t solid_pattern;
|
||||
@ -451,6 +451,10 @@ _composite_trap_region (cairo_clip_t *clip,
|
||||
extents->x, extents->y,
|
||||
extents->width, extents->height);
|
||||
|
||||
/* Restore the original clip if we modified it temporarily. */
|
||||
if (num_rects >1)
|
||||
_cairo_surface_set_clip (dst, clip);
|
||||
|
||||
if (clip_surface)
|
||||
_cairo_pattern_fini (&mask.base);
|
||||
|
||||
@ -466,13 +470,13 @@ typedef struct {
|
||||
} cairo_composite_traps_info_t;
|
||||
|
||||
static cairo_status_t
|
||||
_composite_traps_draw_func (void *closure,
|
||||
cairo_operator_t op,
|
||||
cairo_pattern_t *src,
|
||||
cairo_surface_t *dst,
|
||||
int dst_x,
|
||||
int dst_y,
|
||||
const cairo_rectangle_t *extents)
|
||||
_composite_traps_draw_func (void *closure,
|
||||
cairo_operator_t op,
|
||||
cairo_pattern_t *src,
|
||||
cairo_surface_t *dst,
|
||||
int dst_x,
|
||||
int dst_y,
|
||||
const cairo_rectangle_fixed_t *extents)
|
||||
{
|
||||
cairo_composite_traps_info_t *info = closure;
|
||||
cairo_pattern_union_t pattern;
|
||||
@ -509,7 +513,7 @@ _clip_and_composite_trapezoids (cairo_pattern_t *src,
|
||||
cairo_status_t status;
|
||||
pixman_region16_t *trap_region;
|
||||
pixman_region16_t *clear_region = NULL;
|
||||
cairo_rectangle_t extents;
|
||||
cairo_rectangle_fixed_t extents;
|
||||
cairo_composite_traps_info_t traps_info;
|
||||
|
||||
if (traps->num_traps == 0)
|
||||
@ -652,7 +656,7 @@ _cairo_surface_fallback_paint (cairo_surface_t *surface,
|
||||
cairo_pattern_t *source)
|
||||
{
|
||||
cairo_status_t status;
|
||||
cairo_rectangle_t extents;
|
||||
cairo_rectangle_fixed_t extents;
|
||||
cairo_box_t box;
|
||||
cairo_traps_t traps;
|
||||
|
||||
@ -661,7 +665,7 @@ _cairo_surface_fallback_paint (cairo_surface_t *surface,
|
||||
return status;
|
||||
|
||||
if (_cairo_operator_bounded_by_source (op)) {
|
||||
cairo_rectangle_t source_extents;
|
||||
cairo_rectangle_fixed_t source_extents;
|
||||
status = _cairo_pattern_get_extents (source, &source_extents);
|
||||
if (status)
|
||||
return status;
|
||||
@ -695,13 +699,13 @@ _cairo_surface_fallback_paint (cairo_surface_t *surface,
|
||||
}
|
||||
|
||||
static cairo_status_t
|
||||
_cairo_surface_mask_draw_func (void *closure,
|
||||
cairo_operator_t op,
|
||||
cairo_pattern_t *src,
|
||||
cairo_surface_t *dst,
|
||||
int dst_x,
|
||||
int dst_y,
|
||||
const cairo_rectangle_t *extents)
|
||||
_cairo_surface_mask_draw_func (void *closure,
|
||||
cairo_operator_t op,
|
||||
cairo_pattern_t *src,
|
||||
cairo_surface_t *dst,
|
||||
int dst_x,
|
||||
int dst_y,
|
||||
const cairo_rectangle_fixed_t *extents)
|
||||
{
|
||||
cairo_pattern_t *mask = closure;
|
||||
|
||||
@ -728,7 +732,7 @@ _cairo_surface_fallback_mask (cairo_surface_t *surface,
|
||||
cairo_pattern_t *mask)
|
||||
{
|
||||
cairo_status_t status;
|
||||
cairo_rectangle_t extents, source_extents, mask_extents;
|
||||
cairo_rectangle_fixed_t extents, source_extents, mask_extents;
|
||||
|
||||
status = _cairo_surface_get_extents (surface, &extents);
|
||||
if (status)
|
||||
@ -844,13 +848,13 @@ typedef struct {
|
||||
} cairo_show_glyphs_info_t;
|
||||
|
||||
static cairo_status_t
|
||||
_cairo_surface_old_show_glyphs_draw_func (void *closure,
|
||||
cairo_operator_t op,
|
||||
cairo_pattern_t *src,
|
||||
cairo_surface_t *dst,
|
||||
int dst_x,
|
||||
int dst_y,
|
||||
const cairo_rectangle_t *extents)
|
||||
_cairo_surface_old_show_glyphs_draw_func (void *closure,
|
||||
cairo_operator_t op,
|
||||
cairo_pattern_t *src,
|
||||
cairo_surface_t *dst,
|
||||
int dst_x,
|
||||
int dst_y,
|
||||
const cairo_rectangle_fixed_t *extents)
|
||||
{
|
||||
cairo_show_glyphs_info_t *glyph_info = closure;
|
||||
cairo_pattern_union_t pattern;
|
||||
@ -912,7 +916,7 @@ _cairo_surface_fallback_show_glyphs (cairo_surface_t *surface,
|
||||
cairo_scaled_font_t *scaled_font)
|
||||
{
|
||||
cairo_status_t status;
|
||||
cairo_rectangle_t extents, glyph_extents;
|
||||
cairo_rectangle_fixed_t extents, glyph_extents;
|
||||
cairo_show_glyphs_info_t glyph_info;
|
||||
|
||||
status = _cairo_surface_get_extents (surface, &extents);
|
||||
@ -1035,14 +1039,14 @@ _cairo_surface_fallback_composite (cairo_operator_t op,
|
||||
}
|
||||
|
||||
cairo_status_t
|
||||
_cairo_surface_fallback_fill_rectangles (cairo_surface_t *surface,
|
||||
cairo_operator_t op,
|
||||
const cairo_color_t *color,
|
||||
cairo_rectangle_t *rects,
|
||||
int num_rects)
|
||||
_cairo_surface_fallback_fill_rectangles (cairo_surface_t *surface,
|
||||
cairo_operator_t op,
|
||||
const cairo_color_t *color,
|
||||
cairo_rectangle_fixed_t *rects,
|
||||
int num_rects)
|
||||
{
|
||||
fallback_state_t state;
|
||||
cairo_rectangle_t *offset_rects = NULL;
|
||||
cairo_rectangle_fixed_t *offset_rects = NULL;
|
||||
cairo_status_t status;
|
||||
int x1, y1, x2, y2;
|
||||
int i;
|
||||
@ -1082,7 +1086,7 @@ _cairo_surface_fallback_fill_rectangles (cairo_surface_t *surface,
|
||||
/* If the fetched image isn't at 0,0, we need to offset the rectangles */
|
||||
|
||||
if (state.image_rect.x != 0 || state.image_rect.y != 0) {
|
||||
offset_rects = malloc (sizeof (cairo_rectangle_t) * num_rects);
|
||||
offset_rects = malloc (sizeof (cairo_rectangle_fixed_t) * num_rects);
|
||||
if (offset_rects == NULL) {
|
||||
status = CAIRO_STATUS_NO_MEMORY;
|
||||
goto DONE;
|
||||
|
||||
@ -43,6 +43,7 @@
|
||||
|
||||
const cairo_surface_t _cairo_surface_nil = {
|
||||
&cairo_image_surface_backend, /* backend */
|
||||
CAIRO_CONTENT_COLOR,
|
||||
CAIRO_SURFACE_TYPE_IMAGE,
|
||||
-1, /* ref_count */
|
||||
CAIRO_STATUS_NO_MEMORY, /* status */
|
||||
@ -60,6 +61,7 @@ const cairo_surface_t _cairo_surface_nil = {
|
||||
|
||||
const cairo_surface_t _cairo_surface_nil_file_not_found = {
|
||||
&cairo_image_surface_backend, /* backend */
|
||||
CAIRO_CONTENT_COLOR,
|
||||
CAIRO_SURFACE_TYPE_IMAGE,
|
||||
-1, /* ref_count */
|
||||
CAIRO_STATUS_FILE_NOT_FOUND, /* status */
|
||||
@ -77,6 +79,7 @@ const cairo_surface_t _cairo_surface_nil_file_not_found = {
|
||||
|
||||
const cairo_surface_t _cairo_surface_nil_read_error = {
|
||||
&cairo_image_surface_backend, /* backend */
|
||||
CAIRO_CONTENT_COLOR,
|
||||
CAIRO_SURFACE_TYPE_IMAGE,
|
||||
-1, /* ref_count */
|
||||
CAIRO_STATUS_READ_ERROR, /* status */
|
||||
@ -116,7 +119,7 @@ static void _cairo_surface_copy_pattern_for_destination (const cairo_pattern_t *
|
||||
* breakpoint in _cairo_error() to generate a stack trace for when the
|
||||
* user causes cairo to detect an error.
|
||||
**/
|
||||
static void
|
||||
void
|
||||
_cairo_surface_set_error (cairo_surface_t *surface,
|
||||
cairo_status_t status)
|
||||
{
|
||||
@ -145,6 +148,20 @@ cairo_surface_get_type (cairo_surface_t *surface)
|
||||
return surface->type;
|
||||
}
|
||||
|
||||
/**
|
||||
* cairo_surface_get_content:
|
||||
* @surface: a #cairo_surface_t
|
||||
*
|
||||
* Return value: The content type of @surface which indicates whether
|
||||
* the surface contains color and/or alpha information. See
|
||||
* #cairo_content_t.
|
||||
**/
|
||||
cairo_content_t
|
||||
cairo_surface_get_content (cairo_surface_t *surface)
|
||||
{
|
||||
return surface->content;
|
||||
}
|
||||
|
||||
/**
|
||||
* cairo_surface_status:
|
||||
* @surface: a #cairo_surface_t
|
||||
@ -165,9 +182,12 @@ cairo_surface_status (cairo_surface_t *surface)
|
||||
|
||||
void
|
||||
_cairo_surface_init (cairo_surface_t *surface,
|
||||
const cairo_surface_backend_t *backend)
|
||||
const cairo_surface_backend_t *backend,
|
||||
cairo_content_t content)
|
||||
{
|
||||
surface->backend = backend;
|
||||
|
||||
surface->content = content;
|
||||
|
||||
surface->type = backend->type;
|
||||
|
||||
@ -268,7 +288,10 @@ _cairo_surface_create_similar_solid (cairo_surface_t *other,
|
||||
return (cairo_surface_t*) &_cairo_surface_nil;
|
||||
}
|
||||
|
||||
status = _cairo_surface_paint (surface, CAIRO_OPERATOR_SOURCE, source);
|
||||
status = _cairo_surface_paint (surface,
|
||||
color == CAIRO_COLOR_TRANSPARENT ?
|
||||
CAIRO_OPERATOR_CLEAR :
|
||||
CAIRO_OPERATOR_SOURCE, source);
|
||||
|
||||
cairo_pattern_destroy (source);
|
||||
|
||||
@ -587,8 +610,8 @@ cairo_surface_mark_dirty_rectangle (cairo_surface_t *surface,
|
||||
* sufficient to do this, since functions like
|
||||
* cairo_device_to_user() will expose the hidden offset.
|
||||
*
|
||||
* Note that the offset only affects drawing to the surface, not using
|
||||
* the surface in a surface pattern.
|
||||
* Note that the offset affects drawing to the surface as well as
|
||||
* using the surface in a source pattern.
|
||||
**/
|
||||
void
|
||||
cairo_surface_set_device_offset (cairo_surface_t *surface,
|
||||
@ -614,7 +637,7 @@ cairo_surface_set_device_offset (cairo_surface_t *surface,
|
||||
* @surface: a #cairo_surface_t
|
||||
* @x_offset: the offset in the X direction, in device units
|
||||
* @y_offset: the offset in the Y direction, in device units
|
||||
*
|
||||
*
|
||||
* Returns a previous device offset set by
|
||||
* cairo_surface_set_device_offset().
|
||||
*
|
||||
@ -714,9 +737,9 @@ _cairo_surface_release_source_image (cairo_surface_t *surface,
|
||||
**/
|
||||
cairo_status_t
|
||||
_cairo_surface_acquire_dest_image (cairo_surface_t *surface,
|
||||
cairo_rectangle_t *interest_rect,
|
||||
cairo_rectangle_fixed_t *interest_rect,
|
||||
cairo_image_surface_t **image_out,
|
||||
cairo_rectangle_t *image_rect,
|
||||
cairo_rectangle_fixed_t *image_rect,
|
||||
void **image_extra)
|
||||
{
|
||||
assert (!surface->finished);
|
||||
@ -739,11 +762,11 @@ _cairo_surface_acquire_dest_image (cairo_surface_t *surface,
|
||||
* resources that were allocated.
|
||||
**/
|
||||
void
|
||||
_cairo_surface_release_dest_image (cairo_surface_t *surface,
|
||||
cairo_rectangle_t *interest_rect,
|
||||
cairo_image_surface_t *image,
|
||||
cairo_rectangle_t *image_rect,
|
||||
void *image_extra)
|
||||
_cairo_surface_release_dest_image (cairo_surface_t *surface,
|
||||
cairo_rectangle_fixed_t *interest_rect,
|
||||
cairo_image_surface_t *image,
|
||||
cairo_rectangle_fixed_t *image_rect,
|
||||
void *image_extra)
|
||||
{
|
||||
assert (!surface->finished);
|
||||
|
||||
@ -915,7 +938,7 @@ _cairo_surface_fill_rectangle (cairo_surface_t *surface,
|
||||
int width,
|
||||
int height)
|
||||
{
|
||||
cairo_rectangle_t rect;
|
||||
cairo_rectangle_fixed_t rect;
|
||||
|
||||
assert (! surface->is_snapshot);
|
||||
|
||||
@ -954,7 +977,7 @@ _cairo_surface_fill_region (cairo_surface_t *surface,
|
||||
{
|
||||
int num_rects = pixman_region_num_rects (region);
|
||||
pixman_box16_t *boxes = pixman_region_rects (region);
|
||||
cairo_rectangle_t *rects;
|
||||
cairo_rectangle_fixed_t *rects;
|
||||
cairo_status_t status;
|
||||
int i;
|
||||
|
||||
@ -1000,10 +1023,10 @@ _cairo_surface_fill_region (cairo_surface_t *surface,
|
||||
**/
|
||||
cairo_status_t
|
||||
_cairo_surface_fill_rectangles (cairo_surface_t *surface,
|
||||
cairo_operator_t op,
|
||||
cairo_operator_t op,
|
||||
const cairo_color_t *color,
|
||||
cairo_rectangle_t *rects,
|
||||
int num_rects)
|
||||
cairo_rectangle_fixed_t *rects,
|
||||
int num_rects)
|
||||
{
|
||||
cairo_int_status_t status;
|
||||
|
||||
@ -1081,7 +1104,7 @@ _cairo_surface_mask (cairo_surface_t *surface,
|
||||
FINISH:
|
||||
_cairo_pattern_fini (&dev_source.base);
|
||||
_cairo_pattern_fini (&dev_mask.base);
|
||||
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
@ -1529,8 +1552,8 @@ _cairo_surface_set_clip (cairo_surface_t *surface, cairo_clip_t *clip)
|
||||
*/
|
||||
|
||||
cairo_status_t
|
||||
_cairo_surface_get_extents (cairo_surface_t *surface,
|
||||
cairo_rectangle_t *rectangle)
|
||||
_cairo_surface_get_extents (cairo_surface_t *surface,
|
||||
cairo_rectangle_fixed_t *rectangle)
|
||||
{
|
||||
cairo_status_t status;
|
||||
|
||||
@ -1632,30 +1655,30 @@ _cairo_surface_old_show_glyphs (cairo_scaled_font_t *scaled_font,
|
||||
if (dst->finished)
|
||||
return CAIRO_STATUS_SURFACE_FINISHED;
|
||||
|
||||
if (dst->backend->old_show_glyphs)
|
||||
if (dst->backend->old_show_glyphs) {
|
||||
status = dst->backend->old_show_glyphs (scaled_font,
|
||||
op, pattern, dst,
|
||||
source_x, source_y,
|
||||
dest_x, dest_y,
|
||||
dest_x, dest_y,
|
||||
width, height,
|
||||
glyphs, num_glyphs);
|
||||
else
|
||||
} else
|
||||
status = CAIRO_INT_STATUS_UNSUPPORTED;
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
static cairo_status_t
|
||||
_cairo_surface_composite_fixup_unbounded_internal (cairo_surface_t *dst,
|
||||
cairo_rectangle_t *src_rectangle,
|
||||
cairo_rectangle_t *mask_rectangle,
|
||||
int dst_x,
|
||||
int dst_y,
|
||||
unsigned int width,
|
||||
unsigned int height)
|
||||
_cairo_surface_composite_fixup_unbounded_internal (cairo_surface_t *dst,
|
||||
cairo_rectangle_fixed_t *src_rectangle,
|
||||
cairo_rectangle_fixed_t *mask_rectangle,
|
||||
int dst_x,
|
||||
int dst_y,
|
||||
unsigned int width,
|
||||
unsigned int height)
|
||||
{
|
||||
cairo_rectangle_t dst_rectangle;
|
||||
cairo_rectangle_t drawn_rectangle;
|
||||
cairo_rectangle_fixed_t dst_rectangle;
|
||||
cairo_rectangle_fixed_t drawn_rectangle;
|
||||
pixman_region16_t *drawn_region;
|
||||
pixman_region16_t *clear_region;
|
||||
cairo_status_t status = CAIRO_STATUS_SUCCESS;
|
||||
@ -1744,12 +1767,12 @@ _cairo_surface_composite_fixup_unbounded (cairo_surface_t *dst,
|
||||
unsigned int width,
|
||||
unsigned int height)
|
||||
{
|
||||
cairo_rectangle_t src_tmp, mask_tmp;
|
||||
cairo_rectangle_t *src_rectangle = NULL;
|
||||
cairo_rectangle_t *mask_rectangle = NULL;
|
||||
cairo_rectangle_fixed_t src_tmp, mask_tmp;
|
||||
cairo_rectangle_fixed_t *src_rectangle = NULL;
|
||||
cairo_rectangle_fixed_t *mask_rectangle = NULL;
|
||||
|
||||
assert (! dst->is_snapshot);
|
||||
|
||||
|
||||
/* The RENDER/libpixman operators are clipped to the bounds of the untransformed,
|
||||
* non-repeating sources and masks. Other sources and masks can be ignored.
|
||||
*/
|
||||
@ -1819,12 +1842,12 @@ _cairo_surface_composite_shape_fixup_unbounded (cairo_surface_t *dst,
|
||||
unsigned int width,
|
||||
unsigned int height)
|
||||
{
|
||||
cairo_rectangle_t src_tmp, mask_tmp;
|
||||
cairo_rectangle_t *src_rectangle = NULL;
|
||||
cairo_rectangle_t *mask_rectangle = NULL;
|
||||
cairo_rectangle_fixed_t src_tmp, mask_tmp;
|
||||
cairo_rectangle_fixed_t *src_rectangle = NULL;
|
||||
cairo_rectangle_fixed_t *mask_rectangle = NULL;
|
||||
|
||||
assert (! dst->is_snapshot);
|
||||
|
||||
|
||||
/* The RENDER/libpixman operators are clipped to the bounds of the untransformed,
|
||||
* non-repeating sources and masks. Other sources and masks can be ignored.
|
||||
*/
|
||||
@ -1850,6 +1873,42 @@ _cairo_surface_composite_shape_fixup_unbounded (cairo_surface_t *dst,
|
||||
dst_x, dst_y, width, height);
|
||||
}
|
||||
|
||||
static cairo_bool_t
|
||||
_format_is_opaque (cairo_format_t format)
|
||||
{
|
||||
switch (format) {
|
||||
case CAIRO_FORMAT_ARGB32:
|
||||
return FALSE;
|
||||
case CAIRO_FORMAT_RGB24:
|
||||
return TRUE;
|
||||
case CAIRO_FORMAT_A8:
|
||||
return FALSE;
|
||||
case CAIRO_FORMAT_A1:
|
||||
return TRUE;
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* XXX: This function is funny in a couple of ways. First it seems to
|
||||
* be computing something like "not translucent" rather than "opaque"
|
||||
* since it returns TRUE for an A1 image surface. Second, it just
|
||||
* gives up on anything other than an image surface.
|
||||
*
|
||||
* I imagine something that might be more useful here (or in addition)
|
||||
* would be cairo_surface_get_content.
|
||||
*/
|
||||
cairo_bool_t
|
||||
_cairo_surface_is_opaque (const cairo_surface_t *surface)
|
||||
{
|
||||
if (_cairo_surface_is_image (surface)) {
|
||||
const cairo_image_surface_t *image_surface = (cairo_image_surface_t *) surface;
|
||||
|
||||
return _format_is_opaque (image_surface->format);
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/**
|
||||
* _cairo_surface_copy_pattern_for_destination
|
||||
* @pattern: the pattern to copy
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@ -38,22 +38,39 @@
|
||||
|
||||
CAIRO_BEGIN_DECLS
|
||||
|
||||
cairo_surface_t *
|
||||
typedef enum {
|
||||
CAIRO_SVG_VERSION_1_1 = 0,
|
||||
CAIRO_SVG_VERSION_1_2,
|
||||
CAIRO_SVG_VERSION_LAST
|
||||
} cairo_svg_version_t;
|
||||
|
||||
cairo_public cairo_surface_t *
|
||||
cairo_svg_surface_create (const char *filename,
|
||||
double width_in_points,
|
||||
double height_in_points);
|
||||
|
||||
cairo_surface_t *
|
||||
cairo_public cairo_surface_t *
|
||||
cairo_svg_surface_create_for_stream (cairo_write_func_t write_func,
|
||||
void *closure,
|
||||
double width_in_points,
|
||||
double height_in_points);
|
||||
|
||||
void
|
||||
cairo_public void
|
||||
cairo_svg_surface_set_dpi (cairo_surface_t *surface,
|
||||
double x_dpi,
|
||||
double y_dpi);
|
||||
|
||||
cairo_public void
|
||||
cairo_svg_surface_restrict_to_version (cairo_surface_t *surface,
|
||||
cairo_svg_version_t version);
|
||||
|
||||
cairo_public void
|
||||
cairo_svg_get_versions (cairo_svg_version_t const **versions,
|
||||
int *num_versions);
|
||||
|
||||
cairo_public const char *
|
||||
cairo_svg_version_to_string (cairo_svg_version_t version);
|
||||
|
||||
CAIRO_END_DECLS
|
||||
|
||||
#else /* CAIRO_HAS_SVG_SURFACE */
|
||||
|
||||
@ -39,6 +39,13 @@
|
||||
#include <cairo-win32.h>
|
||||
#include <cairoint.h>
|
||||
|
||||
#ifndef SHADEBLENDCAPS
|
||||
#define SHADEBLENDCAPS 120
|
||||
#endif
|
||||
#ifndef SB_NONE
|
||||
#define SB_NONE 0
|
||||
#endif
|
||||
|
||||
#define WIN32_FONT_LOGICAL_SCALE 32
|
||||
|
||||
typedef struct _cairo_win32_surface {
|
||||
@ -62,13 +69,31 @@ typedef struct _cairo_win32_surface {
|
||||
|
||||
cairo_surface_t *image;
|
||||
|
||||
cairo_rectangle_t clip_rect;
|
||||
cairo_rectangle_fixed_t clip_rect;
|
||||
|
||||
HRGN saved_clip;
|
||||
|
||||
cairo_rectangle_t extents;
|
||||
cairo_rectangle_fixed_t extents;
|
||||
|
||||
/* Surface DC flags */
|
||||
uint32_t flags;
|
||||
} cairo_win32_surface_t;
|
||||
|
||||
/* Surface DC flag values */
|
||||
enum {
|
||||
/* Whether the DC is a display DC or not */
|
||||
CAIRO_WIN32_SURFACE_FLAG_IS_DISPLAY = (1<<1),
|
||||
|
||||
/* Whether we can use BitBlt with this surface */
|
||||
CAIRO_WIN32_SURFACE_CAN_BITBLT = (1<<2),
|
||||
|
||||
/* Whether we can use AlphaBlend with this surface */
|
||||
CAIRO_WIN32_SURFACE_CAN_ALPHABLEND = (1<<3),
|
||||
|
||||
/* Whether we can use StretchBlt with this surface */
|
||||
CAIRO_WIN32_SURFACE_CAN_STRETCHBLT = (1<<4)
|
||||
};
|
||||
|
||||
cairo_status_t
|
||||
_cairo_win32_print_gdi_error (const char *context);
|
||||
|
||||
|
||||
@ -301,7 +301,8 @@ _cairo_win32_surface_create_for_dc (HDC original_dc,
|
||||
|
||||
surface->extents = surface->clip_rect;
|
||||
|
||||
_cairo_surface_init (&surface->base, &cairo_win32_surface_backend);
|
||||
_cairo_surface_init (&surface->base, &cairo_win32_surface_backend,
|
||||
_cairo_content_from_format (format));
|
||||
|
||||
return (cairo_surface_t *)surface;
|
||||
|
||||
@ -448,9 +449,9 @@ _cairo_win32_surface_release_source_image (void *abstract_surf
|
||||
|
||||
static cairo_status_t
|
||||
_cairo_win32_surface_acquire_dest_image (void *abstract_surface,
|
||||
cairo_rectangle_t *interest_rect,
|
||||
cairo_rectangle_fixed_t *interest_rect,
|
||||
cairo_image_surface_t **image_out,
|
||||
cairo_rectangle_t *image_rect,
|
||||
cairo_rectangle_fixed_t *image_rect,
|
||||
void **image_extra)
|
||||
{
|
||||
cairo_win32_surface_t *surface = abstract_surface;
|
||||
@ -515,11 +516,11 @@ _cairo_win32_surface_acquire_dest_image (void *abstract_surfa
|
||||
}
|
||||
|
||||
static void
|
||||
_cairo_win32_surface_release_dest_image (void *abstract_surface,
|
||||
cairo_rectangle_t *interest_rect,
|
||||
cairo_image_surface_t *image,
|
||||
cairo_rectangle_t *image_rect,
|
||||
void *image_extra)
|
||||
_cairo_win32_surface_release_dest_image (void *abstract_surface,
|
||||
cairo_rectangle_fixed_t *interest_rect,
|
||||
cairo_image_surface_t *image,
|
||||
cairo_rectangle_fixed_t *image_rect,
|
||||
void *image_extra)
|
||||
{
|
||||
cairo_win32_surface_t *surface = abstract_surface;
|
||||
cairo_win32_surface_t *local = image_extra;
|
||||
@ -811,7 +812,7 @@ static cairo_int_status_t
|
||||
_cairo_win32_surface_fill_rectangles (void *abstract_surface,
|
||||
cairo_operator_t op,
|
||||
const cairo_color_t *color,
|
||||
cairo_rectangle_t *rects,
|
||||
cairo_rectangle_fixed_t *rects,
|
||||
int num_rects)
|
||||
{
|
||||
cairo_win32_surface_t *surface = abstract_surface;
|
||||
@ -963,8 +964,8 @@ _cairo_win32_surface_set_clip_region (void *abstract_surface,
|
||||
}
|
||||
|
||||
static cairo_int_status_t
|
||||
_cairo_win32_surface_get_extents (void *abstract_surface,
|
||||
cairo_rectangle_t *rectangle)
|
||||
_cairo_win32_surface_get_extents (void *abstract_surface,
|
||||
cairo_rectangle_fixed_t *rectangle)
|
||||
{
|
||||
cairo_win32_surface_t *surface = abstract_surface;
|
||||
|
||||
@ -1184,7 +1185,8 @@ cairo_win32_surface_create (HDC hdc)
|
||||
|
||||
surface->extents = surface->clip_rect;
|
||||
|
||||
_cairo_surface_init (&surface->base, &cairo_win32_surface_backend);
|
||||
_cairo_surface_init (&surface->base, &cairo_win32_surface_backend,
|
||||
_cairo_content_from_format (format));
|
||||
|
||||
return (cairo_surface_t *)surface;
|
||||
}
|
||||
|
||||
@ -66,6 +66,32 @@ format_from_visual(XCBConnection *c, XCBVISUALID visual)
|
||||
return nil;
|
||||
}
|
||||
|
||||
static cairo_content_t
|
||||
_xcb_render_format_to_content (XCBRenderPICTFORMINFO *xrender_format)
|
||||
{
|
||||
cairo_bool_t xrender_format_has_alpha;
|
||||
cairo_bool_t xrender_format_has_color;
|
||||
|
||||
/* This only happens when using a non-Render server. Let's punt
|
||||
* and say there's no alpha here. */
|
||||
if (xrender_format == NULL)
|
||||
return CAIRO_CONTENT_COLOR;
|
||||
|
||||
xrender_format_has_alpha = (xrender_format->direct.alpha_mask != 0);
|
||||
xrender_format_has_color = (xrender_format->direct.red_mask != 0 ||
|
||||
xrender_format->direct.green_mask != 0 ||
|
||||
xrender_format->direct.blue_mask != 0);
|
||||
|
||||
if (xrender_format_has_alpha)
|
||||
if (xrender_format_has_color)
|
||||
return CAIRO_CONTENT_COLOR_ALPHA;
|
||||
else
|
||||
return CAIRO_CONTENT_ALPHA;
|
||||
else
|
||||
return CAIRO_CONTENT_COLOR;
|
||||
|
||||
}
|
||||
|
||||
/* XXX: Why is this ridiculously complex compared to the equivalent
|
||||
* function in cairo-xlib-surface.c */
|
||||
static XCBRenderPICTFORMINFO
|
||||
@ -287,8 +313,8 @@ _cairo_xcb_surface_finish (void *abstract_surface)
|
||||
static int
|
||||
_bits_per_pixel(XCBConnection *c, int depth)
|
||||
{
|
||||
XCBFORMAT *fmt = XCBConnSetupSuccessRepPixmapFormats(XCBGetSetup(c));
|
||||
XCBFORMAT *fmtend = fmt + XCBConnSetupSuccessRepPixmapFormatsLength(XCBGetSetup(c));
|
||||
XCBFORMAT *fmt = XCBSetupPixmapFormats(XCBGetSetup(c));
|
||||
XCBFORMAT *fmtend = fmt + XCBSetupPixmapFormatsLength(XCBGetSetup(c));
|
||||
|
||||
for(; fmt != fmtend; ++fmt)
|
||||
if(fmt->depth == depth)
|
||||
@ -351,10 +377,10 @@ _CAIRO_MASK_FORMAT (cairo_format_masks_t *masks, cairo_format_t *format)
|
||||
}
|
||||
|
||||
static cairo_status_t
|
||||
_get_image_surface (cairo_xcb_surface_t *surface,
|
||||
cairo_rectangle_t *interest_rect,
|
||||
cairo_image_surface_t **image_out,
|
||||
cairo_rectangle_t *image_rect)
|
||||
_get_image_surface (cairo_xcb_surface_t *surface,
|
||||
cairo_rectangle_fixed_t *interest_rect,
|
||||
cairo_image_surface_t **image_out,
|
||||
cairo_rectangle_fixed_t *image_rect)
|
||||
{
|
||||
cairo_image_surface_t *image;
|
||||
XCBGetImageRep *imagerep;
|
||||
@ -370,7 +396,7 @@ _get_image_surface (cairo_xcb_surface_t *surface,
|
||||
y2 = surface->height;
|
||||
|
||||
if (interest_rect) {
|
||||
cairo_rectangle_t rect;
|
||||
cairo_rectangle_fixed_t rect;
|
||||
|
||||
rect.x = interest_rect->x;
|
||||
rect.y = interest_rect->y;
|
||||
@ -405,7 +431,7 @@ _get_image_surface (cairo_xcb_surface_t *surface,
|
||||
{
|
||||
XCBGenericError *error;
|
||||
imagerep = XCBGetImageReply(surface->dpy,
|
||||
XCBGetImage(surface->dpy, ZPixmap,
|
||||
XCBGetImage(surface->dpy, XCBImageFormatZPixmap,
|
||||
surface->drawable,
|
||||
x1, y1,
|
||||
x2 - x1, y2 - y1,
|
||||
@ -444,7 +470,7 @@ _get_image_surface (cairo_xcb_surface_t *surface,
|
||||
x1, y1, 0, 0, x2 - x1, y2 - y1);
|
||||
|
||||
imagerep = XCBGetImageReply(surface->dpy,
|
||||
XCBGetImage(surface->dpy, ZPixmap,
|
||||
XCBGetImage(surface->dpy, XCBImageFormatZPixmap,
|
||||
drawable,
|
||||
x1, y1,
|
||||
x2 - x1, y2 - y1,
|
||||
@ -558,7 +584,7 @@ _draw_image_surface (cairo_xcb_surface_t *surface,
|
||||
_cairo_xcb_surface_ensure_gc (surface);
|
||||
bpp = _bits_per_pixel(surface->dpy, image->depth);
|
||||
data_len = _bytes_per_line(surface->dpy, image->width, bpp) * image->height;
|
||||
XCBPutImage(surface->dpy, ZPixmap, surface->drawable, surface->gc,
|
||||
XCBPutImage(surface->dpy, XCBImageFormatZPixmap, surface->drawable, surface->gc,
|
||||
image->width,
|
||||
image->height,
|
||||
dst_x, dst_y,
|
||||
@ -597,9 +623,9 @@ _cairo_xcb_surface_release_source_image (void *abstract_surfac
|
||||
|
||||
static cairo_status_t
|
||||
_cairo_xcb_surface_acquire_dest_image (void *abstract_surface,
|
||||
cairo_rectangle_t *interest_rect,
|
||||
cairo_rectangle_fixed_t *interest_rect,
|
||||
cairo_image_surface_t **image_out,
|
||||
cairo_rectangle_t *image_rect_out,
|
||||
cairo_rectangle_fixed_t *image_rect_out,
|
||||
void **image_extra)
|
||||
{
|
||||
cairo_xcb_surface_t *surface = abstract_surface;
|
||||
@ -618,9 +644,9 @@ _cairo_xcb_surface_acquire_dest_image (void *abstract_surface
|
||||
|
||||
static void
|
||||
_cairo_xcb_surface_release_dest_image (void *abstract_surface,
|
||||
cairo_rectangle_t *interest_rect,
|
||||
cairo_rectangle_fixed_t *interest_rect,
|
||||
cairo_image_surface_t *image,
|
||||
cairo_rectangle_t *image_rect,
|
||||
cairo_rectangle_fixed_t *image_rect,
|
||||
void *image_extra)
|
||||
{
|
||||
cairo_xcb_surface_t *surface = abstract_surface;
|
||||
@ -914,11 +940,11 @@ _cairo_xcb_surface_composite (cairo_operator_t op,
|
||||
}
|
||||
|
||||
static cairo_int_status_t
|
||||
_cairo_xcb_surface_fill_rectangles (void *abstract_surface,
|
||||
cairo_operator_t op,
|
||||
const cairo_color_t *color,
|
||||
cairo_rectangle_t *rects,
|
||||
int num_rects)
|
||||
_cairo_xcb_surface_fill_rectangles (void *abstract_surface,
|
||||
cairo_operator_t op,
|
||||
const cairo_color_t * color,
|
||||
cairo_rectangle_fixed_t *rects,
|
||||
int num_rects)
|
||||
{
|
||||
cairo_xcb_surface_t *surface = abstract_surface;
|
||||
XCBRenderCOLOR render_color;
|
||||
@ -1010,8 +1036,8 @@ _cairo_xcb_surface_composite_trapezoids (cairo_operator_t op,
|
||||
}
|
||||
|
||||
static cairo_int_status_t
|
||||
_cairo_xcb_surface_get_extents (void *abstract_surface,
|
||||
cairo_rectangle_t *rectangle)
|
||||
_cairo_xcb_surface_get_extents (void *abstract_surface,
|
||||
cairo_rectangle_fixed_t *rectangle)
|
||||
{
|
||||
cairo_xcb_surface_t *surface = abstract_surface;
|
||||
|
||||
@ -1100,7 +1126,8 @@ _cairo_xcb_surface_create_internal (XCBConnection *dpy,
|
||||
return (cairo_surface_t*) &_cairo_surface_nil;
|
||||
}
|
||||
|
||||
_cairo_surface_init (&surface->base, &cairo_xcb_surface_backend);
|
||||
_cairo_surface_init (&surface->base, &cairo_xcb_surface_backend,
|
||||
_xcb_render_format_to_content (format));
|
||||
|
||||
surface->dpy = dpy;
|
||||
|
||||
@ -1130,7 +1157,7 @@ _cairo_xcb_surface_create_internal (XCBConnection *dpy,
|
||||
/* This is ugly, but we have to walk over all visuals
|
||||
* for the display to find the depth.
|
||||
*/
|
||||
roots = XCBConnSetupSuccessRepRootsIter(XCBGetSetup(surface->dpy));
|
||||
roots = XCBSetupRootsIter(XCBGetSetup(surface->dpy));
|
||||
for(; roots.rem; XCBSCREENNext(&roots))
|
||||
{
|
||||
depths = XCBSCREENAllowedDepthsIter(roots.data);
|
||||
@ -1291,9 +1318,10 @@ cairo_xcb_surface_set_size (cairo_surface_t *surface,
|
||||
{
|
||||
cairo_xcb_surface_t *xcb_surface = (cairo_xcb_surface_t *)surface;
|
||||
|
||||
/* XXX: How do we want to handle this error case? */
|
||||
if (! _cairo_surface_is_xcb (surface))
|
||||
if (! _cairo_surface_is_xcb (surface)) {
|
||||
_cairo_surface_set_error (surface, CAIRO_STATUS_SURFACE_TYPE_MISMATCH);
|
||||
return;
|
||||
}
|
||||
|
||||
xcb_surface->width = width;
|
||||
xcb_surface->height = height;
|
||||
|
||||
@ -125,7 +125,7 @@ struct _cairo_xlib_surface {
|
||||
XRectangle *clip_rects;
|
||||
int num_clip_rects;
|
||||
|
||||
XRenderPictFormat *format;
|
||||
XRenderPictFormat *xrender_format;
|
||||
};
|
||||
|
||||
#define CAIRO_SURFACE_RENDER_AT_LEAST(surface, major, minor) \
|
||||
@ -154,7 +154,7 @@ struct _cairo_xlib_surface {
|
||||
static cairo_bool_t cairo_xlib_render_disabled = FALSE;
|
||||
|
||||
/**
|
||||
* cairo_test_xlib_disable_render:
|
||||
* cairo_xlib_test_disable_render:
|
||||
*
|
||||
* Disables the use of the RENDER extension.
|
||||
*
|
||||
@ -165,7 +165,7 @@ static cairo_bool_t cairo_xlib_render_disabled = FALSE;
|
||||
* </note>
|
||||
**/
|
||||
void
|
||||
cairo_test_xlib_disable_render (void)
|
||||
cairo_xlib_test_disable_render (void)
|
||||
{
|
||||
cairo_xlib_render_disabled = TRUE;
|
||||
}
|
||||
@ -187,7 +187,7 @@ _CAIRO_FORMAT_DEPTH (cairo_format_t format)
|
||||
}
|
||||
|
||||
static XRenderPictFormat *
|
||||
_CAIRO_FORMAT_XRENDER_FORMAT(Display *dpy, cairo_format_t format)
|
||||
_CAIRO_FORMAT_TO_XRENDER_FORMAT(Display *dpy, cairo_format_t format)
|
||||
{
|
||||
int pict_format;
|
||||
switch (format) {
|
||||
@ -215,11 +215,12 @@ _cairo_xlib_surface_create_similar_with_format (void *abstract_src,
|
||||
Pixmap pix;
|
||||
cairo_xlib_surface_t *surface;
|
||||
int depth = _CAIRO_FORMAT_DEPTH (format);
|
||||
XRenderPictFormat *xrender_format = _CAIRO_FORMAT_XRENDER_FORMAT (dpy,
|
||||
format);
|
||||
XRenderPictFormat *xrender_format = _CAIRO_FORMAT_TO_XRENDER_FORMAT (dpy,
|
||||
format);
|
||||
|
||||
/* As a good first approximation, if the display doesn't have COMPOSITE,
|
||||
* we're better off using image surfaces for all temporary operations
|
||||
/* As a good first approximation, if the display doesn't have even
|
||||
* the most elementary RENDER operation, then we're better off
|
||||
* using image surfaces for all temporary operations
|
||||
*/
|
||||
if (!CAIRO_SURFACE_RENDER_HAS_COMPOSITE(src)) {
|
||||
return cairo_image_surface_create (format, width, height);
|
||||
@ -243,6 +244,31 @@ _cairo_xlib_surface_create_similar_with_format (void *abstract_src,
|
||||
return &surface->base;
|
||||
}
|
||||
|
||||
static cairo_content_t
|
||||
_xrender_format_to_content (XRenderPictFormat *xrender_format)
|
||||
{
|
||||
cairo_bool_t xrender_format_has_alpha;
|
||||
cairo_bool_t xrender_format_has_color;
|
||||
|
||||
/* This only happens when using a non-Render server. Let's punt
|
||||
* and say there's no alpha here. */
|
||||
if (xrender_format == NULL)
|
||||
return CAIRO_CONTENT_COLOR;
|
||||
|
||||
xrender_format_has_alpha = (xrender_format->direct.alpha != 0);
|
||||
xrender_format_has_color = (xrender_format->direct.red != 0 ||
|
||||
xrender_format->direct.green != 0 ||
|
||||
xrender_format->direct.blue != 0);
|
||||
|
||||
if (xrender_format_has_alpha)
|
||||
if (xrender_format_has_color)
|
||||
return CAIRO_CONTENT_COLOR_ALPHA;
|
||||
else
|
||||
return CAIRO_CONTENT_ALPHA;
|
||||
else
|
||||
return CAIRO_CONTENT_COLOR;
|
||||
}
|
||||
|
||||
static cairo_bool_t
|
||||
_xrender_format_matches_content (XRenderPictFormat *format,
|
||||
cairo_content_t content)
|
||||
@ -486,10 +512,10 @@ _swap_ximage_to_native (XImage *ximage)
|
||||
}
|
||||
|
||||
static cairo_status_t
|
||||
_get_image_surface (cairo_xlib_surface_t *surface,
|
||||
cairo_rectangle_t *interest_rect,
|
||||
cairo_image_surface_t **image_out,
|
||||
cairo_rectangle_t *image_rect)
|
||||
_get_image_surface (cairo_xlib_surface_t *surface,
|
||||
cairo_rectangle_fixed_t *interest_rect,
|
||||
cairo_image_surface_t **image_out,
|
||||
cairo_rectangle_fixed_t *image_rect)
|
||||
{
|
||||
cairo_image_surface_t *image;
|
||||
XImage *ximage;
|
||||
@ -503,7 +529,7 @@ _get_image_surface (cairo_xlib_surface_t *surface,
|
||||
y2 = surface->height;
|
||||
|
||||
if (interest_rect) {
|
||||
cairo_rectangle_t rect;
|
||||
cairo_rectangle_fixed_t rect;
|
||||
|
||||
rect.x = interest_rect->x;
|
||||
rect.y = interest_rect->y;
|
||||
@ -604,12 +630,12 @@ _get_image_surface (cairo_xlib_surface_t *surface,
|
||||
masks.red_mask = surface->visual->red_mask;
|
||||
masks.green_mask = surface->visual->green_mask;
|
||||
masks.blue_mask = surface->visual->blue_mask;
|
||||
} else if (surface->format) {
|
||||
} else if (surface->xrender_format) {
|
||||
masks.bpp = ximage->bits_per_pixel;
|
||||
masks.red_mask = (unsigned long)surface->format->direct.redMask << surface->format->direct.red;
|
||||
masks.green_mask = (unsigned long)surface->format->direct.greenMask << surface->format->direct.green;
|
||||
masks.blue_mask = (unsigned long)surface->format->direct.blueMask << surface->format->direct.blue;
|
||||
masks.alpha_mask = (unsigned long)surface->format->direct.alphaMask << surface->format->direct.alpha;
|
||||
masks.red_mask = (unsigned long)surface->xrender_format->direct.redMask << surface->xrender_format->direct.red;
|
||||
masks.green_mask = (unsigned long)surface->xrender_format->direct.greenMask << surface->xrender_format->direct.green;
|
||||
masks.blue_mask = (unsigned long)surface->xrender_format->direct.blueMask << surface->xrender_format->direct.blue;
|
||||
masks.alpha_mask = (unsigned long)surface->xrender_format->direct.alphaMask << surface->xrender_format->direct.alpha;
|
||||
} else {
|
||||
masks.bpp = ximage->bits_per_pixel;
|
||||
masks.red_mask = 0;
|
||||
@ -673,7 +699,7 @@ _cairo_xlib_surface_ensure_src_picture (cairo_xlib_surface_t *surface)
|
||||
if (!surface->src_picture)
|
||||
surface->src_picture = XRenderCreatePicture (surface->dpy,
|
||||
surface->drawable,
|
||||
surface->format,
|
||||
surface->xrender_format,
|
||||
0, NULL);
|
||||
}
|
||||
|
||||
@ -703,7 +729,7 @@ _cairo_xlib_surface_ensure_dst_picture (cairo_xlib_surface_t *surface)
|
||||
if (!surface->dst_picture) {
|
||||
surface->dst_picture = XRenderCreatePicture (surface->dpy,
|
||||
surface->drawable,
|
||||
surface->format,
|
||||
surface->xrender_format,
|
||||
0, NULL);
|
||||
_cairo_xlib_surface_set_picture_clip_rects (surface);
|
||||
}
|
||||
@ -793,9 +819,9 @@ _cairo_xlib_surface_release_source_image (void *abstract_surfa
|
||||
|
||||
static cairo_status_t
|
||||
_cairo_xlib_surface_acquire_dest_image (void *abstract_surface,
|
||||
cairo_rectangle_t *interest_rect,
|
||||
cairo_rectangle_fixed_t *interest_rect,
|
||||
cairo_image_surface_t **image_out,
|
||||
cairo_rectangle_t *image_rect_out,
|
||||
cairo_rectangle_fixed_t *image_rect_out,
|
||||
void **image_extra)
|
||||
{
|
||||
cairo_xlib_surface_t *surface = abstract_surface;
|
||||
@ -813,11 +839,11 @@ _cairo_xlib_surface_acquire_dest_image (void *abstract_surfac
|
||||
}
|
||||
|
||||
static void
|
||||
_cairo_xlib_surface_release_dest_image (void *abstract_surface,
|
||||
cairo_rectangle_t *interest_rect,
|
||||
cairo_image_surface_t *image,
|
||||
cairo_rectangle_t *image_rect,
|
||||
void *image_extra)
|
||||
_cairo_xlib_surface_release_dest_image (void *abstract_surface,
|
||||
cairo_rectangle_fixed_t *interest_rect,
|
||||
cairo_image_surface_t *image,
|
||||
cairo_rectangle_fixed_t *image_rect,
|
||||
void *image_extra)
|
||||
{
|
||||
cairo_xlib_surface_t *surface = abstract_surface;
|
||||
|
||||
@ -1023,7 +1049,7 @@ _surfaces_compatible (cairo_xlib_surface_t *dst,
|
||||
return FALSE;
|
||||
|
||||
/* if Render is supported, match picture formats */
|
||||
if (src->format != NULL && src->format == dst->format)
|
||||
if (src->xrender_format != NULL && src->xrender_format == dst->xrender_format)
|
||||
return TRUE;
|
||||
|
||||
/* Without Render, match visuals instead */
|
||||
@ -1036,9 +1062,9 @@ _surfaces_compatible (cairo_xlib_surface_t *dst,
|
||||
static cairo_bool_t
|
||||
_surface_has_alpha (cairo_xlib_surface_t *surface)
|
||||
{
|
||||
if (surface->format) {
|
||||
if (surface->format->type == PictTypeDirect &&
|
||||
surface->format->direct.alphaMask != 0)
|
||||
if (surface->xrender_format) {
|
||||
if (surface->xrender_format->type == PictTypeDirect &&
|
||||
surface->xrender_format->direct.alphaMask != 0)
|
||||
return TRUE;
|
||||
else
|
||||
return FALSE;
|
||||
@ -1381,11 +1407,11 @@ _cairo_xlib_surface_composite (cairo_operator_t op,
|
||||
}
|
||||
|
||||
static cairo_int_status_t
|
||||
_cairo_xlib_surface_fill_rectangles (void *abstract_surface,
|
||||
cairo_operator_t op,
|
||||
const cairo_color_t *color,
|
||||
cairo_rectangle_t *rects,
|
||||
int num_rects)
|
||||
_cairo_xlib_surface_fill_rectangles (void *abstract_surface,
|
||||
cairo_operator_t op,
|
||||
const cairo_color_t *color,
|
||||
cairo_rectangle_fixed_t *rects,
|
||||
int num_rects)
|
||||
{
|
||||
cairo_xlib_surface_t *surface = abstract_surface;
|
||||
XRenderColor render_color;
|
||||
@ -1641,7 +1667,7 @@ _cairo_xlib_surface_set_clip_region (void *abstract_surface,
|
||||
if (surface->gc)
|
||||
XSetClipMask (surface->dpy, surface->gc, None);
|
||||
|
||||
if (surface->format && surface->dst_picture) {
|
||||
if (surface->xrender_format && surface->dst_picture) {
|
||||
XRenderPictureAttributes pa;
|
||||
pa.clip_mask = None;
|
||||
XRenderChangePicture (surface->dpy, surface->dst_picture,
|
||||
@ -1685,8 +1711,8 @@ _cairo_xlib_surface_set_clip_region (void *abstract_surface,
|
||||
}
|
||||
|
||||
static cairo_int_status_t
|
||||
_cairo_xlib_surface_get_extents (void *abstract_surface,
|
||||
cairo_rectangle_t *rectangle)
|
||||
_cairo_xlib_surface_get_extents (void *abstract_surface,
|
||||
cairo_rectangle_fixed_t *rectangle)
|
||||
{
|
||||
cairo_xlib_surface_t *surface = abstract_surface;
|
||||
|
||||
@ -1708,6 +1734,14 @@ _cairo_xlib_surface_get_font_options (void *abstract_surface,
|
||||
*options = surface->screen_info->font_options;
|
||||
}
|
||||
|
||||
static cairo_status_t
|
||||
_cairo_xlib_surface_flush (void *abstract_surface)
|
||||
{
|
||||
cairo_xlib_surface_t *surface = abstract_surface;
|
||||
XSync (surface->dpy, False);
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
static void
|
||||
_cairo_xlib_surface_scaled_font_fini (cairo_scaled_font_t *scaled_font);
|
||||
|
||||
@ -1734,7 +1768,7 @@ static const cairo_surface_backend_t cairo_xlib_surface_backend = {
|
||||
_cairo_xlib_surface_get_extents,
|
||||
NULL, /* old_show_glyphs */
|
||||
_cairo_xlib_surface_get_font_options,
|
||||
NULL, /* flush */
|
||||
_cairo_xlib_surface_flush,
|
||||
NULL, /* mark_dirty_rectangle */
|
||||
_cairo_xlib_surface_scaled_font_fini,
|
||||
_cairo_xlib_surface_scaled_glyph_fini,
|
||||
@ -1766,7 +1800,7 @@ _cairo_xlib_surface_create_internal (Display *dpy,
|
||||
Drawable drawable,
|
||||
Screen *screen,
|
||||
Visual *visual,
|
||||
XRenderPictFormat *format,
|
||||
XRenderPictFormat *xrender_format,
|
||||
int width,
|
||||
int height,
|
||||
int depth)
|
||||
@ -1786,21 +1820,8 @@ _cairo_xlib_surface_create_internal (Display *dpy,
|
||||
return (cairo_surface_t*) &_cairo_surface_nil;
|
||||
}
|
||||
|
||||
_cairo_surface_init (&surface->base, &cairo_xlib_surface_backend);
|
||||
|
||||
surface->dpy = dpy;
|
||||
surface->screen_info = screen_info;
|
||||
|
||||
surface->gc = NULL;
|
||||
surface->drawable = drawable;
|
||||
surface->screen = screen;
|
||||
surface->owns_pixmap = FALSE;
|
||||
surface->use_pixmap = 0;
|
||||
surface->width = width;
|
||||
surface->height = height;
|
||||
|
||||
if (format) {
|
||||
depth = format->depth;
|
||||
if (xrender_format) {
|
||||
depth = xrender_format->depth;
|
||||
} else if (visual) {
|
||||
int j, k;
|
||||
|
||||
@ -1826,6 +1847,31 @@ _cairo_xlib_surface_create_internal (Display *dpy,
|
||||
surface->render_minor = -1;
|
||||
}
|
||||
|
||||
if (CAIRO_SURFACE_RENDER_HAS_CREATE_PICTURE (surface)) {
|
||||
if (!xrender_format) {
|
||||
if (visual)
|
||||
xrender_format = XRenderFindVisualFormat (dpy, visual);
|
||||
else if (depth == 1)
|
||||
xrender_format = XRenderFindStandardFormat (dpy, PictStandardA1);
|
||||
}
|
||||
} else {
|
||||
xrender_format = NULL;
|
||||
}
|
||||
|
||||
_cairo_surface_init (&surface->base, &cairo_xlib_surface_backend,
|
||||
_xrender_format_to_content (xrender_format));
|
||||
|
||||
surface->dpy = dpy;
|
||||
surface->screen_info = screen_info;
|
||||
|
||||
surface->gc = NULL;
|
||||
surface->drawable = drawable;
|
||||
surface->screen = screen;
|
||||
surface->owns_pixmap = FALSE;
|
||||
surface->use_pixmap = 0;
|
||||
surface->width = width;
|
||||
surface->height = height;
|
||||
|
||||
surface->buggy_repeat = FALSE;
|
||||
if (strstr (ServerVendor (dpy), "X.Org") != NULL) {
|
||||
if (VendorRelease (dpy) <= 60802000)
|
||||
@ -1838,19 +1884,8 @@ _cairo_xlib_surface_create_internal (Display *dpy,
|
||||
surface->dst_picture = None;
|
||||
surface->src_picture = None;
|
||||
|
||||
if (CAIRO_SURFACE_RENDER_HAS_CREATE_PICTURE (surface)) {
|
||||
if (!format) {
|
||||
if (visual)
|
||||
format = XRenderFindVisualFormat (dpy, visual);
|
||||
else if (depth == 1)
|
||||
format = XRenderFindStandardFormat (dpy, PictStandardA1);
|
||||
}
|
||||
} else {
|
||||
format = NULL;
|
||||
}
|
||||
|
||||
surface->visual = visual;
|
||||
surface->format = format;
|
||||
surface->xrender_format = xrender_format;
|
||||
surface->depth = depth;
|
||||
|
||||
surface->have_clip_rects = FALSE;
|
||||
@ -1994,18 +2029,20 @@ cairo_xlib_surface_create_with_xrender_format (Display *dpy,
|
||||
* this function on a surface created for a Pixmap.
|
||||
**/
|
||||
void
|
||||
cairo_xlib_surface_set_size (cairo_surface_t *surface,
|
||||
cairo_xlib_surface_set_size (cairo_surface_t *abstract_surface,
|
||||
int width,
|
||||
int height)
|
||||
{
|
||||
cairo_xlib_surface_t *xlib_surface = (cairo_xlib_surface_t *)surface;
|
||||
cairo_xlib_surface_t *surface = (cairo_xlib_surface_t *) abstract_surface;
|
||||
|
||||
/* XXX: How do we want to handle this error case? */
|
||||
if (! _cairo_surface_is_xlib (surface))
|
||||
if (! _cairo_surface_is_xlib (abstract_surface)) {
|
||||
_cairo_surface_set_error (abstract_surface,
|
||||
CAIRO_STATUS_SURFACE_TYPE_MISMATCH);
|
||||
return;
|
||||
}
|
||||
|
||||
xlib_surface->width = width;
|
||||
xlib_surface->height = height;
|
||||
surface->width = width;
|
||||
surface->height = height;
|
||||
}
|
||||
/**
|
||||
* cairo_xlib_surface_set_drawable:
|
||||
@ -2029,9 +2066,10 @@ cairo_xlib_surface_set_drawable (cairo_surface_t *abstract_surface,
|
||||
{
|
||||
cairo_xlib_surface_t *surface = (cairo_xlib_surface_t *)abstract_surface;
|
||||
|
||||
/* XXX: How do we want to handle this error case? */
|
||||
if (! _cairo_surface_is_xlib (abstract_surface))
|
||||
if (! _cairo_surface_is_xlib (abstract_surface)) {
|
||||
_cairo_surface_set_error (abstract_surface, CAIRO_STATUS_SURFACE_TYPE_MISMATCH);
|
||||
return;
|
||||
}
|
||||
|
||||
/* XXX: and what about this case? */
|
||||
if (surface->owns_pixmap)
|
||||
@ -2053,44 +2091,41 @@ cairo_xlib_surface_set_drawable (cairo_surface_t *abstract_surface,
|
||||
surface->height = height;
|
||||
}
|
||||
|
||||
static cairo_bool_t _is_valid_xlib_surface (cairo_surface_t *abstract_surface)
|
||||
Display *
|
||||
cairo_xlib_surface_get_display (cairo_surface_t *abstract_surface)
|
||||
{
|
||||
return _cairo_surface_is_xlib (abstract_surface) &&
|
||||
abstract_surface->status == CAIRO_STATUS_SUCCESS;
|
||||
cairo_xlib_surface_t *surface = (cairo_xlib_surface_t *) abstract_surface;
|
||||
|
||||
if (! _cairo_surface_is_xlib (abstract_surface)) {
|
||||
_cairo_error (CAIRO_STATUS_SURFACE_TYPE_MISMATCH);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return surface->dpy;
|
||||
}
|
||||
|
||||
Drawable
|
||||
cairo_xlib_surface_get_drawable (cairo_surface_t *abstract_surface)
|
||||
{
|
||||
cairo_xlib_surface_t *surface = (cairo_xlib_surface_t *)abstract_surface;
|
||||
cairo_xlib_surface_t *surface = (cairo_xlib_surface_t *) abstract_surface;
|
||||
|
||||
/* XXX: How do we want to handle this error case? */
|
||||
if (! _is_valid_xlib_surface (abstract_surface))
|
||||
return 0;
|
||||
if (! _cairo_surface_is_xlib (abstract_surface)) {
|
||||
_cairo_error (CAIRO_STATUS_SURFACE_TYPE_MISMATCH);
|
||||
return 0;
|
||||
}
|
||||
|
||||
return surface->drawable;
|
||||
}
|
||||
|
||||
Display *
|
||||
cairo_xlib_surface_get_display (cairo_surface_t *abstract_surface)
|
||||
{
|
||||
cairo_xlib_surface_t *surface = (cairo_xlib_surface_t *)abstract_surface;
|
||||
|
||||
/* XXX: How do we want to handle this error case? */
|
||||
if (! _is_valid_xlib_surface (abstract_surface))
|
||||
return NULL;
|
||||
|
||||
return surface->dpy;
|
||||
}
|
||||
|
||||
Screen *
|
||||
cairo_xlib_surface_get_screen (cairo_surface_t *abstract_surface)
|
||||
{
|
||||
cairo_xlib_surface_t *surface = (cairo_xlib_surface_t *)abstract_surface;
|
||||
cairo_xlib_surface_t *surface = (cairo_xlib_surface_t *) abstract_surface;
|
||||
|
||||
/* XXX: How do we want to handle this error case? */
|
||||
if (! _is_valid_xlib_surface (abstract_surface))
|
||||
return NULL;
|
||||
if (! _cairo_surface_is_xlib (abstract_surface)) {
|
||||
_cairo_error (CAIRO_STATUS_SURFACE_TYPE_MISMATCH);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return surface->screen;
|
||||
}
|
||||
@ -2098,11 +2133,12 @@ cairo_xlib_surface_get_screen (cairo_surface_t *abstract_surface)
|
||||
Visual *
|
||||
cairo_xlib_surface_get_visual (cairo_surface_t *abstract_surface)
|
||||
{
|
||||
cairo_xlib_surface_t *surface = (cairo_xlib_surface_t *)abstract_surface;
|
||||
cairo_xlib_surface_t *surface = (cairo_xlib_surface_t *) abstract_surface;
|
||||
|
||||
/* XXX: How do we want to handle this error case? */
|
||||
if (! _is_valid_xlib_surface (abstract_surface))
|
||||
return NULL;
|
||||
if (! _cairo_surface_is_xlib (abstract_surface)) {
|
||||
_cairo_error (CAIRO_STATUS_SURFACE_TYPE_MISMATCH);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return surface->visual;
|
||||
}
|
||||
@ -2110,11 +2146,12 @@ cairo_xlib_surface_get_visual (cairo_surface_t *abstract_surface)
|
||||
int
|
||||
cairo_xlib_surface_get_depth (cairo_surface_t *abstract_surface)
|
||||
{
|
||||
cairo_xlib_surface_t *surface = (cairo_xlib_surface_t *)abstract_surface;
|
||||
cairo_xlib_surface_t *surface = (cairo_xlib_surface_t *) abstract_surface;
|
||||
|
||||
/* XXX: How do we want to handle this error case? */
|
||||
if (! _is_valid_xlib_surface (abstract_surface))
|
||||
return -1;
|
||||
if (! _cairo_surface_is_xlib (abstract_surface)) {
|
||||
_cairo_error (CAIRO_STATUS_SURFACE_TYPE_MISMATCH);
|
||||
return 0;
|
||||
}
|
||||
|
||||
return surface->depth;
|
||||
}
|
||||
@ -2122,7 +2159,8 @@ cairo_xlib_surface_get_depth (cairo_surface_t *abstract_surface)
|
||||
typedef struct _cairo_xlib_surface_font_private {
|
||||
Display *dpy;
|
||||
GlyphSet glyphset;
|
||||
XRenderPictFormat *format;
|
||||
cairo_format_t format;
|
||||
XRenderPictFormat *xrender_format;
|
||||
} cairo_xlib_surface_font_private_t;
|
||||
|
||||
static cairo_status_t
|
||||
@ -2137,8 +2175,9 @@ _cairo_xlib_surface_font_init (Display *dpy,
|
||||
return CAIRO_STATUS_NO_MEMORY;
|
||||
|
||||
font_private->dpy = dpy;
|
||||
font_private->format = _CAIRO_FORMAT_XRENDER_FORMAT(dpy, format);
|
||||
font_private->glyphset = XRenderCreateGlyphSet (dpy, font_private->format);
|
||||
font_private->format = format;
|
||||
font_private->xrender_format = _CAIRO_FORMAT_TO_XRENDER_FORMAT(dpy, format);
|
||||
font_private->glyphset = XRenderCreateGlyphSet (dpy, font_private->xrender_format);
|
||||
scaled_font->surface_private = font_private;
|
||||
scaled_font->surface_backend = &cairo_xlib_surface_backend;
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
@ -2185,7 +2224,7 @@ _cairo_xlib_surface_add_glyph (Display *dpy,
|
||||
XGlyphInfo glyph_info;
|
||||
unsigned long glyph_index;
|
||||
unsigned char *data;
|
||||
cairo_status_t status;
|
||||
cairo_status_t status = CAIRO_STATUS_SUCCESS;
|
||||
cairo_xlib_surface_font_private_t *font_private;
|
||||
cairo_image_surface_t *glyph_surface = scaled_glyph->surface;
|
||||
|
||||
@ -2197,6 +2236,32 @@ _cairo_xlib_surface_add_glyph (Display *dpy,
|
||||
}
|
||||
font_private = scaled_font->surface_private;
|
||||
|
||||
/* If the glyph format does not match the font format, then we
|
||||
* create a temporary surface for the glyph image with the font's
|
||||
* format.
|
||||
*/
|
||||
if (glyph_surface->format != font_private->format) {
|
||||
cairo_t *cr;
|
||||
cairo_surface_t *tmp_surface;
|
||||
|
||||
tmp_surface = cairo_image_surface_create (font_private->format,
|
||||
glyph_surface->width,
|
||||
glyph_surface->height);
|
||||
cr = cairo_create (tmp_surface);
|
||||
cairo_set_source_surface (cr, &glyph_surface->base, 0, 0);
|
||||
cairo_set_operator (cr, CAIRO_OPERATOR_SOURCE);
|
||||
cairo_paint (cr);
|
||||
|
||||
status = cairo_status (cr);
|
||||
|
||||
cairo_destroy (cr);
|
||||
|
||||
glyph_surface = (cairo_image_surface_t *) tmp_surface;
|
||||
|
||||
if (status)
|
||||
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
|
||||
@ -2252,8 +2317,10 @@ _cairo_xlib_surface_add_glyph (Display *dpy,
|
||||
unsigned char *new, *n;
|
||||
|
||||
new = malloc (c);
|
||||
if (!new)
|
||||
return CAIRO_STATUS_NO_MEMORY;
|
||||
if (!new) {
|
||||
status = CAIRO_STATUS_NO_MEMORY;
|
||||
goto BAIL;
|
||||
}
|
||||
n = new;
|
||||
d = data;
|
||||
while (c--)
|
||||
@ -2276,8 +2343,10 @@ _cairo_xlib_surface_add_glyph (Display *dpy,
|
||||
unsigned char *new, *n;
|
||||
|
||||
new = malloc (c);
|
||||
if (new == NULL)
|
||||
return CAIRO_STATUS_NO_MEMORY;
|
||||
if (new == NULL) {
|
||||
status = CAIRO_STATUS_NO_MEMORY;
|
||||
goto BAIL;
|
||||
}
|
||||
n = new;
|
||||
d = data;
|
||||
while ((c -= 4) >= 0)
|
||||
@ -2309,7 +2378,11 @@ _cairo_xlib_surface_add_glyph (Display *dpy,
|
||||
if (data != glyph_surface->data)
|
||||
free (data);
|
||||
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
BAIL:
|
||||
if (glyph_surface != scaled_glyph->surface)
|
||||
cairo_surface_destroy (&glyph_surface->base);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
#define N_STACK_BUF 1024
|
||||
@ -2364,7 +2437,7 @@ _cairo_xlib_surface_show_glyphs8 (cairo_xlib_surface_t *dst,
|
||||
_render_operator (op),
|
||||
src->src_picture,
|
||||
dst->dst_picture,
|
||||
font_private->format,
|
||||
font_private->xrender_format,
|
||||
src_x_offset + elts[0].xOff, src_y_offset + elts[0].yOff,
|
||||
elts[0].xOff, elts[0].yOff,
|
||||
elts, num_glyphs);
|
||||
@ -2425,7 +2498,7 @@ _cairo_xlib_surface_show_glyphs16 (cairo_xlib_surface_t *dst,
|
||||
_render_operator (op),
|
||||
src->src_picture,
|
||||
dst->dst_picture,
|
||||
font_private->format,
|
||||
font_private->xrender_format,
|
||||
src_x_offset + elts[0].xOff, src_y_offset + elts[0].yOff,
|
||||
elts[0].xOff, elts[0].yOff,
|
||||
elts, num_glyphs);
|
||||
@ -2486,7 +2559,7 @@ _cairo_xlib_surface_show_glyphs32 (cairo_xlib_surface_t *dst,
|
||||
_render_operator (op),
|
||||
src->src_picture,
|
||||
dst->dst_picture,
|
||||
font_private->format,
|
||||
font_private->xrender_format,
|
||||
src_x_offset + elts[0].xOff, src_y_offset + elts[0].yOff,
|
||||
elts[0].xOff, elts[0].yOff,
|
||||
elts, num_glyphs);
|
||||
@ -2528,7 +2601,7 @@ _cairo_xlib_surface_show_glyphs (void *abstract_dst,
|
||||
|
||||
cairo_pattern_union_t solid_pattern;
|
||||
|
||||
if (!CAIRO_SURFACE_RENDER_HAS_COMPOSITE_TEXT (dst) || !dst->format)
|
||||
if (!CAIRO_SURFACE_RENDER_HAS_COMPOSITE_TEXT (dst) || !dst->xrender_format)
|
||||
return CAIRO_INT_STATUS_UNSUPPORTED;
|
||||
|
||||
/* Just let unbounded operators go through the fallback code
|
||||
@ -2582,7 +2655,7 @@ _cairo_xlib_surface_show_glyphs (void *abstract_dst,
|
||||
(cairo_surface_t **) &src,
|
||||
&attributes);
|
||||
} else {
|
||||
cairo_rectangle_t glyph_extents;
|
||||
cairo_rectangle_fixed_t glyph_extents;
|
||||
|
||||
status = _cairo_scaled_font_glyph_device_extents (scaled_font,
|
||||
glyphs,
|
||||
|
||||
@ -45,8 +45,8 @@
|
||||
|
||||
CAIRO_BEGIN_DECLS
|
||||
|
||||
cairo_public void
|
||||
cairo_test_xlib_disable_render (void);
|
||||
void
|
||||
cairo_xlib_test_disable_render (void);
|
||||
|
||||
CAIRO_END_DECLS
|
||||
|
||||
|
||||
@ -70,12 +70,12 @@ cairo_xlib_surface_set_drawable (cairo_surface_t *surface,
|
||||
int width,
|
||||
int height);
|
||||
|
||||
cairo_public Drawable
|
||||
cairo_xlib_surface_get_drawable (cairo_surface_t *surface);
|
||||
|
||||
cairo_public Display *
|
||||
cairo_xlib_surface_get_display (cairo_surface_t *surface);
|
||||
|
||||
cairo_public Drawable
|
||||
cairo_xlib_surface_get_drawable (cairo_surface_t *surface);
|
||||
|
||||
cairo_public Screen *
|
||||
cairo_xlib_surface_get_screen (cairo_surface_t *surface);
|
||||
|
||||
@ -83,7 +83,7 @@ cairo_public Visual *
|
||||
cairo_xlib_surface_get_visual (cairo_surface_t *surface);
|
||||
|
||||
cairo_public int
|
||||
cairo_xlib_surface_get_depth (cairo_surface_t *abstract_surface);
|
||||
cairo_xlib_surface_get_depth (cairo_surface_t *surface);
|
||||
|
||||
CAIRO_END_DECLS
|
||||
|
||||
|
||||
@ -62,7 +62,7 @@ static const cairo_t cairo_nil = {
|
||||
* a bit of a pain, but it should be easy to always catch as long as
|
||||
* one adds a new test case to test a trigger of the new status value.
|
||||
*/
|
||||
#define CAIRO_STATUS_LAST_STATUS CAIRO_STATUS_INVALID_DASH
|
||||
#define CAIRO_STATUS_LAST_STATUS CAIRO_STATUS_INVALID_DSC_COMMENT
|
||||
|
||||
/**
|
||||
* _cairo_error:
|
||||
@ -82,6 +82,7 @@ static const cairo_t cairo_nil = {
|
||||
void
|
||||
_cairo_error (cairo_status_t status)
|
||||
{
|
||||
fprintf (stderr, "CAIRO ERROR: %d\n", status);
|
||||
assert (status > CAIRO_STATUS_SUCCESS &&
|
||||
status <= CAIRO_STATUS_LAST_STATUS);
|
||||
}
|
||||
@ -220,6 +221,9 @@ cairo_create (cairo_surface_t *target)
|
||||
cairo_t *
|
||||
cairo_reference (cairo_t *cr)
|
||||
{
|
||||
if (cr == NULL)
|
||||
return NULL;
|
||||
|
||||
if (cr->ref_count == (unsigned int)-1)
|
||||
return cr;
|
||||
|
||||
@ -241,6 +245,9 @@ cairo_reference (cairo_t *cr)
|
||||
void
|
||||
cairo_destroy (cairo_t *cr)
|
||||
{
|
||||
if (cr == NULL)
|
||||
return;
|
||||
|
||||
if (cr->ref_count == (unsigned int)-1)
|
||||
return;
|
||||
|
||||
@ -328,11 +335,44 @@ slim_hidden_def(cairo_restore);
|
||||
* cairo_push_group:
|
||||
* @cr: a cairo context
|
||||
*
|
||||
* Pushes a CAIRO_CONTENT_COLOR_ALPHA temporary surface onto
|
||||
* the rendering stack, redirecting all rendering into it.
|
||||
* See cairo_push_group_with_content().
|
||||
* Temporarily redirects drawing to an intermediate surface known as a
|
||||
* group. The redirection lasts until the group is completed by a call
|
||||
* to cairo_pop_group() or cairo_pop_group_to_source(). These calls
|
||||
* provide the result of any drawing to the group as a pattern,
|
||||
* (either as an explicit object, or set as the source pattern).
|
||||
*
|
||||
* This group functionality can be convenient for performing
|
||||
* intermediate compositing. One common use of a group is to render
|
||||
* objects as opaque within the group, (so that they occlude each
|
||||
* other), and then blend the result with translucence onto the
|
||||
* destination.
|
||||
*
|
||||
* Groups can be nested arbitrarily deep by making balanced calls to
|
||||
* cairo_push_group()/cairo_pop_group(). Each call pushes/pops the new
|
||||
* target group onto/from a stack.
|
||||
*
|
||||
* The cairo_push_group() function calls cairo_save() so that any
|
||||
* changes to the graphics state will not be visible outside the
|
||||
* group, (the pop_group functions call cairo_restore()).
|
||||
*
|
||||
* By default the intermediate group will have a content type of
|
||||
* CAIRO_CONTENT_COLOR_ALPHA. Other content types can be chosen for
|
||||
* the group by using cairo_push_group_with_content() instead.
|
||||
*
|
||||
* As an example, here is how one might fill and stroke a path with
|
||||
* translucence, but without any portion of the fill being visible
|
||||
* under the stroke:
|
||||
*
|
||||
* <informalexample><programlisting>
|
||||
* cairo_push_group (cr);
|
||||
* cairo_set_source (cr, fill_pattern);
|
||||
* cairo_fill_preserve (cr);
|
||||
* cairo_set_source (cr, stroke_pattern);
|
||||
* cairo_stroke (cr);
|
||||
* cairo_pop_group_to_source (cr);
|
||||
* cairo_paint_with_alpha (cr, alpha);
|
||||
* </programlisting></informalexample>
|
||||
*/
|
||||
|
||||
void
|
||||
cairo_push_group (cairo_t *cr)
|
||||
{
|
||||
@ -346,22 +386,22 @@ slim_hidden_def(cairo_push_group);
|
||||
* @content: a %cairo_content_t indicating the type of group that
|
||||
* will be created
|
||||
*
|
||||
* Pushes a temporary surface onto the rendering stack, redirecting
|
||||
* all rendering into it. The surface dimensions are the size of
|
||||
* the current clipping bounding box. Initially, this surface
|
||||
* is painted with CAIRO_OPERATOR_CLEAR.
|
||||
* Temporarily redirects drawing to an intermediate surface known as a
|
||||
* group. The redirection lasts until the group is completed by a call
|
||||
* to cairo_pop_group() or cairo_pop_group_to_source(). These calls
|
||||
* provide the result of any drawing to the group as a pattern,
|
||||
* (either as an explicit object, or set as the source pattern).
|
||||
*
|
||||
* cairo_push_group() calls cairo_save() so that any changes to the
|
||||
* graphics state will not be visible after cairo_pop_group() or
|
||||
* cairo_pop_group_with_alpha(). See cairo_pop_group() and
|
||||
* cairo_pop_group_with_alpha().
|
||||
* The group will have a content type of @content. The ability to
|
||||
* control this content type is the only distinction between this
|
||||
* function and cairo_push_group() which you should see for a more
|
||||
* detailed description of group rendering.
|
||||
*/
|
||||
|
||||
void
|
||||
cairo_push_group_with_content (cairo_t *cr, cairo_content_t content)
|
||||
{
|
||||
cairo_status_t status;
|
||||
cairo_rectangle_t extents;
|
||||
cairo_rectangle_fixed_t extents;
|
||||
cairo_surface_t *group_surface = NULL;
|
||||
|
||||
/* Get the extents that we'll use in creating our new group surface */
|
||||
@ -401,6 +441,26 @@ bail:
|
||||
}
|
||||
slim_hidden_def(cairo_push_group_with_content);
|
||||
|
||||
|
||||
/**
|
||||
* cairo_pop_group:
|
||||
* @cr: a cairo context
|
||||
*
|
||||
* Terminates the redirection begun by a call to cairo_push_group() or
|
||||
* cairo_push_group_with_content() and returns a new pattern
|
||||
* containing the results of all drawing operations performed to the
|
||||
* group.
|
||||
*
|
||||
* The cairo_pop_group() function calls cairo_restore(), (balancing a
|
||||
* call to cairo_save() by the push_group function), so that any
|
||||
* changes to the graphics state will not be visible outside the
|
||||
* group.
|
||||
*
|
||||
* Return value: a newly created (surface) pattern containing the
|
||||
* results of all drawing operations performed to the group. The
|
||||
* caller owns the returned object and should call
|
||||
* cairo_pattern_destroy() when finished with it.
|
||||
**/
|
||||
cairo_pattern_t *
|
||||
cairo_pop_group (cairo_t *cr)
|
||||
{
|
||||
@ -443,6 +503,31 @@ done:
|
||||
}
|
||||
slim_hidden_def(cairo_pop_group);
|
||||
|
||||
/**
|
||||
* cairo_pop_group_t_source:
|
||||
* @cr: a cairo context
|
||||
*
|
||||
* Terminates the redirection begun by a call to cairo_push_group() or
|
||||
* cairo_push_group_with_content() and installs the resulting pattern
|
||||
* as the source pattern in the given cairo context.
|
||||
*
|
||||
* The behavior of this function is equivalent to the sequence of
|
||||
* operations:
|
||||
*
|
||||
* <informalexample><programlisting>
|
||||
* cairo_pattern_t *group = cairo_pop_group (cr);
|
||||
* cairo_set_source (cr, group);
|
||||
* cairo_pattern_destroy (group);
|
||||
* </programlisting></informalexample>
|
||||
*
|
||||
* but is more convenient as their is no need for a variable to store
|
||||
* the short-lived pointer to the pattern.
|
||||
*
|
||||
* The cairo_pop_group() function calls cairo_restore(), (balancing a
|
||||
* call to cairo_save() by the push_group function), so that any
|
||||
* changes to the graphics state will not be visible outside the
|
||||
* group.
|
||||
**/
|
||||
void
|
||||
cairo_pop_group_to_source (cairo_t *cr)
|
||||
{
|
||||
@ -718,16 +803,28 @@ cairo_set_fill_rule (cairo_t *cr, cairo_fill_rule_t fill_rule)
|
||||
/**
|
||||
* cairo_set_line_width:
|
||||
* @cr: a #cairo_t
|
||||
* @width: a line width, as a user-space value
|
||||
* @width: a line width
|
||||
*
|
||||
* Sets the current line width within the cairo context. The line
|
||||
* width specifies the diameter of a pen that is circular in
|
||||
* user-space.
|
||||
* width value specifies the diameter of a pen that is circular in
|
||||
* user space, (though device-space pen may be an ellipse in general
|
||||
* due to scaling/shear/rotation of the CTM).
|
||||
*
|
||||
* As with the other stroke parameters, the current line cap style is
|
||||
* Note: When the description above refers to user space and CTM it
|
||||
* refers to the user space and CTM in effect at the time of the
|
||||
* stroking operation, not the user space and CTM in effect at the
|
||||
* time of the call to cairo_set_line_width(). The simplest usage
|
||||
* makes both of these spaces identical. That is, if there is no
|
||||
* change to the CTM between a call to cairo_set_line_with() and the
|
||||
* stroking operation, then one can just pass user-space values to
|
||||
* cairo_set_line_width() and ignore this note.
|
||||
*
|
||||
* As with the other stroke parameters, the current line width is
|
||||
* examined by cairo_stroke(), cairo_stroke_extents(), and
|
||||
* cairo_stroke_to_path(), but does not have any effect during path
|
||||
* construction.
|
||||
*
|
||||
* The default line width value is 2.0.
|
||||
**/
|
||||
void
|
||||
cairo_set_line_width (cairo_t *cr, double width)
|
||||
@ -795,15 +892,19 @@ cairo_set_line_join (cairo_t *cr, cairo_line_join_t line_join)
|
||||
/**
|
||||
* cairo_set_dash:
|
||||
* @cr: a cairo context
|
||||
* @dashes: an array specifying alternate lengths of on and off po
|
||||
* @dashes: an array specifying alternate lengths of on and off stroke portions
|
||||
* @num_dashes: the length of the dashes array
|
||||
* @offset: an offset into the dash pattern at which the stroke should start
|
||||
*
|
||||
* Sets the dash pattern to be used by cairo_stroke(). A dash pattern
|
||||
* is specified by @dashes, an array of positive values. Each value
|
||||
* provides the user-space length of altenate "on" and "off" portions
|
||||
* of the stroke. The @offset specifies an offset into the pattern at
|
||||
* which the stroke begins.
|
||||
* provides the length of alternate "on" and "off" portions of the
|
||||
* stroke. The @offset specifies an offset into the pattern at which
|
||||
* the stroke begins.
|
||||
*
|
||||
* Note: The length values are in user-space units as evaluated at the
|
||||
* time of stroking. This is not necessarily the same as the user
|
||||
* space at the time of cairo_set_dash().
|
||||
*
|
||||
* If @num_dashes is 0 dashing is disabled.
|
||||
*
|
||||
@ -1062,8 +1163,8 @@ cairo_device_to_user_distance (cairo_t *cr, double *dx, double *dy)
|
||||
* cairo_new_path:
|
||||
* @cr: a cairo context
|
||||
*
|
||||
* Clears the current path. After this call there will be no current
|
||||
* point.
|
||||
* Clears the current path. After this call there will be no path and
|
||||
* no current point.
|
||||
**/
|
||||
void
|
||||
cairo_new_path (cairo_t *cr)
|
||||
@ -1081,8 +1182,8 @@ slim_hidden_def(cairo_new_path);
|
||||
* @x: the X coordinate of the new position
|
||||
* @y: the Y coordinate of the new position
|
||||
*
|
||||
* If the current subpath is not empty, begin a new subpath. After
|
||||
* this call the current point will be (@x, @y).
|
||||
* Begin a new subpath. After this call the current point will be (@x,
|
||||
* @y).
|
||||
**/
|
||||
void
|
||||
cairo_move_to (cairo_t *cr, double x, double y)
|
||||
@ -1102,6 +1203,31 @@ cairo_move_to (cairo_t *cr, double x, double y)
|
||||
}
|
||||
slim_hidden_def(cairo_move_to);
|
||||
|
||||
/**
|
||||
* cairo_new_sub_path:
|
||||
* @cr: a cairo context
|
||||
*
|
||||
* Begin a new subpath. Note that the existing path is not
|
||||
* affected. After this call there will be no current point.
|
||||
*
|
||||
* In many cases, this call is not needed since new subpaths are
|
||||
* frequently started with cairo_move_to().
|
||||
*
|
||||
* A call to cairo_new_sub_path() is particularly useful when
|
||||
* beginning a new subpath with one of the cairo_arc() calls. This
|
||||
* makes things easier as it is no longer necessary to manually
|
||||
* compute the arc's initial coordinates for a call to
|
||||
* cairo_move_to().
|
||||
**/
|
||||
void
|
||||
cairo_new_sub_path (cairo_t *cr)
|
||||
{
|
||||
if (cr->status)
|
||||
return;
|
||||
|
||||
_cairo_path_fixed_new_sub_path (&cr->path);
|
||||
}
|
||||
|
||||
/**
|
||||
* cairo_line_to:
|
||||
* @cr: a cairo context
|
||||
@ -1111,6 +1237,9 @@ slim_hidden_def(cairo_move_to);
|
||||
* Adds a line to the path from the current point to position (@x, @y)
|
||||
* in user-space coordinates. After this call the current point
|
||||
* will be (@x, @y).
|
||||
*
|
||||
* If there is no current point before the call to cairo_line_to()
|
||||
* this function will behave as cairo_move_to (@cr, @x, @y).
|
||||
**/
|
||||
void
|
||||
cairo_line_to (cairo_t *cr, double x, double y)
|
||||
@ -1143,6 +1272,10 @@ cairo_line_to (cairo_t *cr, double x, double y)
|
||||
* position (@x3, @y3) in user-space coordinates, using (@x1, @y1) and
|
||||
* (@x2, @y2) as the control points. After this call the current point
|
||||
* will be (@x3, @y3).
|
||||
*
|
||||
* If there is no current point before the call to cairo_curve_to()
|
||||
* this function will behave as if preceded by a call to
|
||||
* cairo_move_to (@cr, @x1, @y1).
|
||||
**/
|
||||
void
|
||||
cairo_curve_to (cairo_t *cr,
|
||||
@ -1198,9 +1331,9 @@ cairo_curve_to (cairo_t *cr,
|
||||
* arc.
|
||||
*
|
||||
* Angles are measured in radians. An angle of 0.0 is in the direction
|
||||
* of the positive X axis (in user-space). An angle of %M_PI/2.0 radians
|
||||
* of the positive X axis (in user space). An angle of %M_PI/2.0 radians
|
||||
* (90 degrees) is in the direction of the positive Y axis (in
|
||||
* user-space). Angles increase in the direction from the positive X
|
||||
* user space). Angles increase in the direction from the positive X
|
||||
* axis toward the positive Y axis. So with the default transformation
|
||||
* matrix, angles increase in a clockwise direction.
|
||||
*
|
||||
@ -1211,7 +1344,7 @@ cairo_curve_to (cairo_t *cr,
|
||||
* see cairo_arc_negative() to get the arc in the direction of
|
||||
* decreasing angles.
|
||||
*
|
||||
* The arc is circular in user-space. To achieve an elliptical arc,
|
||||
* The arc is circular in user space. To achieve an elliptical arc,
|
||||
* you can scale the current transformation matrix by different
|
||||
* amounts in the X and Y directions. For example, to draw an ellipse
|
||||
* in the box given by @x, @y, @width, @height:
|
||||
@ -1313,11 +1446,15 @@ cairo_arc_to (cairo_t *cr,
|
||||
* @dx: the X offset
|
||||
* @dy: the Y offset
|
||||
*
|
||||
* If the current subpath is not empty, begin a new subpath. After
|
||||
* this call the current point will offset by (@x, @y).
|
||||
* Begin a new subpath. After this call the current point will offset
|
||||
* by (@x, @y).
|
||||
*
|
||||
* Given a current point of (x, y), cairo_rel_move_to(@cr, @dx, @dy)
|
||||
* is logically equivalent to cairo_move_to (@cr, x + @dx, y + @dy).
|
||||
*
|
||||
* It is an error to call this function with no current point. Doing
|
||||
* so will cause @cr to shutdown with a status of
|
||||
* CAIRO_STATUS_NO_CURRENT_POINT.
|
||||
**/
|
||||
void
|
||||
cairo_rel_move_to (cairo_t *cr, double dx, double dy)
|
||||
@ -1349,6 +1486,10 @@ cairo_rel_move_to (cairo_t *cr, double dx, double dy)
|
||||
*
|
||||
* Given a current point of (x, y), cairo_rel_line_to(@cr, @dx, @dy)
|
||||
* is logically equivalent to cairo_line_to (@cr, x + @dx, y + @dy).
|
||||
*
|
||||
* It is an error to call this function with no current point. Doing
|
||||
* so will cause @cr to shutdown with a status of
|
||||
* CAIRO_STATUS_NO_CURRENT_POINT.
|
||||
**/
|
||||
void
|
||||
cairo_rel_line_to (cairo_t *cr, double dx, double dy)
|
||||
@ -1389,6 +1530,10 @@ slim_hidden_def(cairo_rel_line_to);
|
||||
* @dy1, @dx2, @dy2, @dx3, @dy3) is logically equivalent to
|
||||
* cairo_curve_to (@cr, x + @dx1, y + @dy1, x + @dx2, y + @dy2, x +
|
||||
* @dx3, y + @dy3).
|
||||
*
|
||||
* It is an error to call this function with no current point. Doing
|
||||
* so will cause @cr to shutdown with a status of
|
||||
* CAIRO_STATUS_NO_CURRENT_POINT.
|
||||
**/
|
||||
void
|
||||
cairo_rel_curve_to (cairo_t *cr,
|
||||
@ -1478,13 +1623,17 @@ cairo_stroke_to_path (cairo_t *cr)
|
||||
*
|
||||
* Adds a line segment to the path from the current point to the
|
||||
* beginning of the current subpath, (the most recent point passed to
|
||||
* cairo_move_to()), and closes this subpath.
|
||||
* cairo_move_to()), and closes this subpath. After this call the
|
||||
* current point will be at the joined endpoint of the subpath.
|
||||
*
|
||||
* The behavior of cairo_close_path() is distinct from simply calling
|
||||
* cairo_line_to() with the equivalent coordinate in the case of
|
||||
* stroking. When a closed subpath is stroked, there are no caps on
|
||||
* the ends of the subpath. Instead, their is a line join connecting
|
||||
* the ends of the subpath. Instead, there is a line join connecting
|
||||
* the final and initial segments of the subpath.
|
||||
*
|
||||
* If there is no current point before the call to cairo_close_path,
|
||||
* this function will have no effect.
|
||||
**/
|
||||
void
|
||||
cairo_close_path (cairo_t *cr)
|
||||
@ -2083,6 +2232,46 @@ cairo_get_font_options (cairo_t *cr,
|
||||
_cairo_gstate_get_font_options (cr->gstate, options);
|
||||
}
|
||||
|
||||
/**
|
||||
* cairo_set_scaled_font:
|
||||
* @cr: a #cairo_t
|
||||
* @scaled_font: a #cairo_scaled_font_t
|
||||
*
|
||||
* Replaces the current font face, font matrix, and font options in
|
||||
* the #cairo_t with those of the #cairo_scaled_font_t. Except for
|
||||
* some translation, the current CTM of the #cairo_t should be the
|
||||
* same as that of the #cairo_scaled_font_t, which can be accessed
|
||||
* using cairo_scaled_font_get_ctm().
|
||||
**/
|
||||
void
|
||||
cairo_set_scaled_font (cairo_t *cr,
|
||||
const cairo_scaled_font_t *scaled_font)
|
||||
{
|
||||
if (cr->status)
|
||||
return;
|
||||
|
||||
cr->status = scaled_font->status;
|
||||
if (cr->status)
|
||||
goto BAIL;
|
||||
|
||||
cr->status = _cairo_gstate_set_font_face (cr->gstate, scaled_font->font_face);
|
||||
if (cr->status)
|
||||
goto BAIL;
|
||||
|
||||
cr->status = _cairo_gstate_set_font_matrix (cr->gstate, &scaled_font->font_matrix);
|
||||
if (cr->status)
|
||||
goto BAIL;
|
||||
|
||||
cr->status = _cairo_gstate_set_font_options (cr->gstate, &scaled_font->options);
|
||||
if (cr->status)
|
||||
goto BAIL;
|
||||
|
||||
return;
|
||||
|
||||
BAIL:
|
||||
_cairo_set_error (cr, cr->status);
|
||||
}
|
||||
|
||||
/**
|
||||
* cairo_text_extents:
|
||||
* @cr: a #cairo_t
|
||||
@ -2419,9 +2608,10 @@ cairo_get_fill_rule (cairo_t *cr)
|
||||
* cairo_get_line_width:
|
||||
* @cr: a cairo context
|
||||
*
|
||||
* Gets the current line width, as set by cairo_set_line_width().
|
||||
*
|
||||
* Return value: the current line width, in user-space units.
|
||||
* Return value: the current line width value exactly as set by
|
||||
* cairo_set_line_width(). Note that the value is unchanged even if
|
||||
* the CTM has changed between the calls to cairo_set_line_width() and
|
||||
* cairo_get_line_width().
|
||||
**/
|
||||
double
|
||||
cairo_get_line_width (cairo_t *cr)
|
||||
@ -2512,14 +2702,10 @@ cairo_get_target (cairo_t *cr)
|
||||
/**
|
||||
* cairo_get_group_target:
|
||||
* @cr: a cairo context
|
||||
* @dx: device offset x value from cr's original target
|
||||
* @dy: device offset y value from cr's original target
|
||||
*
|
||||
* Gets the target surface for the current transparency group
|
||||
* started by the last cairo_push_group() call on the cairo
|
||||
* context. The offset between this surface and the cairo
|
||||
* context's original target surface is also returned if
|
||||
* dx and/or dy are not NULL.
|
||||
* context.
|
||||
*
|
||||
* This function may return NULL if there is no transparency
|
||||
* group on the target.
|
||||
@ -2529,21 +2715,14 @@ cairo_get_target (cairo_t *cr)
|
||||
* cairo_surface_reference().
|
||||
**/
|
||||
cairo_surface_t *
|
||||
cairo_get_group_target (cairo_t *cr, double *dx, double *dy)
|
||||
cairo_get_group_target (cairo_t *cr)
|
||||
{
|
||||
cairo_surface_t *gsurf;
|
||||
|
||||
if (cr->status)
|
||||
return (cairo_surface_t*) &_cairo_surface_nil;
|
||||
|
||||
gsurf = _cairo_gstate_get_target (cr->gstate);
|
||||
if (!gsurf)
|
||||
return NULL;
|
||||
|
||||
if (dx || dy)
|
||||
_cairo_gstate_get_target_offsets_from_original (cr->gstate, dx, dy);
|
||||
|
||||
return gsurf;
|
||||
return _cairo_gstate_get_target (cr->gstate);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -2770,6 +2949,8 @@ cairo_status_to_string (cairo_status_t status)
|
||||
return "file not found";
|
||||
case CAIRO_STATUS_INVALID_DASH:
|
||||
return "invalid value for a dash setting";
|
||||
case CAIRO_STATUS_INVALID_DSC_COMMENT:
|
||||
return "invalid value for a DSC comment";
|
||||
}
|
||||
|
||||
return "<unknown error status>";
|
||||
|
||||
@ -167,6 +167,7 @@ typedef struct _cairo_user_data_key {
|
||||
* @CAIRO_STATUS_INVALID_VISUAL: invalid value for an input Visual*
|
||||
* @CAIRO_STATUS_FILE_NOT_FOUND: file not found
|
||||
* @CAIRO_STATUS_INVALID_DASH: invalid value for a dash setting
|
||||
* @CAIRO_STATUS_INVALID_DSC_COMMENT: invalid value for a DSC comment
|
||||
*
|
||||
* #cairo_status_t is used to indicate errors that can occur when
|
||||
* using Cairo. In some cases it is returned directly by functions.
|
||||
@ -193,7 +194,8 @@ typedef enum _cairo_status {
|
||||
CAIRO_STATUS_INVALID_FORMAT,
|
||||
CAIRO_STATUS_INVALID_VISUAL,
|
||||
CAIRO_STATUS_FILE_NOT_FOUND,
|
||||
CAIRO_STATUS_INVALID_DASH
|
||||
CAIRO_STATUS_INVALID_DASH,
|
||||
CAIRO_STATUS_INVALID_DSC_COMMENT
|
||||
} cairo_status_t;
|
||||
|
||||
/**
|
||||
@ -459,6 +461,9 @@ cairo_new_path (cairo_t *cr);
|
||||
cairo_public void
|
||||
cairo_move_to (cairo_t *cr, double x, double y);
|
||||
|
||||
cairo_public void
|
||||
cairo_new_sub_path (cairo_t *cr);
|
||||
|
||||
cairo_public void
|
||||
cairo_line_to (cairo_t *cr, double x, double y);
|
||||
|
||||
@ -876,6 +881,10 @@ cairo_public void
|
||||
cairo_get_font_options (cairo_t *cr,
|
||||
cairo_font_options_t *options);
|
||||
|
||||
cairo_public void
|
||||
cairo_set_scaled_font (cairo_t *cr,
|
||||
const cairo_scaled_font_t *scaled_font);
|
||||
|
||||
cairo_public void
|
||||
cairo_show_text (cairo_t *cr, const char *utf8);
|
||||
|
||||
@ -1062,7 +1071,7 @@ cairo_public cairo_surface_t *
|
||||
cairo_get_target (cairo_t *cr);
|
||||
|
||||
cairo_public cairo_surface_t *
|
||||
cairo_get_group_target (cairo_t *cr, double *dx, double *dy);
|
||||
cairo_get_group_target (cairo_t *cr);
|
||||
|
||||
typedef enum _cairo_path_data_type {
|
||||
CAIRO_PATH_MOVE_TO,
|
||||
@ -1277,6 +1286,9 @@ typedef enum _cairo_surface_type {
|
||||
cairo_public cairo_surface_type_t
|
||||
cairo_surface_get_type (cairo_surface_t *surface);
|
||||
|
||||
cairo_public cairo_content_t
|
||||
cairo_surface_get_content (cairo_surface_t *surface);
|
||||
|
||||
#if CAIRO_HAS_PNG_FUNCTIONS
|
||||
|
||||
cairo_public cairo_status_t
|
||||
@ -1563,6 +1575,10 @@ cairo_public void
|
||||
cairo_matrix_transform_point (const cairo_matrix_t *matrix,
|
||||
double *x, double *y);
|
||||
|
||||
/* Functions to be used while debugging (not intended for use in production code) */
|
||||
cairo_public void
|
||||
cairo_debug_reset_static_data (void);
|
||||
|
||||
#ifndef _CAIROINT_H_
|
||||
|
||||
/* Obsolete functions. These definitions exist to coerce the compiler
|
||||
|
||||
@ -63,7 +63,6 @@
|
||||
#include <stdio.h>
|
||||
|
||||
#include "cairo.h"
|
||||
#include "cairo-debug.h"
|
||||
#include <pixman.h>
|
||||
|
||||
CAIRO_BEGIN_DECLS
|
||||
@ -247,7 +246,7 @@ typedef struct _cairo_trapezoid {
|
||||
typedef struct _cairo_rectangle {
|
||||
short x, y;
|
||||
unsigned short width, height;
|
||||
} cairo_rectangle_t, cairo_glyph_size_t;
|
||||
} cairo_rectangle_fixed_t, cairo_glyph_size_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
|
||||
@ -262,6 +261,7 @@ typedef enum cairo_int_status {
|
||||
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
|
||||
@ -332,10 +332,10 @@ typedef struct _cairo_image_surface cairo_image_surface_t;
|
||||
typedef struct _cairo_surface_backend cairo_surface_backend_t;
|
||||
|
||||
cairo_private void
|
||||
_cairo_box_round_to_rectangle (cairo_box_t *box, cairo_rectangle_t *rectangle);
|
||||
_cairo_box_round_to_rectangle (cairo_box_t *box, cairo_rectangle_fixed_t *rectangle);
|
||||
|
||||
cairo_private void
|
||||
_cairo_rectangle_intersect (cairo_rectangle_t *dest, cairo_rectangle_t *src);
|
||||
_cairo_rectangle_intersect (cairo_rectangle_fixed_t *dest, cairo_rectangle_fixed_t *src);
|
||||
|
||||
|
||||
/* cairo_array.c structures and functions */
|
||||
@ -637,18 +637,18 @@ struct _cairo_surface_backend {
|
||||
void *image_extra);
|
||||
|
||||
cairo_status_t
|
||||
(*acquire_dest_image) (void *abstract_surface,
|
||||
cairo_rectangle_t *interest_rect,
|
||||
(*acquire_dest_image) (void *abstract_surface,
|
||||
cairo_rectangle_fixed_t *interest_rect,
|
||||
cairo_image_surface_t **image_out,
|
||||
cairo_rectangle_t *image_rect,
|
||||
cairo_rectangle_fixed_t *image_rect,
|
||||
void **image_extra);
|
||||
|
||||
void
|
||||
(*release_dest_image) (void *abstract_surface,
|
||||
cairo_rectangle_t *interest_rect,
|
||||
cairo_image_surface_t *image,
|
||||
cairo_rectangle_t *image_rect,
|
||||
void *image_extra);
|
||||
(*release_dest_image) (void *abstract_surface,
|
||||
cairo_rectangle_fixed_t *interest_rect,
|
||||
cairo_image_surface_t *image,
|
||||
cairo_rectangle_fixed_t *image_rect,
|
||||
void *image_extra);
|
||||
|
||||
cairo_status_t
|
||||
(*clone_similar) (void *surface,
|
||||
@ -671,11 +671,11 @@ struct _cairo_surface_backend {
|
||||
unsigned int height);
|
||||
|
||||
cairo_int_status_t
|
||||
(*fill_rectangles) (void *surface,
|
||||
cairo_operator_t op,
|
||||
const cairo_color_t *color,
|
||||
cairo_rectangle_t *rects,
|
||||
int num_rects);
|
||||
(*fill_rectangles) (void *surface,
|
||||
cairo_operator_t op,
|
||||
const cairo_color_t *color,
|
||||
cairo_rectangle_fixed_t *rects,
|
||||
int num_rects);
|
||||
|
||||
/* XXX: dst should be the first argument for consistency */
|
||||
cairo_int_status_t
|
||||
@ -747,8 +747,8 @@ struct _cairo_surface_backend {
|
||||
* clip.
|
||||
*/
|
||||
cairo_int_status_t
|
||||
(*get_extents) (void *surface,
|
||||
cairo_rectangle_t *rectangle);
|
||||
(*get_extents) (void *surface,
|
||||
cairo_rectangle_fixed_t *rectangle);
|
||||
|
||||
/*
|
||||
* This is an optional entry to let the surface manage its own glyph
|
||||
@ -852,6 +852,8 @@ struct _cairo_surface {
|
||||
* hide their internal type from the user-level API. */
|
||||
cairo_surface_type_t type;
|
||||
|
||||
cairo_content_t content;
|
||||
|
||||
unsigned int ref_count;
|
||||
cairo_status_t status;
|
||||
cairo_bool_t finished;
|
||||
@ -1102,9 +1104,6 @@ _cairo_gstate_get_parent_target (cairo_gstate_t *gstate);
|
||||
cairo_private cairo_surface_t *
|
||||
_cairo_gstate_get_original_target (cairo_gstate_t *gstate);
|
||||
|
||||
cairo_private void
|
||||
_cairo_gstate_get_target_offsets_from_original (cairo_gstate_t *gstate, double *dx, double *dy);
|
||||
|
||||
cairo_private cairo_clip_t *
|
||||
_cairo_gstate_get_clip (cairo_gstate_t *gstate);
|
||||
|
||||
@ -1415,6 +1414,13 @@ _cairo_font_options_init_copy (cairo_font_options_t *options,
|
||||
cairo_private cairo_status_t
|
||||
_cairo_hull_compute (cairo_pen_vertex_t *vertices, int *num_vertices);
|
||||
|
||||
/* cairo_operator.c */
|
||||
cairo_private cairo_bool_t
|
||||
_cairo_operator_always_opaque (cairo_operator_t op);
|
||||
|
||||
cairo_private cairo_bool_t
|
||||
_cairo_operator_always_translucent (cairo_operator_t op);
|
||||
|
||||
/* cairo_path.c */
|
||||
cairo_private void
|
||||
_cairo_path_fixed_init (cairo_path_fixed_t *path);
|
||||
@ -1437,6 +1443,9 @@ _cairo_path_fixed_move_to (cairo_path_fixed_t *path,
|
||||
cairo_fixed_t x,
|
||||
cairo_fixed_t y);
|
||||
|
||||
cairo_private void
|
||||
_cairo_path_fixed_new_sub_path (cairo_path_fixed_t *path);
|
||||
|
||||
cairo_private cairo_status_t
|
||||
_cairo_path_fixed_rel_move_to (cairo_path_fixed_t *path,
|
||||
cairo_fixed_t dx,
|
||||
@ -1560,10 +1569,10 @@ _cairo_scaled_font_glyph_extents (cairo_scaled_font_t *scaled_font,
|
||||
cairo_text_extents_t *extents);
|
||||
|
||||
cairo_private cairo_status_t
|
||||
_cairo_scaled_font_glyph_device_extents (cairo_scaled_font_t *scaled_font,
|
||||
const cairo_glyph_t *glyphs,
|
||||
int num_glyphs,
|
||||
cairo_rectangle_t *extents);
|
||||
_cairo_scaled_font_glyph_device_extents (cairo_scaled_font_t *scaled_font,
|
||||
const cairo_glyph_t *glyphs,
|
||||
int num_glyphs,
|
||||
cairo_rectangle_fixed_t *extents);
|
||||
|
||||
cairo_private cairo_status_t
|
||||
_cairo_scaled_font_show_glyphs (cairo_scaled_font_t *scaled_font,
|
||||
@ -1581,7 +1590,7 @@ _cairo_scaled_font_show_glyphs (cairo_scaled_font_t *scaled_font,
|
||||
|
||||
cairo_private cairo_status_t
|
||||
_cairo_scaled_font_glyph_path (cairo_scaled_font_t *scaled_font,
|
||||
cairo_glyph_t *glyphs,
|
||||
const cairo_glyph_t *glyphs,
|
||||
int num_glyphs,
|
||||
cairo_path_fixed_t *path);
|
||||
|
||||
@ -1627,6 +1636,10 @@ extern const cairo_private cairo_surface_t _cairo_surface_nil;
|
||||
extern const cairo_private cairo_surface_t _cairo_surface_nil_read_error;
|
||||
extern const cairo_private cairo_surface_t _cairo_surface_nil_file_not_found;
|
||||
|
||||
cairo_private void
|
||||
_cairo_surface_set_error (cairo_surface_t *surface,
|
||||
cairo_status_t status);
|
||||
|
||||
cairo_private cairo_surface_t *
|
||||
_cairo_surface_create_similar_scratch (cairo_surface_t *other,
|
||||
cairo_content_t content,
|
||||
@ -1642,7 +1655,8 @@ _cairo_surface_create_similar_solid (cairo_surface_t *other,
|
||||
|
||||
cairo_private void
|
||||
_cairo_surface_init (cairo_surface_t *surface,
|
||||
const cairo_surface_backend_t *backend);
|
||||
const cairo_surface_backend_t *backend,
|
||||
cairo_content_t content);
|
||||
|
||||
cairo_private cairo_clip_mode_t
|
||||
_cairo_surface_get_clip_mode (cairo_surface_t *surface);
|
||||
@ -1678,10 +1692,10 @@ _cairo_surface_fill_region (cairo_surface_t *surface,
|
||||
|
||||
cairo_private cairo_status_t
|
||||
_cairo_surface_fill_rectangles (cairo_surface_t *surface,
|
||||
cairo_operator_t op,
|
||||
cairo_operator_t op,
|
||||
const cairo_color_t *color,
|
||||
cairo_rectangle_t *rects,
|
||||
int num_rects);
|
||||
cairo_rectangle_fixed_t *rects,
|
||||
int num_rects);
|
||||
|
||||
cairo_private cairo_status_t
|
||||
_cairo_surface_paint (cairo_surface_t *surface,
|
||||
@ -1754,16 +1768,16 @@ _cairo_surface_release_source_image (cairo_surface_t *surface,
|
||||
|
||||
cairo_private cairo_status_t
|
||||
_cairo_surface_acquire_dest_image (cairo_surface_t *surface,
|
||||
cairo_rectangle_t *interest_rect,
|
||||
cairo_rectangle_fixed_t *interest_rect,
|
||||
cairo_image_surface_t **image_out,
|
||||
cairo_rectangle_t *image_rect,
|
||||
cairo_rectangle_fixed_t *image_rect,
|
||||
void **image_extra);
|
||||
|
||||
cairo_private void
|
||||
_cairo_surface_release_dest_image (cairo_surface_t *surface,
|
||||
cairo_rectangle_t *interest_rect,
|
||||
cairo_rectangle_fixed_t *interest_rect,
|
||||
cairo_image_surface_t *image,
|
||||
cairo_rectangle_t *image_rect,
|
||||
cairo_rectangle_fixed_t *image_rect,
|
||||
void *image_extra);
|
||||
|
||||
cairo_private cairo_status_t
|
||||
@ -1799,8 +1813,8 @@ cairo_private cairo_status_t
|
||||
_cairo_surface_set_clip (cairo_surface_t *surface, cairo_clip_t *clip);
|
||||
|
||||
cairo_private cairo_status_t
|
||||
_cairo_surface_get_extents (cairo_surface_t *surface,
|
||||
cairo_rectangle_t *rectangle);
|
||||
_cairo_surface_get_extents (cairo_surface_t *surface,
|
||||
cairo_rectangle_fixed_t *rectangle);
|
||||
|
||||
cairo_private cairo_status_t
|
||||
_cairo_surface_old_show_glyphs (cairo_scaled_font_t *scaled_font,
|
||||
@ -1849,6 +1863,9 @@ _cairo_surface_composite_shape_fixup_unbounded (cairo_surface_t *dst,
|
||||
unsigned int width,
|
||||
unsigned int height);
|
||||
|
||||
cairo_private cairo_bool_t
|
||||
_cairo_surface_is_opaque (const cairo_surface_t *surface);
|
||||
|
||||
cairo_private cairo_bool_t
|
||||
_cairo_surface_has_device_offset_or_scale (cairo_surface_t *surface);
|
||||
|
||||
@ -1895,6 +1912,19 @@ _cairo_image_surface_create_for_data_with_content (unsigned char *data,
|
||||
cairo_private void
|
||||
_cairo_image_surface_assume_ownership_of_data (cairo_image_surface_t *surface);
|
||||
|
||||
/* XXX: It's a nasty kludge that this appears here. Backend functions
|
||||
* like this should really be static. But we're doing this to work
|
||||
* around some general defects in the backend clipping interfaces,
|
||||
* (see some notes in test-paginated-surface.c).
|
||||
*
|
||||
* I want to fix the real defects, but it's "hard" as they touch many
|
||||
* backends, so doing that will require synchronizing several backend
|
||||
* maintainers.
|
||||
*/
|
||||
cairo_private cairo_int_status_t
|
||||
_cairo_image_surface_set_clip_region (void *abstract_surface,
|
||||
pixman_region16_t *region);
|
||||
|
||||
cairo_private cairo_bool_t
|
||||
_cairo_surface_is_image (const cairo_surface_t *surface);
|
||||
|
||||
@ -1999,6 +2029,10 @@ cairo_private cairo_bool_t
|
||||
_cairo_matrix_is_integer_translation(const cairo_matrix_t *matrix,
|
||||
int *itx, int *ity);
|
||||
|
||||
cairo_private cairo_bool_t
|
||||
_cairo_matrix_is_integer_translation_and_scale(const cairo_matrix_t *m,
|
||||
int *itx, int *ity, int *sx, int *sy);
|
||||
|
||||
cairo_private double
|
||||
_cairo_matrix_transformed_circle_major_axis(cairo_matrix_t *matrix, double radius);
|
||||
|
||||
@ -2095,7 +2129,10 @@ _cairo_pattern_transform (cairo_pattern_t *pattern,
|
||||
const cairo_matrix_t *ctm_inverse);
|
||||
|
||||
cairo_private cairo_bool_t
|
||||
_cairo_pattern_is_opaque_solid (cairo_pattern_t *pattern);
|
||||
_cairo_pattern_is_opaque_solid (const cairo_pattern_t *pattern);
|
||||
|
||||
cairo_bool_t
|
||||
_cairo_pattern_is_opaque (const cairo_pattern_t *abstract_pattern);
|
||||
|
||||
cairo_private cairo_int_status_t
|
||||
_cairo_pattern_acquire_surface (cairo_pattern_t *pattern,
|
||||
@ -2128,8 +2165,8 @@ _cairo_pattern_acquire_surfaces (cairo_pattern_t *src,
|
||||
cairo_surface_attributes_t *mask_attributes);
|
||||
|
||||
cairo_private cairo_status_t
|
||||
_cairo_pattern_get_extents (cairo_pattern_t *pattern,
|
||||
cairo_rectangle_t *extents);
|
||||
_cairo_pattern_get_extents (cairo_pattern_t *pattern,
|
||||
cairo_rectangle_fixed_t *extents);
|
||||
|
||||
cairo_private cairo_status_t
|
||||
_cairo_gstate_set_antialias (cairo_gstate_t *gstate,
|
||||
@ -2141,11 +2178,11 @@ _cairo_gstate_get_antialias (cairo_gstate_t *gstate);
|
||||
/* cairo-region.c */
|
||||
|
||||
cairo_private pixman_region16_t *
|
||||
_cairo_region_create_from_rectangle (cairo_rectangle_t *rect);
|
||||
_cairo_region_create_from_rectangle (cairo_rectangle_fixed_t *rect);
|
||||
|
||||
cairo_private void
|
||||
_cairo_region_extents_rectangle (pixman_region16_t *region,
|
||||
cairo_rectangle_t *rect);
|
||||
_cairo_region_extents_rectangle (pixman_region16_t *region,
|
||||
cairo_rectangle_fixed_t *rect);
|
||||
|
||||
/* cairo_unicode.c */
|
||||
|
||||
@ -2165,14 +2202,37 @@ _cairo_utf8_to_utf16 (const unsigned char *str,
|
||||
|
||||
typedef struct _cairo_output_stream cairo_output_stream_t;
|
||||
|
||||
extern const cairo_private cairo_output_stream_t cairo_output_stream_nil;
|
||||
|
||||
/* We already have the following declared in cairo.h:
|
||||
|
||||
typedef cairo_status_t (*cairo_write_func_t) (void *closure,
|
||||
const unsigned char *data,
|
||||
unsigned int length);
|
||||
*/
|
||||
typedef cairo_status_t (*cairo_close_func_t) (void *closure);
|
||||
|
||||
|
||||
/* This function never returns NULL. If an error occurs (NO_MEMORY)
|
||||
* while trying to create the output stream this function returns a
|
||||
* valid pointer to a nil output stream.
|
||||
*
|
||||
* Note that even with a nil surface, the close_func callback will be
|
||||
* called by a call to _cairo_output_stream_close or
|
||||
* _cairo_output_stream_destroy.
|
||||
*/
|
||||
cairo_private cairo_output_stream_t *
|
||||
_cairo_output_stream_create (cairo_write_func_t write_func,
|
||||
cairo_close_func_t close_func,
|
||||
void *closure);
|
||||
|
||||
cairo_private void
|
||||
_cairo_output_stream_close (cairo_output_stream_t *stream);
|
||||
|
||||
cairo_private void
|
||||
_cairo_output_stream_destroy (cairo_output_stream_t *stream);
|
||||
|
||||
cairo_private cairo_status_t
|
||||
cairo_private void
|
||||
_cairo_output_stream_write (cairo_output_stream_t *stream,
|
||||
const void *data, size_t length);
|
||||
|
||||
@ -2181,21 +2241,14 @@ _cairo_output_stream_write_hex_string (cairo_output_stream_t *stream,
|
||||
const char *data,
|
||||
size_t length);
|
||||
|
||||
cairo_private unsigned char *
|
||||
_cairo_lzw_compress (unsigned char *data, unsigned long *data_size_in_out);
|
||||
|
||||
cairo_private void
|
||||
_cairo_output_stream_write_base85_string (cairo_output_stream_t *stream,
|
||||
const char *data,
|
||||
size_t length);
|
||||
|
||||
cairo_private void *
|
||||
_cairo_compress_lzw (void *data,
|
||||
unsigned long data_size,
|
||||
unsigned long *compressed_size);
|
||||
|
||||
cairo_private cairo_status_t
|
||||
_cairo_output_stream_vprintf (cairo_output_stream_t *stream,
|
||||
const char *fmt, va_list ap);
|
||||
|
||||
cairo_private cairo_status_t
|
||||
cairo_private void
|
||||
_cairo_output_stream_printf (cairo_output_stream_t *stream,
|
||||
const char *fmt, ...) CAIRO_PRINTF_FORMAT(2, 3);
|
||||
|
||||
@ -2205,8 +2258,30 @@ _cairo_output_stream_get_position (cairo_output_stream_t *status);
|
||||
cairo_private cairo_status_t
|
||||
_cairo_output_stream_get_status (cairo_output_stream_t *stream);
|
||||
|
||||
/* This function never returns NULL. If an error occurs (NO_MEMORY or
|
||||
* WRITE_ERROR) while trying to create the output stream this function
|
||||
* returns a valid pointer to a nil output stream.
|
||||
*
|
||||
* NOTE: Even if a nil surface is returned, the caller should still
|
||||
* call _cairo_output_stream_destroy (or _cairo_output_stream_close at
|
||||
* least) in order to ensure that everything is properly cleaned up.
|
||||
*/
|
||||
cairo_private cairo_output_stream_t *
|
||||
_cairo_output_stream_create_for_file (const char *filename);
|
||||
_cairo_output_stream_create_for_filename (const char *filename);
|
||||
|
||||
/* This function never returns NULL. If an error occurs (NO_MEMORY or
|
||||
* WRITE_ERROR) while trying to create the output stream this function
|
||||
* returns a valid pointer to a nil output stream.
|
||||
*
|
||||
* The caller still "owns" file and is responsible for calling fclose
|
||||
* on it when finished. The stream will not do this itself.
|
||||
*/
|
||||
cairo_private cairo_output_stream_t *
|
||||
_cairo_output_stream_create_for_file (FILE *file);
|
||||
|
||||
/* cairo_base85_stream.c */
|
||||
cairo_output_stream_t *
|
||||
_cairo_base85_stream_create (cairo_output_stream_t *output);
|
||||
|
||||
cairo_private void
|
||||
_cairo_error (cairo_status_t status);
|
||||
|
||||
@ -82,7 +82,8 @@ _test_fallback_surface_create (cairo_content_t content,
|
||||
return (cairo_surface_t*) &_cairo_surface_nil;
|
||||
}
|
||||
|
||||
_cairo_surface_init (&surface->base, &test_fallback_surface_backend);
|
||||
_cairo_surface_init (&surface->base, &test_fallback_surface_backend,
|
||||
content);
|
||||
|
||||
surface->backing = backing;
|
||||
|
||||
@ -134,11 +135,11 @@ _test_fallback_surface_release_source_image (void *abstract_surface,
|
||||
}
|
||||
|
||||
static cairo_status_t
|
||||
_test_fallback_surface_acquire_dest_image (void *abstract_surface,
|
||||
cairo_rectangle_t *interest_rect,
|
||||
cairo_image_surface_t**image_out,
|
||||
cairo_rectangle_t *image_rect_out,
|
||||
void **image_extra)
|
||||
_test_fallback_surface_acquire_dest_image (void *abstract_surface,
|
||||
cairo_rectangle_fixed_t *interest_rect,
|
||||
cairo_image_surface_t **image_out,
|
||||
cairo_rectangle_fixed_t *image_rect_out,
|
||||
void **image_extra)
|
||||
{
|
||||
test_fallback_surface_t *surface = abstract_surface;
|
||||
|
||||
@ -150,11 +151,11 @@ _test_fallback_surface_acquire_dest_image (void *abstract_surface,
|
||||
}
|
||||
|
||||
static void
|
||||
_test_fallback_surface_release_dest_image (void *abstract_surface,
|
||||
cairo_rectangle_t *interest_rect,
|
||||
cairo_image_surface_t*image,
|
||||
cairo_rectangle_t *image_rect,
|
||||
void *image_extra)
|
||||
_test_fallback_surface_release_dest_image (void *abstract_surface,
|
||||
cairo_rectangle_fixed_t *interest_rect,
|
||||
cairo_image_surface_t *image,
|
||||
cairo_rectangle_fixed_t *image_rect,
|
||||
void *image_extra)
|
||||
{
|
||||
test_fallback_surface_t *surface = abstract_surface;
|
||||
|
||||
@ -166,8 +167,8 @@ _test_fallback_surface_release_dest_image (void *abstract_surface,
|
||||
}
|
||||
|
||||
static cairo_int_status_t
|
||||
_test_fallback_surface_get_extents (void *abstract_surface,
|
||||
cairo_rectangle_t *rectangle)
|
||||
_test_fallback_surface_get_extents (void *abstract_surface,
|
||||
cairo_rectangle_fixed_t *rectangle)
|
||||
{
|
||||
test_fallback_surface_t *surface = abstract_surface;
|
||||
|
||||
|
||||
@ -78,7 +78,8 @@ _test_meta_surface_create (cairo_content_t content,
|
||||
if (surface == NULL)
|
||||
goto FAIL;
|
||||
|
||||
_cairo_surface_init (&surface->base, &test_meta_surface_backend);
|
||||
_cairo_surface_init (&surface->base, &test_meta_surface_backend,
|
||||
content);
|
||||
|
||||
surface->meta = _cairo_meta_surface_create (content, width, height);
|
||||
if (cairo_surface_status (surface->meta))
|
||||
@ -169,7 +170,7 @@ _test_meta_surface_intersect_clip_path (void *abstract_surface,
|
||||
|
||||
static cairo_int_status_t
|
||||
_test_meta_surface_get_extents (void *abstract_surface,
|
||||
cairo_rectangle_t *rectangle)
|
||||
cairo_rectangle_fixed_t *rectangle)
|
||||
{
|
||||
test_meta_surface_t *surface = abstract_surface;
|
||||
|
||||
@ -279,7 +280,7 @@ _test_meta_surface_snapshot (void *abstract_other)
|
||||
#if 0
|
||||
return _cairo_surface_snapshot (other->meta);
|
||||
#else
|
||||
cairo_rectangle_t extents;
|
||||
cairo_rectangle_fixed_t extents;
|
||||
cairo_surface_t *surface;
|
||||
|
||||
_cairo_surface_get_extents (other->image, &extents);
|
||||
|
||||
@ -51,6 +51,15 @@
|
||||
|
||||
#include "cairo-paginated-surface-private.h"
|
||||
|
||||
typedef struct _test_paginated_surface {
|
||||
cairo_surface_t base;
|
||||
cairo_surface_t *target;
|
||||
cairo_paginated_mode_t paginated_mode;
|
||||
} test_paginated_surface_t;
|
||||
|
||||
static const cairo_surface_backend_t test_paginated_surface_backend;
|
||||
static const cairo_paginated_surface_backend_t test_paginated_surface_paginated_backend;
|
||||
|
||||
cairo_surface_t *
|
||||
_test_paginated_surface_create_for_data (unsigned char *data,
|
||||
cairo_content_t content,
|
||||
@ -58,11 +67,219 @@ _test_paginated_surface_create_for_data (unsigned char *data,
|
||||
int height,
|
||||
int stride)
|
||||
{
|
||||
cairo_status_t status;
|
||||
cairo_surface_t *target;
|
||||
test_paginated_surface_t *surface;
|
||||
|
||||
target = _cairo_image_surface_create_for_data_with_content (data, content,
|
||||
target = _cairo_image_surface_create_for_data_with_content (data, content,
|
||||
width, height,
|
||||
stride);
|
||||
status = cairo_surface_status (target);
|
||||
if (status) {
|
||||
_cairo_error (status);
|
||||
return (cairo_surface_t *) &_cairo_surface_nil;
|
||||
}
|
||||
|
||||
return _cairo_paginated_surface_create (target, content, width, height);
|
||||
surface = malloc (sizeof (test_paginated_surface_t));
|
||||
if (surface == NULL) {
|
||||
_cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
return (cairo_surface_t *) &_cairo_surface_nil;
|
||||
}
|
||||
|
||||
_cairo_surface_init (&surface->base, &test_paginated_surface_backend,
|
||||
content);
|
||||
|
||||
surface->target = target;
|
||||
|
||||
return _cairo_paginated_surface_create (&surface->base, content, width, height,
|
||||
&test_paginated_surface_paginated_backend);
|
||||
}
|
||||
|
||||
static cairo_int_status_t
|
||||
_test_paginated_surface_set_clip_region (void *abstract_surface,
|
||||
pixman_region16_t *region)
|
||||
{
|
||||
test_paginated_surface_t *surface = abstract_surface;
|
||||
|
||||
if (surface->paginated_mode == CAIRO_PAGINATED_MODE_ANALYZE)
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
|
||||
/* XXX: The whole surface backend clipping interface is a giant
|
||||
* disaster right now. In particular, its uncleanness shows up
|
||||
* when trying to implement one surface that wraps another one (as
|
||||
* we are doing here).
|
||||
*
|
||||
* Here are two of the problems that show up:
|
||||
*
|
||||
* 1. The most critical piece of information in all this stuff,
|
||||
* the "clip" isn't getting passed to the backend
|
||||
* functions. Instead the generic surface layer is caching that as
|
||||
* surface->clip. This is a problem for surfaces like this one
|
||||
* that do wrapping. Our base surface will have the clip set, but
|
||||
* our target's surface will not.
|
||||
*
|
||||
* 2. We're here in our backend's set_clip_region function, and we
|
||||
* want to call into our target surface's set_clip_region.
|
||||
* Generally, we would do this by calling an equivalent
|
||||
* _cairo_surface function, but _cairo_surface_set_clip_region
|
||||
* does not have the same signature/semantics, (it has the
|
||||
* clip_serial stuff as well).
|
||||
*
|
||||
* We kludge around each of these by manually copying the clip
|
||||
* object from our base surface into the target's base surface
|
||||
* (yuck!) and by reaching directly into the image surface's
|
||||
* set_clip_region instead of calling into the generic
|
||||
* _cairo_surface_set_clip_region (double yuck!).
|
||||
*/
|
||||
|
||||
surface->target->clip = surface->base.clip;
|
||||
|
||||
return _cairo_image_surface_set_clip_region (surface->target, region);
|
||||
}
|
||||
|
||||
static cairo_int_status_t
|
||||
_test_paginated_surface_get_extents (void *abstract_surface,
|
||||
cairo_rectangle_fixed_t *rectangle)
|
||||
{
|
||||
test_paginated_surface_t *surface = abstract_surface;
|
||||
|
||||
return _cairo_surface_get_extents (surface->target, rectangle);
|
||||
}
|
||||
|
||||
static cairo_int_status_t
|
||||
_test_paginated_surface_paint (void *abstract_surface,
|
||||
cairo_operator_t op,
|
||||
cairo_pattern_t *source)
|
||||
{
|
||||
test_paginated_surface_t *surface = abstract_surface;
|
||||
|
||||
if (surface->paginated_mode == CAIRO_PAGINATED_MODE_ANALYZE)
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
|
||||
return _cairo_surface_paint (surface->target, op, source);
|
||||
}
|
||||
|
||||
static cairo_int_status_t
|
||||
_test_paginated_surface_mask (void *abstract_surface,
|
||||
cairo_operator_t op,
|
||||
cairo_pattern_t *source,
|
||||
cairo_pattern_t *mask)
|
||||
{
|
||||
test_paginated_surface_t *surface = abstract_surface;
|
||||
|
||||
if (surface->paginated_mode == CAIRO_PAGINATED_MODE_ANALYZE)
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
|
||||
return _cairo_surface_mask (surface->target, op, source, mask);
|
||||
}
|
||||
|
||||
static cairo_int_status_t
|
||||
_test_paginated_surface_stroke (void *abstract_surface,
|
||||
cairo_operator_t op,
|
||||
cairo_pattern_t *source,
|
||||
cairo_path_fixed_t *path,
|
||||
cairo_stroke_style_t *style,
|
||||
cairo_matrix_t *ctm,
|
||||
cairo_matrix_t *ctm_inverse,
|
||||
double tolerance,
|
||||
cairo_antialias_t antialias)
|
||||
{
|
||||
test_paginated_surface_t *surface = abstract_surface;
|
||||
|
||||
if (surface->paginated_mode == CAIRO_PAGINATED_MODE_ANALYZE)
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
|
||||
return _cairo_surface_stroke (surface->target, op, source,
|
||||
path, style,
|
||||
ctm, ctm_inverse,
|
||||
tolerance, antialias);
|
||||
}
|
||||
|
||||
static cairo_int_status_t
|
||||
_test_paginated_surface_fill (void *abstract_surface,
|
||||
cairo_operator_t op,
|
||||
cairo_pattern_t *source,
|
||||
cairo_path_fixed_t *path,
|
||||
cairo_fill_rule_t fill_rule,
|
||||
double tolerance,
|
||||
cairo_antialias_t antialias)
|
||||
{
|
||||
test_paginated_surface_t *surface = abstract_surface;
|
||||
|
||||
if (surface->paginated_mode == CAIRO_PAGINATED_MODE_ANALYZE)
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
|
||||
return _cairo_surface_fill (surface->target, op, source,
|
||||
path, fill_rule,
|
||||
tolerance, antialias);
|
||||
}
|
||||
|
||||
static cairo_int_status_t
|
||||
_test_paginated_surface_show_glyphs (void *abstract_surface,
|
||||
cairo_operator_t op,
|
||||
cairo_pattern_t *source,
|
||||
const cairo_glyph_t *glyphs,
|
||||
int num_glyphs,
|
||||
cairo_scaled_font_t *scaled_font)
|
||||
{
|
||||
test_paginated_surface_t *surface = abstract_surface;
|
||||
|
||||
if (surface->paginated_mode == CAIRO_PAGINATED_MODE_ANALYZE)
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
|
||||
return _cairo_surface_show_glyphs (surface->target, op, source,
|
||||
glyphs, num_glyphs, scaled_font);
|
||||
}
|
||||
|
||||
static void
|
||||
_test_paginated_surface_set_paginated_mode (void *abstract_surface,
|
||||
cairo_paginated_mode_t mode)
|
||||
{
|
||||
test_paginated_surface_t *surface = abstract_surface;
|
||||
|
||||
surface->paginated_mode = mode;
|
||||
}
|
||||
|
||||
static const cairo_surface_backend_t test_paginated_surface_backend = {
|
||||
CAIRO_INTERNAL_SURFACE_TYPE_TEST_PAGINATED,
|
||||
|
||||
/* Since we are a paginated user, we get to regard most of the
|
||||
* surface backend interface as historical cruft and ignore it. */
|
||||
|
||||
NULL, /* create_similar */
|
||||
NULL, /* finish */
|
||||
NULL, /* acquire_source_image */
|
||||
NULL, /* release_source_image */
|
||||
NULL, /* acquire_dest_image */
|
||||
NULL, /* release_dest_image */
|
||||
NULL, /* clone_similar */
|
||||
NULL, /* composite */
|
||||
NULL, /* fill_rectangles */
|
||||
NULL, /* composite_trapezoids */
|
||||
NULL, /* copy_page */
|
||||
NULL, /* show_page */
|
||||
_test_paginated_surface_set_clip_region,
|
||||
NULL, /* intersect_clip_path */
|
||||
_test_paginated_surface_get_extents,
|
||||
NULL, /* old_show_glyphs */
|
||||
NULL, /* get_font_options */
|
||||
NULL, /* flush */
|
||||
NULL, /* mark_dirty_rectangle */
|
||||
NULL, /* scaled_font_fini */
|
||||
NULL, /* scaled_glyph_fini */
|
||||
|
||||
/* Here is the more "modern" section of the surface backend
|
||||
* interface which is mostly just drawing functions */
|
||||
|
||||
_test_paginated_surface_paint,
|
||||
_test_paginated_surface_mask,
|
||||
_test_paginated_surface_stroke,
|
||||
_test_paginated_surface_fill,
|
||||
_test_paginated_surface_show_glyphs,
|
||||
NULL /* snapshot */
|
||||
};
|
||||
|
||||
static const cairo_paginated_surface_backend_t test_paginated_surface_paginated_backend = {
|
||||
NULL, /* start_page */
|
||||
_test_paginated_surface_set_paginated_mode
|
||||
};
|
||||
|
||||
@ -430,8 +430,9 @@ nsThebesRenderingContext::Translate(nscoord aX, nscoord aY)
|
||||
NS_IMETHODIMP
|
||||
nsThebesRenderingContext::Scale(float aSx, float aSy)
|
||||
{
|
||||
// as far as I can tell, noone actually calls this
|
||||
PR_LOG(gThebesGFXLog, PR_LOG_DEBUG, ("## %p nsTRC::Scale %f %f\n", this, aSx, aSy));
|
||||
mThebes->Scale (FROM_TWIPS(aSx), FROM_TWIPS(aSy));
|
||||
mThebes->Scale (aSx, aSy);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
||||
@ -104,6 +104,7 @@ endif
|
||||
|
||||
EXTRA_DSO_LDOPTS += $(TK_LIBS)
|
||||
|
||||
DEFINES += -DIMPL_THEBES
|
||||
|
||||
include $(topsrcdir)/config/rules.mk
|
||||
|
||||
|
||||
@ -75,18 +75,17 @@ gfxASurface *gfxContext::OriginalSurface()
|
||||
|
||||
already_AddRefed<gfxASurface> gfxContext::CurrentSurface(gfxFloat *dx, gfxFloat *dy)
|
||||
{
|
||||
cairo_surface_t *s = cairo_get_group_target(mCairo, dx, dy);
|
||||
cairo_surface_t *s = cairo_get_group_target(mCairo);
|
||||
if (!s) {
|
||||
if (dx) {
|
||||
*dx = 0.0;
|
||||
*dy = 0.0;
|
||||
}
|
||||
|
||||
if (dx && dy)
|
||||
cairo_surface_get_device_offset (mSurface->CairoSurface(), dx, dy);
|
||||
gfxASurface *ret = mSurface;
|
||||
NS_ADDREF(ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (dx && dy)
|
||||
cairo_surface_get_device_offset (s, dx, dy);
|
||||
return gfxASurface::Wrap(s);
|
||||
}
|
||||
|
||||
|
||||
@ -815,10 +815,6 @@ nsNativeThemeWin::DrawWidgetBackground(nsIRenderingContext* aContext,
|
||||
|
||||
gfxFloat xoff, yoff;
|
||||
nsRefPtr<gfxASurface> surf = ctx->CurrentSurface(&xoff, &yoff);
|
||||
if (!surf) {
|
||||
surf = ctx->CurrentSurface();
|
||||
xoff = yoff = 0.0;
|
||||
}
|
||||
|
||||
HDC hdc = NS_STATIC_CAST(gfxWindowsSurface*, NS_STATIC_CAST(gfxASurface*, surf.get()))->GetDC();
|
||||
SaveDC(hdc);
|
||||
@ -827,18 +823,12 @@ nsNativeThemeWin::DrawWidgetBackground(nsIRenderingContext* aContext,
|
||||
/* Need to force the clip to be set */
|
||||
ctx->UpdateSurfaceClip();
|
||||
|
||||
//ctx->CurrentSurface()->Flush();
|
||||
|
||||
/* Set the device offsets as appropriate */
|
||||
POINT origViewportOrigin;
|
||||
GetViewportOrgEx(hdc, &origViewportOrigin);
|
||||
SetViewportOrgEx(hdc, origViewportOrigin.x - (int) xoff, origViewportOrigin.y - (int) yoff, NULL);
|
||||
|
||||
/* Covert the current transform to a world transform */
|
||||
gfxMatrix m = ctx->CurrentMatrix();
|
||||
XFORM xform;
|
||||
double dm[6];
|
||||
m.ToValues(&dm[0], &dm[1], &dm[2], &dm[3], &dm[4], &dm[5]);
|
||||
|
||||
xform.eM11 = (FLOAT) dm[0];
|
||||
xform.eM12 = (FLOAT) dm[1];
|
||||
xform.eM21 = (FLOAT) dm[2];
|
||||
@ -847,6 +837,19 @@ nsNativeThemeWin::DrawWidgetBackground(nsIRenderingContext* aContext,
|
||||
xform.eDy = (FLOAT) dm[5];
|
||||
SetWorldTransform (hdc, &xform);
|
||||
|
||||
#if 0
|
||||
fprintf (stderr, "xform: %f %f %f %f [%f %f]\n", dm[0], dm[1], dm[2], dm[3], dm[4], dm[5]);
|
||||
fprintf (stderr, "tr: [%d %d %d %d]\ncr: [%d %d %d %d]\noff: [%f %f]\n",
|
||||
tr.x, tr.y, tr.width, tr.height, cr.x, cr.y, cr.width, cr.height,
|
||||
xoff, yoff);
|
||||
fflush (stderr);
|
||||
#endif
|
||||
|
||||
/* Set the device offsets as appropriate */
|
||||
POINT origViewportOrigin;
|
||||
GetViewportOrgEx(hdc, &origViewportOrigin);
|
||||
SetViewportOrgEx(hdc, origViewportOrigin.x + (int) xoff, origViewportOrigin.y + (int) yoff, NULL);
|
||||
|
||||
#else /* non-MOZ_CAIRO_GFX */
|
||||
|
||||
nsTransform2D* transformMatrix;
|
||||
@ -870,6 +873,13 @@ nsNativeThemeWin::DrawWidgetBackground(nsIRenderingContext* aContext,
|
||||
GetNativeRect(tr, widgetRect);
|
||||
GetNativeRect(cr, clipRect);
|
||||
|
||||
#if 0
|
||||
fprintf (stderr, "widget: [%d %d %d %d]\nclip: [%d %d %d %d]\n",
|
||||
widgetRect.left, widgetRect.top, widgetRect.right, widgetRect.bottom,
|
||||
clipRect.left, clipRect.top, clipRect.right, clipRect.bottom);
|
||||
fflush (stderr);
|
||||
#endif
|
||||
|
||||
// For left edge and right edge tabs, we need to adjust the widget
|
||||
// rects and clip rects so that the edges don't get drawn.
|
||||
if (aWidgetType == NS_THEME_TAB_LEFT_EDGE || aWidgetType == NS_THEME_TAB_RIGHT_EDGE) {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user