--- a/gfx/cairo/README
+++ b/gfx/cairo/README
@@ -2,37 +2,32 @@ Snapshots of cairo and glitz for mozilla
We only include the relevant parts of each release (generally, src/*.[ch]),
as we have Makefile.in's that integrate into the Mozilla build system. For
documentation and similar, please see the official tarballs at
http://www.cairographics.org/.
VERSIONS:
- cairo (1.5.x - c0a7d33ac6c81dd74ee2a9daaa3749a346ef4897)
- pixman (0.9.3 - 0c80a0cd84f30616563cef5910df9deb4f8ed687)
+ cairo (1.4.2)
glitz 0.5.2 (cvs - 2006-01-10)
***** NOTE FOR VISUAL C++ 6.0 *****
VC6 is not supported. Please upgrade to VC8.
==== Patches ====
-All patches in the cairo tree are surrounded by "MOZILLA_CAIRO_NOT_DEFINED"
-(which should obviously not be defined).
+All patches in the cairo tree are surrounded by "MOZILLA_CAIRO_NOT_DEFINED" (which should NOT be defined).
Some specific things:
max-font-size.patch: Clamp freetype font size to 1000 to avoid overflow issues
+fbcompose-bandaid.patch: Disable "optimized" code in non-MMX case due to bugs
+
+quartz-glyph-rounding.patch: Round glyph positions, not advances, to float
+
win32-scaled-font-size.patch: Add cairo_win32_font_face_create_for_logfontw_hfont,
allow win32 scaled_fonts to rescale themselves properly to the required CTM
and only use the font_face's hfont if we're sure it's appropriate
-win32-logical-font-scale.patch: set CAIRO_WIN32_LOGICAL_FONT_SCALE to 1
-
-win32-no-printer-bitblt.patch: If we need to BitBlt from a DC (to do
-fallback), only bother trying if the IS_DISPLAY flag is set -- many
-printers lie about their support for BitBlt, and we end up getting
-black instead of what we want.
-
nonfatal-assertions.patch: Make assertions non-fatal
--- a/gfx/cairo/cairo/src/Makefile.in
+++ b/gfx/cairo/cairo/src/Makefile.in
@@ -76,27 +76,26 @@ CSRCS = \
cairo-array.c \
cairo-bentley-ottmann.c \
cairo-cache.c \
cairo-clip.c \
cairo-color.c \
cairo-debug.c \
cairo-deflate-stream.c \
cairo-fixed.c \
- cairo-font-face.c \
+ cairo-font.c \
cairo-font-options.c \
cairo-freelist.c \
cairo-gstate.c \
cairo-hash.c \
cairo-hull.c \
cairo-image-surface.c \
cairo-lzw.c \
cairo-matrix.c \
cairo-meta-surface.c \
- cairo-mutex.c \
cairo-operator.c \
cairo-output-stream.c \
cairo-paginated-surface.c \
cairo-path.c \
cairo-path-bounds.c \
cairo-path-fill.c \
cairo-path-fixed.c \
cairo-path-stroke.c \
@@ -161,18 +160,17 @@ endif
ifdef BUILD_CAIRO_SVG
CSRCS += cairo-svg-surface.c
EXPORTS += cairo-svg.h
endif
ifdef MOZ_X11
CSRCS += cairo-xlib-surface.c \
- cairo-xlib-screen.c \
- cairo-xlib-display.c
+ cairo-xlib-screen.c
EXPORTS += cairo-xlib.h cairo-xlib-xrender.h
endif
ifdef MOZ_ENABLE_CAIRO_FT
CSRCS += cairo-ft-font.c
EXPORTS += cairo-ft.h
OS_INCLUDES += $(CAIRO_FT_CFLAGS)
endif
@@ -193,12 +191,8 @@ FORCE_USE_PIC = 1
include $(topsrcdir)/config/rules.mk
DEFINES += -DPACKAGE_VERSION="\"moz\"" -DPACKAGE_BUGREPORT="\"http://bugzilla.mozilla.org/\""
ifeq ($(MOZ_WIDGET_TOOLKIT),windows)
DEFINES += -DCAIRO_WIN32_STATIC_BUILD
endif
-
-ifdef MOZ_TREE_CAIRO
-DEFINES += -DMOZ_TREE_CAIRO
-endif
--- a/gfx/cairo/cairo/src/cairo-analysis-surface-private.h
+++ b/gfx/cairo/cairo/src/cairo-analysis-surface-private.h
@@ -1,9 +1,10 @@
-/*
+/* $Id: cairo-analysis-surface-private.h,v 1.10 2007/07/24 19:24:27 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
@@ -37,18 +38,18 @@
#include "cairoint.h"
cairo_private cairo_surface_t *
_cairo_analysis_surface_create (cairo_surface_t *target,
int width,
int height);
-cairo_private cairo_region_t *
+cairo_private pixman_region16_t *
_cairo_analysis_surface_get_supported (cairo_surface_t *surface);
-cairo_private cairo_region_t *
+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 */
--- a/gfx/cairo/cairo/src/cairo-analysis-surface.c
+++ b/gfx/cairo/cairo/src/cairo-analysis-surface.c
@@ -30,31 +30,31 @@
*
* Contributor(s):
* Keith Packard <keithp@keithp.com>
*/
#include "cairoint.h"
#include "cairo-analysis-surface-private.h"
-#include "cairo-paginated-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_int_t *rectangle)
+ cairo_rectangle_int16_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,
@@ -229,24 +229,24 @@ cairo_private cairo_surface_t *
surface->fallback = FALSE;
return &surface->base;
FAIL:
_cairo_error (CAIRO_STATUS_NO_MEMORY);
return NULL;
}
-cairo_private cairo_region_t *
+cairo_private pixman_region16_t *
_cairo_analysis_surface_get_supported (cairo_surface_t *abstract_surface)
{
/* XXX */
return NULL;
}
-cairo_private cairo_region_t *
+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)
--- a/gfx/cairo/cairo/src/cairo-arc.c
+++ b/gfx/cairo/cairo/src/cairo-arc.c
@@ -29,18 +29,16 @@
*
* The Initial Developer of the Original Code is University of Southern
* California.
*
* Contributor(s):
* Carl D. Worth <cworth@cworth.org>
*/
-#include "cairoint.h"
-
#include "cairo-arc-private.h"
/* Spline deviation from the circle in radius would be given by:
error = sqrt (x**2 + y**2) - 1
A simpler error function to work with is:
@@ -82,17 +80,17 @@ static double
{ M_PI / 5.0, 1.11281001494389081528e-06 },
{ M_PI / 6.0, 3.72662000942734705475e-07 },
{ M_PI / 7.0, 1.47783685574284411325e-07 },
{ M_PI / 8.0, 6.63240432022601149057e-08 },
{ M_PI / 9.0, 3.2715520137536980553e-08 },
{ M_PI / 10.0, 1.73863223499021216974e-08 },
{ M_PI / 11.0, 9.81410988043554039085e-09 },
};
- int table_size = ARRAY_LENGTH (table);
+ int table_size = (sizeof (table) / sizeof (table[0]));
for (i = 0; i < table_size; i++)
if (table[i].error < tolerance)
return table[i].angle;
++i;
do {
angle = M_PI / i++;
--- a/gfx/cairo/cairo/src/cairo-atsui-font.c
+++ b/gfx/cairo/cairo/src/cairo-atsui-font.c
@@ -29,20 +29,21 @@
* The Original Code is the cairo graphics library.
*
* The Initial Developer of the Original Code is Calum Robinson
*
* Contributor(s):
* Calum Robinson <calumr@mac.com>
*/
+#include <stdlib.h>
+#include <math.h>
+#include "cairo-atsui.h"
#include "cairoint.h"
-
#include "cairo.h"
-#include "cairo-atsui.h"
#include "cairo-quartz-private.h"
/*
* FixedToFloat/FloatToFixed are 10.3+ SDK items - include definitions
* here so we can use older SDKs.
*/
#ifndef FixedToFloat
#define fixed1 ((Fixed) 0x00010000L)
@@ -111,42 +112,30 @@ static cairo_status_t
cairo_atsui_font_face_t *font_face = abstract_face;
OSStatus err;
ATSUAttributeTag styleTags[] = { kATSUFontTag };
ATSUAttributeValuePtr styleValues[] = { &font_face->font_id };
ByteCount styleSizes[] = { sizeof(ATSUFontID) };
ATSUStyle style;
err = ATSUCreateStyle (&style);
- err = ATSUSetAttributes(style, ARRAY_LENGTH (styleTags),
+ err = ATSUSetAttributes(style,
+ sizeof(styleTags) / sizeof(styleTags[0]),
styleTags, styleSizes, styleValues);
return _cairo_atsui_font_create_scaled (&font_face->base, font_face->font_id, style,
font_matrix, ctm, options, font);
}
static const cairo_font_face_backend_t _cairo_atsui_font_face_backend = {
CAIRO_FONT_TYPE_ATSUI,
_cairo_atsui_font_face_destroy,
_cairo_atsui_font_face_scaled_font_create
};
-/**
- * cairo_atsui_font_face_create_for_atsu_font_id
- * @font_id: an ATSUFontID for the font.
- *
- * Creates a new font for the ATSUI font backend based on an
- * #ATSUFontID. This font can then be used with
- * cairo_set_font_face() or cairo_scaled_font_create().
- *
- * Return value: a newly created #cairo_font_face_t. Free with
- * cairo_font_face_destroy() when you are done using it.
- *
- * Since: 1.4
- **/
cairo_font_face_t *
cairo_atsui_font_face_create_for_atsu_font_id (ATSUFontID font_id)
{
cairo_atsui_font_face_t *font_face;
font_face = malloc (sizeof (cairo_atsui_font_face_t));
if (!font_face) {
_cairo_error (CAIRO_STATUS_NO_MEMORY);
@@ -155,16 +144,24 @@ cairo_atsui_font_face_create_for_atsu_fo
font_face->font_id = font_id;
_cairo_font_face_init (&font_face->base, &_cairo_atsui_font_face_backend);
return &font_face->base;
}
+static CGAffineTransform
+CGAffineTransformMakeWithCairoFontScale(const cairo_matrix_t *scale)
+{
+ return CGAffineTransformMake(scale->xx, scale->yx,
+ scale->xy, scale->yy,
+ 0, 0);
+}
+
static ATSUStyle
CreateSizedCopyOfStyle(ATSUStyle inStyle,
const Fixed *theSize,
const CGAffineTransform *theTransform)
{
ATSUStyle style;
OSStatus err;
const ATSUAttributeTag theFontStyleTags[] = { kATSUSizeTag,
@@ -230,23 +227,18 @@ static cairo_status_t
cairo_status_t status;
double xscale = 1.0;
double yscale = 1.0;
font = malloc(sizeof(cairo_atsui_font_t));
if (font == NULL)
return CAIRO_STATUS_NO_MEMORY;
- status = _cairo_scaled_font_init (&font->base,
- font_face, font_matrix, ctm, options,
- &cairo_atsui_scaled_font_backend);
- if (status) {
- free (font);
- return status;
- }
+ _cairo_scaled_font_init(&font->base, font_face, font_matrix, ctm, options,
+ &cairo_atsui_scaled_font_backend);
_cairo_matrix_compute_scale_factors (&font->base.scale,
&xscale, &yscale, 1);
font->font_matrix = CGAffineTransformMake (1., 0.,
0., yscale/xscale,
0., 0.);
font->size = FloatToFixed (xscale);
@@ -377,17 +369,18 @@ static cairo_status_t
{
ATSUAttributeTag styleTags[] =
{ kATSUQDItalicTag, kATSUQDBoldfaceTag, kATSUFontTag };
ATSUAttributeValuePtr styleValues[] = { &isItalic, &isBold, &fontID };
ByteCount styleSizes[] =
{ sizeof(Boolean), sizeof(Boolean), sizeof(ATSUFontID) };
- err = ATSUSetAttributes(style, ARRAY_LENGTH (styleTags),
+ err = ATSUSetAttributes(style,
+ sizeof(styleTags) / sizeof(styleTags[0]),
styleTags, styleSizes, styleValues);
}
return _cairo_atsui_font_create_scaled (&toy_face->base, fontID, style,
font_matrix, ctm, options, font_out);
}
static void
@@ -399,33 +392,83 @@ static void
return;
if (font->style)
ATSUDisposeStyle(font->style);
if (font->unscaled_style)
ATSUDisposeStyle(font->unscaled_style);
}
+static
+OSStatus _move_to_for_metrics (const Float32Point *point, void *callback_data)
+{
+ CGMutablePathRef path = callback_data;
+
+ CGPathMoveToPoint (path, &CGAffineTransformIdentity,
+ point->x, point->y);
+ return noErr;
+}
+
+static
+OSStatus _line_to_for_metrics(const Float32Point *point, void *callback_data)
+{
+ CGMutablePathRef path = callback_data;
+
+ CGPathAddLineToPoint (path, &CGAffineTransformIdentity,
+ point->x, point->y);
+ return noErr;
+}
+
+static
+OSStatus _curve_to_for_metrics (const Float32Point *point1,
+ const Float32Point *point2,
+ const Float32Point *point3,
+ void *callback_data)
+{
+ CGMutablePathRef path = callback_data;
+
+ CGPathAddCurveToPoint (path, &CGAffineTransformIdentity,
+ point1->x, point1->y,
+ point2->x, point2->y,
+ point3->x, point3->y);
+ return noErr;
+}
+
+static
+OSStatus _close_path_for_metrics(void *callback_data)
+{
+ CGMutablePathRef path = callback_data;
+
+ CGPathCloseSubpath (path);
+ return noErr;
+}
+
static GlyphID
_cairo_atsui_scaled_glyph_index (cairo_scaled_glyph_t *scaled_glyph) {
unsigned long index = _cairo_scaled_glyph_index (scaled_glyph);
if (index > 0xffff)
return kATSDeletedGlyphcode;
return index;
}
static cairo_status_t
_cairo_atsui_font_init_glyph_metrics (cairo_atsui_font_t *scaled_font,
cairo_scaled_glyph_t *scaled_glyph)
{
cairo_text_extents_t extents = {0, 0, 0, 0, 0, 0};
- OSStatus err;
+ OSStatus err, callback_err;
ATSGlyphScreenMetrics metricsH;
+ static ATSCubicMoveToUPP moveProc = NULL;
+ static ATSCubicLineToUPP lineProc = NULL;
+ static ATSCubicCurveToUPP curveProc = NULL;
+ static ATSCubicClosePathUPP closePathProc = NULL;
+ CGMutablePathRef path;
GlyphID theGlyph = _cairo_atsui_scaled_glyph_index (scaled_glyph);
double xscale, yscale;
+ CGRect rect;
if (theGlyph == kATSDeletedGlyphcode) {
_cairo_scaled_glyph_set_metrics (scaled_glyph,
&scaled_font->base,
&extents);
return CAIRO_STATUS_SUCCESS;
}
@@ -441,25 +484,51 @@ static cairo_status_t
/* Scale down to font units.*/
_cairo_matrix_compute_scale_factors (&scaled_font->base.scale,
&xscale, &yscale, 1);
xscale = 1.0/xscale;
yscale = 1.0/yscale;
extents.x_advance = metricsH.deviceAdvance.x * xscale;
extents.y_advance = 0;
-
- extents.x_bearing = metricsH.topLeft.x * xscale;
- extents.y_bearing = -metricsH.topLeft.y * yscale;
- extents.width = metricsH.width * xscale;
- extents.height = metricsH.height * yscale;
+
+ if (moveProc == NULL) {
+ moveProc = NewATSCubicMoveToUPP (_move_to_for_metrics);
+ lineProc = NewATSCubicLineToUPP (_line_to_for_metrics);
+ curveProc = NewATSCubicCurveToUPP (_curve_to_for_metrics);
+ closePathProc = NewATSCubicClosePathUPP (_close_path_for_metrics);
+ }
+
+ path = CGPathCreateMutable ();
+
+ /* The callback error contains any error our functions returned.
+ * Its only meaningful if err != noErr, and we don't currently
+ * use it for anything.
+ */
+ err = ATSUGlyphGetCubicPaths (scaled_font->style, theGlyph,
+ moveProc, lineProc, curveProc, closePathProc,
+ (void *)path, &callback_err);
+
+ if (err != noErr) {
+ CGPathRelease (path);
+ return CAIRO_STATUS_NO_MEMORY;
+ }
+
+ rect = CGPathGetBoundingBox (path);
+
+ extents.x_bearing = rect.origin.x * xscale;
+ extents.y_bearing = rect.origin.y * yscale;
+ extents.width = rect.size.width * xscale;
+ extents.height = rect.size.height * yscale;
_cairo_scaled_glyph_set_metrics (scaled_glyph,
&scaled_font->base,
&extents);
+ CGPathRelease (path);
+
return CAIRO_STATUS_SUCCESS;
}
static OSStatus
_move_to (const Float32Point *point,
void *callback_data)
{
cairo_atsui_scaled_path_t *scaled_path = callback_data;
@@ -593,63 +662,54 @@ static cairo_status_t
static cairo_status_t
_cairo_atsui_scaled_font_init_glyph_surface (cairo_atsui_font_t *scaled_font,
cairo_scaled_glyph_t *scaled_glyph)
{
OSStatus err;
CGContextRef drawingContext;
cairo_image_surface_t *surface;
cairo_format_t format;
- cairo_status_t status;
ATSFontRef atsFont;
CGFontRef cgFont;
cairo_scaled_font_t base = scaled_font->base;
cairo_font_extents_t extents = base.extents;
GlyphID theGlyph = _cairo_atsui_scaled_glyph_index (scaled_glyph);
ATSGlyphScreenMetrics metricsH;
double left, bottom, width, height;
double xscale, yscale;
CGRect bbox;
CGAffineTransform transform;
if (theGlyph == kATSDeletedGlyphcode) {
surface = (cairo_image_surface_t *)cairo_image_surface_create (CAIRO_FORMAT_A8, 2, 2);
- status = cairo_surface_status ((cairo_surface_t *)surface);
- if (status)
- return status;
-
+ if (!surface)
+ return CAIRO_STATUS_NO_MEMORY;
_cairo_scaled_glyph_set_surface (scaled_glyph,
&base,
surface);
return CAIRO_STATUS_SUCCESS;
}
/* Compute a box to contain the glyph mask. The vertical
- * sizes come from the font extents; extra pixels are
+ * sizes come from the font extents; extra pixels are
* added to account for fractional sizes.
*/
height = extents.ascent + extents.descent + 2.0;
bottom = -extents.descent - 1.0;
- _cairo_matrix_compute_scale_factors (&base.scale,
- &xscale, &yscale, 1);
- bbox = CGRectApplyAffineTransform (CGRectMake (1.0, bottom, 1.0, height), CGAffineTransformMakeScale(xscale, yscale));
- bottom = CGRectGetMinY (bbox);
- height = bbox.size.height;
-
/* Horizontal sizes come from the glyph typographic metrics.
* It is possible that this might result in clipped text
* in fonts where the typographic bounds don't cover the ink.
* The width is recalculated, since metricsH.width is rounded.
*/
err = ATSUGlyphGetScreenMetrics (scaled_font->style,
- 1, &theGlyph, 0, false,
+ 1, &theGlyph, 0, false,
false, &metricsH);
left = metricsH.sideBearing.x - 1.0;
width = metricsH.deviceAdvance.x
- metricsH.sideBearing.x
+ metricsH.otherSideBearing.x + 2.0;
/* The xy and yx components are negated because the y-axis
* is flipped into the cairo system then flipped back, ie:
@@ -678,19 +738,18 @@ static cairo_status_t
left = CGRectGetMinX (bbox);
bottom = CGRectGetMinY (bbox);
/* XXX should we select format based on antialiasing flags, as ft does? */
format = CAIRO_FORMAT_A8;
/* create the glyph mask surface */
surface = (cairo_image_surface_t *)cairo_image_surface_create (format, bbox.size.width, bbox.size.height);
- status = cairo_surface_status ((cairo_surface_t *)surface);
- if (status)
- return status;
+ if (!surface)
+ return CAIRO_STATUS_NO_MEMORY;
/* Create a CGBitmapContext for the dest surface for drawing into */
{
CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceGray ();
drawingContext = CGBitmapContextCreate (surface->data,
surface->width,
surface->height,
@@ -804,17 +863,17 @@ static cairo_int_status_t
err = ATSUDirectGetLayoutDataArrayPtrFromTextLayout(textLayout,
0,
kATSUDirectDataLayoutRecordATSLayoutRecordCurrent,
(void *)&layoutRecords,
&glyphCount);
*num_glyphs = glyphCount - 1;
*glyphs =
- (cairo_glyph_t *) _cairo_malloc_ab(*num_glyphs, sizeof (cairo_glyph_t));
+ (cairo_glyph_t *) malloc(*num_glyphs * (sizeof (cairo_glyph_t)));
if (*glyphs == NULL) {
return CAIRO_STATUS_NO_MEMORY;
}
_cairo_matrix_compute_scale_factors (&font->base.ctm, &xscale, &yscale, 1);
device_to_user_scale =
CGAffineTransformInvert (CGAffineTransformMake (xscale, 0,
0, yscale,
--- a/gfx/cairo/cairo/src/cairo-base85-stream.c
+++ b/gfx/cairo/cairo/src/cairo-base85-stream.c
@@ -110,17 +110,17 @@ static cairo_status_t
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;
+ return (cairo_output_stream_t *) &cairo_output_stream_nil;
_cairo_output_stream_init (&stream->base,
_cairo_base85_stream_write,
_cairo_base85_stream_close);
stream->output = output;
stream->pending = 0;
return &stream->base;
--- a/gfx/cairo/cairo/src/cairo-bentley-ottmann.c
+++ b/gfx/cairo/cairo/src/cairo-bentley-ottmann.c
@@ -132,17 +132,16 @@ typedef struct _cairo_bo_event_queue {
/* This structure extends cairo_skip_list_t, which must come first. */
typedef struct _cairo_bo_sweep_line {
cairo_skip_list_t active_edges;
cairo_bo_edge_t *head;
cairo_bo_edge_t *tail;
int32_t current_y;
} cairo_bo_sweep_line_t;
-
static inline int
_cairo_bo_point32_compare (cairo_bo_point32_t const *a,
cairo_bo_point32_t const *b)
{
int cmp = a->y - b->y;
if (cmp) return cmp;
return a->x - b->x;
}
@@ -688,26 +687,23 @@ static void
cairo_bo_point32_t point)
{
event->type = type;
event->e1 = e1;
event->e2 = e2;
event->point = point;
}
-static cairo_status_t
+static void
_cairo_bo_event_queue_insert (cairo_bo_event_queue_t *queue,
cairo_bo_event_t *event)
{
- cairo_status_t status = CAIRO_STATUS_SUCCESS;
/* Don't insert if there's already an equivalent intersection event in the queue. */
- if (_cairo_skip_list_insert (&queue->intersection_queue, event,
- event->type == CAIRO_BO_EVENT_TYPE_INTERSECTION) == NULL)
- status = CAIRO_STATUS_NO_MEMORY;
- return status;
+ _cairo_skip_list_insert (&queue->intersection_queue, event,
+ event->type == CAIRO_BO_EVENT_TYPE_INTERSECTION);
}
static void
_cairo_bo_event_queue_delete (cairo_bo_event_queue_t *queue,
cairo_bo_event_t *event)
{
if (CAIRO_BO_EVENT_TYPE_INTERSECTION == event->type)
_cairo_skip_list_delete_given ( &queue->intersection_queue, &event->elt );
@@ -749,24 +745,26 @@ static cairo_status_t
sizeof (cairo_bo_event_t));
if (0 == num_edges)
return CAIRO_STATUS_SUCCESS;
/* The skip_elt_t field of a cairo_bo_event_t isn't used for start
* or stop events, so this allocation is safe. XXX: make the
* event type a union so it doesn't always contain the skip
* elt? */
- events = _cairo_malloc_ab (num_events, sizeof (cairo_bo_event_t) + sizeof(cairo_bo_event_t*));
- if (events == NULL)
+ events = malloc (num_events * sizeof(cairo_bo_event_t));
+ sorted_event_ptrs = malloc (num_events * sizeof(cairo_bo_event_t*));
+ if (!events || !sorted_event_ptrs) {
+ if (events) free(events);
+ if (sorted_event_ptrs) free(sorted_event_ptrs);
return CAIRO_STATUS_NO_MEMORY;
-
- sorted_event_ptrs = (cairo_bo_event_t **) (events + num_events);
+ }
event_queue->startstop_events = events;
event_queue->sorted_startstop_event_ptrs = sorted_event_ptrs;
- event_queue->num_startstop_events = num_events;
+ event_queue->num_startstop_events = (unsigned)(num_events);
event_queue->next_startstop_event_index = 0;
for (i = 0; i < num_edges; i++) {
sorted_event_ptrs[2*i] = &events[2*i];
sorted_event_ptrs[2*i+1] = &events[2*i+1];
/* Initialize "middle" to top */
edges[i].middle = edges[i].top;
@@ -789,51 +787,53 @@ static cairo_status_t
}
static void
_cairo_bo_event_queue_fini (cairo_bo_event_queue_t *event_queue)
{
_cairo_skip_list_fini (&event_queue->intersection_queue);
if (event_queue->startstop_events)
free (event_queue->startstop_events);
+ if (event_queue->sorted_startstop_event_ptrs)
+ free (event_queue->sorted_startstop_event_ptrs);
}
-static cairo_status_t
+static void
_cairo_bo_event_queue_insert_if_intersect_below_current_y (cairo_bo_event_queue_t *event_queue,
cairo_bo_edge_t *left,
cairo_bo_edge_t *right)
{
cairo_bo_status_t status;
cairo_bo_point32_t intersection;
cairo_bo_event_t event;
if (left == NULL || right == NULL)
- return CAIRO_STATUS_SUCCESS;
+ return;
/* The names "left" and "right" here are correct descriptions of
* the order of the two edges within the active edge list. So if a
* slope comparison also puts left less than right, then we know
* that the intersection of these two segments has oalready
* occurred before the current sweep line position. */
if (_slope_compare (left, right) < 0)
- return CAIRO_STATUS_SUCCESS;
+ return;
status = _cairo_bo_edge_intersect (left, right, &intersection);
if (status == CAIRO_BO_STATUS_PARALLEL ||
status == CAIRO_BO_STATUS_NO_INTERSECTION)
{
- return CAIRO_STATUS_SUCCESS;
+ return;
}
_cairo_bo_event_init (&event,
CAIRO_BO_EVENT_TYPE_INTERSECTION,
left, right,
intersection);
- return _cairo_bo_event_queue_insert (event_queue, &event);
+ _cairo_bo_event_queue_insert (event_queue, &event);
}
static void
_cairo_bo_sweep_line_init (cairo_bo_sweep_line_t *sweep_line)
{
_cairo_skip_list_init (&sweep_line->active_edges,
_sweep_line_elt_compare,
sizeof (sweep_line_elt_t));
@@ -843,28 +843,26 @@ static void
}
static void
_cairo_bo_sweep_line_fini (cairo_bo_sweep_line_t *sweep_line)
{
_cairo_skip_list_fini (&sweep_line->active_edges);
}
-static cairo_status_t
+static void
_cairo_bo_sweep_line_insert (cairo_bo_sweep_line_t *sweep_line,
cairo_bo_edge_t *edge)
{
skip_elt_t *next_elt;
sweep_line_elt_t *sweep_line_elt;
cairo_bo_edge_t **prev_of_next, **next_of_prev;
sweep_line_elt = _cairo_skip_list_insert (&sweep_line->active_edges, &edge,
1 /* unique inserts*/);
- if (sweep_line_elt == NULL)
- return CAIRO_STATUS_NO_MEMORY;
next_elt = sweep_line_elt->elt.next[0];
if (next_elt)
prev_of_next = & (SKIP_ELT_TO_EDGE (next_elt)->prev);
else
prev_of_next = &sweep_line->tail;
if (*prev_of_next)
@@ -873,18 +871,16 @@ static cairo_status_t
next_of_prev = &sweep_line->head;
edge->prev = *prev_of_next;
edge->next = *next_of_prev;
*prev_of_next = edge;
*next_of_prev = edge;
edge->sweep_line_elt = sweep_line_elt;
-
- return CAIRO_STATUS_SUCCESS;
}
static void
_cairo_bo_sweep_line_delete (cairo_bo_sweep_line_t *sweep_line,
cairo_bo_edge_t *edge)
{
cairo_bo_edge_t **left_next, **right_prev;
@@ -1056,16 +1052,17 @@ print_state (const char *msg,
/* Adds the trapezoid, if any, of the left edge to the cairo_traps_t
* of bo_traps. */
static cairo_status_t
_cairo_bo_edge_end_trap (cairo_bo_edge_t *left,
int32_t bot,
cairo_bo_traps_t *bo_traps)
{
cairo_fixed_t fixed_top, fixed_bot;
+ cairo_status_t status = CAIRO_STATUS_SUCCESS;
cairo_bo_trap_t *trap = left->deferred_trap;
cairo_bo_edge_t *right;
if (!trap)
return CAIRO_STATUS_SUCCESS;
/* If the right edge of the trapezoid stopped earlier than the
* left edge, then cut the trapezoid bottom early. */
@@ -1097,36 +1094,35 @@ static cairo_status_t
* TODO: need a real collinearity test here for the cases
* where the trapezoid is degenerate, yet the top and bottom
* coordinates aren't equal. */
if (left_top.x != right_top.x ||
left_top.y != right_top.y ||
left_bot.x != right_bot.x ||
left_bot.y != right_bot.y)
{
- _cairo_traps_add_trap_from_points (bo_traps->traps,
- fixed_top,
- fixed_bot,
- left_top, left_bot,
- right_top, right_bot);
+ status = _cairo_traps_add_trap_from_points (bo_traps->traps,
+ fixed_top,
+ fixed_bot,
+ left_top, left_bot,
+ right_top, right_bot);
#if DEBUG_PRINT_STATE
printf ("Deferred trap: left=(%08x, %08x)-(%08x,%08x) "
"right=(%08x,%08x)-(%08x,%08x) top=%08x, bot=%08x\n",
left->top.x, left->top.y, left->bottom.x, left->bottom.y,
right->top.x, right->top.y, right->bottom.x, right->bottom.y,
trap->top, bot);
#endif
}
}
_cairo_freelist_free (&bo_traps->freelist, trap);
left->deferred_trap = NULL;
-
- return _cairo_traps_status (bo_traps->traps);
+ return status;
}
/* Start a new trapezoid at the given top y coordinate, whose edges
* are `edge' and `edge->next'. If `edge' already has a trapezoid,
* then either add it to the traps in `bo_traps', if the trapezoid's
* right edge differs from `edge->next', or do nothing if the new
* trapezoid would be a continuation of the existing one. */
static cairo_status_t
@@ -1253,30 +1249,27 @@ static cairo_status_t
cairo_fill_rule_t fill_rule,
cairo_traps_t *traps,
cairo_fixed_t xmin,
cairo_fixed_t ymin,
cairo_fixed_t xmax,
cairo_fixed_t ymax,
int *num_intersections)
{
- cairo_status_t status;
+ cairo_status_t status = CAIRO_STATUS_SUCCESS;
int intersection_count = 0;
cairo_bo_event_queue_t event_queue;
cairo_bo_sweep_line_t sweep_line;
cairo_bo_traps_t bo_traps;
cairo_bo_event_t *event, event_saved;
cairo_bo_edge_t *edge;
cairo_bo_edge_t *left, *right;
cairo_bo_edge_t *edge1, *edge2;
- status = _cairo_bo_event_queue_init (&event_queue, edges, num_edges);
- if (status)
- return status;
-
+ _cairo_bo_event_queue_init (&event_queue, edges, num_edges);
_cairo_bo_sweep_line_init (&sweep_line);
_cairo_bo_traps_init (&bo_traps, traps, xmin, ymin, xmax, ymax);
#if DEBUG_PRINT_STATE
print_state ("After initializing", &event_queue, &sweep_line);
#endif
while (1)
@@ -1298,33 +1291,27 @@ static cairo_status_t
event_saved = *event;
_cairo_bo_event_queue_delete (&event_queue, event);
event = &event_saved;
switch (event->type) {
case CAIRO_BO_EVENT_TYPE_START:
edge = event->e1;
- status = _cairo_bo_sweep_line_insert (&sweep_line, edge);
- if (status)
- goto unwind;
+ _cairo_bo_sweep_line_insert (&sweep_line, edge);
/* Cache the insert position for use in pass 2.
event->e2 = Sortlist::prev (sweep_line, edge);
*/
left = edge->prev;
right = edge->next;
- status = _cairo_bo_event_queue_insert_if_intersect_below_current_y (&event_queue, left, edge);
- if (status)
- goto unwind;
+ _cairo_bo_event_queue_insert_if_intersect_below_current_y (&event_queue, left, edge);
- status = _cairo_bo_event_queue_insert_if_intersect_below_current_y (&event_queue, edge, right);
- if (status)
- goto unwind;
+ _cairo_bo_event_queue_insert_if_intersect_below_current_y (&event_queue, edge, right);
#if DEBUG_PRINT_STATE
print_state ("After processing start", &event_queue, &sweep_line);
#endif
_cairo_bo_sweep_line_validate (&sweep_line);
break;
case CAIRO_BO_EVENT_TYPE_STOP:
@@ -1334,19 +1321,17 @@ static cairo_status_t
right = edge->next;
_cairo_bo_sweep_line_delete (&sweep_line, edge);
status = _cairo_bo_edge_end_trap (edge, edge->bottom.y, &bo_traps);
if (status)
goto unwind;
- status = _cairo_bo_event_queue_insert_if_intersect_below_current_y (&event_queue, left, right);
- if (status)
- goto unwind;
+ _cairo_bo_event_queue_insert_if_intersect_below_current_y (&event_queue, left, right);
#if DEBUG_PRINT_STATE
print_state ("After processing stop", &event_queue, &sweep_line);
#endif
_cairo_bo_sweep_line_validate (&sweep_line);
break;
case CAIRO_BO_EVENT_TYPE_INTERSECTION:
@@ -1364,25 +1349,21 @@ static cairo_status_t
left = edge1->prev;
right = edge2->next;
_cairo_bo_sweep_line_swap (&sweep_line, edge1, edge2);
/* after the swap e2 is left of e1 */
- status = _cairo_bo_event_queue_insert_if_intersect_below_current_y (&event_queue,
+ _cairo_bo_event_queue_insert_if_intersect_below_current_y (&event_queue,
left, edge2);
- if (status)
- goto unwind;
- status = _cairo_bo_event_queue_insert_if_intersect_below_current_y (&event_queue,
+ _cairo_bo_event_queue_insert_if_intersect_below_current_y (&event_queue,
edge1, right);
- if (status)
- goto unwind;
#if DEBUG_PRINT_STATE
print_state ("After processing intersection", &event_queue, &sweep_line);
#endif
_cairo_bo_sweep_line_validate (&sweep_line);
break;
}
@@ -1416,35 +1397,30 @@ update_minmax(cairo_fixed_t *inout_min,
cairo_status_t
_cairo_bentley_ottmann_tessellate_polygon (cairo_traps_t *traps,
cairo_polygon_t *polygon,
cairo_fill_rule_t fill_rule)
{
int intersections;
cairo_status_t status;
- cairo_bo_edge_t stack_edges[CAIRO_STACK_BUFFER_SIZE / sizeof (cairo_bo_edge_t)];
cairo_bo_edge_t *edges;
cairo_fixed_t xmin = 0x7FFFFFFF;
cairo_fixed_t ymin = 0x7FFFFFFF;
cairo_fixed_t xmax = -0x80000000;
cairo_fixed_t ymax = -0x80000000;
int num_bo_edges;
int i;
if (0 == polygon->num_edges)
return CAIRO_STATUS_SUCCESS;
- if (polygon->num_edges < ARRAY_LENGTH (stack_edges)) {
- edges = stack_edges;
- } else {
- edges = _cairo_malloc_ab (polygon->num_edges, sizeof (cairo_bo_edge_t));
- if (edges == NULL)
- return CAIRO_STATUS_NO_MEMORY;
- }
+ edges = malloc (polygon->num_edges * sizeof (cairo_bo_edge_t));
+ if (edges == NULL)
+ return CAIRO_STATUS_NO_MEMORY;
/* Figure out the bounding box of the input coordinates and
* validate that we're not given invalid polygon edges. */
for (i = 0; i < polygon->num_edges; i++) {
update_minmax (&xmin, &xmax, polygon->edges[i].edge.p1.x);
update_minmax (&ymin, &ymax, polygon->edges[i].edge.p1.y);
update_minmax (&xmin, &xmax, polygon->edges[i].edge.p2.x);
update_minmax (&ymin, &ymax, polygon->edges[i].edge.p2.y);
@@ -1514,18 +1490,17 @@ cairo_status_t
* passes of the Bentley-Ottmann algorithm. It would merely
* require storing the results of each pass into a temporary
* cairo_traps_t. */
status = _cairo_bentley_ottmann_tessellate_bo_edges (edges, num_bo_edges,
fill_rule, traps,
xmin, ymin, xmax, ymax,
&intersections);
- if (edges != stack_edges)
- free (edges);
+ free (edges);
return status;
}
#if 0
static cairo_bool_t
edges_have_an_intersection_quadratic (cairo_bo_edge_t *edges,
int num_edges)
@@ -1752,17 +1727,17 @@ run_test (const char *test_name,
/* XXX: Multi-pass Bentley-Ottmmann. Preferable would be to add a
* pass of Hobby's tolerance-square algorithm instead. */
passes = 1;
while (intersections) {
int num_edges = _cairo_array_num_elements (&intersected_edges);
passes++;
- edges = _cairo_malloc_ab (num_edges, sizeof (cairo_bo_edge_t));
+ edges = malloc (num_edges * sizeof (cairo_bo_edge_t));
assert (edges != NULL);
memcpy (edges, _cairo_array_index (&intersected_edges, 0), num_edges * sizeof (cairo_bo_edge_t));
_cairo_array_fini (&intersected_edges);
_cairo_array_init (&intersected_edges, sizeof (cairo_bo_edge_t));
intersections = _cairo_bentley_ottmann_intersect_edges (edges, num_edges, &intersected_edges);
free (edges);
if (intersections){
@@ -1791,17 +1766,17 @@ run_test (const char *test_name,
int
main (void)
{
char random_name[] = "random-XX";
cairo_bo_edge_t random_edges[MAX_RANDOM], *edge;
unsigned int i, num_random;
test_t *test;
- for (i = 0; i < ARRAY_LENGTH (tests); i++) {
+ for (i = 0; i < sizeof (tests) / sizeof (tests[0]); i++) {
test = &tests[i];
run_test (test->name, test->edges, test->num_edges);
}
for (num_random = 0; num_random < MAX_RANDOM; num_random++) {
srand (0);
for (i = 0; i < num_random; i++) {
do {
--- a/gfx/cairo/cairo/src/cairo-cache-private.h
+++ b/gfx/cairo/cairo/src/cairo-cache-private.h
@@ -34,17 +34,17 @@
* Keith Packard <keithp@keithp.com>
* Graydon Hoare <graydon@redhat.com>
* Carl Worth <cworth@cworth.org>
*/
#ifndef CAIRO_CACHE_PRIVATE_H
#define CAIRO_CACHE_PRIVATE_H
-#include "cairo-types-private.h"
+typedef struct _cairo_cache cairo_cache_t;
/**
* cairo_cache_entry_t:
*
* A #cairo_cache_entry_t contains both a key and a value for
* cairo_cache_t. User-derived types for cairo_cache_entry_t must
* have a cairo_cache_entry_t as their first field. For example:
*
--- a/gfx/cairo/cairo/src/cairo-cache.c
+++ b/gfx/cairo/cairo/src/cairo-cache.c
@@ -33,16 +33,27 @@
* Contributor(s):
* Keith Packard <keithp@keithp.com>
* Graydon Hoare <graydon@redhat.com>
* Carl Worth <cworth@cworth.org>
*/
#include "cairoint.h"
+struct _cairo_cache {
+ cairo_hash_table_t *hash_table;
+
+ cairo_destroy_func_t entry_destroy;
+
+ unsigned long max_size;
+ unsigned long size;
+
+ int freeze_count;
+};
+
static void
_cairo_cache_remove (cairo_cache_t *cache,
cairo_cache_entry_t *entry);
static void
_cairo_cache_shrink_to_accommodate (cairo_cache_t *cache,
unsigned long additional);
--- a/gfx/cairo/cairo/src/cairo-cff-subset.c
+++ b/gfx/cairo/cairo/src/cairo-cff-subset.c
@@ -32,44 +32,39 @@
* Contributor(s):
* Adrian Johnson <ajohnson@redneon.com>
* Eugeniy Meshcheryakov <eugen@debian.org>
*/
#include "cairoint.h"
#include "cairo-scaled-font-subsets-private.h"
#include "cairo-truetype-subset-private.h"
-#include <string.h>
/* CFF Dict Operators. If the high byte is 0 the command is encoded
* with a single byte. */
#define BASEFONTNAME_OP 0x0c16
-#define CIDCOUNT_OP 0x0c22
#define CHARSET_OP 0x000f
#define CHARSTRINGS_OP 0x0011
#define COPYRIGHT_OP 0x0c00
#define ENCODING_OP 0x0010
#define FAMILYNAME_OP 0x0003
-#define FDARRAY_OP 0x0c24
-#define FDSELECT_OP 0x0c25
-#define FONTBBOX_OP 0x0005
#define FONTNAME_OP 0x0c26
#define FULLNAME_OP 0x0002
#define LOCAL_SUB_OP 0x0013
#define NOTICE_OP 0x0001
#define POSTSCRIPT_OP 0x0c15
#define PRIVATE_OP 0x0012
#define ROS_OP 0x0c1e
-#define UNIQUEID_OP 0x000d
#define VERSION_OP 0x0000
#define WEIGHT_OP 0x0004
-#define XUID_OP 0x000e
#define NUM_STD_STRINGS 391
+#define ARRAY_LENGTH(a) ( (sizeof (a)) / (sizeof ((a)[0])) )
+
typedef struct _cff_header {
uint8_t major;
uint8_t minor;
uint8_t header_size;
uint8_t offset_size;
} cff_header_t;
typedef struct _cff_index_element {
@@ -82,16 +77,23 @@ typedef struct _cff_dict_operator {
cairo_hash_entry_t base;
unsigned short operator;
unsigned char *operand;
int operand_length;
int operand_offset;
} cff_dict_operator_t;
+typedef struct _cff_charset {
+ cairo_bool_t is_builtin;
+ const uint16_t *sids;
+ const unsigned char *data;
+ int length;
+} cff_charset_t;
+
typedef struct _cairo_cff_font {
cairo_scaled_font_subset_t *scaled_font_subset;
const cairo_scaled_font_backend_t *backend;
/* Font Data */
unsigned char *data;
unsigned long data_length;
@@ -101,33 +103,24 @@ typedef struct _cairo_cff_font {
char *font_name;
cairo_hash_table_t *top_dict;
cairo_hash_table_t *private_dict;
cairo_array_t strings_index;
cairo_array_t charstrings_index;
cairo_array_t global_sub_index;
cairo_array_t local_sub_index;
int num_glyphs;
- cairo_bool_t is_cid;
-
- /* CID Font Data */
- int *fdselect;
- unsigned int num_fontdicts;
- cairo_hash_table_t **fd_dict;
- cairo_hash_table_t **fd_private_dict;
- cairo_array_t *fd_local_sub_index;
+ cff_charset_t charset;
+ int charset_offset;
/* Subsetted Font Data */
char *subset_font_name;
cairo_array_t charstrings_subset_index;
cairo_array_t strings_subset_index;
- int *fdselect_subset;
- unsigned int num_subset_fontdicts;
- int *fd_subset_map;
- int *private_dict_offset;
+ cairo_array_t charset_subset;
cairo_array_t output;
/* Subset Metrics */
int *widths;
int x_min, y_min, x_max, y_max;
int ascent, descent;
} cairo_cff_font_t;
@@ -349,16 +342,17 @@ cff_index_write (cairo_array_t *index, c
for (i = 0; i < num_elem; i++) {
element = _cairo_array_index (index, i);
offset += element->length;
encode_index_offset (buf, offset_size, offset);
status = _cairo_array_append_multiple (output, buf, offset_size);
if (status)
return status;
+
}
for (i = 0; i < num_elem; i++) {
element = _cairo_array_index (index, i);
status = _cairo_array_append_multiple (output,
element->data,
element->length);
if (status)
@@ -375,19 +369,17 @@ cff_index_append (cairo_array_t *index,
element.length = length;
element.is_copy = FALSE;
element.data = object;
return _cairo_array_append (index, &element);
}
static cairo_status_t
-cff_index_append_copy (cairo_array_t *index,
- const unsigned char *object,
- unsigned int length)
+cff_index_append_copy (cairo_array_t *index, unsigned char *object , int length)
{
cff_index_element_t element;
element.length = length;
element.is_copy = TRUE;
element.data = malloc (element.length);
if (element.data == NULL)
return CAIRO_STATUS_NO_MEMORY;
@@ -491,31 +483,16 @@ cff_dict_read (cairo_hash_table_t *dict,
}
fail:
_cairo_array_fini (&operands);
return status;
}
-static void
-cff_dict_remove (cairo_hash_table_t *dict, unsigned short operator)
-{
- cff_dict_operator_t key, *op;
-
- _cairo_dict_init_key (&key, operator);
- if (_cairo_hash_table_lookup (dict, &key.base,
- (cairo_hash_entry_t **) &op))
- {
- free (op->operand);
- _cairo_hash_table_remove (dict, (cairo_hash_entry_t *) op);
- free (op);
- }
-}
-
static unsigned char *
cff_dict_get_operands (cairo_hash_table_t *dict,
unsigned short operator,
int *size)
{
cff_dict_operator_t key, *op;
_cairo_dict_init_key (&key, operator);
@@ -581,65 +558,49 @@ cff_dict_get_location (cairo_hash_table_
}
typedef struct _dict_write_info {
cairo_array_t *output;
cairo_status_t status;
} dict_write_info_t;
static void
-cairo_dict_write_operator (cff_dict_operator_t *op, dict_write_info_t *write_info)
+_cairo_dict_collect (void *entry, void *closure)
{
+ dict_write_info_t *write_info = closure;
+ cff_dict_operator_t *op = entry;
unsigned char data;
+ if (write_info->status)
+ return;
+
op->operand_offset = _cairo_array_num_elements (write_info->output);
- write_info->status = _cairo_array_append_multiple (write_info->output, op->operand, op->operand_length);
+ write_info->status = _cairo_array_append_multiple (write_info->output,
+ op->operand,
+ op->operand_length);
if (write_info->status)
return;
if (op->operator & 0xff00) {
data = op->operator >> 8;
write_info->status = _cairo_array_append (write_info->output, &data);
if (write_info->status)
return;
}
data = op->operator & 0xff;
write_info->status = _cairo_array_append (write_info->output, &data);
}
-static void
-_cairo_dict_collect (void *entry, void *closure)
-{
- dict_write_info_t *write_info = closure;
- cff_dict_operator_t *op = entry;
-
- if (write_info->status)
- return;
-
- /* The ROS operator is handled separately in cff_dict_write() */
- if (op->operator != ROS_OP)
- cairo_dict_write_operator (op, write_info);
-}
-
static cairo_status_t
cff_dict_write (cairo_hash_table_t *dict, cairo_array_t *output)
{
dict_write_info_t write_info;
- cff_dict_operator_t key, *op;
write_info.output = output;
write_info.status = CAIRO_STATUS_SUCCESS;
-
- /* The CFF specification requires that the Top Dict of CID fonts
- * begin with the ROS operator. */
- _cairo_dict_init_key (&key, ROS_OP);
- if (_cairo_hash_table_lookup (dict, &key.base,
- (cairo_hash_entry_t **) &op))
- cairo_dict_write_operator (op, &write_info);
-
_cairo_hash_table_foreach (dict, _cairo_dict_collect, &write_info);
return write_info.status;
}
static void
cff_dict_fini (cairo_hash_table_t *dict)
{
@@ -680,163 +641,42 @@ cairo_cff_font_read_name (cairo_cff_font
status = cff_index_read (&index, &font->current_ptr, font->data_end);
cff_index_fini (&index);
return status;
}
static cairo_int_status_t
cairo_cff_font_read_private_dict (cairo_cff_font_t *font,
- cairo_hash_table_t *private_dict,
- cairo_array_t *local_sub_index,
unsigned char *ptr,
int size)
{
unsigned char buf[10];
unsigned char *end_buf;
int offset;
int i;
unsigned char *operand;
unsigned char *p;
- cff_dict_read (private_dict, ptr, size);
- operand = cff_dict_get_operands (private_dict, LOCAL_SUB_OP, &i);
+ cff_dict_read (font->private_dict, ptr, size);
+ operand = cff_dict_get_operands (font->private_dict, LOCAL_SUB_OP, &i);
if (operand) {
decode_integer (operand, &offset);
p = ptr + offset;
- cff_index_read (local_sub_index, &p, font->data_end);
+ cff_index_read (&font->local_sub_index, &p, font->data_end);
/* Use maximum sized encoding to reserve space for later modification. */
end_buf = encode_integer_max (buf, 0);
- cff_dict_set_operands (private_dict, LOCAL_SUB_OP, buf, end_buf - buf);
- }
-
- return CAIRO_STATUS_SUCCESS;
-}
-
-static cairo_int_status_t
-cairo_cff_font_read_fdselect (cairo_cff_font_t *font, unsigned char *p)
-{
- int type, num_ranges, first, last, fd, i, j;
-
- font->fdselect = calloc (font->num_glyphs, sizeof (int));
- if (font->fdselect == NULL)
- return CAIRO_STATUS_NO_MEMORY;
-
- type = *p++;
- if (type == 0)
- {
- for (i = 0; i < font->num_glyphs; i++)
- font->fdselect[i] = *p++;
- } else if (type == 3) {
- num_ranges = be16_to_cpu( *((uint16_t *)p) );
- p += 2;
- for (i = 0; i < num_ranges; i++)
- {
- first = be16_to_cpu( *((uint16_t *)p) );
- p += 2;
- fd = *p++;
- last = be16_to_cpu( *((uint16_t *)p) );
- for (j = first; j < last; j++)
- font->fdselect[j] = fd;
- }
- } else {
- return CAIRO_INT_STATUS_UNSUPPORTED;
+ cff_dict_set_operands (font->private_dict, LOCAL_SUB_OP, buf, end_buf - buf);
}
return CAIRO_STATUS_SUCCESS;
}
static cairo_int_status_t
-cairo_cff_font_read_cid_fontdict (cairo_cff_font_t *font, unsigned char *ptr)
-{
- cairo_array_t index;
- cff_index_element_t *element;
- unsigned int i;
- int size;
- unsigned char *operand;
- int offset;
- cairo_int_status_t status;
- unsigned char buf[100];
- unsigned char *end_buf;
-
- cff_index_init (&index);
- status = cff_index_read (&index, &ptr, font->data_end);
- if (status)
- goto fail;
-
- font->num_fontdicts = _cairo_array_num_elements (&index);
-
- font->fd_dict = calloc (sizeof (cairo_hash_table_t *), font->num_fontdicts);
- if (font->fd_dict == NULL) {
- status = CAIRO_STATUS_NO_MEMORY;
- goto fail;
- }
-
- font->fd_private_dict = calloc (sizeof (cairo_hash_table_t *), font->num_fontdicts);
- if (font->fd_private_dict == NULL) {
- status = CAIRO_STATUS_NO_MEMORY;
- goto fail;
- }
-
- font->fd_local_sub_index = calloc (sizeof (cairo_array_t), font->num_fontdicts);
- if (font->fd_local_sub_index == NULL) {
- status = CAIRO_STATUS_NO_MEMORY;
- goto fail;
- }
-
- for (i = 0; i < font->num_fontdicts; i++) {
- cff_dict_init (&font->fd_dict[i]);
- if (font->fd_dict[i] == NULL) {
- status = CAIRO_STATUS_NO_MEMORY;
- goto fail;
- }
- element = _cairo_array_index (&index, i);
- status = cff_dict_read (font->fd_dict[i], element->data, element->length);
- if (status)
- goto fail;
-
- operand = cff_dict_get_operands (font->fd_dict[i], PRIVATE_OP, &size);
- if (operand == NULL) {
- status = CAIRO_INT_STATUS_UNSUPPORTED;
- goto fail;
- }
- operand = decode_integer (operand, &size);
- decode_integer (operand, &offset);
- cff_dict_init (&font->fd_private_dict[i]);
- if (font->fd_private_dict[i] == NULL) {
- status = CAIRO_STATUS_NO_MEMORY;
- goto fail;
- }
- cff_index_init (&font->fd_local_sub_index[i]);
- status = cairo_cff_font_read_private_dict (font,
- font->fd_private_dict[i],
- &font->fd_local_sub_index[i],
- font->data + offset,
- size);
- if (status)
- goto fail;
- /* Set integer operand to max value to use max size encoding to reserve
- * space for any value later */
- end_buf = encode_integer_max (buf, 0);
- end_buf = encode_integer_max (end_buf, 0);
- status = cff_dict_set_operands (font->fd_dict[i], PRIVATE_OP, buf, end_buf - buf);
- if (status)
- goto fail;
- }
-
- return CAIRO_STATUS_SUCCESS;
-
-fail:
- cff_index_fini (&index);
-
- return status;
-}
-
-static cairo_int_status_t
cairo_cff_font_read_top_dict (cairo_cff_font_t *font)
{
cairo_array_t index;
cff_index_element_t *element;
unsigned char buf[20];
unsigned char *end_buf;
unsigned char *operand;
cairo_int_status_t status;
@@ -845,66 +685,53 @@ cairo_cff_font_read_top_dict (cairo_cff_
int offset;
cff_index_init (&index);
status = cff_index_read (&index, &font->current_ptr, font->data_end);
if (status)
goto fail;
element = _cairo_array_index (&index, 0);
- status = cff_dict_read (font->top_dict, element->data, element->length);
- if (status)
- goto fail;
+ cff_dict_read (font->top_dict, element->data, element->length);
- if (cff_dict_get_operands (font->top_dict, ROS_OP, &size) != NULL)
- font->is_cid = TRUE;
- else
- font->is_cid = FALSE;
+ /* CID fonts are NYI */
+ if (cff_dict_get_operands (font->top_dict, ROS_OP, &size) != NULL) {
+ status = CAIRO_INT_STATUS_UNSUPPORTED;
+ goto fail;
+ }
operand = cff_dict_get_operands (font->top_dict, CHARSTRINGS_OP, &size);
decode_integer (operand, &offset);
p = font->data + offset;
status = cff_index_read (&font->charstrings_index, &p, font->data_end);
if (status)
goto fail;
font->num_glyphs = _cairo_array_num_elements (&font->charstrings_index);
- if (font->is_cid) {
- operand = cff_dict_get_operands (font->top_dict, FDSELECT_OP, &size);
- decode_integer (operand, &offset);
- cairo_cff_font_read_fdselect (font, font->data + offset);
+ operand = cff_dict_get_operands (font->top_dict, PRIVATE_OP, &size);
+ operand = decode_integer (operand, &size);
+ decode_integer (operand, &offset);
+ cairo_cff_font_read_private_dict (font, font->data + offset, size);
- operand = cff_dict_get_operands (font->top_dict, FDARRAY_OP, &size);
- decode_integer (operand, &offset);
- cairo_cff_font_read_cid_fontdict (font, font->data + offset);
- } else {
- operand = cff_dict_get_operands (font->top_dict, PRIVATE_OP, &size);
- operand = decode_integer (operand, &size);
- decode_integer (operand, &offset);
- cairo_cff_font_read_private_dict (font,
- font->private_dict,
- &font->local_sub_index,
- font->data + offset,
- size);
+ operand = cff_dict_get_operands (font->top_dict, CHARSET_OP, &size);
+ if (!operand)
+ font->charset_offset = 0;
+ else {
+ decode_integer (operand, &offset);
+ font->charset_offset = offset;
}
/* Use maximum sized encoding to reserve space for later modification. */
end_buf = encode_integer_max (buf, 0);
cff_dict_set_operands (font->top_dict, CHARSTRINGS_OP, buf, end_buf - buf);
- cff_dict_set_operands (font->top_dict, FDSELECT_OP, buf, end_buf - buf);
- cff_dict_set_operands (font->top_dict, FDARRAY_OP, buf, end_buf - buf);
+ cff_dict_set_operands (font->top_dict, ENCODING_OP, buf, end_buf - buf);
cff_dict_set_operands (font->top_dict, CHARSET_OP, buf, end_buf - buf);
-
- cff_dict_remove (font->top_dict, ENCODING_OP);
- cff_dict_remove (font->top_dict, PRIVATE_OP);
-
- /* Remove the unique identifier operators as the subsetted font is
- * not the same is the original font. */
- cff_dict_remove (font->top_dict, UNIQUEID_OP);
- cff_dict_remove (font->top_dict, XUID_OP);
+ /* Private has two operands - size and offset */
+ end_buf = encode_integer_max (end_buf, 0);
+ cff_dict_set_operands (font->top_dict, PRIVATE_OP, buf, end_buf - buf);
fail:
cff_index_fini (&index);
return status;
}
static cairo_int_status_t
@@ -914,25 +741,159 @@ cairo_cff_font_read_strings (cairo_cff_f
}
static cairo_int_status_t
cairo_cff_font_read_global_subroutines (cairo_cff_font_t *font)
{
return cff_index_read (&font->global_sub_index, &font->current_ptr, font->data_end);
}
+static cairo_int_status_t
+cff_charset_read_data (cff_charset_t *charset, const unsigned char *data,
+ const unsigned char *data_end, int num_glyphs)
+{
+ const unsigned char *p = data;
+
+ num_glyphs -= 1; /* do not count .notdef */
+
+ if (p + 1 > data_end)
+ return CAIRO_INT_STATUS_UNSUPPORTED;
+
+ switch (*p++) {
+ case 0:
+ if (p + num_glyphs*2 > data_end)
+ return CAIRO_INT_STATUS_UNSUPPORTED;
+ charset->is_builtin = FALSE;
+ charset->data = data;
+ charset->length = num_glyphs * 2 + 1;
+ break;
+ case 1:
+ while (num_glyphs > 0) {
+ if (p + 3 > data_end)
+ return CAIRO_INT_STATUS_UNSUPPORTED;
+ num_glyphs -= p[2] + 1;
+ p += 3;
+ }
+ if (num_glyphs < 0)
+ return CAIRO_INT_STATUS_UNSUPPORTED;
+ charset->is_builtin = FALSE;
+ charset->data = data;
+ charset->length = p - data;
+ break;
+ case 2:
+ while (num_glyphs > 0) {
+ if (p + 4 > data_end)
+ return CAIRO_INT_STATUS_UNSUPPORTED;
+ num_glyphs -= be16_to_cpu(*(uint16_t *)(p + 2)) + 1;
+ p += 4;
+ }
+ if (num_glyphs < 0)
+ return CAIRO_INT_STATUS_UNSUPPORTED;
+ charset->is_builtin = FALSE;
+ charset->data = data;
+ charset->length = p - data;
+ break;
+ default:
+ return CAIRO_INT_STATUS_UNSUPPORTED;
+ }
+
+ return CAIRO_STATUS_SUCCESS;
+}
+
+static const uint16_t ISOAdobe_charset[] = {
+ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16,
+ 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30,
+ 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44,
+ 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58,
+ 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72,
+ 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86,
+ 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100,
+ 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111,
+ 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122,
+ 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133,
+ 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144,
+ 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155,
+ 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166,
+ 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177,
+ 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188,
+ 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199,
+ 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210,
+ 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221,
+ 222, 223, 224, 225, 226, 227, 228,
+};
+
+static const uint16_t Expert_charset[] = {
+ 1, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 13,
+ 14, 15, 99, 239, 240, 241, 242, 243, 244, 245, 246, 247,
+ 248, 27, 28, 249, 250, 251, 252, 253, 254, 255, 256, 257,
+ 258, 259, 260, 261, 262, 263, 264, 265, 266, 109, 110,
+ 267, 268, 269, 270, 271, 272, 273, 274, 275, 276, 277,
+ 278, 279, 280, 281, 282, 283, 284, 285, 286, 287, 288,
+ 289, 290, 291, 292, 293, 294, 295, 296, 297, 298, 299,
+ 300, 301, 302, 303, 304, 305, 306, 307, 308, 309, 310,
+ 311, 312, 313, 314, 315, 316, 317, 318, 158, 155, 163,
+ 319, 320, 321, 322, 323, 324, 325, 326, 150, 164, 169,
+ 327, 328, 329, 330, 331, 332, 333, 334, 335, 336, 337,
+ 338, 339, 340, 341, 342, 343, 344, 345, 346, 347, 348,
+ 349, 350, 351, 352, 353, 354, 355, 356, 357, 358, 359,
+ 360, 361, 362, 363, 364, 365, 366, 367, 368, 369, 370,
+ 371, 372, 373, 374, 375, 376, 377, 378,
+};
+
+static const uint16_t ExpertSubset_charset[] = {
+ 1, 231, 232, 235, 236, 237, 238, 13, 14, 15, 99, 239, 240,
+ 241, 242, 243, 244, 245, 246, 247, 248, 27, 28, 249, 250,
+ 251, 253, 254, 255, 256, 257, 258, 259, 260, 261, 262,
+ 263, 264, 265, 266, 109, 110, 267, 268, 269, 270, 272,
+ 300, 301, 302, 305, 314, 315, 158, 155, 163, 320, 321,
+ 322, 323, 324, 325, 326, 150, 164, 169, 327, 328, 329,
+ 330, 331, 332, 333, 334, 335, 336, 337, 338, 339, 340,
+ 341, 342, 343, 344, 345, 346,
+};
+
+static cairo_int_status_t
+cairo_cff_font_read_charset (cairo_cff_font_t *font)
+{
+ switch (font->charset_offset) {
+ case 0:
+ /* ISOAdobe charset */
+ font->charset.is_builtin = TRUE;
+ font->charset.sids = ISOAdobe_charset;
+ font->charset.length = sizeof (ISOAdobe_charset);
+ return CAIRO_STATUS_SUCCESS;
+ case 1:
+ /* Expert charset */
+ font->charset.is_builtin = TRUE;
+ font->charset.sids = Expert_charset;
+ font->charset.length = sizeof (Expert_charset);
+ return CAIRO_STATUS_SUCCESS;
+ case 2:
+ /* ExpertSubset charset */;
+ font->charset.is_builtin = TRUE;
+ font->charset.sids = ExpertSubset_charset;
+ font->charset.length = sizeof (ExpertSubset_charset);
+ return CAIRO_STATUS_SUCCESS;
+ default:
+ break;
+ }
+ return cff_charset_read_data (&font->charset, font->data + (unsigned)font->charset_offset,
+ font->data_end, font->num_glyphs);
+}
+
typedef cairo_int_status_t
(*font_read_t) (cairo_cff_font_t *font);
static const font_read_t font_read_funcs[] = {
cairo_cff_font_read_header,
cairo_cff_font_read_name,
cairo_cff_font_read_top_dict,
cairo_cff_font_read_strings,
cairo_cff_font_read_global_subroutines,
+ /* non-contiguous */
+ cairo_cff_font_read_charset,
};
static cairo_int_status_t
cairo_cff_font_read_font (cairo_cff_font_t *font)
{
cairo_int_status_t status;
unsigned int i;
@@ -940,44 +901,16 @@ cairo_cff_font_read_font (cairo_cff_font
status = font_read_funcs[i] (font);
if (status)
return status;
}
return CAIRO_STATUS_SUCCESS;
}
-static void
-cairo_cff_font_set_ros_strings (cairo_cff_font_t *font)
-{
- unsigned char buf[30];
- unsigned char *p;
- int sid1, sid2;
- const char *registry = "Adobe";
- const char *ordering = "Identity";
-
- sid1 = NUM_STD_STRINGS + _cairo_array_num_elements (&font->strings_subset_index);
- cff_index_append_copy (&font->strings_subset_index,
- (unsigned char *)registry,
- strlen(registry));
-
- sid2 = NUM_STD_STRINGS + _cairo_array_num_elements (&font->strings_subset_index);
- cff_index_append_copy (&font->strings_subset_index,
- (unsigned char *)ordering,
- strlen(ordering));
-
- p = encode_integer (buf, sid1);
- p = encode_integer (p, sid2);
- p = encode_integer (p, 0);
- cff_dict_set_operands (font->top_dict, ROS_OP, buf, p - buf);
-
- p = encode_integer (buf, font->scaled_font_subset->num_glyphs);
- cff_dict_set_operands (font->top_dict, CIDCOUNT_OP, buf, p - buf);
-}
-
static cairo_status_t
cairo_cff_font_subset_dict_string(cairo_cff_font_t *font,
cairo_hash_table_t *dict,
int operator)
{
int size;
unsigned char *p;
int sid;
@@ -1029,156 +962,148 @@ cairo_cff_font_subset_dict_strings (cair
if (status)
return status;
}
return CAIRO_STATUS_SUCCESS;
}
static cairo_status_t
+cairo_cff_font_subset_strings (cairo_cff_font_t *font)
+{
+ cairo_status_t status;
+
+ status = cairo_cff_font_subset_dict_strings (font, font->top_dict);
+ if (status)
+ return status;
+
+ status = cairo_cff_font_subset_dict_strings (font, font->private_dict);
+
+ return status;
+}
+
+static cairo_status_t
cairo_cff_font_subset_charstrings (cairo_cff_font_t *font)
{
cff_index_element_t *element;
unsigned int i;
cairo_status_t status;
+ /* add .notdef */
+ element = _cairo_array_index (&font->charstrings_index, 0);
+ status = cff_index_append (&font->charstrings_subset_index,
+ element->data,
+ element->length);
+ if (status)
+ return status;
+
for (i = 0; i < font->scaled_font_subset->num_glyphs; i++) {
element = _cairo_array_index (&font->charstrings_index,
font->scaled_font_subset->glyphs[i]);
status = cff_index_append (&font->charstrings_subset_index,
element->data,
element->length);
if (status)
return status;
}
return CAIRO_STATUS_SUCCESS;
}
-static cairo_status_t
-cairo_cff_font_subset_fontdict (cairo_cff_font_t *font)
+static uint16_t
+cff_sid_from_gid (const cff_charset_t *charset, int gid)
{
- unsigned int i;
- int fd;
- int *reverse_map;
-
- font->fdselect_subset = calloc (font->scaled_font_subset->num_glyphs,
- sizeof (int));
- if (font->fdselect_subset == NULL)
- return CAIRO_STATUS_NO_MEMORY;
-
- font->fd_subset_map = calloc (font->num_fontdicts, sizeof (int));
- if (font->fd_subset_map == NULL)
- return CAIRO_STATUS_NO_MEMORY;
-
- font->private_dict_offset = calloc (font->num_fontdicts, sizeof (int));
- if (font->private_dict_offset == NULL)
- return CAIRO_STATUS_NO_MEMORY;
+ const uint16_t *sids;
+ const unsigned char *p;
+ int prev_glyph;
- reverse_map = calloc (font->num_fontdicts, sizeof (int));
- if (reverse_map == NULL)
- return CAIRO_STATUS_NO_MEMORY;
-
- for (i = 0; i < font->num_fontdicts; i++)
- reverse_map[i] = -1;
-
- font->num_subset_fontdicts = 0;
- for (i = 0; i < font->scaled_font_subset->num_glyphs; i++) {
- fd = font->fdselect[font->scaled_font_subset->glyphs[i]];
- if (reverse_map[fd] < 0) {
- font->fd_subset_map[font->num_subset_fontdicts] = fd;
- reverse_map[fd] = font->num_subset_fontdicts++;
- }
- font->fdselect_subset[i] = reverse_map[fd];
+ if (charset->is_builtin) {
+ if (gid - 1 < charset->length / 2)
+ return charset->sids[gid - 1];
}
-
- free (reverse_map);
-
- return CAIRO_STATUS_SUCCESS;
+ else {
+ /* no need to check sizes here, this was done during reading */
+ switch (charset->data[0]) {
+ case 0:
+ sids = (const uint16_t *)(charset->data + 1);
+ return be16_to_cpu(sids[gid - 1]);
+ case 1:
+ prev_glyph = 1;
+ for (p = charset->data + 1; p < charset->data + charset->length; p += 3) {
+ if (gid <= prev_glyph + p[2]) {
+ uint16_t sid = be16_to_cpu(*(const uint16_t *)p);
+ return sid + gid - prev_glyph;
+ }
+ prev_glyph += p[2] + 1;
+ }
+ break;
+ case 2:
+ prev_glyph = 1;
+ for (p = charset->data + 1; p < charset->data + charset->length; p += 4) {
+ uint16_t nLeft = be16_to_cpu(*(const uint16_t *)(p + 2));
+ if (gid <= prev_glyph + nLeft) {
+ uint16_t sid = be16_to_cpu(*(const uint16_t *)p);
+ return sid + gid - prev_glyph;
+ }
+ prev_glyph += nLeft + 1;
+ }
+ break;
+ default:
+ break;
+ }
+ }
+ return 0;
}
static cairo_status_t
-cairo_cff_font_create_cid_fontdict (cairo_cff_font_t *font)
+cairo_cff_font_subset_charset (cairo_cff_font_t *font)
{
- unsigned char buf[100];
- unsigned char *end_buf;
-
- font->num_fontdicts = 1;
- font->fd_dict = malloc (sizeof (cairo_hash_table_t *));
- if (font->fd_dict == NULL)
- return CAIRO_STATUS_NO_MEMORY;
-
- cff_dict_init (&font->fd_dict[0]);
-
- font->fd_subset_map = malloc (sizeof (int));
- if (font->fd_subset_map == NULL)
- return CAIRO_STATUS_NO_MEMORY;
-
- font->private_dict_offset = malloc (sizeof (int));
- if (font->private_dict_offset == NULL)
- return CAIRO_STATUS_NO_MEMORY;
-
- font->fd_subset_map[0] = 0;
- font->num_subset_fontdicts = 1;
-
- /* Set integer operand to max value to use max size encoding to reserve
- * space for any value later */
- end_buf = encode_integer_max (buf, 0);
- end_buf = encode_integer_max (end_buf, 0);
- cff_dict_set_operands (font->fd_dict[0], PRIVATE_OP, buf, end_buf - buf);
-
- return CAIRO_STATUS_SUCCESS;
-}
-
-static cairo_status_t
-cairo_cff_font_subset_strings (cairo_cff_font_t *font)
-{
- cairo_status_t status;
unsigned int i;
- status = cairo_cff_font_subset_dict_strings (font, font->top_dict);
- if (status)
- return status;
- if (font->is_cid) {
- for (i = 0; i < font->num_subset_fontdicts; i++) {
- status = cairo_cff_font_subset_dict_strings (font, font->fd_dict[font->fd_subset_map[i]]);
- if (status)
- return status;
+ for (i = 0; i < font->scaled_font_subset->num_glyphs; i++) {
+ int gid = font->scaled_font_subset->glyphs[i];
+ uint16_t original_sid = cff_sid_from_gid(&font->charset, gid);
+ uint16_t new_sid;
+ cff_index_element_t *element;
+ cairo_status_t status;
- status = cairo_cff_font_subset_dict_strings (font, font->fd_private_dict[font->fd_subset_map[i]]);
- if (status)
- return status;
- }
- } else {
- status = cairo_cff_font_subset_dict_strings (font, font->private_dict);
+ if (original_sid >= NUM_STD_STRINGS) {
+ element = _cairo_array_index (&font->strings_index, original_sid - NUM_STD_STRINGS);
+ new_sid = NUM_STD_STRINGS + _cairo_array_num_elements (&font->strings_subset_index);
+ status = cff_index_append (&font->strings_subset_index, element->data, element->length);
+ if (status)
+ return status;
+ }
+ else
+ new_sid = original_sid;
+
+ status = _cairo_array_append(&font->charset_subset, &new_sid);
+ if (status)
+ return status;
}
-
- return status;
+ return CAIRO_STATUS_SUCCESS;
}
static cairo_status_t
cairo_cff_font_subset_font (cairo_cff_font_t *font)
{
cairo_status_t status;
- cairo_cff_font_set_ros_strings (font);
-
- status = cairo_cff_font_subset_charstrings (font);
- if (status)
- return status;
-
- if (font->is_cid)
- cairo_cff_font_subset_fontdict (font);
- else
- cairo_cff_font_create_cid_fontdict (font);
+ /* TODO: subset subroutines */
status = cairo_cff_font_subset_strings (font);
if (status)
return status;
+ status = cairo_cff_font_subset_charstrings (font);
+ if (status)
+ return status;
+
+ status = cairo_cff_font_subset_charset (font);
+
return status;
}
/* Set the operand of the specified operator in the (already written)
* top dict to point to the current position in the output
* array. Operands updated with this function must have previously
* been encoded with the 5-byte (max) integer encoding. */
static void
@@ -1282,255 +1207,114 @@ cairo_cff_font_write_strings (cairo_cff_
static cairo_status_t
cairo_cff_font_write_global_subrs (cairo_cff_font_t *font)
{
return cff_index_write (&font->global_sub_index, &font->output);
}
static cairo_status_t
-cairo_cff_font_write_fdselect (cairo_cff_font_t *font)
+cairo_cff_font_write_encoding (cairo_cff_font_t *font)
{
- unsigned char data;
- unsigned int i;
- cairo_int_status_t status;
-
- cairo_cff_font_set_topdict_operator_to_cur_pos (font, FDSELECT_OP);
-
- if (font->is_cid) {
- data = 0;
- status = _cairo_array_append (&font->output, &data);
- if (status)
- return status;
-
- for (i = 0; i < font->scaled_font_subset->num_glyphs; i++) {
- data = font->fdselect_subset[i];
- status = _cairo_array_append (&font->output, &data);
- if (status)
- return status;
- }
- } else {
- unsigned char byte;
- uint16_t word;
+ unsigned char buf[10];
- status = _cairo_array_grow_by (&font->output, 9);
- if (status)
- return status;
-
- byte = 3;
- status = _cairo_array_append (&font->output, &byte);
- assert (status == CAIRO_STATUS_SUCCESS);
-
- word = cpu_to_be16 (1);
- status = _cairo_array_append_multiple (&font->output, &word, 2);
- assert (status == CAIRO_STATUS_SUCCESS);
+ cairo_cff_font_set_topdict_operator_to_cur_pos (font, ENCODING_OP);
+ buf[0] = 1; /* Format 1 */
+ buf[1] = 1; /* Number of ranges */
+ buf[2] = 0; /* First code in range */
+ /* Codes left in range excluding first */
+ buf[3] = font->scaled_font_subset->num_glyphs - 1;
- word = cpu_to_be16 (0);
- status = _cairo_array_append_multiple (&font->output, &word, 2);
- assert (status == CAIRO_STATUS_SUCCESS);
-
- byte = 0;
- status = _cairo_array_append (&font->output, &byte);
- assert (status == CAIRO_STATUS_SUCCESS);
-
- word = cpu_to_be16 (font->scaled_font_subset->num_glyphs);
- status = _cairo_array_append_multiple (&font->output, &word, 2);
- assert (status == CAIRO_STATUS_SUCCESS);
- }
-
- return CAIRO_STATUS_SUCCESS;
+ return _cairo_array_append_multiple (&font->output, buf, 4);
}
static cairo_status_t
cairo_cff_font_write_charset (cairo_cff_font_t *font)
{
- unsigned char byte;
- uint16_t word;
+ unsigned char format = 0;
+ unsigned int i;
cairo_status_t status;
cairo_cff_font_set_topdict_operator_to_cur_pos (font, CHARSET_OP);
- status = _cairo_array_grow_by (&font->output, 5);
+ status = _cairo_array_append (&font->output, &format);
if (status)
- return status;
-
- byte = 2;
- status = _cairo_array_append (&font->output, &byte);
- assert (status == CAIRO_STATUS_SUCCESS);
+ return status;
- word = cpu_to_be16 (1);
- status = _cairo_array_append_multiple (&font->output, &word, 2);
- assert (status == CAIRO_STATUS_SUCCESS);
-
- word = cpu_to_be16 (font->scaled_font_subset->num_glyphs - 2);
- status = _cairo_array_append_multiple (&font->output, &word, 2);
- assert (status == CAIRO_STATUS_SUCCESS);
-
+ for (i = 0; i < (unsigned)_cairo_array_num_elements(&font->charset_subset); i++) {
+ uint16_t sid = cpu_to_be16(*(uint16_t *)_cairo_array_index(&font->charset_subset, i));
+ status = _cairo_array_append_multiple (&font->output, &sid, sizeof(sid));
+ if (status)
+ return status;
+ }
return CAIRO_STATUS_SUCCESS;
}
static cairo_status_t
cairo_cff_font_write_charstrings (cairo_cff_font_t *font)
{
cairo_cff_font_set_topdict_operator_to_cur_pos (font, CHARSTRINGS_OP);
return cff_index_write (&font->charstrings_subset_index, &font->output);
}
static cairo_status_t
-cairo_cff_font_write_cid_fontdict (cairo_cff_font_t *font)
+cairo_cff_font_write_private_dict_and_local_sub (cairo_cff_font_t *font)
{
- unsigned int i;
- cairo_int_status_t status;
- uint32_t *offset_array;
- int offset_base;
- uint16_t count;
- uint8_t offset_size = 4;
-
- cairo_cff_font_set_topdict_operator_to_cur_pos (font, FDARRAY_OP);
- count = cpu_to_be16 (font->num_subset_fontdicts);
- status = _cairo_array_append_multiple (&font->output, &count, sizeof (uint16_t));
- if (status)
- return status;
- status = _cairo_array_append (&font->output, &offset_size);
- if (status)
- return status;
- status = _cairo_array_allocate (&font->output,
- (font->num_subset_fontdicts + 1)*offset_size,
- (void **) &offset_array);
- if (status)
- return status;
- offset_base = _cairo_array_num_elements (&font->output) - 1;
- *offset_array++ = cpu_to_be32(1);
- for (i = 0; i < font->num_subset_fontdicts; i++) {
- status = cff_dict_write (font->fd_dict[font->fd_subset_map[i]],
- &font->output);
- if (status)
- return status;
- *offset_array++ = cpu_to_be32(_cairo_array_num_elements (&font->output) - offset_base);
- }
-
- return CAIRO_STATUS_SUCCESS;
-}
-
-static cairo_status_t
-cairo_cff_font_write_private_dict (cairo_cff_font_t *font,
- int dict_num,
- cairo_hash_table_t *parent_dict,
- cairo_hash_table_t *private_dict)
-{
- int offset;
+ int offset, private_dict_offset;
int size;
unsigned char buf[10];
unsigned char *buf_end;
unsigned char *p;
cairo_status_t status;
/* Write private dict and update offset and size in top dict */
- font->private_dict_offset[dict_num] = _cairo_array_num_elements (&font->output);
- status = cff_dict_write (private_dict, &font->output);
+ private_dict_offset = _cairo_array_num_elements (&font->output);
+ status = cff_dict_write (font->private_dict, &font->output);
if (status)
return status;
- size = _cairo_array_num_elements (&font->output) - font->private_dict_offset[dict_num];
+ size = _cairo_array_num_elements (&font->output) - private_dict_offset;
/* private entry has two operands - size and offset */
buf_end = encode_integer_max (buf, size);
- buf_end = encode_integer_max (buf_end, font->private_dict_offset[dict_num]);
- offset = cff_dict_get_location (parent_dict, PRIVATE_OP, &size);
+ buf_end = encode_integer_max (buf_end, private_dict_offset);
+ offset = cff_dict_get_location (font->top_dict, PRIVATE_OP, &size);
assert (offset > 0);
p = _cairo_array_index (&font->output, offset);
memcpy (p, buf, buf_end - buf);
- return CAIRO_STATUS_SUCCESS;
-}
-
-static cairo_status_t
-cairo_cff_font_write_local_sub (cairo_cff_font_t *font,
- int dict_num,
- cairo_hash_table_t *private_dict,
- cairo_array_t *local_sub_index)
-{
- int offset;
- int size;
- unsigned char buf[10];
- unsigned char *buf_end;
- unsigned char *p;
- cairo_status_t status;
-
- if (_cairo_array_num_elements (local_sub_index) > 0) {
+ if (_cairo_array_num_elements (&font->local_sub_index) > 0) {
/* Write local subroutines and update offset in private
* dict. Local subroutines offset is relative to start of
* private dict */
- offset = _cairo_array_num_elements (&font->output) - font->private_dict_offset[dict_num];
+ offset = _cairo_array_num_elements (&font->output) - private_dict_offset;
buf_end = encode_integer_max (buf, offset);
- offset = cff_dict_get_location (private_dict, LOCAL_SUB_OP, &size);
+ offset = cff_dict_get_location (font->private_dict, LOCAL_SUB_OP, &size);
assert (offset > 0);
p = _cairo_array_index (&font->output, offset);
memcpy (p, buf, buf_end - buf);
- status = cff_index_write (local_sub_index, &font->output);
+ status = cff_index_write (&font->local_sub_index, &font->output);
if (status)
return status;
}
return CAIRO_STATUS_SUCCESS;
}
-
-static cairo_status_t
-cairo_cff_font_write_cid_private_dict_and_local_sub (cairo_cff_font_t *font)
-{
- unsigned int i;
- cairo_int_status_t status = CAIRO_STATUS_SUCCESS;
-
- if (font->is_cid) {
- for (i = 0; i < font->num_subset_fontdicts; i++) {
- status = cairo_cff_font_write_private_dict (
- font,
- i,
- font->fd_dict[font->fd_subset_map[i]],
- font->fd_private_dict[font->fd_subset_map[i]]);
- if (status)
- return status;
- }
-
- for (i = 0; i < font->num_subset_fontdicts; i++) {
- status = cairo_cff_font_write_local_sub (
- font,
- i,
- font->fd_private_dict[font->fd_subset_map[i]],
- &font->fd_local_sub_index[font->fd_subset_map[i]]);
- if (status)
- return status;
- }
- } else {
- status = cairo_cff_font_write_private_dict (font,
- 0,
- font->fd_dict[0],
- font->private_dict);
- status = cairo_cff_font_write_local_sub (font,
- 0,
- font->private_dict,
- &font->local_sub_index);
- }
-
- return status;
-}
-
typedef cairo_status_t
(*font_write_t) (cairo_cff_font_t *font);
static const font_write_t font_write_funcs[] = {
cairo_cff_font_write_header,
cairo_cff_font_write_name,
cairo_cff_font_write_top_dict,
cairo_cff_font_write_strings,
cairo_cff_font_write_global_subrs,
- cairo_cff_font_write_fdselect,
+ cairo_cff_font_write_encoding,
cairo_cff_font_write_charset,
cairo_cff_font_write_charstrings,
- cairo_cff_font_write_cid_fontdict,
- cairo_cff_font_write_cid_private_dict_and_local_sub,
+ cairo_cff_font_write_private_dict_and_local_sub,
};
static cairo_status_t
cairo_cff_font_write_subset (cairo_cff_font_t *font)
{
cairo_int_status_t status;
unsigned int i;
@@ -1584,17 +1368,17 @@ cairo_cff_font_create_set_widths (cairo_
size = sizeof (tt_hhea_t);
status = font->backend->load_truetype_table (font->scaled_font_subset->scaled_font,
TT_TAG_hhea, 0,
(unsigned char*) &hhea, &size);
if (status)
return status;
num_hmetrics = be16_to_cpu (hhea.num_hmetrics);
- for (i = 1; i < font->scaled_font_subset->num_glyphs; i++) {
+ for (i = 0; i < font->scaled_font_subset->num_glyphs; i++) {
glyph_index = font->scaled_font_subset->glyphs[i];
long_entry_size = 2 * sizeof (int16_t);
short_entry_size = sizeof (int16_t);
if (glyph_index < num_hmetrics) {
status = font->backend->load_truetype_table (font->scaled_font_subset->scaled_font,
TT_TAG_hmtx,
glyph_index * long_entry_size,
buf, &short_entry_size);
@@ -1766,23 +1550,17 @@ static cairo_int_status_t
cff_dict_init (&font->top_dict);
cff_dict_init (&font->private_dict);
cff_index_init (&font->strings_index);
cff_index_init (&font->charstrings_index);
cff_index_init (&font->global_sub_index);
cff_index_init (&font->local_sub_index);
cff_index_init (&font->charstrings_subset_index);
cff_index_init (&font->strings_subset_index);
- font->fdselect = NULL;
- font->fd_dict = NULL;
- font->fd_private_dict = NULL;
- font->fd_local_sub_index = NULL;
- font->fdselect_subset = NULL;
- font->fd_subset_map = NULL;
- font->private_dict_offset = NULL;
+ _cairo_array_init (&font->charset_subset, sizeof(uint16_t));
free (name);
*font_return = font;
return CAIRO_STATUS_SUCCESS;
fail7:
free (font->data);
@@ -1799,67 +1577,29 @@ fail2:
fail1:
free (name);
return status;
}
static void
cairo_cff_font_destroy (cairo_cff_font_t *font)
{
- unsigned int i;
-
free (font->widths);
free (font->font_name);
free (font->subset_font_name);
_cairo_array_fini (&font->output);
cff_dict_fini (font->top_dict);
cff_dict_fini (font->private_dict);
cff_index_fini (&font->strings_index);
cff_index_fini (&font->charstrings_index);
cff_index_fini (&font->global_sub_index);
cff_index_fini (&font->local_sub_index);
cff_index_fini (&font->charstrings_subset_index);
cff_index_fini (&font->strings_subset_index);
-
- /* If we bailed out early as a result of an error some of the
- * following cairo_cff_font_t members may still be NULL */
- if (font->fd_dict) {
- for (i = 0; i < font->num_fontdicts; i++) {
- if (font->fd_dict[i])
- cff_dict_fini (font->fd_dict[i]);
- }
- free (font->fd_dict);
- }
- if (font->fd_subset_map)
- free (font->fd_subset_map);
- if (font->private_dict_offset)
- free (font->private_dict_offset);
-
- if (font->is_cid) {
- if (font->fdselect)
- free (font->fdselect);
- if (font->fdselect_subset)
- free (font->fdselect_subset);
- if (font->fd_private_dict) {
- for (i = 0; i < font->num_fontdicts; i++) {
- if (font->fd_private_dict[i])
- cff_dict_fini (font->fd_private_dict[i]);
- }
- free (font->fd_private_dict);
- }
- if (font->fd_local_sub_index) {
- for (i = 0; i < font->num_fontdicts; i++)
- cff_index_fini (&font->fd_local_sub_index[i]);
- free (font->fd_local_sub_index);
- }
- }
-
- if (font->data)
- free (font->data);
-
+ _cairo_array_fini (&font->charset_subset);
free (font);
}
cairo_status_t
_cairo_cff_subset_init (cairo_cff_subset_t *cff_subset,
const char *subset_name,
cairo_scaled_font_subset_t *font_subset)
{
@@ -1917,220 +1657,8 @@ cairo_status_t
void
_cairo_cff_subset_fini (cairo_cff_subset_t *subset)
{
free (subset->base_font);
free (subset->widths);
free (subset->data);
}
-
-static cairo_int_status_t
-_cairo_cff_font_fallback_create (cairo_scaled_font_subset_t *scaled_font_subset,
- cairo_cff_font_t **font_return,
- const char *subset_name)
-{
- cairo_status_t status;
- cairo_cff_font_t *font;
-
- font = malloc (sizeof (cairo_cff_font_t));
- if (font == NULL)
- return CAIRO_STATUS_NO_MEMORY;
-
- font->backend = NULL;
- font->scaled_font_subset = scaled_font_subset;
-
- _cairo_array_init (&font->output, sizeof (char));
- status = _cairo_array_grow_by (&font->output, 4096);
- if (status)
- goto fail1;
-
- font->subset_font_name = strdup (subset_name);
- if (font->subset_font_name == NULL) {
- status = CAIRO_STATUS_NO_MEMORY;
- goto fail2;
- }
-
- font->font_name = strdup (subset_name);
- if (font->subset_font_name == NULL) {
- status = CAIRO_STATUS_NO_MEMORY;
- goto fail3;
- }
-
- font->x_min = 0;
- font->y_min = 0;
- font->x_max = 0;
- font->y_max = 0;
- font->ascent = 0;
- font->descent = 0;
-
- font->widths = calloc (font->scaled_font_subset->num_glyphs, sizeof (int));
- if (font->widths == NULL) {
- status = CAIRO_STATUS_NO_MEMORY;
- goto fail4;
- }
-
- font->data_length = 0;
- font->data = NULL;
- font->data_end = 0;
-
- cff_dict_init (&font->top_dict);
- cff_dict_init (&font->private_dict);
- cff_index_init (&font->strings_index);
- cff_index_init (&font->charstrings_index);
- cff_index_init (&font->global_sub_index);
- cff_index_init (&font->local_sub_index);
- cff_index_init (&font->charstrings_subset_index);
- cff_index_init (&font->strings_subset_index);
- font->fdselect = NULL;
- font->fd_dict = NULL;
- font->fd_private_dict = NULL;
- font->fd_local_sub_index = NULL;
- font->fdselect_subset = NULL;
- font->fd_subset_map = NULL;
- font->private_dict_offset = NULL;
-
- *font_return = font;
-
- return CAIRO_STATUS_SUCCESS;
-
-fail4:
- free (font->font_name);
-fail3:
- free (font->subset_font_name);
-fail2:
- _cairo_array_fini (&font->output);
-fail1:
- free (font);
- return status;
-}
-
-static cairo_int_status_t
-cairo_cff_font_fallback_generate (cairo_cff_font_t *font,
- cairo_type2_charstrings_t *type2_subset,
- const char **data,
- unsigned long *length)
-{
- cairo_int_status_t status;
- cff_header_t header;
- cairo_array_t *charstring;
- unsigned char buf[40];
- unsigned char *end_buf;
- unsigned int i;
-
- /* Create header */
- header.major = 1;
- header.minor = 0;
- header.header_size = 4;
- header.offset_size = 4;
- font->header = &header;
-
- /* Create Top Dict */
- font->is_cid = FALSE;
- end_buf = encode_integer (buf, type2_subset->x_min);
- end_buf = encode_integer (end_buf, type2_subset->y_min);
- end_buf = encode_integer (end_buf, type2_subset->x_max);
- end_buf = encode_integer (end_buf, type2_subset->y_max);
- cff_dict_set_operands (font->top_dict, FONTBBOX_OP, buf, end_buf - buf);
- end_buf = encode_integer_max (buf, 0);
- cff_dict_set_operands (font->top_dict, CHARSTRINGS_OP, buf, end_buf - buf);
- cff_dict_set_operands (font->top_dict, FDSELECT_OP, buf, end_buf - buf);
- cff_dict_set_operands (font->top_dict, FDARRAY_OP, buf, end_buf - buf);
- cff_dict_set_operands (font->top_dict, CHARSET_OP, buf, end_buf - buf);
- cairo_cff_font_set_ros_strings (font);
-
- /* Create CID FD dictionary */
- cairo_cff_font_create_cid_fontdict (font);
-
- /* Create charstrings */
- for (i = 0; i < font->scaled_font_subset->num_glyphs; i++) {
- charstring = _cairo_array_index(&type2_subset->charstrings, i);
-
- status = cff_index_append (&font->charstrings_subset_index,
- _cairo_array_index (charstring, 0),
- _cairo_array_num_elements (charstring));
-
- if (status)
- return status;
- }
-
- status = cairo_cff_font_write_subset (font);
- if (status)
- return status;
-
- *data = _cairo_array_index (&font->output, 0);
- *length = _cairo_array_num_elements (&font->output);
-
- return CAIRO_STATUS_SUCCESS;
-}
-
-cairo_status_t
-_cairo_cff_fallback_init (cairo_cff_subset_t *cff_subset,
- const char *subset_name,
- cairo_scaled_font_subset_t *font_subset)
-{
- cairo_cff_font_t *font = NULL; /* squelch bogus compiler warning */
- cairo_status_t status;
- const char *data = NULL; /* squelch bogus compiler warning */
- unsigned long length = 0; /* squelch bogus compiler warning */
- unsigned int i;
- cairo_type2_charstrings_t type2_subset;
-
- status = _cairo_cff_font_fallback_create (font_subset, &font, subset_name);
- if (status)
- return status;
-
- status = _cairo_type2_charstrings_init (&type2_subset, font_subset);
- if (status)
- goto fail1;
-
- status = cairo_cff_font_fallback_generate (font, &type2_subset, &data, &length);
- if (status)
- goto fail1;
-
- cff_subset->base_font = strdup (font->font_name);
- if (cff_subset->base_font == NULL)
- goto fail1;
-
- cff_subset->widths = calloc (sizeof (int), font->scaled_font_subset->num_glyphs);
- if (cff_subset->widths == NULL)
- goto fail2;
- for (i = 0; i < font->scaled_font_subset->num_glyphs; i++)
- cff_subset->widths[i] = type2_subset.widths[i];
-
- cff_subset->x_min = type2_subset.x_min;
- cff_subset->y_min = type2_subset.y_min;
- cff_subset->x_max = type2_subset.x_max;
- cff_subset->y_max = type2_subset.y_max;
- cff_subset->ascent = type2_subset.y_max;
- cff_subset->descent = type2_subset.y_min;
-
- _cairo_type2_charstrings_fini (&type2_subset);
-
- cff_subset->data = malloc (length);
- if (cff_subset->data == NULL)
- goto fail3;
-
- memcpy (cff_subset->data, data, length);
- cff_subset->data_length = length;
- cff_subset->data_length = length;
-
- cairo_cff_font_destroy (font);
-
- return CAIRO_STATUS_SUCCESS;
-
- fail3:
- free (cff_subset->widths);
- fail2:
- free (cff_subset->base_font);
- fail1:
- cairo_cff_font_destroy (font);
-
- return status;
-}
-
-void
-_cairo_cff_fallback_fini (cairo_cff_subset_t *subset)
-{
- free (subset->base_font);
- free (subset->widths);
- free (subset->data);
-}
--- a/gfx/cairo/cairo/src/cairo-clip-private.h
+++ b/gfx/cairo/cairo/src/cairo-clip-private.h
@@ -33,17 +33,17 @@
* Kristian Høgsberg <krh@redhat.com>
*/
#ifndef CAIRO_CLIP_PRIVATE_H
#define CAIRO_CLIP_PRIVATE_H
#include "cairo-path-fixed-private.h"
-extern const cairo_private cairo_rectangle_list_t _cairo_rectangles_nil;
+extern cairo_private const cairo_rectangle_list_t _cairo_rectangles_nil;
struct _cairo_clip_path {
unsigned int ref_count;
cairo_path_fixed_t path;
cairo_fill_rule_t fill_rule;
double tolerance;
cairo_antialias_t antialias;
cairo_clip_path_t *prev;
@@ -58,71 +58,73 @@ struct _cairo_clip {
*
* The rectangle here represents the
* portion of the destination surface that this
* clip surface maps to, it does not
* represent the extents of the clip region or
* clip paths
*/
cairo_surface_t *surface;
- cairo_rectangle_int_t surface_rect;
+ cairo_rectangle_int16_t surface_rect;
/*
* Surface clip serial number to store
* in the surface when this clip is set
*/
unsigned int serial;
/*
* A clip region that can be placed in the surface
*/
- cairo_region_t region;
- cairo_bool_t has_region;
+ pixman_region16_t *region;
/*
* If the surface supports path clipping, we store the list of
* clipping paths that has been set here as a linked list.
*/
cairo_clip_path_t *path;
};
cairo_private void
_cairo_clip_init (cairo_clip_t *clip, cairo_surface_t *target);
-cairo_private cairo_status_t
+cairo_private void
+_cairo_clip_fini (cairo_clip_t *clip);
+
+cairo_private void
_cairo_clip_init_copy (cairo_clip_t *clip, cairo_clip_t *other);
-cairo_private cairo_status_t
+cairo_private void
_cairo_clip_init_deep_copy (cairo_clip_t *clip,
cairo_clip_t *other,
cairo_surface_t *target);
-cairo_private void
+cairo_private cairo_status_t
_cairo_clip_reset (cairo_clip_t *clip);
cairo_private cairo_status_t
_cairo_clip_clip (cairo_clip_t *clip,
cairo_path_fixed_t *path,
cairo_fill_rule_t fill_rule,
double tolerance,
cairo_antialias_t antialias,
cairo_surface_t *target);
cairo_private cairo_status_t
_cairo_clip_intersect_to_rectangle (cairo_clip_t *clip,
- cairo_rectangle_int_t *rectangle);
+ cairo_rectangle_int16_t *rectangle);
cairo_private cairo_status_t
_cairo_clip_intersect_to_region (cairo_clip_t *clip,
- cairo_region_t *region);
+ 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_int_t *extents);
+ const cairo_rectangle_int16_t *extents);
cairo_private void
_cairo_clip_translate (cairo_clip_t *clip,
cairo_fixed_t tx,
cairo_fixed_t ty);
cairo_private cairo_rectangle_list_t*
_cairo_clip_copy_rectangle_list (cairo_clip_t *clip, cairo_gstate_t *gstate);
--- a/gfx/cairo/cairo/src/cairo-clip.c
+++ b/gfx/cairo/cairo/src/cairo-clip.c
@@ -1,9 +1,8 @@
-/* -*- Mode: c; tab-width: 8; c-basic-offset: 4; indent-tabs-mode: t; -*- */
/* cairo - a vector graphics library with display and print output
*
* Copyright © 2002 University of Southern California
* Copyright © 2005 Red Hat, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it either under the terms of the GNU Lesser General Public
* License version 2.1 as published by the Free Software Foundation
@@ -57,84 +56,85 @@ void
clip->surface = NULL;
clip->surface_rect.x = 0;
clip->surface_rect.y = 0;
clip->surface_rect.width = 0;
clip->surface_rect.height = 0;
clip->serial = 0;
- _cairo_region_init (&clip->region);
- clip->has_region = FALSE;
+ clip->region = NULL;
clip->path = NULL;
}
-cairo_status_t
+void
+_cairo_clip_fini (cairo_clip_t *clip)
+{
+ cairo_surface_destroy (clip->surface);
+ clip->surface = NULL;
+
+ clip->serial = 0;
+
+ if (clip->region)
+ pixman_region_destroy (clip->region);
+ clip->region = NULL;
+
+ _cairo_clip_path_destroy (clip->path);
+ clip->path = NULL;
+}
+
+void
_cairo_clip_init_copy (cairo_clip_t *clip, cairo_clip_t *other)
{
clip->mode = other->mode;
clip->surface = cairo_surface_reference (other->surface);
clip->surface_rect = other->surface_rect;
clip->serial = other->serial;
- _cairo_region_init (&clip->region);
-
- if (other->has_region) {
- if (_cairo_region_copy (&clip->region, &other->region) !=
- CAIRO_STATUS_SUCCESS)
- {
- _cairo_region_fini (&clip->region);
- cairo_surface_destroy (clip->surface);
- return CAIRO_STATUS_NO_MEMORY;
- }
- clip->has_region = TRUE;
+ if (other->region == NULL) {
+ clip->region = other->region;
} else {
- clip->has_region = FALSE;
+ clip->region = pixman_region_create ();
+ pixman_region_copy (clip->region, other->region);
}
clip->path = _cairo_clip_path_reference (other->path);
-
- return CAIRO_STATUS_SUCCESS;
}
-void
+cairo_status_t
_cairo_clip_reset (cairo_clip_t *clip)
{
/* destroy any existing clip-region artifacts */
cairo_surface_destroy (clip->surface);
clip->surface = NULL;
clip->serial = 0;
- if (clip->has_region) {
- /* _cairo_region_fini just releases the resources used but
- * doesn't bother with leaving the region in a valid state.
- * So _cairo_region_init has to be called afterwards. */
- _cairo_region_fini (&clip->region);
- _cairo_region_init (&clip->region);
-
- clip->has_region = FALSE;
- }
+ if (clip->region)
+ pixman_region_destroy (clip->region);
+ clip->region = NULL;
_cairo_clip_path_destroy (clip->path);
clip->path = NULL;
+
+ return CAIRO_STATUS_SUCCESS;
}
static cairo_status_t
_cairo_clip_path_intersect_to_rectangle (cairo_clip_path_t *clip_path,
- cairo_rectangle_int_t *rectangle)
+ cairo_rectangle_int16_t *rectangle)
{
while (clip_path) {
cairo_status_t status;
cairo_traps_t traps;
cairo_box_t extents;
- cairo_rectangle_int_t extents_rect;
+ cairo_rectangle_int16_t extents_rect;
_cairo_traps_init (&traps);
status = _cairo_path_fixed_fill_to_traps (&clip_path->path,
clip_path->fill_rule,
clip_path->tolerance,
&traps);
if (status) {
@@ -151,100 +151,108 @@ static cairo_status_t
clip_path = clip_path->prev;
}
return CAIRO_STATUS_SUCCESS;
}
cairo_status_t
_cairo_clip_intersect_to_rectangle (cairo_clip_t *clip,
- cairo_rectangle_int_t *rectangle)
+ cairo_rectangle_int16_t *rectangle)
{
if (!clip)
return CAIRO_STATUS_SUCCESS;
if (clip->path) {
cairo_status_t status;
status = _cairo_clip_path_intersect_to_rectangle (clip->path,
rectangle);
if (status)
return status;
}
- if (clip->has_region) {
+ if (clip->region) {
+ pixman_region16_t *intersection;
cairo_status_t status = CAIRO_STATUS_SUCCESS;
- cairo_region_t intersection;
+ pixman_region_status_t pixman_status;
- _cairo_region_init_rect (&intersection, rectangle);
+ intersection = _cairo_region_create_from_rectangle (rectangle);
+ if (intersection == NULL)
+ return CAIRO_STATUS_NO_MEMORY;
- status = _cairo_region_intersect (&intersection, &clip->region,
- &intersection);
+ pixman_status = pixman_region_intersect (intersection,
+ clip->region,
+ intersection);
+ if (pixman_status == PIXMAN_REGION_STATUS_SUCCESS)
+ _cairo_region_extents_rectangle (intersection, rectangle);
+ else
+ status = CAIRO_STATUS_NO_MEMORY;
- if (!status)
- _cairo_region_get_extents (&intersection, rectangle);
+ pixman_region_destroy (intersection);
- _cairo_region_fini (&intersection);
-
- if (status)
- return status;
+ if (status)
+ return status;
}
if (clip->surface)
_cairo_rectangle_intersect (rectangle, &clip->surface_rect);
return CAIRO_STATUS_SUCCESS;
}
cairo_status_t
_cairo_clip_intersect_to_region (cairo_clip_t *clip,
- cairo_region_t *region)
+ pixman_region16_t *region)
{
- cairo_status_t status;
-
if (!clip)
return CAIRO_STATUS_SUCCESS;
if (clip->path) {
/* Intersect clip path into region. */
}
- if (clip->has_region) {
- status = _cairo_region_intersect (region, &clip->region, region);
- if (status)
- return status;
- }
+ if (clip->region)
+ pixman_region_intersect (region, clip->region, region);
if (clip->surface) {
- cairo_region_t clip_rect;
+ pixman_region16_t *clip_rect;
+ pixman_region_status_t pixman_status;
+ cairo_status_t status = CAIRO_STATUS_SUCCESS;
- _cairo_region_init_rect (&clip_rect, &clip->surface_rect);
+ clip_rect = _cairo_region_create_from_rectangle (&clip->surface_rect);
+ if (clip_rect == NULL)
+ return CAIRO_STATUS_NO_MEMORY;
- status = _cairo_region_intersect (region, &clip_rect, region);
+ pixman_status = pixman_region_intersect (region,
+ clip_rect,
+ region);
+ if (pixman_status != PIXMAN_REGION_STATUS_SUCCESS)
+ status = CAIRO_STATUS_NO_MEMORY;
- _cairo_region_fini (&clip_rect);
+ pixman_region_destroy (clip_rect);
- if (status)
- return status;
+ if (status)
+ return status;
}
return CAIRO_STATUS_SUCCESS;
}
/* Combines the region of clip->surface given by extents in
* device backend coordinates into the given temporary surface,
* 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_int_t *extents)
+ const cairo_rectangle_int16_t *extents)
{
cairo_pattern_union_t pattern;
cairo_status_t status;
_cairo_pattern_init_for_surface (&pattern.surface, clip->surface);
status = _cairo_surface_composite (op,
&pattern.base,
@@ -316,67 +324,65 @@ static void
if (clip_path->ref_count)
return;
_cairo_path_fixed_fini (&clip_path->path);
_cairo_clip_path_destroy (clip_path->prev);
free (clip_path);
}
-static cairo_int_status_t
+static cairo_status_t
_cairo_clip_intersect_region (cairo_clip_t *clip,
cairo_traps_t *traps,
cairo_surface_t *target)
{
- cairo_region_t region;
- cairo_int_status_t status;
+ pixman_region16_t *region;
+ cairo_status_t status;
if (clip->mode != CAIRO_CLIP_MODE_REGION)
return CAIRO_INT_STATUS_UNSUPPORTED;
status = _cairo_traps_extract_region (traps, ®ion);
-
if (status)
return status;
- status = CAIRO_STATUS_SUCCESS;
+ if (region == NULL)
+ return CAIRO_INT_STATUS_UNSUPPORTED;
- if (!clip->has_region) {
- status = _cairo_region_copy (&clip->region, ®ion);
- if (status == CAIRO_STATUS_SUCCESS)
- clip->has_region = TRUE;
+ status = CAIRO_STATUS_SUCCESS;
+ if (clip->region == NULL) {
+ clip->region = region;
} else {
- cairo_region_t intersection;
- _cairo_region_init (&intersection);
+ pixman_region16_t *intersection = pixman_region_create();
- status = _cairo_region_intersect (&intersection,
- &clip->region,
- ®ion);
-
- if (status == CAIRO_STATUS_SUCCESS)
- status = _cairo_region_copy (&clip->region, &intersection);
-
- _cairo_region_fini (&intersection);
+ if (pixman_region_intersect (intersection,
+ clip->region, region)
+ == PIXMAN_REGION_STATUS_SUCCESS) {
+ pixman_region_destroy (clip->region);
+ clip->region = intersection;
+ } else {
+ status = CAIRO_STATUS_NO_MEMORY;
+ }
+ pixman_region_destroy (region);
}
clip->serial = _cairo_surface_allocate_clip_serial (target);
- _cairo_region_fini (®ion);
return status;
}
static cairo_status_t
_cairo_clip_intersect_mask (cairo_clip_t *clip,
cairo_traps_t *traps,
cairo_antialias_t antialias,
cairo_surface_t *target)
{
cairo_pattern_union_t pattern;
cairo_box_t extents;
- cairo_rectangle_int_t surface_rect, target_rect;
+ cairo_rectangle_int16_t surface_rect, target_rect;
cairo_surface_t *surface;
cairo_status_t status;
/* Represent the clip as a mask surface. We create a new surface
* the size of the intersection of the old mask surface and the
* extents of the new clip path. */
_cairo_traps_extents (traps, &extents);
@@ -391,26 +397,24 @@ static cairo_status_t
status = _cairo_surface_get_extents (target, &target_rect);
if (!status)
_cairo_rectangle_intersect (&surface_rect, &target_rect);
surface = _cairo_surface_create_similar_solid (target,
CAIRO_CONTENT_ALPHA,
surface_rect.width,
surface_rect.height,
- CAIRO_COLOR_WHITE,
- NULL);
+ CAIRO_COLOR_WHITE);
if (surface->status)
return CAIRO_STATUS_NO_MEMORY;
/* Render the new clipping path into the new mask surface. */
_cairo_traps_translate (traps, -surface_rect.x, -surface_rect.y);
- _cairo_pattern_init_solid (&pattern.solid, CAIRO_COLOR_WHITE,
- CAIRO_CONTENT_COLOR);
+ _cairo_pattern_init_solid (&pattern.solid, CAIRO_COLOR_WHITE);
status = _cairo_surface_composite_trapezoids (CAIRO_OPERATOR_IN,
&pattern.base,
surface,
antialias,
0, 0,
0, 0,
surface_rect.width,
@@ -500,18 +504,18 @@ cairo_status_t
return status;
}
void
_cairo_clip_translate (cairo_clip_t *clip,
cairo_fixed_t tx,
cairo_fixed_t ty)
{
- if (clip->has_region) {
- _cairo_region_translate (&clip->region,
+ if (clip->region) {
+ pixman_region_translate (clip->region,
_cairo_fixed_integer_part (tx),
_cairo_fixed_integer_part (ty));
}
if (clip->surface) {
clip->surface_rect.x += _cairo_fixed_integer_part (tx);
clip->surface_rect.y += _cairo_fixed_integer_part (ty);
}
@@ -540,138 +544,110 @@ static void
_cairo_clip_intersect_path (clip,
&clip_path->path,
clip_path->fill_rule,
clip_path->tolerance,
clip_path->antialias);
}
-cairo_status_t
+void
_cairo_clip_init_deep_copy (cairo_clip_t *clip,
cairo_clip_t *other,
cairo_surface_t *target)
{
_cairo_clip_init (clip, target);
if (other->mode != clip->mode) {
/* We should reapply the original clip path in this case, and let
* whatever the right handling is happen */
} else {
- if (other->has_region) {
- if (_cairo_region_copy (&clip->region, &other->region) !=
- CAIRO_STATUS_SUCCESS)
- goto BAIL;
- clip->has_region = TRUE;
+ if (other->region) {
+ clip->region = pixman_region_create ();
+ pixman_region_copy (clip->region, other->region);
}
if (other->surface) {
- if (_cairo_surface_clone_similar (target, other->surface,
+ _cairo_surface_clone_similar (target, other->surface,
other->surface_rect.x,
other->surface_rect.y,
other->surface_rect.width,
other->surface_rect.height,
- &clip->surface) !=
- CAIRO_STATUS_SUCCESS)
- goto BAIL;
+ &clip->surface);
clip->surface_rect = other->surface_rect;
}
if (other->path) {
_cairo_clip_path_reapply_clip_path (clip, other->path);
}
}
-
- return CAIRO_STATUS_SUCCESS;
-
-BAIL:
- if (clip->has_region)
- _cairo_region_fini (&clip->region);
- if (clip->surface)
- cairo_surface_destroy (clip->surface);
-
- return CAIRO_STATUS_NO_MEMORY;
}
const cairo_rectangle_list_t _cairo_rectangles_nil =
{ CAIRO_STATUS_NO_MEMORY, NULL, 0 };
static const cairo_rectangle_list_t _cairo_rectangles_not_representable =
{ CAIRO_STATUS_CLIP_NOT_REPRESENTABLE, NULL, 0 };
static cairo_bool_t
-_cairo_clip_int_rect_to_user (cairo_gstate_t *gstate,
- cairo_rectangle_int_t *clip_rect,
- cairo_rectangle_t *user_rect)
+_cairo_clip_rect_to_user (cairo_gstate_t *gstate,
+ double x, double y, double width, double height,
+ cairo_rectangle_t *rectangle)
{
+ double x2 = x + width;
+ double y2 = y + height;
cairo_bool_t is_tight;
- double x1 = clip_rect->x;
- double y1 = clip_rect->y;
- double x2 = clip_rect->x + clip_rect->width;
- double y2 = clip_rect->y + clip_rect->height;
-
- _cairo_gstate_backend_to_user_rectangle (gstate, &x1, &y1, &x2, &y2, &is_tight);
-
- user_rect->x = x1;
- user_rect->y = y1;
- user_rect->width = x2 - x1;
- user_rect->height = y2 - y1;
-
+ _cairo_gstate_backend_to_user_rectangle (gstate, &x, &y, &x2, &y2, &is_tight);
+ rectangle->x = x;
+ rectangle->y = y;
+ rectangle->width = x2 - x;
+ rectangle->height = y2 - y;
return is_tight;
}
cairo_private cairo_rectangle_list_t*
_cairo_clip_copy_rectangle_list (cairo_clip_t *clip, cairo_gstate_t *gstate)
{
cairo_rectangle_list_t *list;
- cairo_rectangle_t *rectangles = NULL;
+ cairo_rectangle_t *rectangles;
int n_boxes;
if (clip->path || clip->surface)
- return (cairo_rectangle_list_t*) &_cairo_rectangles_not_representable;
+ return (cairo_rectangle_list_t*) &_cairo_rectangles_not_representable;
- if (clip->has_region) {
- cairo_box_int_t *boxes;
- int i;
-
- if (_cairo_region_get_boxes (&clip->region, &n_boxes, &boxes) != CAIRO_STATUS_SUCCESS)
- return (cairo_rectangle_list_t*) &_cairo_rectangles_nil;
+ n_boxes = clip->region ? pixman_region_num_rects (clip->region) : 1;
+ rectangles = malloc (sizeof (cairo_rectangle_t)*n_boxes);
+ if (rectangles == NULL)
+ return (cairo_rectangle_list_t*) &_cairo_rectangles_nil;
- rectangles = _cairo_malloc_ab (n_boxes, sizeof (cairo_rectangle_t));
- if (rectangles == NULL) {
- _cairo_region_boxes_fini (&clip->region, boxes);
- return (cairo_rectangle_list_t*) &_cairo_rectangles_nil;
- }
-
+ if (clip->region) {
+ pixman_box16_t *boxes;
+ int i;
+
+ boxes = pixman_region_rects (clip->region);
for (i = 0; i < n_boxes; ++i) {
- cairo_rectangle_int_t clip_rect = { boxes[i].p1.x, boxes[i].p1.y,
- boxes[i].p2.x - boxes[i].p1.x,
- boxes[i].p2.y - boxes[i].p1.y };
-
- if (!_cairo_clip_int_rect_to_user(gstate, &clip_rect, &rectangles[i])) {
- _cairo_region_boxes_fini (&clip->region, boxes);
- free (rectangles);
- return (cairo_rectangle_list_t*) &_cairo_rectangles_not_representable;
- }
+ if (!_cairo_clip_rect_to_user(gstate, boxes[i].x1, boxes[i].y1,
+ boxes[i].x2 - boxes[i].x1,
+ boxes[i].y2 - boxes[i].y1,
+ &rectangles[i])) {
+ free (rectangles);
+ return (cairo_rectangle_list_t*)
+ &_cairo_rectangles_not_representable;
+ }
}
} else {
- cairo_rectangle_int_t extents;
-
- n_boxes = 1;
-
- rectangles = malloc(sizeof (cairo_rectangle_t));
- if (rectangles == NULL)
- return (cairo_rectangle_list_t*) &_cairo_rectangles_nil;
-
- if (_cairo_surface_get_extents (_cairo_gstate_get_target (gstate), &extents) ||
- !_cairo_clip_int_rect_to_user(gstate, &extents, rectangles))
- {
- free (rectangles);
- return (cairo_rectangle_list_t*) &_cairo_rectangles_not_representable;
- }
+ cairo_rectangle_int16_t extents;
+ _cairo_surface_get_extents (_cairo_gstate_get_target (gstate), &extents);
+ if (!_cairo_clip_rect_to_user(gstate, extents.x, extents.y,
+ extents.width, extents.height,
+ rectangles)) {
+ free (rectangles);
+ return (cairo_rectangle_list_t*)
+ &_cairo_rectangles_not_representable;
+ }
}
list = malloc (sizeof (cairo_rectangle_list_t));
if (list == NULL) {
free (rectangles);
return (cairo_rectangle_list_t*) &_cairo_rectangles_nil;
}
--- a/gfx/cairo/cairo/src/cairo-color.c
+++ b/gfx/cairo/cairo/src/cairo-color.c
@@ -155,18 +155,8 @@ void
double *blue,
double *alpha)
{
*red = color->red * color->alpha;
*green = color->green * color->alpha;
*blue = color->blue * color->alpha;
*alpha = color->alpha;
}
-
-cairo_bool_t
-_cairo_color_equal (const cairo_color_t *color_a,
- const cairo_color_t *color_b)
-{
- return color_a->red_short == color_b->red_short &&
- color_a->green_short == color_b->green_short &&
- color_a->blue_short == color_b->blue_short &&
- color_a->alpha_short == color_b->alpha_short;
-}
--- a/gfx/cairo/cairo/src/cairo-debug.c
+++ b/gfx/cairo/cairo/src/cairo-debug.c
@@ -54,16 +54,18 @@
* active cairo objects remaining, (ie. the appropriate destroy
* functions have been called as necessary). If there are active cairo
* objects, this call is likely to cause a crash, (eg. an assertion
* failure due to a hash table being destroyed when non-empty).
**/
void
cairo_debug_reset_static_data (void)
{
+#if CAIRO_HAS_XLIB_SURFACE
+ _cairo_xlib_screen_reset_static_data ();
+#endif
+
_cairo_font_reset_static_data ();
#if CAIRO_HAS_FT_FONT
_cairo_ft_font_reset_static_data ();
#endif
-
- _cairo_pattern_reset_static_data ();
}
--- a/gfx/cairo/cairo/src/cairo-deflate-stream.c
+++ b/gfx/cairo/cairo/src/cairo-deflate-stream.c
@@ -114,31 +114,29 @@ static cairo_status_t
cairo_output_stream_t *
_cairo_deflate_stream_create (cairo_output_stream_t *output)
{
cairo_deflate_stream_t *stream;
stream = malloc (sizeof (cairo_deflate_stream_t));
if (stream == NULL)
- return (cairo_output_stream_t *) &_cairo_output_stream_nil;
+ return (cairo_output_stream_t *) &cairo_output_stream_nil;
_cairo_output_stream_init (&stream->base,
_cairo_deflate_stream_write,
_cairo_deflate_stream_close);
stream->output = output;
stream->zlib_stream.zalloc = Z_NULL;
stream->zlib_stream.zfree = Z_NULL;
stream->zlib_stream.opaque = Z_NULL;
- if (deflateInit (&stream->zlib_stream, Z_DEFAULT_COMPRESSION) != Z_OK) {
- free (stream);
- return (cairo_output_stream_t *) &_cairo_output_stream_nil;
- }
+ if (deflateInit (&stream->zlib_stream, Z_DEFAULT_COMPRESSION) != Z_OK)
+ return (cairo_output_stream_t *) &cairo_output_stream_nil;
stream->zlib_stream.next_in = stream->input_buf;
stream->zlib_stream.avail_in = 0;
stream->zlib_stream.next_out = stream->output_buf;
stream->zlib_stream.avail_out = BUFFER_SIZE;
return &stream->base;
}
--- a/gfx/cairo/cairo/src/cairo-directfb-surface.c
+++ b/gfx/cairo/cairo/src/cairo-directfb-surface.c
@@ -30,27 +30,31 @@
* The Initial Developer of the Original Code is University of Southern
* California.
*
* Contributor(s):
* Michael Emmel <mike.emmel@gmail.com>
* Claudio Ciccani <klan@users.sf.net>
*/
-#include "cairoint.h"
-
-#include "cairo-directfb.h"
+#include <stdio.h>
+#include <stdlib.h>
+#include <math.h>
+#include <assert.h>
#include <directfb.h>
#include <direct/types.h>
#include <direct/debug.h>
#include <direct/memcpy.h>
#include <direct/util.h>
+#include "cairo-directfb.h"
+#include "cairoint.h"
+
/*
* Rectangle causes problems (see bugs 361377, 359553, 359243 in Gnome BTS).
*/
#define DFB_RECTANGLES 0
/*
* Composite works fine.
@@ -315,30 +319,30 @@ static IDirectFBSurface*
return NULL;
}
return buffer;
}
static cairo_status_t
_directfb_acquire_surface (cairo_directfb_surface_t *surface,
- cairo_rectangle_int_t *intrest_rec,
+ cairo_rectangle_int16_t *intrest_rec,
cairo_image_surface_t **image_out,
- cairo_rectangle_int_t *image_rect_out,
+ cairo_rectangle_int16_t *image_rect_out,
void **image_extra,
DFBSurfaceLockFlags lock_flags)
{
void *data;
int pitch;
IDirectFBSurface *buffer;
DFBRectangle source_rect;
cairo_format_t cairo_format;
cairo_format = surface->format;
- if (surface->format == (cairo_format_t) -1) {
+ if (surface->format == -1) {
if( intrest_rec ) {
source_rect.x = intrest_rec->x;
source_rect.y = intrest_rec->y;
source_rect.w = intrest_rec->width;
source_rect.h = intrest_rec->height;
}else {
source_rect.x=0;
source_rect.y=0;
@@ -494,35 +498,35 @@ static void
if (surface->dfbsurface != buffer) {
buffer->Release (buffer);
}
cairo_surface_destroy (&image->base);
}
static cairo_status_t
_cairo_directfb_surface_acquire_dest_image (void *abstract_surface,
- cairo_rectangle_int_t *interest_rect,
+ cairo_rectangle_int16_t *interest_rect,
cairo_image_surface_t **image_out,
- cairo_rectangle_int_t *image_rect_out,
+ cairo_rectangle_int16_t *image_rect_out,
void **image_extra)
{
cairo_directfb_surface_t *surface = abstract_surface;
D_DEBUG_AT (Cairo_DirectFB,
"%s( surface=%p ).\n", __FUNCTION__, surface);
return _directfb_acquire_surface (surface,interest_rect,image_out,image_rect_out,image_extra,
DSLF_READ | DSLF_WRITE);
}
static void
_cairo_directfb_surface_release_dest_image (void *abstract_surface,
- cairo_rectangle_int_t *interest_rect,
+ cairo_rectangle_int16_t *interest_rect,
cairo_image_surface_t *image,
- cairo_rectangle_int_t *image_rect,
+ cairo_rectangle_int16_t *image_rect,
void *image_extra)
{
cairo_directfb_surface_t *surface = abstract_surface;
IDirectFBSurface *buffer = image_extra;
D_DEBUG_AT (Cairo_DirectFB,
"%s( surface=%p ).\n", __FUNCTION__, surface);
buffer->Unlock (buffer);
@@ -906,17 +910,17 @@ static cairo_int_status_t
}
#endif /* DFB_COMPOSITE */
#if DFB_RECTANGLES
static cairo_int_status_t
_cairo_directfb_surface_fill_rectangles (void *abstract_surface,
cairo_operator_t op,
const cairo_color_t *color,
- cairo_rectangle_int_t *rects,
+ cairo_rectangle_int16_t *rects,
int n_rects)
{
cairo_directfb_surface_t *dst = abstract_surface;
DFBSurfaceDrawingFlags flags;
DFBSurfaceBlendFunction sblend;
DFBSurfaceBlendFunction dblend;
DFBRectangle r[n_rects];
int i;
@@ -1090,69 +1094,64 @@ static cairo_int_status_t
_directfb_finish_composite (dst, pattern, &src->base, &src_attr);
return ret;
}
#endif /* DFB_COMPOSITE_TRAPEZOIDS */
static cairo_int_status_t
-_cairo_directfb_surface_set_clip_region (void *abstract_surface,
- cairo_region_t *region)
+_cairo_directfb_surface_set_clip_region (void *abstract_surface,
+ pixman_region16_t *region)
{
cairo_directfb_surface_t *surface = abstract_surface;
D_DEBUG_AT (Cairo_DirectFB,
"%s( surface=%p, region=%p ).\n",
__FUNCTION__, surface, region);
if (region) {
- cairo_box_int_t *boxes;
- int n_boxes, i;
-
- if (_cairo_region_get_boxes (region, &n_boxes, &boxes) != CAIRO_STATUS_SUCCESS)
- return CAIRO_STATUS_NO_MEMORY;
-
+ pixman_box16_t *boxes = pixman_region_rects (region);
+ int n_boxes = pixman_region_num_rects (region);
+ int i;
+
if (surface->n_clips != n_boxes) {
if( surface->clips )
free (surface->clips);
- surface->clips = _cairo_malloc_ab (n_boxes, sizeof(DFBRegion));
+ surface->clips = malloc (n_boxes * sizeof(DFBRegion));
if (!surface->clips) {
- _cairo_region_boxes_fini (region, boxes);
surface->n_clips = 0;
return CAIRO_STATUS_NO_MEMORY;
}
surface->n_clips = n_boxes;
}
for (i = 0; i < n_boxes; i++) {
- surface->clips[i].x1 = boxes[i].p1.x;
- surface->clips[i].y1 = boxes[i].p1.y;
- surface->clips[i].x2 = boxes[i].p2.x;
- surface->clips[i].y2 = boxes[i].p2.y;
+ surface->clips[i].x1 = boxes[i].x1;
+ surface->clips[i].y1 = boxes[i].y1;
+ surface->clips[i].x2 = boxes[i].x2;
+ surface->clips[i].y2 = boxes[i].y2;
}
-
- _cairo_region_boxes_fini (region, boxes);
}
else {
if (surface->clips) {
free (surface->clips);
surface->clips = NULL;
surface->n_clips = 0;
}
}
return CAIRO_STATUS_SUCCESS;
}
static cairo_int_status_t
_cairo_directfb_abstract_surface_get_extents (void *abstract_surface,
- cairo_rectangle_int_t *rectangle)
+ cairo_rectangle_int16_t *rectangle)
{
cairo_directfb_surface_t *surface = abstract_surface;
D_DEBUG_AT (Cairo_DirectFB,
"%s( surface=%p, rectangle=%p ).\n",
__FUNCTION__, surface, rectangle);
if (rectangle) {
@@ -1511,27 +1510,16 @@ static cairo_int_status_t
dst->dfbsurface->BatchBlit (dst->dfbsurface,
cache->dfbsurface, rects, points, num));
return CAIRO_STATUS_SUCCESS;
}
#endif /* DFB_SHOW_GLYPHS */
-static cairo_bool_t
-_cairo_directfb_surface_is_similar (void *surface_a,
- void *surface_b,
- cairo_content_t content)
-{
- cairo_directfb_surface_t *a = (cairo_directfb_surface_t *) surface_a;
- cairo_directfb_surface_t *b = (cairo_directfb_surface_t *) surface_b;
-
- return a->dfb == b->dfb;
-}
-
static cairo_surface_backend_t cairo_directfb_surface_backend = {
CAIRO_SURFACE_TYPE_DIRECTFB, /*type*/
_cairo_directfb_surface_create_similar,/*create_similar*/
_cairo_directfb_surface_finish, /*finish*/
_cairo_directfb_surface_acquire_source_image,/*acquire_source_image*/
_cairo_directfb_surface_release_source_image,/*release_source_image*/
_cairo_directfb_surface_acquire_dest_image,/*acquire_dest_image*/
_cairo_directfb_surface_release_dest_image,/*release_dest_image*/
@@ -1571,19 +1559,17 @@ static cairo_surface_backend_t cairo_dir
NULL, /* mask */
NULL, /* stroke */
NULL, /* fill */
#if DFB_SHOW_GLYPHS
_cairo_directfb_surface_show_glyphs,/*show_glyphs*/
#else
NULL, /* show_glyphs */
#endif
- NULL, /* snapshot */
- _cairo_directfb_surface_is_similar,
- NULL /* reset */
+ NULL /* snapshot */
};
static void
cairo_directfb_surface_backend_init (IDirectFB *dfb)
{
DFBGraphicsDeviceDescription dsc;
static int done = 0;
--- a/gfx/cairo/cairo/src/cairo-directfb.h
+++ b/gfx/cairo/cairo/src/cairo-directfb.h
@@ -36,18 +36,16 @@
#ifndef CAIRO_DIRECTFB_H
#define CAIRO_DIRECTFB_H
#include <cairo.h>
#ifdef CAIRO_HAS_DIRECTFB_SURFACE
-#include <directfb.h>
-
CAIRO_BEGIN_DECLS
cairo_public cairo_surface_t *
cairo_directfb_surface_create (IDirectFB *dfb,IDirectFBSurface *surface);
CAIRO_END_DECLS
#else /*CAIRO_HAS_DIRECTFB_SURFACE*/
--- a/gfx/cairo/cairo/src/cairo-features.h.in
+++ b/gfx/cairo/cairo/src/cairo-features.h.in
@@ -47,31 +47,29 @@
# define CAIRO_END_DECLS
#endif
#ifndef cairo_public
# define cairo_public
#endif
#define CAIRO_VERSION_MAJOR 1
-#define CAIRO_VERSION_MINOR 5
-#define CAIRO_VERSION_MICRO 1
+#define CAIRO_VERSION_MINOR 4
+#define CAIRO_VERSION_MICRO 2
-#define CAIRO_VERSION_STRING "1.5.1"
+#define CAIRO_VERSION_STRING "1.4.2"
@PS_SURFACE_FEATURE@
@PDF_SURFACE_FEATURE@
@SVG_SURFACE_FEATURE@
@XLIB_SURFACE_FEATURE@
-@XLIB_XRENDER_SURFACE_FEATURE@
-
@QUARTZ_SURFACE_FEATURE@
@XCB_SURFACE_FEATURE@
@WIN32_SURFACE_FEATURE@
@OS2_SURFACE_FEATURE@
--- a/gfx/cairo/cairo/src/cairo-fixed.c
+++ b/gfx/cairo/cairo/src/cairo-fixed.c
@@ -31,9 +31,107 @@
* California.
*
* Contributor(s):
* Carl D. Worth <cworth@cworth.org>
*/
#include "cairoint.h"
-#include "cairo-fixed-private.h"
+cairo_fixed_t
+_cairo_fixed_from_int (int i)
+{
+ return i << 16;
+}
+
+/* This is the "magic number" approach to converting a double into fixed
+ * point as described here:
+ *
+ * http://www.stereopsis.com/sree/fpu2006.html (an overview)
+ * http://www.d6.com/users/checker/pdfs/gdmfp.pdf (in detail)
+ *
+ * The basic idea is to add a large enough number to the double that the
+ * literal floating point is moved up to the extent that it forces the
+ * double's value to be shifted down to the bottom of the mantissa (to make
+ * room for the large number being added in). Since the mantissa is, at a
+ * given moment in time, a fixed point integer itself, one can convert a
+ * float to various fixed point representations by moving around the point
+ * of a floating point number through arithmetic operations. This behavior
+ * is reliable on most modern platforms as it is mandated by the IEEE-754
+ * standard for floating point arithmetic.
+ *
+ * For our purposes, a "magic number" must be carefully selected that is
+ * both large enough to produce the desired point-shifting effect, and also
+ * has no lower bits in its representation that would interfere with our
+ * value at the bottom of the mantissa. The magic number is calculated as
+ * follows:
+ *
+ * (2 ^ (MANTISSA_SIZE - FRACTIONAL_SIZE)) * 1.5
+ *
+ * where in our case:
+ * - MANTISSA_SIZE for 64-bit doubles is 52
+ * - FRACTIONAL_SIZE for 16.16 fixed point is 16
+ *
+ * Although this approach provides a very large speedup of this function
+ * on a wide-array of systems, it does come with two caveats:
+ *
+ * 1) It uses banker's rounding as opposed to arithmetic rounding.
+ * 2) It doesn't function properly if the FPU is in single-precision
+ * mode.
+ */
+#define CAIRO_MAGIC_NUMBER_FIXED_16_16 (103079215104.0)
+cairo_fixed_t
+_cairo_fixed_from_double (double d)
+{
+ union {
+ double d;
+ int32_t i[2];
+ } u;
+
+ u.d = d + CAIRO_MAGIC_NUMBER_FIXED_16_16;
+#ifdef FLOAT_WORDS_BIGENDIAN
+ return u.i[1];
+#else
+ return u.i[0];
+#endif
+}
+
+cairo_fixed_t
+_cairo_fixed_from_26_6 (uint32_t i)
+{
+ return i << 10;
+}
+
+double
+_cairo_fixed_to_double (cairo_fixed_t f)
+{
+ return ((double) f) / 65536.0;
+}
+
+int
+_cairo_fixed_is_integer (cairo_fixed_t f)
+{
+ return (f & 0xFFFF) == 0;
+}
+
+int
+_cairo_fixed_integer_part (cairo_fixed_t f)
+{
+ return f >> 16;
+}
+
+int
+_cairo_fixed_integer_floor (cairo_fixed_t f)
+{
+ if (f >= 0)
+ return f >> 16;
+ else
+ return -((-f - 1) >> 16) - 1;
+}
+
+int
+_cairo_fixed_integer_ceil (cairo_fixed_t f)
+{
+ if (f > 0)
+ return ((f - 1)>>16) + 1;
+ else
+ return - (-f >> 16);
+}
--- a/gfx/cairo/cairo/src/cairo-font-options.c
+++ b/gfx/cairo/cairo/src/cairo-font-options.c
@@ -31,33 +31,33 @@
* California.
*
* Contributor(s):
* Owen Taylor <otaylor@redhat.com>
*/
#include "cairoint.h"
-static const cairo_font_options_t _cairo_font_options_nil = {
+static const cairo_font_options_t cairo_font_options_nil = {
CAIRO_ANTIALIAS_DEFAULT,
CAIRO_SUBPIXEL_ORDER_DEFAULT,
CAIRO_HINT_STYLE_DEFAULT,
CAIRO_HINT_METRICS_DEFAULT
};
/**
* _cairo_font_options_init_default:
* @options: a #cairo_font_options_t
*
* Initializes all fields of the font options object to default values.
**/
void
_cairo_font_options_init_default (cairo_font_options_t *options)
{
- if (options == (cairo_font_options_t *)&_cairo_font_options_nil)
+ if (options == (cairo_font_options_t *)&cairo_font_options_nil)
return;
options->antialias = CAIRO_ANTIALIAS_DEFAULT;
options->subpixel_order = CAIRO_SUBPIXEL_ORDER_DEFAULT;
options->hint_style = CAIRO_HINT_STYLE_DEFAULT;
options->hint_metrics = CAIRO_HINT_METRICS_DEFAULT;
}
@@ -84,17 +84,17 @@ void
* You can check for this with cairo_font_options_status().
**/
cairo_font_options_t *
cairo_font_options_create (void)
{
cairo_font_options_t *options = malloc (sizeof (cairo_font_options_t));
if (!options)
- return (cairo_font_options_t *)&_cairo_font_options_nil;
+ return (cairo_font_options_t *)&cairo_font_options_nil;
_cairo_font_options_init_default (options);
return options;
}
slim_hidden_def (cairo_font_options_create);
/**
@@ -108,41 +108,37 @@ slim_hidden_def (cairo_font_options_crea
* cairo_font_options_destroy(). This function always returns a
* valid pointer; if memory cannot be allocated, then a special
* error object is returned where all operations on the object do nothing.
* You can check for this with cairo_font_options_status().
**/
cairo_font_options_t *
cairo_font_options_copy (const cairo_font_options_t *original)
{
- cairo_font_options_t *options;
+ cairo_font_options_t *options = malloc (sizeof (cairo_font_options_t));
- if (original == &_cairo_font_options_nil)
- return (cairo_font_options_t *)&_cairo_font_options_nil;
-
- options = malloc (sizeof (cairo_font_options_t));
if (!options)
- return (cairo_font_options_t *)&_cairo_font_options_nil;
+ return (cairo_font_options_t *)&cairo_font_options_nil;
_cairo_font_options_init_copy (options, original);
return options;
}
/**
* cairo_font_options_destroy:
* @options: a #cairo_font_options_t
*
* Destroys a #cairo_font_options_t object created with with
* cairo_font_options_create() or cairo_font_options_copy().
**/
void
cairo_font_options_destroy (cairo_font_options_t *options)
{
- if (options == (cairo_font_options_t *)&_cairo_font_options_nil)
+ if (options == (cairo_font_options_t *)&cairo_font_options_nil)
return;
free (options);
}
slim_hidden_def (cairo_font_options_destroy);
/**
* cairo_font_options_status:
@@ -151,38 +147,37 @@ slim_hidden_def (cairo_font_options_dest
* Checks whether an error has previously occurred for this
* font options object
*
* Return value: %CAIRO_STATUS_SUCCESS or %CAIRO_STATUS_NO_MEMORY
**/
cairo_status_t
cairo_font_options_status (cairo_font_options_t *options)
{
- if (options == (cairo_font_options_t *)&_cairo_font_options_nil)
+ if (options == (cairo_font_options_t *)&cairo_font_options_nil)
return CAIRO_STATUS_NO_MEMORY;
else
return CAIRO_STATUS_SUCCESS;
}
-slim_hidden_def (cairo_font_options_status);
/**
* cairo_font_options_merge:
* @options: a #cairo_font_options_t
* @other: another #cairo_font_options_t
*
* Merges non-default options from @other into @options, replacing
* existing values. This operation can be thought of as somewhat
* similar to compositing @other onto @options with the operation
* of %CAIRO_OPERATION_OVER.
**/
void
cairo_font_options_merge (cairo_font_options_t *options,
const cairo_font_options_t *other)
{
- if (options == (cairo_font_options_t *)&_cairo_font_options_nil)
+ if (options == (cairo_font_options_t *)&cairo_font_options_nil)
return;
if (other->antialias != CAIRO_ANTIALIAS_DEFAULT)
options->antialias = other->antialias;
if (other->subpixel_order != CAIRO_SUBPIXEL_ORDER_DEFAULT)
options->subpixel_order = other->subpixel_order;
if (other->hint_style != CAIRO_HINT_STYLE_DEFAULT)
options->hint_style = other->hint_style;
@@ -240,17 +235,17 @@ slim_hidden_def (cairo_font_options_hash
*
* Sets the antialiasing mode for the font options object. This
* specifies the type of antialiasing to do when rendering text.
**/
void
cairo_font_options_set_antialias (cairo_font_options_t *options,
cairo_antialias_t antialias)
{
- if (options == (cairo_font_options_t *)&_cairo_font_options_nil)
+ if (options == (cairo_font_options_t *)&cairo_font_options_nil)
return;
options->antialias = antialias;
}
slim_hidden_def (cairo_font_options_set_antialias);
/**
* cairo_font_options_get_antialias:
@@ -276,17 +271,17 @@ cairo_font_options_get_antialias (const
* the display device when rendering with an antialiasing mode of
* %CAIRO_ANTIALIAS_SUBPIXEL. See the documentation for
* #cairo_subpixel_order_t for full details.
**/
void
cairo_font_options_set_subpixel_order (cairo_font_options_t *options,
cairo_subpixel_order_t subpixel_order)
{
- if (options == (cairo_font_options_t *)&_cairo_font_options_nil)
+ if (options == (cairo_font_options_t *)&cairo_font_options_nil)
return;
options->subpixel_order = subpixel_order;
}
slim_hidden_def (cairo_font_options_set_subpixel_order);
/**
* cairo_font_options_get_subpixel_order:
@@ -312,17 +307,17 @@ cairo_font_options_get_subpixel_order (c
* This controls whether to fit font outlines to the pixel grid,
* and if so, whether to optimize for fidelity or contrast.
* See the documentation for #cairo_hint_style_t for full details.
**/
void
cairo_font_options_set_hint_style (cairo_font_options_t *options,
cairo_hint_style_t hint_style)
{
- if (options == (cairo_font_options_t *)&_cairo_font_options_nil)
+ if (options == (cairo_font_options_t *)&cairo_font_options_nil)
return;
options->hint_style = hint_style;
}
slim_hidden_def (cairo_font_options_set_hint_style);
/**
* cairo_font_options_get_hint_style:
@@ -348,17 +343,17 @@ cairo_font_options_get_hint_style (const
* controls whether metrics are quantized to integer values in
* device units.
* See the documentation for #cairo_hint_metrics_t for full details.
**/
void
cairo_font_options_set_hint_metrics (cairo_font_options_t *options,
cairo_hint_metrics_t hint_metrics)
{
- if (options == (cairo_font_options_t *)&_cairo_font_options_nil)
+ if (options == (cairo_font_options_t *)&cairo_font_options_nil)
return;
options->hint_metrics = hint_metrics;
}
slim_hidden_def (cairo_font_options_set_hint_metrics);
/**
* cairo_font_options_get_hint_metrics:
new file mode 100644
--- /dev/null
+++ b/gfx/cairo/cairo/src/cairo-font.c
@@ -0,0 +1,516 @@
+/* -*- Mode: c; c-basic-offset: 4; indent-tabs-mode: t; tab-width: 8; -*- */
+/* cairo - a vector graphics library with display and print output
+ *
+ * Copyright © 2002 University of Southern California
+ * Copyright © 2005 Red Hat Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it either under the terms of the GNU Lesser General Public
+ * License version 2.1 as published by the Free Software Foundation
+ * (the "LGPL") or, at your option, under the terms of the Mozilla
+ * Public License Version 1.1 (the "MPL"). If you do not alter this
+ * notice, a recipient may use your version of this file under either
+ * the MPL or the LGPL.
+ *
+ * You should have received a copy of the LGPL along with this library
+ * in the file COPYING-LGPL-2.1; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ * You should have received a copy of the MPL along with this library
+ * in the file COPYING-MPL-1.1
+ *
+ * The contents of this file are subject to the Mozilla Public License
+ * Version 1.1 (the "License"); you may not use this file except in
+ * compliance with the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY
+ * OF ANY KIND, either express or implied. See the LGPL or the MPL for
+ * the specific language governing rights and limitations.
+ *
+ * The Original Code is the cairo graphics library.
+ *
+ * The Initial Developer of the Original Code is University of Southern
+ * California.
+ *
+ * Contributor(s):
+ * Carl D. Worth <cworth@cworth.org>
+ * Graydon Hoare <graydon@redhat.com>
+ * Owen Taylor <otaylor@redhat.com>
+ */
+
+#include "cairoint.h"
+
+/* Forward declare so we can use it as an arbitrary backend for
+ * _cairo_font_face_nil.
+ */
+static const cairo_font_face_backend_t _cairo_toy_font_face_backend;
+
+/* cairo_font_face_t */
+
+const cairo_font_face_t _cairo_font_face_nil = {
+ { 0 }, /* hash_entry */
+ CAIRO_STATUS_NO_MEMORY, /* status */
+ CAIRO_REF_COUNT_INVALID, /* ref_count */
+ { 0, 0, 0, NULL }, /* user_data */
+ &_cairo_toy_font_face_backend
+};
+
+void
+_cairo_font_face_init (cairo_font_face_t *font_face,
+ const cairo_font_face_backend_t *backend)
+{
+ font_face->status = CAIRO_STATUS_SUCCESS;
+ font_face->ref_count = 1;
+ font_face->backend = backend;
+
+ _cairo_user_data_array_init (&font_face->user_data);
+}
+
+/* This mutex protects both cairo_toy_font_hash_table as well as
+ reference count manipulations for all cairo_font_face_t. */
+CAIRO_MUTEX_DECLARE (_cairo_font_face_mutex);
+
+/**
+ * cairo_font_face_reference:
+ * @font_face: a #cairo_font_face_t, (may be %NULL in which case this
+ * function does nothing).
+ *
+ * Increases the reference count on @font_face by one. This prevents
+ * @font_face from being destroyed until a matching call to
+ * cairo_font_face_destroy() is made.
+ *
+ * The number of references to a #cairo_font_face_t can be get using
+ * cairo_font_face_get_reference_count().
+ *
+ * Return value: the referenced #cairo_font_face_t.
+ **/
+cairo_font_face_t *
+cairo_font_face_reference (cairo_font_face_t *font_face)
+{
+ if (font_face == NULL || font_face->ref_count == CAIRO_REF_COUNT_INVALID)
+ return font_face;
+
+ CAIRO_MUTEX_LOCK (_cairo_font_face_mutex);
+
+ /* We would normally assert (font_face->ref_count >0) here but we
+ * can't get away with that due to the zombie case as documented
+ * in _cairo_ft_font_face_destroy. */
+
+ font_face->ref_count++;
+
+ CAIRO_MUTEX_UNLOCK (_cairo_font_face_mutex);
+
+ return font_face;
+}
+slim_hidden_def (cairo_font_face_reference);
+
+/**
+ * cairo_font_face_destroy:
+ * @font_face: a #cairo_font_face_t
+ *
+ * Decreases the reference count on @font_face by one. If the result
+ * is zero, then @font_face and all associated resources are freed.
+ * See cairo_font_face_reference().
+ **/
+void
+cairo_font_face_destroy (cairo_font_face_t *font_face)
+{
+ if (font_face == NULL || font_face->ref_count == CAIRO_REF_COUNT_INVALID)
+ return;
+
+ CAIRO_MUTEX_LOCK (_cairo_font_face_mutex);
+
+ assert (font_face->ref_count > 0);
+
+ if (--(font_face->ref_count) > 0) {
+ CAIRO_MUTEX_UNLOCK (_cairo_font_face_mutex);
+ return;
+ }
+
+ CAIRO_MUTEX_UNLOCK (_cairo_font_face_mutex);
+
+ font_face->backend->destroy (font_face);
+
+ /* We allow resurrection to deal with some memory management for the
+ * FreeType backend where cairo_ft_font_face_t and cairo_ft_unscaled_font_t
+ * need to effectively mutually reference each other
+ */
+ if (font_face->ref_count > 0)
+ return;
+
+ _cairo_user_data_array_fini (&font_face->user_data);
+
+ free (font_face);
+}
+slim_hidden_def (cairo_font_face_destroy);
+
+/**
+ * cairo_font_face_get_type:
+ * @font_face: a font face
+ *
+ * This function returns the type of the backend used to create
+ * a font face. See #cairo_font_type_t for available types.
+ *
+ * Return value: The type of @font_face.
+ *
+ * Since: 1.2
+ **/
+cairo_font_type_t
+cairo_font_face_get_type (cairo_font_face_t *font_face)
+{
+ return font_face->backend->type;
+}
+
+/**
+ * cairo_font_face_get_reference_count:
+ * @font_face: a #cairo_font_face_t
+ *
+ * Returns the current reference count of @font_face.
+ *
+ * Return value: the current reference count of @font_face. If the
+ * object is a nil object, 0 will be returned.
+ *
+ * Since: 1.4
+ **/
+unsigned int
+cairo_font_face_get_reference_count (cairo_font_face_t *font_face)
+{
+ if (font_face == NULL || font_face->ref_count == CAIRO_REF_COUNT_INVALID)
+ return 0;
+
+ return font_face->ref_count;
+}
+
+/**
+ * cairo_font_face_status:
+ * @font_face: a #cairo_font_face_t
+ *
+ * Checks whether an error has previously occurred for this
+ * font face
+ *
+ * Return value: %CAIRO_STATUS_SUCCESS or another error such as
+ * %CAIRO_STATUS_NO_MEMORY.
+ **/
+cairo_status_t
+cairo_font_face_status (cairo_font_face_t *font_face)
+{
+ return font_face->status;
+}
+
+/**
+ * cairo_font_face_get_user_data:
+ * @font_face: a #cairo_font_face_t
+ * @key: the address of the #cairo_user_data_key_t the user data was
+ * attached to
+ *
+ * Return user data previously attached to @font_face using the specified
+ * key. If no user data has been attached with the given key this
+ * function returns %NULL.
+ *
+ * Return value: the user data previously attached or %NULL.
+ **/
+void *
+cairo_font_face_get_user_data (cairo_font_face_t *font_face,
+ const cairo_user_data_key_t *key)
+{
+ return _cairo_user_data_array_get_data (&font_face->user_data,
+ key);
+}
+
+/**
+ * cairo_font_face_set_user_data:
+ * @font_face: a #cairo_font_face_t
+ * @key: the address of a #cairo_user_data_key_t to attach the user data to
+ * @user_data: the user data to attach to the font face
+ * @destroy: a #cairo_destroy_func_t which will be called when the
+ * font face is destroyed or when new user data is attached using the
+ * same key.
+ *
+ * Attach user data to @font_face. To remove user data from a font face,
+ * call this function with the key that was used to set it and %NULL
+ * for @data.
+ *
+ * Return value: %CAIRO_STATUS_SUCCESS or %CAIRO_STATUS_NO_MEMORY if a
+ * slot could not be allocated for the user data.
+ **/
+cairo_status_t
+cairo_font_face_set_user_data (cairo_font_face_t *font_face,
+ const cairo_user_data_key_t *key,
+ void *user_data,
+ cairo_destroy_func_t destroy)
+{
+ if (font_face->ref_count == CAIRO_REF_COUNT_INVALID)
+ return CAIRO_STATUS_NO_MEMORY;
+
+ return _cairo_user_data_array_set_data (&font_face->user_data,
+ key, user_data, destroy);
+}
+
+static const cairo_font_face_backend_t _cairo_toy_font_face_backend;
+
+static int
+_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
+ * this mapping is to provide unique cairo_font_face_t values so that
+ * our cache and mapping from cairo_font_face_t => cairo_scaled_font_t
+ * works. Once the corresponding cairo_font_face_t objects fall out of
+ * downstream caches, we don't need them in this hash table anymore.
+ *
+ * Modifications to this hash table are protected by
+ * _cairo_font_face_mutex.
+ */
+static cairo_hash_table_t *cairo_toy_font_face_hash_table = NULL;
+
+static cairo_hash_table_t *
+_cairo_toy_font_face_hash_table_lock (void)
+{
+ CAIRO_MUTEX_LOCK (_cairo_font_face_mutex);
+
+ if (cairo_toy_font_face_hash_table == NULL)
+ {
+ cairo_toy_font_face_hash_table =
+ _cairo_hash_table_create (_cairo_toy_font_face_keys_equal);
+
+ if (cairo_toy_font_face_hash_table == NULL) {
+ CAIRO_MUTEX_UNLOCK (_cairo_font_face_mutex);
+ return NULL;
+ }
+ }
+
+ return cairo_toy_font_face_hash_table;
+}
+
+static void
+_cairo_toy_font_face_hash_table_unlock (void)
+{
+ CAIRO_MUTEX_UNLOCK (_cairo_font_face_mutex);
+}
+
+/**
+ * _cairo_toy_font_face_init_key:
+ *
+ * Initialize those portions of cairo_toy_font_face_t needed to use
+ * it as a hash table key, including the hash code buried away in
+ * font_face->base.hash_entry. No memory allocation is performed here
+ * so that no fini call is needed. We do this to make it easier to use
+ * an automatic cairo_toy_font_face_t variable as a key.
+ **/
+static void
+_cairo_toy_font_face_init_key (cairo_toy_font_face_t *key,
+ const char *family,
+ cairo_font_slant_t slant,
+ cairo_font_weight_t weight)
+{
+ unsigned long hash;
+
+ key->family = family;
+ key->owns_family = FALSE;
+
+ key->slant = slant;
+ key->weight = weight;
+
+ /* 1607 and 1451 are just a couple of arbitrary primes. */
+ hash = _cairo_hash_string (family);
+ hash += ((unsigned long) slant) * 1607;
+ hash += ((unsigned long) weight) * 1451;
+
+ key->base.hash_entry.hash = hash;
+}
+
+static cairo_status_t
+_cairo_toy_font_face_init (cairo_toy_font_face_t *font_face,
+ const char *family,
+ cairo_font_slant_t slant,
+ cairo_font_weight_t weight)
+{
+ char *family_copy;
+
+ family_copy = strdup (family);
+ if (family_copy == NULL)
+ return CAIRO_STATUS_NO_MEMORY;
+
+ _cairo_toy_font_face_init_key (font_face, family_copy,
+ slant, weight);
+ font_face->owns_family = TRUE;
+
+ _cairo_font_face_init (&font_face->base, &_cairo_toy_font_face_backend);
+
+ return CAIRO_STATUS_SUCCESS;
+}
+
+static void
+_cairo_toy_font_face_fini (cairo_toy_font_face_t *font_face)
+{
+ /* We assert here that we own font_face->family before casting
+ * away the const qualifer. */
+ assert (font_face->owns_family);
+ free ((char*) font_face->family);
+}
+
+static int
+_cairo_toy_font_face_keys_equal (const void *key_a,
+ const void *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 &&
+ face_a->weight == face_b->weight);
+}
+
+/**
+ * _cairo_toy_font_face_create:
+ * @family: a font family name, encoded in UTF-8
+ * @slant: the slant for the font
+ * @weight: the weight for the font
+ *
+ * Creates a font face from a triplet of family, slant, and weight.
+ * These font faces are used in implementation of the the #cairo_t "toy"
+ * font API.
+ *
+ * Return value: a newly created #cairo_font_face_t, destroy with
+ * cairo_font_face_destroy()
+ **/
+cairo_font_face_t *
+_cairo_toy_font_face_create (const char *family,
+ cairo_font_slant_t slant,
+ cairo_font_weight_t weight)
+{
+ cairo_status_t status;
+ cairo_toy_font_face_t key, *font_face;
+ cairo_hash_table_t *hash_table;
+
+ hash_table = _cairo_toy_font_face_hash_table_lock ();
+ if (hash_table == NULL)
+ goto UNWIND;
+
+ _cairo_toy_font_face_init_key (&key, family, slant, weight);
+
+ /* Return existing font_face if it exists in the hash table. */
+ if (_cairo_hash_table_lookup (hash_table,
+ &key.base.hash_entry,
+ (cairo_hash_entry_t **) &font_face))
+ {
+ /* We increment the reference count here manually to avoid
+ double-locking. */
+ font_face->base.ref_count++;
+ _cairo_toy_font_face_hash_table_unlock ();
+ return &font_face->base;
+ }
+
+ /* Otherwise create it and insert into hash table. */
+ font_face = malloc (sizeof (cairo_toy_font_face_t));
+ if (font_face == NULL)
+ goto UNWIND_HASH_TABLE_LOCK;
+
+ status = _cairo_toy_font_face_init (font_face, family, slant, weight);
+ if (status)
+ goto UNWIND_FONT_FACE_MALLOC;
+
+ status = _cairo_hash_table_insert (hash_table, &font_face->base.hash_entry);
+ if (status)
+ goto UNWIND_FONT_FACE_INIT;
+
+ _cairo_toy_font_face_hash_table_unlock ();
+
+ return &font_face->base;
+
+ UNWIND_FONT_FACE_INIT:
+ UNWIND_FONT_FACE_MALLOC:
+ free (font_face);
+ UNWIND_HASH_TABLE_LOCK:
+ _cairo_toy_font_face_hash_table_unlock ();
+ UNWIND:
+ return (cairo_font_face_t*) &_cairo_font_face_nil;
+}
+
+static void
+_cairo_toy_font_face_destroy (void *abstract_face)
+{
+ cairo_toy_font_face_t *font_face = abstract_face;
+ cairo_hash_table_t *hash_table;
+
+ if (font_face == NULL)
+ return;
+
+ hash_table = _cairo_toy_font_face_hash_table_lock ();
+ /* All created objects must have been mapped in the hash table. */
+ assert (hash_table != NULL);
+
+ _cairo_hash_table_remove (hash_table, &font_face->base.hash_entry);
+
+ _cairo_toy_font_face_hash_table_unlock ();
+
+ _cairo_toy_font_face_fini (font_face);
+}
+
+static cairo_status_t
+_cairo_toy_font_face_scaled_font_create (void *abstract_font_face,
+ const cairo_matrix_t *font_matrix,
+ const cairo_matrix_t *ctm,
+ const cairo_font_options_t *options,
+ cairo_scaled_font_t **scaled_font)
+{
+ cairo_toy_font_face_t *font_face = abstract_font_face;
+ const cairo_scaled_font_backend_t * backend = CAIRO_SCALED_FONT_BACKEND_DEFAULT;
+
+ return backend->create_toy (font_face,
+ font_matrix, ctm, options, scaled_font);
+}
+
+static const cairo_font_face_backend_t _cairo_toy_font_face_backend = {
+ CAIRO_FONT_TYPE_TOY,
+ _cairo_toy_font_face_destroy,
+ _cairo_toy_font_face_scaled_font_create
+};
+
+void
+_cairo_unscaled_font_init (cairo_unscaled_font_t *unscaled_font,
+ const cairo_unscaled_font_backend_t *backend)
+{
+ unscaled_font->ref_count = 1;
+ unscaled_font->backend = backend;
+}
+
+cairo_unscaled_font_t *
+_cairo_unscaled_font_reference (cairo_unscaled_font_t *unscaled_font)
+{
+ if (unscaled_font == NULL)
+ return NULL;
+
+ unscaled_font->ref_count++;
+
+ return unscaled_font;
+}
+
+void
+_cairo_unscaled_font_destroy (cairo_unscaled_font_t *unscaled_font)
+{
+ if (unscaled_font == NULL)
+ return;
+
+ if (--(unscaled_font->ref_count) > 0)
+ return;
+
+ unscaled_font->backend->destroy (unscaled_font);
+
+ free (unscaled_font);
+}
+
+void
+_cairo_font_reset_static_data (void)
+{
+ _cairo_scaled_font_map_destroy ();
+
+ /* We manually acquire the lock rather than calling
+ * cairo_toy_font_face_hash_table_lock simply to avoid
+ * creating the table only to destroy it again. */
+ CAIRO_MUTEX_LOCK (_cairo_font_face_mutex);
+ _cairo_hash_table_destroy (cairo_toy_font_face_hash_table);
+ cairo_toy_font_face_hash_table = NULL;
+ CAIRO_MUTEX_UNLOCK (_cairo_font_face_mutex);
+}
--- a/gfx/cairo/cairo/src/cairo-freelist-private.h
+++ b/gfx/cairo/cairo/src/cairo-freelist-private.h
@@ -21,16 +21,18 @@
*/
#ifndef CAIRO_FREELIST_H
#define CAIRO_FREELIST_H
#include "cairoint.h"
#include <stddef.h>
/* Opaque implementation types. */
+struct _cairo_freelist;
+struct _cairo_freelist_node;
typedef struct _cairo_freelist cairo_freelist_t;
typedef struct _cairo_freelist_node cairo_freelist_node_t;
struct _cairo_freelist_node {
cairo_freelist_node_t *next;
};
struct _cairo_freelist {
--- a/gfx/cairo/cairo/src/cairo-freelist.c
+++ b/gfx/cairo/cairo/src/cairo-freelist.c
@@ -14,19 +14,18 @@
* THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
* EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
* CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
* DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
* TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
* OF THIS SOFTWARE.
*/
-
-#include "cairoint.h"
-
+#include <stdlib.h>
+#include <string.h>
#include "cairo-freelist-private.h"
void
_cairo_freelist_init (cairo_freelist_t *freelist, unsigned nodesize)
{
memset (freelist, 0, sizeof(cairo_freelist_t));
freelist->nodesize = nodesize;
}
--- a/gfx/cairo/cairo/src/cairo-ft-font.c
+++ b/gfx/cairo/cairo/src/cairo-ft-font.c
@@ -32,22 +32,20 @@
*
* Contributor(s):
* Graydon Hoare <graydon@redhat.com>
* Owen Taylor <otaylor@redhat.com>
* Keith Packard <keithp@keithp.com>
* Carl Worth <cworth@cworth.org>
*/
-#include "cairoint.h"
+#include <float.h>
#include "cairo-ft-private.h"
-#include <float.h>
-
#include <fontconfig/fontconfig.h>
#include <fontconfig/fcfreetype.h>
#include <ft2build.h>
#include FT_FREETYPE_H
#include FT_OUTLINE_H
#include FT_IMAGE_H
#include FT_TRUETYPE_TABLES_H
@@ -59,19 +57,21 @@
#define DOUBLE_FROM_26_6(t) ((double)(t) / 64.0)
#define DOUBLE_TO_16_16(d) ((FT_Fixed)((d) * 65536.0))
#define DOUBLE_FROM_16_16(t) ((double)(t) / 65536.0)
/* This is the max number of FT_face objects we keep open at once
*/
#define MAX_OPEN_FACES 10
+#ifndef MOZILLA_CAIRO_NOT_DEFINED
/* This is the maximum font size we allow to be passed to FT_Set_Char_Size
*/
#define MAX_FONT_SIZE 1000
+#endif /* !MOZILLA_CAIRO_NOT_DEFINED */
/*
* The simple 2x2 matrix is converted into separate scale and shape
* factors so that hinting works right
*/
typedef struct _cairo_ft_font_transform {
double x_scale, y_scale;
@@ -151,16 +151,18 @@ static const cairo_unscaled_font_backend
typedef struct _cairo_ft_unscaled_font_map {
cairo_hash_table_t *hash_table;
FT_Library ft_library;
int num_open_faces;
} cairo_ft_unscaled_font_map_t;
static cairo_ft_unscaled_font_map_t *cairo_ft_unscaled_font_map = NULL;
+CAIRO_MUTEX_DECLARE(_cairo_ft_unscaled_font_map_mutex);
+
static void
_font_map_release_face_lock_held (cairo_ft_unscaled_font_map_t *font_map,
cairo_ft_unscaled_font_t *unscaled)
{
if (unscaled->face) {
FT_Done_Face (unscaled->face);
unscaled->face = NULL;
unscaled->have_scale = FALSE;
@@ -254,17 +256,16 @@ static cairo_ft_unscaled_font_map_t *
CAIRO_MUTEX_LOCK (_cairo_ft_unscaled_font_map_mutex);
if (cairo_ft_unscaled_font_map == NULL)
{
_cairo_ft_unscaled_font_map_create ();
if (cairo_ft_unscaled_font_map == NULL) {
CAIRO_MUTEX_UNLOCK (_cairo_ft_unscaled_font_map_mutex);
- _cairo_error (CAIRO_STATUS_NO_MEMORY);
return NULL;
}
}
return cairo_ft_unscaled_font_map;
}
static void
@@ -327,26 +328,24 @@ static cairo_status_t
unscaled->id = 0;
} else {
char *filename_copy;
unscaled->from_face = FALSE;
unscaled->face = NULL;
filename_copy = strdup (filename);
- if (filename_copy == NULL) {
- _cairo_error (CAIRO_STATUS_NO_MEMORY);
+ if (filename_copy == NULL)
return CAIRO_STATUS_NO_MEMORY;
- }
_cairo_ft_unscaled_font_init_key (unscaled, filename_copy, id);
}
unscaled->have_scale = FALSE;
- CAIRO_MUTEX_INIT (unscaled->mutex);
+ CAIRO_MUTEX_INIT (&unscaled->mutex);
unscaled->lock_count = 0;
unscaled->faces = NULL;
return CAIRO_STATUS_SUCCESS;
}
cairo_bool_t
@@ -371,17 +370,17 @@ static void
{
assert (unscaled->face == NULL);
if (unscaled->filename) {
free (unscaled->filename);
unscaled->filename = NULL;
}
- CAIRO_MUTEX_FINI (unscaled->mutex);
+ CAIRO_MUTEX_FINI (&unscaled->mutex);
}
static int
_cairo_ft_unscaled_font_keys_equal (const void *key_a,
const void *key_b)
{
const cairo_ft_unscaled_font_t *unscaled_a = key_a;
const cairo_ft_unscaled_font_t *unscaled_b = key_b;
@@ -415,18 +414,18 @@ static cairo_ft_unscaled_font_t *
goto UNWIND;
_cairo_ft_unscaled_font_init_key (&key, filename, id);
/* Return existing unscaled font if it exists in the hash table. */
if (_cairo_hash_table_lookup (font_map->hash_table, &key.base.hash_entry,
(cairo_hash_entry_t **) &unscaled))
{
+ _cairo_ft_unscaled_font_map_unlock ();
_cairo_unscaled_font_reference (&unscaled->base);
- _cairo_ft_unscaled_font_map_unlock ();
return unscaled;
}
/* Otherwise create it and insert into hash table. */
unscaled = malloc (sizeof (cairo_ft_unscaled_font_t));
if (unscaled == NULL)
goto UNWIND_FONT_MAP_LOCK;
@@ -552,17 +551,16 @@ FT_Face
_cairo_ft_unscaled_font_map_unlock ();
if (FT_New_Face (font_map->ft_library,
unscaled->filename,
unscaled->id,
&face) != FT_Err_Ok)
{
CAIRO_MUTEX_UNLOCK (unscaled->mutex);
- _cairo_error (CAIRO_STATUS_NO_MEMORY);
return NULL;
}
unscaled->face = face;
font_map->num_open_faces++;
return face;
@@ -611,32 +609,32 @@ static void
sf->shape[0][0] = sf->shape[1][1] = 1.0;
sf->shape[0][1] = sf->shape[1][0] = 0.0;
}
}
/* Temporarily scales an unscaled font to the give scale. We catch
* scaling to the same size, since changing a FT_Face is expensive.
*/
-static cairo_status_t
+static void
_cairo_ft_unscaled_font_set_scale (cairo_ft_unscaled_font_t *unscaled,
cairo_matrix_t *scale)
{
cairo_ft_font_transform_t sf;
FT_Matrix mat;
FT_Error error;
assert (unscaled->face != NULL);
if (unscaled->have_scale &&
scale->xx == unscaled->current_scale.xx &&
scale->yx == unscaled->current_scale.yx &&
scale->xy == unscaled->current_scale.xy &&
scale->yy == unscaled->current_scale.yy)
- return CAIRO_STATUS_SUCCESS;
+ return;
unscaled->have_scale = TRUE;
unscaled->current_scale = *scale;
_compute_transform (&sf, scale);
unscaled->x_scale = sf.x_scale;
unscaled->y_scale = sf.y_scale;
@@ -655,33 +653,37 @@ static cairo_status_t
cairo_matrix_init (&unscaled->current_shape,
sf.shape[0][0], sf.shape[0][1],
sf.shape[1][0], sf.shape[1][1],
0.0, 0.0);
FT_Set_Transform(unscaled->face, &mat, NULL);
if ((unscaled->face->face_flags & FT_FACE_FLAG_SCALABLE) != 0) {
+#ifndef MOZILLA_CAIRO_NOT_DEFINED
double x_scale = sf.x_scale;
double y_scale = sf.y_scale;
if (x_scale > MAX_FONT_SIZE) {
x_scale = MAX_FONT_SIZE;
}
if (y_scale > MAX_FONT_SIZE) {
y_scale = MAX_FONT_SIZE;
}
error = FT_Set_Char_Size (unscaled->face,
+ sf.x_scale * 64.0,
+ sf.y_scale * 64.0,
+ 0, 0);
+#else
+ error = FT_Set_Char_Size (unscaled->face,
x_scale * 64.0,
y_scale * 64.0,
0, 0);
- if (error) {
- _cairo_error (CAIRO_STATUS_NO_MEMORY);
- return CAIRO_STATUS_NO_MEMORY;
- }
+#endif /* MOZCAIRO */
+ assert (error == 0);
} else {
double min_distance = DBL_MAX;
int i;
int best_i = 0;
for (i = 0; i < unscaled->face->num_fixed_sizes; i++) {
#if HAVE_FT_BITMAP_SIZE_Y_PPEM
double size = unscaled->face->available_sizes[i].y_ppem / 64.;
@@ -700,23 +702,18 @@ static cairo_status_t
unscaled->face->available_sizes[best_i].x_ppem,
unscaled->face->available_sizes[best_i].y_ppem,
0, 0);
if (error)
#endif
error = FT_Set_Pixel_Sizes (unscaled->face,
unscaled->face->available_sizes[best_i].width,
unscaled->face->available_sizes[best_i].height);
- if (error) {
- _cairo_error (CAIRO_STATUS_NO_MEMORY);
- return CAIRO_STATUS_NO_MEMORY;
- }
+ assert (error == 0);
}
-
- return CAIRO_STATUS_SUCCESS;
}
/* Empirically-derived subpixel filtering values thanks to Keith
* Packard and libXft. */
static const int filters[3][3] = {
/* red */
#if 0
{ 65538*4/7,65538*2/7,65538*1/7 },
@@ -750,21 +747,19 @@ static cairo_status_t
switch (bitmap->pixel_mode) {
case FT_PIXEL_MODE_MONO:
stride = (((width + 31) & ~31) >> 3);
if (own_buffer) {
data = bitmap->buffer;
assert (stride == bitmap->pitch);
} else {
- data = _cairo_malloc_ab (height, stride);
- if (!data) {
- _cairo_error (CAIRO_STATUS_NO_MEMORY);
+ data = malloc (stride * height);
+ if (!data)
return CAIRO_STATUS_NO_MEMORY;
- }
if (stride == bitmap->pitch) {
memcpy (data, bitmap->buffer, stride * height);
} else {
int i;
unsigned char *source, *dest;
source = bitmap->buffer;
@@ -800,21 +795,19 @@ static cairo_status_t
case CAIRO_ANTIALIAS_DEFAULT:
case CAIRO_ANTIALIAS_GRAY:
case CAIRO_ANTIALIAS_NONE:
default:
stride = bitmap->pitch;
if (own_buffer) {
data = bitmap->buffer;
} else {
- data = _cairo_malloc_ab (height, stride);
- if (!data) {
- _cairo_error (CAIRO_STATUS_NO_MEMORY);
+ data = malloc (stride * height);
+ if (!data)
return CAIRO_STATUS_NO_MEMORY;
- }
memcpy (data, bitmap->buffer, stride * height);
}
format = CAIRO_FORMAT_A8;
break;
case CAIRO_ANTIALIAS_SUBPIXEL: {
int x, y;
unsigned char *in_line, *out_line, *in;
unsigned int *out;
@@ -843,22 +836,16 @@ static cairo_status_t
}
/*
* Filter the glyph to soften the color fringes
*/
width_rgba = width;
stride = bitmap->pitch;
stride_rgba = (width_rgba * 4 + 3) & ~3;
data_rgba = calloc (1, stride_rgba * height);
- if (data_rgba == NULL) {
- if (own_buffer)
- free (bitmap->buffer);
- _cairo_error (CAIRO_STATUS_NO_MEMORY);
- return CAIRO_STATUS_NO_MEMORY;
- }
os = 1;
switch (font_options->subpixel_order) {
case CAIRO_SUBPIXEL_ORDER_VRGB:
os = stride;
case CAIRO_SUBPIXEL_ORDER_DEFAULT:
case CAIRO_SUBPIXEL_ORDER_RGB:
default:
@@ -913,19 +900,16 @@ static cairo_status_t
break;
}
}
break;
case FT_PIXEL_MODE_GRAY2:
case FT_PIXEL_MODE_GRAY4:
/* These could be triggered by very rare types of TrueType fonts */
default:
- if (own_buffer)
- free (bitmap->buffer);
- _cairo_error (CAIRO_STATUS_NO_MEMORY);
return CAIRO_STATUS_NO_MEMORY;
}
*surface = (cairo_image_surface_t *)
cairo_image_surface_create_for_data (data,
format,
width, height, stride);
if ((*surface)->base.status) {
@@ -1046,25 +1030,23 @@ static cairo_status_t
}
bitmap.pitch = stride;
bitmap.width = width * hmul;
bitmap.rows = height * vmul;
bitmap.buffer = calloc (1, stride * bitmap.rows);
if (bitmap.buffer == NULL) {
- _cairo_error (CAIRO_STATUS_NO_MEMORY);
return CAIRO_STATUS_NO_MEMORY;
}
FT_Outline_Translate (outline, -cbox.xMin*hmul, -cbox.yMin*vmul);
if (FT_Outline_Get_Bitmap (glyphslot->library, outline, &bitmap) != 0) {
free (bitmap.buffer);
- _cairo_error (CAIRO_STATUS_NO_MEMORY);
return CAIRO_STATUS_NO_MEMORY;
}
status = _get_bitmap_surface (&bitmap, TRUE, font_options, surface);
if (status)
return status;
}
@@ -1092,20 +1074,18 @@ static cairo_status_t
/* According to the FreeType docs, glyphslot->format could be
* something other than FT_GLYPH_FORMAT_OUTLINE or
* FT_GLYPH_FORMAT_BITMAP. Calling FT_Render_Glyph gives FreeType
* the opportunity to convert such to
* bitmap. FT_GLYPH_FORMAT_COMPOSITE will not be encountered since
* we avoid the FT_LOAD_NO_RECURSE flag.
*/
error = FT_Render_Glyph (glyphslot, FT_RENDER_MODE_NORMAL);
- if (error) {
- _cairo_error (CAIRO_STATUS_NO_MEMORY);
+ if (error)
return CAIRO_STATUS_NO_MEMORY;
- }
status = _get_bitmap_surface (&glyphslot->bitmap, FALSE, font_options, surface);
if (status)
return status;
/*
* Note: the font's coordinate system is upside down from ours, so the
* Y coordinate of the control box needs to be negated.
@@ -1193,43 +1173,34 @@ static cairo_status_t
/* We need to pad out the width to 32-bit intervals for cairo-xlib-surface.c */
width = (width + 3) & ~3;
image = cairo_image_surface_create (CAIRO_FORMAT_A8, width, height);
if (image->status)
return CAIRO_STATUS_NO_MEMORY;
/* Initialize it to empty
*/
- status = _cairo_surface_fill_rectangle (image, CAIRO_OPERATOR_CLEAR,
- CAIRO_COLOR_TRANSPARENT,
- 0, 0,
- width, height);
- if (status) {
- cairo_surface_destroy (image);
- return status;
- }
+ _cairo_surface_fill_rectangle (image, CAIRO_OPERATOR_CLEAR,
+ CAIRO_COLOR_TRANSPARENT,
+ 0, 0,
+ width, height);
/* Draw the original bitmap transformed into the new bitmap
*/
_cairo_pattern_init_for_surface (&pattern, &(*surface)->base);
cairo_pattern_set_matrix (&pattern.base, &transformed_to_original);
- status = _cairo_surface_composite (CAIRO_OPERATOR_OVER,
- &pattern.base, NULL, image,
- 0, 0, 0, 0, 0, 0,
- width,
- height);
+ _cairo_surface_composite (CAIRO_OPERATOR_OVER,
+ &pattern.base, NULL, image,
+ 0, 0, 0, 0, 0, 0,
+ width,
+ height);
_cairo_pattern_fini (&pattern.base);
- if (status) {
- cairo_surface_destroy (image);
- return status;
- }
-
/* Now update the cache entry for the new bitmap, recomputing
* the origin based on the final transform.
*/
origin_x = - origin_x;
origin_y = - origin_y;
cairo_matrix_transform_point (&original_to_transformed,
&origin_x, &origin_y);
@@ -1469,58 +1440,43 @@ static cairo_scaled_font_t *
const cairo_matrix_t *ctm,
const cairo_font_options_t *options,
cairo_ft_options_t ft_options)
{
cairo_ft_scaled_font_t *scaled_font = NULL;
FT_Face face;
FT_Size_Metrics *metrics;
cairo_font_extents_t fs_metrics;
- cairo_status_t status;
face = _cairo_ft_unscaled_font_lock_face (unscaled);
if (!face)
return NULL;
scaled_font = malloc (sizeof(cairo_ft_scaled_font_t));
if (scaled_font == NULL) {
_cairo_ft_unscaled_font_unlock_face (unscaled);
- _cairo_error (CAIRO_STATUS_NO_MEMORY);
return NULL;
}
_cairo_unscaled_font_reference (&unscaled->base);
scaled_font->unscaled = unscaled;
if (options->hint_metrics != CAIRO_HINT_METRICS_OFF)
ft_options.extra_flags |= CAIRO_FT_OPTIONS_HINT_METRICS;
_cairo_font_options_init_copy (&scaled_font->ft_options.base, options);
_cairo_ft_options_merge (&scaled_font->ft_options, &ft_options);
- status = _cairo_scaled_font_init (&scaled_font->base,
- font_face,
- font_matrix, ctm, options,
- &cairo_ft_scaled_font_backend);
- if (status) {
- free (scaled_font);
- _cairo_unscaled_font_destroy (&unscaled->base);
- _cairo_ft_unscaled_font_unlock_face (unscaled);
- return NULL;
- }
+ _cairo_scaled_font_init (&scaled_font->base,
+ font_face,
+ font_matrix, ctm, options,
+ &cairo_ft_scaled_font_backend);
- status = _cairo_ft_unscaled_font_set_scale (unscaled,
- &scaled_font->base.scale);
- if (status) {
- free (scaled_font);
- _cairo_unscaled_font_destroy (&unscaled->base);
- _cairo_ft_unscaled_font_unlock_face (unscaled);
- return NULL;
- }
-
+ _cairo_ft_unscaled_font_set_scale (unscaled,
+ &scaled_font->base.scale);
metrics = &face->size->metrics;
/*
* Get to unscaled metrics so that the upper level can get back to
* user space
*/
if (scaled_font->base.options.hint_metrics != CAIRO_HINT_METRICS_OFF) {
@@ -1588,20 +1544,18 @@ static cairo_status_t
int fcslant;
int fcweight;
cairo_matrix_t scale;
cairo_ft_font_transform_t sf;
cairo_ft_options_t ft_options;
unsigned char *family = (unsigned char*) toy_face->family;
pattern = FcPatternCreate ();
- if (!pattern) {
- _cairo_error (CAIRO_STATUS_NO_MEMORY);
+ if (!pattern)
return CAIRO_STATUS_NO_MEMORY;
- }
switch (toy_face->weight)
{
case CAIRO_FONT_WEIGHT_BOLD:
fcweight = FC_WEIGHT_BOLD;
break;
case CAIRO_FONT_WEIGHT_NORMAL:
default:
@@ -1661,17 +1615,16 @@ static cairo_status_t
FREE_PATTERN:
FcPatternDestroy (pattern);
if (new_font) {
*font = new_font;
return CAIRO_STATUS_SUCCESS;
} else {
- _cairo_error (CAIRO_STATUS_NO_MEMORY);
return CAIRO_STATUS_NO_MEMORY;
}
}
static void
_cairo_ft_scaled_font_fini (void *abstract_font)
{
cairo_ft_scaled_font_t *scaled_font = abstract_font;
@@ -1686,71 +1639,65 @@ static int
_move_to (FT_Vector *to, void *closure)
{
cairo_path_fixed_t *path = closure;
cairo_fixed_t x, y;
x = _cairo_fixed_from_26_6 (to->x);
y = _cairo_fixed_from_26_6 (to->y);
- if (_cairo_path_fixed_close_path (path) != CAIRO_STATUS_SUCCESS)
- return 1;
- if (_cairo_path_fixed_move_to (path, x, y) != CAIRO_STATUS_SUCCESS)
- return 1;
+ _cairo_path_fixed_close_path (path);
+ _cairo_path_fixed_move_to (path, x, y);
return 0;
}
static int
_line_to (FT_Vector *to, void *closure)
{
cairo_path_fixed_t *path = closure;
cairo_fixed_t x, y;
x = _cairo_fixed_from_26_6 (to->x);
y = _cairo_fixed_from_26_6 (to->y);
- if (_cairo_path_fixed_line_to (path, x, y) != CAIRO_STATUS_SUCCESS)
- return 1;
+ _cairo_path_fixed_line_to (path, x, y);
return 0;
}
static int
_conic_to (FT_Vector *control, FT_Vector *to, void *closure)
{
cairo_path_fixed_t *path = closure;
cairo_fixed_t x0, y0;
cairo_fixed_t x1, y1;
cairo_fixed_t x2, y2;
cairo_fixed_t x3, y3;
cairo_point_t conic;
- if (_cairo_path_fixed_get_current_point (path, &x0, &y0) !=
- CAIRO_STATUS_SUCCESS)
- return 1;
+ _cairo_path_fixed_get_current_point (path, &x0, &y0);
conic.x = _cairo_fixed_from_26_6 (control->x);
conic.y = _cairo_fixed_from_26_6 (control->y);
x3 = _cairo_fixed_from_26_6 (to->x);
y3 = _cairo_fixed_from_26_6 (to->y);
x1 = x0 + 2.0/3.0 * (conic.x - x0);
y1 = y0 + 2.0/3.0 * (conic.y - y0);
x2 = x3 + 2.0/3.0 * (conic.x - x3);
y2 = y3 + 2.0/3.0 * (conic.y - y3);
- if (_cairo_path_fixed_curve_to (path,
- x1, y1,
- x2, y2,
- x3, y3) != CAIRO_STATUS_SUCCESS)
- return 1;
+ _cairo_path_fixed_curve_to (path,
+ x1, y1,
+ x2, y2,
+ x3, y3);
return 0;
}
static int
_cubic_to (FT_Vector *control1, FT_Vector *control2,
FT_Vector *to, void *closure)
{
@@ -1763,21 +1710,20 @@ static int
y0 = _cairo_fixed_from_26_6 (control1->y);
x1 = _cairo_fixed_from_26_6 (control2->x);
y1 = _cairo_fixed_from_26_6 (control2->y);
x2 = _cairo_fixed_from_26_6 (to->x);
y2 = _cairo_fixed_from_26_6 (to->y);
- if (_cairo_path_fixed_curve_to (path,
- x0, y0,
- x1, y1,
- x2, y2) != CAIRO_STATUS_SUCCESS)
- return 1;
+ _cairo_path_fixed_curve_to (path,
+ x0, y0,
+ x1, y1,
+ x2, y2);
return 0;
}
static cairo_status_t
_decompose_glyph_outline (FT_Face face,
cairo_font_options_t *options,
cairo_path_fixed_t **pathp)
@@ -1792,37 +1738,28 @@ static cairo_status_t
};
static const FT_Matrix invert_y = {
DOUBLE_TO_16_16 (1.0), 0,
0, DOUBLE_TO_16_16 (-1.0),
};
FT_GlyphSlot glyph;
cairo_path_fixed_t *path;
- cairo_status_t status;
path = _cairo_path_fixed_create ();
if (!path)
return CAIRO_STATUS_NO_MEMORY;
glyph = face->glyph;
/* Font glyphs have an inverted Y axis compared to cairo. */
FT_Outline_Transform (&glyph->outline, &invert_y);
- if (FT_Outline_Decompose (&glyph->outline, &outline_funcs, path)) {
- _cairo_path_fixed_destroy (path);
- _cairo_error (CAIRO_STATUS_NO_MEMORY);
- return CAIRO_STATUS_NO_MEMORY;
- }
+ FT_Outline_Decompose (&glyph->outline, &outline_funcs, path);
- status = _cairo_path_fixed_close_path (path);
- if (status) {
- _cairo_path_fixed_destroy (path);
- return status;
- }
+ _cairo_path_fixed_close_path (path);
*pathp = path;
return CAIRO_STATUS_SUCCESS;
}
/*
* Translate glyph to match its metrics.
@@ -1856,26 +1793,24 @@ static cairo_int_status_t
cairo_ft_unscaled_font_t *unscaled = scaled_font->unscaled;
FT_GlyphSlot glyph;
FT_Face face;
FT_Error error;
int load_flags = scaled_font->ft_options.load_flags;
FT_Glyph_Metrics *metrics;
double x_factor, y_factor;
cairo_bool_t vertical_layout = FALSE;
- cairo_status_t status;
+ cairo_status_t status = CAIRO_STATUS_SUCCESS;
face = _cairo_ft_unscaled_font_lock_face (unscaled);
if (!face)
return CAIRO_STATUS_NO_MEMORY;
- status = _cairo_ft_unscaled_font_set_scale (scaled_font->unscaled,
- &scaled_font->base.scale);
- if (status)
- goto FAIL;
+ _cairo_ft_unscaled_font_set_scale (scaled_font->unscaled,
+ &scaled_font->base.scale);
/* Ignore global advance unconditionally */
load_flags |= FT_LOAD_IGNORE_GLOBAL_ADVANCE_WIDTH;
if ((info & CAIRO_SCALED_GLYPH_INFO_PATH) != 0 &&
(info & CAIRO_SCALED_GLYPH_INFO_SURFACE) == 0)
load_flags |= FT_LOAD_NO_BITMAP;
@@ -2011,22 +1946,19 @@ static cairo_int_status_t
cairo_image_surface_t *surface;
if (glyph->format == FT_GLYPH_FORMAT_OUTLINE) {
status = _render_glyph_outline (face, &scaled_font->ft_options.base,
&surface);
} else {
status = _render_glyph_bitmap (face, &scaled_font->ft_options.base,
&surface);
- if (status == CAIRO_STATUS_SUCCESS && unscaled->have_shape) {
+ if (status == CAIRO_STATUS_SUCCESS && unscaled->have_shape)
status = _transform_glyph_bitmap (&unscaled->current_shape,
&surface);
- if (status)
- cairo_surface_destroy (&surface->base);
- }
}
if (status)
goto FAIL;
_cairo_scaled_glyph_set_surface (scaled_glyph,
&scaled_font->base,
surface);
}
@@ -2040,17 +1972,16 @@ static cairo_int_status_t
*/
if ((info & CAIRO_SCALED_GLYPH_INFO_SURFACE) != 0) {
error = FT_Load_Glyph (face,
_cairo_scaled_glyph_index(scaled_glyph),
load_flags | FT_LOAD_NO_BITMAP);
if (error) {
_cairo_ft_unscaled_font_unlock_face (unscaled);
- _cairo_error (CAIRO_STATUS_NO_MEMORY);
return CAIRO_STATUS_NO_MEMORY;
}
#if HAVE_FT_GLYPHSLOT_EMBOLDEN
/*
* embolden glyphs if requested
*/
if (scaled_font->ft_options.extra_flags & CAIRO_FT_OPTIONS_EMBOLDEN)
FT_GlyphSlot_Embolden (glyph);
@@ -2250,60 +2181,49 @@ static cairo_status_t
*/
ft_options = font_face->ft_options;
*scaled_font = _cairo_ft_scaled_font_create (font_face->unscaled,
&font_face->base,
font_matrix, ctm,
options, ft_options);
- if (*scaled_font) {
+ if (*scaled_font)
return CAIRO_STATUS_SUCCESS;
- } else {
- _cairo_error (CAIRO_STATUS_NO_MEMORY);
+ else
return CAIRO_STATUS_NO_MEMORY;
- }
}
static const cairo_font_face_backend_t _cairo_ft_font_face_backend = {
CAIRO_FONT_TYPE_FT,
_cairo_ft_font_face_destroy,
_cairo_ft_font_face_scaled_font_create
};
static cairo_font_face_t *
_cairo_ft_font_face_create (cairo_ft_unscaled_font_t *unscaled,
cairo_ft_options_t *ft_options)
{
- cairo_ft_font_face_t *font_face, **prev_font_face;
+ cairo_ft_font_face_t *font_face;
/* Looked for an existing matching font face */
- for (font_face = unscaled->faces, prev_font_face = &unscaled->faces;
+ for (font_face = unscaled->faces;
font_face;
- prev_font_face = &font_face->next, font_face = font_face->next)
+ font_face = font_face->next)
{
if (font_face->ft_options.load_flags == ft_options->load_flags &&
font_face->ft_options.extra_flags == ft_options->extra_flags &&
cairo_font_options_equal (&font_face->ft_options.base, &ft_options->base))
- {
- if (! font_face->base.status)
- return cairo_font_face_reference (&font_face->base);
-
- /* The font_face has been left in an error state, abandon it. */
- *prev_font_face = font_face->next;
- break;
- }
+ return cairo_font_face_reference (&font_face->base);
}
/* No match found, create a new one */
font_face = malloc (sizeof (cairo_ft_font_face_t));
- if (!font_face) {
- _cairo_error (CAIRO_STATUS_NO_MEMORY);
+ if (!font_face)
return NULL;
- }
font_face->unscaled = unscaled;
_cairo_unscaled_font_reference (&unscaled->base);
font_face->ft_options = *ft_options;
font_face->next = unscaled->faces;
unscaled->faces = font_face;
@@ -2451,18 +2371,20 @@ cairo_ft_font_face_create_for_pattern (F
}
_get_pattern_ft_options (pattern, &ft_options);
font_face = _cairo_ft_font_face_create (unscaled, &ft_options);
_cairo_unscaled_font_destroy (&unscaled->base);
if (font_face)
return font_face;
- else
+ else {
+ _cairo_error (CAIRO_STATUS_NO_MEMORY);
return (cairo_font_face_t *)&_cairo_font_face_nil;
+ }
}
/**
* cairo_ft_font_face_create_for_ft_face:
* @face: A FreeType face object, already opened. This must
* be kept around until the face's ref_count drops to
* zero and it is freed. Since the face may be referenced
* internally to Cairo, the best way to determine when it
@@ -2502,20 +2424,22 @@ cairo_ft_font_face_create_for_ft_face (F
ft_options.load_flags = load_flags;
ft_options.extra_flags = 0;
_cairo_font_options_init_default (&ft_options.base);
font_face = _cairo_ft_font_face_create (unscaled, &ft_options);
_cairo_unscaled_font_destroy (&unscaled->base);
- if (font_face)
+ if (font_face) {
return font_face;
- else
+ } else {
+ _cairo_error (CAIRO_STATUS_NO_MEMORY);
return (cairo_font_face_t *)&_cairo_font_face_nil;
+ }
}
/**
* cairo_ft_scaled_font_lock_face:
* @scaled_font: A #cairo_scaled_font_t from the FreeType font backend. Such an
* object can be created by calling cairo_scaled_font_create() on a
* FreeType backend font face (see cairo_ft_font_face_create_for_pattern(),
* cairo_ft_font_face_create_for_face()).
@@ -2543,34 +2467,28 @@ cairo_ft_font_face_create_for_ft_face (F
* or %NULL if @scaled_font is in an error state (see
* cairo_scaled_font_status()) or there is insufficient memory.
**/
FT_Face
cairo_ft_scaled_font_lock_face (cairo_scaled_font_t *abstract_font)
{
cairo_ft_scaled_font_t *scaled_font = (cairo_ft_scaled_font_t *) abstract_font;
FT_Face face;
- cairo_status_t status;
if (scaled_font->base.status)
return NULL;
face = _cairo_ft_unscaled_font_lock_face (scaled_font->unscaled);
if (face == NULL) {
_cairo_scaled_font_set_error (&scaled_font->base, CAIRO_STATUS_NO_MEMORY);
return NULL;
}
- status = _cairo_ft_unscaled_font_set_scale (scaled_font->unscaled,
- &scaled_font->base.scale);
- if (status) {
- _cairo_ft_unscaled_font_unlock_face (scaled_font->unscaled);
- _cairo_scaled_font_set_error (&scaled_font->base, status);
- return NULL;
- }
+ _cairo_ft_unscaled_font_set_scale (scaled_font->unscaled,
+ &scaled_font->base.scale);
/* NOTE: We deliberately release the unscaled font's mutex here,
* so that we are not holding a lock across two separate calls to
* cairo function, (which would give the application some
* opportunity for creating deadlock. This is obviously unsafe,
* but as documented, the user must add manual locking when using
* this function. */
CAIRO_MUTEX_UNLOCK (scaled_font->unscaled->mutex);
--- a/gfx/cairo/cairo/src/cairo-glitz-surface.c
+++ b/gfx/cairo/cairo/src/cairo-glitz-surface.c
@@ -28,31 +28,31 @@
#include "cairo-glitz.h"
#include "cairo-glitz-private.h"
typedef struct _cairo_glitz_surface {
cairo_surface_t base;
glitz_surface_t *surface;
glitz_format_t *format;
- cairo_bool_t has_clip;
- cairo_region_t clip;
+ pixman_region16_t *clip;
} cairo_glitz_surface_t;
static const cairo_surface_backend_t *
_cairo_glitz_surface_get_backend (void);
static cairo_status_t
_cairo_glitz_surface_finish (void *abstract_surface)
{
cairo_glitz_surface_t *surface = abstract_surface;
- if (surface->has_clip) {
- glitz_surface_set_clip_region (surface->surface, 0, 0, NULL, 0);
- _cairo_region_fini (&surface->clip);
+ if (surface->clip)
+ {
+ glitz_surface_set_clip_region (surface->surface, 0, 0, NULL, 0);
+ pixman_region_destroy (surface->clip);
}
glitz_surface_destroy (surface->surface);
return CAIRO_STATUS_SUCCESS;
}
static glitz_format_name_t
@@ -105,100 +105,29 @@ static cairo_surface_t *
crsurface = cairo_glitz_surface_create (surface);
glitz_surface_destroy (surface);
return crsurface;
}
-static cairo_bool_t
-_CAIRO_MASK_FORMAT (cairo_format_masks_t *masks, cairo_format_t *format)
-{
- switch (masks->bpp) {
- case 32:
- if (masks->alpha_mask == 0xff000000 &&
- masks->red_mask == 0x00ff0000 &&
- masks->green_mask == 0x0000ff00 &&
- masks->blue_mask == 0x000000ff)
- {
- *format = CAIRO_FORMAT_ARGB32;
- return TRUE;
- }
- if (masks->alpha_mask == 0x00000000 &&
- masks->red_mask == 0x00ff0000 &&
- masks->green_mask == 0x0000ff00 &&
- masks->blue_mask == 0x000000ff)
- {
- *format = CAIRO_FORMAT_RGB24;
- return TRUE;
- }
- break;
- case 8:
- if (masks->alpha_mask == 0xff)
- {
- *format = CAIRO_FORMAT_A8;
- return TRUE;
- }
- break;
- case 1:
- if (masks->alpha_mask == 0x1)
- {
- *format = CAIRO_FORMAT_A1;
- return TRUE;
- }
- break;
- }
- return FALSE;
-}
-
-static glitz_box_t *
-_cairo_glitz_get_boxes_from_region (cairo_region_t *region, int *nboxes)
-{
- cairo_box_int_t *cboxes;
- glitz_box_t *gboxes;
- int n, i;
-
- if (_cairo_region_get_boxes (&surface->clip, &n, &cboxes) != CAIRO_STATUS_SUCCESS)
- return NULL;
-
- *nboxes = n;
- if (n == 0)
- return NULL;
-
- gboxes = _cairo_malloc_ab (n, sizeof(glitz_box_t));
- if (gboxes == NULL)
- goto done;
-
- for (i = 0; i < n; i++) {
- gboxes[i].x1 = cboxes[i].p1.x;
- gboxes[i].y1 = cboxes[i].p1.y;
- gboxes[i].x2 = cboxes[i].p2.x;
- gboxes[i].y2 = cboxes[i].p2.y;
- }
-
-done:
- _cairo_region_boxes_fini (&sruface->clip, &cboxes);
- return gboxes;
-}
-
static cairo_status_t
_cairo_glitz_surface_get_image (cairo_glitz_surface_t *surface,
- cairo_rectangle_int_t *interest,
+ cairo_rectangle_int16_t *interest,
cairo_image_surface_t **image_out,
- cairo_rectangle_int_t *rect_out)
+ cairo_rectangle_int16_t *rect_out)
{
cairo_image_surface_t *image;
int x1, y1, x2, y2;
int width, height;
unsigned char *pixels;
- cairo_format_masks_t masks;
+ cairo_format_masks_t format;
glitz_buffer_t *buffer;
glitz_pixel_format_t pf;
- cairo_format_t format;
x1 = 0;
y1 = 0;
x2 = glitz_surface_get_width (surface->surface);
y2 = glitz_surface_get_height (surface->surface);
if (interest)
{
@@ -226,187 +155,126 @@ static cairo_status_t
rect_out->x = x1;
rect_out->y = y1;
rect_out->width = width;
rect_out->height = height;
}
if (surface->format->color.fourcc == GLITZ_FOURCC_RGB) {
if (surface->format->color.red_size > 0) {
- masks.bpp = 32;
+ format.bpp = 32;
if (surface->format->color.alpha_size > 0)
- masks.alpha_mask = 0xff000000;
+ format.alpha_mask = 0xff000000;
else
- masks.alpha_mask = 0x0;
+ format.alpha_mask = 0x0;
- masks.red_mask = 0xff0000;
- masks.green_mask = 0xff00;
- masks.blue_mask = 0xff;
+ format.red_mask = 0xff0000;
+ format.green_mask = 0xff00;
+ format.blue_mask = 0xff;
} else {
- masks.bpp = 8;
- masks.blue_mask = masks.green_mask = masks.red_mask = 0x0;
- masks.alpha_mask = 0xff;
+ format.bpp = 8;
+ format.blue_mask = format.green_mask = format.red_mask = 0x0;
+ format.alpha_mask = 0xff;
}
} else {
- masks.bpp = 32;
- masks.alpha_mask = 0xff000000;
- masks.red_mask = 0xff0000;
- masks.green_mask = 0xff00;
- masks.blue_mask = 0xff;
+ format.bpp = 32;
+ format.alpha_mask = 0xff000000;
+ format.red_mask = 0xff0000;
+ format.green_mask = 0xff00;
+ format.blue_mask = 0xff;
}
pf.fourcc = GLITZ_FOURCC_RGB;
- pf.masks.bpp = masks.bpp;
- pf.masks.alpha_mask = masks.alpha_mask;
- pf.masks.red_mask = masks.red_mask;
- pf.masks.green_mask = masks.green_mask;
- pf.masks.blue_mask = masks.blue_mask;
+ pf.masks.bpp = format.bpp;
+ pf.masks.alpha_mask = format.alpha_mask;
+ pf.masks.red_mask = format.red_mask;
+ pf.masks.green_mask = format.green_mask;
+ pf.masks.blue_mask = format.blue_mask;
pf.xoffset = 0;
pf.skip_lines = 0;
/* XXX: we should eventually return images with negative stride,
need to verify that libpixman have no problem with this first. */
- pf.bytes_per_line = (((width * masks.bpp) / 8) + 3) & -4;
+ pf.bytes_per_line = (((width * format.bpp) / 8) + 3) & -4;
pf.scanline_order = GLITZ_PIXEL_SCANLINE_ORDER_TOP_DOWN;
- pixels = _cairo_malloc_ab (height, pf.bytes_per_line);
+ pixels = malloc (height * pf.bytes_per_line);
if (!pixels)
return CAIRO_STATUS_NO_MEMORY;
buffer = glitz_buffer_create_for_data (pixels);
if (!buffer) {
free (pixels);
return CAIRO_STATUS_NO_MEMORY;
}
/* clear out the glitz clip; the clip affects glitz_get_pixels */
- if (surface->has_clip)
+ if (surface->clip)
glitz_surface_set_clip_region (surface->surface,
0, 0, NULL, 0);
glitz_get_pixels (surface->surface,
x1, y1,
width, height,
&pf,
buffer);
glitz_buffer_destroy (buffer);
/* restore the clip, if any */
- if (surface->has_clip) {
+ if (surface->clip) {
glitz_box_t *box;
- int n;
+ int n;
- box = _cairo_glitz_get_boxes_from_region (&surface->clip, &n);
- if (box == NULL && n != 0) {
- free (pixels);
- return CAIRO_STATUS_NO_MEMORY;
- }
-
+ box = (glitz_box_t *) pixman_region_rects (surface->clip);
+ n = pixman_region_num_rects (surface->clip);
glitz_surface_set_clip_region (surface->surface, 0, 0, box, n);
-
- free (box);
}
- /*
- * Prefer to use a standard pixman format instead of the
- * general masks case.
- */
- if (_CAIRO_MASK_FORMAT (&masks, &format)) {
- image = (cairo_image_surface_t *)
- cairo_image_surface_create_for_data (pixels,
- format,
- x2 - x1,
- y2 - y1,
- pf.bytes_per_line);
- if (image->base.status)
- goto FAIL;
- } else {
- /*
- * XXX This can't work. We must convert the data to one of the
- * supported pixman formats. Pixman needs another function
- * which takes data in an arbitrary format and converts it
- * to something supported by that library.
- */
- image = (cairo_image_surface_t *)
- _cairo_image_surface_create_with_masks (pixels,
- &masks,
- x2 - x1,
- y2 - y1,
- pf.bytes_per_line);
- if (image->base.status)
- goto FAIL;
+ image = (cairo_image_surface_t *)
+ _cairo_image_surface_create_with_masks (pixels,
+ &format,
+ width, height,
+ pf.bytes_per_line);
+ if (image->base.status)
+ {
+ free (pixels);
+ return CAIRO_STATUS_NO_MEMORY;
}
_cairo_image_surface_assume_ownership_of_data (image);
*image_out = image;
return CAIRO_STATUS_SUCCESS;
-
-FAIL:
- free (pixels);
- return CAIRO_STATUS_NO_MEMORY;
-}
-
-static void
-cairo_format_get_masks (cairo_format_t format,
- uint32_t *bpp,
- uint32_t *alpha,
- uint32_t *red,
- uint32_t *green,
- uint32_t *blue)
-{
- *red = 0x0;
- *green = 0x0;
- *blue = 0x0;
- *alpha = 0x0;
-
- switch (format)
- {
- case CAIRO_FORMAT_ARGB32:
- *alpha = 0xff000000;
- case CAIRO_FORMAT_RGB24:
- default:
- *bpp = 32;
- *red = 0x00ff0000;
- *green = 0x0000ff00;
- *blue = 0x000000ff;
- break;
-
- case CAIRO_FORMAT_A8:
- *bpp = 8;
- *alpha = 0xff;
- break;
-
- case CAIRO_FORMAT_A1:
- *bpp = 1;
- *alpha = 0x1;
- break;
- }
}
static cairo_status_t
_cairo_glitz_surface_set_image (void *abstract_surface,
cairo_image_surface_t *image,
int src_x,
int src_y,
int width,
int height,
int x_dst,
int y_dst)
{
cairo_glitz_surface_t *surface = abstract_surface;
glitz_buffer_t *buffer;
glitz_pixel_format_t pf;
- uint32_t bpp, am, rm, gm, bm;
+ pixman_format_t *format;
+ unsigned int bpp, am, rm, gm, bm;
char *data;
- cairo_format_get_masks (image->format, &bpp, &am, &rm, &gm, &bm);
+ format = pixman_image_get_format (image->pixman_image);
+ if (!format)
+ return CAIRO_STATUS_NO_MEMORY;
+
+ pixman_format_get_masks (format, &bpp, &am, &rm, &gm, &bm);
pf.fourcc = GLITZ_FOURCC_RGB;
pf.masks.bpp = bpp;
pf.masks.alpha_mask = am;
pf.masks.red_mask = rm;
pf.masks.green_mask = gm;
pf.masks.blue_mask = bm;
pf.xoffset = src_x;
@@ -458,19 +326,19 @@ static void
cairo_image_surface_t *image,
void *image_extra)
{
cairo_surface_destroy (&image->base);
}
static cairo_status_t
_cairo_glitz_surface_acquire_dest_image (void *abstract_surface,
- cairo_rectangle_int_t *interest_rect,
+ cairo_rectangle_int16_t *interest_rect,
cairo_image_surface_t **image_out,
- cairo_rectangle_int_t *image_rect_out,
+ cairo_rectangle_int16_t *image_rect_out,
void **image_extra)
{
cairo_glitz_surface_t *surface = abstract_surface;
cairo_image_surface_t *image;
cairo_status_t status;
status = _cairo_glitz_surface_get_image (surface, interest_rect, &image,
image_rect_out);
@@ -480,19 +348,19 @@ static cairo_status_t
*image_out = image;
*image_extra = NULL;
return status;
}
static void
_cairo_glitz_surface_release_dest_image (void *abstract_surface,
- cairo_rectangle_int_t *interest_rect,
+ cairo_rectangle_int16_t *interest_rect,
cairo_image_surface_t *image,
- cairo_rectangle_int_t *image_rect,
+ cairo_rectangle_int16_t *image_rect,
void *image_extra)
{
cairo_glitz_surface_t *surface = abstract_surface;
_cairo_glitz_surface_set_image (surface, image, 0, 0,
image->width, image->height,
image_rect->x, image_rect->y);
@@ -519,18 +387,18 @@ static cairo_status_t
*clone_out = cairo_surface_reference (src);
return CAIRO_STATUS_SUCCESS;
}
else if (_cairo_surface_is_image (src))
{
cairo_image_surface_t *image_src = (cairo_image_surface_t *) src;
cairo_content_t content;
- cairo_rectangle_int_t image_extent;
- cairo_rectangle_int_t extent;
+ cairo_rectangle_int16_t image_extent;
+ cairo_rectangle_int16_t extent;
content = _cairo_content_from_format (image_src->format);
clone = (cairo_glitz_surface_t *)
_cairo_glitz_surface_create_similar (surface, content,
image_src->width,
image_src->height);
if (clone->base.status)
@@ -717,17 +585,17 @@ static cairo_int_status_t
switch (pattern->type) {
case CAIRO_PATTERN_TYPE_LINEAR:
case CAIRO_PATTERN_TYPE_RADIAL: {
cairo_gradient_pattern_t *gradient =
(cairo_gradient_pattern_t *) pattern;
char *data;
glitz_fixed16_16_t *params;
- unsigned int n_params;
+ int n_params;
unsigned int *pixels;
unsigned int i, n_base_params;
glitz_buffer_t *buffer;
static const glitz_pixel_format_t format = {
GLITZ_FOURCC_RGB,
{
32,
0xff000000,
@@ -754,32 +622,18 @@ static cairo_int_status_t
if (pattern->type == CAIRO_PATTERN_TYPE_RADIAL)
n_base_params = 6;
else
n_base_params = 4;
n_params = gradient->n_stops * 3 + n_base_params;
- /* check for int overflow */
- {
- int size1, size2;
- if (n_params >= INT32_MAX / sizeof (glitz_fixed16_16_t) ||
- gradient->n_stops >= INT32_MAX / sizeof (unsigned int))
- return CAIRO_STATUS_NO_MEMORY;
-
- size1 = n_params * sizeof (glitz_fixed16_16_t);
- size2 = gradient->n_stops * sizeof (unsigned int);
-
- if (size1 >= INT32_MAX - size2)
- return CAIRO_STATUS_NO_MEMORY;
-
- data = malloc (size1 + size2);
- }
-
+ data = malloc (sizeof (glitz_fixed16_16_t) * n_params +
+ sizeof (unsigned int) * gradient->n_stops);
if (!data)
return CAIRO_STATUS_NO_MEMORY;
params = (glitz_fixed16_16_t *) data;
pixels = (unsigned int *)
(data + sizeof (glitz_fixed16_16_t) * n_params);
buffer = glitz_buffer_create_for_data (pixels);
@@ -809,40 +663,40 @@ static cairo_int_status_t
(((int) (gradient->stops[i].color.blue >> 8)));
params[n_base_params + 3 * i + 0] = gradient->stops[i].x;
params[n_base_params + 3 * i + 1] = i << 16;
params[n_base_params + 3 * i + 2] = 0;
}
glitz_set_pixels (src->surface, 0, 0, gradient->n_stops, 1,
- (glitz_pixel_format_t *)&format, buffer);
+ &format, buffer);
glitz_buffer_destroy (buffer);
if (pattern->type == CAIRO_PATTERN_TYPE_LINEAR)
{
cairo_linear_pattern_t *grad = (cairo_linear_pattern_t *) pattern;
- params[0] = grad->p1.x;
- params[1] = grad->p1.y;
- params[2] = grad->p2.x;
- params[3] = grad->p2.y;
+ params[0] = grad->gradient.p1.x;
+ params[1] = grad->gradient.p1.y;
+ params[2] = grad->gradient.p2.x;
+ params[3] = grad->gradient.p2.y;
attr->filter = GLITZ_FILTER_LINEAR_GRADIENT;
}
else
{
cairo_radial_pattern_t *grad = (cairo_radial_pattern_t *) pattern;
- params[0] = grad->c1.x;
- params[1] = grad->c1.y;
- params[2] = grad->radius1;
- params[3] = grad->c2.x;
- params[4] = grad->c2.y;
- params[5] = grad->radius2;
+ params[0] = grad->gradient.c1.x;
+ params[1] = grad->gradient.c1.y;
+ params[2] = grad->gradient.c1.radius;
+ params[3] = grad->gradient.c2.x;
+ params[4] = grad->gradient.c2.y;
+ params[5] = grad->gradient.c2.radius;
attr->filter = GLITZ_FILTER_RADIAL_GRADIENT;
}
switch (pattern->extend) {
case CAIRO_EXTEND_NONE:
attr->fill = GLITZ_FILL_TRANSPARENT;
break;
case CAIRO_EXTEND_REPEAT:
@@ -963,43 +817,36 @@ static cairo_int_status_t
{
cairo_color_t combined;
cairo_solid_pattern_t *src_solid = (cairo_solid_pattern_t *) src;
cairo_solid_pattern_t *mask_solid = (cairo_solid_pattern_t *) mask;
combined = src_solid->color;
_cairo_color_multiply_alpha (&combined, mask_solid->color.alpha);
- _cairo_pattern_init_solid (&tmp.solid, &combined,
- CAIRO_COLOR_IS_OPAQUE (&combined) ?
- CAIRO_CONTENT_COLOR :
- CAIRO_CONTENT_COLOR_ALPHA);
+ _cairo_pattern_init_solid (&tmp.solid, &combined);
mask = NULL;
} else {
- status = _cairo_pattern_init_copy (&tmp.base, src);
- if (status)
- return status;
+ _cairo_pattern_init_copy (&tmp.base, src);
}
status = _cairo_glitz_pattern_acquire_surface (&tmp.base, dst,
src_x, src_y,
width, height,
src_out, sattr);
_cairo_pattern_fini (&tmp.base);
if (status)
return status;
if (mask)
{
- status = _cairo_pattern_init_copy (&tmp.base, mask);
- if (status)
- return status;
+ _cairo_pattern_init_copy (&tmp.base, mask);
status = _cairo_glitz_pattern_acquire_surface (&tmp.base, dst,
mask_x, mask_y,
width, height,
mask_out, mattr);
if (status)
_cairo_glitz_pattern_release_surface (&tmp.base, *src_out, sattr);
@@ -1105,17 +952,17 @@ static cairo_int_status_t
return CAIRO_STATUS_SUCCESS;
}
static cairo_int_status_t
_cairo_glitz_surface_fill_rectangles (void *abstract_dst,
cairo_operator_t op,
const cairo_color_t *color,
- cairo_rectangle_int_t *rects,
+ cairo_rectangle_int16_t *rects,
int n_rects)
{
cairo_glitz_surface_t *dst = abstract_dst;
cairo_glitz_surface_t *src;
switch (op) {
case CAIRO_OPERATOR_SOURCE: {
glitz_color_t glitz_color;
@@ -1150,18 +997,17 @@ static cairo_int_status_t
default:
if (_glitz_ensure_target (dst->surface))
return CAIRO_INT_STATUS_UNSUPPORTED;
src = (cairo_glitz_surface_t *)
_cairo_surface_create_similar_solid (&dst->base,
CAIRO_CONTENT_COLOR_ALPHA,
1, 1,
- (cairo_color_t *) color,
- NULL);
+ (cairo_color_t *) color);
if (src->base.status)
return CAIRO_STATUS_NO_MEMORY;
glitz_surface_set_fill (src->surface, GLITZ_FILL_REPEAT);
while (n_rects--)
{
glitz_composite (_glitz_operator (op),
@@ -1220,19 +1066,17 @@ static cairo_int_status_t
if (op == CAIRO_OPERATOR_SATURATE)
return CAIRO_INT_STATUS_UNSUPPORTED;
if (_glitz_ensure_target (dst->surface))
return CAIRO_INT_STATUS_UNSUPPORTED;
if (pattern->type == CAIRO_PATTERN_TYPE_SURFACE)
{
- status = _cairo_pattern_init_copy (&tmp_src_pattern.base, pattern);
- if (status)
- return status;
+ _cairo_pattern_init_copy (&tmp_src_pattern.base, pattern);
status = _cairo_glitz_pattern_acquire_surface (&tmp_src_pattern.base,
dst,
src_x, src_y,
width, height,
&src, &attributes);
src_pattern = &tmp_src_pattern.base;
}
@@ -1367,17 +1211,17 @@ static cairo_int_status_t
if (image->base.status)
{
cairo_surface_destroy (&src->base);
free (data);
return CAIRO_STATUS_NO_MEMORY;
}
pixman_add_trapezoids (image->pixman_image, -dst_x, -dst_y,
- n_traps, (pixman_trapezoid_t *) traps);
+ (pixman_trapezoid_t *) traps, n_traps);
mask = (cairo_glitz_surface_t *)
_cairo_surface_create_similar_scratch (&dst->base,
CAIRO_CONTENT_ALPHA,
width, height);
if (mask->base.status)
{
_cairo_glitz_pattern_release_surface (src_pattern, src, &attributes);
@@ -1425,65 +1269,53 @@ static cairo_int_status_t
if (glitz_surface_get_status (dst->surface) == GLITZ_STATUS_NOT_SUPPORTED)
return CAIRO_INT_STATUS_UNSUPPORTED;
return CAIRO_STATUS_SUCCESS;
}
static cairo_int_status_t
_cairo_glitz_surface_set_clip_region (void *abstract_surface,
- cairo_region_t *region);
+ pixman_region16_t *region)
{
cairo_glitz_surface_t *surface = abstract_surface;
if (region)
-
{
glitz_box_t *box;
int n;
- if (!surface->has_clip) {
- _cairo_region_init (&surface->clip);
- surface->has_clip = TRUE;
- }
+ if (!surface->clip)
+ {
+ surface->clip = pixman_region_create ();
+ if (!surface->clip)
+ return CAIRO_STATUS_NO_MEMORY;
+ }
+ pixman_region_copy (surface->clip, region);
- if (_cairo_region_copy (&surface->clip, region) != CAIRO_STATUS_SUCCESS)
- {
- _cairo_region_fini (&surface->clip);
- surface->has_clip = FALSE;
- return CAIRO_STATUS_NO_MEMORY;
- }
-
- box = _cairo_glitz_get_boxes_from_region (&surface->clip, &n);
- if (box == NULL && n != 0) {
- _cairo_region_fini (&surface->clip);
- surface->has_clip = FALSE;
- return CAIRO_STATUS_NO_MEMORY;
- }
-
+ box = (glitz_box_t *) pixman_region_rects (surface->clip);
+ n = pixman_region_num_rects (surface->clip);
glitz_surface_set_clip_region (surface->surface, 0, 0, box, n);
-
- free (box);
}
else
{
glitz_surface_set_clip_region (surface->surface, 0, 0, NULL, 0);
- if (surface->has_clip) {
- _cairo_region_fini (&surface->clip);
- surface->has_clip = FALSE;
- }
+ if (surface->clip)
+ pixman_region_destroy (surface->clip);
+
+ surface->clip = NULL;
}
return CAIRO_STATUS_SUCCESS;
}
static cairo_int_status_t
_cairo_glitz_surface_get_extents (void *abstract_surface,
- cairo_rectangle_int_t *rectangle)
+ cairo_rectangle_int16_t *rectangle)
{
cairo_glitz_surface_t *surface = abstract_surface;
rectangle->x = 0;
rectangle->y = 0;
rectangle->width = glitz_surface_get_width (surface->surface);
rectangle->height = glitz_surface_get_height (surface->surface);
@@ -1975,16 +1807,17 @@ static cairo_status_t
cairo_scaled_glyph_t *scaled_glyph)
{
cairo_image_surface_t *glyph_surface = scaled_glyph->surface;
cairo_glitz_surface_font_private_t *font_private;
cairo_glitz_surface_glyph_private_t *glyph_private;
glitz_point_fixed_t p1, p2;
glitz_pixel_format_t pf;
glitz_buffer_t *buffer;
+ pixman_format_t *format;
unsigned int bpp, am, rm, gm, bm;
cairo_int_status_t status;
glyph_private = scaled_glyph->surface_private;
if (glyph_private == NULL)
{
glyph_private = malloc (sizeof (cairo_glitz_surface_glyph_private_t));
if (!glyph_private)
@@ -2011,16 +1844,20 @@ static cairo_status_t
font_private = scaled_font->surface_private;
if (glyph_surface->width == 0 || glyph_surface->height == 0)
{
glyph_private->area = &_empty_area;
return CAIRO_STATUS_SUCCESS;
}
+ format = pixman_image_get_format (glyph_surface->pixman_image);
+ if (!format)
+ return CAIRO_STATUS_NO_MEMORY;
+
if (_cairo_glitz_area_find (font_private->root.area,
glyph_surface->width,
glyph_surface->height,
FALSE, glyph_private))
{
if (_cairo_glitz_area_find (font_private->root.area,
glyph_surface->width,
glyph_surface->height,
@@ -2030,17 +1867,17 @@ static cairo_status_t
buffer = glitz_buffer_create_for_data (glyph_surface->data);
if (!buffer)
{
_cairo_glitz_area_move_out (glyph_private->area);
return CAIRO_STATUS_NO_MEMORY;
}
- cairo_format_get_masks (glyph_surface->format, &bpp, &am, &rm, &gm, &bm);
+ pixman_format_get_masks (format, &bpp, &am, &rm, &gm, &bm);
pf.fourcc = GLITZ_FOURCC_RGB;
pf.masks.bpp = bpp;
pf.masks.alpha_mask = am;
pf.masks.red_mask = rm;
pf.masks.green_mask = gm;
pf.masks.blue_mask = bm;
@@ -2134,29 +1971,19 @@ static cairo_int_status_t
if (status)
return status;
_cairo_glitz_surface_set_attributes (src, &attributes);
if (num_glyphs > N_STACK_BUF)
{
char *data;
- size_t size1, size2;
- if ((size_t)num_glyphs >= INT32_MAX / sizeof(void*) ||
- (size_t)num_glyphs >= INT32_MAX / sizeof(glitz_float_t) ||
- ((size_t)num_glyphs * sizeof(glitz_float_t)) >= INT32_MAX / 16)
- goto FAIL1;
-
- size1 = num_glyphs * sizeof(void *);
- size2 = num_glyphs * sizeof(glitz_float_t) * 16;
- if (size1 >= INT32_MAX - size2)
- goto FAIL1;
-
- data = malloc (size1 + size2);
+ data = malloc (num_glyphs * sizeof (void *) +
+ num_glyphs * sizeof (glitz_float_t) * 16);
if (!data)
goto FAIL1;
scaled_glyphs = (cairo_scaled_glyph_t **) data;
vertices = (glitz_float_t *) (data + num_glyphs * sizeof (void *));
}
else
{
@@ -2340,43 +2167,16 @@ static cairo_status_t
{
cairo_glitz_surface_t *surface = abstract_surface;
glitz_surface_flush (surface->surface);
return CAIRO_STATUS_SUCCESS;
}
-static cairo_bool_t
-_cairo_glitz_surface_is_similar (void *surface_a,
- void *surface_b,
- cairo_content_t content)
-{
- cairo_glitz_surface_t *a = (cairo_glitz_surface_t *) surface_a;
- cairo_glitz_surface_t *b = (cairo_glitz_surface_t *) surface_b;
-
- glitz_drawable_t *drawable_a = glitz_surface_get_drawable (a->surface);
- glitz_drawable_t *drawable_b = glitz_surface_get_drawable (b->surface);
-
- return drawable_a == drawable_b;
-}
-
-static cairo_status_t
-_cairo_glitz_surface_reset (void *abstract_surface)
-{
- cairo_glitz_surface_t *surface = abstract_surface;
- cairo_status_t status;
-
- status = _cairo_glitz_surface_set_clip_region (surface, NULL);
- if (status)
- return status;
-
- return CAIRO_STATUS_SUCCESS;
-}
-
static const cairo_surface_backend_t cairo_glitz_surface_backend = {
CAIRO_SURFACE_TYPE_GLITZ,
_cairo_glitz_surface_create_similar,
_cairo_glitz_surface_finish,
_cairo_glitz_surface_acquire_source_image,
_cairo_glitz_surface_release_source_image,
_cairo_glitz_surface_acquire_dest_image,
_cairo_glitz_surface_release_dest_image,
@@ -2389,28 +2189,17 @@ static const cairo_surface_backend_t cai
_cairo_glitz_surface_set_clip_region,
NULL, /* intersect_clip_path */
_cairo_glitz_surface_get_extents,
_cairo_glitz_surface_old_show_glyphs,
NULL, /* get_font_options */
_cairo_glitz_surface_flush,
NULL, /* mark_dirty_rectangle */
_cairo_glitz_surface_scaled_font_fini,
- _cairo_glitz_surface_scaled_glyph_fini,
-
- NULL, /* paint */
- NULL, /* mask */
- NULL, /* stroke */
- NULL, /* fill */
- NULL, /* show_glyphs */
-
- NULL, /* snapshot */
- _cairo_glitz_surface_is_similar,
-
- _cairo_glitz_surface_reset
+ _cairo_glitz_surface_scaled_glyph_fini
};
static const cairo_surface_backend_t *
_cairo_glitz_surface_get_backend (void)
{
return &cairo_glitz_surface_backend;
}
@@ -2446,15 +2235,15 @@ cairo_glitz_surface_create (glitz_surfac
}
format = glitz_surface_get_format (surface);
_cairo_surface_init (&crsurface->base, &cairo_glitz_surface_backend,
_glitz_format_to_content(format));
glitz_surface_reference (surface);
- crsurface->surface = surface;
- crsurface->format = format;
- crsurface->has_clip = FALSE;
+ crsurface->surface = surface;
+ crsurface->format = format;
+ crsurface->clip = NULL;
return (cairo_surface_t *) crsurface;
}
slim_hidden_def (cairo_glitz_surface_create);
--- a/gfx/cairo/cairo/src/cairo-gstate.c
+++ b/gfx/cairo/cairo/src/cairo-gstate.c
@@ -30,16 +30,18 @@
*
* The Initial Developer of the Original Code is University of Southern
* California.
*
* Contributor(s):
* Carl D. Worth <cworth@cworth.org>
*/
+#include <stdlib.h>
+
#include "cairoint.h"
#include "cairo-clip-private.h"
#include "cairo-gstate-private.h"
static cairo_status_t
_cairo_gstate_init_copy (cairo_gstate_t *gstate, cairo_gstate_t *other);
@@ -57,18 +59,16 @@ static void
const cairo_glyph_t *glyphs,
int num_glyphs,
cairo_glyph_t *transformed_glyphs);
cairo_status_t
_cairo_gstate_init (cairo_gstate_t *gstate,
cairo_surface_t *target)
{
- gstate->next = NULL;
-
gstate->op = CAIRO_GSTATE_OPERATOR_DEFAULT;
gstate->tolerance = CAIRO_GSTATE_TOLERANCE_DEFAULT;
gstate->antialias = CAIRO_ANTIALIAS_DEFAULT;
_cairo_stroke_style_init (&gstate->stroke_style);
gstate->fill_rule = CAIRO_GSTATE_FILL_RULE_DEFAULT;
@@ -86,22 +86,23 @@ cairo_status_t
gstate->target = cairo_surface_reference (target);
gstate->parent_target = NULL;
gstate->original_target = cairo_surface_reference (target);
_cairo_gstate_identity_matrix (gstate);
gstate->source_ctm_inverse = gstate->ctm_inverse;
- gstate->source = _cairo_pattern_create_solid (CAIRO_COLOR_BLACK,
- CAIRO_CONTENT_COLOR);
+ gstate->source = _cairo_pattern_create_solid (CAIRO_COLOR_BLACK);
if (gstate->source->status)
return CAIRO_STATUS_NO_MEMORY;
- return target ? target->status : CAIRO_STATUS_NULL_POINTER;
+ gstate->next = NULL;
+
+ return CAIRO_STATUS_SUCCESS;
}
/**
* _cairo_gstate_init_copy:
*
* Initialize @gstate by performing a deep copy of state fields from
* @other. Note that gstate->next is not copied but is set to NULL by
* this function.
@@ -125,19 +126,17 @@ static cairo_status_t
gstate->font_face = cairo_font_face_reference (other->font_face);
gstate->scaled_font = cairo_scaled_font_reference (other->scaled_font);
gstate->font_matrix = other->font_matrix;
_cairo_font_options_init_copy (&gstate->font_options , &other->font_options);
- status = _cairo_clip_init_copy (&gstate->clip, &other->clip);
- if (status)
- return status;
+ _cairo_clip_init_copy (&gstate->clip, &other->clip);
gstate->target = cairo_surface_reference (other->target);
/* parent_target is always set to NULL; it's only ever set by redirect_target */
gstate->parent_target = NULL;
gstate->original_target = cairo_surface_reference (other->original_target);
gstate->ctm = other->ctm;
gstate->ctm_inverse = other->ctm_inverse;
@@ -156,32 +155,32 @@ void
_cairo_stroke_style_fini (&gstate->stroke_style);
cairo_font_face_destroy (gstate->font_face);
gstate->font_face = NULL;
cairo_scaled_font_destroy (gstate->scaled_font);
gstate->scaled_font = NULL;
- _cairo_clip_reset (&gstate->clip);
+ _cairo_clip_fini (&gstate->clip);
cairo_surface_destroy (gstate->target);
gstate->target = NULL;
cairo_surface_destroy (gstate->parent_target);
gstate->parent_target = NULL;
cairo_surface_destroy (gstate->original_target);
gstate->target = NULL;
cairo_pattern_destroy (gstate->source);
gstate->source = NULL;
}
-static void
+void
_cairo_gstate_destroy (cairo_gstate_t *gstate)
{
if (gstate == NULL)
return;
_cairo_gstate_fini (gstate);
free (gstate);
}
@@ -193,17 +192,17 @@ static void
* Create a new #cairo_gstate_t setting all graphics state parameters
* to the same values as contained in @other. gstate->next will be set
* to NULL and may be used by the caller to chain cairo_gstate_t
* objects together.
*
* Return value: a new cairo_gstate_t or NULL if there is insufficient
* memory.
**/
-static cairo_gstate_t*
+cairo_gstate_t*
_cairo_gstate_clone (cairo_gstate_t *other)
{
cairo_status_t status;
cairo_gstate_t *gstate;
assert (other != NULL);
gstate = malloc (sizeof (cairo_gstate_t));
@@ -214,65 +213,16 @@ static cairo_gstate_t*
if (status) {
free (gstate);
return NULL;
}
return gstate;
}
-/**
- * _cairo_gstate_save:
- * @gstate: input/output gstate pointer
- *
- * Makes a copy of the current state of @gstate and saves it
- * to @gstate->next, then put the address of the newly allcated
- * copy into @gstate. _cairo_gstate_restore() reverses this.
- **/
-cairo_status_t
-_cairo_gstate_save (cairo_gstate_t **gstate)
-{
- cairo_gstate_t *top;
-
- top = _cairo_gstate_clone (*gstate);
-
- if (top == NULL) {
- return CAIRO_STATUS_NO_MEMORY;
- }
-
- top->next = *gstate;
- *gstate = top;
-
- return CAIRO_STATUS_SUCCESS;
-}
-
-/**
- * _cairo_gstate_restore:
- * @gstate: input/output gstate pointer
- *
- * Reverses the effects of one _cairo_gstate_save() call.
- **/
-cairo_status_t
-_cairo_gstate_restore (cairo_gstate_t **gstate)
-{
- cairo_gstate_t *top;
-
- top = *gstate;
-
- if (top->next == NULL) {
- return CAIRO_STATUS_INVALID_RESTORE;
- }
-
- *gstate = top->next;
-
- _cairo_gstate_destroy (top);
-
- return CAIRO_STATUS_SUCCESS;
-}
-
static cairo_status_t
_cairo_gstate_recursive_apply_clip_path (cairo_gstate_t *gstate,
cairo_clip_path_t *cpath)
{
cairo_status_t status;
if (cpath == NULL)
return CAIRO_STATUS_SUCCESS;
@@ -297,47 +247,41 @@ static cairo_status_t
* Redirect @gstate rendering to a "child" target. The original
* "parent" target with which the gstate was created will not be
* affected. See _cairo_gstate_get_target().
*
* Unless the redirected target has the same device offsets as the
* original #cairo_t target, the clip will be INVALID after this call,
* and the caller should either recreate or reset the clip.
**/
-cairo_status_t
+void
_cairo_gstate_redirect_target (cairo_gstate_t *gstate, cairo_surface_t *child)
{
- cairo_status_t status;
-
/* If this gstate is already redirected, this is an error; we need a
* new gstate to be able to redirect */
assert (gstate->parent_target == NULL);
/* Set up our new parent_target based on our current target;
* gstate->parent_target will take the ref that is held by gstate->target
*/
cairo_surface_destroy (gstate->parent_target);
gstate->parent_target = gstate->target;
/* Now set up our new target; we overwrite gstate->target directly,
* since its ref is now owned by gstate->parent_target */
gstate->target = cairo_surface_reference (child);
- _cairo_clip_reset (&gstate->clip);
- status = _cairo_clip_init_deep_copy (&gstate->clip, &gstate->next->clip, child);
- if (status)
- return status;
+ _cairo_clip_fini (&gstate->clip);
+ _cairo_clip_init_deep_copy (&gstate->clip, &gstate->next->clip, child);
/* The clip is in surface backend coordinates for the previous target;
* translate it into the child's backend coordinates. */
_cairo_clip_translate (&gstate->clip,
_cairo_fixed_from_double (child->device_transform.x0 - gstate->parent_target->device_transform.x0),
_cairo_fixed_from_double (child->device_transform.y0 - gstate->parent_target->device_transform.y0));
-
- return CAIRO_STATUS_SUCCESS;
}
/**
* _cairo_gstate_is_redirected
* @gstate: a #cairo_gstate_t
*
* Return value: TRUE if the gstate is redirected to a target
* different than the original, FALSE otherwise.
@@ -407,17 +351,17 @@ cairo_clip_t *
cairo_status_t
_cairo_gstate_set_source (cairo_gstate_t *gstate,
cairo_pattern_t *source)
{
if (source->status)
return source->status;
- source = cairo_pattern_reference (source);
+ cairo_pattern_reference (source);
cairo_pattern_destroy (gstate->source);
gstate->source = source;
gstate->source_ctm_inverse = gstate->ctm_inverse;
return CAIRO_STATUS_SUCCESS;
}
cairo_pattern_t *
@@ -525,17 +469,17 @@ cairo_status_t
gstate->stroke_style.num_dashes = num_dashes;
if (gstate->stroke_style.num_dashes == 0) {
gstate->stroke_style.dash = NULL;
gstate->stroke_style.dash_offset = 0.0;
return CAIRO_STATUS_SUCCESS;
}
- gstate->stroke_style.dash = _cairo_malloc_ab (gstate->stroke_style.num_dashes, sizeof (double));
+ gstate->stroke_style.dash = malloc (gstate->stroke_style.num_dashes * sizeof (double));
if (gstate->stroke_style.dash == NULL) {
gstate->stroke_style.num_dashes = 0;
return CAIRO_STATUS_NO_MEMORY;
}
memcpy (gstate->stroke_style.dash, dash, gstate->stroke_style.num_dashes * sizeof (double));
dash_total = 0.0;
@@ -558,34 +502,16 @@ cairo_status_t
if (offset < 0)
offset += ceil (-offset / dash_total + 0.5) * dash_total;
gstate->stroke_style.dash_offset = offset;
return CAIRO_STATUS_SUCCESS;
}
-void
-_cairo_gstate_get_dash (cairo_gstate_t *gstate,
- double *dashes,
- int *num_dashes,
- double *offset)
-{
- if (dashes)
- memcpy (dashes,
- gstate->stroke_style.dash,
- sizeof (double) * gstate->stroke_style.num_dashes);
-
- if (num_dashes)
- *num_dashes = gstate->stroke_style.num_dashes;
-
- if (offset)
- *offset = gstate->stroke_style.dash_offset;
-}
-
cairo_status_t
_cairo_gstate_set_miter_limit (cairo_gstate_t *gstate, double limit)
{
gstate->stroke_style.miter_limit = limit;
return CAIRO_STATUS_SUCCESS;
}
@@ -652,26 +578,23 @@ cairo_status_t
return CAIRO_STATUS_SUCCESS;
}
cairo_status_t
_cairo_gstate_transform (cairo_gstate_t *gstate,
const cairo_matrix_t *matrix)
{
cairo_matrix_t tmp;
- cairo_status_t status;
_cairo_gstate_unset_scaled_font (gstate);
tmp = *matrix;
cairo_matrix_multiply (&gstate->ctm, &tmp, &gstate->ctm);
- status = cairo_matrix_invert (&tmp);
- if (status)
- return status;
+ cairo_matrix_invert (&tmp);
cairo_matrix_multiply (&gstate->ctm_inverse, &gstate->ctm_inverse, &tmp);
return CAIRO_STATUS_SUCCESS;
}
cairo_status_t
_cairo_gstate_set_matrix (cairo_gstate_t *gstate,
const cairo_matrix_t *matrix)
@@ -685,49 +608,59 @@ cairo_status_t
gstate->ctm_inverse = *matrix;
status = cairo_matrix_invert (&gstate->ctm_inverse);
if (status)
return status;
return CAIRO_STATUS_SUCCESS;
}
-void
+cairo_status_t
_cairo_gstate_identity_matrix (cairo_gstate_t *gstate)
{
_cairo_gstate_unset_scaled_font (gstate);
cairo_matrix_init_identity (&gstate->ctm);
cairo_matrix_init_identity (&gstate->ctm_inverse);
+
+ return CAIRO_STATUS_SUCCESS;
}
-void
+cairo_status_t
_cairo_gstate_user_to_device (cairo_gstate_t *gstate, double *x, double *y)
{
cairo_matrix_transform_point (&gstate->ctm, x, y);
+
+ return CAIRO_STATUS_SUCCESS;
}
-void
+cairo_status_t
_cairo_gstate_user_to_device_distance (cairo_gstate_t *gstate,
double *dx, double *dy)
{
cairo_matrix_transform_distance (&gstate->ctm, dx, dy);
+
+ return CAIRO_STATUS_SUCCESS;
}
-void
+cairo_status_t
_cairo_gstate_device_to_user (cairo_gstate_t *gstate, double *x, double *y)
{
cairo_matrix_transform_point (&gstate->ctm_inverse, x, y);
+
+ return CAIRO_STATUS_SUCCESS;
}
-void
+cairo_status_t
_cairo_gstate_device_to_user_distance (cairo_gstate_t *gstate,
double *dx, double *dy)
{
cairo_matrix_transform_distance (&gstate->ctm_inverse, dx, dy);
+
+ return CAIRO_STATUS_SUCCESS;
}
void
_cairo_gstate_user_to_backend (cairo_gstate_t *gstate, double *x, double *y)
{
cairo_matrix_transform_point (&gstate->ctm, x, y);
cairo_matrix_transform_point (&gstate->target->device_transform, x, y);
}
@@ -759,77 +692,70 @@ cairo_status_t
{
cairo_status_t status;
_cairo_pen_init (&gstate);
return CAIRO_STATUS_SUCCESS;
}
*/
-static cairo_status_t
+static void
_cairo_gstate_copy_transformed_pattern (cairo_gstate_t *gstate,
cairo_pattern_t *pattern,
cairo_pattern_t *original,
cairo_matrix_t *ctm_inverse)
{
cairo_surface_pattern_t *surface_pattern;
cairo_surface_t *surface;
- cairo_status_t status;
- status = _cairo_pattern_init_copy (pattern, original);
- if (status)
- return status;
-
+ _cairo_pattern_init_copy (pattern, original);
_cairo_pattern_transform (pattern, ctm_inverse);
if (cairo_pattern_get_type (original) == CAIRO_PATTERN_TYPE_SURFACE) {
surface_pattern = (cairo_surface_pattern_t *) original;
surface = surface_pattern->surface;
if (_cairo_surface_has_device_transform (surface))
_cairo_pattern_transform (pattern, &surface->device_transform);
}
- return CAIRO_STATUS_SUCCESS;
}
-static cairo_status_t
+static void
_cairo_gstate_copy_transformed_source (cairo_gstate_t *gstate,
cairo_pattern_t *pattern)
{
- return _cairo_gstate_copy_transformed_pattern (gstate, pattern,
- gstate->source,
- &gstate->source_ctm_inverse);
+ _cairo_gstate_copy_transformed_pattern (gstate, pattern,
+ gstate->source,
+ &gstate->source_ctm_inverse);
}
-static cairo_status_t
+static void
_cairo_gstate_copy_transformed_mask (cairo_gstate_t *gstate,
cairo_pattern_t *pattern,
cairo_pattern_t *mask)
{
- return _cairo_gstate_copy_transformed_pattern (gstate, pattern,
- mask,
- &gstate->ctm_inverse);
+ _cairo_gstate_copy_transformed_pattern (gstate, pattern,
+ mask,
+ &gstate->ctm_inverse);
}
cairo_status_t
_cairo_gstate_paint (cairo_gstate_t *gstate)
{
cairo_status_t status;
cairo_pattern_union_t pattern;
if (gstate->source->status)
return gstate->source->status;
status = _cairo_surface_set_clip (gstate->target, &gstate->clip);
if (status)
return status;
- status = _cairo_gstate_copy_transformed_source (gstate, &pattern.base);
- if (status)
- return status;
+ _cairo_gstate_copy_transformed_source (gstate, &pattern.base);
status = _cairo_surface_paint (gstate->target,
gstate->op,
&pattern.base);
_cairo_pattern_fini (&pattern.base);
return status;
@@ -926,32 +852,26 @@ cairo_status_t
if (gstate->source->status)
return gstate->source->status;
status = _cairo_surface_set_clip (gstate->target, &gstate->clip);
if (status)
return status;
- status = _cairo_gstate_copy_transformed_source (gstate, &source_pattern.base);
- if (status)
- return status;
-
- status = _cairo_gstate_copy_transformed_mask (gstate, &mask_pattern.base, mask);
- if (status)
- goto CLEANUP_SOURCE;
+ _cairo_gstate_copy_transformed_source (gstate, &source_pattern.base);
+ _cairo_gstate_copy_transformed_mask (gstate, &mask_pattern.base, mask);
status = _cairo_surface_mask (gstate->target,
gstate->op,
&source_pattern.base,
&mask_pattern.base);
+ _cairo_pattern_fini (&source_pattern.base);
_cairo_pattern_fini (&mask_pattern.base);
-CLEANUP_SOURCE:
- _cairo_pattern_fini (&source_pattern.base);
return status;
}
cairo_status_t
_cairo_gstate_stroke (cairo_gstate_t *gstate, cairo_path_fixed_t *path)
{
cairo_status_t status;
@@ -962,20 +882,17 @@ cairo_status_t
if (gstate->stroke_style.line_width <= 0.0)
return CAIRO_STATUS_SUCCESS;
status = _cairo_surface_set_clip (gstate->target, &gstate->clip);
if (status)
return status;
- status = _cairo_gstate_copy_transformed_source (gstate,
- &source_pattern.base);
- if (status)
- return status;
+ _cairo_gstate_copy_transformed_source (gstate, &source_pattern.base);
status = _cairo_surface_stroke (gstate->target,
gstate->op,
&source_pattern.base,
path,
&gstate->stroke_style,
&gstate->ctm,
&gstate->ctm_inverse,
@@ -1032,19 +949,17 @@ cairo_status_t
if (gstate->source->status)
return gstate->source->status;
status = _cairo_surface_set_clip (gstate->target, &gstate->clip);
if (status)
return status;
- status = _cairo_gstate_copy_transformed_source (gstate, &pattern.base);
- if (status)
- return status;
+ _cairo_gstate_copy_transformed_source (gstate, &pattern.base);
status = _cairo_surface_fill (gstate->target,
gstate->op,
&pattern.base,
path,
gstate->fill_rule,
gstate->tolerance,
gstate->antialias);
@@ -1081,23 +996,39 @@ BAIL:
_cairo_traps_fini (&traps);
return status;
}
cairo_status_t
_cairo_gstate_copy_page (cairo_gstate_t *gstate)
{
- return _cairo_surface_copy_page (gstate->target);
+ cairo_int_status_t status;
+
+ status = _cairo_surface_copy_page (gstate->target);
+
+ /* It's fine if some surfaces just don't support this. */
+ if (status == CAIRO_INT_STATUS_UNSUPPORTED)
+ return CAIRO_STATUS_SUCCESS;
+
+ return status;
}
cairo_status_t
_cairo_gstate_show_page (cairo_gstate_t *gstate)
{
- return _cairo_surface_show_page (gstate->target);
+ cairo_int_status_t status;
+
+ status = _cairo_surface_show_page (gstate->target);
+
+ /* It's fine if some surfaces just don't support this. */
+ if (status == CAIRO_INT_STATUS_UNSUPPORTED)
+ return CAIRO_STATUS_SUCCESS;
+
+ return status;
}
static void
_cairo_gstate_traps_extents_to_user_rectangle (cairo_gstate_t *gstate,
cairo_traps_t *traps,
double *x1, double *y1,
double *x2, double *y2)
{
@@ -1189,19 +1120,17 @@ cairo_status_t
_cairo_traps_fini (&traps);
return status;
}
cairo_status_t
_cairo_gstate_reset_clip (cairo_gstate_t *gstate)
{
- _cairo_clip_reset (&gstate->clip);
-
- return CAIRO_STATUS_SUCCESS;
+ return _cairo_clip_reset (&gstate->clip);
}
cairo_status_t
_cairo_gstate_clip (cairo_gstate_t *gstate, cairo_path_fixed_t *path)
{
return _cairo_clip_clip (&gstate->clip,
path, gstate->fill_rule, gstate->tolerance,
gstate->antialias, gstate->target);
@@ -1209,17 +1138,17 @@ cairo_status_t
cairo_status_t
_cairo_gstate_clip_extents (cairo_gstate_t *gstate,
double *x1,
double *y1,
double *x2,
double *y2)
{
- cairo_rectangle_int_t extents;
+ cairo_rectangle_int16_t extents;
cairo_status_t status;
status = _cairo_surface_get_extents (gstate->target, &extents);
if (status)
return status;
status = _cairo_clip_intersect_to_rectangle (&gstate->clip, &extents);
if (status)
@@ -1256,25 +1185,22 @@ static void
cairo_status_t
_cairo_gstate_select_font_face (cairo_gstate_t *gstate,
const char *family,
cairo_font_slant_t slant,
cairo_font_weight_t weight)
{
cairo_font_face_t *font_face;
- cairo_status_t status;
font_face = _cairo_toy_font_face_create (family, slant, weight);
if (font_face->status)
return font_face->status;
- status = _cairo_gstate_set_font_face (gstate, font_face);
- if (status)
- return status;
+ _cairo_gstate_set_font_face (gstate, font_face);
cairo_font_face_destroy (font_face);
return CAIRO_STATUS_SUCCESS;
}
cairo_status_t
_cairo_gstate_set_font_size (cairo_gstate_t *gstate,
double size)
@@ -1299,23 +1225,25 @@ cairo_status_t
void
_cairo_gstate_get_font_matrix (cairo_gstate_t *gstate,
cairo_matrix_t *matrix)
{
*matrix = gstate->font_matrix;
}
-void
+cairo_status_t
_cairo_gstate_set_font_options (cairo_gstate_t *gstate,
const cairo_font_options_t *options)
{
_cairo_gstate_unset_scaled_font (gstate);
gstate->font_options = *options;
+
+ return CAIRO_STATUS_SUCCESS;
}
void
_cairo_gstate_get_font_options (cairo_gstate_t *gstate,
cairo_font_options_t *options)
{
*options = gstate->font_options;
}
@@ -1424,93 +1352,92 @@ cairo_status_t
* CTM (for user-input glyph vectors), and return values by the CTM inverse
* (for font responses such as metrics or glyph vectors).
*
*/
static cairo_status_t
_cairo_gstate_ensure_font_face (cairo_gstate_t *gstate)
{
- cairo_font_face_t *font_face;
-
- if (gstate->font_face != NULL)
- return gstate->font_face->status;
-
+ if (!gstate->font_face) {
+ cairo_font_face_t *font_face;
- font_face = _cairo_toy_font_face_create (CAIRO_FONT_FAMILY_DEFAULT,
- CAIRO_FONT_SLANT_DEFAULT,
- CAIRO_FONT_WEIGHT_DEFAULT);
- if (font_face->status)
- return font_face->status;
-
- gstate->font_face = font_face;
+ font_face = _cairo_toy_font_face_create (CAIRO_FONT_FAMILY_DEFAULT,
+ CAIRO_FONT_SLANT_DEFAULT,
+ CAIRO_FONT_WEIGHT_DEFAULT);
+ if (font_face->status)
+ return font_face->status;
+ else
+ gstate->font_face = font_face;
+ }
return CAIRO_STATUS_SUCCESS;
}
static cairo_status_t
_cairo_gstate_ensure_scaled_font (cairo_gstate_t *gstate)
{
cairo_status_t status;
cairo_font_options_t options;
- cairo_scaled_font_t *scaled_font;
- if (gstate->scaled_font != NULL)
- return gstate->scaled_font->status;
+ if (gstate->scaled_font)
+ return CAIRO_STATUS_SUCCESS;
status = _cairo_gstate_ensure_font_face (gstate);
if (status)
return status;
cairo_surface_get_font_options (gstate->target, &options);
cairo_font_options_merge (&options, &gstate->font_options);
- scaled_font = cairo_scaled_font_create (gstate->font_face,
- &gstate->font_matrix,
- &gstate->ctm,
- &options);
+ gstate->scaled_font = cairo_scaled_font_create (gstate->font_face,
+ &gstate->font_matrix,
+ &gstate->ctm,
+ &options);
- status = cairo_scaled_font_status (scaled_font);
- if (status)
- return status;
-
- gstate->scaled_font = scaled_font;
+ if (!gstate->scaled_font)
+ return CAIRO_STATUS_NO_MEMORY;
return CAIRO_STATUS_SUCCESS;
}
cairo_status_t
_cairo_gstate_get_font_extents (cairo_gstate_t *gstate,
cairo_font_extents_t *extents)
{
cairo_status_t status = _cairo_gstate_ensure_scaled_font (gstate);
if (status)
return status;
cairo_scaled_font_extents (gstate->scaled_font, extents);
- return cairo_scaled_font_status (gstate->scaled_font);
+ return CAIRO_STATUS_SUCCESS;
}
cairo_status_t
_cairo_gstate_text_to_glyphs (cairo_gstate_t *gstate,
const char *utf8,
double x,
double y,
cairo_glyph_t **glyphs,
int *num_glyphs)
{
cairo_status_t status;
status = _cairo_gstate_ensure_scaled_font (gstate);
if (status)
return status;
- return _cairo_scaled_font_text_to_glyphs (gstate->scaled_font, x, y,
- utf8, glyphs, num_glyphs);
+ status = _cairo_scaled_font_text_to_glyphs (gstate->scaled_font, x, y,
+ utf8, glyphs, num_glyphs);
+
+ if (status || !glyphs || !num_glyphs || !(*glyphs) || !(num_glyphs))
+ return status;
+
+ return CAIRO_STATUS_SUCCESS;
}
cairo_status_t
_cairo_gstate_set_font_face (cairo_gstate_t *gstate,
cairo_font_face_t *font_face)
{
if (font_face && font_face->status)
return font_face->status;
@@ -1536,17 +1463,17 @@ cairo_status_t
status = _cairo_gstate_ensure_scaled_font (gstate);
if (status)
return status;
cairo_scaled_font_glyph_extents (gstate->scaled_font,
glyphs, num_glyphs,
extents);
- return cairo_scaled_font_status (gstate->scaled_font);
+ return CAIRO_STATUS_SUCCESS;
}
#define STACK_GLYPHS_LEN ((int) (CAIRO_STACK_BUFFER_SIZE / sizeof (cairo_glyph_t)))
cairo_status_t
_cairo_gstate_show_glyphs (cairo_gstate_t *gstate,
const cairo_glyph_t *glyphs,
int num_glyphs)
{
@@ -1565,38 +1492,35 @@ cairo_status_t
status = _cairo_gstate_ensure_scaled_font (gstate);
if (status)
return status;
if (num_glyphs <= STACK_GLYPHS_LEN) {
transformed_glyphs = stack_transformed_glyphs;
} else {
- transformed_glyphs = _cairo_malloc_ab (num_glyphs, sizeof(cairo_glyph_t));
+ transformed_glyphs = malloc (num_glyphs * sizeof(cairo_glyph_t));
if (transformed_glyphs == NULL)
return CAIRO_STATUS_NO_MEMORY;
}
_cairo_gstate_transform_glyphs_to_backend (gstate, glyphs, num_glyphs,
transformed_glyphs);
- status = _cairo_gstate_copy_transformed_source (gstate, &source_pattern.base);
- if (status)
- goto CLEANUP_GLYPHS;
+ _cairo_gstate_copy_transformed_source (gstate, &source_pattern.base);
status = _cairo_surface_show_glyphs (gstate->target,
gstate->op,
&source_pattern.base,
transformed_glyphs,
num_glyphs,
gstate->scaled_font);
_cairo_pattern_fini (&source_pattern.base);
-CLEANUP_GLYPHS:
if (transformed_glyphs != stack_transformed_glyphs)
free (transformed_glyphs);
return status;
}
cairo_status_t
_cairo_gstate_glyph_path (cairo_gstate_t *gstate,
@@ -1610,17 +1534,17 @@ cairo_status_t
status = _cairo_gstate_ensure_scaled_font (gstate);
if (status)
return status;
if (num_glyphs < STACK_GLYPHS_LEN)
transformed_glyphs = stack_transformed_glyphs;
else
- transformed_glyphs = _cairo_malloc_ab (num_glyphs, sizeof(cairo_glyph_t));
+ transformed_glyphs = malloc (num_glyphs * sizeof(cairo_glyph_t));
if (transformed_glyphs == NULL)
return CAIRO_STATUS_NO_MEMORY;
_cairo_gstate_transform_glyphs_to_backend (gstate, glyphs, num_glyphs,
transformed_glyphs);
status = _cairo_scaled_font_glyph_path (gstate->scaled_font,
transformed_glyphs, num_glyphs,
--- a/gfx/cairo/cairo/src/cairo-hash-private.h
+++ b/gfx/cairo/cairo/src/cairo-hash-private.h
@@ -34,23 +34,61 @@
* Keith Packard <keithp@keithp.com>
* Graydon Hoare <graydon@redhat.com>
* Carl Worth <cworth@cworth.org>
*/
#ifndef CAIRO_HASH_PRIVATE_H
#define CAIRO_HASH_PRIVATE_H
-#include "cairo-types-private.h"
-
/* XXX: I'd like this file to be self-contained in terms of
* includeability, but that's not really possible with the current
* monolithic cairoint.h. So, for now, just include cairoint.h instead
* if you want to include this file. */
+typedef struct _cairo_hash_table cairo_hash_table_t;
+
+/**
+ * cairo_hash_entry_t:
+ *
+ * A #cairo_hash_entry_t contains both a key and a value for
+ * cairo_hash_table_t. User-derived types for cairo_hash_entry_t must
+ * be type-compatible with this structure (eg. they must have an
+ * unsigned long as the first parameter. The easiest way to get this
+ * is to use:
+ *
+ * typedef _my_entry {
+ * cairo_hash_entry_t base;
+ * ... Remainder of key and value fields here ..
+ * } my_entry_t;
+ *
+ * which then allows a pointer to my_entry_t to be passed to any of
+ * the cairo_hash_table functions as follows without requiring a cast:
+ *
+ * _cairo_hash_table_insert (hash_table, &my_entry->base);
+ *
+ * IMPORTANT: The caller is reponsible for initializing
+ * my_entry->base.hash with a hash code derived from the key. The
+ * essential property of the hash code is that keys_equal must never
+ * return TRUE for two keys that have different hashes. The best hash
+ * code will reduce the frequency of two keys with the same code for
+ * which keys_equal returns FALSE.
+ *
+ * Which parts of the entry make up the "key" and which part make up
+ * the value are entirely up to the caller, (as determined by the
+ * computation going into base.hash as well as the keys_equal
+ * function). A few of the cairo_hash_table functions accept an entry
+ * which will be used exclusively as a "key", (indicated by a
+ * parameter name of key). In these cases, the value-related fields of
+ * the entry need not be initialized if so desired.
+ **/
+typedef struct _cairo_hash_entry {
+ unsigned long hash;
+} cairo_hash_entry_t;
+
typedef cairo_bool_t
(*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);
typedef void
(*cairo_hash_callback_func_t) (void *entry,
--- a/gfx/cairo/cairo/src/cairo-hash.c
+++ b/gfx/cairo/cairo/src/cairo-hash.c
@@ -110,17 +110,17 @@ static const cairo_hash_table_arrangemen
{ 8388608, 18455029, 18455027 },
{ 16777216, 36911011, 36911009 },
{ 33554432, 73819861, 73819859 },
{ 67108864, 147639589, 147639587 },
{ 134217728, 295279081, 295279079 },
{ 268435456, 590559793, 590559791 }
};
-#define NUM_HASH_TABLE_ARRANGEMENTS ARRAY_LENGTH (hash_table_arrangements)
+#define NUM_HASH_TABLE_ARRANGEMENTS ((int)(sizeof(hash_table_arrangements)/sizeof(hash_table_arrangements[0])))
struct _cairo_hash_table {
cairo_hash_keys_equal_func_t keys_equal;
const cairo_hash_table_arrangement_t *arrangement;
cairo_hash_entry_t **entries;
unsigned long live_entries;
@@ -476,22 +476,18 @@ cairo_status_t
/* User is being bad, let's crash. */
ASSERT_NOT_REACHED;
}
*entry = key_and_value;
hash_table->live_entries++;
status = _cairo_hash_table_resize (hash_table);
- if (status) {
- /* abort the insert... */
- *entry = DEAD_ENTRY;
- hash_table->live_entries--;
+ if (status)
return status;
- }
return CAIRO_STATUS_SUCCESS;
}
/**
* _cairo_hash_table_remove:
* @hash_table: a hash table
* @key: key of entry to be removed
@@ -560,14 +556,11 @@ void
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) {
- /* Should we fail to shrink the hash table, it is left unaltered,
- * and we don't need to propagate the error status. */
+ if (--hash_table->iterating == 0)
_cairo_hash_table_resize (hash_table);
- }
}
--- a/gfx/cairo/cairo/src/cairo-hull.c
+++ b/gfx/cairo/cairo/src/cairo-hull.c
@@ -57,17 +57,17 @@ static cairo_hull_t *
if (p->y < extremum->y || (p->y == extremum->y && p->x < extremum->x))
extremum = p;
}
/* Put the extremal point at the beginning of the array */
tmp = *extremum;
*extremum = vertices[0].point;
vertices[0].point = tmp;
- hull = _cairo_malloc_ab (num_vertices, sizeof (cairo_hull_t));
+ hull = malloc (num_vertices * sizeof (cairo_hull_t));
if (hull == NULL)
return NULL;
for (i = 0; i < num_vertices; i++) {
hull[i].point = vertices[i].point;
_cairo_slope_init (&hull[i].slope, &hull[0].point, &hull[i].point);
/* give each point a unique id for later comparison */
--- a/gfx/cairo/cairo/src/cairo-image-surface.c
+++ b/gfx/cairo/cairo/src/cairo-image-surface.c
@@ -1,9 +1,8 @@
-/* -*- Mode: c; tab-width: 8; c-basic-offset: 4; indent-tabs-mode: t; -*- */
/* cairo - a vector graphics library with display and print output
*
* Copyright © 2003 University of Southern California
*
* 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
@@ -32,17 +31,17 @@
* California.
*
* Contributor(s):
* Carl D. Worth <cworth@cworth.org>
*/
#include "cairoint.h"
-static const cairo_image_surface_t _cairo_image_surface_nil_invalid_format = {
+const cairo_image_surface_t _cairo_image_surface_nil_invalid_format = {
{
&cairo_image_surface_backend, /* backend */
CAIRO_SURFACE_TYPE_IMAGE,
CAIRO_CONTENT_COLOR,
CAIRO_REF_COUNT_INVALID, /* ref_count */
CAIRO_STATUS_INVALID_FORMAT, /* status */
FALSE, /* finished */
{ 0, /* size */
@@ -78,16 +77,33 @@ static const cairo_image_surface_t _cair
0, /* width */
0, /* height */
0, /* stride */
0, /* depth */
NULL /* pixman_image */
};
+static int
+_cairo_format_bpp (cairo_format_t format)
+{
+ switch (format) {
+ case CAIRO_FORMAT_A1:
+ return 1;
+ case CAIRO_FORMAT_A8:
+ return 8;
+ case CAIRO_FORMAT_RGB24:
+ case CAIRO_FORMAT_ARGB32:
+ return 32;
+ }
+
+ ASSERT_NOT_REACHED;
+ return 32;
+}
+
cairo_surface_t *
_cairo_image_surface_create_for_pixman_image (pixman_image_t *pixman_image,
cairo_format_t format)
{
cairo_image_surface_t *surface;
surface = malloc (sizeof (cairo_image_surface_t));
if (surface == NULL) {
@@ -108,105 +124,150 @@ cairo_surface_t *
surface->width = pixman_image_get_width (pixman_image);
surface->height = pixman_image_get_height (pixman_image);
surface->stride = pixman_image_get_stride (pixman_image);
surface->depth = pixman_image_get_depth (pixman_image);
return &surface->base;
}
-static cairo_bool_t
-_CAIRO_MASK_FORMAT (cairo_format_masks_t *masks, cairo_format_t *format)
+/* Try to recover a cairo_format_t from a pixman_format
+ * by looking at the bpp and masks values. */
+static cairo_format_t
+_cairo_format_from_pixman_format (pixman_format_t *pixman_format)
{
- /* XXX: many formats are simply not supported by pixman, so this function
- * converts the masks into something we know will be supported.
- */
- switch (masks->bpp) {
+ unsigned int bpp, am, rm, gm, bm;
+
+ pixman_format_get_masks (pixman_format, &bpp, &am, &rm, &gm, &bm);
+
+ /* See definition of cairo_internal_format_t for an explanation of
+ * the CAIRO_INTERNAL_FORMAT values used here. */
+ switch (bpp) {
case 32:
- if (masks->alpha_mask == 0xff000000 &&
- masks->red_mask == 0x00ff0000 &&
- masks->green_mask == 0x0000ff00 &&
- masks->blue_mask == 0x000000ff)
- {
- *format = CAIRO_FORMAT_ARGB32;
- return TRUE;
- }
- if (masks->alpha_mask == 0x00000000 &&
- masks->red_mask == 0x00ff0000 &&
- masks->green_mask == 0x0000ff00 &&
- masks->blue_mask == 0x000000ff)
- {
- *format = CAIRO_FORMAT_RGB24;
- return TRUE;
+ if (am == 0xff000000) {
+ if (rm == 0x00ff0000 &&
+ gm == 0x0000ff00 &&
+ bm == 0x000000ff)
+ return CAIRO_FORMAT_ARGB32;
+ if (rm == 0x000000ff &&
+ gm == 0x0000ff00 &&
+ bm == 0x00ff0000)
+ return CAIRO_INTERNAL_FORMAT_ABGR32;
+ } else if (am == 0x0) {
+ if (rm == 0x00ff0000 &&
+ gm == 0x0000ff00 &&
+ bm == 0x000000ff)
+ return CAIRO_FORMAT_RGB24;
+ if (rm == 0x000000ff &&
+ gm == 0x0000ff00 &&
+ bm == 0x00ff0000)
+ return CAIRO_INTERNAL_FORMAT_BGR24;
}
break;
+ case 16:
+ if (am == 0x0 &&
+ rm == 0xf800 &&
+ gm == 0x07e0 &&
+ bm == 0x001f)
+ return CAIRO_FORMAT_RGB16_565;
+ break;
case 8:
- if (masks->alpha_mask == 0xff)
- {
- *format = CAIRO_FORMAT_A8;
- return TRUE;
- }
+ if (am == 0xff &&
+ rm == 0x0 &&
+ gm == 0x0 &&
+ bm == 0x0)
+ return CAIRO_FORMAT_A8;
break;
case 1:
- if (masks->alpha_mask == 0x1)
- {
- *format = CAIRO_FORMAT_A1;
- return TRUE;
- }
+ if (am == 0x1 &&
+ rm == 0x0 &&
+ gm == 0x0 &&
+ bm == 0x0)
+ return CAIRO_FORMAT_A1;
break;
}
- return FALSE;
+
+ fprintf (stderr,
+ "Error: Cairo " PACKAGE_VERSION " does not yet support the requested image format:\n"
+ "\tDepth: %d\n"
+ "\tAlpha mask: 0x%08x\n"
+ "\tRed mask: 0x%08x\n"
+ "\tGreen mask: 0x%08x\n"
+ "\tBlue mask: 0x%08x\n"
+ "Please file an enhancement request (quoting the above) at:\n"
+ PACKAGE_BUGREPORT "\n",
+ bpp, am, rm, gm, bm);
+
+ ASSERT_NOT_REACHED;
+ return (cairo_format_t) -1;
}
/* XXX: This function really should be eliminated. We don't really
* want to advertise a cairo image surface that supports any possible
* format. A minimal step would be to replace this function with one
* that accepts a cairo_internal_format_t rather than mask values. */
cairo_surface_t *
_cairo_image_surface_create_with_masks (unsigned char *data,
- cairo_format_masks_t *masks,
+ cairo_format_masks_t *format,
int width,
int height,
int stride)
{
- cairo_format_t format;
-
- if (!_CAIRO_MASK_FORMAT (masks, &format)) {
- _cairo_error (CAIRO_STATUS_INVALID_FORMAT);
+ cairo_surface_t *surface;
+ pixman_format_t *pixman_format;
+ pixman_image_t *pixman_image;
+ cairo_format_t cairo_format;
+
+ pixman_format = pixman_format_create_masks (format->bpp,
+ format->alpha_mask,
+ format->red_mask,
+ format->green_mask,
+ format->blue_mask);
+
+ if (pixman_format == NULL) {
+ _cairo_error (CAIRO_STATUS_NO_MEMORY);
return (cairo_surface_t*) &_cairo_surface_nil;
}
- return cairo_image_surface_create_for_data (data,
- format,
- width,
- height,
- stride);
+ cairo_format = _cairo_format_from_pixman_format (pixman_format);
+
+ pixman_image = pixman_image_create_for_data ((pixman_bits_t *) data, pixman_format,
+ width, height, format->bpp, stride);
+
+ pixman_format_destroy (pixman_format);
+
+ if (pixman_image == NULL) {
+ _cairo_error (CAIRO_STATUS_NO_MEMORY);
+ return (cairo_surface_t*) &_cairo_surface_nil;
+ }
+
+ surface = _cairo_image_surface_create_for_pixman_image (pixman_image,
+ cairo_format);
+
+ return surface;
}
-static pixman_format_code_t
-_cairo_format_to_pixman_format_code (cairo_format_t format)
+static pixman_format_t *
+_create_pixman_format (cairo_format_t format)
{
- int ret = 0;
switch (format) {
case CAIRO_FORMAT_A1:
- ret = PIXMAN_a1;
+ return pixman_format_create (PIXMAN_FORMAT_NAME_A1);
break;
case CAIRO_FORMAT_A8:
- ret = PIXMAN_a8;
+ return pixman_format_create (PIXMAN_FORMAT_NAME_A8);
break;
case CAIRO_FORMAT_RGB24:
- ret = PIXMAN_x8r8g8b8;
+ return pixman_format_create (PIXMAN_FORMAT_NAME_RGB24);
break;
case CAIRO_FORMAT_ARGB32:
default:
- ret = PIXMAN_a8r8g8b8;
+ return pixman_format_create (PIXMAN_FORMAT_NAME_ARGB32);
break;
}
- assert (ret);
- return ret;
}
/**
* cairo_image_surface_create:
* @format: format of pixels in the surface to create
* @width: width of the surface, in pixels
* @height: height of the surface, in pixels
*
@@ -224,38 +285,41 @@ static pixman_format_code_t
* pointer to a "nil" surface if an error such as out of memory
* occurs. You can use cairo_surface_status() to check for this.
**/
cairo_surface_t *
cairo_image_surface_create (cairo_format_t format,
int width,
int height)
{
- cairo_surface_t *surface;
- pixman_format_code_t pixman_format;
- pixman_image_t *pixman_image;
+ cairo_surface_t *surface;
+ pixman_format_t *pixman_format;
+ pixman_image_t *pixman_image;
if (! CAIRO_FORMAT_VALID (format)) {
_cairo_error (CAIRO_STATUS_INVALID_FORMAT);
return (cairo_surface_t*) &_cairo_image_surface_nil_invalid_format;
}
- pixman_format = _cairo_format_to_pixman_format_code (format);
-
- pixman_image = pixman_image_create_bits (pixman_format, width, height,
- NULL, -1);
+ pixman_format = _create_pixman_format (format);
+ if (pixman_format == NULL) {
+ _cairo_error (CAIRO_STATUS_NO_MEMORY);
+ return (cairo_surface_t*) &_cairo_surface_nil;
+ }
+
+ pixman_image = pixman_image_create (pixman_format, width, height);
+
+ pixman_format_destroy (pixman_format);
+
if (pixman_image == NULL) {
_cairo_error (CAIRO_STATUS_NO_MEMORY);
return (cairo_surface_t*) &_cairo_surface_nil;
}
surface = _cairo_image_surface_create_for_pixman_image (pixman_image, format);
- if (cairo_surface_status (surface)) {
- pixman_image_unref (pixman_image);
- }
return surface;
}
slim_hidden_def (cairo_image_surface_create);
cairo_surface_t *
_cairo_image_surface_create_with_content (cairo_content_t content,
int width,
@@ -300,37 +364,42 @@ cairo_surface_t *
**/
cairo_surface_t *
cairo_image_surface_create_for_data (unsigned char *data,
cairo_format_t format,
int width,
int height,
int stride)
{
- cairo_surface_t *surface;
- pixman_format_code_t pixman_format;
- pixman_image_t *pixman_image;
+ cairo_surface_t *surface;
+ pixman_format_t *pixman_format;
+ pixman_image_t *pixman_image;
if (! CAIRO_FORMAT_VALID (format))
return (cairo_surface_t*) &_cairo_surface_nil;
- pixman_format = _cairo_format_to_pixman_format_code (format);
+ pixman_format = _create_pixman_format (format);
+ if (pixman_format == NULL) {
+ _cairo_error (CAIRO_STATUS_NO_MEMORY);
+ return (cairo_surface_t*) &_cairo_surface_nil;
+ }
- pixman_image = pixman_image_create_bits (pixman_format, width, height,
- (uint32_t *) data, stride);
-
+ pixman_image = pixman_image_create_for_data ((pixman_bits_t *) data, pixman_format,
+ width, height,
+ _cairo_format_bpp (format),
+ stride);
+
+ pixman_format_destroy (pixman_format);
+
if (pixman_image == NULL) {
_cairo_error (CAIRO_STATUS_NO_MEMORY);
return (cairo_surface_t*) &_cairo_surface_nil;
}
surface = _cairo_image_surface_create_for_pixman_image (pixman_image, format);
- if (cairo_surface_status (surface)) {
- pixman_image_unref (pixman_image);
- }
return surface;
}
slim_hidden_def (cairo_image_surface_create_for_data);
cairo_surface_t *
_cairo_image_surface_create_for_data_with_content (unsigned char *data,
cairo_content_t content,
@@ -493,17 +562,17 @@ cairo_content_t
* bug #7294 fixed so we can release cairo 1.2.2 . */
int f = format;
switch (f) {
case CAIRO_FORMAT_ARGB32:
case CAIRO_INTERNAL_FORMAT_ABGR32:
return CAIRO_CONTENT_COLOR_ALPHA;
case CAIRO_FORMAT_RGB24:
- case CAIRO_INTERNAL_FORMAT_RGB16_565:
+ case CAIRO_FORMAT_RGB16_565:
case CAIRO_INTERNAL_FORMAT_BGR24:
return CAIRO_CONTENT_COLOR;
case CAIRO_FORMAT_A8:
case CAIRO_FORMAT_A1:
return CAIRO_CONTENT_ALPHA;
}
ASSERT_NOT_REACHED;
@@ -523,17 +592,17 @@ static cairo_surface_t *
}
static cairo_status_t
_cairo_image_surface_finish (void *abstract_surface)
{
cairo_image_surface_t *surface = abstract_surface;
if (surface->pixman_image) {
- pixman_image_unref (surface->pixman_image);
+ pixman_image_destroy (surface->pixman_image);
surface->pixman_image = NULL;
}
if (surface->owns_data) {
free (surface->data);
surface->data = NULL;
}
@@ -561,19 +630,19 @@ static void
_cairo_image_surface_release_source_image (void *abstract_surface,
cairo_image_surface_t *image,
void *image_extra)
{
}
static cairo_status_t
_cairo_image_surface_acquire_dest_image (void *abstract_surface,
- cairo_rectangle_int_t *interest_rect,
+ cairo_rectangle_int16_t *interest_rect,
cairo_image_surface_t **image_out,
- cairo_rectangle_int_t *image_rect_out,
+ cairo_rectangle_int16_t *image_rect_out,
void **image_extra)
{
cairo_image_surface_t *surface = abstract_surface;
image_rect_out->x = 0;
image_rect_out->y = 0;
image_rect_out->width = surface->width;
image_rect_out->height = surface->height;
@@ -581,19 +650,19 @@ static cairo_status_t
*image_out = surface;
*image_extra = NULL;
return CAIRO_STATUS_SUCCESS;
}
static void
_cairo_image_surface_release_dest_image (void *abstract_surface,
- cairo_rectangle_int_t *interest_rect,
+ cairo_rectangle_int16_t *interest_rect,
cairo_image_surface_t *image,
- cairo_rectangle_int_t *image_rect,
+ cairo_rectangle_int16_t *image_rect,
void *image_extra)
{
}
static cairo_status_t
_cairo_image_surface_clone_similar (void *abstract_surface,
cairo_surface_t *src,
int src_x,
@@ -616,18 +685,17 @@ static cairo_status_t
static cairo_status_t
_cairo_image_surface_set_matrix (cairo_image_surface_t *surface,
const cairo_matrix_t *matrix)
{
pixman_transform_t pixman_transform;
_cairo_matrix_to_pixman_matrix (matrix, &pixman_transform);
- if (!pixman_image_set_transform (surface->pixman_image, &pixman_transform))
- return CAIRO_STATUS_NO_MEMORY;
+ pixman_image_set_transform (surface->pixman_image, &pixman_transform);
return CAIRO_STATUS_SUCCESS;
}
static cairo_status_t
_cairo_image_surface_set_filter (cairo_image_surface_t *surface, cairo_filter_t filter)
{
pixman_filter_t pixman_filter;
@@ -653,17 +721,17 @@ static cairo_status_t
* whatsoever, so it was really a mistake to have it in the
* API. We could fix this by officially deprecating it, or
* else inventing semantics and providing an actual
* implementation for it. */
default:
pixman_filter = PIXMAN_FILTER_BEST;
}
- pixman_image_set_filter (surface->pixman_image, pixman_filter, NULL, 0);
+ pixman_image_set_filter (surface->pixman_image, pixman_filter);
return CAIRO_STATUS_SUCCESS;
}
static cairo_int_status_t
_cairo_image_surface_set_attributes (cairo_image_surface_t *surface,
cairo_surface_attributes_t *attributes)
{
@@ -693,53 +761,53 @@ static cairo_int_status_t
return status;
}
/* XXX: I think we should fix pixman to match the names/order of the
* cairo operators, but that will likely be better done at the same
* time the X server is ported to pixman, (which will change a lot of
* things in pixman I think).
*/
-static pixman_op_t
+static pixman_operator_t
_pixman_operator (cairo_operator_t op)
{
switch (op) {
case CAIRO_OPERATOR_CLEAR:
- return PIXMAN_OP_CLEAR;
+ return PIXMAN_OPERATOR_CLEAR;
case CAIRO_OPERATOR_SOURCE:
- return PIXMAN_OP_SRC;
+ return PIXMAN_OPERATOR_SRC;
case CAIRO_OPERATOR_OVER:
- return PIXMAN_OP_OVER;
+ return PIXMAN_OPERATOR_OVER;
case CAIRO_OPERATOR_IN:
- return PIXMAN_OP_IN;
+ return PIXMAN_OPERATOR_IN;
case CAIRO_OPERATOR_OUT:
- return PIXMAN_OP_OUT;
+ return PIXMAN_OPERATOR_OUT;
case CAIRO_OPERATOR_ATOP:
- return PIXMAN_OP_ATOP;
+ return PIXMAN_OPERATOR_ATOP;
case CAIRO_OPERATOR_DEST:
- return PIXMAN_OP_DST;
+ return PIXMAN_OPERATOR_DST;
case CAIRO_OPERATOR_DEST_OVER:
- return PIXMAN_OP_OVER_REVERSE;
+ return PIXMAN_OPERATOR_OVER_REVERSE;
case CAIRO_OPERATOR_DEST_IN:
- return PIXMAN_OP_IN_REVERSE;
+ return PIXMAN_OPERATOR_IN_REVERSE;
case CAIRO_OPERATOR_DEST_OUT:
- return PIXMAN_OP_OUT_REVERSE;
+ return PIXMAN_OPERATOR_OUT_REVERSE;
case CAIRO_OPERATOR_DEST_ATOP:
- return PIXMAN_OP_ATOP_REVERSE;
+ return PIXMAN_OPERATOR_ATOP_REVERSE;
case CAIRO_OPERATOR_XOR:
- return PIXMAN_OP_XOR;
+ return PIXMAN_OPERATOR_XOR;
case CAIRO_OPERATOR_ADD:
- return PIXMAN_OP_ADD;
+ return PIXMAN_OPERATOR_ADD;
case CAIRO_OPERATOR_SATURATE:
- return PIXMAN_OP_SATURATE;
+ return PIXMAN_OPERATOR_SATURATE;
default:
- return PIXMAN_OP_OVER;
+ return PIXMAN_OPERATOR_OVER;
}
}
static cairo_int_status_t
_cairo_image_surface_composite (cairo_operator_t op,
cairo_pattern_t *src_pattern,
cairo_pattern_t *mask_pattern,
void *abstract_dst,
@@ -774,38 +842,38 @@ static cairo_int_status_t
goto CLEANUP_SURFACES;
if (mask)
{
status = _cairo_image_surface_set_attributes (mask, &mask_attr);
if (status)
goto CLEANUP_SURFACES;
- pixman_image_composite (_pixman_operator (op),
- src->pixman_image,
- mask->pixman_image,
- dst->pixman_image,
- src_x + src_attr.x_offset,
- src_y + src_attr.y_offset,
- mask_x + mask_attr.x_offset,
- mask_y + mask_attr.y_offset,
- dst_x, dst_y,
- width, height);
+ pixman_composite (_pixman_operator (op),
+ src->pixman_image,
+ mask->pixman_image,
+ dst->pixman_image,
+ src_x + src_attr.x_offset,
+ src_y + src_attr.y_offset,
+ mask_x + mask_attr.x_offset,
+ mask_y + mask_attr.y_offset,
+ dst_x, dst_y,
+ width, height);
}
else
{
- pixman_image_composite (_pixman_operator (op),
- src->pixman_image,
- NULL,
- dst->pixman_image,
- src_x + src_attr.x_offset,
- src_y + src_attr.y_offset,
- 0, 0,
- dst_x, dst_y,
- width, height);
+ pixman_composite (_pixman_operator (op),
+ src->pixman_image,
+ NULL,
+ dst->pixman_image,
+ src_x + src_attr.x_offset,
+ src_y + src_attr.y_offset,
+ 0, 0,
+ dst_x, dst_y,
+ width, height);
}
if (!_cairo_operator_bounded_by_source (op))
status = _cairo_surface_composite_fixup_unbounded (&dst->base,
&src_attr, src->width, src->height,
mask ? &mask_attr : NULL,
mask ? mask->width : 0,
mask ? mask->height : 0,
@@ -817,70 +885,39 @@ static cairo_int_status_t
if (mask)
_cairo_pattern_release_surface (mask_pattern, &mask->base, &mask_attr);
_cairo_pattern_release_surface (src_pattern, &src->base, &src_attr);
return status;
}
-#define STACK_RECTS_LEN (CAIRO_STACK_BUFFER_SIZE / sizeof(pixman_rectangle16_t))
-
static cairo_int_status_t
_cairo_image_surface_fill_rectangles (void *abstract_surface,
cairo_operator_t op,
const cairo_color_t *color,
- cairo_rectangle_int_t *rects,
+ cairo_rectangle_int16_t *rects,
int num_rects)
{
cairo_image_surface_t *surface = abstract_surface;
pixman_color_t pixman_color;
- pixman_rectangle16_t stack_rects[STACK_RECTS_LEN];
- pixman_rectangle16_t *pixman_rects = stack_rects;
- int i;
-
- cairo_int_status_t status = CAIRO_STATUS_SUCCESS;
pixman_color.red = color->red_short;
pixman_color.green = color->green_short;
pixman_color.blue = color->blue_short;
pixman_color.alpha = color->alpha_short;
- if (num_rects > ARRAY_LENGTH(stack_rects)) {
- pixman_rects = _cairo_malloc_ab (num_rects, sizeof(pixman_rectangle16_t));
- if (pixman_rects == NULL)
- return CAIRO_STATUS_NO_MEMORY;
- }
-
- for (i = 0; i < num_rects; i++) {
- pixman_rects[i].x = rects[i].x;
- pixman_rects[i].y = rects[i].y;
- pixman_rects[i].width = rects[i].width;
- pixman_rects[i].height = rects[i].height;
- }
+ /* XXX: The pixman_rectangle_t cast is evil... it needs to go away somehow. */
+ pixman_fill_rectangles (_pixman_operator(op), surface->pixman_image,
+ &pixman_color, (pixman_rectangle_t *) rects, num_rects);
- /* XXX: pixman_fill_rectangles() should be implemented */
- if (!pixman_image_fill_rectangles (_pixman_operator(op),
- surface->pixman_image,
- &pixman_color,
- num_rects,
- pixman_rects))
- status = CAIRO_STATUS_NO_MEMORY;
-
- if (pixman_rects != stack_rects)
- free (pixman_rects);
-
- return status;
+ return CAIRO_STATUS_SUCCESS;
}
-#undef STACK_RECTS_LEN
-
-#define STACK_TRAPS_LEN ((int) (CAIRO_STACK_BUFFER_SIZE / sizeof(pixman_trapezoid_t)))
-
static cairo_int_status_t
_cairo_image_surface_composite_trapezoids (cairo_operator_t op,
cairo_pattern_t *pattern,
void *abstract_dst,
cairo_antialias_t antialias,
int src_x,
int src_y,
int dst_x,
@@ -890,43 +927,20 @@ static cairo_int_status_t
cairo_trapezoid_t *traps,
int num_traps)
{
cairo_surface_attributes_t attributes;
cairo_image_surface_t *dst = abstract_dst;
cairo_image_surface_t *src;
cairo_int_status_t status;
pixman_image_t *mask;
- pixman_format_code_t format;
- uint32_t *mask_data;
- pixman_trapezoid_t stack_traps[STACK_TRAPS_LEN];
- pixman_trapezoid_t *pixman_traps = stack_traps;
- int mask_stride;
- int mask_bpp;
- int ret, i;
-
- /* Convert traps to pixman traps */
- if (num_traps > ARRAY_LENGTH(stack_traps)) {
- pixman_traps = _cairo_malloc_ab (num_traps, sizeof(pixman_trapezoid_t));
- if (pixman_traps == NULL)
- return CAIRO_STATUS_NO_MEMORY;
- }
-
- for (i = 0; i < num_traps; i++) {
- pixman_traps[i].top = _cairo_fixed_to_16_16 (traps[i].top);
- pixman_traps[i].bottom = _cairo_fixed_to_16_16 (traps[i].bottom);
- pixman_traps[i].left.p1.x = _cairo_fixed_to_16_16 (traps[i].left.p1.x);
- pixman_traps[i].left.p1.y = _cairo_fixed_to_16_16 (traps[i].left.p1.y);
- pixman_traps[i].left.p2.x = _cairo_fixed_to_16_16 (traps[i].left.p2.x);
- pixman_traps[i].left.p2.y = _cairo_fixed_to_16_16 (traps[i].left.p2.y);
- pixman_traps[i].right.p1.x = _cairo_fixed_to_16_16 (traps[i].right.p1.x);
- pixman_traps[i].right.p1.y = _cairo_fixed_to_16_16 (traps[i].right.p1.y);
- pixman_traps[i].right.p2.x = _cairo_fixed_to_16_16 (traps[i].right.p2.x);
- pixman_traps[i].right.p2.y = _cairo_fixed_to_16_16 (traps[i].right.p2.y);
- }
+ pixman_format_t *format;
+ pixman_bits_t *mask_data;
+ int mask_stride;
+ int mask_bpp;
/* Special case adding trapezoids onto a mask surface; we want to avoid
* creating an intermediate temporary mask unecessarily.
*
* We make the assumption here that the portion of the trapezoids
* contained within the surface is bounded by [dst_x,dst_y,width,height];
* the Cairo core code passes bounds based on the trapezoid extents.
*
@@ -938,153 +952,127 @@ static cairo_int_status_t
*/
if (op == CAIRO_OPERATOR_ADD &&
_cairo_pattern_is_opaque_solid (pattern) &&
dst->base.content == CAIRO_CONTENT_ALPHA &&
!dst->has_clip &&
antialias != CAIRO_ANTIALIAS_NONE)
{
pixman_add_trapezoids (dst->pixman_image, 0, 0,
- num_traps, pixman_traps);
- status = CAIRO_STATUS_SUCCESS;
- goto finish;
+ (pixman_trapezoid_t *) traps, num_traps);
+ return CAIRO_STATUS_SUCCESS;
}
status = _cairo_pattern_acquire_surface (pattern, &dst->base,
src_x, src_y, width, height,
(cairo_surface_t **) &src,
&attributes);
if (status)
- goto finish;
+ return status;
status = _cairo_image_surface_set_attributes (src, &attributes);
if (status)
goto CLEANUP_SOURCE;
switch (antialias) {
case CAIRO_ANTIALIAS_NONE:
- format = PIXMAN_a1;
- ret = 1;
- assert (ret);
- mask_stride = ((width + 31) / 8) & ~0x03;
+ format = pixman_format_create (PIXMAN_FORMAT_NAME_A1);
+ mask_stride = (width + 31)/8;
mask_bpp = 1;
break;
case CAIRO_ANTIALIAS_GRAY:
case CAIRO_ANTIALIAS_SUBPIXEL:
case CAIRO_ANTIALIAS_DEFAULT:
default:
- format = PIXMAN_a8;
- ret = 1;
- assert (ret);
+ format = pixman_format_create (PIXMAN_FORMAT_NAME_A8);
mask_stride = (width + 3) & ~3;
mask_bpp = 8;
break;
}
-
- /* The image must be initially transparent */
- mask_data = calloc (1, mask_stride * height);
- if (mask_data == NULL) {
+ if (!format) {
status = CAIRO_STATUS_NO_MEMORY;
goto CLEANUP_SOURCE;
}
- mask = pixman_image_create_bits (format, width, height,
- mask_data, mask_stride);
- if (mask == NULL) {
+ /* The image must be initially transparent */
+ mask_data = calloc (1, mask_stride * height);
+ if (!mask_data) {
+ status = CAIRO_STATUS_NO_MEMORY;
+ pixman_format_destroy (format);
+ goto CLEANUP_SOURCE;
+ }
+
+ mask = pixman_image_create_for_data (mask_data, format, width, height,
+ mask_bpp, mask_stride);
+ pixman_format_destroy (format);
+ if (!mask) {
status = CAIRO_STATUS_NO_MEMORY;
goto CLEANUP_IMAGE_DATA;
}
+ /* XXX: The pixman_trapezoid_t cast is evil and needs to go away
+ * somehow. */
pixman_add_trapezoids (mask, - dst_x, - dst_y,
- num_traps, pixman_traps);
+ (pixman_trapezoid_t *) traps, num_traps);
- pixman_image_composite (_pixman_operator (op),
- src->pixman_image,
- mask,
- dst->pixman_image,
- src_x + attributes.x_offset,
- src_y + attributes.y_offset,
- 0, 0,
- dst_x, dst_y,
- width, height);
+ pixman_composite (_pixman_operator (op),
+ src->pixman_image,
+ mask,
+ dst->pixman_image,
+ src_x + attributes.x_offset,
+ src_y + attributes.y_offset,
+ 0, 0,
+ dst_x, dst_y,
+ width, height);
if (!_cairo_operator_bounded_by_mask (op))
status = _cairo_surface_composite_shape_fixup_unbounded (&dst->base,
&attributes, src->width, src->height,
width, height,
src_x, src_y,
0, 0,
dst_x, dst_y, width, height);
- pixman_image_unref (mask);
+ pixman_image_destroy (mask);
CLEANUP_IMAGE_DATA:
free (mask_data);
CLEANUP_SOURCE:
_cairo_pattern_release_surface (pattern, &src->base, &attributes);
- finish:
- if (pixman_traps != stack_traps)
- free (pixman_traps);
-
return status;
}
-#undef STACK_TRAPS_LEN
-
cairo_int_status_t
_cairo_image_surface_set_clip_region (void *abstract_surface,
- cairo_region_t *region)
+ pixman_region16_t *region)
{
cairo_image_surface_t *surface = (cairo_image_surface_t *) abstract_surface;
- if (!pixman_image_set_clip_region (surface->pixman_image, ®ion->rgn))
- return CAIRO_STATUS_NO_MEMORY;
+ pixman_image_set_clip_region (surface->pixman_image, region);
surface->has_clip = region != NULL;
return CAIRO_STATUS_SUCCESS;
}
static cairo_int_status_t
_cairo_image_surface_get_extents (void *abstract_surface,
- cairo_rectangle_int_t *rectangle)
+ cairo_rectangle_int16_t *rectangle)
{
cairo_image_surface_t *surface = abstract_surface;
rectangle->x = 0;
rectangle->y = 0;
rectangle->width = surface->width;
rectangle->height = surface->height;
return CAIRO_STATUS_SUCCESS;
}
-static void
-_cairo_image_surface_get_font_options (void *abstract_surface,
- cairo_font_options_t *options)
-{
- _cairo_font_options_init_default (options);
-
- cairo_font_options_set_hint_metrics (options, CAIRO_HINT_METRICS_ON);
-}
-
-static cairo_status_t
-_cairo_image_surface_reset (void *abstract_surface)
-{
- cairo_image_surface_t *surface = abstract_surface;
- cairo_status_t status;
-
- status = _cairo_image_surface_set_clip_region (surface, NULL);
- if (status)
- return status;
-
- return CAIRO_STATUS_SUCCESS;
-}
-
/**
* _cairo_surface_is_image:
* @surface: a #cairo_surface_t
*
* Checks if a surface is an #cairo_image_surface_t
*
* Return value: TRUE if the surface is an image surface
**/
@@ -1106,32 +1094,17 @@ const cairo_surface_backend_t cairo_imag
_cairo_image_surface_composite,
_cairo_image_surface_fill_rectangles,
_cairo_image_surface_composite_trapezoids,
NULL, /* copy_page */
NULL, /* show_page */
_cairo_image_surface_set_clip_region,
NULL, /* intersect_clip_path */
_cairo_image_surface_get_extents,
- NULL, /* old_show_glyphs */
- _cairo_image_surface_get_font_options,
- NULL, /* flush */
- NULL, /* mark_dirty_rectangle */
- NULL, //* font_fini */
- NULL, //* glyph_fini */
-
- NULL, /* paint */
- NULL, /* mask */
- NULL, /* stroke */
- NULL, /* fill */
- NULL, /* show_glyphs */
- NULL, /* snapshot */
- NULL, /* is_similar */
-
- _cairo_image_surface_reset
+ NULL /* old_show_glyphs */
};
/* A convenience function for when one needs to coerce an image
* surface to an alternate format. */
cairo_image_surface_t *
_cairo_image_surface_clone (cairo_image_surface_t *surface,
cairo_format_t format)
{
--- a/gfx/cairo/cairo/src/cairo-matrix.c
+++ b/gfx/cairo/cairo/src/cairo-matrix.c
@@ -30,16 +30,17 @@
* The Initial Developer of the Original Code is University of Southern
* California.
*
* Contributor(s):
* Carl D. Worth <cworth@cworth.org>
*/
#define _GNU_SOURCE
+#include <stdlib.h>
#include "cairoint.h"
static void
_cairo_matrix_scalar_multiply (cairo_matrix_t *matrix, double scalar);
static void
_cairo_matrix_compute_adjoint (cairo_matrix_t *matrix);
@@ -192,17 +193,17 @@ cairo_matrix_init_scale (cairo_matrix_t
slim_hidden_def(cairo_matrix_init_scale);
/**
* cairo_matrix_scale:
* @matrix: a #cairo_matrix_t
* @sx: scale factor in the X direction
* @sy: scale factor in the Y direction
*
- * Applies scaling by @sx, @sy to the transformation in @matrix. The
+ * Applies scaling by @tx, @ty to the transformation in @matrix. The
* effect of the new transformation is to first scale the coordinates
* by @sx and @sy, then apply the original transformation to the coordinates.
**/
void
cairo_matrix_scale (cairo_matrix_t *matrix, double sx, double sy)
{
cairo_matrix_t tmp;
@@ -470,20 +471,16 @@ cairo_matrix_invert (cairo_matrix_t *mat
/* inv (A) = 1/det (A) * adj (A) */
double det;
_cairo_matrix_compute_determinant (matrix, &det);
if (det == 0)
return CAIRO_STATUS_INVALID_MATRIX;
- /* this weird construct is for detecting NaNs */
- if (! (det * det > 0.))
- return CAIRO_STATUS_INVALID_MATRIX;
-
_cairo_matrix_compute_adjoint (matrix);
_cairo_matrix_scalar_multiply (matrix, 1 / det);
return CAIRO_STATUS_SUCCESS;
}
slim_hidden_def(cairo_matrix_invert);
void
@@ -494,17 +491,17 @@ void
a = matrix->xx; b = matrix->yx;
c = matrix->xy; d = matrix->yy;
*det = a*d - b*c;
}
/* Compute the amount that each basis vector is scaled by. */
-void
+cairo_status_t
_cairo_matrix_compute_scale_factors (const cairo_matrix_t *matrix,
double *sx, double *sy, int x_major)
{
double det;
_cairo_matrix_compute_determinant (matrix, &det);
if (det == 0)
@@ -534,16 +531,18 @@ void
*sy = minor;
}
else
{
*sx = minor;
*sy = major;
}
}
+
+ return CAIRO_STATUS_SUCCESS;
}
cairo_bool_t
_cairo_matrix_is_identity (const cairo_matrix_t *matrix)
{
return (matrix->xx == 1.0 && matrix->yx == 0.0 &&
matrix->xy == 0.0 && matrix->yy == 1.0 &&
matrix->x0 == 0.0 && matrix->y0 == 0.0);
@@ -731,21 +730,21 @@ void
{ 0, 1 << 16, 0},
{ 0, 0, 1 << 16}
}};
if (_cairo_matrix_is_identity (matrix)) {
*pixman_transform = pixman_identity_transform;
}
else {
- pixman_transform->matrix[0][0] = _cairo_fixed_16_16_from_double (matrix->xx);
- pixman_transform->matrix[0][1] = _cairo_fixed_16_16_from_double (matrix->xy);
- pixman_transform->matrix[0][2] = _cairo_fixed_16_16_from_double (matrix->x0);
+ pixman_transform->matrix[0][0] = _cairo_fixed_from_double (matrix->xx);
+ pixman_transform->matrix[0][1] = _cairo_fixed_from_double (matrix->xy);
+ pixman_transform->matrix[0][2] = _cairo_fixed_from_double (matrix->x0);
- pixman_transform->matrix[1][0] = _cairo_fixed_16_16_from_double (matrix->yx);
- pixman_transform->matrix[1][1] = _cairo_fixed_16_16_from_double (matrix->yy);
- pixman_transform->matrix[1][2] = _cairo_fixed_16_16_from_double (matrix->y0);
+ pixman_transform->matrix[1][0] = _cairo_fixed_from_double (matrix->yx);
+ pixman_transform->matrix[1][1] = _cairo_fixed_from_double (matrix->yy);
+ pixman_transform->matrix[1][2] = _cairo_fixed_from_double (matrix->y0);
pixman_transform->matrix[2][0] = 0;
pixman_transform->matrix[2][1] = 0;
pixman_transform->matrix[2][2] = 1 << 16;
}
}
--- a/gfx/cairo/cairo/src/cairo-meta-surface.c
+++ b/gfx/cairo/cairo/src/cairo-meta-surface.c
@@ -207,21 +207,17 @@ static void
{
cairo_surface_destroy (&image->base);
}
static cairo_status_t
_init_pattern_with_snapshot (cairo_pattern_t *pattern,
const cairo_pattern_t *other)
{
- cairo_status_t status;
-
- status = _cairo_pattern_init_copy (pattern, other);
- if (status)
- return status;
+ _cairo_pattern_init_copy (pattern, other);
if (pattern->type == CAIRO_PATTERN_TYPE_SURFACE) {
cairo_surface_pattern_t *surface_pattern =
(cairo_surface_pattern_t *) pattern;
cairo_surface_t *surface = surface_pattern->surface;
surface_pattern->surface = _cairo_surface_snapshot (surface);
@@ -434,17 +430,17 @@ static cairo_int_status_t
command->type = CAIRO_COMMAND_SHOW_GLYPHS;
command->op = op;
status = _init_pattern_with_snapshot (&command->source.base, source);
if (status)
goto CLEANUP_COMMAND;
- command->glyphs = _cairo_malloc_ab (num_glyphs, sizeof (cairo_glyph_t));
+ command->glyphs = malloc (sizeof (cairo_glyph_t) * num_glyphs);
if (command->glyphs == NULL) {
status = CAIRO_STATUS_NO_MEMORY;
goto CLEANUP_SOURCE;
}
memcpy (command->glyphs, glyphs, sizeof (cairo_glyph_t) * num_glyphs);
command->num_glyphs = num_glyphs;
@@ -551,17 +547,17 @@ static cairo_int_status_t
}
/* Currently, we're using as the "size" of a meta surface the largest
* surface size against which the meta-surface is expected to be
* replayed, (as passed in to _cairo_meta_surface_create).
*/
static cairo_int_status_t
_cairo_meta_surface_get_extents (void *abstract_surface,
- cairo_rectangle_int_t *rectangle)
+ cairo_rectangle_int16_t *rectangle)
{
cairo_meta_surface_t *surface = abstract_surface;
rectangle->x = 0;
rectangle->y = 0;
rectangle->width = surface->width_pixels;
rectangle->height = surface->height_pixels;
@@ -647,19 +643,16 @@ cairo_status_t
cairo_command_t *command, **elements;
int i, num_elements;
cairo_int_status_t status;
cairo_clip_t clip;
cairo_bool_t has_device_transform = _cairo_surface_has_device_transform (target);
cairo_matrix_t *device_transform = &target->device_transform;
cairo_path_fixed_t path_copy, *dev_path;
- if (surface->status)
- return surface->status;
-
meta = (cairo_meta_surface_t *) surface;
status = CAIRO_STATUS_SUCCESS;
_cairo_clip_init (&clip, target);
num_elements = meta->commands.num_elements;
elements = _cairo_array_index (&meta->commands, 0);
for (i = meta->replay_start_idx; i < num_elements; i++) {
@@ -670,19 +663,17 @@ cairo_status_t
if (command->type != CAIRO_COMMAND_INTERSECT_CLIP_PATH) {
status = _cairo_surface_set_clip (target, &clip);
if (status)
break;
}
dev_path = _cairo_command_get_path (command);
if (dev_path && has_device_transform) {
- status = _cairo_path_fixed_init_copy (&path_copy, dev_path);
- if (status)
- break;
+ _cairo_path_fixed_init_copy (&path_copy, dev_path);
_cairo_path_fixed_device_transform (&path_copy, device_transform);
dev_path = &path_copy;
}
switch (command->type) {
case CAIRO_COMMAND_PAINT:
status = _cairo_surface_paint (target,
command->paint.op,
@@ -730,17 +721,17 @@ cairo_status_t
break;
case CAIRO_COMMAND_SHOW_GLYPHS:
{
cairo_glyph_t *glyphs = command->show_glyphs.glyphs;
cairo_glyph_t *dev_glyphs = glyphs;
int i, num_glyphs = command->show_glyphs.num_glyphs;
if (has_device_transform) {
- dev_glyphs = _cairo_malloc_ab (num_glyphs, sizeof (cairo_glyph_t));
+ dev_glyphs = malloc (sizeof (cairo_glyph_t) * num_glyphs);
if (dev_glyphs == NULL) {
status = CAIRO_STATUS_NO_MEMORY;
break;
}
for (i = 0; i < num_glyphs; i++) {
dev_glyphs[i] = glyphs[i];
cairo_matrix_transform_point (device_transform,
&dev_glyphs[i].x,
@@ -758,17 +749,17 @@ cairo_status_t
free (dev_glyphs);
break;
}
case CAIRO_COMMAND_INTERSECT_CLIP_PATH:
/* XXX Meta surface clipping is broken and requires some
* cairo-gstate.c rewriting. Work around it for now. */
if (dev_path == NULL)
- _cairo_clip_reset (&clip);
+ status = _cairo_clip_reset (&clip);
else
status = _cairo_clip_clip (&clip, dev_path,
command->intersect_clip_path.fill_rule,
command->intersect_clip_path.tolerance,
command->intersect_clip_path.antialias,
target);
break;
default:
@@ -777,12 +768,12 @@ cairo_status_t
if (dev_path == &path_copy)
_cairo_path_fixed_fini (&path_copy);
if (status)
break;
}
- _cairo_clip_reset (&clip);
+ _cairo_clip_fini (&clip);
return status;
}
--- a/gfx/cairo/cairo/src/cairo-os2-surface.c
+++ b/gfx/cairo/cairo/src/cairo-os2-surface.c
@@ -30,50 +30,57 @@
*
* The Initial Developer of the Original Code is
* Doodle <doodle@scenergy.dfmk.hu>
*
* Contributor(s):
* Peter Weilbacher <mozilla@Weilbacher.org>
*/
-#include "cairoint.h"
-
-#include "cairo-os2-private.h"
-
-#include <fontconfig/fontconfig.h>
-
+#include <stdlib.h>
+#include <stdio.h>
#include <float.h>
#ifdef BUILD_CAIRO_DLL
# define INCL_WIN
# define INCL_GPI
# define INCL_DOS
# define INCL_DOSERRORS
# include <os2emx.h>
# include "cairo-os2.h"
# ifndef __WATCOMC__
# include <emx/startup.h>
# endif
#endif
+#include "cairoint.h"
+#include "cairo-os2-private.h"
+#include "fontconfig/fontconfig.h"
/*
* Here comes the extra API for the OS/2 platform. Currently it consists
* of two extra functions, the cairo_os2_init () and the
* cairo_os2_fini (). Both of them are called automatically if
* Cairo is compiled to be a DLL file, but you have to call them before
* using the Cairo API if you link to Cairo statically!
*
* You'll also find the code in here which deals with DLL initialization
* and termination, if the code is built to be a DLL.
* (if BUILD_CAIRO_DLL is defined)
*/
/* Initialization counter: */
static int cairo_os2_initialization_count = 0;
+/* The mutex semaphores Cairo uses all around: */
+HMTX _cairo_scaled_font_map_mutex = 0;
+HMTX _global_image_glyph_cache_mutex = 0;
+HMTX _cairo_font_face_mutex = 0;
+#ifdef CAIRO_HAS_FT_FONT
+HMTX _cairo_ft_unscaled_font_map_mutex = 0;
+#endif
+
static void inline
DisableFPUException (void)
{
unsigned short usCW;
/* Some OS/2 PM API calls modify the FPU Control Word,
* but forget to restore it.
*
@@ -91,20 +98,30 @@ cairo_os2_init (void)
{
/* This may initialize some stuffs, like create mutex semaphores etc.. */
cairo_os2_initialization_count++;
if (cairo_os2_initialization_count > 1) return;
DisableFPUException ();
+ /* Create the mutex semaphores we'll use! */
+
+ /* cairo-font.c: */
+ DosCreateMutexSem (NULL, &_cairo_scaled_font_map_mutex, 0, FALSE);
+ DosCreateMutexSem (NULL, &_global_image_glyph_cache_mutex, 0, FALSE);
+ DosCreateMutexSem (NULL, &_cairo_font_face_mutex, 0, FALSE);
+
+#ifdef CAIRO_HAS_FT_FONT
+ /* cairo-ft-font.c: */
+ DosCreateMutexSem (NULL, &_cairo_ft_unscaled_font_map_mutex, 0, FALSE);
+#endif
+
/* Initialize FontConfig */
FcInit ();
-
- CAIRO_MUTEX_INITIALIZE ();
}
cairo_public void
cairo_os2_fini (void)
{
/* This has to uninitialize some stuffs, like destroy mutex semaphores etc.. */
if (cairo_os2_initialization_count <= 0) return;
@@ -115,17 +132,38 @@ cairo_os2_fini (void)
/* Free allocated memories! */
/* (Check cairo_debug_reset_static_date () for an example of this!) */
_cairo_font_reset_static_data ();
#ifdef CAIRO_HAS_FT_FONT
_cairo_ft_font_reset_static_data ();
#endif
- CAIRO_MUTEX_FINALIZE ();
+ /* Destroy the mutex semaphores we've created! */
+ /* cairo-font.c: */
+ if (_cairo_scaled_font_map_mutex) {
+ DosCloseMutexSem (_cairo_scaled_font_map_mutex);
+ _cairo_scaled_font_map_mutex = 0;
+ }
+ if (_global_image_glyph_cache_mutex) {
+ DosCloseMutexSem (_global_image_glyph_cache_mutex);
+ _global_image_glyph_cache_mutex = 0;
+ }
+ if (_cairo_font_face_mutex) {
+ DosCloseMutexSem (_cairo_font_face_mutex);
+ _cairo_font_face_mutex = 0;
+ }
+
+#ifdef CAIRO_HAS_FT_FONT
+ /* cairo-ft-font.c: */
+ if (_cairo_ft_unscaled_font_map_mutex) {
+ DosCloseMutexSem (_cairo_ft_unscaled_font_map_mutex);
+ _cairo_ft_unscaled_font_map_mutex = 0;
+ }
+#endif
/* Uninitialize FontConfig */
FcFini ();
#ifdef __WATCOMC__
/* It can happen that the libraries we use have memory leaks,
* so there are still memory chunks allocated at this point.
* In these cases, Watcom might still have a bigger memory chunk,
@@ -291,19 +329,18 @@ static void
* - clean up the new buffer
*/
BITMAPINFOHEADER2 bmpheader;
unsigned char *pchPixBuf, *pchPixSource;
void *pBufStart;
ULONG ulPixels;
/* allocate temporary pixel buffer */
- pchPixBuf = (unsigned char *) _cairo_malloc_abc (surface->bitmap_info.cy,
- surface->bitmap_info.cx,
- 3);
+ pchPixBuf = (unsigned char *) malloc (3 * surface->bitmap_info.cx *
+ surface->bitmap_info.cy);
pchPixSource = surface->pixels; /* start at beginning of pixel buffer */
pBufStart = pchPixBuf; /* remember beginning of the new pixel buffer */
/* copy the first three bytes for each pixel but skip over the fourth */
for (ulPixels = 0; ulPixels < surface->bitmap_info.cx * surface->bitmap_info.cy; ulPixels++)
{
/* copy BGR from source buffer */
*pchPixBuf++ = *pchPixSource++;
@@ -512,19 +549,19 @@ static void
DosPostEventSem (local_os2_surface->hev_pixel_array_came_back);
DosReleaseMutexSem (local_os2_surface->hmtx_use_private_fields);
return;
}
static cairo_status_t
_cairo_os2_surface_acquire_dest_image (void *abstract_surface,
- cairo_rectangle_int_t *interest_rect,
+ cairo_rectangle_int16_t *interest_rect,
cairo_image_surface_t **image_out,
- cairo_rectangle_int_t *image_rect,
+ cairo_rectangle_int16_t *image_rect,
void **image_extra)
{
cairo_os2_surface_t *local_os2_surface;
local_os2_surface = (cairo_os2_surface_t *) abstract_surface;
if ((!local_os2_surface) ||
(local_os2_surface->base.backend != &cairo_os2_surface_backend))
{
@@ -547,19 +584,19 @@ static cairo_status_t
DosReleaseMutexSem (local_os2_surface->hmtx_use_private_fields);
return CAIRO_STATUS_SUCCESS;
}
static void
_cairo_os2_surface_release_dest_image (void *abstract_surface,
- cairo_rectangle_int_t *interest_rect,
+ cairo_rectangle_int16_t *interest_rect,
cairo_image_surface_t *image,
- cairo_rectangle_int_t *image_rect,
+ cairo_rectangle_int16_t *image_rect,
void *image_extra)
{
cairo_os2_surface_t *local_os2_surface;
RECTL rclToBlit;
local_os2_surface = (cairo_os2_surface_t *) abstract_surface;
if ((!local_os2_surface) ||
(local_os2_surface->base.backend != &cairo_os2_surface_backend))
@@ -623,17 +660,17 @@ static void
local_os2_surface->pixel_array_lend_count--;
DosPostEventSem (local_os2_surface->hev_pixel_array_came_back);
DosReleaseMutexSem (local_os2_surface->hmtx_use_private_fields);
}
static cairo_int_status_t
_cairo_os2_surface_get_extents (void *abstract_surface,
- cairo_rectangle_int_t *rectangle)
+ cairo_rectangle_int16_t *rectangle)
{
cairo_os2_surface_t *local_os2_surface;
local_os2_surface = (cairo_os2_surface_t *) abstract_surface;
if ((!local_os2_surface) ||
(local_os2_surface->base.backend != &cairo_os2_surface_backend))
{
/* Invalid parameter (wrong surface)! */
@@ -709,17 +746,17 @@ cairo_os2_surface_create (HPS hps_client
memset (&(local_os2_surface->bitmap_info), 0, sizeof (local_os2_surface->bitmap_info));
local_os2_surface->bitmap_info.cbFix = sizeof (BITMAPINFOHEADER2);
local_os2_surface->bitmap_info.cx = width;
local_os2_surface->bitmap_info.cy = height;
local_os2_surface->bitmap_info.cPlanes = 1;
local_os2_surface->bitmap_info.cBitCount = 32;
/* Allocate memory for pixels */
- local_os2_surface->pixels = (unsigned char *) _cairo_malloc_abc (height, width, 4);
+ local_os2_surface->pixels = (unsigned char *) malloc (width * height * 4);
if (!(local_os2_surface->pixels)) {
/* Not enough memory for the pixels! */
DosCloseEventSem (local_os2_surface->hev_pixel_array_came_back);
DosCloseMutexSem (local_os2_surface->hmtx_use_private_fields);
free (local_os2_surface);
_cairo_error (CAIRO_STATUS_NO_MEMORY);
return (cairo_surface_t *) &_cairo_surface_nil;
}
@@ -779,17 +816,17 @@ cairo_os2_surface_set_size (cairo_surfac
if ((new_width <= 0) ||
(new_height <= 0))
{
/* Invalid size! */
return CAIRO_STATUS_NO_MEMORY;
}
/* Allocate memory for new stuffs */
- pchNewPixels = (unsigned char *) _cairo_malloc_abc (new_height, new_width, 4);
+ pchNewPixels = (unsigned char *) malloc (new_width * new_height * 4);
if (!pchNewPixels) {
/* Not enough memory for the pixels!
* Everything remains the same!
*/
return CAIRO_STATUS_NO_MEMORY;
}
/* This is possibly not needed, malloc'd space is usually
--- a/gfx/cairo/cairo/src/cairo-output-stream-private.h
+++ b/gfx/cairo/cairo/src/cairo-output-stream-private.h
@@ -32,33 +32,33 @@
*
* Author(s):
* Kristian Høgsberg <krh@redhat.com>
*/
#ifndef CAIRO_OUTPUT_STREAM_PRIVATE_H
#define CAIRO_OUTPUT_STREAM_PRIVATE_H
-#include "cairo-types-private.h"
+typedef struct _cairo_output_stream cairo_output_stream_t;
typedef cairo_status_t (*cairo_output_stream_write_func_t) (cairo_output_stream_t *output_stream,
const unsigned char *data,
unsigned int length);
typedef cairo_status_t (*cairo_output_stream_close_func_t) (cairo_output_stream_t *output_stream);
struct _cairo_output_stream {
cairo_output_stream_write_func_t write_func;
cairo_output_stream_close_func_t close_func;
unsigned long position;
cairo_status_t status;
cairo_bool_t closed;
};
-extern const cairo_private cairo_output_stream_t _cairo_output_stream_nil;
+extern const cairo_private cairo_output_stream_t cairo_output_stream_nil;
cairo_private void
_cairo_output_stream_init (cairo_output_stream_t *stream,
cairo_output_stream_write_func_t write_func,
cairo_output_stream_close_func_t close_func);
cairo_private cairo_status_t
_cairo_output_stream_fini (cairo_output_stream_t *stream);
@@ -102,17 +102,17 @@ cairo_private void
_cairo_output_stream_write (cairo_output_stream_t *stream,
const void *data, size_t length);
cairo_private void
_cairo_output_stream_write_hex_string (cairo_output_stream_t *stream,
const char *data,
size_t length);
-cairo_private void
+cairo_private int
_cairo_dtostr (char *buffer, size_t size, double d);
cairo_private void
_cairo_output_stream_vprintf (cairo_output_stream_t *stream,
const char *fmt, va_list ap);
cairo_private void
_cairo_output_stream_printf (cairo_output_stream_t *stream,
--- a/gfx/cairo/cairo/src/cairo-output-stream.c
+++ b/gfx/cairo/cairo/src/cairo-output-stream.c
@@ -29,22 +29,21 @@
* 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"
-
-#include "cairo-output-stream-private.h"
-
+#include <stdio.h>
#include <locale.h>
#include <ctype.h>
+#include "cairoint.h"
+#include "cairo-output-stream-private.h"
#ifdef _MSC_VER
#define snprintf _snprintf
#endif /* _MSC_VER */
cairo_private void
_cairo_output_stream_init (cairo_output_stream_t *stream,
@@ -59,25 +58,25 @@ cairo_private void
}
cairo_private cairo_status_t
_cairo_output_stream_fini (cairo_output_stream_t *stream)
{
return _cairo_output_stream_close (stream);
}
-const cairo_output_stream_t _cairo_output_stream_nil = {
+const cairo_output_stream_t cairo_output_stream_nil = {
NULL, /* write_func */
NULL, /* close_func */
0, /* position */
CAIRO_STATUS_NO_MEMORY,
FALSE /* closed */
};
-static const cairo_output_stream_t _cairo_output_stream_nil_write_error = {
+static const cairo_output_stream_t cairo_output_stream_nil_write_error = {
NULL, /* write_func */
NULL, /* close_func */
0, /* position */
CAIRO_STATUS_WRITE_ERROR,
FALSE /* closed */
};
typedef struct _cairo_output_stream_with_closure {
@@ -115,17 +114,17 @@ cairo_output_stream_t *
_cairo_output_stream_create (cairo_write_func_t write_func,
cairo_close_func_t close_func,
void *closure)
{
cairo_output_stream_with_closure_t *stream;
stream = malloc (sizeof (cairo_output_stream_with_closure_t));
if (stream == NULL)
- return (cairo_output_stream_t *) &_cairo_output_stream_nil;
+ return (cairo_output_stream_t *) &cairo_output_stream_nil;
_cairo_output_stream_init (&stream->base, closure_write, closure_close);
stream->write_func = write_func;
stream->close_func = close_func;
stream->closure = closure;
return &stream->base;
}
@@ -133,18 +132,18 @@ cairo_output_stream_t *
cairo_status_t
_cairo_output_stream_close (cairo_output_stream_t *stream)
{
cairo_status_t status;
if (stream->closed)
return stream->status;
- if (stream == &_cairo_output_stream_nil ||
- stream == &_cairo_output_stream_nil_write_error)
+ if (stream == &cairo_output_stream_nil ||
+ stream == &cairo_output_stream_nil_write_error)
{
return stream->status;
}
if (stream->close_func) {
status = stream->close_func (stream);
/* Don't overwrite a pre-existing status failure. */
if (stream->status == CAIRO_STATUS_SUCCESS)
@@ -210,59 +209,62 @@ void
/* 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>
*/
-void
+
+int
_cairo_dtostr (char *buffer, size_t size, double d)
{
- struct lconv *locale_data;
- const char *decimal_point;
- int decimal_point_len;
- char *p;
- int decimal_len;
+ struct lconv *locale_data;
+ const char *decimal_point;
+ int decimal_point_len;
+ char *p;
+ int decimal_len;
- /* Omit the minus sign from negative zero. */
- if (d == 0.0)
- d = 0.0;
+ /* Omit the minus sign from negative zero. */
+ if (d == 0.0)
+ d = 0.0;
- snprintf (buffer, size, "%f", d);
+ snprintf (buffer, size, "%f", d);
- locale_data = localeconv ();
- decimal_point = locale_data->decimal_point;
- decimal_point_len = strlen (decimal_point);
+ locale_data = localeconv ();
+ decimal_point = locale_data->decimal_point;
+ decimal_point_len = strlen (decimal_point);
- assert (decimal_point_len != 0);
- p = buffer;
+ assert (decimal_point_len != 0);
+ p = buffer;
- if (*p == '+' || *p == '-')
- p++;
+ if (*p == '+' || *p == '-')
+ p++;
+
+ while (isdigit (*p))
+ p++;
- while (isdigit (*p))
- p++;
+ if (strncmp (p, decimal_point, decimal_point_len) == 0) {
+ *p = '.';
+ decimal_len = strlen (p + decimal_point_len);
+ memmove (p + 1, p + decimal_point_len, decimal_len);
+ p[1 + decimal_len] = 0;
- if (strncmp (p, decimal_point, decimal_point_len) == 0) {
- *p = '.';
- decimal_len = strlen (p + decimal_point_len);
- memmove (p + 1, p + decimal_point_len, decimal_len);
- p[1 + decimal_len] = 0;
+ /* Remove trailing zeros and decimal point if possible. */
+ for (p = p + decimal_len; *p == '0'; p--)
+ *p = 0;
- /* Remove trailing zeros and decimal point if possible. */
- for (p = p + decimal_len; *p == '0'; p--)
- *p = 0;
+ if (*p == '.') {
+ *p = 0;
+ p--;
+ }
+ }
- if (*p == '.') {
- *p = 0;
- p--;
- }
- }
+ return p + 1 - buffer;
}
enum {
LENGTH_MODIFIER_LONG = 0x100
};
/* Here's a limited reimplementation of printf. The reason for doing
* this is primarily to special case handling of doubles. We want
@@ -271,23 +273,20 @@ enum {
* below handles everything else by calling snprintf() to do the
* formatting. This functionality is only for internal use and we
* only implement the formats we actually use.
*/
void
_cairo_output_stream_vprintf (cairo_output_stream_t *stream,
const char *fmt, va_list ap)
{
-#define SINGLE_FMT_BUFFER_SIZE 32
- char buffer[512], single_fmt[SINGLE_FMT_BUFFER_SIZE];
- int single_fmt_length;
- char *p;
+ char buffer[512], single_fmt[32];
+ char *p, *end;
const char *f, *start;
- int length_modifier, width;
- cairo_bool_t var_width;
+ int length_modifier;
if (stream->status)
return;
f = fmt;
p = buffer;
while (*f != '\0') {
if (p == buffer + sizeof (buffer)) {
@@ -301,40 +300,30 @@ void
}
start = f;
f++;
if (*f == '0')
f++;
- var_width = FALSE;
- if (*f == '*') {
- var_width = TRUE;
- f++;
- }
-
- while (isdigit (*f))
- f++;
+ if (isdigit (*f)) {
+ strtol (f, &end, 10);
+ f = end;
+ }
length_modifier = 0;
if (*f == 'l') {
length_modifier = LENGTH_MODIFIER_LONG;
f++;
}
- /* The only format strings exist in the cairo implementation
- * itself. So there's an internal consistency problem if any
- * of them is larger than our format buffer size. */
- single_fmt_length = f - start + 1;
- assert (single_fmt_length + 1 <= SINGLE_FMT_BUFFER_SIZE);
-
/* Reuse the format string for this conversion. */
- memcpy (single_fmt, start, single_fmt_length);
- single_fmt[single_fmt_length] = '\0';
+ memcpy (single_fmt, start, f + 1 - start);
+ single_fmt[f + 1 - start] = '\0';
/* Flush contents of buffer before snprintf()'ing into it. */
_cairo_output_stream_write (stream, buffer, p - buffer);
p = buffer;
/* We group signed and unsigned together in this switch, the
* only thing that matters here is the size of the arguments,
* since we're just passing the data through to sprintf(). */
@@ -343,37 +332,25 @@ void
buffer[0] = *f;
buffer[1] = 0;
break;
case 'd':
case 'u':
case 'o':
case 'x':
case 'X':
- if (var_width) {
- width = va_arg (ap, int);
- snprintf (buffer, sizeof buffer,
- single_fmt, width, va_arg (ap, int));
- } else {
- snprintf (buffer, sizeof buffer, single_fmt, va_arg (ap, int));
- }
+ snprintf (buffer, sizeof buffer, single_fmt, va_arg (ap, int));
break;
case 'd' | LENGTH_MODIFIER_LONG:
case 'u' | LENGTH_MODIFIER_LONG:
case 'o' | LENGTH_MODIFIER_LONG:
case 'x' | LENGTH_MODIFIER_LONG:
case 'X' | LENGTH_MODIFIER_LONG:
- if (var_width) {
- width = va_arg (ap, int);
- snprintf (buffer, sizeof buffer,
- single_fmt, width, va_arg (ap, long int));
- } else {
- snprintf (buffer, sizeof buffer,
- single_fmt, va_arg (ap, long int));
- }
+ snprintf (buffer, sizeof buffer,
+ single_fmt, va_arg (ap, long int));
break;
case 's':
snprintf (buffer, sizeof buffer,
single_fmt, va_arg (ap, const char *));
break;
case 'f':
_cairo_dtostr (buffer, sizeof buffer, va_arg (ap, double));
break;
@@ -464,42 +441,42 @@ stdio_close (cairo_output_stream_t *base
}
cairo_output_stream_t *
_cairo_output_stream_create_for_file (FILE *file)
{
stdio_stream_t *stream;
if (file == NULL)
- return (cairo_output_stream_t *) &_cairo_output_stream_nil_write_error;
+ return (cairo_output_stream_t *) &cairo_output_stream_nil_write_error;
stream = malloc (sizeof *stream);
if (stream == NULL)
- return (cairo_output_stream_t *) &_cairo_output_stream_nil;
+ return (cairo_output_stream_t *) &cairo_output_stream_nil;
_cairo_output_stream_init (&stream->base, stdio_write, stdio_flush);
stream->file = file;
return &stream->base;
}
cairo_output_stream_t *
_cairo_output_stream_create_for_filename (const char *filename)
{
stdio_stream_t *stream;
FILE *file;
file = fopen (filename, "wb");
if (file == NULL)
- return (cairo_output_stream_t *) &_cairo_output_stream_nil_write_error;
+ return (cairo_output_stream_t *) &cairo_output_stream_nil_write_error;
stream = malloc (sizeof *stream);
if (stream == NULL) {
fclose (file);
- return (cairo_output_stream_t *) &_cairo_output_stream_nil;
+ return (cairo_output_stream_t *) &cairo_output_stream_nil;
}
_cairo_output_stream_init (&stream->base, stdio_write, stdio_close);
stream->file = file;
return &stream->base;
}
@@ -530,17 +507,17 @@ memory_close (cairo_output_stream_t *bas
cairo_output_stream_t *
_cairo_memory_stream_create (void)
{
memory_stream_t *stream;
stream = malloc (sizeof *stream);
if (stream == NULL)
- return (cairo_output_stream_t *) &_cairo_output_stream_nil;
+ return (cairo_output_stream_t *) &cairo_output_stream_nil;
_cairo_output_stream_init (&stream->base, memory_write, memory_close);
_cairo_array_init (&stream->array, 1);
return &stream->base;
}
void
--- a/gfx/cairo/cairo/src/cairo-paginated-surface-private.h
+++ b/gfx/cairo/cairo/src/cairo-paginated-surface-private.h
@@ -31,42 +31,111 @@
*
* Contributor(s):
* Carl Worth <cworth@cworth.org>
*/
#ifndef CAIRO_PAGINATED_SURFACE_H
#define CAIRO_PAGINATED_SURFACE_H
-#include "cairo.h"
+#include "cairoint.h"
-#include "cairo-surface-private.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 {
- cairo_surface_t base;
+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);
- /* The target surface to hold the final result. */
- cairo_surface_t *target;
-
- cairo_content_t content;
+ /* 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;
- /* XXX: These shouldn't actually exist. We inherit this ugliness
- * from _cairo_meta_surface_create. The width/height parameters
- * from that function also should not exist. The fix that will
- * allow us to remove all of these is to fix acquire_source_image
- * to pass an interest rectangle. */
- int width;
- int height;
+/* 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,
+ const cairo_paginated_surface_backend_t *backend);
- /* Paginated-surface specific functions for the target */
- const cairo_paginated_surface_backend_t *backend;
+cairo_private cairo_surface_t *
+_cairo_paginated_surface_get_target (cairo_surface_t *surface);
- /* 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;
-
- int page_num;
- cairo_bool_t page_is_blank;
-
-} cairo_paginated_surface_t;
+cairo_private cairo_bool_t
+_cairo_surface_is_paginated (cairo_surface_t *surface);
#endif /* CAIRO_PAGINATED_SURFACE_H */
--- a/gfx/cairo/cairo/src/cairo-paginated-surface.c
+++ b/gfx/cairo/cairo/src/cairo-paginated-surface.c
@@ -31,27 +31,55 @@
*
* 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.). See cairo-paginated-private.h for
+ * (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-private.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
+ * from _cairo_meta_surface_create. The width/height parameters
+ * from that function also should not exist. The fix that will
+ * allow us to remove all of these is to fix acquire_source_image
+ * to pass an interest rectangle. */
+ int width;
+ int height;
+
+ /* 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;
+
+ int page_num;
+ cairo_bool_t page_is_blank;
+
+} cairo_paginated_surface_t;
+
const cairo_private cairo_surface_backend_t cairo_paginated_surface_backend;
static cairo_int_status_t
_cairo_paginated_surface_show_page (void *abstract_surface);
static cairo_surface_t *
_cairo_paginated_surface_create_similar (void *abstract_surface,
cairo_content_t content,
@@ -129,25 +157,21 @@ static cairo_status_t
_cairo_paginated_surface_finish (void *abstract_surface)
{
cairo_paginated_surface_t *surface = abstract_surface;
cairo_status_t status = CAIRO_STATUS_SUCCESS;
if (surface->page_is_blank == FALSE || surface->page_num == 1)
status = _cairo_paginated_surface_show_page (abstract_surface);
- if (status == CAIRO_STATUS_SUCCESS) {
+ if (status == CAIRO_STATUS_SUCCESS)
cairo_surface_finish (surface->target);
- status = cairo_surface_status (surface->target);
- }
- if (status == CAIRO_STATUS_SUCCESS) {
+ if (status == CAIRO_STATUS_SUCCESS)
cairo_surface_finish (surface->meta);
- status = cairo_surface_status (surface->meta);
- }
cairo_surface_destroy (surface->target);
cairo_surface_destroy (surface->meta);
return status;
}
@@ -172,32 +196,25 @@ static cairo_surface_t *
static cairo_status_t
_cairo_paginated_surface_acquire_source_image (void *abstract_surface,
cairo_image_surface_t **image_out,
void **image_extra)
{
cairo_paginated_surface_t *surface = abstract_surface;
cairo_surface_t *image;
- cairo_status_t status;
- cairo_rectangle_int_t extents;
+ cairo_rectangle_int16_t extents;
- status = _cairo_surface_get_extents (surface->target, &extents);
- if (status)
- return status;
+ _cairo_surface_get_extents (surface->target, &extents);
image = _cairo_paginated_surface_create_image_surface (surface,
extents.width,
extents.height);
- status = _cairo_meta_surface_replay (surface->meta, image);
- if (status) {
- cairo_surface_destroy (image);
- return status;
- }
+ _cairo_meta_surface_replay (surface->meta, image);
*image_out = (cairo_image_surface_t*) image;
*image_extra = NULL;
return CAIRO_STATUS_SUCCESS;
}
static void
@@ -213,64 +230,58 @@ static cairo_int_status_t
{
cairo_surface_t *analysis;
cairo_surface_t *image;
cairo_pattern_t *pattern;
cairo_status_t status;
analysis = _cairo_analysis_surface_create (surface->target,
surface->width, surface->height);
- if (analysis == NULL)
- return CAIRO_STATUS_NO_MEMORY;
surface->backend->set_paginated_mode (surface->target, CAIRO_PAGINATED_MODE_ANALYZE);
- status = _cairo_meta_surface_replay (surface->meta, analysis);
+ _cairo_meta_surface_replay (surface->meta, analysis);
surface->backend->set_paginated_mode (surface->target, CAIRO_PAGINATED_MODE_RENDER);
- if (status || analysis->status) {
- if (status == CAIRO_STATUS_SUCCESS)
- status = analysis->status;
+ if (analysis->status) {
+ status = analysis->status;
cairo_surface_destroy (analysis);
return status;
}
if (_cairo_analysis_surface_has_unsupported (analysis))
{
double x_scale = surface->base.x_fallback_resolution / 72.0;
double y_scale = surface->base.y_fallback_resolution / 72.0;
cairo_matrix_t matrix;
image = _cairo_paginated_surface_create_image_surface (surface,
surface->width * x_scale,
surface->height * y_scale);
_cairo_surface_set_device_scale (image, x_scale, y_scale);
- status = _cairo_meta_surface_replay (surface->meta, image);
- if (status)
- goto CLEANUP_IMAGE;
+ _cairo_meta_surface_replay (surface->meta, image);
pattern = cairo_pattern_create_for_surface (image);
cairo_matrix_init_scale (&matrix, x_scale, y_scale);
cairo_pattern_set_matrix (pattern, &matrix);
- status = _cairo_surface_paint (surface->target, CAIRO_OPERATOR_SOURCE, pattern);
+ _cairo_surface_paint (surface->target, CAIRO_OPERATOR_SOURCE, pattern);
cairo_pattern_destroy (pattern);
- CLEANUP_IMAGE:
cairo_surface_destroy (image);
}
else
{
- status = _cairo_meta_surface_replay (surface->meta, surface->target);
+ _cairo_meta_surface_replay (surface->meta, surface->target);
}
cairo_surface_destroy (analysis);
- return status;
+ return CAIRO_STATUS_SUCCESS;
}
static cairo_status_t
_start_page (cairo_paginated_surface_t *surface)
{
if (! surface->backend->start_page)
return CAIRO_STATUS_SUCCESS;
@@ -282,19 +293,17 @@ static cairo_int_status_t
{
cairo_status_t status;
cairo_paginated_surface_t *surface = abstract_surface;
status = _start_page (surface);
if (status)
return status;
- status = _paint_page (surface);
- if (status)
- return status;
+ _paint_page (surface);
surface->page_num++;
/* XXX: It might make sense to add some suport here for calling
* _cairo_surface_copy_page on the target surface. It would be an
* optimization for the output, (so that PostScript could include
* copypage, for example), but the interaction with image
* fallbacks gets tricky. For now, we just let the target see a
@@ -309,26 +318,19 @@ static cairo_int_status_t
{
cairo_status_t status;
cairo_paginated_surface_t *surface = abstract_surface;
status = _start_page (surface);
if (status)
return status;
- status = _paint_page (surface);
- if (status)
- return status;
+ _paint_page (surface);
- status = _cairo_surface_show_page (surface->target);
- if (status)
- return status;
-
- if (cairo_surface_status (surface->meta))
- return cairo_surface_status (surface->meta);
+ _cairo_surface_show_page (surface->target);
cairo_surface_destroy (surface->meta);
surface->meta = _cairo_meta_surface_create (surface->content,
surface->width, surface->height);
if (cairo_surface_status (surface->meta))
return cairo_surface_status (surface->meta);
@@ -349,17 +351,17 @@ static cairo_int_status_t
return _cairo_surface_intersect_clip_path (surface->meta,
path, fill_rule,
tolerance, antialias);
}
static cairo_int_status_t
_cairo_paginated_surface_get_extents (void *abstract_surface,
- cairo_rectangle_int_t *rectangle)
+ cairo_rectangle_int16_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,
@@ -478,17 +480,16 @@ static cairo_int_status_t
CAIRO_MUTEX_LOCK (scaled_font->mutex);
return status;
}
static cairo_surface_t *
_cairo_paginated_surface_snapshot (void *abstract_other)
{
- cairo_status_t status;
cairo_paginated_surface_t *other = abstract_other;
/* XXX: Just making a snapshot of other->meta is what we really
* want. But this currently triggers a bug somewhere (the "mask"
* test from the test suite segfaults).
*
* For now, we'll create a new image surface and replay onto
* that. It would be tempting to replay into other->image and then
@@ -496,32 +497,26 @@ static cairo_surface_t *
* test to fail, (since our replay will be affected by a clip that
* should not have any effect on the use of the resulting snapshot
* as a source).
*/
#if 0
return _cairo_surface_snapshot (other->meta);
#else
- cairo_rectangle_int_t extents;
+ cairo_rectangle_int16_t extents;
cairo_surface_t *surface;
- status = _cairo_surface_get_extents (other->target, &extents);
- if (status)
- return (cairo_surface_t*) &_cairo_surface_nil;
+ _cairo_surface_get_extents (other->target, &extents);
surface = _cairo_paginated_surface_create_image_surface (other,
extents.width,
extents.height);
- status = _cairo_meta_surface_replay (other->meta, surface);
- if (status) {
- cairo_surface_destroy (surface);
- surface = (cairo_surface_t*) &_cairo_surface_nil;
- }
+ _cairo_meta_surface_replay (other->meta, surface);
return surface;
#endif
}
const cairo_surface_backend_t cairo_paginated_surface_backend = {
CAIRO_INTERNAL_SURFACE_TYPE_PAGINATED,
_cairo_paginated_surface_create_similar,
--- a/gfx/cairo/cairo/src/cairo-path-bounds.c
+++ b/gfx/cairo/cairo/src/cairo-path-bounds.c
@@ -46,17 +46,17 @@ typedef struct cairo_path_bounder {
} cairo_path_bounder_t;
static void
_cairo_path_bounder_init (cairo_path_bounder_t *bounder);
static void
_cairo_path_bounder_fini (cairo_path_bounder_t *bounder);
-static void
+static cairo_status_t
_cairo_path_bounder_add_point (cairo_path_bounder_t *bounder, cairo_point_t *point);
static cairo_status_t
_cairo_path_bounder_move_to (void *closure, cairo_point_t *point);
static cairo_status_t
_cairo_path_bounder_line_to (void *closure, cairo_point_t *point);
@@ -76,17 +76,17 @@ static void
}
static void
_cairo_path_bounder_fini (cairo_path_bounder_t *bounder)
{
bounder->has_point = 0;
}
-static void
+static cairo_status_t
_cairo_path_bounder_add_point (cairo_path_bounder_t *bounder, cairo_point_t *point)
{
if (bounder->has_point) {
if (point->x < bounder->min_x)
bounder->min_x = point->x;
if (point->y < bounder->min_y)
bounder->min_y = point->y;
@@ -99,16 +99,18 @@ static void
} else {
bounder->min_x = point->x;
bounder->min_y = point->y;
bounder->max_x = point->x;
bounder->max_y = point->y;