diff --git a/configure.in b/configure.in index 60898652bf9a..ba729ce22535 100644 --- a/configure.in +++ b/configure.in @@ -6968,7 +6968,6 @@ if test "$MOZ_SVG" -o "$MOZ_ENABLE_CANVAS" -o "$MOZ_ENABLE_CAIRO_GFX" ; then # Define macros for cairo-features.h if test "$MOZ_X11"; then XLIB_SURFACE_FEATURE="#define CAIRO_HAS_XLIB_SURFACE 1" - XLIB_XRENDER_SURFACE_FEATURE="#define CAIRO_HAS_XLIB_XRENDER_SURFACE 1" PS_SURFACE_FEATURE="#define CAIRO_HAS_PS_SURFACE 1" PDF_SURFACE_FEATURE="#define CAIRO_HAS_PDF_SURFACE 1" FT_FONT_FEATURE="#define CAIRO_HAS_FT_FONT 1" @@ -7015,7 +7014,6 @@ if test "$MOZ_SVG" -o "$MOZ_ENABLE_CANVAS" -o "$MOZ_ENABLE_CAIRO_GFX" ; then AC_SUBST(PDF_SURFACE_FEATURE) AC_SUBST(SVG_SURFACE_FEATURE) AC_SUBST(XLIB_SURFACE_FEATURE) - AC_SUBST(XLIB_XRENDER_SURFACE_FEATURE) AC_SUBST(QUARTZ_SURFACE_FEATURE) AC_SUBST(NQUARTZ_SURFACE_FEATURE) AC_SUBST(XCB_SURFACE_FEATURE) diff --git a/gfx/cairo/README b/gfx/cairo/README index 819e446a0361..86ce5e69ee89 100644 --- a/gfx/cairo/README +++ b/gfx/cairo/README @@ -7,7 +7,7 @@ http://www.cairographics.org/. VERSIONS: - cairo (1.4.10) + cairo (1.4.2) glitz 0.5.2 (cvs - 2006-01-10) ***** NOTE FOR VISUAL C++ 6.0 ***** @@ -16,21 +16,18 @@ VC6 is not supported. Please upgrade to VC8. ==== Patches ==== +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 diff --git a/gfx/cairo/cairo/src/Makefile.in b/gfx/cairo/cairo/src/Makefile.in index 2ba65655eebd..c128e377a9e1 100644 --- a/gfx/cairo/cairo/src/Makefile.in +++ b/gfx/cairo/cairo/src/Makefile.in @@ -70,7 +70,7 @@ CSRCS = \ 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 \ @@ -80,7 +80,6 @@ CSRCS = \ cairo-lzw.c \ cairo-matrix.c \ cairo-meta-surface.c \ - cairo-mutex.c \ cairo-operator.c \ cairo-output-stream.c \ cairo-paginated-surface.c \ @@ -155,8 +154,7 @@ 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 diff --git a/gfx/cairo/cairo/src/cairo-analysis-surface-private.h b/gfx/cairo/cairo/src/cairo-analysis-surface-private.h index bb1145382f96..a94450c9405f 100644 --- a/gfx/cairo/cairo/src/cairo-analysis-surface-private.h +++ b/gfx/cairo/cairo/src/cairo-analysis-surface-private.h @@ -1,4 +1,5 @@ -/* +/* $Id: cairo-analysis-surface-private.h,v 1.8 2007/06/30 10:45:11 vladimir%pobox.com Exp $ + * * Copyright © 2005 Keith Packard * * This library is free software; you can redistribute it and/or diff --git a/gfx/cairo/cairo/src/cairo-analysis-surface.c b/gfx/cairo/cairo/src/cairo-analysis-surface.c index 26a373fa6c37..a89636efae84 100644 --- a/gfx/cairo/cairo/src/cairo-analysis-surface.c +++ b/gfx/cairo/cairo/src/cairo-analysis-surface.c @@ -35,7 +35,7 @@ #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; diff --git a/gfx/cairo/cairo/src/cairo-arc.c b/gfx/cairo/cairo/src/cairo-arc.c index 89e6ce1a655d..2bf6c89f0b12 100644 --- a/gfx/cairo/cairo/src/cairo-arc.c +++ b/gfx/cairo/cairo/src/cairo-arc.c @@ -34,8 +34,6 @@ * Carl D. Worth */ -#include "cairoint.h" - #include "cairo-arc-private.h" /* Spline deviation from the circle in radius would be given by: @@ -87,7 +85,7 @@ _arc_max_angle_for_tolerance_normalized (double tolerance) { 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) diff --git a/gfx/cairo/cairo/src/cairo-atsui-font.c b/gfx/cairo/cairo/src/cairo-atsui-font.c index 361e787e7718..a26e76ffa1c9 100644 --- a/gfx/cairo/cairo/src/cairo-atsui-font.c +++ b/gfx/cairo/cairo/src/cairo-atsui-font.c @@ -34,10 +34,11 @@ * Calum Robinson */ -#include "cairoint.h" - -#include "cairo.h" +#include +#include #include "cairo-atsui.h" +#include "cairoint.h" +#include "cairo.h" #include "cairo-quartz-private.h" /* @@ -116,7 +117,8 @@ _cairo_atsui_font_face_scaled_font_create (void *abstract_face, 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, @@ -129,19 +131,6 @@ static const cairo_font_face_backend_t _cairo_atsui_font_face_backend = { _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) { @@ -160,6 +149,14 @@ cairo_atsui_font_face_create_for_atsu_font_id (ATSUFontID font_id) 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, @@ -235,13 +232,8 @@ _cairo_atsui_font_create_scaled (cairo_font_face_t *font_face, 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); @@ -382,7 +374,8 @@ _cairo_atsui_font_create_toy(cairo_toy_font_face_t *toy_face, 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); } @@ -404,6 +397,50 @@ _cairo_atsui_font_fini(void *abstract_font) 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); @@ -417,10 +454,16 @@ _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, @@ -446,15 +489,41 @@ _cairo_atsui_font_init_glyph_metrics (cairo_atsui_font_t *scaled_font, 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; } @@ -598,7 +667,6 @@ _cairo_atsui_scaled_font_init_glyph_surface (cairo_atsui_font_t *scaled_font, CGContextRef drawingContext; cairo_image_surface_t *surface; cairo_format_t format; - cairo_status_t status; ATSFontRef atsFont; CGFontRef cgFont; @@ -615,10 +683,8 @@ _cairo_atsui_scaled_font_init_glyph_surface (cairo_atsui_font_t *scaled_font, 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); @@ -626,25 +692,19 @@ _cairo_atsui_scaled_font_init_glyph_surface (cairo_atsui_font_t *scaled_font, } /* 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 @@ -683,9 +743,8 @@ _cairo_atsui_scaled_font_init_glyph_surface (cairo_atsui_font_t *scaled_font, /* 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 */ { diff --git a/gfx/cairo/cairo/src/cairo-base85-stream.c b/gfx/cairo/cairo/src/cairo-base85-stream.c index 08ae8a74aa70..7163d0092693 100644 --- a/gfx/cairo/cairo/src/cairo-base85-stream.c +++ b/gfx/cairo/cairo/src/cairo-base85-stream.c @@ -115,7 +115,7 @@ _cairo_base85_stream_create (cairo_output_stream_t *output) 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, diff --git a/gfx/cairo/cairo/src/cairo-bentley-ottmann.c b/gfx/cairo/cairo/src/cairo-bentley-ottmann.c index b8d97fa2634e..928b6cd56464 100644 --- a/gfx/cairo/cairo/src/cairo-bentley-ottmann.c +++ b/gfx/cairo/cairo/src/cairo-bentley-ottmann.c @@ -137,7 +137,6 @@ typedef struct _cairo_bo_sweep_line { 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) @@ -693,16 +692,13 @@ _cairo_bo_event_init (cairo_bo_event_t *event, 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 @@ -754,14 +750,16 @@ _cairo_bo_event_queue_init (cairo_bo_event_queue_t *event_queue, * 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 = malloc (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++) { @@ -794,9 +792,11 @@ _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) @@ -806,7 +806,7 @@ _cairo_bo_event_queue_insert_if_intersect_below_current_y (cairo_bo_event_queue_ 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 @@ -814,13 +814,13 @@ _cairo_bo_event_queue_insert_if_intersect_below_current_y (cairo_bo_event_queue_ * 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, @@ -828,7 +828,7 @@ _cairo_bo_event_queue_insert_if_intersect_below_current_y (cairo_bo_event_queue_ left, right, intersection); - return _cairo_bo_event_queue_insert (event_queue, &event); + _cairo_bo_event_queue_insert (event_queue, &event); } static void @@ -848,7 +848,7 @@ _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) { @@ -858,8 +858,6 @@ _cairo_bo_sweep_line_insert (cairo_bo_sweep_line_t *sweep_line, 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) @@ -878,8 +876,6 @@ _cairo_bo_sweep_line_insert (cairo_bo_sweep_line_t *sweep_line, *next_of_prev = edge; edge->sweep_line_elt = sweep_line_elt; - - return CAIRO_STATUS_SUCCESS; } static void @@ -1061,6 +1057,7 @@ _cairo_bo_edge_end_trap (cairo_bo_edge_t *left, 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; @@ -1102,11 +1099,11 @@ _cairo_bo_edge_end_trap (cairo_bo_edge_t *left, 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) " @@ -1120,8 +1117,7 @@ _cairo_bo_edge_end_trap (cairo_bo_edge_t *left, _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 @@ -1258,7 +1254,7 @@ _cairo_bentley_ottmann_tessellate_bo_edges (cairo_bo_edge_t *edges, 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; @@ -1268,10 +1264,7 @@ _cairo_bentley_ottmann_tessellate_bo_edges (cairo_bo_edge_t *edges, 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); @@ -1303,9 +1296,7 @@ _cairo_bentley_ottmann_tessellate_bo_edges (cairo_bo_edge_t *edges, 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); */ @@ -1313,13 +1304,9 @@ _cairo_bentley_ottmann_tessellate_bo_edges (cairo_bo_edge_t *edges, 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); @@ -1339,9 +1326,7 @@ _cairo_bentley_ottmann_tessellate_bo_edges (cairo_bo_edge_t *edges, 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); @@ -1369,15 +1354,11 @@ _cairo_bentley_ottmann_tessellate_bo_edges (cairo_bo_edge_t *edges, /* 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); @@ -1421,7 +1402,6 @@ _cairo_bentley_ottmann_tessellate_polygon (cairo_traps_t *traps, { 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; @@ -1433,13 +1413,9 @@ _cairo_bentley_ottmann_tessellate_polygon (cairo_traps_t *traps, if (0 == polygon->num_edges) return CAIRO_STATUS_SUCCESS; - if (polygon->num_edges < ARRAY_LENGTH (stack_edges)) { - edges = stack_edges; - } else { - edges = malloc (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. */ @@ -1519,8 +1495,7 @@ _cairo_bentley_ottmann_tessellate_polygon (cairo_traps_t *traps, xmin, ymin, xmax, ymax, &intersections); - if (edges != stack_edges) - free (edges); + free (edges); return status; } @@ -1796,7 +1771,7 @@ main (void) 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); } diff --git a/gfx/cairo/cairo/src/cairo-cache-private.h b/gfx/cairo/cairo/src/cairo-cache-private.h index 7ab14e26cd17..566dbe22d395 100644 --- a/gfx/cairo/cairo/src/cairo-cache-private.h +++ b/gfx/cairo/cairo/src/cairo-cache-private.h @@ -39,7 +39,7 @@ #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: diff --git a/gfx/cairo/cairo/src/cairo-cache.c b/gfx/cairo/cairo/src/cairo-cache.c index 18c3d8cca38c..fa1f003a659c 100644 --- a/gfx/cairo/cairo/src/cairo-cache.c +++ b/gfx/cairo/cairo/src/cairo-cache.c @@ -38,6 +38,17 @@ #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); diff --git a/gfx/cairo/cairo/src/cairo-cff-subset.c b/gfx/cairo/cairo/src/cairo-cff-subset.c index 2adc709c0bde..b35498940b82 100644 --- a/gfx/cairo/cairo/src/cairo-cff-subset.c +++ b/gfx/cairo/cairo/src/cairo-cff-subset.c @@ -37,20 +37,15 @@ #include "cairoint.h" #include "cairo-scaled-font-subsets-private.h" #include "cairo-truetype-subset-private.h" -#include /* 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 @@ -58,13 +53,13 @@ #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; @@ -87,6 +82,13 @@ typedef struct _cff_dict_operator { 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; @@ -106,23 +108,14 @@ typedef struct _cairo_cff_font { 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 */ @@ -354,6 +347,7 @@ cff_index_write (cairo_array_t *index, cairo_array_t *output) status = _cairo_array_append_multiple (output, buf, offset_size); if (status) return status; + } for (i = 0; i < num_elem; i++) { @@ -380,9 +374,7 @@ cff_index_append (cairo_array_t *index, unsigned char *object , int length) } 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; @@ -496,21 +488,6 @@ fail: 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, @@ -586,12 +563,19 @@ typedef struct _dict_write_info { } 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; @@ -605,36 +589,13 @@ cairo_dict_write_operator (cff_dict_operator_t *op, dict_write_info_t *write_inf 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; @@ -685,8 +646,6 @@ cairo_cff_font_read_name (cairo_cff_font_t *font) 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) { @@ -697,140 +656,21 @@ cairo_cff_font_read_private_dict (cairo_cff_font_t *font, 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); + 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_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; - } - - 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) { @@ -850,14 +690,13 @@ cairo_cff_font_read_top_dict (cairo_cff_font_t *font) 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); @@ -867,39 +706,27 @@ cairo_cff_font_read_top_dict (cairo_cff_font_t *font) 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); @@ -919,6 +746,138 @@ 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); @@ -928,6 +887,8 @@ static const font_read_t font_read_funcs[] = { 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 @@ -945,34 +906,6 @@ cairo_cff_font_read_font (cairo_cff_font_t *font) 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, @@ -1033,6 +966,20 @@ cairo_cff_font_subset_dict_strings (cairo_cff_font_t *font, 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) { @@ -1040,6 +987,14 @@ cairo_cff_font_subset_charstrings (cairo_cff_font_t *font) 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]); @@ -1053,127 +1008,97 @@ cairo_cff_font_subset_charstrings (cairo_cff_font_t *font) return CAIRO_STATUS_SUCCESS; } +static uint16_t +cff_sid_from_gid (const cff_charset_t *charset, int gid) +{ + const uint16_t *sids; + const unsigned char *p; + int prev_glyph; + + if (charset->is_builtin) { + if (gid - 1 < charset->length / 2) + return charset->sids[gid - 1]; + } + 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_subset_fontdict (cairo_cff_font_t *font) +cairo_cff_font_subset_charset (cairo_cff_font_t *font) { 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; - - 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]; + 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; + + 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; } - - free (reverse_map); - return CAIRO_STATUS_SUCCESS; } -static cairo_status_t -cairo_cff_font_create_cid_fontdict (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; - - 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); - } - - return status; -} - 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; } @@ -1287,82 +1212,38 @@ cairo_cff_font_write_global_subrs (cairo_cff_font_t *font) } 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; + unsigned char buf[10]; - cairo_cff_font_set_topdict_operator_to_cur_pos (font, FDSELECT_OP); + 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; - 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; - - 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); - - 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); - - 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); + return status; + 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; } @@ -1375,48 +1256,9 @@ cairo_cff_font_write_charstrings (cairo_cff_font_t *font) } 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; @@ -1424,46 +1266,30 @@ cairo_cff_font_write_private_dict (cairo_cff_font_t *font, 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; } @@ -1471,47 +1297,6 @@ cairo_cff_font_write_local_sub (cairo_cff_font_t *font, 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); @@ -1521,11 +1306,10 @@ static const font_write_t font_write_funcs[] = { 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 @@ -1589,7 +1373,7 @@ cairo_cff_font_create_set_widths (cairo_cff_font_t *font) 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); @@ -1771,13 +1555,7 @@ _cairo_cff_font_create (cairo_scaled_font_subset_t *scaled_font_subset, 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; @@ -1804,8 +1582,6 @@ fail1: 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); @@ -1818,43 +1594,7 @@ cairo_cff_font_destroy (cairo_cff_font_t *font) 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); } @@ -1922,215 +1662,3 @@ _cairo_cff_subset_fini (cairo_cff_subset_t *subset) 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); -} diff --git a/gfx/cairo/cairo/src/cairo-clip-private.h b/gfx/cairo/cairo/src/cairo-clip-private.h index e7190cf1d563..3c4ff0d4233d 100644 --- a/gfx/cairo/cairo/src/cairo-clip-private.h +++ b/gfx/cairo/cairo/src/cairo-clip-private.h @@ -38,7 +38,7 @@ #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; @@ -72,8 +72,7 @@ struct _cairo_clip { /* * A clip region that can be placed in the surface */ - pixman_region16_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. @@ -84,15 +83,18 @@ struct _cairo_clip { 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 diff --git a/gfx/cairo/cairo/src/cairo-clip.c b/gfx/cairo/cairo/src/cairo-clip.c index 60f2418ffe43..efecd89efd2f 100644 --- a/gfx/cairo/cairo/src/cairo-clip.c +++ b/gfx/cairo/cairo/src/cairo-clip.c @@ -61,13 +61,28 @@ _cairo_clip_init (cairo_clip_t *clip, cairo_surface_t *target) clip->serial = 0; - pixman_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; @@ -77,26 +92,17 @@ _cairo_clip_init_copy (cairo_clip_t *clip, cairo_clip_t *other) clip->serial = other->serial; - pixman_region_init (&clip->region); - - if (other->has_region) { - if (pixman_region_copy (&clip->region, &other->region) != - PIXMAN_REGION_STATUS_SUCCESS) { - pixman_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 */ @@ -105,18 +111,14 @@ _cairo_clip_reset (cairo_clip_t *clip) clip->serial = 0; - if (clip->has_region) { - /* pixman_region_fini just releases the resources used but - * doesn't bother with leaving the region in a valid state. - * So pixman_region_init has to be called afterwards. */ - pixman_region_fini (&clip->region); - pixman_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 @@ -168,26 +170,27 @@ _cairo_clip_intersect_to_rectangle (cairo_clip_t *clip, return status; } - if (clip->has_region) { + if (clip->region) { + pixman_region16_t *intersection; cairo_status_t status = CAIRO_STATUS_SUCCESS; - pixman_region16_t intersection; + pixman_region_status_t pixman_status; - pixman_region_init_rect (&intersection, - rectangle->x, rectangle->y, - rectangle->width, rectangle->height); + intersection = _cairo_region_create_from_rectangle (rectangle); + if (intersection == NULL) + return CAIRO_STATUS_NO_MEMORY; - if (PIXMAN_REGION_STATUS_SUCCESS != - pixman_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; - } else { - _cairo_region_extents_rectangle (&intersection, rectangle); - } - pixman_region_fini (&intersection); + pixman_region_destroy (intersection); - if (status) - return status; + if (status) + return status; } if (clip->surface) @@ -200,8 +203,6 @@ cairo_status_t _cairo_clip_intersect_to_region (cairo_clip_t *clip, pixman_region16_t *region) { - pixman_region_status_t pixman_status; - if (!clip) return CAIRO_STATUS_SUCCESS; @@ -209,28 +210,28 @@ _cairo_clip_intersect_to_region (cairo_clip_t *clip, /* Intersect clip path into region. */ } - if (clip->has_region) { - pixman_status = pixman_region_intersect (region, &clip->region, region); - if (pixman_status != PIXMAN_REGION_STATUS_SUCCESS) - return CAIRO_STATUS_NO_MEMORY; - } + if (clip->region) + pixman_region_intersect (region, clip->region, region); if (clip->surface) { + pixman_region16_t *clip_rect; + pixman_region_status_t pixman_status; cairo_status_t status = CAIRO_STATUS_SUCCESS; - pixman_region16_t clip_rect; - pixman_region_init_rect (&clip_rect, - clip->surface_rect.x, clip->surface_rect.y, - clip->surface_rect.width, clip->surface_rect.height); + clip_rect = _cairo_region_create_from_rectangle (&clip->surface_rect); + if (clip_rect == NULL) + return CAIRO_STATUS_NO_MEMORY; - if (PIXMAN_REGION_STATUS_SUCCESS != - pixman_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; - pixman_region_fini (&clip_rect); + pixman_region_destroy (clip_rect); - if (status) - return status; + if (status) + return status; } return CAIRO_STATUS_SUCCESS; @@ -328,47 +329,42 @@ _cairo_clip_path_destroy (cairo_clip_path_t *clip_path) 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) { - pixman_region16_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; + if (region == NULL) + return CAIRO_INT_STATUS_UNSUPPORTED; + status = CAIRO_STATUS_SUCCESS; - - if (!clip->has_region) { - if (pixman_region_copy (&clip->region, ®ion) == - PIXMAN_REGION_STATUS_SUCCESS) - clip->has_region = TRUE; - else - status = CAIRO_STATUS_NO_MEMORY; + if (clip->region == NULL) { + clip->region = region; } else { - pixman_region16_t intersection; - pixman_region_init (&intersection); + pixman_region16_t *intersection = pixman_region_create(); - if (PIXMAN_REGION_STATUS_SUCCESS != - pixman_region_intersect (&intersection, - &clip->region, - ®ion) || - PIXMAN_REGION_STATUS_SUCCESS != - pixman_region_copy (&clip->region, &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_fini (&intersection); + } + pixman_region_destroy (region); } clip->serial = _cairo_surface_allocate_clip_serial (target); - pixman_region_fini (®ion); return status; } @@ -406,16 +402,14 @@ _cairo_clip_intersect_mask (cairo_clip_t *clip, 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, @@ -515,8 +509,8 @@ _cairo_clip_translate (cairo_clip_t *clip, cairo_fixed_t tx, cairo_fixed_t ty) { - if (clip->has_region) { - pixman_region_translate (&clip->region, + if (clip->region) { + pixman_region_translate (clip->region, _cairo_fixed_integer_part (tx), _cairo_fixed_integer_part (ty)); } @@ -555,7 +549,7 @@ _cairo_clip_path_reapply_clip_path (cairo_clip_t *clip, clip_path->antialias); } -cairo_status_t +void _cairo_clip_init_deep_copy (cairo_clip_t *clip, cairo_clip_t *other, cairo_surface_t *target) @@ -566,22 +560,18 @@ _cairo_clip_init_deep_copy (cairo_clip_t *clip, /* We should reapply the original clip path in this case, and let * whatever the right handling is happen */ } else { - if (other->has_region) { - if (pixman_region_copy (&clip->region, &other->region) != - PIXMAN_REGION_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; } @@ -589,16 +579,6 @@ _cairo_clip_init_deep_copy (cairo_clip_t *clip, _cairo_clip_path_reapply_clip_path (clip, other->path); } } - - return CAIRO_STATUS_SUCCESS; - -BAIL: - if (clip->has_region) - pixman_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 = @@ -633,16 +613,16 @@ _cairo_clip_copy_rectangle_list (cairo_clip_t *clip, cairo_gstate_t *gstate) if (clip->path || clip->surface) return (cairo_rectangle_list_t*) &_cairo_rectangles_not_representable; - n_boxes = clip->has_region ? pixman_region_num_rects (&clip->region) : 1; + 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; - if (clip->has_region) { + if (clip->region) { pixman_box16_t *boxes; int i; - boxes = pixman_region_rects (&clip->region); + boxes = pixman_region_rects (clip->region); for (i = 0; i < n_boxes; ++i) { if (!_cairo_clip_rect_to_user(gstate, boxes[i].x1, boxes[i].y1, boxes[i].x2 - boxes[i].x1, @@ -655,14 +635,10 @@ _cairo_clip_copy_rectangle_list (cairo_clip_t *clip, cairo_gstate_t *gstate) } } else { cairo_rectangle_int16_t extents; - if (_cairo_surface_get_extents (_cairo_gstate_get_target (gstate), - &extents) != CAIRO_STATUS_SUCCESS) { - free (rectangles); - return (cairo_rectangle_list_t*) &_cairo_rectangles_nil; - } - if (! _cairo_clip_rect_to_user(gstate, extents.x, extents.y, - extents.width, extents.height, - rectangles)) { + _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; diff --git a/gfx/cairo/cairo/src/cairo-color.c b/gfx/cairo/cairo/src/cairo-color.c index 50a9a1c26d3d..ad6316e10efe 100644 --- a/gfx/cairo/cairo/src/cairo-color.c +++ b/gfx/cairo/cairo/src/cairo-color.c @@ -160,13 +160,3 @@ _cairo_color_get_rgba_premultiplied (cairo_color_t *color, *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; -} diff --git a/gfx/cairo/cairo/src/cairo-debug.c b/gfx/cairo/cairo/src/cairo-debug.c index 6a50353ca327..7c299325f250 100644 --- a/gfx/cairo/cairo/src/cairo-debug.c +++ b/gfx/cairo/cairo/src/cairo-debug.c @@ -59,11 +59,13 @@ 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 (); } diff --git a/gfx/cairo/cairo/src/cairo-deflate-stream.c b/gfx/cairo/cairo/src/cairo-deflate-stream.c index 38ce63961b9b..816f5c57c758 100644 --- a/gfx/cairo/cairo/src/cairo-deflate-stream.c +++ b/gfx/cairo/cairo/src/cairo-deflate-stream.c @@ -119,7 +119,7 @@ _cairo_deflate_stream_create (cairo_output_stream_t *output) 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, @@ -130,10 +130,8 @@ _cairo_deflate_stream_create (cairo_output_stream_t *output) 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; diff --git a/gfx/cairo/cairo/src/cairo-directfb-surface.c b/gfx/cairo/cairo/src/cairo-directfb-surface.c index fa31b0631ccf..686510d61ed0 100644 --- a/gfx/cairo/cairo/src/cairo-directfb-surface.c +++ b/gfx/cairo/cairo/src/cairo-directfb-surface.c @@ -35,9 +35,10 @@ * Claudio Ciccani */ -#include "cairoint.h" - -#include "cairo-directfb.h" +#include +#include +#include +#include #include @@ -46,6 +47,9 @@ #include #include +#include "cairo-directfb.h" +#include "cairoint.h" + /* * Rectangle causes problems (see bugs 361377, 359553, 359243 in Gnome BTS). @@ -333,7 +337,7 @@ _directfb_acquire_surface (cairo_directfb_surface_t *surface, 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; @@ -1511,17 +1515,6 @@ _cairo_directfb_surface_show_glyphs ( void *abstract_dst, #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*/ @@ -1571,9 +1564,7 @@ static cairo_surface_backend_t cairo_directfb_surface_backend = { #else NULL, /* show_glyphs */ #endif - NULL, /* snapshot */ - _cairo_directfb_surface_is_similar, - NULL /* reset */ + NULL /* snapshot */ }; diff --git a/gfx/cairo/cairo/src/cairo-directfb.h b/gfx/cairo/cairo/src/cairo-directfb.h index 5b35a443d58d..795a0dc167bc 100644 --- a/gfx/cairo/cairo/src/cairo-directfb.h +++ b/gfx/cairo/cairo/src/cairo-directfb.h @@ -41,8 +41,6 @@ #ifdef CAIRO_HAS_DIRECTFB_SURFACE -#include - CAIRO_BEGIN_DECLS cairo_public cairo_surface_t * diff --git a/gfx/cairo/cairo/src/cairo-features.h.in b/gfx/cairo/cairo/src/cairo-features.h.in index 0ea7bd923dd9..84fb3e5a8ef7 100644 --- a/gfx/cairo/cairo/src/cairo-features.h.in +++ b/gfx/cairo/cairo/src/cairo-features.h.in @@ -53,9 +53,9 @@ #define CAIRO_VERSION_MAJOR 1 #define CAIRO_VERSION_MINOR 4 -#define CAIRO_VERSION_MICRO 10 +#define CAIRO_VERSION_MICRO 2 -#define CAIRO_VERSION_STRING "1.4.10" +#define CAIRO_VERSION_STRING "1.4.2" @PS_SURFACE_FEATURE@ @@ -65,8 +65,6 @@ @XLIB_SURFACE_FEATURE@ -@XLIB_XRENDER_SURFACE_FEATURE@ - @QUARTZ_SURFACE_FEATURE@ @XCB_SURFACE_FEATURE@ diff --git a/gfx/cairo/cairo/src/cairo-font-options.c b/gfx/cairo/cairo/src/cairo-font-options.c index 33b021da1126..316299b0574f 100644 --- a/gfx/cairo/cairo/src/cairo-font-options.c +++ b/gfx/cairo/cairo/src/cairo-font-options.c @@ -36,7 +36,7 @@ #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, @@ -52,7 +52,7 @@ static const cairo_font_options_t _cairo_font_options_nil = { 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; @@ -89,7 +89,7 @@ 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); @@ -113,14 +113,10 @@ slim_hidden_def (cairo_font_options_create); 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); @@ -137,7 +133,7 @@ cairo_font_options_copy (const cairo_font_options_t *original) 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); @@ -156,12 +152,11 @@ slim_hidden_def (cairo_font_options_destroy); 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: @@ -177,7 +172,7 @@ 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) @@ -245,7 +240,7 @@ 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; @@ -281,7 +276,7 @@ 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; @@ -317,7 +312,7 @@ 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; @@ -353,7 +348,7 @@ 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; diff --git a/gfx/cairo/cairo/src/cairo-font-face.c b/gfx/cairo/cairo/src/cairo-font.c similarity index 98% rename from gfx/cairo/cairo/src/cairo-font-face.c rename to gfx/cairo/cairo/src/cairo-font.c index 3b6dab3b6a53..cacc5899da95 100644 --- a/gfx/cairo/cairo/src/cairo-font-face.c +++ b/gfx/cairo/cairo/src/cairo-font.c @@ -59,8 +59,6 @@ void _cairo_font_face_init (cairo_font_face_t *font_face, const cairo_font_face_backend_t *backend) { - CAIRO_MUTEX_INITIALIZE (); - font_face->status = CAIRO_STATUS_SUCCESS; font_face->ref_count = 1; font_face->backend = backend; @@ -68,6 +66,10 @@ _cairo_font_face_init (cairo_font_face_t *font_face, _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 @@ -455,11 +457,6 @@ _cairo_toy_font_face_scaled_font_create (void *abstract_font_face { cairo_toy_font_face_t *font_face = abstract_font_face; const cairo_scaled_font_backend_t * backend = CAIRO_SCALED_FONT_BACKEND_DEFAULT; - cairo_status_t status; - - status = cairo_font_options_status ((cairo_font_options_t *) options); - if (status) - return status; return backend->create_toy (font_face, font_matrix, ctm, options, scaled_font); diff --git a/gfx/cairo/cairo/src/cairo-freelist-private.h b/gfx/cairo/cairo/src/cairo-freelist-private.h index 7e2036c23b02..41855f7ebc10 100644 --- a/gfx/cairo/cairo/src/cairo-freelist-private.h +++ b/gfx/cairo/cairo/src/cairo-freelist-private.h @@ -26,6 +26,8 @@ #include /* 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; diff --git a/gfx/cairo/cairo/src/cairo-freelist.c b/gfx/cairo/cairo/src/cairo-freelist.c index 3887f4b5f0ea..eed1934cfbb3 100644 --- a/gfx/cairo/cairo/src/cairo-freelist.c +++ b/gfx/cairo/cairo/src/cairo-freelist.c @@ -19,9 +19,8 @@ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE * OF THIS SOFTWARE. */ - -#include "cairoint.h" - +#include +#include #include "cairo-freelist-private.h" void diff --git a/gfx/cairo/cairo/src/cairo-ft-font.c b/gfx/cairo/cairo/src/cairo-ft-font.c index 13cc03fb62a9..6174d1415c16 100644 --- a/gfx/cairo/cairo/src/cairo-ft-font.c +++ b/gfx/cairo/cairo/src/cairo-ft-font.c @@ -37,12 +37,10 @@ * Carl Worth */ -#include "cairoint.h" +#include #include "cairo-ft-private.h" -#include - #include #include @@ -64,9 +62,11 @@ */ #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 @@ -156,6 +156,8 @@ typedef struct _cairo_ft_unscaled_font_map { 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) @@ -259,7 +261,6 @@ _cairo_ft_unscaled_font_map_lock (void) if (cairo_ft_unscaled_font_map == NULL) { CAIRO_MUTEX_UNLOCK (_cairo_ft_unscaled_font_map_mutex); - _cairo_error (CAIRO_STATUS_NO_MEMORY); return NULL; } } @@ -332,16 +333,14 @@ _cairo_ft_unscaled_font_init (cairo_ft_unscaled_font_t *unscaled, 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; @@ -376,7 +375,7 @@ _cairo_ft_unscaled_font_fini (cairo_ft_unscaled_font_t *unscaled) unscaled->filename = NULL; } - CAIRO_MUTEX_FINI (unscaled->mutex); + CAIRO_MUTEX_FINI (&unscaled->mutex); } static int @@ -420,8 +419,8 @@ _cairo_ft_unscaled_font_create_for_pattern (FcPattern *pattern) if (_cairo_hash_table_lookup (font_map->hash_table, &key.base.hash_entry, (cairo_hash_entry_t **) &unscaled)) { - _cairo_unscaled_font_reference (&unscaled->base); _cairo_ft_unscaled_font_map_unlock (); + _cairo_unscaled_font_reference (&unscaled->base); return unscaled; } @@ -557,7 +556,6 @@ _cairo_ft_unscaled_font_lock_face (cairo_ft_unscaled_font_t *unscaled) &face) != FT_Err_Ok) { CAIRO_MUTEX_UNLOCK (unscaled->mutex); - _cairo_error (CAIRO_STATUS_NO_MEMORY); return NULL; } @@ -616,7 +614,7 @@ _compute_transform (cairo_ft_font_transform_t *sf, /* 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) { @@ -631,7 +629,7 @@ _cairo_ft_unscaled_font_set_scale (cairo_ft_unscaled_font_t *unscaled, 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; @@ -660,6 +658,7 @@ _cairo_ft_unscaled_font_set_scale (cairo_ft_unscaled_font_t *unscaled, 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) { @@ -669,14 +668,17 @@ _cairo_ft_unscaled_font_set_scale (cairo_ft_unscaled_font_t *unscaled, 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; @@ -705,13 +707,8 @@ _cairo_ft_unscaled_font_set_scale (cairo_ft_unscaled_font_t *unscaled, 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 @@ -756,10 +753,8 @@ _get_bitmap_surface (FT_Bitmap *bitmap, assert (stride == bitmap->pitch); } else { data = malloc (stride * height); - if (!data) { - _cairo_error (CAIRO_STATUS_NO_MEMORY); + if (!data) return CAIRO_STATUS_NO_MEMORY; - } if (stride == bitmap->pitch) { memcpy (data, bitmap->buffer, stride * height); @@ -806,10 +801,8 @@ _get_bitmap_surface (FT_Bitmap *bitmap, data = bitmap->buffer; } else { data = malloc (stride * height); - if (!data) { - _cairo_error (CAIRO_STATUS_NO_MEMORY); + if (!data) return CAIRO_STATUS_NO_MEMORY; - } memcpy (data, bitmap->buffer, stride * height); } format = CAIRO_FORMAT_A8; @@ -848,12 +841,6 @@ _get_bitmap_surface (FT_Bitmap *bitmap, 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) { @@ -918,9 +905,6 @@ _get_bitmap_surface (FT_Bitmap *bitmap, 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; } @@ -1051,7 +1035,6 @@ _render_glyph_outline (FT_Face face, bitmap.buffer = calloc (1, stride * bitmap.rows); if (bitmap.buffer == NULL) { - _cairo_error (CAIRO_STATUS_NO_MEMORY); return CAIRO_STATUS_NO_MEMORY; } @@ -1059,7 +1042,6 @@ _render_glyph_outline (FT_Face face, if (FT_Outline_Get_Bitmap (glyphslot->library, outline, &bitmap) != 0) { free (bitmap.buffer); - _cairo_error (CAIRO_STATUS_NO_MEMORY); return CAIRO_STATUS_NO_MEMORY; } @@ -1097,10 +1079,8 @@ _render_glyph_bitmap (FT_Face face, * we avoid the FT_LOAD_NO_RECURSE flag. */ error = FT_Render_Glyph (glyphslot, FT_RENDER_MODE_NORMAL); - if (error) { - _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) @@ -1198,33 +1178,24 @@ _transform_glyph_bitmap (cairo_matrix_t * shape, /* 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. */ @@ -1474,7 +1445,6 @@ _cairo_ft_scaled_font_create (cairo_ft_unscaled_font_t *unscaled, 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) @@ -1483,7 +1453,6 @@ _cairo_ft_scaled_font_create (cairo_ft_unscaled_font_t *unscaled, 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; } @@ -1496,26 +1465,13 @@ _cairo_ft_scaled_font_create (cairo_ft_unscaled_font_t *unscaled, _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; - } - - 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_scaled_font_init (&scaled_font->base, + font_face, + font_matrix, ctm, options, + &cairo_ft_scaled_font_backend); + _cairo_ft_unscaled_font_set_scale (unscaled, + &scaled_font->base.scale); metrics = &face->size->metrics; @@ -1593,10 +1549,8 @@ _cairo_ft_scaled_font_create_toy (cairo_toy_font_face_t *toy_face, 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) { @@ -1666,7 +1620,6 @@ _cairo_ft_scaled_font_create_toy (cairo_toy_font_face_t *toy_face, *font = new_font; return CAIRO_STATUS_SUCCESS; } else { - _cairo_error (CAIRO_STATUS_NO_MEMORY); return CAIRO_STATUS_NO_MEMORY; } } @@ -1691,10 +1644,8 @@ _move_to (FT_Vector *to, void *closure) 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; } @@ -1708,8 +1659,7 @@ _line_to (FT_Vector *to, void *closure) 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; } @@ -1725,9 +1675,7 @@ _conic_to (FT_Vector *control, FT_Vector *to, void *closure) 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); @@ -1741,11 +1689,10 @@ _conic_to (FT_Vector *control, FT_Vector *to, void *closure) 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; } @@ -1768,11 +1715,10 @@ _cubic_to (FT_Vector *control1, FT_Vector *control2, 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; } @@ -1797,7 +1743,6 @@ _decompose_glyph_outline (FT_Face face, FT_GlyphSlot glyph; cairo_path_fixed_t *path; - cairo_status_t status; path = _cairo_path_fixed_create (); if (!path) @@ -1807,17 +1752,9 @@ _decompose_glyph_outline (FT_Face face, /* 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; @@ -1861,16 +1798,14 @@ _cairo_ft_scaled_glyph_init (void *abstract_font, 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; @@ -2016,12 +1951,9 @@ _cairo_ft_scaled_glyph_init (void *abstract_font, } 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; @@ -2045,7 +1977,6 @@ _cairo_ft_scaled_glyph_init (void *abstract_font, 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 @@ -2255,12 +2186,10 @@ _cairo_ft_font_face_scaled_font_create (void *abstract_face, &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 = { @@ -2273,32 +2202,23 @@ 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); @@ -2456,8 +2376,10 @@ cairo_ft_font_face_create_for_pattern (FcPattern *pattern) if (font_face) return font_face; - else + else { + _cairo_error (CAIRO_STATUS_NO_MEMORY); return (cairo_font_face_t *)&_cairo_font_face_nil; + } } /** @@ -2507,10 +2429,12 @@ cairo_ft_font_face_create_for_ft_face (FT_Face face, 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; + } } /** @@ -2548,7 +2472,6 @@ 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; @@ -2559,13 +2482,8 @@ cairo_ft_scaled_font_lock_face (cairo_scaled_font_t *abstract_font) 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 diff --git a/gfx/cairo/cairo/src/cairo-glitz-surface.c b/gfx/cairo/cairo/src/cairo-glitz-surface.c index ab15404291e5..b9e4f72d2b7c 100644 --- a/gfx/cairo/cairo/src/cairo-glitz-surface.c +++ b/gfx/cairo/cairo/src/cairo-glitz-surface.c @@ -33,8 +33,7 @@ typedef struct _cairo_glitz_surface { glitz_surface_t *surface; glitz_format_t *format; - cairo_bool_t has_clip; - pixman_region16_t clip; + pixman_region16_t *clip; } cairo_glitz_surface_t; static const cairo_surface_backend_t * @@ -45,9 +44,10 @@ _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); - pixman_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); @@ -208,7 +208,7 @@ _cairo_glitz_surface_get_image (cairo_glitz_surface_t *surface, } /* 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); @@ -221,12 +221,12 @@ _cairo_glitz_surface_get_image (cairo_glitz_surface_t *surface, glitz_buffer_destroy (buffer); /* restore the clip, if any */ - if (surface->has_clip) { + if (surface->clip) { glitz_box_t *box; int n; - box = (glitz_box_t *) pixman_region_rects (&surface->clip); - n = pixman_region_num_rects (&surface->clip); + 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); } @@ -668,7 +668,7 @@ _cairo_glitz_pattern_acquire_surface (cairo_pattern_t *pattern, } glitz_set_pixels (src->surface, 0, 0, gradient->n_stops, 1, - (glitz_pixel_format_t *)&format, buffer); + &format, buffer); glitz_buffer_destroy (buffer); @@ -822,16 +822,11 @@ _cairo_glitz_pattern_acquire_surfaces (cairo_pattern_t *src, 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, @@ -846,9 +841,7 @@ _cairo_glitz_pattern_acquire_surfaces (cairo_pattern_t *src, 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, @@ -1009,8 +1002,7 @@ _cairo_glitz_surface_fill_rectangles (void *abstract_dst, _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; @@ -1079,9 +1071,7 @@ _cairo_glitz_surface_composite_trapezoids (cairo_operator_t op, 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, @@ -1293,32 +1283,26 @@ _cairo_glitz_surface_set_clip_region (void *abstract_surface, glitz_box_t *box; int n; - if (!surface->has_clip) { - pixman_region_init (&surface->clip); - surface->has_clip = TRUE; - } - - if (pixman_region_copy (&surface->clip, region) != - PIXMAN_REGION_STATUS_SUCCESS) - { - pixman_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); + if (!surface->clip) + { + surface->clip = pixman_region_create (); + if (!surface->clip) + return CAIRO_STATUS_NO_MEMORY; + } + pixman_region_copy (surface->clip, region); + 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); } else { glitz_surface_set_clip_region (surface->surface, 0, 0, NULL, 0); - if (surface->has_clip) { - pixman_region_fini (&surface->clip); - surface->has_clip = FALSE; - } + if (surface->clip) + pixman_region_destroy (surface->clip); + + surface->clip = NULL; } return CAIRO_STATUS_SUCCESS; @@ -2188,33 +2172,6 @@ _cairo_glitz_surface_flush (void *abstract_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, @@ -2237,18 +2194,7 @@ static const cairo_surface_backend_t cairo_glitz_surface_backend = { _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 * @@ -2294,9 +2240,9 @@ cairo_glitz_surface_create (glitz_surface_t *surface) 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; } diff --git a/gfx/cairo/cairo/src/cairo-gstate.c b/gfx/cairo/cairo/src/cairo-gstate.c index fc8c5456902a..b75a90baab7e 100644 --- a/gfx/cairo/cairo/src/cairo-gstate.c +++ b/gfx/cairo/cairo/src/cairo-gstate.c @@ -35,6 +35,8 @@ * Carl D. Worth */ +#include + #include "cairoint.h" #include "cairo-clip-private.h" @@ -62,8 +64,6 @@ 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; @@ -91,12 +91,13 @@ _cairo_gstate_init (cairo_gstate_t *gstate, _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; } /** @@ -130,9 +131,7 @@ _cairo_gstate_init_copy (cairo_gstate_t *gstate, cairo_gstate_t *other) _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 */ @@ -161,7 +160,7 @@ _cairo_gstate_fini (cairo_gstate_t *gstate) 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; @@ -176,7 +175,7 @@ _cairo_gstate_fini (cairo_gstate_t *gstate) gstate->source = NULL; } -static void +void _cairo_gstate_destroy (cairo_gstate_t *gstate) { if (gstate == NULL) @@ -198,7 +197,7 @@ _cairo_gstate_destroy (cairo_gstate_t *gstate) * 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; @@ -219,55 +218,6 @@ _cairo_gstate_clone (cairo_gstate_t *other) 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) @@ -302,11 +252,9 @@ _cairo_gstate_recursive_apply_clip_path (cairo_gstate_t *gstate, * 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); @@ -321,18 +269,14 @@ _cairo_gstate_redirect_target (cairo_gstate_t *gstate, cairo_surface_t *child) * 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; } /** @@ -412,7 +356,7 @@ _cairo_gstate_set_source (cairo_gstate_t *gstate, 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; @@ -563,24 +507,6 @@ _cairo_gstate_set_dash (cairo_gstate_t *gstate, const double *dash, int num_dash 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) { @@ -657,16 +583,13 @@ _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; @@ -690,39 +613,49 @@ _cairo_gstate_set_matrix (cairo_gstate_t *gstate, 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 @@ -764,7 +697,7 @@ _cairo_gstate_stroke_to_path (cairo_gstate_t *gstate) } */ -static cairo_status_t +static void _cairo_gstate_copy_transformed_pattern (cairo_gstate_t *gstate, cairo_pattern_t *pattern, cairo_pattern_t *original, @@ -772,12 +705,8 @@ _cairo_gstate_copy_transformed_pattern (cairo_gstate_t *gstate, { 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) { @@ -787,26 +716,25 @@ _cairo_gstate_copy_transformed_pattern (cairo_gstate_t *gstate, _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 @@ -822,9 +750,7 @@ _cairo_gstate_paint (cairo_gstate_t *gstate) 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, @@ -931,22 +857,16 @@ _cairo_gstate_mask (cairo_gstate_t *gstate, 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 (&mask_pattern.base); -CLEANUP_SOURCE: _cairo_pattern_fini (&source_pattern.base); + _cairo_pattern_fini (&mask_pattern.base); return status; } @@ -967,10 +887,7 @@ _cairo_gstate_stroke (cairo_gstate_t *gstate, cairo_path_fixed_t *path) 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, @@ -1037,9 +954,7 @@ _cairo_gstate_fill (cairo_gstate_t *gstate, cairo_path_fixed_t *path) 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, @@ -1086,13 +1001,29 @@ BAIL: 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 @@ -1194,9 +1125,7 @@ _cairo_gstate_fill_extents (cairo_gstate_t *gstate, 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 @@ -1261,15 +1190,12 @@ _cairo_gstate_select_font_face (cairo_gstate_t *gstate, 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; @@ -1304,13 +1230,15 @@ _cairo_gstate_get_font_matrix (cairo_gstate_t *gstate, *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 @@ -1429,19 +1357,17 @@ _cairo_gstate_get_scaled_font (cairo_gstate_t *gstate, static cairo_status_t _cairo_gstate_ensure_font_face (cairo_gstate_t *gstate) { - cairo_font_face_t *font_face; + if (!gstate->font_face) { + cairo_font_face_t *font_face; - if (gstate->font_face != NULL) - return gstate->font_face->status; - - - 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; } @@ -1451,10 +1377,9 @@ _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) @@ -1463,16 +1388,13 @@ _cairo_gstate_ensure_scaled_font (cairo_gstate_t *gstate) 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; } @@ -1487,7 +1409,7 @@ _cairo_gstate_get_font_extents (cairo_gstate_t *gstate, cairo_scaled_font_extents (gstate->scaled_font, extents); - return cairo_scaled_font_status (gstate->scaled_font); + return CAIRO_STATUS_SUCCESS; } cairo_status_t @@ -1504,8 +1426,13 @@ _cairo_gstate_text_to_glyphs (cairo_gstate_t *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 @@ -1541,7 +1468,7 @@ _cairo_gstate_glyph_extents (cairo_gstate_t *gstate, 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))) @@ -1578,9 +1505,7 @@ _cairo_gstate_show_glyphs (cairo_gstate_t *gstate, _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, @@ -1591,7 +1516,6 @@ _cairo_gstate_show_glyphs (cairo_gstate_t *gstate, _cairo_pattern_fini (&source_pattern.base); -CLEANUP_GLYPHS: if (transformed_glyphs != stack_transformed_glyphs) free (transformed_glyphs); diff --git a/gfx/cairo/cairo/src/cairo-hash-private.h b/gfx/cairo/cairo/src/cairo-hash-private.h index 8ed3ba83aa3c..617b8410dbdd 100644 --- a/gfx/cairo/cairo/src/cairo-hash-private.h +++ b/gfx/cairo/cairo/src/cairo-hash-private.h @@ -39,13 +39,51 @@ #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); diff --git a/gfx/cairo/cairo/src/cairo-hash.c b/gfx/cairo/cairo/src/cairo-hash.c index 99343754f3f3..948cd232f898 100644 --- a/gfx/cairo/cairo/src/cairo-hash.c +++ b/gfx/cairo/cairo/src/cairo-hash.c @@ -115,7 +115,7 @@ static const cairo_hash_table_arrangement_t hash_table_arrangements [] = { { 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; @@ -481,12 +481,8 @@ _cairo_hash_table_insert (cairo_hash_table_t *hash_table, 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; } @@ -565,9 +561,6 @@ _cairo_hash_table_foreach (cairo_hash_table_t *hash_table, * 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); - } } diff --git a/gfx/cairo/cairo/src/cairo-image-surface.c b/gfx/cairo/cairo/src/cairo-image-surface.c index ad41a4cba97b..627901216b0b 100644 --- a/gfx/cairo/cairo/src/cairo-image-surface.c +++ b/gfx/cairo/cairo/src/cairo-image-surface.c @@ -36,7 +36,7 @@ #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, @@ -131,7 +131,7 @@ _cairo_image_surface_create_for_pixman_image (pixman_image_t *pixman_image, /* Try to recover a cairo_format_t from a pixman_format * by looking at the bpp and masks values. */ -static cairo_internal_format_t +static cairo_format_t _cairo_format_from_pixman_format (pixman_format_t *pixman_format) { unsigned int bpp, am, rm, gm, bm; @@ -167,7 +167,7 @@ _cairo_format_from_pixman_format (pixman_format_t *pixman_format) rm == 0xf800 && gm == 0x07e0 && bm == 0x001f) - return CAIRO_INTERNAL_FORMAT_RGB16_565; + return CAIRO_FORMAT_RGB16_565; break; case 8: if (am == 0xff && @@ -212,23 +212,28 @@ _cairo_image_surface_create_with_masks (unsigned char *data, int stride) { cairo_surface_t *surface; - pixman_format_t pixman_format; - pixman_image_t *pixman_image; - cairo_format_t cairo_format; + pixman_format_t *pixman_format; + pixman_image_t *pixman_image; + cairo_format_t cairo_format; - pixman_format_init_masks (&pixman_format, - format->bpp, - format->alpha_mask, - format->red_mask, - format->green_mask, - format->blue_mask); + pixman_format = pixman_format_create_masks (format->bpp, + format->alpha_mask, + format->red_mask, + format->green_mask, + format->blue_mask); - cairo_format = _cairo_format_from_pixman_format (&pixman_format); + if (pixman_format == NULL) { + _cairo_error (CAIRO_STATUS_NO_MEMORY); + return (cairo_surface_t*) &_cairo_surface_nil; + } - pixman_image = pixman_image_create_for_data ((pixman_bits_t *) data, - &pixman_format, + 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; @@ -236,33 +241,28 @@ _cairo_image_surface_create_with_masks (unsigned char *data, surface = _cairo_image_surface_create_for_pixman_image (pixman_image, cairo_format); - if (cairo_surface_status (surface)) { - pixman_image_destroy (pixman_image); - } return surface; } -static void -_init_pixman_format (pixman_format_t *pixman_format, cairo_format_t format) +static pixman_format_t * +_create_pixman_format (cairo_format_t format) { - int ret; switch (format) { case CAIRO_FORMAT_A1: - ret = pixman_format_init (pixman_format, PIXMAN_FORMAT_NAME_A1); + return pixman_format_create (PIXMAN_FORMAT_NAME_A1); break; case CAIRO_FORMAT_A8: - ret = pixman_format_init (pixman_format, PIXMAN_FORMAT_NAME_A8); + return pixman_format_create (PIXMAN_FORMAT_NAME_A8); break; case CAIRO_FORMAT_RGB24: - ret = pixman_format_init (pixman_format, PIXMAN_FORMAT_NAME_RGB24); + return pixman_format_create (PIXMAN_FORMAT_NAME_RGB24); break; case CAIRO_FORMAT_ARGB32: default: - ret = pixman_format_init (pixman_format, PIXMAN_FORMAT_NAME_ARGB32); + return pixman_format_create (PIXMAN_FORMAT_NAME_ARGB32); break; } - assert (ret); } /** @@ -290,27 +290,31 @@ cairo_image_surface_create (cairo_format_t format, int width, int height) { - cairo_surface_t *surface; - pixman_format_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; } - _init_pixman_format (&pixman_format, 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 (pixman_format, width, height); + + pixman_format_destroy (pixman_format); - pixman_image = pixman_image_create (&pixman_format, width, height); 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_destroy (pixman_image); - } return surface; } @@ -365,29 +369,32 @@ cairo_image_surface_create_for_data (unsigned char *data, int height, int stride) { - cairo_surface_t *surface; - pixman_format_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; - _init_pixman_format (&pixman_format, 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_for_data ((pixman_bits_t *) data, - &pixman_format, + 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_destroy (pixman_image); - } return surface; } @@ -560,7 +567,7 @@ _cairo_content_from_format (cairo_format_t format) 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: @@ -683,8 +690,7 @@ _cairo_image_surface_set_matrix (cairo_image_surface_t *surface, _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; } @@ -901,10 +907,8 @@ _cairo_image_surface_fill_rectangles (void *abstract_surface, pixman_color.alpha = color->alpha_short; /* XXX: The pixman_rectangle_t cast is evil... it needs to go away somehow. */ - if (pixman_fill_rectangles (_pixman_operator(op), surface->pixman_image, - &pixman_color, - (pixman_rectangle_t *) rects, num_rects)) - return CAIRO_STATUS_NO_MEMORY; + pixman_fill_rectangles (_pixman_operator(op), surface->pixman_image, + &pixman_color, (pixman_rectangle_t *) rects, num_rects); return CAIRO_STATUS_SUCCESS; } @@ -928,11 +932,10 @@ _cairo_image_surface_composite_trapezoids (cairo_operator_t op, cairo_image_surface_t *src; cairo_int_status_t status; pixman_image_t *mask; - pixman_format_t format; + pixman_format_t *format; pixman_bits_t *mask_data; - int mask_stride; - int mask_bpp; - int ret; + int mask_stride; + int mask_bpp; /* Special case adding trapezoids onto a mask surface; we want to avoid * creating an intermediate temporary mask unecessarily. @@ -971,8 +974,7 @@ _cairo_image_surface_composite_trapezoids (cairo_operator_t op, switch (antialias) { case CAIRO_ANTIALIAS_NONE: - ret = pixman_format_init (&format, PIXMAN_FORMAT_NAME_A1); - assert (ret); + format = pixman_format_create (PIXMAN_FORMAT_NAME_A1); mask_stride = (width + 31)/8; mask_bpp = 1; break; @@ -980,23 +982,28 @@ _cairo_image_surface_composite_trapezoids (cairo_operator_t op, case CAIRO_ANTIALIAS_SUBPIXEL: case CAIRO_ANTIALIAS_DEFAULT: default: - ret = pixman_format_init (&format, PIXMAN_FORMAT_NAME_A8); - 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_for_data (mask_data, &format, width, height, + /* 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); - if (mask == NULL) { + pixman_format_destroy (format); + if (!mask) { status = CAIRO_STATUS_NO_MEMORY; goto CLEANUP_IMAGE_DATA; } @@ -1040,8 +1047,7 @@ _cairo_image_surface_set_clip_region (void *abstract_surface, { cairo_image_surface_t *surface = (cairo_image_surface_t *) abstract_surface; - if (pixman_image_set_clip_region (surface->pixman_image, region)) - return CAIRO_STATUS_NO_MEMORY; + pixman_image_set_clip_region (surface->pixman_image, region); surface->has_clip = region != NULL; @@ -1062,28 +1068,6 @@ _cairo_image_surface_get_extents (void *abstract_surface, 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 @@ -1115,22 +1099,7 @@ const cairo_surface_backend_t cairo_image_surface_backend = { _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 diff --git a/gfx/cairo/cairo/src/cairo-matrix.c b/gfx/cairo/cairo/src/cairo-matrix.c index c85b02768acc..b689f2aaff76 100644 --- a/gfx/cairo/cairo/src/cairo-matrix.c +++ b/gfx/cairo/cairo/src/cairo-matrix.c @@ -35,6 +35,7 @@ */ #define _GNU_SOURCE +#include #include "cairoint.h" @@ -197,7 +198,7 @@ slim_hidden_def(cairo_matrix_init_scale); * @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. **/ @@ -495,7 +496,7 @@ _cairo_matrix_compute_determinant (const cairo_matrix_t *matrix, } /* 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) { @@ -535,6 +536,8 @@ _cairo_matrix_compute_scale_factors (const cairo_matrix_t *matrix, *sy = major; } } + + return CAIRO_STATUS_SUCCESS; } cairo_bool_t diff --git a/gfx/cairo/cairo/src/cairo-meta-surface.c b/gfx/cairo/cairo/src/cairo-meta-surface.c index 8dbd6084167a..e196df29cf3a 100644 --- a/gfx/cairo/cairo/src/cairo-meta-surface.c +++ b/gfx/cairo/cairo/src/cairo-meta-surface.c @@ -212,11 +212,7 @@ 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 = @@ -652,9 +648,6 @@ _cairo_meta_surface_replay (cairo_surface_t *surface, 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; @@ -675,9 +668,7 @@ _cairo_meta_surface_replay (cairo_surface_t *surface, 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; } @@ -763,7 +754,7 @@ _cairo_meta_surface_replay (cairo_surface_t *surface, /* 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, @@ -782,7 +773,7 @@ _cairo_meta_surface_replay (cairo_surface_t *surface, break; } - _cairo_clip_reset (&clip); + _cairo_clip_fini (&clip); return status; } diff --git a/gfx/cairo/cairo/src/cairo-mutex-list-private.h b/gfx/cairo/cairo/src/cairo-mutex-list-private.h deleted file mode 100644 index abb4a9a3db3e..000000000000 --- a/gfx/cairo/cairo/src/cairo-mutex-list-private.h +++ /dev/null @@ -1,51 +0,0 @@ -/* cairo - a vector graphics library with display and print output - * - * Copyright © 2007 Mathias Hasselmann - * - * 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. - * - * Contributor(s): - * Mathias Hasselmann - */ - - -CAIRO_MUTEX_DECLARE (_cairo_pattern_solid_pattern_cache_lock); -CAIRO_MUTEX_DECLARE (_cairo_pattern_solid_surface_cache_lock); - -CAIRO_MUTEX_DECLARE (_cairo_font_face_mutex); -CAIRO_MUTEX_DECLARE (_cairo_scaled_font_map_mutex); - -#if CAIRO_HAS_FT_FONT -CAIRO_MUTEX_DECLARE (_cairo_ft_unscaled_font_map_mutex); -#endif - -#if CAIRO_HAS_XLIB_SURFACE -CAIRO_MUTEX_DECLARE (_cairo_xlib_display_mutex); -#endif - - -/* Undefine, to err on unintended inclusion */ -#undef CAIRO_MUTEX_DECLARE diff --git a/gfx/cairo/cairo/src/cairo-mutex-private.h b/gfx/cairo/cairo/src/cairo-mutex-private.h deleted file mode 100644 index 88e88bb0f5ce..000000000000 --- a/gfx/cairo/cairo/src/cairo-mutex-private.h +++ /dev/null @@ -1,175 +0,0 @@ -/* cairo - a vector graphics library with display and print output - * - * Copyright © 2002 University of Southern California - * Copyright © 2005,2007 Red Hat, Inc. - * Copyright © 2007 Mathias Hasselmann - * - * 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 - * Mathias Hasselmann - * Behdad Esfahbod - */ - -#ifndef CAIRO_MUTEX_PRIVATE_H -#define CAIRO_MUTEX_PRIVATE_H - -#if HAVE_CONFIG_H -#include "config.h" -#endif - -#include - -#include "cairo-mutex-type-private.h" - -/* Only the following three are mandatory at this point */ -#ifndef CAIRO_MUTEX_LOCK -# error "CAIRO_MUTEX_LOCK not defined. Check cairo-mutex-type-private.h." -#endif -#ifndef CAIRO_MUTEX_UNLOCK -# error "CAIRO_MUTEX_UNLOCK not defined. Check cairo-mutex-type-private.h." -#endif -#ifndef CAIRO_MUTEX_NIL_INITIALIZER -# error "CAIRO_MUTEX_NIL_INITIALIZER not defined. Check cairo-mutex-type-private.h." -#endif - -CAIRO_BEGIN_DECLS - - -#define CAIRO_MUTEX_DECLARE(mutex) extern cairo_mutex_t mutex -#include "cairo-mutex-list-private.h" -#undef CAIRO_MUTEX_DECLARE - - -/* make sure implementations don't fool us: we decide these ourself */ -#undef _CAIRO_MUTEX_USE_STATIC_INITIALIZER -#undef _CAIRO_MUTEX_USE_STATIC_FINALIZER - - -#ifdef CAIRO_MUTEX_INIT - -/* If CAIRO_MUTEX_INIT is defined, we may need to initialize all - * static mutex'es. */ -# ifndef CAIRO_MUTEX_INITIALIZE -# define CAIRO_MUTEX_INITIALIZE() do { \ - if (!_cairo_mutex_initialized) \ - _cairo_mutex_initialize (); \ - } while(0) - - cairo_private void _cairo_mutex_initialize (void); - - /* and make sure we implement the above */ -# define _CAIRO_MUTEX_USE_STATIC_INITIALIZER 1 -# endif /* CAIRO_MUTEX_INITIALIZE */ - -#else /* no CAIRO_MUTEX_INIT */ - -/* Otherwise we probably don't need to initialize static mutex'es, */ -# ifndef CAIRO_MUTEX_INITIALIZE -# define CAIRO_MUTEX_INITIALIZE() CAIRO_MUTEX_NOOP -# endif /* CAIRO_MUTEX_INITIALIZE */ - -/* and dynamic ones can be initialized using the static initializer. */ -# define CAIRO_MUTEX_INIT(mutex) do { \ - cairo_mutex_t _tmp_mutex = CAIRO_MUTEX_NIL_INITIALIZER; \ - memcpy (&(mutex), &_tmp_mutex, sizeof (_tmp_mutex)); \ - } while (0) - -#endif /* CAIRO_MUTEX_INIT */ - - -#ifdef CAIRO_MUTEX_FINI - -/* If CAIRO_MUTEX_FINI is defined, we may need to finalize all - * static mutex'es. */ -# ifndef CAIRO_MUTEX_FINALIZE -# define CAIRO_MUTEX_FINALIZE() do { \ - if (_cairo_mutex_initialized) \ - _cairo_mutex_finalize (); \ - } while(0) - - cairo_private void _cairo_mutex_finalize (void); - - /* and make sure we implement the above */ -# define _CAIRO_MUTEX_USE_STATIC_FINALIZER 1 -# endif /* CAIRO_MUTEX_FINALIZE */ - -#else /* no CAIRO_MUTEX_FINI */ - -/* Otherwise we probably don't need to finalize static mutex'es, */ -# ifndef CAIRO_MUTEX_FINALIZE -# define CAIRO_MUTEX_FINALIZE() CAIRO_MUTEX_NOOP -# endif /* CAIRO_MUTEX_FINALIZE */ - -/* neither do the dynamic ones. */ -# define CAIRO_MUTEX_FINI(mutex) CAIRO_MUTEX_NOOP1(mutex) - -#endif /* CAIRO_MUTEX_FINI */ - - -#ifndef _CAIRO_MUTEX_USE_STATIC_INITIALIZER -#define _CAIRO_MUTEX_USE_STATIC_INITIALIZER 0 -#endif -#ifndef _CAIRO_MUTEX_USE_STATIC_FINALIZER -#define _CAIRO_MUTEX_USE_STATIC_FINALIZER 0 -#endif - -/* only if using static initializer and/or finalizer define the boolean */ -#if _CAIRO_MUTEX_USE_STATIC_INITIALIZER || _CAIRO_MUTEX_USE_STATIC_FINALIZER - cairo_private extern cairo_bool_t _cairo_mutex_initialized; -#endif - - -CAIRO_END_DECLS - -/* Make sure everything we want is defined */ -#ifndef CAIRO_MUTEX_INITIALIZE -# error "CAIRO_MUTEX_INITIALIZE not defined" -#endif -#ifndef CAIRO_MUTEX_FINALIZE -# error "CAIRO_MUTEX_FINALIZE not defined" -#endif -#ifndef CAIRO_MUTEX_LOCK -# error "CAIRO_MUTEX_LOCK not defined" -#endif -#ifndef CAIRO_MUTEX_UNLOCK -# error "CAIRO_MUTEX_UNLOCK not defined" -#endif -#ifndef CAIRO_MUTEX_INIT -# error "CAIRO_MUTEX_INIT not defined" -#endif -#ifndef CAIRO_MUTEX_FINI -# error "CAIRO_MUTEX_FINI not defined" -#endif -#ifndef CAIRO_MUTEX_NIL_INITIALIZER -# error "CAIRO_MUTEX_NIL_INITIALIZER not defined" -#endif - -#endif diff --git a/gfx/cairo/cairo/src/cairo-mutex-type-private.h b/gfx/cairo/cairo/src/cairo-mutex-type-private.h deleted file mode 100644 index 59d581afadda..000000000000 --- a/gfx/cairo/cairo/src/cairo-mutex-type-private.h +++ /dev/null @@ -1,210 +0,0 @@ -/* cairo - a vector graphics library with display and print output - * - * Copyright © 2002 University of Southern California - * Copyright © 2005,2007 Red Hat, Inc. - * Copyright © 2007 Mathias Hasselmann - * - * 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 - * Mathias Hasselmann - * Behdad Esfahbod - */ - -#ifndef CAIRO_MUTEX_TYPE_PRIVATE_H -#define CAIRO_MUTEX_TYPE_PRIVATE_H - -#if HAVE_CONFIG_H -#include "config.h" -#endif - -#include - -CAIRO_BEGIN_DECLS - - -/* A fully qualified no-operation statement */ -#define CAIRO_MUTEX_NOOP do {/*no-op*/} while (0) -/* And one that evaluates it's argument once */ -#define CAIRO_MUTEX_NOOP1(expr) do { if (expr) ; } while (0) - - -/* Cairo mutex implementation: - * - * Any new mutex implementation needs to do the following: - * - * - Condition on the right header or feature. Headers are - * preferred as eg. you still can use win32 mutex implementation - * on a win32 system even if you do not compile the win32 - * surface/backend. - * - * - typedef cairo_mutex_t to the proper mutex type on your target - * system. Note that you may or may not need to use a pointer, - * depending on what kinds of initialization your mutex - * implementation supports. No trailing semicolon needed. - * You should be able to compile the following snippet (don't try - * running it): - * - * cairo_mutex_t _cairo_some_mutex; - * - * - #define CAIRO_MUTEX_LOCK(mutex) and CAIRO_MUTEX_UNLOCK(mutex) to - * proper statement to lock/unlock the mutex object passed in. - * You can (and should) assume that the mutex is already - * initialized, and is-not-already-locked/is-locked, - * respectively. Use the "do { ... } while (0)" idiom if necessary. - * No trailing semicolons are needed (in any macro you define here). - * You should be able to compile the following snippet: - * - * cairo_mutex_t _cairo_some_mutex; - * - * if (1) - * CAIRO_MUTEX_LOCK (_cairo_some_mutex); - * else - * CAIRO_MUTEX_UNLOCK (_cairo_some_mutex); - * - * - #define CAIRO_MUTEX_NIL_INITIALIZER to something that can - * initialize the cairo_mutex_t type you defined. Most of the - * time one of 0, NULL, or {} works. At this point - * you should be able to compile the following snippet: - * - * cairo_mutex_t _cairo_some_mutex = CAIRO_MUTEX_NIL_INITIALIZER; - * - * if (1) - * CAIRO_MUTEX_LOCK (_cairo_some_mutex); - * else - * CAIRO_MUTEX_UNLOCK (_cairo_some_mutex); - * - * - If the above code is not enough to initialize a mutex on - * your platform, #define CAIRO_MUTEX_INIT(mutex) to statement - * to initialize the mutex (allocate resources, etc). Such that - * you should be able to compile AND RUN the following snippet: - * - * cairo_mutex_t _cairo_some_mutex = CAIRO_MUTEX_NIL_INITIALIZER; - * - * CAIRO_MUTEX_INIT (_cairo_some_mutex); - * - * if (1) - * CAIRO_MUTEX_LOCK (_cairo_some_mutex); - * else - * CAIRO_MUTEX_UNLOCK (_cairo_some_mutex); - * - * - If you define CAIRO_MUTEX_INIT(mutex), cairo will use it to - * initialize all static mutex'es. If for any reason that should - * not happen (eg. CAIRO_MUTEX_INIT is just a faster way than - * what cairo does using CAIRO_MUTEX_NIL_INITIALIZER), then - * #define CAIRO_MUTEX_INITIALIZE() CAIRO_MUTEX_NOOP - * - * - If your system supports freeing a mutex object (deallocating - * resources, etc), then #define CAIRO_MUTEX_FINI(mutex) to do - * that. - * - * - If you define CAIRO_MUTEX_FINI(mutex), cairo will use it to - * define a finalizer function to finalize all static mutex'es. - * However, it's up to you to call CAIRO_MUTEX_FINALIZE() at - * proper places, eg. when the system is unloading the cairo library. - * So, if for any reason finalizing static mutex'es is not needed - * (eg. you never call CAIRO_MUTEX_FINALIZE), then - * #define CAIRO_MUTEX_FINALIZE() CAIRO_MUTEX_NOOP - * - * - That is all. If for any reason you think the above API is - * not enough to implement cairo_mutex_t on your system, please - * stop and write to the cairo mailing list about it. DO NOT - * poke around cairo-mutex-private.h for possible solutions. - */ - -#if CAIRO_NO_MUTEX - -/* A poor man's mutex */ - - typedef int cairo_mutex_t; - -# define CAIRO_MUTEX_INITIALIZE() CAIRO_MUTEX_NOOP -# define CAIRO_MUTEX_LOCK(mutex) do { while (mutex) ; (mutex) = 1; } while (0) -# define CAIRO_MUTEX_UNLOCK(mutex) (mutex) = 0 -# define CAIRO_MUTEX_NIL_INITIALIZER 0 - -#elif HAVE_PTHREAD_H /*******************************************************/ - -# include - - typedef pthread_mutex_t cairo_mutex_t; - -# define CAIRO_MUTEX_LOCK(mutex) pthread_mutex_lock (&(mutex)) -# define CAIRO_MUTEX_UNLOCK(mutex) pthread_mutex_unlock (&(mutex)) -# define CAIRO_MUTEX_FINI(mutex) pthread_mutex_destroy (&(mutex)) -# define CAIRO_MUTEX_FINALIZE() CAIRO_MUTEX_NOOP -# define CAIRO_MUTEX_NIL_INITIALIZER PTHREAD_MUTEX_INITIALIZER - -#elif HAVE_WINDOWS_H /*******************************************************/ - -# include - - typedef CRITICAL_SECTION cairo_mutex_t; - -# define CAIRO_MUTEX_LOCK(mutex) EnterCriticalSection (&(mutex)) -# define CAIRO_MUTEX_UNLOCK(mutex) LeaveCriticalSection (&(mutex)) -# define CAIRO_MUTEX_INIT(mutex) InitializeCriticalSection (&(mutex)) -# define CAIRO_MUTEX_FINI(mutex) DeleteCriticalSection (&(mutex)) -# define CAIRO_MUTEX_NIL_INITIALIZER { NULL, 0, 0, NULL, NULL, 0 } - -#elif defined __OS2__ /******************************************************/ - -# define INCL_BASE -# define INCL_PM -# include - - typedef HMTX cairo_mutex_t; - -# define CAIRO_MUTEX_LOCK(mutex) DosRequestMutexSem(mutex, SEM_INDEFINITE_WAIT) -# define CAIRO_MUTEX_UNLOCK(mutex) DosReleaseMutexSem(mutex) -# define CAIRO_MUTEX_INIT(mutex) DosCreateMutexSem (NULL, &(mutex), 0L, FALSE) -# define CAIRO_MUTEX_FINI(mutex) DosCloseMutexSem (mutex) -# define CAIRO_MUTEX_NIL_INITIALIZER 0 - -#elif CAIRO_HAS_BEOS_SURFACE /***********************************************/ - - typedef BLocker* cairo_mutex_t; - -# define CAIRO_MUTEX_LOCK(mutex) (mutex)->Lock() -# define CAIRO_MUTEX_UNLOCK(mutex) (mutex)->Unlock() -# define CAIRO_MUTEX_INIT(mutex) (mutex) = new BLocker() -# define CAIRO_MUTEX_FINI(mutex) delete (mutex) -# define CAIRO_MUTEX_NIL_INITIALIZER NULL - -#else /**********************************************************************/ - -# error "XXX: No mutex implementation found. Cairo will not work with multiple threads. Define CAIRO_NO_MUTEX to 1 to acknowledge and accept this limitation and compile cairo without thread-safety support." - - -#endif - -CAIRO_END_DECLS - -#endif diff --git a/gfx/cairo/cairo/src/cairo-mutex.c b/gfx/cairo/cairo/src/cairo-mutex.c deleted file mode 100644 index 88aaf0d0290b..000000000000 --- a/gfx/cairo/cairo/src/cairo-mutex.c +++ /dev/null @@ -1,80 +0,0 @@ -/* cairo - a vector graphics library with display and print output - * - * Copyright © 2007 Mathias Hasselmann - * - * 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. - * - * Contributor(s): - * Mathias Hasselmann - */ - -#include "cairoint.h" - -#define CAIRO_MUTEX_DECLARE(mutex) cairo_mutex_t mutex = CAIRO_MUTEX_NIL_INITIALIZER -#include "cairo-mutex-list-private.h" -#undef CAIRO_MUTEX_DECLARE - -#if _CAIRO_MUTEX_USE_STATIC_INITIALIZER || _CAIRO_MUTEX_USE_STATIC_FINALIZER - -# if _CAIRO_MUTEX_USE_STATIC_INITIALIZER -# define _CAIRO_MUTEX_INITIALIZED_DEFAULT_VALUE FALSE -# else -# define _CAIRO_MUTEX_INITIALIZED_DEFAULT_VALUE TRUE -# endif - -cairo_bool_t _cairo_mutex_initialized = _CAIRO_MUTEX_INITIALIZED_DEFAULT_VALUE; - -# undef _CAIRO_MUTEX_INITIALIZED_DEFAULT_VALUE - -#endif - -#if _CAIRO_MUTEX_USE_STATIC_INITIALIZER -void _cairo_mutex_initialize (void) -{ - if (_cairo_mutex_initialized) - return; - - _cairo_mutex_initialized = TRUE; - -#define CAIRO_MUTEX_DECLARE(mutex) CAIRO_MUTEX_INIT (mutex) -#include "cairo-mutex-list-private.h" -#undef CAIRO_MUTEX_DECLARE -} -#endif - -#if _CAIRO_MUTEX_USE_STATIC_FINALIZER -void _cairo_mutex_finalize (void) -{ - if (!_cairo_mutex_initialized) - return; - - _cairo_mutex_initialized = FALSE; - -#define CAIRO_MUTEX_DECLARE(mutex) CAIRO_MUTEX_FINI (mutex) -#include "cairo-mutex-list-private.h" -#undef CAIRO_MUTEX_DECLARE -} -#endif diff --git a/gfx/cairo/cairo/src/cairo-os2-surface.c b/gfx/cairo/cairo/src/cairo-os2-surface.c index 319a7aba2fb9..f6ec8f6256c5 100644 --- a/gfx/cairo/cairo/src/cairo-os2-surface.c +++ b/gfx/cairo/cairo/src/cairo-os2-surface.c @@ -35,12 +35,8 @@ * Peter Weilbacher */ -#include "cairoint.h" - -#include "cairo-os2-private.h" - -#include - +#include +#include #include #ifdef BUILD_CAIRO_DLL # define INCL_WIN @@ -53,6 +49,9 @@ # include # 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 @@ -69,6 +68,14 @@ /* 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) { @@ -96,10 +103,20 @@ cairo_os2_init (void) 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 @@ -120,7 +137,28 @@ cairo_os2_fini (void) _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 (); diff --git a/gfx/cairo/cairo/src/cairo-output-stream-private.h b/gfx/cairo/cairo/src/cairo-output-stream-private.h index 0600431eac6c..d68fbb4802e1 100644 --- a/gfx/cairo/cairo/src/cairo-output-stream-private.h +++ b/gfx/cairo/cairo/src/cairo-output-stream-private.h @@ -37,7 +37,7 @@ #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, @@ -53,7 +53,7 @@ struct _cairo_output_stream { 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, @@ -107,7 +107,7 @@ _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 diff --git a/gfx/cairo/cairo/src/cairo-output-stream.c b/gfx/cairo/cairo/src/cairo-output-stream.c index b9f0d383aaf5..df3ae4d4334c 100644 --- a/gfx/cairo/cairo/src/cairo-output-stream.c +++ b/gfx/cairo/cairo/src/cairo-output-stream.c @@ -34,12 +34,11 @@ * Kristian Høgsberg */ -#include "cairoint.h" - -#include "cairo-output-stream-private.h" - +#include #include #include +#include "cairoint.h" +#include "cairo-output-stream-private.h" #ifdef _MSC_VER #define snprintf _snprintf @@ -64,7 +63,7 @@ _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 */ @@ -72,7 +71,7 @@ const cairo_output_stream_t _cairo_output_stream_nil = { 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 */ @@ -120,7 +119,7 @@ _cairo_output_stream_create (cairo_write_func_t write_func, 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; @@ -138,8 +137,8 @@ _cairo_output_stream_close (cairo_output_stream_t *stream) 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; } @@ -215,49 +214,52 @@ _cairo_output_stream_write_hex_string (cairo_output_stream_t *stream, * has been relicensed under the LGPL/MPL dual license for inclusion * into cairo (see COPYING). -- Kristian Høgsberg */ -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 { @@ -276,13 +278,10 @@ 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; @@ -306,14 +305,10 @@ _cairo_output_stream_vprintf (cairo_output_stream_t *stream, 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') { @@ -321,15 +316,9 @@ _cairo_output_stream_vprintf (cairo_output_stream_t *stream, 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); @@ -348,27 +337,15 @@ _cairo_output_stream_vprintf (cairo_output_stream_t *stream, 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, @@ -469,11 +446,11 @@ _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; @@ -489,12 +466,12 @@ _cairo_output_stream_create_for_filename (const char *filename) 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); @@ -535,7 +512,7 @@ _cairo_memory_stream_create (void) 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); diff --git a/gfx/cairo/cairo/src/cairo-paginated-private.h b/gfx/cairo/cairo/src/cairo-paginated-private.h deleted file mode 100644 index 42d100b4bcfb..000000000000 --- a/gfx/cairo/cairo/src/cairo-paginated-private.h +++ /dev/null @@ -1,136 +0,0 @@ -/* cairo - a vector graphics library with display and print output - * - * 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 Red Hat, Inc. - * - * Contributor(s): - * Carl Worth - */ - -#ifndef CAIRO_PAGINATED_H -#define CAIRO_PAGINATED_H - -#include "cairoint.h" - -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_warn cairo_int_status_t - (*start_page) (void *surface); - - /* Required. Will be called twice for each page, once with an - * argument of CAIRO_PAGINATED_MODE_ANALYZE and once with - * CAIRO_PAGINATED_MODE_RENDER. See more details in the - * documentation for _cairo_paginated_surface_create below. - */ - void - (*set_paginated_mode) (void *surface, - cairo_paginated_mode_t mode); -}; - -/* 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__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); - -cairo_private cairo_surface_t * -_cairo_paginated_surface_get_target (cairo_surface_t *surface); - -cairo_private cairo_bool_t -_cairo_surface_is_paginated (cairo_surface_t *surface); - -#endif /* CAIRO_PAGINATED_H */ diff --git a/gfx/cairo/cairo/src/cairo-paginated-surface-private.h b/gfx/cairo/cairo/src/cairo-paginated-surface-private.h index b406cac15002..b5e4d5c9b808 100644 --- a/gfx/cairo/cairo/src/cairo-paginated-surface-private.h +++ b/gfx/cairo/cairo/src/cairo-paginated-surface-private.h @@ -36,37 +36,106 @@ #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; + /* 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; - cairo_content_t content; +/* 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__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); - /* 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; +cairo_private cairo_surface_t * +_cairo_paginated_surface_get_target (cairo_surface_t *surface); - /* 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; +cairo_private cairo_bool_t +_cairo_surface_is_paginated (cairo_surface_t *surface); #endif /* CAIRO_PAGINATED_SURFACE_H */ diff --git a/gfx/cairo/cairo/src/cairo-paginated-surface.c b/gfx/cairo/cairo/src/cairo-paginated-surface.c index 17470949ef91..c8e46124f994 100644 --- a/gfx/cairo/cairo/src/cairo-paginated-surface.c +++ b/gfx/cairo/cairo/src/cairo-paginated-surface.c @@ -36,17 +36,45 @@ /* 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 @@ -134,15 +162,11 @@ _cairo_paginated_surface_finish (void *abstract_surface) 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); @@ -177,22 +201,15 @@ _cairo_paginated_surface_acquire_source_image (void *abstract_surface, { cairo_paginated_surface_t *surface = abstract_surface; cairo_surface_t *image; - cairo_status_t status; 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; @@ -218,16 +235,13 @@ _paint_page (cairo_paginated_surface_t *surface) 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; } @@ -243,29 +257,26 @@ _paint_page (cairo_paginated_surface_t *surface) 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 @@ -287,9 +298,7 @@ _cairo_paginated_surface_copy_page (void *abstract_surface) if (status) return status; - status = _paint_page (surface); - if (status) - return status; + _paint_page (surface); surface->page_num++; @@ -314,16 +323,9 @@ _cairo_paginated_surface_show_page (void *abstract_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); @@ -483,7 +485,6 @@ _cairo_paginated_surface_show_glyphs (void *abstract_surface, 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 @@ -504,19 +505,13 @@ _cairo_paginated_surface_snapshot (void *abstract_other) 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 diff --git a/gfx/cairo/cairo/src/cairo-path-bounds.c b/gfx/cairo/cairo/src/cairo-path-bounds.c index 5b60cf1c3931..48b4393a74a8 100644 --- a/gfx/cairo/cairo/src/cairo-path-bounds.c +++ b/gfx/cairo/cairo/src/cairo-path-bounds.c @@ -51,7 +51,7 @@ _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 @@ -81,7 +81,7 @@ _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) { @@ -104,6 +104,8 @@ _cairo_path_bounder_add_point (cairo_path_bounder_t *bounder, cairo_point_t *poi bounder->has_point = 1; } + + return CAIRO_STATUS_SUCCESS; } static cairo_status_t diff --git a/gfx/cairo/cairo/src/cairo-path-fill.c b/gfx/cairo/cairo/src/cairo-path-fill.c index 25420297ff25..b1b7a120d278 100644 --- a/gfx/cairo/cairo/src/cairo-path-fill.c +++ b/gfx/cairo/cairo/src/cairo-path-fill.c @@ -88,28 +88,37 @@ _cairo_filler_fini (cairo_filler_t *filler) static cairo_status_t _cairo_filler_move_to (void *closure, cairo_point_t *point) { + cairo_status_t status; cairo_filler_t *filler = closure; cairo_polygon_t *polygon = &filler->polygon; - _cairo_polygon_close (polygon); - _cairo_polygon_move_to (polygon, point); + status = _cairo_polygon_close (polygon); + if (status) + return status; + + status = _cairo_polygon_move_to (polygon, point); + if (status) + return status; filler->current_point = *point; - return _cairo_polygon_status (&filler->polygon); + return CAIRO_STATUS_SUCCESS; } static cairo_status_t _cairo_filler_line_to (void *closure, cairo_point_t *point) { + cairo_status_t status; cairo_filler_t *filler = closure; cairo_polygon_t *polygon = &filler->polygon; - _cairo_polygon_line_to (polygon, point); + status = _cairo_polygon_line_to (polygon, point); + if (status) + return status; filler->current_point = *point; - return _cairo_polygon_status (&filler->polygon); + return CAIRO_STATUS_SUCCESS; } static cairo_status_t @@ -129,12 +138,15 @@ _cairo_filler_curve_to (void *closure, if (status == CAIRO_INT_STATUS_DEGENERATE) return CAIRO_STATUS_SUCCESS; - status = _cairo_spline_decompose (&spline, filler->tolerance); + _cairo_spline_decompose (&spline, filler->tolerance); if (status) goto CLEANUP_SPLINE; - for (i = 1; i < spline.num_points; i++) - _cairo_polygon_line_to (polygon, &spline.points[i]); + for (i = 1; i < spline.num_points; i++) { + status = _cairo_polygon_line_to (polygon, &spline.points[i]); + if (status) + break; + } CLEANUP_SPLINE: _cairo_spline_fini (&spline); @@ -147,12 +159,15 @@ _cairo_filler_curve_to (void *closure, static cairo_status_t _cairo_filler_close_path (void *closure) { + cairo_status_t status; cairo_filler_t *filler = closure; cairo_polygon_t *polygon = &filler->polygon; - _cairo_polygon_close (polygon); + status = _cairo_polygon_close (polygon); + if (status) + return status; - return _cairo_polygon_status (polygon); + return CAIRO_STATUS_SUCCESS; } static cairo_int_status_t @@ -186,8 +201,7 @@ _cairo_path_fixed_fill_to_traps (cairo_path_fixed_t *path, if (status) goto BAIL; - _cairo_polygon_close (&filler.polygon); - status = _cairo_polygon_status (&filler.polygon); + status = _cairo_polygon_close (&filler.polygon); if (status) goto BAIL; diff --git a/gfx/cairo/cairo/src/cairo-path-fixed.c b/gfx/cairo/cairo/src/cairo-path-fixed.c index dfd30b1c12fb..4845ada21755 100644 --- a/gfx/cairo/cairo/src/cairo-path-fixed.c +++ b/gfx/cairo/cairo/src/cairo-path-fixed.c @@ -35,6 +35,7 @@ * Carl D. Worth */ +#include #include "cairoint.h" #include "cairo-path-fixed-private.h" @@ -355,8 +356,8 @@ _cairo_path_fixed_add (cairo_path_fixed_t *path, cairo_point_t *points, int num_points) { - if ((unsigned int) path->buf_tail->num_ops + 1 > CAIRO_PATH_BUF_SIZE || - (unsigned int) path->buf_tail->num_points + num_points > CAIRO_PATH_BUF_SIZE) + if (path->buf_tail->num_ops + 1 > CAIRO_PATH_BUF_SIZE || + path->buf_tail->num_points + num_points > CAIRO_PATH_BUF_SIZE) { cairo_path_buf_t *buf; diff --git a/gfx/cairo/cairo/src/cairo-path-stroke.c b/gfx/cairo/cairo/src/cairo-path-stroke.c index d9f7ed2caf74..09bafbf8e71d 100644 --- a/gfx/cairo/cairo/src/cairo-path-stroke.c +++ b/gfx/cairo/cairo/src/cairo-path-stroke.c @@ -67,7 +67,7 @@ typedef struct cairo_stroker { } cairo_stroker_t; /* private functions */ -static cairo_status_t +static void _cairo_stroker_init (cairo_stroker_t *stroker, cairo_stroke_style_t *stroke_style, cairo_matrix_t *ctm, @@ -148,7 +148,7 @@ _cairo_stroker_step_dash (cairo_stroker_t *stroker, double step) } } -static cairo_status_t +static void _cairo_stroker_init (cairo_stroker_t *stroker, cairo_stroke_style_t *stroke_style, cairo_matrix_t *ctm, @@ -156,18 +156,15 @@ _cairo_stroker_init (cairo_stroker_t *stroker, double tolerance, cairo_traps_t *traps) { - cairo_status_t status; stroker->style = stroke_style; stroker->ctm = ctm; stroker->ctm_inverse = ctm_inverse; stroker->tolerance = tolerance; stroker->traps = traps; - status = _cairo_pen_init (&stroker->pen, - stroke_style->line_width / 2.0, - tolerance, ctm); - if (status) - return status; + _cairo_pen_init (&stroker->pen, + stroke_style->line_width / 2.0, + tolerance, ctm); stroker->has_current_face = FALSE; stroker->has_first_face = FALSE; @@ -177,8 +174,6 @@ _cairo_stroker_init (cairo_stroker_t *stroker, _cairo_stroker_start_dash (stroker); else stroker->dashed = FALSE; - - return CAIRO_STATUS_SUCCESS; } static void @@ -210,7 +205,6 @@ _cairo_stroker_join (cairo_stroker_t *stroker, cairo_stroke_face_t *in, cairo_st { int clockwise = _cairo_stroker_face_clockwise (out, in); cairo_point_t *inpt, *outpt; - cairo_status_t status; if (in->cw.x == out->cw.x && in->cw.y == out->cw.y @@ -237,21 +231,13 @@ _cairo_stroker_join (cairo_stroker_t *stroker, cairo_stroke_face_t *in, cairo_st tri[0] = in->point; if (clockwise) { - status = _cairo_pen_find_active_ccw_vertex_index (pen, &in->dev_vector, &start); - if (status) - return status; + _cairo_pen_find_active_ccw_vertex_index (pen, &in->dev_vector, &start); step = -1; - status = _cairo_pen_find_active_ccw_vertex_index (pen, &out->dev_vector, &stop); - if (status) - return status; + _cairo_pen_find_active_ccw_vertex_index (pen, &out->dev_vector, &stop); } else { - status = _cairo_pen_find_active_cw_vertex_index (pen, &in->dev_vector, &start); - if (status) - return status; + _cairo_pen_find_active_cw_vertex_index (pen, &in->dev_vector, &start); step = +1; - status = _cairo_pen_find_active_cw_vertex_index (pen, &out->dev_vector, &stop); - if (status) - return status; + _cairo_pen_find_active_cw_vertex_index (pen, &out->dev_vector, &stop); } i = start; @@ -259,9 +245,7 @@ _cairo_stroker_join (cairo_stroker_t *stroker, cairo_stroke_face_t *in, cairo_st while (i != stop) { tri[2] = in->point; _translate_point (&tri[2], &pen->vertices[i].point); - status = _cairo_traps_tessellate_triangle (stroker->traps, tri); - if (status) - return status; + _cairo_traps_tessellate_triangle (stroker->traps, tri); tri[1] = tri[2]; i += step; if (i < 0) @@ -394,23 +378,17 @@ _cairo_stroker_add_cap (cairo_stroker_t *stroker, cairo_stroke_face_t *f) cairo_pen_t *pen = &stroker->pen; slope = f->dev_vector; - status = _cairo_pen_find_active_cw_vertex_index (pen, &slope, &start); - if (status) - return status; + _cairo_pen_find_active_cw_vertex_index (pen, &slope, &start); slope.dx = -slope.dx; slope.dy = -slope.dy; - status = _cairo_pen_find_active_cw_vertex_index (pen, &slope, &stop); - if (status) - return status; + _cairo_pen_find_active_cw_vertex_index (pen, &slope, &stop); tri[0] = f->point; tri[1] = f->cw; for (i=start; i != stop; i = (i+1) % pen->num_vertices) { tri[2] = f->point; _translate_point (&tri[2], &pen->vertices[i].point); - status = _cairo_traps_tessellate_triangle (stroker->traps, tri); - if (status) - return status; + _cairo_traps_tessellate_triangle (stroker->traps, tri); tri[1] = tri[2]; } tri[2] = f->ccw; @@ -441,14 +419,8 @@ _cairo_stroker_add_cap (cairo_stroker_t *stroker, cairo_stroke_face_t *f) _cairo_polygon_line_to (&polygon, &occw); _cairo_polygon_line_to (&polygon, &f->ccw); _cairo_polygon_close (&polygon); - status = _cairo_polygon_status (&polygon); - - if (status == CAIRO_STATUS_SUCCESS) { - status = _cairo_bentley_ottmann_tessellate_polygon (stroker->traps, - &polygon, - CAIRO_FILL_RULE_WINDING); - } + status = _cairo_bentley_ottmann_tessellate_polygon (stroker->traps, &polygon, CAIRO_FILL_RULE_WINDING); _cairo_polygon_fini (&polygon); return status; @@ -995,11 +967,9 @@ _cairo_path_fixed_stroke_to_traps (cairo_path_fixed_t *path, if (status != CAIRO_INT_STATUS_UNSUPPORTED) return status; - status = _cairo_stroker_init (&stroker, stroke_style, - ctm, ctm_inverse, tolerance, - traps); - if (status) - return status; + _cairo_stroker_init (&stroker, stroke_style, + ctm, ctm_inverse, tolerance, + traps); if (stroker.style->dash) status = _cairo_path_fixed_interpret (path, diff --git a/gfx/cairo/cairo/src/cairo-path.c b/gfx/cairo/cairo/src/cairo-path.c index 4c8e09e113b2..7c2374c2a4fb 100644 --- a/gfx/cairo/cairo/src/cairo-path.c +++ b/gfx/cairo/cairo/src/cairo-path.c @@ -34,10 +34,9 @@ * Carl D. Worth */ -#include "cairoint.h" - #include "cairo-path-private.h" #include "cairo-path-fixed-private.h" +#include "cairo-gstate-private.h" const cairo_path_t _cairo_path_nil = { CAIRO_STATUS_NO_MEMORY, NULL, 0 }; @@ -136,7 +135,6 @@ _cairo_path_count (cairo_path_t *path, double tolerance, cairo_bool_t flatten) { - cairo_status_t status; cpc_t cpc; cpc.count = 0; @@ -144,17 +142,15 @@ _cairo_path_count (cairo_path_t *path, cpc.current_point.x = 0; cpc.current_point.y = 0; - status = _cairo_path_fixed_interpret (path_fixed, - CAIRO_DIRECTION_FORWARD, - _cpc_move_to, - _cpc_line_to, - flatten ? - _cpc_curve_to_flatten : - _cpc_curve_to, - _cpc_close_path, - &cpc); - if (status) - return -1; + _cairo_path_fixed_interpret (path_fixed, + CAIRO_DIRECTION_FORWARD, + _cpc_move_to, + _cpc_line_to, + flatten ? + _cpc_curve_to_flatten : + _cpc_curve_to, + _cpc_close_path, + &cpc); return cpc.count; } @@ -279,8 +275,7 @@ _cpp_curve_to_flatten (void *closure, if (status == CAIRO_INT_STATUS_DEGENERATE) return CAIRO_STATUS_SUCCESS; - status = _cairo_spline_decompose (&spline, - _cairo_gstate_get_tolerance (cpp->gstate)); + status = _cairo_spline_decompose (&spline, cpp->gstate->tolerance); if (status) goto out; @@ -310,13 +305,12 @@ _cpp_close_path (void *closure) return CAIRO_STATUS_SUCCESS; } -static cairo_status_t +static void _cairo_path_populate (cairo_path_t *path, cairo_path_fixed_t *path_fixed, cairo_gstate_t *gstate, cairo_bool_t flatten) { - cairo_status_t status; cpp_t cpp; cpp.data = path->data; @@ -324,22 +318,18 @@ _cairo_path_populate (cairo_path_t *path, cpp.current_point.x = 0; cpp.current_point.y = 0; - status = _cairo_path_fixed_interpret (path_fixed, - CAIRO_DIRECTION_FORWARD, - _cpp_move_to, - _cpp_line_to, - flatten ? - _cpp_curve_to_flatten : - _cpp_curve_to, - _cpp_close_path, - &cpp); - if (status) - return status; + _cairo_path_fixed_interpret (path_fixed, + CAIRO_DIRECTION_FORWARD, + _cpp_move_to, + _cpp_line_to, + flatten ? + _cpp_curve_to_flatten : + _cpp_curve_to, + _cpp_close_path, + &cpp); /* Sanity check the count */ assert (cpp.data - path->data == path->num_data); - - return status; } cairo_path_t * @@ -347,10 +337,6 @@ _cairo_path_create_in_error (cairo_status_t status) { cairo_path_t *path; - /* special case NO_MEMORY so as to avoid allocations */ - if (status == CAIRO_STATUS_NO_MEMORY) - return (cairo_path_t*) &_cairo_path_nil; - path = malloc (sizeof (cairo_path_t)); if (path == NULL) return (cairo_path_t*) &_cairo_path_nil; @@ -374,12 +360,7 @@ _cairo_path_create_internal (cairo_path_fixed_t *path_fixed, return (cairo_path_t*) &_cairo_path_nil; path->num_data = _cairo_path_count (path, path_fixed, - _cairo_gstate_get_tolerance (gstate), - flatten); - if (path->num_data <= 0) { - free (path); - return (cairo_path_t*) &_cairo_path_nil; - } + gstate->tolerance, flatten); path->data = malloc (path->num_data * sizeof (cairo_path_data_t)); if (path->data == NULL) { @@ -387,8 +368,10 @@ _cairo_path_create_internal (cairo_path_fixed_t *path_fixed, return (cairo_path_t*) &_cairo_path_nil; } - path->status = _cairo_path_populate (path, path_fixed, - gstate, flatten); + path->status = CAIRO_STATUS_SUCCESS; + + _cairo_path_populate (path, path_fixed, + gstate, flatten); return path; } @@ -477,7 +460,6 @@ _cairo_path_append_to_context (const cairo_path_t *path, { int i; cairo_path_data_t *p; - cairo_status_t status; for (i=0; i < path->num_data; i += path->data[i].header.length) { p = &path->data[i]; @@ -510,10 +492,6 @@ _cairo_path_append_to_context (const cairo_path_t *path, default: return CAIRO_STATUS_INVALID_PATH_DATA; } - - status = cairo_status (cr); - if (status) - return status; } return CAIRO_STATUS_SUCCESS; diff --git a/gfx/cairo/cairo/src/cairo-pattern.c b/gfx/cairo/cairo/src/cairo-pattern.c index 9fafc99186d0..f076259b5259 100644 --- a/gfx/cairo/cairo/src/cairo-pattern.c +++ b/gfx/cairo/cairo/src/cairo-pattern.c @@ -30,7 +30,7 @@ #include "cairoint.h" -const cairo_solid_pattern_t _cairo_pattern_nil = { +const cairo_solid_pattern_t cairo_pattern_nil = { { CAIRO_PATTERN_TYPE_SOLID, /* type */ CAIRO_REF_COUNT_INVALID, /* ref_count */ CAIRO_STATUS_NO_MEMORY, /* status */ @@ -40,7 +40,7 @@ const cairo_solid_pattern_t _cairo_pattern_nil = { CAIRO_EXTEND_GRADIENT_DEFAULT }, /* extend */ }; -static const cairo_solid_pattern_t _cairo_pattern_nil_null_pointer = { +static const cairo_solid_pattern_t cairo_pattern_nil_null_pointer = { { CAIRO_PATTERN_TYPE_SOLID, /* type */ CAIRO_REF_COUNT_INVALID, /* ref_count */ CAIRO_STATUS_NULL_POINTER,/* status */ @@ -50,16 +50,6 @@ static const cairo_solid_pattern_t _cairo_pattern_nil_null_pointer = { CAIRO_EXTEND_GRADIENT_DEFAULT }, /* extend */ }; -const cairo_solid_pattern_t cairo_pattern_none = { - { CAIRO_PATTERN_TYPE_SOLID, /* type */ - CAIRO_REF_COUNT_INVALID, /* ref_count */ - CAIRO_STATUS_SUCCESS, /* status */ - { 0, 0, 0, NULL }, /* user_data */ - { 1., 0., 0., 1., 0., 0., }, /* matrix */ - CAIRO_FILTER_DEFAULT, /* filter */ - CAIRO_EXTEND_GRADIENT_DEFAULT }, /* extend */ -}; - /** * _cairo_pattern_set_error: * @pattern: a pattern @@ -92,8 +82,6 @@ _cairo_pattern_set_error (cairo_pattern_t *pattern, static void _cairo_pattern_init (cairo_pattern_t *pattern, cairo_pattern_type_t type) { - CAIRO_MUTEX_INITIALIZE (); - pattern->type = type; pattern->ref_count = 1; pattern->status = CAIRO_STATUS_SUCCESS; @@ -110,7 +98,7 @@ _cairo_pattern_init (cairo_pattern_t *pattern, cairo_pattern_type_t type) cairo_matrix_init_identity (&pattern->matrix); } -static cairo_status_t +static void _cairo_gradient_pattern_init_copy (cairo_gradient_pattern_t *pattern, const cairo_gradient_pattern_t *other) { @@ -139,23 +127,21 @@ _cairo_gradient_pattern_init_copy (cairo_gradient_pattern_t *pattern, pattern->stops_size = 0; pattern->n_stops = 0; _cairo_pattern_set_error (&pattern->base, CAIRO_STATUS_NO_MEMORY); - return CAIRO_STATUS_NO_MEMORY; + return; } memcpy (pattern->stops, other->stops, other->n_stops * sizeof (pixman_gradient_stop_t)); } - - return CAIRO_STATUS_SUCCESS; } -cairo_status_t +void _cairo_pattern_init_copy (cairo_pattern_t *pattern, const cairo_pattern_t *other) { if (other->status) { _cairo_pattern_set_error (pattern, other->status); - return other->status; + return; } switch (other->type) { @@ -176,18 +162,12 @@ _cairo_pattern_init_copy (cairo_pattern_t *pattern, case CAIRO_PATTERN_TYPE_RADIAL: { cairo_gradient_pattern_t *dst = (cairo_gradient_pattern_t *) pattern; cairo_gradient_pattern_t *src = (cairo_gradient_pattern_t *) other; - cairo_status_t status; - - status = _cairo_gradient_pattern_init_copy (dst, src); - if (status) - return status; + _cairo_gradient_pattern_init_copy (dst, src); } break; } pattern->ref_count = 1; - - return CAIRO_STATUS_SUCCESS; } void @@ -217,12 +197,10 @@ _cairo_pattern_fini (cairo_pattern_t *pattern) void _cairo_pattern_init_solid (cairo_solid_pattern_t *pattern, - const cairo_color_t *color, - cairo_content_t content) + const cairo_color_t *color) { _cairo_pattern_init (&pattern->base, CAIRO_PATTERN_TYPE_SOLID); pattern->color = *color; - pattern->content = content; } void @@ -231,7 +209,7 @@ _cairo_pattern_init_for_surface (cairo_surface_pattern_t *pattern, { if (surface->status) { /* Force to solid to simplify the pattern_fini process. */ - _cairo_pattern_init (&pattern->base, CAIRO_PATTERN_TYPE_SOLID); + pattern->base.type = CAIRO_PATTERN_TYPE_SOLID; _cairo_pattern_set_error (&pattern->base, surface->status); return; } @@ -279,71 +257,29 @@ _cairo_pattern_init_radial (cairo_radial_pattern_t *pattern, pattern->gradient.c2.radius = _cairo_fixed_from_double (fabs (radius1)); } -/* We use a small freed pattern cache here, because we don't want to - * constantly reallocate simple colors. */ -#define MAX_PATTERN_CACHE_SIZE 4 -static struct { - cairo_solid_pattern_t *patterns[MAX_PATTERN_CACHE_SIZE]; - int size; -} solid_pattern_cache; - cairo_pattern_t * -_cairo_pattern_create_solid (const cairo_color_t *color, - cairo_content_t content) +_cairo_pattern_create_solid (const cairo_color_t *color) { - cairo_solid_pattern_t *pattern = NULL; - - CAIRO_MUTEX_LOCK (_cairo_pattern_solid_pattern_cache_lock); - - if (solid_pattern_cache.size) { - int i = --solid_pattern_cache.size % - ARRAY_LENGTH (solid_pattern_cache.patterns); - pattern = solid_pattern_cache.patterns[i]; - solid_pattern_cache.patterns[i] = NULL; - } - - CAIRO_MUTEX_UNLOCK (_cairo_pattern_solid_pattern_cache_lock); - - if (pattern == NULL) { - /* None cached, need to create a new pattern. */ - pattern = malloc (sizeof (cairo_solid_pattern_t)); - } + cairo_solid_pattern_t *pattern; + pattern = malloc (sizeof (cairo_solid_pattern_t)); if (pattern == NULL) - pattern = (cairo_solid_pattern_t *) &_cairo_pattern_nil; - else - _cairo_pattern_init_solid (pattern, color, content); + return (cairo_pattern_t *) &cairo_pattern_nil.base; + + _cairo_pattern_init_solid (pattern, color); return &pattern->base; } -static void -_cairo_pattern_reset_solid_pattern_cache (void) -{ - int i; - - CAIRO_MUTEX_LOCK (_cairo_pattern_solid_pattern_cache_lock); - - for (i = 0; i < MIN (ARRAY_LENGTH (solid_pattern_cache.patterns), solid_pattern_cache.size); i++) { - free (solid_pattern_cache.patterns[i]); - solid_pattern_cache.patterns[i] = NULL; - } - solid_pattern_cache.size = 0; - - CAIRO_MUTEX_UNLOCK (_cairo_pattern_solid_pattern_cache_lock); -} - static const cairo_pattern_t * _cairo_pattern_create_in_error (cairo_status_t status) { cairo_pattern_t *pattern; - if (status == CAIRO_STATUS_NO_MEMORY) - return (cairo_pattern_t *)&_cairo_pattern_nil.base; + pattern = _cairo_pattern_create_solid (_cairo_stock_color (CAIRO_STOCK_BLACK)); + if (cairo_pattern_status (pattern)) + return pattern; - pattern = _cairo_pattern_create_solid (_cairo_stock_color (CAIRO_STOCK_BLACK), - CAIRO_CONTENT_COLOR); - /* no-op on a pattern already in error i.e the _cairo_pattern_nil */ _cairo_pattern_set_error (pattern, status); return pattern; @@ -381,8 +317,7 @@ cairo_pattern_create_rgb (double red, double green, double blue) _cairo_color_init_rgb (&color, red, green, blue); - pattern = _cairo_pattern_create_solid (&color, - CAIRO_CONTENT_COLOR); + pattern = _cairo_pattern_create_solid (&color); if (pattern->status) _cairo_error (pattern->status); @@ -425,8 +360,7 @@ cairo_pattern_create_rgba (double red, double green, double blue, _cairo_color_init_rgba (&color, red, green, blue, alpha); - pattern = _cairo_pattern_create_solid (&color, - CAIRO_CONTENT_COLOR_ALPHA); + pattern = _cairo_pattern_create_solid (&color); if (pattern->status) _cairo_error (pattern->status); @@ -455,7 +389,7 @@ cairo_pattern_create_for_surface (cairo_surface_t *surface) cairo_surface_pattern_t *pattern; if (surface == NULL) - return (cairo_pattern_t*) &_cairo_pattern_nil_null_pointer; + return (cairo_pattern_t*) &cairo_pattern_nil_null_pointer; if (surface->status) return (cairo_pattern_t*) _cairo_pattern_create_in_error (surface->status); @@ -463,7 +397,7 @@ cairo_pattern_create_for_surface (cairo_surface_t *surface) pattern = malloc (sizeof (cairo_surface_pattern_t)); if (pattern == NULL) { _cairo_error (CAIRO_STATUS_NO_MEMORY); - return (cairo_pattern_t *)&_cairo_pattern_nil.base; + return (cairo_pattern_t *)&cairo_pattern_nil.base; } _cairo_pattern_init_for_surface (pattern, surface); @@ -506,7 +440,7 @@ cairo_pattern_create_linear (double x0, double y0, double x1, double y1) pattern = malloc (sizeof (cairo_linear_pattern_t)); if (pattern == NULL) { _cairo_error (CAIRO_STATUS_NO_MEMORY); - return (cairo_pattern_t *) &_cairo_pattern_nil.base; + return (cairo_pattern_t *) &cairo_pattern_nil.base; } _cairo_pattern_init_linear (pattern, x0, y0, x1, y1); @@ -524,7 +458,7 @@ cairo_pattern_create_linear (double x0, double y0, double x1, double y1) * @radius1: radius of the end circle * * Creates a new radial gradient cairo_pattern_t between the two - * circles defined by (cx0, cy0, radius0) and (cx1, cy1, radius1). Before using the + * circles defined by (x0, y0, c0) and (x1, y1, c0). Before using the * gradient pattern, a number of color stops should be defined using * cairo_pattern_add_color_stop_rgb() or * cairo_pattern_add_color_stop_rgba(). @@ -551,7 +485,7 @@ cairo_pattern_create_radial (double cx0, double cy0, double radius0, pattern = malloc (sizeof (cairo_radial_pattern_t)); if (pattern == NULL) { _cairo_error (CAIRO_STATUS_NO_MEMORY); - return (cairo_pattern_t *) &_cairo_pattern_nil.base; + return (cairo_pattern_t *) &cairo_pattern_nil.base; } _cairo_pattern_init_radial (pattern, cx0, cy0, radius0, cx1, cy1, radius1); @@ -642,25 +576,7 @@ cairo_pattern_destroy (cairo_pattern_t *pattern) return; _cairo_pattern_fini (pattern); - - /* maintain a small cache of freed patterns */ - if (pattern->type == CAIRO_PATTERN_TYPE_SOLID) { - int i; - - CAIRO_MUTEX_LOCK (_cairo_pattern_solid_pattern_cache_lock); - - i = solid_pattern_cache.size++ % - ARRAY_LENGTH (solid_pattern_cache.patterns); - /* swap an old pattern for this 'cache-hot' pattern */ - if (solid_pattern_cache.patterns[i]) - free (solid_pattern_cache.patterns[i]); - - solid_pattern_cache.patterns[i] = (cairo_solid_pattern_t *) pattern; - - CAIRO_MUTEX_UNLOCK (_cairo_pattern_solid_pattern_cache_lock); - } else { - free (pattern); - } + free (pattern); } slim_hidden_def (cairo_pattern_destroy); @@ -743,7 +659,7 @@ _cairo_pattern_gradient_grow (cairo_gradient_pattern_t *pattern) { pixman_gradient_stop_t *new_stops; int old_size = pattern->stops_size; - int embedded_size = ARRAY_LENGTH (pattern->stops_embedded); + int embedded_size = sizeof (pattern->stops_embedded) / sizeof (pattern->stops_embedded[0]); int new_size = 2 * MAX (old_size, 4); /* we have a local buffer at pattern->stops_embedded. try to fulfill the request @@ -834,13 +750,6 @@ _cairo_pattern_add_color_stop (cairo_gradient_pattern_t *pattern, * * The color is specified in the same way as in cairo_set_source_rgb(). * - * If two (or more) stops are specified with identical offset values, - * they will be sorted according to the order in which the stops are - * added, (stops added earlier will compare less than stops added - * later). This can be useful for reliably making sharp color - * transitions instead of the typical blend. - * - * * Note: If the pattern is not a gradient pattern, (eg. a linear or * radial pattern), then the pattern will be put into an error status * with a status of %CAIRO_STATUS_PATTERN_TYPE_MISMATCH. @@ -888,12 +797,6 @@ cairo_pattern_add_color_stop_rgb (cairo_pattern_t *pattern, * * The color is specified in the same way as in cairo_set_source_rgba(). * - * If two (or more) stops are specified with identical offset values, - * they will be sorted according to the order in which the stops are - * added, (stops added earlier will compare less than stops added - * later). This can be useful for reliably making sharp color - * transitions instead of the typical blend. - * * Note: If the pattern is not a gradient pattern, (eg. a linear or * radial pattern), then the pattern will be put into an error status * with a status of %CAIRO_STATUS_PATTERN_TYPE_MISMATCH. @@ -962,18 +865,10 @@ void cairo_pattern_set_matrix (cairo_pattern_t *pattern, const cairo_matrix_t *matrix) { - cairo_matrix_t inverse; - cairo_status_t status; - if (pattern->status) return; pattern->matrix = *matrix; - - inverse = *matrix; - status = cairo_matrix_invert (&inverse); - if (status) - _cairo_pattern_set_error (pattern, status); } slim_hidden_def (cairo_pattern_set_matrix); @@ -1063,8 +958,7 @@ void _cairo_pattern_transform (cairo_pattern_t *pattern, const cairo_matrix_t *ctm_inverse) { - if (pattern->status) - return; + assert (pattern->status == CAIRO_STATUS_SUCCESS); cairo_matrix_multiply (&pattern->matrix, ctm_inverse, &pattern->matrix); } @@ -1084,7 +978,7 @@ _cairo_linear_pattern_classify (cairo_linear_pattern_t *pattern, cairo_fixed_t factors[3]; int i; - /* To classify a pattern as horizontal or vertical, we first + /* To classidy a pattern as horizontal or vertical, we first * compute the (fixed point) factors at the corners of the * pattern. We actually only need 3/4 corners, so we skip the * fourth. @@ -1219,11 +1113,7 @@ _cairo_pattern_acquire_surface_for_gradient (cairo_gradient_pattern_t *pattern, pixman_image_set_filter (pixman_image, PIXMAN_FILTER_BILINEAR); _cairo_matrix_to_pixman_matrix (&pattern->base.matrix, &pixman_transform); - if (pixman_image_set_transform (pixman_image, &pixman_transform)) { - cairo_surface_destroy (&image->base); - pixman_image_destroy (pixman_image); - return CAIRO_STATUS_NO_MEMORY; - } + pixman_image_set_transform (pixman_image, &pixman_transform); switch (pattern->base.extend) { case CAIRO_EXTEND_NONE: @@ -1266,35 +1156,6 @@ _cairo_pattern_acquire_surface_for_gradient (cairo_gradient_pattern_t *pattern, return status; } -/* We maintain a small cache here, because we don't want to constantly - * recreate surfaces for simple solid colors. */ -#define MAX_SURFACE_CACHE_SIZE 16 -static struct { - struct _cairo_pattern_solid_surface_cache{ - cairo_color_t color; - cairo_surface_t *surface; - } cache[MAX_SURFACE_CACHE_SIZE]; - int size; -} solid_surface_cache; - -static cairo_bool_t -_cairo_pattern_solid_surface_matches ( - const struct _cairo_pattern_solid_surface_cache *cache, - const cairo_solid_pattern_t *pattern, - cairo_surface_t *dst) -{ - if (cache->surface->ref_count != 1) - return FALSE; - - if (! _cairo_color_equal (&cache->color, &pattern->color)) - return FALSE; - - if (! _cairo_surface_is_similar (cache->surface, dst, pattern->content)) - return FALSE; - - return TRUE; -} - static cairo_int_status_t _cairo_pattern_acquire_surface_for_solid (cairo_solid_pattern_t *pattern, cairo_surface_t *dst, @@ -1305,94 +1166,20 @@ _cairo_pattern_acquire_surface_for_solid (cairo_solid_pattern_t *pattern, cairo_surface_t **out, cairo_surface_attributes_t *attribs) { - static int i; + *out = _cairo_surface_create_similar_solid (dst, + CAIRO_CONTENT_COLOR_ALPHA, + 1, 1, + &pattern->color); + if ((*out)->status) + return CAIRO_STATUS_NO_MEMORY; - cairo_surface_t *surface; - cairo_status_t status; - - CAIRO_MUTEX_LOCK (_cairo_pattern_solid_surface_cache_lock); - - /* Check cache first */ - if (i < solid_surface_cache.size && - _cairo_pattern_solid_surface_matches (&solid_surface_cache.cache[i], - pattern, - dst)) - { - if (! _cairo_surface_reset (solid_surface_cache.cache[i].surface)) - goto DONE; - } - - for (i = 0 ; i < solid_surface_cache.size; i++) { - if (_cairo_pattern_solid_surface_matches (&solid_surface_cache.cache[i], - pattern, - dst)) - { - if (! _cairo_surface_reset (solid_surface_cache.cache[i].surface)) - goto DONE; - } - } - - /* Not cached, need to create new */ - surface = _cairo_surface_create_similar_solid (dst, - pattern->content, - 1, 1, - &pattern->color, - &pattern->base); - if (surface->status) { - status = surface->status; - goto UNLOCK; - } - - if (! _cairo_surface_is_similar (surface, dst, pattern->content)) { - /* in the rare event of a substitute surface being returned (e.g. - * malloc failure) don't cache the fallback surface */ - *out = surface; - goto NOCACHE; - } - - /* Cache new */ - if (solid_surface_cache.size < MAX_SURFACE_CACHE_SIZE) { - solid_surface_cache.size++; - } else { - i = rand () % MAX_SURFACE_CACHE_SIZE; - - /* Evict old */ - cairo_surface_destroy (solid_surface_cache.cache[i].surface); - } - - solid_surface_cache.cache[i].color = pattern->color; - solid_surface_cache.cache[i].surface = surface; - -DONE: - *out = cairo_surface_reference (solid_surface_cache.cache[i].surface); - -NOCACHE: attribs->x_offset = attribs->y_offset = 0; cairo_matrix_init_identity (&attribs->matrix); attribs->extend = CAIRO_EXTEND_REPEAT; attribs->filter = CAIRO_FILTER_NEAREST; attribs->acquired = FALSE; - status = CAIRO_STATUS_SUCCESS; - -UNLOCK: - CAIRO_MUTEX_UNLOCK (_cairo_pattern_solid_surface_cache_lock); - - return status; -} - -static void -_cairo_pattern_reset_solid_surface_cache (void) -{ - int i; - - CAIRO_MUTEX_LOCK (_cairo_pattern_solid_surface_cache_lock); - - for (i = 0; i < solid_surface_cache.size; i++) - cairo_surface_destroy (solid_surface_cache.cache[i].surface); - solid_surface_cache.size = 0; - - CAIRO_MUTEX_UNLOCK (_cairo_pattern_solid_surface_cache_lock); + return CAIRO_STATUS_SUCCESS; } /** @@ -1416,7 +1203,7 @@ _cairo_pattern_is_opaque_solid (const cairo_pattern_t *pattern) solid = (cairo_solid_pattern_t *) pattern; - return CAIRO_COLOR_IS_OPAQUE (&solid->color); + return CAIRO_ALPHA_IS_OPAQUE (solid->color.alpha); } static cairo_bool_t @@ -1425,7 +1212,7 @@ _gradient_is_opaque (const cairo_gradient_pattern_t *gradient) unsigned int i; for (i = 0; i < gradient->n_stops; i++) - if (! CAIRO_ALPHA_SHORT_IS_OPAQUE (gradient->stops[i].color.alpha)) + if (! CAIRO_ALPHA_IS_OPAQUE (gradient->stops[i].color.alpha)) return FALSE; return TRUE; @@ -1515,25 +1302,14 @@ _cairo_pattern_acquire_surface_for_surface (cairo_surface_pattern_t *pattern, attr->extend = CAIRO_EXTEND_REPEAT; - /* TODO: Instead of rendering pattern->surface four times to - * out, we should first copy pattern->surface to surface similar - * to dst and then copy that four times to out. This may cause - * an extra copy in the case of image destination, but for X servers, - * this will send pattern->surface just once over the wire instead - * of current four. - */ x = extents.x; y = extents.y; w = 2 * extents.width; h = 2 * extents.height; *out = cairo_surface_create_similar (dst, dst->content, w, h); - status = cairo_surface_status (*out); - if (status) { - cairo_surface_destroy (*out); - *out = NULL; - return status; - } + if (!*out) + return CAIRO_STATUS_NO_MEMORY; (*out)->device_transform = pattern->surface->device_transform; (*out)->device_transform_inverse = pattern->surface->device_transform_inverse; @@ -1558,11 +1334,6 @@ _cairo_pattern_acquire_surface_for_surface (cairo_surface_pattern_t *pattern, status = cairo_status (cr); cairo_destroy (cr); - if (status) { - cairo_surface_destroy (*out); - *out = NULL; - } - return status; } @@ -1615,16 +1386,11 @@ _cairo_pattern_acquire_surface_for_surface (cairo_surface_pattern_t *pattern, * in a region larger than the surface, but we never * want to clone more than the surface itself, (we * know we're not repeating at this point due to the - * above. - * - * XXX: The one padding here is to account for filter - * radius. It's a workaround right now, until we get a - * proper fix. (see bug #10508) - */ - x = MAX (0, floor (x1) - 1); - y = MAX (0, floor (y1) - 1); - width = MIN (extents.width, ceil (x2) + 1) - x; - height = MIN (extents.height, ceil (y2) + 1) - y; + * above. */ + x = MAX (0, floor (x1)); + y = MAX (0, floor (y1)); + width = MIN (extents.width, ceil (x2)) - x; + height = MIN (extents.height, ceil (y2)) - y; } x += tx; y += ty; @@ -1639,12 +1405,8 @@ _cairo_pattern_acquire_surface_for_surface (cairo_surface_pattern_t *pattern, *out = cairo_surface_create_similar (dst, dst->content, width, height); - status = cairo_surface_status (*out); - if (status) { - cairo_surface_destroy (*out); - *out = NULL; - return status; - } + if (!*out) + return CAIRO_STATUS_NO_MEMORY; (*out)->device_transform = pattern->surface->device_transform; (*out)->device_transform_inverse = pattern->surface->device_transform_inverse; @@ -1658,11 +1420,6 @@ _cairo_pattern_acquire_surface_for_surface (cairo_surface_pattern_t *pattern, status = cairo_status (cr); cairo_destroy (cr); - - if (status) { - cairo_surface_destroy (*out); - *out = NULL; - } } } @@ -1732,18 +1489,14 @@ _cairo_pattern_acquire_surface (cairo_pattern_t *pattern, src->stops->color.blue / 65535.0, src->stops->color.alpha / 65535.0); - _cairo_pattern_init_solid (&solid, &color, - CAIRO_COLOR_IS_OPAQUE (&color) ? - CAIRO_CONTENT_COLOR : - CAIRO_CONTENT_COLOR_ALPHA); + _cairo_pattern_init_solid (&solid, &color); } else { const cairo_color_t *color; color = _cairo_stock_color (CAIRO_STOCK_TRANSPARENT); - _cairo_pattern_init_solid (&solid, color, - CAIRO_CONTENT_ALPHA); + _cairo_pattern_init_solid (&solid, color); } status = _cairo_pattern_acquire_surface_for_solid (&solid, dst, @@ -1845,18 +1598,13 @@ _cairo_pattern_acquire_surfaces (cairo_pattern_t *src, combined = src_solid->color; _cairo_color_multiply_alpha (&combined, mask_solid->color.alpha); - _cairo_pattern_init_solid (&src_tmp.solid, &combined, - CAIRO_COLOR_IS_OPAQUE (&combined) ? - CAIRO_CONTENT_COLOR : - CAIRO_CONTENT_COLOR_ALPHA); + _cairo_pattern_init_solid (&src_tmp.solid, &combined); mask = NULL; } else { - status = _cairo_pattern_init_copy (&src_tmp.base, src); - if (status) - return status; + _cairo_pattern_init_copy (&src_tmp.base, src); } status = _cairo_pattern_acquire_surface (&src_tmp.base, dst, @@ -1875,23 +1623,19 @@ _cairo_pattern_acquire_surfaces (cairo_pattern_t *src, return CAIRO_STATUS_SUCCESS; } - status = _cairo_pattern_init_copy (&mask_tmp.base, mask); - if (status) - goto CLEANUP_SOURCE; + _cairo_pattern_init_copy (&mask_tmp.base, mask); status = _cairo_pattern_acquire_surface (&mask_tmp.base, dst, mask_x, mask_y, width, height, mask_out, mask_attributes); - _cairo_pattern_fini (&mask_tmp.base); - -CLEANUP_SOURCE: if (status) _cairo_pattern_release_surface (&src_tmp.base, *src_out, src_attributes); _cairo_pattern_fini (&src_tmp.base); + _cairo_pattern_fini (&mask_tmp.base); return status; } @@ -1933,9 +1677,7 @@ _cairo_pattern_get_extents (cairo_pattern_t *pattern, return status; imatrix = pattern->matrix; - status = cairo_matrix_invert (&imatrix); - if (status) - return status; + cairo_matrix_invert (&imatrix); /* XXX Use _cairo_matrix_transform_bounding_box here */ for (sy = 0; sy <= 1; sy++) { @@ -2214,10 +1956,3 @@ cairo_pattern_get_radial_circles (cairo_pattern_t *pattern, return CAIRO_STATUS_SUCCESS; } - -void -_cairo_pattern_reset_static_data (void) -{ - _cairo_pattern_reset_solid_pattern_cache (); - _cairo_pattern_reset_solid_surface_cache (); -} diff --git a/gfx/cairo/cairo/src/cairo-pdf-surface-private.h b/gfx/cairo/cairo/src/cairo-pdf-surface-private.h deleted file mode 100644 index 1af2ad06b86b..000000000000 --- a/gfx/cairo/cairo/src/cairo-pdf-surface-private.h +++ /dev/null @@ -1,105 +0,0 @@ -/* cairo - a vector graphics library with display and print output - * - * Copyright © 2004 Red Hat, Inc - * Copyright © 2006 Red Hat, Inc - * - * This library is free software; you can redistribute it and/or - * modify it either under the terms of the GNU Lesser General Public - * 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): - * Kristian Høgsberg - * Carl Worth - */ - -#ifndef CAIRO_PDF_SURFACE_PRIVATE_H -#define CAIRO_PDF_SURFACE_PRIVATE_H - -#include "cairo-pdf.h" - -#include "cairo-surface-private.h" - -typedef struct _cairo_pdf_resource { - unsigned int id; -} cairo_pdf_resource_t; - -typedef struct _cairo_pdf_surface cairo_pdf_surface_t; - -struct _cairo_pdf_surface { - cairo_surface_t base; - - /* Prefer the name "output" here to avoid confusion over the - * structure within a PDF document known as a "stream". */ - cairo_output_stream_t *output; - - double width; - double height; - cairo_matrix_t cairo_to_pdf; - - cairo_array_t objects; - cairo_array_t pages; - cairo_array_t patterns; - cairo_array_t xobjects; - cairo_array_t streams; - cairo_array_t alphas; - cairo_array_t smasks; - cairo_array_t rgb_linear_functions; - cairo_array_t alpha_linear_functions; - - cairo_scaled_font_subsets_t *font_subsets; - cairo_array_t fonts; - - cairo_pdf_resource_t next_available_resource; - cairo_pdf_resource_t pages_resource; - - struct { - cairo_bool_t active; - cairo_pdf_resource_t self; - cairo_pdf_resource_t length; - long start_offset; - cairo_bool_t compressed; - cairo_output_stream_t *old_output; - } current_stream; - - struct { - cairo_pattern_type_t type; - double red; - double green; - double blue; - int alpha; - cairo_pdf_resource_t smask; - cairo_pdf_resource_t pattern; - } emitted_pattern; - - cairo_bool_t has_clip; - - cairo_paginated_mode_t paginated_mode; - - cairo_bool_t force_fallbacks; -}; - -#endif /* CAIRO_PDF_SURFACE_PRIVATE_H */ diff --git a/gfx/cairo/cairo/src/cairo-pdf-surface.c b/gfx/cairo/cairo/src/cairo-pdf-surface.c index 1e73c4c44fa3..924b80c03f88 100644 --- a/gfx/cairo/cairo/src/cairo-pdf-surface.c +++ b/gfx/cairo/cairo/src/cairo-pdf-surface.c @@ -38,9 +38,9 @@ #include "cairoint.h" #include "cairo-pdf.h" -#include "cairo-pdf-surface-private.h" +#include "cairo-pdf-test.h" #include "cairo-scaled-font-subsets-private.h" -#include "cairo-paginated-private.h" +#include "cairo-paginated-surface-private.h" #include "cairo-path-fixed-private.h" #include "cairo-output-stream-private.h" @@ -64,6 +64,8 @@ * * - Surface patterns. * + * - Alpha channels in gradients. + * * - Should/does cairo support drawing into a scratch surface and then * using that as a fill pattern? For this backend, that would involve * using a tiling pattern (4.6.2). How do you create such a scratch @@ -89,23 +91,54 @@ typedef struct _cairo_pdf_object { long offset; } cairo_pdf_object_t; +typedef struct _cairo_pdf_resource { + unsigned int id; +} cairo_pdf_resource_t; + typedef struct _cairo_pdf_font { unsigned int font_id; unsigned int subset_id; cairo_pdf_resource_t subset_resource; } cairo_pdf_font_t; -typedef struct _cairo_pdf_rgb_linear_function { - cairo_pdf_resource_t resource; - double color1[3]; - double color2[3]; -} cairo_pdf_rgb_linear_function_t; +typedef struct _cairo_pdf_surface { + cairo_surface_t base; -typedef struct _cairo_pdf_alpha_linear_function { - cairo_pdf_resource_t resource; - double alpha1; - double alpha2; -} cairo_pdf_alpha_linear_function_t; + /* Prefer the name "output" here to avoid confusion over the + * structure within a PDF document known as a "stream". */ + cairo_output_stream_t *output; + + double width; + double height; + + cairo_array_t objects; + cairo_array_t pages; + cairo_array_t patterns; + cairo_array_t xobjects; + cairo_array_t streams; + cairo_array_t alphas; + + cairo_scaled_font_subsets_t *font_subsets; + cairo_array_t fonts; + + cairo_pdf_resource_t next_available_resource; + cairo_pdf_resource_t pages_resource; + + struct { + cairo_bool_t active; + cairo_pdf_resource_t self; + cairo_pdf_resource_t length; + long start_offset; + cairo_bool_t compressed; + cairo_output_stream_t *old_output; + } current_stream; + + cairo_bool_t has_clip; + + cairo_paginated_mode_t paginated_mode; +} cairo_pdf_surface_t; + +#define PDF_SURFACE_MAX_GLYPHS_PER_FONT 256 static cairo_pdf_resource_t _cairo_pdf_surface_new_object (cairo_pdf_surface_t *surface); @@ -118,10 +151,10 @@ _cairo_pdf_surface_open_stream (cairo_pdf_surface_t *surface, cairo_bool_t compressed, const char *fmt, ...) CAIRO_PRINTF_FORMAT(3, 4); -static cairo_status_t +static void _cairo_pdf_surface_close_stream (cairo_pdf_surface_t *surface); -static cairo_status_t +static void _cairo_pdf_surface_add_stream (cairo_pdf_surface_t *surface, cairo_pdf_resource_t stream); @@ -177,50 +210,43 @@ _cairo_pdf_surface_update_object (cairo_pdf_surface_t *surface, object->offset = _cairo_output_stream_get_position (surface->output); } -static cairo_status_t +static void _cairo_pdf_surface_add_stream (cairo_pdf_surface_t *surface, cairo_pdf_resource_t stream) { - return _cairo_array_append (&surface->streams, &stream); + /* XXX: Should be checking the return value here. */ + _cairo_array_append (&surface->streams, &stream); } -static cairo_status_t +static void _cairo_pdf_surface_add_pattern (cairo_pdf_surface_t *surface, cairo_pdf_resource_t pattern) { - return _cairo_array_append (&surface->patterns, &pattern); + /* XXX: Should be checking the return value here. */ + _cairo_array_append (&surface->patterns, &pattern); } -static cairo_status_t -_cairo_pdf_surface_add_smask (cairo_pdf_surface_t *surface, - cairo_pdf_resource_t smask) -{ - return _cairo_array_append (&surface->smasks, &smask); -} - -static cairo_status_t -_cairo_pdf_surface_add_alpha (cairo_pdf_surface_t *surface, double alpha, int *index) +static cairo_pdf_resource_t +_cairo_pdf_surface_add_alpha (cairo_pdf_surface_t *surface, double alpha) { + cairo_pdf_resource_t resource; int num_alphas, i; double other; - cairo_status_t status; num_alphas = _cairo_array_num_elements (&surface->alphas); for (i = 0; i < num_alphas; i++) { - _cairo_array_copy_element (&surface->alphas, i, &other); - if (alpha == other) { - *index = i; - return CAIRO_STATUS_SUCCESS; - } + _cairo_array_copy_element (&surface->alphas, i, &other); + if (alpha == other) { + resource.id = i; + return resource; + } } - status = _cairo_array_append (&surface->alphas, &alpha); - if (status) - return status; + /* XXX: Should be checking the return value here. */ + _cairo_array_append (&surface->alphas, &alpha); - *index = _cairo_array_num_elements (&surface->alphas) - 1; - - return CAIRO_STATUS_SUCCESS; + resource.id = _cairo_array_num_elements (&surface->alphas) - 1; + return resource; } static cairo_surface_t * @@ -229,8 +255,6 @@ _cairo_pdf_surface_create_for_stream_internal (cairo_output_stream_t *output, double height) { cairo_pdf_surface_t *surface; - cairo_status_t status; - int alpha; surface = malloc (sizeof (cairo_pdf_surface_t)); if (surface == NULL) { @@ -245,7 +269,6 @@ _cairo_pdf_surface_create_for_stream_internal (cairo_output_stream_t *output, surface->width = width; surface->height = height; - cairo_matrix_init (&surface->cairo_to_pdf, 1, 0, 0, -1, 0, height); _cairo_array_init (&surface->objects, sizeof (cairo_pdf_object_t)); _cairo_array_init (&surface->pages, sizeof (cairo_pdf_resource_t)); @@ -253,23 +276,13 @@ _cairo_pdf_surface_create_for_stream_internal (cairo_output_stream_t *output, _cairo_array_init (&surface->xobjects, sizeof (cairo_pdf_resource_t)); _cairo_array_init (&surface->streams, sizeof (cairo_pdf_resource_t)); _cairo_array_init (&surface->alphas, sizeof (double)); - _cairo_array_init (&surface->smasks, sizeof (cairo_pdf_resource_t)); - _cairo_array_init (&surface->rgb_linear_functions, sizeof (cairo_pdf_rgb_linear_function_t)); - _cairo_array_init (&surface->alpha_linear_functions, sizeof (cairo_pdf_alpha_linear_function_t)); - - /* Add alpha=1 as the first element in the list of alpha values as - * this is the most frequently referenced value. */ - status = _cairo_pdf_surface_add_alpha (surface, 1, &alpha); - if (status) { - _cairo_error (status); - goto fail1; - } - - surface->font_subsets = _cairo_scaled_font_subsets_create_composite (); + surface->font_subsets = _cairo_scaled_font_subsets_create (PDF_SURFACE_MAX_GLYPHS_PER_FONT, + PDF_SURFACE_MAX_GLYPHS_PER_FONT); if (! surface->font_subsets) { _cairo_error (CAIRO_STATUS_NO_MEMORY); - goto fail2; + free (surface); + return (cairo_surface_t*) &_cairo_surface_nil; } _cairo_array_init (&surface->fonts, sizeof (cairo_pdf_font_t)); @@ -283,8 +296,6 @@ _cairo_pdf_surface_create_for_stream_internal (cairo_output_stream_t *output, surface->paginated_mode = CAIRO_PAGINATED_MODE_ANALYZE; - surface->force_fallbacks = FALSE; - /* Document header */ _cairo_output_stream_printf (surface->output, "%%PDF-1.4\r\n"); @@ -295,11 +306,6 @@ _cairo_pdf_surface_create_for_stream_internal (cairo_output_stream_t *output, CAIRO_CONTENT_COLOR_ALPHA, width, height, &cairo_pdf_surface_paginated_backend); - -fail1: - free (surface); -fail2: - return (cairo_surface_t*) &_cairo_surface_nil; } /** @@ -496,17 +502,16 @@ _cairo_pdf_surface_open_stream (cairo_pdf_surface_t *surface, return surface->current_stream.self; } -static cairo_status_t +static void _cairo_pdf_surface_close_stream (cairo_pdf_surface_t *surface) { - cairo_status_t status = CAIRO_STATUS_SUCCESS; long length; if (! surface->current_stream.active) - return CAIRO_STATUS_SUCCESS; + return; if (surface->current_stream.compressed) { - status = _cairo_output_stream_destroy (surface->output); + _cairo_output_stream_destroy (surface->output); surface->output = surface->current_stream.old_output; _cairo_output_stream_printf (surface->output, "\r\n"); @@ -528,19 +533,17 @@ _cairo_pdf_surface_close_stream (cairo_pdf_surface_t *surface) length); surface->current_stream.active = FALSE; - - return status; } static cairo_status_t _cairo_pdf_surface_finish (void *abstract_surface) { - cairo_status_t status, status2; + cairo_status_t status; cairo_pdf_surface_t *surface = abstract_surface; long offset; cairo_pdf_resource_t info, catalog; - status = _cairo_pdf_surface_close_stream (surface); + _cairo_pdf_surface_close_stream (surface); _cairo_pdf_surface_emit_font_subsets (surface); @@ -566,9 +569,7 @@ _cairo_pdf_surface_finish (void *abstract_surface) "%%%%EOF\r\n", offset); - status2 = _cairo_output_stream_destroy (surface->output); - if (status == CAIRO_STATUS_SUCCESS) - status = status2; + status = _cairo_output_stream_destroy (surface->output); _cairo_array_fini (&surface->objects); _cairo_array_fini (&surface->pages); @@ -576,9 +577,6 @@ _cairo_pdf_surface_finish (void *abstract_surface) _cairo_array_fini (&surface->xobjects); _cairo_array_fini (&surface->streams); _cairo_array_fini (&surface->alphas); - _cairo_array_fini (&surface->smasks); - _cairo_array_fini (&surface->rgb_linear_functions); - _cairo_array_fini (&surface->alpha_linear_functions); if (surface->font_subsets) { _cairo_scaled_font_subsets_destroy (surface->font_subsets); @@ -590,13 +588,13 @@ _cairo_pdf_surface_finish (void *abstract_surface) return status; } -static cairo_status_t +static void _cairo_pdf_surface_pause_content_stream (cairo_pdf_surface_t *surface) { - return _cairo_pdf_surface_close_stream (surface); + _cairo_pdf_surface_close_stream (surface); } -static cairo_status_t +static void _cairo_pdf_surface_resume_content_stream (cairo_pdf_surface_t *surface) { cairo_pdf_resource_t stream; @@ -609,46 +607,12 @@ _cairo_pdf_surface_resume_content_stream (cairo_pdf_surface_t *surface) surface->width, surface->height); - return _cairo_pdf_surface_add_stream (surface, stream); -} - -static cairo_status_t -_cairo_pdf_surface_begin_group (cairo_pdf_surface_t *surface, cairo_pdf_resource_t *group) -{ - cairo_pdf_resource_t g; - cairo_status_t status; - - _cairo_pdf_surface_pause_content_stream (surface); - g = _cairo_pdf_surface_open_stream (surface, - TRUE, - " /Type /XObject\r\n" - " /Subtype /Form\r\n" - " /BBox [ 0 0 %f %f ]\r\n" - " /Group <<\r\n" - " /Type /Group\r\n" - " /S /Transparency\r\n" - " /CS /DeviceRGB\r\n" - " >>\r\n", - surface->width, - surface->height); - - status = _cairo_array_append (&surface->xobjects, &g); - *group = g; - - return status; -} - -static void -_cairo_pdf_surface_end_group (cairo_pdf_surface_t *surface) -{ - _cairo_pdf_surface_close_stream (surface); - _cairo_pdf_surface_resume_content_stream (surface); + _cairo_pdf_surface_add_stream (surface, stream); } static cairo_int_status_t _cairo_pdf_surface_start_page (void *abstract_surface) { - cairo_status_t status; cairo_pdf_surface_t *surface = abstract_surface; cairo_pdf_resource_t stream; @@ -660,9 +624,11 @@ _cairo_pdf_surface_start_page (void *abstract_surface) surface->width, surface->height); - status = _cairo_pdf_surface_add_stream (surface, stream); - if (status) - return status; + _cairo_pdf_surface_add_stream (surface, stream); + + _cairo_output_stream_printf (surface->output, + "1 0 0 -1 0 %f cm\r\n", + surface->height); return CAIRO_STATUS_SUCCESS; } @@ -750,7 +716,7 @@ _cairo_pdf_surface_emit_smask (cairo_pdf_surface_t *surface, image->width, image->height); _cairo_output_stream_write (surface->output, alpha_compressed, alpha_compressed_size); _cairo_output_stream_printf (surface->output, "\r\n"); - status = _cairo_pdf_surface_close_stream (surface); + _cairo_pdf_surface_close_stream (surface); free (alpha_compressed); CLEANUP_ALPHA: @@ -762,9 +728,9 @@ _cairo_pdf_surface_emit_smask (cairo_pdf_surface_t *surface, /* Emit image data into the given surface, providing a resource that * can be used to reference the data in image_ret. */ static cairo_status_t -_cairo_pdf_surface_emit_image (cairo_pdf_surface_t *surface, - cairo_image_surface_t *image, - cairo_pdf_resource_t *image_ret) +_cairo_pdf_surface_emit_image (cairo_pdf_surface_t *surface, + cairo_image_surface_t *image, + cairo_pdf_resource_t *image_ret) { cairo_status_t status = CAIRO_STATUS_SUCCESS; char *rgb, *compressed; @@ -864,7 +830,7 @@ _cairo_pdf_surface_emit_image (cairo_pdf_surface_t *surface, _cairo_output_stream_write (surface->output, compressed, compressed_size); _cairo_output_stream_printf (surface->output, "\r\n"); - status = _cairo_pdf_surface_close_stream (surface); + _cairo_pdf_surface_close_stream (surface); CLEANUP_COMPRESSED: free (compressed); @@ -875,30 +841,33 @@ _cairo_pdf_surface_emit_image (cairo_pdf_surface_t *surface, } static cairo_status_t -_cairo_pdf_surface_emit_solid_pattern (cairo_pdf_surface_t *surface, - cairo_solid_pattern_t *pattern) +_cairo_pdf_surface_emit_solid_pattern (cairo_pdf_surface_t *surface, + cairo_solid_pattern_t *pattern) { - int alpha; - cairo_status_t status; + cairo_pdf_resource_t alpha; - status = _cairo_pdf_surface_add_alpha (surface, pattern->color.alpha, &alpha); - if (status) - return status; + alpha = _cairo_pdf_surface_add_alpha (surface, pattern->color.alpha); - surface->emitted_pattern.type = CAIRO_PATTERN_TYPE_SOLID; - surface->emitted_pattern.red = pattern->color.red; - surface->emitted_pattern.green = pattern->color.green; - surface->emitted_pattern.blue = pattern->color.blue; - surface->emitted_pattern.alpha = alpha; - surface->emitted_pattern.smask.id = 0; - surface->emitted_pattern.pattern.id = 0; + /* With some work, we could separate the stroking + * or non-stroking color here as actually needed. */ + _cairo_output_stream_printf (surface->output, + "%f %f %f RG " + "%f %f %f rg " + "/a%d gs\r\n", + pattern->color.red, + pattern->color.green, + pattern->color.blue, + pattern->color.red, + pattern->color.green, + pattern->color.blue, + alpha.id); return CAIRO_STATUS_SUCCESS; } static cairo_status_t -_cairo_pdf_surface_emit_surface_pattern (cairo_pdf_surface_t *surface, - cairo_surface_pattern_t *pattern) +_cairo_pdf_surface_emit_surface_pattern (cairo_pdf_surface_t *surface, + cairo_surface_pattern_t *pattern) { cairo_pdf_resource_t stream; cairo_surface_t *pat_surface; @@ -906,7 +875,7 @@ _cairo_pdf_surface_emit_surface_pattern (cairo_pdf_surface_t *surface, cairo_image_surface_t *image; void *image_extra; cairo_status_t status = CAIRO_STATUS_SUCCESS; - cairo_pdf_resource_t image_resource = {0}; /* squelch bogus compiler warning */ + cairo_pdf_resource_t alpha, image_resource = {0}; /* squelch bogus compiler warning */ cairo_matrix_t cairo_p2d, pdf_p2d; cairo_extend_t extend = cairo_pattern_get_extend (&pattern->base); double xstep, ystep; @@ -914,9 +883,7 @@ _cairo_pdf_surface_emit_surface_pattern (cairo_pdf_surface_t *surface, /* XXX: Should do something clever here for PDF source surfaces ? */ - status = _cairo_pdf_surface_pause_content_stream (surface); - if (status) - return status; + _cairo_pdf_surface_pause_content_stream (surface); status = _cairo_pattern_acquire_surface ((cairo_pattern_t *)pattern, (cairo_surface_t *)surface, @@ -933,9 +900,7 @@ _cairo_pdf_surface_emit_surface_pattern (cairo_pdf_surface_t *surface, if (status) goto BAIL; - status = _cairo_surface_get_extents (&surface->base, &surface_extents); - if (status) - goto BAIL; + _cairo_surface_get_extents (&surface->base, &surface_extents); switch (extend) { /* We implement EXTEND_PAD like EXTEND_NONE for now */ @@ -1009,9 +974,7 @@ _cairo_pdf_surface_emit_surface_pattern (cairo_pdf_surface_t *surface, * pattern cell. */ cairo_p2d = pattern->base.matrix; - status = cairo_matrix_invert (&cairo_p2d); - /* cairo_pattern_set_matrix ensures the matrix is invertible */ - assert (status == CAIRO_STATUS_SUCCESS); + cairo_matrix_invert (&cairo_p2d); cairo_matrix_init_identity (&pdf_p2d); cairo_matrix_translate (&pdf_p2d, 0.0, surface_extents.height); @@ -1043,24 +1006,20 @@ _cairo_pdf_surface_emit_surface_pattern (cairo_pdf_surface_t *surface, image->width, image->height, image_resource.id); - status = _cairo_pdf_surface_close_stream (surface); - if (status) - goto BAIL; + _cairo_pdf_surface_close_stream (surface); - status = _cairo_pdf_surface_resume_content_stream (surface); - if (status) - goto BAIL; + _cairo_pdf_surface_resume_content_stream (surface); - status = _cairo_pdf_surface_add_pattern (surface, stream); - if (status) - goto BAIL; + _cairo_pdf_surface_add_pattern (surface, stream); - status = _cairo_pdf_surface_add_alpha (surface, 1.0, &surface->emitted_pattern.alpha); - if (status) - goto BAIL; - surface->emitted_pattern.type = CAIRO_PATTERN_TYPE_SURFACE; - surface->emitted_pattern.smask.id = 0; - surface->emitted_pattern.pattern = stream; + alpha = _cairo_pdf_surface_add_alpha (surface, 1.0); + /* With some work, we could separate the stroking + * or non-stroking pattern here as actually needed. */ + _cairo_output_stream_printf (surface->output, + "/Pattern CS /res%d SCN " + "/Pattern cs /res%d scn " + "/a%d gs\r\n", + stream.id, stream.id, alpha.id); BAIL: _cairo_surface_release_source_image (pat_surface, image, image_extra); @@ -1071,168 +1030,90 @@ _cairo_pdf_surface_emit_surface_pattern (cairo_pdf_surface_t *surface, } typedef struct _cairo_pdf_color_stop { - double offset; - double color[4]; - cairo_pdf_resource_t resource; + double offset; + cairo_pdf_resource_t gradient; + unsigned char color_char[4]; } cairo_pdf_color_stop_t; -static cairo_status_t -cairo_pdf_surface_emit_rgb_linear_function (cairo_pdf_surface_t *surface, - cairo_pdf_color_stop_t *stop1, - cairo_pdf_color_stop_t *stop2, - cairo_pdf_resource_t *function) +static cairo_pdf_resource_t +_cairo_pdf_surface_emit_linear_colorgradient (cairo_pdf_surface_t *surface, + cairo_pdf_color_stop_t *stop1, + cairo_pdf_color_stop_t *stop2) { - int num_elems, i; - cairo_pdf_rgb_linear_function_t elem; - cairo_pdf_resource_t res; - cairo_status_t status; - - num_elems = _cairo_array_num_elements (&surface->rgb_linear_functions); - for (i = 0; i < num_elems; i++) { - _cairo_array_copy_element (&surface->rgb_linear_functions, i, &elem); - if (memcmp (&elem.color1[0], &stop1->color[0], sizeof (double)*3) != 0) - continue; - if (memcmp (&elem.color2[0], &stop2->color[0], sizeof (double)*3) != 0) - continue; - *function = elem.resource; - return CAIRO_STATUS_SUCCESS; - } - - res = _cairo_pdf_surface_new_object (surface); + cairo_pdf_resource_t function = _cairo_pdf_surface_new_object (surface); _cairo_output_stream_printf (surface->output, "%d 0 obj\r\n" - "<< /FunctionType 2\r\n" + "<< /FunctionType 0\r\n" " /Domain [ 0 1 ]\r\n" - " /C0 [ %f %f %f ]\r\n" - " /C1 [ %f %f %f ]\r\n" - " /N 1\r\n" + " /Size [ 2 ]\r\n" + " /BitsPerSample 8\r\n" + " /Range [ 0 1 0 1 0 1 ]\r\n" + " /Length 6\r\n" ">>\r\n" - "endobj\r\n", - res.id, - stop1->color[0], - stop1->color[1], - stop1->color[2], - stop2->color[0], - stop2->color[1], - stop2->color[2]); - - elem.resource = res; - memcpy (&elem.color1[0], &stop1->color[0], sizeof (double)*3); - memcpy (&elem.color2[0], &stop2->color[0], sizeof (double)*3); - - status = _cairo_array_append (&surface->rgb_linear_functions, &elem); - *function = res; - - return status; -} - -static cairo_status_t -cairo_pdf_surface_emit_alpha_linear_function (cairo_pdf_surface_t *surface, - cairo_pdf_color_stop_t *stop1, - cairo_pdf_color_stop_t *stop2, - cairo_pdf_resource_t *function) -{ - int num_elems, i; - cairo_pdf_alpha_linear_function_t elem; - cairo_pdf_resource_t res; - cairo_status_t status; - - num_elems = _cairo_array_num_elements (&surface->alpha_linear_functions); - for (i = 0; i < num_elems; i++) { - _cairo_array_copy_element (&surface->alpha_linear_functions, i, &elem); - if (elem.alpha1 != stop1->color[3]) - continue; - if (elem.alpha2 != stop2->color[3]) - continue; - *function = elem.resource; - return CAIRO_STATUS_SUCCESS; - } - - res = _cairo_pdf_surface_new_object (surface); + "stream\r\n", + function.id); + _cairo_output_stream_write (surface->output, stop1->color_char, 3); + _cairo_output_stream_write (surface->output, stop2->color_char, 3); _cairo_output_stream_printf (surface->output, - "%d 0 obj\r\n" - "<< /FunctionType 2\r\n" - " /Domain [ 0 1 ]\r\n" - " /C0 [ %f ]\r\n" - " /C1 [ %f ]\r\n" - " /N 1\r\n" - ">>\r\n" - "endobj\r\n", - res.id, - stop1->color[3], - stop2->color[3]); + "\r\n" + "endstream\r\n" + "endobj\r\n"); - elem.resource = res; - elem.alpha1 = stop1->color[3]; - elem.alpha2 = stop2->color[3]; - - status = _cairo_array_append (&surface->alpha_linear_functions, &elem); - *function = res; - - return status; + return function; } -static cairo_status_t -_cairo_pdf_surface_emit_stitched_colorgradient (cairo_pdf_surface_t *surface, - unsigned int n_stops, - cairo_pdf_color_stop_t *stops, - cairo_bool_t is_alpha, - cairo_pdf_resource_t *function) +static cairo_pdf_resource_t +_cairo_pdf_surface_emit_stitched_colorgradient (cairo_pdf_surface_t *surface, + unsigned int n_stops, + cairo_pdf_color_stop_t stops[]) { - cairo_pdf_resource_t res; + cairo_pdf_resource_t function; unsigned int i; - cairo_status_t status; /* emit linear gradients between pairs of subsequent stops... */ for (i = 0; i < n_stops-1; i++) { - if (is_alpha) { - status = cairo_pdf_surface_emit_alpha_linear_function (surface, - &stops[i], - &stops[i+1], - &stops[i].resource); - if (status) - return status; - } else { - status = cairo_pdf_surface_emit_rgb_linear_function (surface, - &stops[i], - &stops[i+1], - &stops[i].resource); - if (status) - return status; - } + stops[i].gradient = _cairo_pdf_surface_emit_linear_colorgradient (surface, + &stops[i], + &stops[i+1]); } /* ... and stitch them together */ - res = _cairo_pdf_surface_new_object (surface); + function = _cairo_pdf_surface_new_object (surface); _cairo_output_stream_printf (surface->output, "%d 0 obj\r\n" "<< /FunctionType 3\r\n" " /Domain [ 0 1 ]\r\n", - res.id); + function.id); _cairo_output_stream_printf (surface->output, " /Functions [ "); for (i = 0; i < n_stops-1; i++) + { _cairo_output_stream_printf (surface->output, - "%d 0 R ", stops[i].resource.id); + "%d 0 R ", stops[i].gradient.id); + } _cairo_output_stream_printf (surface->output, "]\r\n"); _cairo_output_stream_printf (surface->output, " /Bounds [ "); for (i = 1; i < n_stops-1; i++) + { _cairo_output_stream_printf (surface->output, "%f ", stops[i].offset); + } _cairo_output_stream_printf (surface->output, "]\r\n"); _cairo_output_stream_printf (surface->output, " /Encode [ "); for (i = 1; i < n_stops; i++) + { _cairo_output_stream_printf (surface->output, "0 1 "); + } _cairo_output_stream_printf (surface->output, "]\r\n"); @@ -1240,42 +1121,34 @@ _cairo_pdf_surface_emit_stitched_colorgradient (cairo_pdf_surface_t *surface, ">>\r\n" "endobj\r\n"); - *function = res; - - return CAIRO_STATUS_SUCCESS; + return function; } #define COLOR_STOP_EPSILON 1e-6 -static cairo_status_t -_cairo_pdf_surface_emit_pattern_stops (cairo_pdf_surface_t *surface, - cairo_gradient_pattern_t *pattern, - cairo_pdf_resource_t *color_function, - cairo_pdf_resource_t *alpha_function) +static cairo_pdf_resource_t +_cairo_pdf_surface_emit_pattern_stops (cairo_pdf_surface_t *surface, cairo_gradient_pattern_t *pattern) { + cairo_pdf_resource_t function; cairo_pdf_color_stop_t *allstops, *stops; - unsigned int n_stops; - unsigned int i; - cairo_bool_t emit_alpha = FALSE; - cairo_status_t status; + unsigned int i, n_stops; - color_function->id = 0; - alpha_function->id = 0; + function = _cairo_pdf_surface_new_object (surface); allstops = malloc ((pattern->n_stops + 2) * sizeof (cairo_pdf_color_stop_t)); - if (allstops == NULL) - return CAIRO_STATUS_NO_MEMORY; - + if (allstops == NULL) { + _cairo_error (CAIRO_STATUS_NO_MEMORY); + function.id = 0; + return function; + } stops = &allstops[1]; n_stops = pattern->n_stops; - for (i = 0; i < n_stops; i++) { - stops[i].color[0] = pattern->stops[i].color.red / 65535.0; - stops[i].color[1] = pattern->stops[i].color.green / 65535.0; - stops[i].color[2] = pattern->stops[i].color.blue / 65535.0; - stops[i].color[3] = pattern->stops[i].color.alpha / 65535.0; - if (!CAIRO_ALPHA_IS_OPAQUE (stops[i].color[3])) - emit_alpha = TRUE; + for (i = 0; i < pattern->n_stops; i++) { + stops[i].color_char[0] = pattern->stops[i].color.red >> 8; + stops[i].color_char[1] = pattern->stops[i].color.green >> 8; + stops[i].color_char[2] = pattern->stops[i].color.blue >> 8; + stops[i].color_char[3] = pattern->stops[i].color.alpha >> 8; stops[i].offset = _cairo_fixed_to_double (pattern->stops[i].x); } @@ -1284,378 +1157,170 @@ _cairo_pdf_surface_emit_pattern_stops (cairo_pdf_surface_t *surface, if (stops[0].offset > COLOR_STOP_EPSILON) { memcpy (allstops, stops, sizeof (cairo_pdf_color_stop_t)); stops = allstops; + stops[0].offset = 0.0; n_stops++; } - stops[0].offset = 0.0; - if (stops[n_stops-1].offset < 1.0 - COLOR_STOP_EPSILON) { memcpy (&stops[n_stops], &stops[n_stops - 1], sizeof (cairo_pdf_color_stop_t)); + stops[n_stops].offset = 1.0; n_stops++; } - stops[n_stops-1].offset = 1.0; if (n_stops == 2) { - /* no need for stitched function */ - status = cairo_pdf_surface_emit_rgb_linear_function (surface, - &stops[0], - &stops[1], - color_function); - if (status) - goto BAIL; - - if (emit_alpha) { - status = cairo_pdf_surface_emit_alpha_linear_function (surface, - &stops[0], - &stops[1], - alpha_function); - if (status) - goto BAIL; - } + /* no need for stitched function */ + function = _cairo_pdf_surface_emit_linear_colorgradient (surface, &stops[0], &stops[1]); } else { - /* multiple stops: stitch. XXX possible optimization: regulary spaced - * stops do not require stitching. XXX */ - status = _cairo_pdf_surface_emit_stitched_colorgradient (surface, - n_stops, - stops, - FALSE, - color_function); - if (status) - goto BAIL; - - if (emit_alpha) { - status = _cairo_pdf_surface_emit_stitched_colorgradient (surface, - n_stops, - stops, - TRUE, - alpha_function); - if (status) - goto BAIL; - } + /* multiple stops: stitch. XXX possible optimization: regulary spaced + * stops do not require stitching. XXX */ + function = _cairo_pdf_surface_emit_stitched_colorgradient (surface, + n_stops, + stops); } -BAIL: free (allstops); - return status; -} -static cairo_pdf_resource_t -cairo_pdf_surface_emit_transparency_group (cairo_pdf_surface_t *surface, - cairo_pdf_resource_t gradient_mask) -{ - cairo_pdf_resource_t xobj_resource, smask_resource, gstate_resource; - - xobj_resource = _cairo_pdf_surface_open_stream (surface, - TRUE, - " /Type /XObject\r\n" - " /Subtype /Form\r\n" - " /FormType 1\r\n" - " /BBox [ 0 0 %f %f ]\r\n" - " /Resources\r\n" - " << /ExtGState\r\n" - " << /a0 << /ca 1 /CA 1 >>" - " >>\r\n" - " /Pattern\r\n" - " << /res%d %d 0 R >>\r\n" - " >>\r\n" - " /Group\r\n" - " << /Type /Group\r\n" - " /S /Transparency\r\n" - " /CS /DeviceGray\r\n" - " >>\r\n", - surface->width, - surface->height, - gradient_mask.id, - gradient_mask.id); - - _cairo_output_stream_printf (surface->output, - "q\r\n" - "/a0 gs\r\n" - "/Pattern cs /res%d scn\r\n" - "0 0 %f %f re\r\n" - "f\r\n" - "Q\r\n", - gradient_mask.id, - surface->width, - surface->height); - - _cairo_pdf_surface_close_stream (surface); - - smask_resource = _cairo_pdf_surface_new_object (surface); - _cairo_output_stream_printf (surface->output, - "%d 0 obj\r\n" - "<< /Type /Mask\r\n" - " /S /Luminosity\r\n" - " /G %d 0 R\r\n" - " /BC [ 0.0 ]\r\n" - ">>\r\n" - "endobj\r\n", - smask_resource.id, - xobj_resource.id); - - /* Create GState which uses the transparency group as an SMask. */ - gstate_resource = _cairo_pdf_surface_new_object (surface); - _cairo_output_stream_printf (surface->output, - "%d 0 obj\r\n" - "<< /Type /ExtGState\r\n" - " /SMask %d 0 R\r\n" - " /ca 1\r\n" - " /CA 1\r\n" - " /AIS false\r\n" - ">>\r\n" - "endobj\r\n", - gstate_resource.id, - smask_resource.id); - - _cairo_pdf_surface_add_smask (surface, gstate_resource); - - return gstate_resource; + return function; } static cairo_status_t -_cairo_pdf_surface_emit_linear_pattern (cairo_pdf_surface_t *surface, - cairo_linear_pattern_t *pattern) +_cairo_pdf_surface_emit_linear_pattern (cairo_pdf_surface_t *surface, cairo_linear_pattern_t *pattern) { - cairo_pdf_resource_t pattern_resource, smask; - cairo_pdf_resource_t color_function, alpha_function; - double x1, y1, x2, y2; - cairo_matrix_t pat_to_pdf; - cairo_extend_t extend; - cairo_status_t status; + cairo_pdf_resource_t function, pattern_resource, alpha; + double x0, y0, x1, y1; + cairo_matrix_t p2u; - extend = cairo_pattern_get_extend (&pattern->base.base); - status = _cairo_pdf_surface_pause_content_stream (surface); - if (status) - return status; + _cairo_pdf_surface_pause_content_stream (surface); - status = _cairo_pdf_surface_emit_pattern_stops (surface, - &pattern->base, - &color_function, - &alpha_function); - if (status) - return status; + function = _cairo_pdf_surface_emit_pattern_stops (surface, &pattern->base); + if (function.id == 0) + return CAIRO_STATUS_NO_MEMORY; - pat_to_pdf = pattern->base.base.matrix; - status = cairo_matrix_invert (&pat_to_pdf); - if (status) - return status; + p2u = pattern->base.base.matrix; + cairo_matrix_invert (&p2u); - cairo_matrix_multiply (&pat_to_pdf, &pat_to_pdf, &surface->cairo_to_pdf); - x1 = _cairo_fixed_to_double (pattern->gradient.p1.x); - y1 = _cairo_fixed_to_double (pattern->gradient.p1.y); - x2 = _cairo_fixed_to_double (pattern->gradient.p2.x); - y2 = _cairo_fixed_to_double (pattern->gradient.p2.y); + x0 = _cairo_fixed_to_double (pattern->gradient.p1.x); + y0 = _cairo_fixed_to_double (pattern->gradient.p1.y); + cairo_matrix_transform_point (&p2u, &x0, &y0); + x1 = _cairo_fixed_to_double (pattern->gradient.p2.x); + y1 = _cairo_fixed_to_double (pattern->gradient.p2.y); + cairo_matrix_transform_point (&p2u, &x1, &y1); pattern_resource = _cairo_pdf_surface_new_object (surface); _cairo_output_stream_printf (surface->output, - "%d 0 obj\r\n" - "<< /Type /Pattern\r\n" - " /PatternType 2\r\n" - " /Matrix [ %f %f %f %f %f %f ]\r\n" - " /Shading\r\n" - " << /ShadingType 2\r\n" - " /ColorSpace /DeviceRGB\r\n" - " /Coords [ %f %f %f %f ]\r\n" - " /Function %d 0 R\r\n", - pattern_resource.id, - pat_to_pdf.xx, pat_to_pdf.yx, - pat_to_pdf.xy, pat_to_pdf.yy, - pat_to_pdf.x0, pat_to_pdf.y0, - x1, y1, x2, y2, - color_function.id); + "%d 0 obj\r\n" + "<< /Type /Pattern\r\n" + " /PatternType 2\r\n" + " /Matrix [ 1 0 0 -1 0 %f ]\r\n" + " /Shading\r\n" + " << /ShadingType 2\r\n" + " /ColorSpace /DeviceRGB\r\n" + " /Coords [ %f %f %f %f ]\r\n" + " /Function %d 0 R\r\n" + " /Extend [ true true ]\r\n" + " >>\r\n" + ">>\r\n" + "endobj\r\n", + pattern_resource.id, + surface->height, + x0, y0, x1, y1, + function.id); - if (extend == CAIRO_EXTEND_PAD) { - _cairo_output_stream_printf (surface->output, - " /Extend [ true true ]\r\n"); - } else { - _cairo_output_stream_printf (surface->output, - " /Extend [ false false ]\r\n"); - } + _cairo_pdf_surface_add_pattern (surface, pattern_resource); + alpha = _cairo_pdf_surface_add_alpha (surface, 1.0); + + /* Use pattern */ + /* With some work, we could separate the stroking + * or non-stroking pattern here as actually needed. */ _cairo_output_stream_printf (surface->output, - " >>\r\n" - ">>\r\n" - "endobj\r\n"); + "/Pattern CS /res%d SCN " + "/Pattern cs /res%d scn " + "/a%d gs\r\n", + pattern_resource.id, + pattern_resource.id, + alpha.id); - if (alpha_function.id == 0) { - surface->emitted_pattern.smask.id = 0; - } else { - cairo_pdf_resource_t mask_resource; + _cairo_pdf_surface_resume_content_stream (surface); - /* Create pattern for SMask. */ - mask_resource = _cairo_pdf_surface_new_object (surface); - _cairo_output_stream_printf (surface->output, - "%d 0 obj\r\n" - "<< /Type /Pattern\r\n" - " /PatternType 2\r\n" - " /Matrix [ %f %f %f %f %f %f ]\r\n" - " /Shading\r\n" - " << /ShadingType 2\r\n" - " /ColorSpace /DeviceGray\r\n" - " /Coords [ %f %f %f %f ]\r\n" - " /Function %d 0 R\r\n", - mask_resource.id, - pat_to_pdf.xx, pat_to_pdf.yx, - pat_to_pdf.xy, pat_to_pdf.yy, - pat_to_pdf.x0, pat_to_pdf.y0, - x1, y1, x2, y2, - alpha_function.id); - - if (extend == CAIRO_EXTEND_PAD) { - _cairo_output_stream_printf (surface->output, - " /Extend [ true true ]\r\n"); - } else { - _cairo_output_stream_printf (surface->output, - " /Extend [ false false ]\r\n"); - } - - _cairo_output_stream_printf (surface->output, - " >>\r\n" - ">>\r\n" - "endobj\r\n"); - status = _cairo_pdf_surface_add_pattern (surface, mask_resource); - if (status) - return status; - - smask = cairo_pdf_surface_emit_transparency_group (surface, mask_resource); - surface->emitted_pattern.smask = smask; - } - - surface->emitted_pattern.type = CAIRO_PATTERN_TYPE_LINEAR; - status = _cairo_pdf_surface_add_alpha (surface, 1, &surface->emitted_pattern.alpha); - if (status) - return status; - - surface->emitted_pattern.pattern = pattern_resource; - status = _cairo_pdf_surface_add_pattern (surface, pattern_resource); - if (status) - return status; - - return _cairo_pdf_surface_resume_content_stream (surface); + return CAIRO_STATUS_SUCCESS; } static cairo_status_t -_cairo_pdf_surface_emit_radial_pattern (cairo_pdf_surface_t *surface, - cairo_radial_pattern_t *pattern) +_cairo_pdf_surface_emit_radial_pattern (cairo_pdf_surface_t *surface, cairo_radial_pattern_t *pattern) { - cairo_pdf_resource_t pattern_resource, smask; - cairo_pdf_resource_t color_function, alpha_function; - double x1, y1, x2, y2, r1, r2; - cairo_matrix_t pat_to_pdf; - cairo_extend_t extend; - cairo_status_t status; + cairo_pdf_resource_t function, pattern_resource, alpha; + double x0, y0, x1, y1, r0, r1; + cairo_matrix_t p2u; - extend = cairo_pattern_get_extend (&pattern->base.base); - status = _cairo_pdf_surface_pause_content_stream (surface); - if (status) - return status; + _cairo_pdf_surface_pause_content_stream (surface); - status = _cairo_pdf_surface_emit_pattern_stops (surface, - &pattern->base, - &color_function, - &alpha_function); - if (status) - return status; + function = _cairo_pdf_surface_emit_pattern_stops (surface, &pattern->base); + if (function.id == 0) + return CAIRO_STATUS_NO_MEMORY; - pat_to_pdf = pattern->base.base.matrix; - status = cairo_matrix_invert (&pat_to_pdf); - if (status) - return status; + p2u = pattern->base.base.matrix; + cairo_matrix_invert (&p2u); - cairo_matrix_multiply (&pat_to_pdf, &pat_to_pdf, &surface->cairo_to_pdf); - x1 = _cairo_fixed_to_double (pattern->gradient.c1.x); - y1 = _cairo_fixed_to_double (pattern->gradient.c1.y); - r1 = _cairo_fixed_to_double (pattern->gradient.c1.radius); - x2 = _cairo_fixed_to_double (pattern->gradient.c2.x); - y2 = _cairo_fixed_to_double (pattern->gradient.c2.y); - r2 = _cairo_fixed_to_double (pattern->gradient.c2.radius); + x0 = _cairo_fixed_to_double (pattern->gradient.c1.x); + y0 = _cairo_fixed_to_double (pattern->gradient.c1.y); + r0 = _cairo_fixed_to_double (pattern->gradient.c1.radius); + cairo_matrix_transform_point (&p2u, &x0, &y0); + x1 = _cairo_fixed_to_double (pattern->gradient.c2.x); + y1 = _cairo_fixed_to_double (pattern->gradient.c2.y); + r1 = _cairo_fixed_to_double (pattern->gradient.c2.radius); + cairo_matrix_transform_point (&p2u, &x1, &y1); + /* FIXME: This is surely crack, but how should you scale a radius + * in a non-orthogonal coordinate system? */ + cairo_matrix_transform_distance (&p2u, &r0, &r1); + + /* FIXME: There is a difference between the cairo gradient extend + * semantics and PDF extend semantics. PDFs extend=false means + * that nothing is painted outside the gradient boundaries, + * whereas cairo takes this to mean that the end color is padded + * to infinity. Setting extend=true in PDF gives the cairo default + * behavoir, not yet sure how to implement the cairo mirror and + * repeat behaviour. */ pattern_resource = _cairo_pdf_surface_new_object (surface); _cairo_output_stream_printf (surface->output, - "%d 0 obj\r\n" - "<< /Type /Pattern\r\n" - " /PatternType 2\r\n" - " /Matrix [ %f %f %f %f %f %f ]\r\n" - " /Shading\r\n" - " << /ShadingType 3\r\n" - " /ColorSpace /DeviceRGB\r\n" - " /Coords [ %f %f %f %f %f %f ]\r\n" - " /Function %d 0 R\r\n", - pattern_resource.id, - pat_to_pdf.xx, pat_to_pdf.yx, - pat_to_pdf.xy, pat_to_pdf.yy, - pat_to_pdf.x0, pat_to_pdf.y0, - x1, y1, r1, x2, y2, r2, - color_function.id); + "%d 0 obj\r\n" + "<< /Type /Pattern\r\n" + " /PatternType 2\r\n" + " /Matrix [ 1 0 0 -1 0 %f ]\r\n" + " /Shading\r\n" + " << /ShadingType 3\r\n" + " /ColorSpace /DeviceRGB\r\n" + " /Coords [ %f %f %f %f %f %f ]\r\n" + " /Function %d 0 R\r\n" + " /Extend [ true true ]\r\n" + " >>\r\n" + ">>\r\n" + "endobj\r\n", + pattern_resource.id, + surface->height, + x0, y0, r0, x1, y1, r1, + function.id); - if (extend == CAIRO_EXTEND_PAD) { - _cairo_output_stream_printf (surface->output, - " /Extend [ true true ]\r\n"); - } else { - _cairo_output_stream_printf (surface->output, - " /Extend [ false false ]\r\n"); - } + _cairo_pdf_surface_add_pattern (surface, pattern_resource); + alpha = _cairo_pdf_surface_add_alpha (surface, 1.0); + + /* Use pattern */ + /* With some work, we could separate the stroking + * or non-stroking pattern here as actually needed. */ _cairo_output_stream_printf (surface->output, - " >>\r\n" - ">>\r\n" - "endobj\r\n"); + "/Pattern CS /res%d SCN " + "/Pattern cs /res%d scn " + "/a%d gs\r\n", + pattern_resource.id, + pattern_resource.id, + alpha.id); - if (alpha_function.id == 0) { - surface->emitted_pattern.smask.id = 0; - } else { - cairo_pdf_resource_t mask_resource; + _cairo_pdf_surface_resume_content_stream (surface); - /* Create pattern for SMask. */ - mask_resource = _cairo_pdf_surface_new_object (surface); - _cairo_output_stream_printf (surface->output, - "%d 0 obj\r\n" - "<< /Type /Pattern\r\n" - " /PatternType 2\r\n" - " /Matrix [ %f %f %f %f %f %f ]\r\n" - " /Shading\r\n" - " << /ShadingType 3\r\n" - " /ColorSpace /DeviceGray\r\n" - " /Coords [ %f %f %f %f %f %f ]\r\n" - " /Function %d 0 R\r\n", - mask_resource.id, - pat_to_pdf.xx, pat_to_pdf.yx, - pat_to_pdf.xy, pat_to_pdf.yy, - pat_to_pdf.x0, pat_to_pdf.y0, - x1, y1, r1, x2, y2, r2, - alpha_function.id); - - if (extend == CAIRO_EXTEND_PAD) { - _cairo_output_stream_printf (surface->output, - " /Extend [ true true ]\r\n"); - } else { - _cairo_output_stream_printf (surface->output, - " /Extend [ false false ]\r\n"); - } - - _cairo_output_stream_printf (surface->output, - " >>\r\n" - ">>\r\n" - "endobj\r\n"); - - smask = cairo_pdf_surface_emit_transparency_group (surface, mask_resource); - surface->emitted_pattern.smask = smask; - } - - surface->emitted_pattern.type = CAIRO_PATTERN_TYPE_RADIAL; - - status = _cairo_pdf_surface_add_alpha (surface, 1.0, &surface->emitted_pattern.alpha); - if (status) - return status; - - surface->emitted_pattern.pattern = pattern_resource; - - status = _cairo_pdf_surface_add_pattern (surface, pattern_resource); - if (status) - return status; - - return _cairo_pdf_surface_resume_content_stream (surface); + return CAIRO_STATUS_SUCCESS; } static cairo_status_t @@ -1673,52 +1338,13 @@ _cairo_pdf_surface_emit_pattern (cairo_pdf_surface_t *surface, cairo_pattern_t * case CAIRO_PATTERN_TYPE_RADIAL: return _cairo_pdf_surface_emit_radial_pattern (surface, (cairo_radial_pattern_t *) pattern); + } ASSERT_NOT_REACHED; return CAIRO_STATUS_PATTERN_TYPE_MISMATCH; } -static cairo_status_t -_cairo_pdf_surface_select_pattern (cairo_pdf_surface_t *surface, - cairo_bool_t is_stroke) -{ - if (surface->emitted_pattern.type == CAIRO_PATTERN_TYPE_SOLID) { - _cairo_output_stream_printf (surface->output, - "%f %f %f ", - surface->emitted_pattern.red, - surface->emitted_pattern.green, - surface->emitted_pattern.blue); - - if (is_stroke) - _cairo_output_stream_printf (surface->output, "RG "); - else - _cairo_output_stream_printf (surface->output, "rg "); - - _cairo_output_stream_printf (surface->output, - "/a%d gs\r\n", - surface->emitted_pattern.alpha); - } else { - if (is_stroke) { - _cairo_output_stream_printf (surface->output, - "/Pattern CS /res%d SCN ", - surface->emitted_pattern.pattern); - } else { - _cairo_output_stream_printf (surface->output, - "/Pattern cs /res%d scn ", - surface->emitted_pattern.pattern); - } - - _cairo_output_stream_printf (surface->output, - "/a%d gs ", - surface->emitted_pattern.alpha ); - - _cairo_output_stream_printf (surface->output, "\r\n"); - } - - return CAIRO_STATUS_SUCCESS; -} - static cairo_int_status_t _cairo_pdf_surface_copy_page (void *abstract_surface) { @@ -1763,7 +1389,6 @@ _cairo_pdf_surface_get_extents (void *abstract_surface, typedef struct _pdf_path_info { cairo_output_stream_t *output; - cairo_matrix_t *cairo_to_pdf; cairo_matrix_t *ctm_inverse; } pdf_path_info_t; @@ -1774,8 +1399,6 @@ _cairo_pdf_path_move_to (void *closure, cairo_point_t *point) double x = _cairo_fixed_to_double (point->x); double y = _cairo_fixed_to_double (point->y); - if (info->cairo_to_pdf) - cairo_matrix_transform_point (info->cairo_to_pdf, &x, &y); if (info->ctm_inverse) cairo_matrix_transform_point (info->ctm_inverse, &x, &y); @@ -1792,8 +1415,6 @@ _cairo_pdf_path_line_to (void *closure, cairo_point_t *point) double x = _cairo_fixed_to_double (point->x); double y = _cairo_fixed_to_double (point->y); - if (info->cairo_to_pdf) - cairo_matrix_transform_point (info->cairo_to_pdf, &x, &y); if (info->ctm_inverse) cairo_matrix_transform_point (info->ctm_inverse, &x, &y); @@ -1816,11 +1437,6 @@ _cairo_pdf_path_curve_to (void *closure, double dx = _cairo_fixed_to_double (d->x); double dy = _cairo_fixed_to_double (d->y); - if (info->cairo_to_pdf) { - cairo_matrix_transform_point (info->cairo_to_pdf, &bx, &by); - cairo_matrix_transform_point (info->cairo_to_pdf, &cx, &cy); - cairo_matrix_transform_point (info->cairo_to_pdf, &dx, &dy); - } if (info->ctm_inverse) { cairo_matrix_transform_point (info->ctm_inverse, &bx, &by); cairo_matrix_transform_point (info->ctm_inverse, &cx, &cy); @@ -1869,7 +1485,6 @@ _cairo_pdf_surface_intersect_clip_path (void *abstract_surface, } info.output = surface->output; - info.cairo_to_pdf = &surface->cairo_to_pdf; info.ctm_inverse = NULL; status = _cairo_path_fixed_interpret (path, @@ -1931,10 +1546,10 @@ _cairo_pdf_surface_write_info (cairo_pdf_surface_t *surface) static void _cairo_pdf_surface_write_pages (cairo_pdf_surface_t *surface) { - cairo_pdf_resource_t page, *res, smask; + cairo_pdf_resource_t page, *res; cairo_pdf_font_t font; int num_pages, num_fonts, i; - int num_alphas, num_smasks, num_resources; + int num_alphas, num_resources; double alpha; _cairo_pdf_surface_update_object (surface, surface->pages_resource); @@ -1956,25 +1571,19 @@ _cairo_pdf_surface_write_pages (cairo_pdf_surface_t *surface) _cairo_output_stream_printf (surface->output, " /Resources <<\r\n"); num_alphas = _cairo_array_num_elements (&surface->alphas); - num_smasks = _cairo_array_num_elements (&surface->smasks); - if (num_alphas > 0 || num_smasks > 0) { + if (num_alphas > 0) { _cairo_output_stream_printf (surface->output, " /ExtGState <<\r\n"); for (i = 0; i < num_alphas; i++) { + /* With some work, we could separate the stroking + * or non-stroking alpha here as actually needed. */ _cairo_array_copy_element (&surface->alphas, i, &alpha); _cairo_output_stream_printf (surface->output, " /a%d << /CA %f /ca %f >>\r\n", i, alpha, alpha); } - for (i = 0; i < num_smasks; i++) { - _cairo_array_copy_element (&surface->smasks, i, &smask); - _cairo_output_stream_printf (surface->output, - " /sm%d %d 0 R\r\n", - smask.id, smask.id); - } - _cairo_output_stream_printf (surface->output, " >>\r\n"); } @@ -2010,20 +1619,14 @@ _cairo_pdf_surface_write_pages (cairo_pdf_surface_t *surface) " >>\r\n"); } + _cairo_output_stream_printf (surface->output," /Font <<\r\n"); num_fonts = _cairo_array_num_elements (&surface->fonts); - if (num_fonts > 0) { - _cairo_output_stream_printf (surface->output," /Font <<\r\n"); - num_fonts = _cairo_array_num_elements (&surface->fonts); - for (i = 0; i < num_fonts; i++) { - _cairo_array_copy_element (&surface->fonts, i, &font); - _cairo_output_stream_printf (surface->output, - " /CairoFont-%d-%d %d 0 R\r\n", - font.font_id, - font.subset_id, - font.subset_resource.id); - } - _cairo_output_stream_printf (surface->output, " >>\r\n"); + for (i = 0; i < num_fonts; i++) { + _cairo_array_copy_element (&surface->fonts, i, &font); + _cairo_output_stream_printf (surface->output, " /CairoFont-%d-%d %d 0 R\r\n", + font.font_id, font.subset_id, font.subset_resource.id); } + _cairo_output_stream_printf (surface->output, " >>\r\n"); _cairo_output_stream_printf (surface->output, " >>\r\n"); @@ -2036,14 +1639,12 @@ _cairo_pdf_surface_write_pages (cairo_pdf_surface_t *surface) } static cairo_pdf_resource_t -_cairo_pdf_surface_emit_to_unicode_stream (cairo_pdf_surface_t *surface, - cairo_scaled_font_subset_t *font_subset, - cairo_bool_t is_composite) +_cairo_pdf_surface_emit_toUnicode_stream (cairo_pdf_surface_t *surface, + cairo_scaled_font_subset_t *font_subset) { const cairo_scaled_font_backend_t *backend; cairo_pdf_resource_t stream; - unsigned int i, num_bfchar; - cairo_status_t status; + unsigned int i; if (font_subset->to_unicode == NULL) { stream.id = 0; @@ -2065,86 +1666,88 @@ _cairo_pdf_surface_emit_to_unicode_stream (cairo_pdf_surface_t *surface, "12 dict begin\r\n" "begincmap\r\n" "/CIDSystemInfo\r\n" - "<< /Registry (Adobe)\r\n" - " /Ordering (UCS)\r\n" + "<< /Registry (Cairo)\r\n" + " /Ordering (ToUnicode-%d-%d)\r\n" " /Supplement 0\r\n" ">> def\r\n" - "/CMapName /Adobe-Identity-UCS def\r\n" + "/CMapName /Cairo-ToUnicode-%d-%d def\r\n" "/CMapType 2 def\r\n" - "1 begincodespacerange\r\n"); + "1 begincodespacerange\r\n" + "<00> \r\n" + "endcodespacerange\r\n", + font_subset->font_id, + font_subset->subset_id, + font_subset->font_id, + font_subset->subset_id); - if (is_composite) { - _cairo_output_stream_printf (surface->output, - "<0000> \r\n"); - } else { - _cairo_output_stream_printf (surface->output, - "<00> \r\n"); - } - - _cairo_output_stream_printf (surface->output, - "endcodespacerange\r\n"); - - num_bfchar = font_subset->num_glyphs - 1; /* The CMap specification has a limit of 100 characters per beginbfchar operator */ _cairo_output_stream_printf (surface->output, "%d beginbfchar\r\n", - num_bfchar > 100 ? 100 : num_bfchar); - for (i = 0; i < num_bfchar; i++) { + font_subset->num_glyphs > 100 ? 100 : font_subset->num_glyphs); + for (i = 0; i < font_subset->num_glyphs; i++) { if (i != 0 && i % 100 == 0) { _cairo_output_stream_printf (surface->output, "endbfchar\r\n" "%d beginbfchar\r\n", - num_bfchar - i > 100 ? 100 : num_bfchar - i); - } - if (is_composite) { - _cairo_output_stream_printf (surface->output, - "<%04x> <%04x>\r\n", - i + 1, font_subset->to_unicode[i + 1]); - } else { - _cairo_output_stream_printf (surface->output, - "<%02x> <%04x>\r\n", - i + 1, font_subset->to_unicode[i + 1]); + font_subset->num_glyphs - i > 100 ? 100 : font_subset->num_glyphs - i); } + _cairo_output_stream_printf (surface->output, + "<%02x> <%04x>\r\n", + i, font_subset->to_unicode[i]); } _cairo_output_stream_printf (surface->output, "endbfchar\r\n"); + if (font_subset->num_glyphs < 256) { + _cairo_output_stream_printf (surface->output, + "1 beginnotdefrange\r\n" + "<%02x> 0\r\n" + "endnotdefrange\r\n", + font_subset->num_glyphs); + } + _cairo_output_stream_printf (surface->output, - "endcmap\r\n" - "CMapName currentdict /CMap defineresource pop\r\n" - "end\r\n" + "endcmap\r\n" + "CMapName currentdict /CMap defineresource pop\r\n" + "end\r\n" "end\r\n"); - status = _cairo_pdf_surface_close_stream (surface); - if (status) - stream.id = 0; + _cairo_pdf_surface_close_stream (surface); return stream; } static cairo_status_t -_cairo_pdf_surface_emit_cff_font (cairo_pdf_surface_t *surface, - cairo_scaled_font_subset_t *font_subset, - cairo_cff_subset_t *subset) +_cairo_pdf_surface_emit_cff_font_subset (cairo_pdf_surface_t *surface, + cairo_scaled_font_subset_t *font_subset) { - cairo_pdf_resource_t stream, descriptor, cidfont_dict; - cairo_pdf_resource_t subset_resource, to_unicode_stream; + cairo_pdf_resource_t stream, descriptor, subset_resource, to_unicode_stream; + cairo_status_t status; cairo_pdf_font_t font; + cairo_cff_subset_t subset; unsigned long compressed_length; char *compressed; unsigned int i; - cairo_status_t status; + char name[64]; - compressed = compress_dup (subset->data, subset->data_length, &compressed_length); - if (compressed == NULL) + snprintf (name, sizeof name, "CairoFont-%d-%d", + font_subset->font_id, font_subset->subset_id); + status = _cairo_cff_subset_init (&subset, name, font_subset); + if (status) + return status; + + compressed = compress_dup (subset.data, subset.data_length, &compressed_length); + if (compressed == NULL) { + _cairo_cff_subset_fini (&subset); return CAIRO_STATUS_NO_MEMORY; + } stream = _cairo_pdf_surface_new_object (surface); _cairo_output_stream_printf (surface->output, "%d 0 obj\r\n" "<< /Filter /FlateDecode\r\n" " /Length %lu\r\n" - " /Subtype /CIDFontType0C\r\n" + " /Subtype /Type1C\r\n" ">>\r\n" "stream\r\n", stream.id, @@ -2156,7 +1759,7 @@ _cairo_pdf_surface_emit_cff_font (cairo_pdf_surface_t *surface, "endobj\r\n"); free (compressed); - to_unicode_stream = _cairo_pdf_surface_emit_to_unicode_stream (surface, font_subset, TRUE); + to_unicode_stream = _cairo_pdf_surface_emit_toUnicode_stream (surface, font_subset); descriptor = _cairo_pdf_surface_new_object (surface); _cairo_output_stream_printf (surface->output, @@ -2175,57 +1778,41 @@ _cairo_pdf_surface_emit_cff_font (cairo_pdf_surface_t *surface, ">>\r\n" "endobj\r\n", descriptor.id, - subset->base_font, - subset->x_min, - subset->y_min, - subset->x_max, - subset->y_max, - subset->ascent, - subset->descent, + subset.base_font, + subset.x_min, + subset.y_min, + subset.x_max, + subset.y_max, + subset.ascent, + subset.descent, stream.id); - cidfont_dict = _cairo_pdf_surface_new_object (surface); - _cairo_output_stream_printf (surface->output, - "%d 0 obj\r\n" - "<< /Type /Font\r\n" - " /Subtype /CIDFontType0\r\n" - " /BaseFont /%s\r\n" - " /CIDSystemInfo\r\n" - " << /Registry (Adobe)\r\n" - " /Ordering (Identity)\r\n" - " /Supplement 0\r\n" - " >>\r\n" - " /FontDescriptor %d 0 R\r\n" - " /W [0 [", - cidfont_dict.id, - subset->base_font, - descriptor.id); - - for (i = 0; i < font_subset->num_glyphs; i++) - _cairo_output_stream_printf (surface->output, - " %d", - subset->widths[i]); - - _cairo_output_stream_printf (surface->output, - " ]]\r\n" - ">>\r\n" - "endobj\r\n"); - subset_resource = _cairo_pdf_surface_new_object (surface); _cairo_output_stream_printf (surface->output, "%d 0 obj\r\n" "<< /Type /Font\r\n" - " /Subtype /Type0\r\n" + " /Subtype /Type1\r\n" " /BaseFont /%s\r\n" - " /Encoding /Identity-H\r\n" - " /DescendantFonts [ %d 0 R]\r\n", + " /FirstChar 0\r\n" + " /LastChar %d\r\n" + " /FontDescriptor %d 0 R\r\n" + " /Widths [", subset_resource.id, - subset->base_font, - cidfont_dict.id); + subset.base_font, + font_subset->num_glyphs - 1, + descriptor.id); + + for (i = 0; i < font_subset->num_glyphs; i++) + _cairo_output_stream_printf (surface->output, + " %d", + subset.widths[i]); + + _cairo_output_stream_printf (surface->output, + " ]\r\n"); if (to_unicode_stream.id != 0) _cairo_output_stream_printf (surface->output, - " /ToUnicode %d 0 R\r\n", + " /ToUnicode %d 0 R\r\n", to_unicode_stream.id); _cairo_output_stream_printf (surface->output, @@ -2235,51 +1822,11 @@ _cairo_pdf_surface_emit_cff_font (cairo_pdf_surface_t *surface, font.font_id = font_subset->font_id; font.subset_id = font_subset->subset_id; font.subset_resource = subset_resource; - status = _cairo_array_append (&surface->fonts, &font); - - return status; -} - -static cairo_status_t -_cairo_pdf_surface_emit_cff_font_subset (cairo_pdf_surface_t *surface, - cairo_scaled_font_subset_t *font_subset) -{ - cairo_status_t status; - cairo_cff_subset_t subset; - char name[64]; - - snprintf (name, sizeof name, "CairoFont-%d-%d", - font_subset->font_id, font_subset->subset_id); - status = _cairo_cff_subset_init (&subset, name, font_subset); - if (status) - return status; - - status = _cairo_pdf_surface_emit_cff_font (surface, font_subset, &subset); + _cairo_array_append (&surface->fonts, &font); _cairo_cff_subset_fini (&subset); - return status; -} - -static cairo_status_t -_cairo_pdf_surface_emit_cff_fallback_font (cairo_pdf_surface_t *surface, - cairo_scaled_font_subset_t *font_subset) -{ - cairo_status_t status; - cairo_cff_subset_t subset; - char name[64]; - - snprintf (name, sizeof name, "CairoFont-%d-%d", - font_subset->font_id, font_subset->subset_id); - status = _cairo_cff_fallback_init (&subset, name, font_subset); - if (status) - return status; - - status = _cairo_pdf_surface_emit_cff_font (surface, font_subset, &subset); - - _cairo_cff_fallback_fini (&subset); - - return status; + return CAIRO_STATUS_SUCCESS; } static cairo_status_t @@ -2321,7 +1868,7 @@ _cairo_pdf_surface_emit_type1_font (cairo_pdf_surface_t *surface, "endobj\r\n"); free (compressed); - to_unicode_stream = _cairo_pdf_surface_emit_to_unicode_stream (surface, font_subset, FALSE); + to_unicode_stream = _cairo_pdf_surface_emit_toUnicode_stream (surface, font_subset); descriptor = _cairo_pdf_surface_new_object (surface); _cairo_output_stream_printf (surface->output, @@ -2384,7 +1931,9 @@ _cairo_pdf_surface_emit_type1_font (cairo_pdf_surface_t *surface, font.font_id = font_subset->font_id; font.subset_id = font_subset->subset_id; font.subset_resource = subset_resource; - return _cairo_array_append (&surface->fonts, &font); + _cairo_array_append (&surface->fonts, &font); + + return CAIRO_STATUS_SUCCESS; } #if CAIRO_HAS_FT_FONT @@ -2435,8 +1984,7 @@ static cairo_status_t _cairo_pdf_surface_emit_truetype_font_subset (cairo_pdf_surface_t *surface, cairo_scaled_font_subset_t *font_subset) { - cairo_pdf_resource_t stream, descriptor, cidfont_dict; - cairo_pdf_resource_t subset_resource, to_unicode_stream; + cairo_pdf_resource_t stream, descriptor, encoding, subset_resource, to_unicode_stream; cairo_status_t status; cairo_pdf_font_t font; cairo_truetype_subset_t subset; @@ -2473,7 +2021,7 @@ _cairo_pdf_surface_emit_truetype_font_subset (cairo_pdf_surface_t *surface, "endobj\r\n"); free (compressed); - to_unicode_stream = _cairo_pdf_surface_emit_to_unicode_stream (surface, font_subset, TRUE); + to_unicode_stream = _cairo_pdf_surface_emit_toUnicode_stream (surface, font_subset); descriptor = _cairo_pdf_surface_new_object (surface); _cairo_output_stream_printf (surface->output, @@ -2502,30 +2050,18 @@ _cairo_pdf_surface_emit_truetype_font_subset (cairo_pdf_surface_t *surface, (long)(subset.y_max*PDF_UNITS_PER_EM), stream.id); - cidfont_dict = _cairo_pdf_surface_new_object (surface); + encoding = _cairo_pdf_surface_new_object (surface); _cairo_output_stream_printf (surface->output, - "%d 0 obj\r\n" - "<< /Type /Font\r\n" - " /Subtype /CIDFontType2\r\n" - " /BaseFont /%s\r\n" - " /CIDSystemInfo\r\n" - " << /Registry (Adobe)\r\n" - " /Ordering (Identity)\r\n" - " /Supplement 0\r\n" - " >>\r\n" - " /FontDescriptor %d 0 R\r\n" - " /W [0 [", - cidfont_dict.id, - subset.base_font, - descriptor.id); + "%d 0 obj\r\n" + "<< /Type /Encoding\r\n" + " /Differences [0 ", + encoding.id); for (i = 0; i < font_subset->num_glyphs; i++) - _cairo_output_stream_printf (surface->output, - " %ld", - (long)(subset.widths[i]*PDF_UNITS_PER_EM)); + _cairo_output_stream_printf (surface->output, "/g%d ", i); _cairo_output_stream_printf (surface->output, - " ]]\r\n" + " ]\r\n" ">>\r\n" "endobj\r\n"); @@ -2533,17 +2069,30 @@ _cairo_pdf_surface_emit_truetype_font_subset (cairo_pdf_surface_t *surface, _cairo_output_stream_printf (surface->output, "%d 0 obj\r\n" "<< /Type /Font\r\n" - " /Subtype /Type0\r\n" + " /Subtype /TrueType\r\n" " /BaseFont /%s\r\n" - " /Encoding /Identity-H\r\n" - " /DescendantFonts [ %d 0 R]\r\n", + " /FirstChar 0\r\n" + " /LastChar %d\r\n" + " /FontDescriptor %d 0 R\r\n" + " /Encoding %d 0 R\r\n" + " /Widths [", subset_resource.id, subset.base_font, - cidfont_dict.id); + font_subset->num_glyphs - 1, + descriptor.id, + encoding.id); + + for (i = 0; i < font_subset->num_glyphs; i++) + _cairo_output_stream_printf (surface->output, + " %ld", + (long)(subset.widths[i]*PDF_UNITS_PER_EM)); + + _cairo_output_stream_printf (surface->output, + " ]\r\n"); if (to_unicode_stream.id != 0) _cairo_output_stream_printf (surface->output, - " /ToUnicode %d 0 R\r\n", + " /ToUnicode %d 0 R\r\n", to_unicode_stream.id); _cairo_output_stream_printf (surface->output, @@ -2553,11 +2102,11 @@ _cairo_pdf_surface_emit_truetype_font_subset (cairo_pdf_surface_t *surface, font.font_id = font_subset->font_id; font.subset_id = font_subset->subset_id; font.subset_resource = subset_resource; - status = _cairo_array_append (&surface->fonts, &font); + _cairo_array_append (&surface->fonts, &font); _cairo_truetype_subset_fini (&subset); - return status; + return CAIRO_STATUS_SUCCESS; } static cairo_int_status_t @@ -2588,7 +2137,6 @@ _cairo_pdf_surface_emit_outline_glyph (cairo_pdf_surface_t *surface, -_cairo_fixed_to_double (scaled_glyph->bbox.p1.y)); info.output = surface->output; - info.cairo_to_pdf = &surface->cairo_to_pdf; info.ctm_inverse = NULL; status = _cairo_path_fixed_interpret (scaled_glyph->path, @@ -2602,7 +2150,9 @@ _cairo_pdf_surface_emit_outline_glyph (cairo_pdf_surface_t *surface, _cairo_output_stream_printf (surface->output, " f"); - return _cairo_pdf_surface_close_stream (surface); + _cairo_pdf_surface_close_stream (surface); + + return CAIRO_STATUS_SUCCESS; } static cairo_int_status_t @@ -2679,7 +2229,7 @@ _cairo_pdf_surface_emit_bitmap_glyph (cairo_pdf_surface_t *surface, _cairo_output_stream_printf (surface->output, "\r\nEI\r\n"); - status = _cairo_pdf_surface_close_stream (surface); + _cairo_pdf_surface_close_stream (surface); if (image != scaled_glyph->surface) cairo_surface_destroy (&image->base); @@ -2717,7 +2267,6 @@ static cairo_status_t _cairo_pdf_surface_emit_type3_font_subset (cairo_pdf_surface_t *surface, cairo_scaled_font_subset_t *font_subset) { - cairo_status_t status; cairo_pdf_resource_t *glyphs, encoding, char_procs, subset_resource, to_unicode_stream; cairo_pdf_font_t font; cairo_matrix_t matrix; @@ -2790,13 +2339,11 @@ _cairo_pdf_surface_emit_type3_font_subset (cairo_pdf_surface_t *surface, free (glyphs); - to_unicode_stream = _cairo_pdf_surface_emit_to_unicode_stream (surface, font_subset, FALSE); + to_unicode_stream = _cairo_pdf_surface_emit_toUnicode_stream (surface, font_subset); subset_resource = _cairo_pdf_surface_new_object (surface); matrix = font_subset->scaled_font->scale; - status = cairo_matrix_invert (&matrix); - /* _cairo_scaled_font_init ensures the matrix is invertible */ - assert (status == CAIRO_STATUS_SUCCESS); + cairo_matrix_invert (&matrix); _cairo_output_stream_printf (surface->output, "%d 0 obj\r\n" "<< /Type /Font\r\n" @@ -2840,7 +2387,9 @@ _cairo_pdf_surface_emit_type3_font_subset (cairo_pdf_surface_t *surface, font.font_id = font_subset->font_id; font.subset_id = font_subset->subset_id; font.subset_resource = subset_resource; - return _cairo_array_append (&surface->fonts, &font); + _cairo_array_append (&surface->fonts, &font); + + return CAIRO_STATUS_SUCCESS; } static void @@ -2850,29 +2399,23 @@ _cairo_pdf_surface_emit_unscaled_font_subset (cairo_scaled_font_subset_t *font_s cairo_pdf_surface_t *surface = closure; cairo_status_t status; - if (font_subset->is_composite) { - status = _cairo_pdf_surface_emit_cff_font_subset (surface, font_subset); - if (status != CAIRO_INT_STATUS_UNSUPPORTED) - return; + status = _cairo_pdf_surface_emit_cff_font_subset (surface, font_subset); + if (status != CAIRO_INT_STATUS_UNSUPPORTED) + return; - status = _cairo_pdf_surface_emit_truetype_font_subset (surface, font_subset); - if (status != CAIRO_INT_STATUS_UNSUPPORTED) - return; - - status = _cairo_pdf_surface_emit_cff_fallback_font (surface, font_subset); - if (status != CAIRO_INT_STATUS_UNSUPPORTED) - return; - } else { #if CAIRO_HAS_FT_FONT - status = _cairo_pdf_surface_emit_type1_font_subset (surface, font_subset); - if (status != CAIRO_INT_STATUS_UNSUPPORTED) - return; + status = _cairo_pdf_surface_emit_type1_font_subset (surface, font_subset); + if (status != CAIRO_INT_STATUS_UNSUPPORTED) + return; #endif - status = _cairo_pdf_surface_emit_type1_fallback_font (surface, font_subset); - if (status != CAIRO_INT_STATUS_UNSUPPORTED) - return; - } + status = _cairo_pdf_surface_emit_truetype_font_subset (surface, font_subset); + if (status != CAIRO_INT_STATUS_UNSUPPORTED) + return; + + status = _cairo_pdf_surface_emit_type1_fallback_font (surface, font_subset); + if (status != CAIRO_INT_STATUS_UNSUPPORTED) + return; } static void @@ -2966,9 +2509,7 @@ _cairo_pdf_surface_write_page (cairo_pdf_surface_t *surface) surface->has_clip = FALSE; } - status = _cairo_pdf_surface_close_stream (surface); - if (status) - return status; + _cairo_pdf_surface_close_stream (surface); page = _cairo_pdf_surface_new_object (surface); _cairo_output_stream_printf (surface->output, @@ -3041,62 +2582,44 @@ _surface_pattern_supported (cairo_surface_pattern_t *pattern) return FALSE; } -static cairo_bool_t -_gradient_pattern_supported (cairo_pattern_t *pattern) -{ - cairo_extend_t extend; - - extend = cairo_pattern_get_extend (pattern); - - if (extend == CAIRO_EXTEND_REPEAT || - extend == CAIRO_EXTEND_REFLECT) { - return FALSE; - } - - /* Radial gradients are currently only supported when one circle - * is inside the other. */ - if (pattern->type == CAIRO_PATTERN_TYPE_RADIAL) { - double x1, y1, x2, y2, r1, r2, d; - cairo_radial_pattern_t *radial = (cairo_radial_pattern_t *) pattern; - - x1 = _cairo_fixed_to_double (radial->gradient.c1.x); - y1 = _cairo_fixed_to_double (radial->gradient.c1.y); - r1 = _cairo_fixed_to_double (radial->gradient.c1.radius); - x2 = _cairo_fixed_to_double (radial->gradient.c2.x); - y2 = _cairo_fixed_to_double (radial->gradient.c2.y); - r2 = _cairo_fixed_to_double (radial->gradient.c2.radius); - - d = sqrt((x2 - x1)*(x2 - x1) + (y2 - y1)*(y2 - y1)); - if (d > fabs(r2 - r1)) { - return FALSE; - } - } - - return TRUE; -} - static cairo_bool_t _pattern_supported (cairo_pattern_t *pattern) { if (pattern->type == CAIRO_PATTERN_TYPE_SOLID) return TRUE; - if (pattern->type == CAIRO_PATTERN_TYPE_LINEAR || - pattern->type == CAIRO_PATTERN_TYPE_RADIAL) - return _gradient_pattern_supported (pattern); - if (pattern->type == CAIRO_PATTERN_TYPE_SURFACE) return _surface_pattern_supported ((cairo_surface_pattern_t *) pattern); return FALSE; } +static cairo_bool_t cairo_pdf_force_fallbacks = FALSE; + +/** + * _cairo_pdf_test_force_fallbacks + * + * Force the PDF surface backend to use image fallbacks for every + * operation. + * + * + * This function is only intended for internal + * testing use within the cairo distribution. It is not installed in + * any public header file. + * + **/ +void +_cairo_pdf_test_force_fallbacks (void) +{ + cairo_pdf_force_fallbacks = TRUE; +} + static cairo_int_status_t -_cairo_pdf_surface_operation_supported (cairo_pdf_surface_t *surface, +__cairo_pdf_surface_operation_supported (cairo_pdf_surface_t *surface, cairo_operator_t op, cairo_pattern_t *pattern) { - if (surface->force_fallbacks) + if (cairo_pdf_force_fallbacks) return FALSE; if (! _pattern_supported (pattern)) @@ -3115,7 +2638,7 @@ _cairo_pdf_surface_analyze_operation (cairo_pdf_surface_t *surface, cairo_operator_t op, cairo_pattern_t *pattern) { - if (_cairo_pdf_surface_operation_supported (surface, op, pattern)) + if (__cairo_pdf_surface_operation_supported (surface, op, pattern)) return CAIRO_STATUS_SUCCESS; else return CAIRO_INT_STATUS_UNSUPPORTED; @@ -3127,7 +2650,6 @@ _cairo_pdf_surface_paint (void *abstract_surface, cairo_pattern_t *source) { cairo_pdf_surface_t *surface = abstract_surface; - cairo_pdf_resource_t group = {0}; /* squelch bogus compiler warning */ cairo_status_t status; if (surface->paginated_mode == CAIRO_PAGINATED_MODE_ANALYZE) @@ -3140,38 +2662,17 @@ _cairo_pdf_surface_paint (void *abstract_surface, * possible only because there is nothing between the fallback * images and the paper, nor is anything painted above. */ /* - assert (_cairo_pdf_surface_operation_supported (op, source)); + assert (__cairo_pdf_surface_operation_supported (op, source)); */ status = _cairo_pdf_surface_emit_pattern (surface, source); if (status) return status; - if (surface->emitted_pattern.smask.id != 0) { - status = _cairo_pdf_surface_begin_group (surface, &group); - if (status) - return status; - } else { - _cairo_output_stream_printf (surface->output, "q "); - } - - _cairo_pdf_surface_select_pattern (surface, FALSE); - _cairo_output_stream_printf (surface->output, "0 0 %f %f re f\r\n", surface->width, surface->height); - if (surface->emitted_pattern.smask.id != 0) { - _cairo_pdf_surface_end_group (surface); - - _cairo_output_stream_printf (surface->output, - "q /sm%d gs /res%d Do Q\r\n", - surface->emitted_pattern.smask, - group.id); - } else { - _cairo_output_stream_printf (surface->output, "Q\r\n"); - } - return _cairo_output_stream_get_status (surface->output); } @@ -3269,44 +2770,30 @@ _cairo_pdf_surface_stroke (void *abstract_surface, cairo_antialias_t antialias) { cairo_pdf_surface_t *surface = abstract_surface; - cairo_pdf_resource_t group = {0}; /* squelch bogus compiler warning */ pdf_path_info_t info; cairo_status_t status; - cairo_matrix_t m; if (surface->paginated_mode == CAIRO_PAGINATED_MODE_ANALYZE) return _cairo_pdf_surface_analyze_operation (surface, op, source); - assert (_cairo_pdf_surface_operation_supported (surface, op, source)); + assert (__cairo_pdf_surface_operation_supported (surface, op, source)); status = _cairo_pdf_surface_emit_pattern (surface, source); if (status) return status; - if (surface->emitted_pattern.smask.id != 0) { - status = _cairo_pdf_surface_begin_group (surface, &group); - if (status) - return status; - } else { - _cairo_output_stream_printf (surface->output, "q "); - } - - _cairo_pdf_surface_select_pattern (surface, TRUE); - status = _cairo_pdf_surface_emit_stroke_style (surface, style); if (status) return status; info.output = surface->output; - info.cairo_to_pdf = NULL; info.ctm_inverse = ctm_inverse; - cairo_matrix_multiply (&m, ctm, &surface->cairo_to_pdf); _cairo_output_stream_printf (surface->output, "q %f %f %f %f %f %f cm\r\n", - m.xx, m.yx, m.xy, m.yy, - m.x0, m.y0); + ctm->xx, ctm->yx, ctm->xy, ctm->yy, + ctm->x0, ctm->y0); status = _cairo_path_fixed_interpret (path, CAIRO_DIRECTION_FORWARD, @@ -3318,17 +2805,6 @@ _cairo_pdf_surface_stroke (void *abstract_surface, _cairo_output_stream_printf (surface->output, "S Q\r\n"); - if (surface->emitted_pattern.smask.id != 0) { - _cairo_pdf_surface_end_group (surface); - - _cairo_output_stream_printf (surface->output, - "q /sm%d gs /res%d Do Q\r\n", - surface->emitted_pattern.smask, - group.id); - } else { - _cairo_output_stream_printf (surface->output, "Q\r\n"); - } - return status; } @@ -3342,7 +2818,6 @@ _cairo_pdf_surface_fill (void *abstract_surface, cairo_antialias_t antialias) { cairo_pdf_surface_t *surface = abstract_surface; - cairo_pdf_resource_t group = {0}; /* squelch bogus compiler warning */ const char *pdf_operator; cairo_status_t status; pdf_path_info_t info; @@ -3350,24 +2825,15 @@ _cairo_pdf_surface_fill (void *abstract_surface, if (surface->paginated_mode == CAIRO_PAGINATED_MODE_ANALYZE) return _cairo_pdf_surface_analyze_operation (surface, op, source); - assert (_cairo_pdf_surface_operation_supported (surface, op, source)); + assert (__cairo_pdf_surface_operation_supported (surface, op, source)); status = _cairo_pdf_surface_emit_pattern (surface, source); if (status) return status; - if (surface->emitted_pattern.smask.id != 0) { - status = _cairo_pdf_surface_begin_group (surface, &group); - if (status) - return status; - } else { - _cairo_output_stream_printf (surface->output, "q "); - } - - _cairo_pdf_surface_select_pattern (surface, FALSE); info.output = surface->output; - info.cairo_to_pdf = &surface->cairo_to_pdf; info.ctm_inverse = NULL; + status = _cairo_path_fixed_interpret (path, CAIRO_DIRECTION_FORWARD, _cairo_pdf_path_move_to, @@ -3391,22 +2857,9 @@ _cairo_pdf_surface_fill (void *abstract_surface, "%s\r\n", pdf_operator); - if (surface->emitted_pattern.smask.id != 0) { - _cairo_pdf_surface_end_group (surface); - - _cairo_output_stream_printf (surface->output, - "q /sm%d gs /res%d Do Q\r\n", - surface->emitted_pattern.smask, - group.id); - } else { - _cairo_output_stream_printf (surface->output, "Q\r\n"); - } - return status; } -#define GLYPH_POSITION_TOLERANCE 0.001 - static cairo_int_status_t _cairo_pdf_surface_show_glyphs (void *abstract_surface, cairo_operator_t op, @@ -3416,34 +2869,21 @@ _cairo_pdf_surface_show_glyphs (void *abstract_surface, cairo_scaled_font_t *scaled_font) { cairo_pdf_surface_t *surface = abstract_surface; - cairo_pdf_resource_t group = {0}; /* squelch bogus compiler warning */ unsigned int current_subset_id = (unsigned int)-1; - cairo_scaled_font_subsets_glyph_t subset_glyph; - cairo_bool_t diagonal, in_TJ; + unsigned int font_id, subset_id, subset_glyph_index; + cairo_bool_t diagonal; cairo_status_t status; - double Tlm_x = 0, Tlm_y = 0; - double Tm_x = 0, y; - int i, hex_width; + int i; if (surface->paginated_mode == CAIRO_PAGINATED_MODE_ANALYZE) return _cairo_pdf_surface_analyze_operation (surface, op, source); - assert (_cairo_pdf_surface_operation_supported (surface, op, source)); + assert (__cairo_pdf_surface_operation_supported (surface, op, source)); status = _cairo_pdf_surface_emit_pattern (surface, source); if (status) return status; - if (surface->emitted_pattern.smask.id != 0) { - status = _cairo_pdf_surface_begin_group (surface, &group); - if (status) - return status; - } else { - _cairo_output_stream_printf (surface->output, "q "); - } - - _cairo_pdf_surface_select_pattern (surface, FALSE); - _cairo_output_stream_printf (surface->output, "BT\r\n"); @@ -3453,146 +2893,41 @@ _cairo_pdf_surface_show_glyphs (void *abstract_surface, else diagonal = FALSE; - in_TJ = FALSE; for (i = 0; i < num_glyphs; i++) { - status = _cairo_scaled_font_subsets_map_glyph (surface->font_subsets, - scaled_font, glyphs[i].index, - &subset_glyph); + status = _cairo_scaled_font_subsets_map_glyph (surface->font_subsets, + scaled_font, glyphs[i].index, + &font_id, &subset_id, &subset_glyph_index); if (status) - return status; + return status; - if (subset_glyph.is_composite) - hex_width = 4; - else - hex_width = 2; + if (subset_id != current_subset_id) + _cairo_output_stream_printf (surface->output, + "/CairoFont-%d-%d 1 Tf\r\n", + font_id, subset_id); - if (subset_glyph.is_scaled == FALSE) { - y = 0.0; - cairo_matrix_transform_distance (&scaled_font->scale, - &subset_glyph.x_advance, - &y); - } - - if (subset_glyph.subset_id != current_subset_id) { - if (in_TJ) { - _cairo_output_stream_printf (surface->output, ">] TJ\r\n"); - in_TJ = FALSE; - } + if (subset_id != current_subset_id || !diagonal) { _cairo_output_stream_printf (surface->output, - "/CairoFont-%d-%d 1 Tf\r\n", - subset_glyph.font_id, - subset_glyph.subset_id); - } - - if (subset_glyph.subset_id != current_subset_id || !diagonal) { - _cairo_output_stream_printf (surface->output, - "%f %f %f %f %f %f Tm\r\n", + "%f %f %f %f %f %f Tm <%02x> Tj\r\n", scaled_font->scale.xx, - -scaled_font->scale.yx, + scaled_font->scale.yx, -scaled_font->scale.xy, - scaled_font->scale.yy, + -scaled_font->scale.yy, glyphs[i].x, - surface->height - glyphs[i].y); - current_subset_id = subset_glyph.subset_id; - Tlm_x = glyphs[i].x; - Tlm_y = glyphs[i].y; - Tm_x = Tlm_x; - } - - if (diagonal) { - if (i < num_glyphs - 1 && - fabs((glyphs[i].y - glyphs[i+1].y)/scaled_font->scale.yy) < GLYPH_POSITION_TOLERANCE && - fabs((glyphs[i].x - glyphs[i+1].x)/scaled_font->scale.xx) < 10) - { - if (!in_TJ) { - if (i != 0) { - _cairo_output_stream_printf (surface->output, - "%f %f Td\r\n", - (glyphs[i].x - Tlm_x)/scaled_font->scale.xx, - -(glyphs[i].y - Tlm_y)/scaled_font->scale.yy); - - Tlm_x = glyphs[i].x; - Tlm_y = glyphs[i].y; - Tm_x = Tlm_x; - } - _cairo_output_stream_printf (surface->output, - "[<%0*x", - hex_width, - subset_glyph.subset_glyph_index); - Tm_x += subset_glyph.x_advance; - in_TJ = TRUE; - } else { - if (fabs((glyphs[i].x - Tm_x)/scaled_font->scale.xx) > GLYPH_POSITION_TOLERANCE) { - double delta = glyphs[i].x - Tm_x; - - _cairo_output_stream_printf (surface->output, - "> %f <", - -1000.0*delta/scaled_font->scale.xx); - Tm_x += delta; - } - _cairo_output_stream_printf (surface->output, - "%0*x", - hex_width, - subset_glyph.subset_glyph_index); - Tm_x += subset_glyph.x_advance; - } - } - else - { - if (in_TJ) { - if (fabs((glyphs[i].x - Tm_x)/scaled_font->scale.xx) > GLYPH_POSITION_TOLERANCE) { - double delta = glyphs[i].x - Tm_x; - - _cairo_output_stream_printf (surface->output, - "> %f <", - -1000.0*delta/scaled_font->scale.xx); - Tm_x += delta; - } - _cairo_output_stream_printf (surface->output, - "%0*x>] TJ\r\n", - hex_width, - subset_glyph.subset_glyph_index); - Tm_x += subset_glyph.x_advance; - in_TJ = FALSE; - } else { - if (i != 0) { - _cairo_output_stream_printf (surface->output, - "%f %f Td ", - (glyphs[i].x - Tlm_x)/scaled_font->scale.xx, - (glyphs[i].y - Tlm_y)/-scaled_font->scale.yy); - Tlm_x = glyphs[i].x; - Tlm_y = glyphs[i].y; - Tm_x = Tlm_x; - } - _cairo_output_stream_printf (surface->output, - "<%0*x> Tj ", - hex_width, - subset_glyph.subset_glyph_index); - Tm_x += subset_glyph.x_advance; - } - } + glyphs[i].y, + subset_glyph_index); + current_subset_id = subset_id; } else { _cairo_output_stream_printf (surface->output, - "<%0*x> Tj\r\n", - hex_width, - subset_glyph.subset_glyph_index); + "%f %f Td <%02x> Tj\r\n", + (glyphs[i].x - glyphs[i-1].x)/scaled_font->scale.xx, + (glyphs[i].y - glyphs[i-1].y)/-scaled_font->scale.yy, + subset_glyph_index); } } _cairo_output_stream_printf (surface->output, "ET\r\n"); - if (surface->emitted_pattern.smask.id != 0) { - _cairo_pdf_surface_end_group (surface); - - _cairo_output_stream_printf (surface->output, - "q /sm%d gs /res%d Do Q\r\n", - surface->emitted_pattern.smask, - group.id); - } else { - _cairo_output_stream_printf (surface->output, "Q\r\n"); - } - return _cairo_output_stream_get_status (surface->output); } @@ -3637,9 +2972,6 @@ static const cairo_surface_backend_t cairo_pdf_surface_backend = { _cairo_pdf_surface_fill, _cairo_pdf_surface_show_glyphs, NULL, /* snapshot */ - - NULL, /* is_compatible */ - NULL, /* reset */ }; static const cairo_paginated_surface_backend_t cairo_pdf_surface_paginated_backend = { diff --git a/gfx/cairo/cairo/src/cairo-pen.c b/gfx/cairo/cairo/src/cairo-pen.c index ec9eb7ac4692..1af8c36a1de7 100644 --- a/gfx/cairo/cairo/src/cairo-pen.c +++ b/gfx/cairo/cairo/src/cairo-pen.c @@ -45,13 +45,15 @@ _cairo_pen_compute_slopes (cairo_pen_t *pen); static cairo_status_t _cairo_pen_stroke_spline_half (cairo_pen_t *pen, cairo_spline_t *spline, cairo_direction_t dir, cairo_polygon_t *polygon); -void +cairo_status_t _cairo_pen_init_empty (cairo_pen_t *pen) { pen->radius = 0; pen->tolerance = 0; pen->vertices = NULL; pen->num_vertices = 0; + + return CAIRO_STATUS_SUCCESS; } cairo_status_t @@ -133,7 +135,6 @@ cairo_status_t _cairo_pen_add_points (cairo_pen_t *pen, cairo_point_t *point, int num_points) { cairo_pen_vertex_t *vertices; - cairo_status_t status; int num_vertices; int i; @@ -149,9 +150,7 @@ _cairo_pen_add_points (cairo_pen_t *pen, cairo_point_t *point, int num_points) for (i=0; i < num_points; i++) pen->vertices[pen->num_vertices-num_points+i].point = point[i]; - status = _cairo_hull_compute (pen->vertices, &pen->num_vertices); - if (status) - return status; + _cairo_hull_compute (pen->vertices, &pen->num_vertices); _cairo_pen_compute_slopes (pen); @@ -389,18 +388,15 @@ _cairo_pen_stroke_spline_half (cairo_pen_t *pen, final_slope.dy = -final_slope.dy; } - status = _cairo_pen_find_active_cw_vertex_index (pen, - &initial_slope, - &active); - if (status) - return status; + _cairo_pen_find_active_cw_vertex_index (pen, &initial_slope, &active); i = start; while (i != stop) { hull_point.x = point[i].x + pen->vertices[active].point.x; hull_point.y = point[i].y + pen->vertices[active].point.y; - - _cairo_polygon_line_to (polygon, &hull_point); + status = _cairo_polygon_line_to (polygon, &hull_point); + if (status) + return status; if (i + step == stop) slope = final_slope; @@ -441,24 +437,19 @@ _cairo_pen_stroke_spline (cairo_pen_t *pen, status = _cairo_spline_decompose (spline, tolerance); if (status) - goto BAIL; + return status; status = _cairo_pen_stroke_spline_half (pen, spline, CAIRO_DIRECTION_FORWARD, &polygon); if (status) - goto BAIL; + return status; status = _cairo_pen_stroke_spline_half (pen, spline, CAIRO_DIRECTION_REVERSE, &polygon); if (status) - goto BAIL; + return status; _cairo_polygon_close (&polygon); - status = _cairo_polygon_status (&polygon); - if (status) - goto BAIL; - - status = _cairo_bentley_ottmann_tessellate_polygon (traps, &polygon, CAIRO_FILL_RULE_WINDING); -BAIL: + _cairo_bentley_ottmann_tessellate_polygon (traps, &polygon, CAIRO_FILL_RULE_WINDING); _cairo_polygon_fini (&polygon); - return status; + return CAIRO_STATUS_SUCCESS; } diff --git a/gfx/cairo/cairo/src/cairo-platform.h b/gfx/cairo/cairo/src/cairo-platform.h index ee214ea213ef..8f88dd0aa241 100644 --- a/gfx/cairo/cairo/src/cairo-platform.h +++ b/gfx/cairo/cairo/src/cairo-platform.h @@ -93,6 +93,4 @@ #define FLOAT_WORDS_BIGENDIAN #endif -#define CAIRO_NO_MUTEX 1 - #endif /* CAIRO_PLATFORM_H */ diff --git a/gfx/cairo/cairo/src/cairo-png.c b/gfx/cairo/cairo/src/cairo-png.c index 35db3d9aa563..006cae3fd2b0 100644 --- a/gfx/cairo/cairo/src/cairo-png.c +++ b/gfx/cairo/cairo/src/cairo-png.c @@ -35,9 +35,8 @@ * Kristian Høgsberg */ -#include "cairoint.h" - #include +#include "cairoint.h" #include /* Unpremultiplies data and converts native endian ARGB => RGBA bytes */ @@ -83,25 +82,6 @@ convert_data_to_bytes (png_structp png, png_row_infop row_info, png_bytep data) } } -/* Use a couple of simple error callbacks that do not print anything to - * stderr and rely on the user to check for errors via the cairo_status_t - * return. - */ -static void -png_simple_error_callback (png_structp png_save_ptr, - png_const_charp error_msg) -{ - _cairo_error (CAIRO_STATUS_NO_MEMORY); - longjmp (png_save_ptr->jmpbuf, CAIRO_STATUS_NO_MEMORY); -} - -static void -png_simple_warning_callback (png_structp png_save_ptr, - png_const_charp error_msg) -{ -} - - static cairo_status_t write_png (cairo_surface_t *surface, png_rw_ptr write_func, @@ -137,9 +117,7 @@ write_png (cairo_surface_t *surface, for (i = 0; i < image->height; i++) rows[i] = (png_byte *) image->data + i * image->stride; - png = png_create_write_struct (PNG_LIBPNG_VER_STRING, NULL, - png_simple_error_callback, - png_simple_warning_callback); + png = png_create_write_struct (PNG_LIBPNG_VER_STRING, NULL, NULL, NULL); if (png == NULL) { status = CAIRO_STATUS_NO_MEMORY; goto BAIL2; @@ -151,9 +129,10 @@ write_png (cairo_surface_t *surface, goto BAIL3; } - status = setjmp (png_jmpbuf (png)); - if (status) + if (setjmp (png_jmpbuf (png))) { + status = CAIRO_STATUS_NO_MEMORY; goto BAIL3; + } png_set_write_fn (png, closure, write_func, NULL); @@ -175,7 +154,7 @@ write_png (cairo_surface_t *surface, png_color_type = PNG_COLOR_TYPE_GRAY; break; default: - status = CAIRO_STATUS_INVALID_FORMAT; + status = CAIRO_STATUS_NULL_POINTER; goto BAIL3; } @@ -227,13 +206,8 @@ stdio_write_func (png_structp png, png_bytep data, png_size_t size) FILE *fp; fp = png_get_io_ptr (png); - while (size) { - size_t ret = fwrite (data, 1, size, fp); - size -= ret; - data += ret; - if (size && ferror (fp)) - png_error(png, "Write Error"); - } + if (fwrite (data, 1, size, fp) != size) + png_error(png, "Write Error"); } /** @@ -358,20 +332,20 @@ read_png (png_rw_ptr read_func, void *closure) { cairo_surface_t *surface = (cairo_surface_t*) &_cairo_surface_nil; + png_byte *data = NULL; + unsigned int i; png_struct *png = NULL; png_info *info; - png_byte *data = NULL; - png_byte **row_pointers = NULL; png_uint_32 png_width, png_height, stride; int depth, color_type, interlace; - unsigned int i; unsigned int pixel_size; + png_byte **row_pointers = NULL; /* XXX: Perhaps we'll want some other error handlers? */ png = png_create_read_struct (PNG_LIBPNG_VER_STRING, NULL, - png_simple_error_callback, - png_simple_warning_callback); + NULL, + NULL); if (png == NULL) goto BAIL; @@ -399,11 +373,7 @@ read_png (png_rw_ptr read_func, /* expand gray bit depth if needed */ if (color_type == PNG_COLOR_TYPE_GRAY && depth < 8) -#if PNG_LIBPNG_VER >= 10209 - png_set_expand_gray_1_2_4_to_8 (png); -#else png_set_gray_1_2_4_to_8 (png); -#endif /* transform transparency to alpha */ if (png_get_valid(png, info, PNG_INFO_tRNS)) png_set_tRNS_to_alpha (png); @@ -472,13 +442,8 @@ stdio_read_func (png_structp png, png_bytep data, png_size_t size) FILE *fp; fp = png_get_io_ptr (png); - while (size) { - size_t ret = fread (data, 1, size, fp); - size -= ret; - data += ret; - if (size && ferror (fp)) - png_error(png, "Read Error"); - } + if (fread (data, 1, size, fp) != size) + png_error(png, "Read Error"); } /** diff --git a/gfx/cairo/cairo/src/cairo-polygon.c b/gfx/cairo/cairo/src/cairo-polygon.c index e9fc78b79add..52c72b710d14 100644 --- a/gfx/cairo/cairo/src/cairo-polygon.c +++ b/gfx/cairo/cairo/src/cairo-polygon.c @@ -34,6 +34,7 @@ * Carl D. Worth */ +#include #include "cairoint.h" /* private functions */ @@ -44,8 +45,6 @@ _cairo_polygon_grow (cairo_polygon_t *polygon); void _cairo_polygon_init (cairo_polygon_t *polygon) { - polygon->status = CAIRO_STATUS_SUCCESS; - polygon->num_edges = 0; polygon->edges_size = 0; @@ -67,19 +66,13 @@ _cairo_polygon_fini (cairo_polygon_t *polygon) polygon->has_current_point = FALSE; } -cairo_status_t -_cairo_polygon_status (cairo_polygon_t *polygon) -{ - return polygon->status; -} - /* make room for at least one more edge */ static cairo_status_t _cairo_polygon_grow (cairo_polygon_t *polygon) { cairo_edge_t *new_edges; int old_size = polygon->edges_size; - int embedded_size = ARRAY_LENGTH (polygon->edges_embedded); + int embedded_size = sizeof (polygon->edges_embedded) / sizeof (polygon->edges_embedded[0]); int new_size = 2 * MAX (old_size, 16); /* we have a local buffer at polygon->edges_embedded. try to fulfill the request @@ -110,22 +103,22 @@ _cairo_polygon_grow (cairo_polygon_t *polygon) return CAIRO_STATUS_SUCCESS; } -void +cairo_status_t _cairo_polygon_add_edge (cairo_polygon_t *polygon, cairo_point_t *p1, cairo_point_t *p2) { + cairo_status_t status; cairo_edge_t *edge; - if (polygon->status) - return; - /* drop horizontal edges */ - if (p1->y == p2->y) + if (p1->y == p2->y) { goto DONE; + } if (polygon->num_edges >= polygon->edges_size) { - polygon->status = _cairo_polygon_grow (polygon); - if (polygon->status) - return; + status = _cairo_polygon_grow (polygon); + if (status) { + return status; + } } edge = &polygon->edges[polygon->num_edges]; @@ -143,45 +136,49 @@ _cairo_polygon_add_edge (cairo_polygon_t *polygon, cairo_point_t *p1, cairo_poin DONE: _cairo_polygon_move_to (polygon, p2); + + return CAIRO_STATUS_SUCCESS; } -void +cairo_status_t _cairo_polygon_move_to (cairo_polygon_t *polygon, cairo_point_t *point) { - if (polygon->status) - return; - if (! polygon->has_current_point) polygon->first_point = *point; - polygon->current_point = *point; polygon->has_current_point = TRUE; + + return CAIRO_STATUS_SUCCESS; } -void +cairo_status_t _cairo_polygon_line_to (cairo_polygon_t *polygon, cairo_point_t *point) { - if (polygon->status) - return; + cairo_status_t status = CAIRO_STATUS_SUCCESS; if (polygon->has_current_point) { - _cairo_polygon_add_edge (polygon, &polygon->current_point, point); + status = _cairo_polygon_add_edge (polygon, &polygon->current_point, point); } else { _cairo_polygon_move_to (polygon, point); } + + return status; } -void +cairo_status_t _cairo_polygon_close (cairo_polygon_t *polygon) { - if (polygon->status) - return; + cairo_status_t status; if (polygon->has_current_point) { - _cairo_polygon_add_edge (polygon, - &polygon->current_point, - &polygon->first_point); + status = _cairo_polygon_add_edge (polygon, + &polygon->current_point, + &polygon->first_point); + if (status) + return status; polygon->has_current_point = FALSE; } + + return CAIRO_STATUS_SUCCESS; } diff --git a/gfx/cairo/cairo/src/cairo-ps-surface-private.h b/gfx/cairo/cairo/src/cairo-ps-surface-private.h deleted file mode 100644 index 2499b992fb96..000000000000 --- a/gfx/cairo/cairo/src/cairo-ps-surface-private.h +++ /dev/null @@ -1,80 +0,0 @@ -/* cairo - a vector graphics library with display and print output - * - * Copyright © 2003 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 - * Kristian Høgsberg - * Keith Packard - */ - -#ifndef CAIRO_PS_SURFACE_PRIVATE_H -#define CAIRO_PS_SURFACE_PRIVATE_H - -#include "cairo-ps.h" - -#include "cairo-surface-private.h" - -typedef struct cairo_ps_surface { - cairo_surface_t base; - - /* Here final_stream corresponds to the stream/file passed to - * cairo_ps_surface_create surface is built. Meanwhile stream is a - * temporary stream in which the file output is built, (so that - * the header can be built and inserted into the target stream - * before the contents of the temporary stream are copied). */ - cairo_output_stream_t *final_stream; - - FILE *tmpfile; - cairo_output_stream_t *stream; - - double width; - double height; - double max_width; - double max_height; - - int num_pages; - - cairo_paginated_mode_t paginated_mode; - - cairo_bool_t force_fallbacks; - - cairo_scaled_font_subsets_t *font_subsets; - - cairo_array_t dsc_header_comments; - cairo_array_t dsc_setup_comments; - cairo_array_t dsc_page_setup_comments; - - cairo_array_t *dsc_comment_target; -} cairo_ps_surface_t; - -#endif /* CAIRO_PS_SURFACE_PRIVATE_H */ diff --git a/gfx/cairo/cairo/src/cairo-ps-surface.c b/gfx/cairo/cairo/src/cairo-ps-surface.c index 919a498c5bad..5f43e98c7971 100644 --- a/gfx/cairo/cairo/src/cairo-ps-surface.c +++ b/gfx/cairo/cairo/src/cairo-ps-surface.c @@ -39,9 +39,9 @@ #include "cairoint.h" #include "cairo-ps.h" -#include "cairo-ps-surface-private.h" +#include "cairo-ps-test.h" #include "cairo-scaled-font-subsets-private.h" -#include "cairo-paginated-private.h" +#include "cairo-paginated-surface-private.h" #include "cairo-meta-surface-private.h" #include "cairo-output-stream-private.h" @@ -52,6 +52,40 @@ static const cairo_surface_backend_t cairo_ps_surface_backend; static const cairo_paginated_surface_backend_t cairo_ps_surface_paginated_backend; +typedef struct cairo_ps_surface { + cairo_surface_t base; + + /* Here final_stream corresponds to the stream/file passed to + * cairo_ps_surface_create surface is built. Meanwhile stream is a + * temporary stream in which the file output is built, (so that + * the header can be built and inserted into the target stream + * before the contents of the temporary stream are copied). */ + cairo_output_stream_t *final_stream; + + FILE *tmpfile; + cairo_output_stream_t *stream; + + double width; + double height; + double max_width; + double max_height; + + int num_pages; + + cairo_paginated_mode_t paginated_mode; + + cairo_scaled_font_subsets_t *font_subsets; + + cairo_array_t dsc_header_comments; + cairo_array_t dsc_setup_comments; + cairo_array_t dsc_page_setup_comments; + + cairo_array_t *dsc_comment_target; + +} cairo_ps_surface_t; + +#define PS_SURFACE_MAX_GLYPHS_PER_FONT 256 + /* A word wrap stream can be used as a filter to do word wrapping on * top of an existing output stream. The word wrapping is quite * simple, using isspace to determine characters that separate @@ -148,7 +182,7 @@ _word_wrap_stream_create (cairo_output_stream_t *output, int max_column) stream = malloc (sizeof (word_wrap_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, _word_wrap_stream_write, @@ -263,7 +297,7 @@ _cairo_ps_surface_emit_path (cairo_ps_surface_t *surface, cairo_line_cap_t line_cap) { cairo_output_stream_t *word_wrap; - cairo_status_t status, status2; + cairo_status_t status; ps_path_info_t path_info; word_wrap = _word_wrap_stream_create (stream, 79); @@ -281,9 +315,7 @@ _cairo_ps_surface_emit_path (cairo_ps_surface_t *surface, if (status == CAIRO_STATUS_SUCCESS) status = _cairo_output_stream_get_status (word_wrap); - status2 = _cairo_output_stream_destroy (word_wrap); - if (status == CAIRO_STATUS_SUCCESS) - status = status2; + _cairo_output_stream_destroy (word_wrap); return status; } @@ -452,18 +484,18 @@ _cairo_ps_surface_emit_truetype_font_subset (cairo_ps_surface_t *surface, /* FIXME: Figure out how subset->x_max etc maps to the /FontBBox */ - for (i = 1; i < font_subset->num_glyphs; i++) + for (i = 0; i < font_subset->num_glyphs; i++) _cairo_output_stream_printf (surface->final_stream, "Encoding %d /g%d put\n", i, i); _cairo_output_stream_printf (surface->final_stream, "/CharStrings %d dict dup begin\n" "/.notdef 0 def\n", - font_subset->num_glyphs); + font_subset->num_glyphs + 1); - for (i = 1; i < font_subset->num_glyphs; i++) + for (i = 0; i < font_subset->num_glyphs; i++) _cairo_output_stream_printf (surface->final_stream, - "/g%d %d def\n", i, i); + "/g%d %d def\n", i, i + 1); _cairo_output_stream_printf (surface->final_stream, "end readonly def\n"); @@ -547,8 +579,6 @@ _cairo_ps_surface_emit_bitmap_glyph_data (cairo_ps_surface_t *surface, CAIRO_SCALED_GLYPH_INFO_METRICS| CAIRO_SCALED_GLYPH_INFO_SURFACE, &scaled_glyph); - if (status) - return status; image = scaled_glyph->surface; if (image->format != CAIRO_FORMAT_A1) { @@ -604,7 +634,7 @@ _cairo_ps_surface_emit_bitmap_glyph_data (cairo_ps_surface_t *surface, return CAIRO_STATUS_SUCCESS; } -static cairo_status_t +static void _cairo_ps_surface_emit_glyph (cairo_ps_surface_t *surface, cairo_scaled_font_t *scaled_font, unsigned long scaled_font_glyph_index, @@ -628,8 +658,6 @@ _cairo_ps_surface_emit_glyph (cairo_ps_surface_t *surface, if (status) _cairo_surface_set_error (&surface->base, status); - - return status; } static cairo_status_t @@ -638,7 +666,6 @@ _cairo_ps_surface_emit_type3_font_subset (cairo_ps_surface_t *surface, { - cairo_status_t status; cairo_matrix_t matrix; unsigned int i; @@ -651,9 +678,7 @@ _cairo_ps_surface_emit_type3_font_subset (cairo_ps_surface_t *surface, font_subset->subset_id); matrix = font_subset->scaled_font->scale; - status = cairo_matrix_invert (&matrix); - /* _cairo_scaled_font_init ensures the matrix is invertible */ - assert (status == CAIRO_STATUS_SUCCESS); + cairo_matrix_invert (&matrix); _cairo_output_stream_printf (surface->final_stream, "\t/FontType\t3\n" "\t/FontMatrix\t[%f %f %f %f 0 0]\n" @@ -666,11 +691,9 @@ _cairo_ps_surface_emit_type3_font_subset (cairo_ps_surface_t *surface, -matrix.yy); for (i = 0; i < font_subset->num_glyphs; i++) { - status = _cairo_ps_surface_emit_glyph (surface, - font_subset->scaled_font, - font_subset->glyphs[i], i); - if (status) - return status; + _cairo_ps_surface_emit_glyph (surface, + font_subset->scaled_font, + font_subset->glyphs[i], i); } _cairo_output_stream_printf (surface->final_stream, @@ -786,7 +809,8 @@ _cairo_ps_surface_create_for_stream_internal (cairo_output_stream_t *stream, if (status) goto CLEANUP_TMPFILE; - surface->font_subsets = _cairo_scaled_font_subsets_create_simple (); + surface->font_subsets = _cairo_scaled_font_subsets_create (PS_SURFACE_MAX_GLYPHS_PER_FONT, + PS_SURFACE_MAX_GLYPHS_PER_FONT); if (! surface->font_subsets) goto CLEANUP_OUTPUT_STREAM; @@ -795,7 +819,6 @@ _cairo_ps_surface_create_for_stream_internal (cairo_output_stream_t *stream, surface->max_width = width; surface->max_height = height; surface->paginated_mode = CAIRO_PAGINATED_MODE_ANALYZE; - surface->force_fallbacks = FALSE; surface->num_pages = 0; @@ -811,8 +834,7 @@ _cairo_ps_surface_create_for_stream_internal (cairo_output_stream_t *stream, &cairo_ps_surface_paginated_backend); CLEANUP_OUTPUT_STREAM: - status = _cairo_output_stream_destroy (surface->stream); - /* Ignore status---we're already on a failure path. */ + _cairo_output_stream_destroy (surface->stream); CLEANUP_TMPFILE: fclose (surface->tmpfile); CLEANUP_SURFACE: @@ -1179,7 +1201,7 @@ cairo_ps_surface_dsc_begin_page_setup (cairo_surface_t *surface) static cairo_status_t _cairo_ps_surface_finish (void *abstract_surface) { - cairo_status_t status, status2; + cairo_status_t status; cairo_ps_surface_t *surface = abstract_surface; int i, num_comments; char **comments; @@ -1192,13 +1214,16 @@ _cairo_ps_surface_finish (void *abstract_surface) _cairo_ps_surface_emit_footer (surface); - status = _cairo_output_stream_destroy (surface->stream); + _cairo_output_stream_close (surface->stream); + status = _cairo_output_stream_get_status (surface->stream); + _cairo_output_stream_destroy (surface->stream); fclose (surface->tmpfile); - status2 = _cairo_output_stream_destroy (surface->final_stream); + _cairo_output_stream_close (surface->final_stream); if (status == CAIRO_STATUS_SUCCESS) - status = status2; + status = _cairo_output_stream_get_status (surface->final_stream); + _cairo_output_stream_destroy (surface->final_stream); num_comments = _cairo_array_num_elements (&surface->dsc_header_comments); comments = _cairo_array_index (&surface->dsc_header_comments, 0); @@ -1358,12 +1383,32 @@ pattern_supported (const cairo_pattern_t *pattern) return FALSE; } +static cairo_bool_t cairo_ps_force_fallbacks = FALSE; + +/** + * _cairo_ps_test_force_fallbacks + * + * Force the PS surface backend to use image fallbacks for every + * operation. + * + * + * This function is only intended for internal + * testing use within the cairo distribution. It is not installed in + * any public header file. + * + **/ +void +_cairo_ps_test_force_fallbacks (void) +{ + cairo_ps_force_fallbacks = TRUE; +} + static cairo_int_status_t _cairo_ps_surface_operation_supported (cairo_ps_surface_t *surface, cairo_operator_t op, const cairo_pattern_t *pattern) { - if (surface->force_fallbacks) + if (cairo_ps_force_fallbacks) return FALSE; if (! pattern_supported (pattern)) @@ -1497,7 +1542,7 @@ _string_array_stream_create (cairo_output_stream_t *output) stream = malloc (sizeof (string_array_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, _string_array_stream_write, @@ -1517,7 +1562,7 @@ _cairo_ps_surface_emit_image (cairo_ps_surface_t *surface, cairo_image_surface_t *image, const char *name) { - cairo_status_t status, status2; + cairo_status_t status; unsigned char *rgb, *compressed; unsigned long rgb_size, compressed_size; cairo_surface_t *opaque; @@ -1543,29 +1588,20 @@ _cairo_ps_surface_emit_image (cairo_ps_surface_t *surface, _cairo_pattern_init_for_surface (&pattern.surface, &image->base); - status = _cairo_surface_fill_rectangle (opaque, - CAIRO_OPERATOR_SOURCE, - CAIRO_COLOR_WHITE, - 0, 0, - image->width, image->height); - if (status) { - _cairo_pattern_fini (&pattern.base); - goto bail0; - } + _cairo_surface_fill_rectangle (opaque, + CAIRO_OPERATOR_SOURCE, + CAIRO_COLOR_WHITE, + 0, 0, image->width, image->height); - status = _cairo_surface_composite (CAIRO_OPERATOR_OVER, - &pattern.base, - NULL, - opaque, - 0, 0, - 0, 0, - 0, 0, - image->width, - image->height); - if (status) { - _cairo_pattern_fini (&pattern.base); - goto bail0; - } + _cairo_surface_composite (CAIRO_OPERATOR_OVER, + &pattern.base, + NULL, + opaque, + 0, 0, + 0, 0, + 0, 0, + image->width, + image->height); _cairo_pattern_fini (&pattern.base); opaque_image = (cairo_image_surface_t *) opaque; @@ -1610,12 +1646,8 @@ _cairo_ps_surface_emit_image (cairo_ps_surface_t *surface, _cairo_output_stream_write (base85_stream, compressed, compressed_size); - status = _cairo_output_stream_destroy (base85_stream); - status2 = _cairo_output_stream_destroy (string_array_stream); - if (status == CAIRO_STATUS_SUCCESS) - status = status2; - if (status) - goto bail3; + _cairo_output_stream_destroy (base85_stream); + _cairo_output_stream_destroy (string_array_stream); _cairo_output_stream_printf (surface->stream, "] def\n"); @@ -1647,7 +1679,6 @@ _cairo_ps_surface_emit_image (cairo_ps_surface_t *surface, status = CAIRO_STATUS_SUCCESS; - bail3: free (compressed); bail2: free (rgb); @@ -1674,26 +1705,19 @@ _cairo_ps_surface_emit_solid_pattern (cairo_ps_surface_t *surface, pattern->color.blue); } -static cairo_status_t +static void _cairo_ps_surface_emit_surface_pattern (cairo_ps_surface_t *surface, cairo_surface_pattern_t *pattern) { - cairo_status_t status; double bbox_width, bbox_height; double xstep, ystep; cairo_matrix_t inverse = pattern->base.matrix; - status = cairo_matrix_invert (&inverse); - /* cairo_pattern_set_matrix ensures the matrix is invertible */ - assert (status == CAIRO_STATUS_SUCCESS); + cairo_matrix_invert (&inverse); if (_cairo_surface_is_meta (pattern->surface)) { _cairo_output_stream_printf (surface->stream, "/MyPattern {\n"); - - status = _cairo_meta_surface_replay (pattern->surface, &surface->base); - if (status) - return status; - + _cairo_meta_surface_replay (pattern->surface, &surface->base); bbox_width = surface->width; bbox_height = surface->height; xstep = surface->width; @@ -1781,8 +1805,6 @@ _cairo_ps_surface_emit_surface_pattern (cairo_ps_surface_t *surface, inverse.x0, inverse.y0); _cairo_output_stream_printf (surface->stream, "makepattern setpattern\n"); - - return CAIRO_STATUS_SUCCESS; } static void @@ -1799,13 +1821,12 @@ _cairo_ps_surface_emit_radial_pattern (cairo_ps_surface_t *surface, /* XXX: NYI */ } -static cairo_status_t +static void _cairo_ps_surface_emit_pattern (cairo_ps_surface_t *surface, cairo_pattern_t *pattern) { /* FIXME: We should keep track of what pattern is currently set in * the postscript file and only emit code if we're setting a * different pattern. */ - cairo_status_t status; switch (pattern->type) { case CAIRO_PATTERN_TYPE_SOLID: @@ -1813,10 +1834,7 @@ _cairo_ps_surface_emit_pattern (cairo_ps_surface_t *surface, cairo_pattern_t *pa break; case CAIRO_PATTERN_TYPE_SURFACE: - status = _cairo_ps_surface_emit_surface_pattern (surface, - (cairo_surface_pattern_t *) pattern); - if (status) - return status; + _cairo_ps_surface_emit_surface_pattern (surface, (cairo_surface_pattern_t *) pattern); break; case CAIRO_PATTERN_TYPE_LINEAR: @@ -1827,8 +1845,6 @@ _cairo_ps_surface_emit_pattern (cairo_ps_surface_t *surface, cairo_pattern_t *pa _cairo_ps_surface_emit_radial_pattern (surface, (cairo_radial_pattern_t *) pattern); break; } - - return CAIRO_STATUS_SUCCESS; } static cairo_int_status_t @@ -1914,7 +1930,6 @@ _cairo_ps_surface_paint (void *abstract_surface, cairo_ps_surface_t *surface = abstract_surface; cairo_output_stream_t *stream = surface->stream; cairo_rectangle_int16_t extents, pattern_extents; - cairo_status_t status; if (surface->paginated_mode == CAIRO_PAGINATED_MODE_ANALYZE) return _cairo_ps_surface_analyze_operation (surface, op, source); @@ -1926,25 +1941,17 @@ _cairo_ps_surface_paint (void *abstract_surface, * possible only because there is nothing between the fallback * images and the paper, nor is anything painted above. */ /* - assert (_cairo_ps_surface_operation_supported (op, source)); + assert (__cairo_ps_surface_operation_supported (op, source)); */ _cairo_output_stream_printf (stream, "%% _cairo_ps_surface_paint\n"); - status = _cairo_surface_get_extents (&surface->base, &extents); - if (status) - return status; - - status = _cairo_pattern_get_extents (source, &pattern_extents); - if (status) - return status; - + _cairo_surface_get_extents (&surface->base, &extents); + _cairo_pattern_get_extents (source, &pattern_extents); _cairo_rectangle_intersect (&extents, &pattern_extents); - status = _cairo_ps_surface_emit_pattern (surface, source); - if (status) - return status; + _cairo_ps_surface_emit_pattern (surface, source); _cairo_output_stream_printf (stream, "%d %d M\n", extents.x, extents.y); @@ -1958,7 +1965,6 @@ _cairo_ps_surface_paint (void *abstract_surface, extents.x, extents.y + extents.height); _cairo_output_stream_printf (stream, "P F\n"); - return CAIRO_STATUS_SUCCESS; } @@ -2194,7 +2200,7 @@ _cairo_ps_surface_show_glyphs (void *abstract_surface, cairo_ps_surface_t *surface = abstract_surface; cairo_output_stream_t *stream = surface->stream; unsigned int current_subset_id = -1; - cairo_scaled_font_subsets_glyph_t subset_glyph; + unsigned int font_id; cairo_ps_glyph_id_t *glyph_ids; cairo_status_t status; unsigned int num_glyphs_unsigned, i, j, last, end; @@ -2222,11 +2228,11 @@ _cairo_ps_surface_show_glyphs (void *abstract_surface, for (i = 0; i < num_glyphs_unsigned; i++) { status = _cairo_scaled_font_subsets_map_glyph (surface->font_subsets, scaled_font, glyphs[i].index, - &subset_glyph); + &font_id, + &(glyph_ids[i].subset_id), + &(glyph_ids[i].glyph_id)); if (status) goto fail; - glyph_ids[i].subset_id = subset_glyph.subset_id; - glyph_ids[i].glyph_id = subset_glyph.subset_glyph_index; } i = 0; @@ -2236,7 +2242,7 @@ _cairo_ps_surface_show_glyphs (void *abstract_surface, "/CairoFont-%d-%d findfont\n" "[ %f %f %f %f 0 0 ] makefont\n" "setfont\n", - subset_glyph.font_id, + font_id, glyph_ids[i].subset_id, scaled_font->scale.xx, scaled_font->scale.yx, diff --git a/gfx/cairo/cairo/src/cairo-quartz-private.h b/gfx/cairo/cairo/src/cairo-quartz-private.h index cd1b15cd9faa..23d7d4be51fb 100644 --- a/gfx/cairo/cairo/src/cairo-quartz-private.h +++ b/gfx/cairo/cairo/src/cairo-quartz-private.h @@ -56,11 +56,8 @@ typedef struct cairo_quartz_surface { /* These are stored while drawing operations are in place, set up * by quartz_setup_source() and quartz_finish_source() */ + CGAffineTransform imageTransform; CGImageRef sourceImage; - cairo_surface_t *sourceImageSurface; - CGAffineTransform sourceImageTransform; - CGRect sourceImageRect; - CGShadingRef sourceShading; CGPatternRef sourcePattern; } cairo_quartz_surface_t; diff --git a/gfx/cairo/cairo/src/cairo-quartz-surface.c b/gfx/cairo/cairo/src/cairo-quartz-surface.c index 06c8ba8c813b..e390988d2110 100644 --- a/gfx/cairo/cairo/src/cairo-quartz-surface.c +++ b/gfx/cairo/cairo/src/cairo-quartz-surface.c @@ -34,12 +34,12 @@ * Vladimir Vukicevic */ +#include + #include "cairoint.h" #include "cairo-quartz-private.h" -#include - #undef QUARTZ_DEBUG #ifdef QUARTZ_DEBUG @@ -101,24 +101,47 @@ static void quartz_image_to_png (CGImageRef, char *dest); * Cairo path -> Quartz path conversion helpers */ -typedef struct _quartz_stroke { - CGContextRef cgContext; - cairo_matrix_t *ctm_inverse; -} quartz_stroke_t; +/* cairo path -> mutable path */ +static cairo_status_t +_cairo_path_to_quartz_path_move_to (void *closure, cairo_point_t *point) +{ + CGPathMoveToPoint ((CGMutablePathRef) closure, NULL, + _cairo_fixed_to_double(point->x), _cairo_fixed_to_double(point->y)); + return CAIRO_STATUS_SUCCESS; +} + +static cairo_status_t +_cairo_path_to_quartz_path_line_to (void *closure, cairo_point_t *point) +{ + CGPathAddLineToPoint ((CGMutablePathRef) closure, NULL, + _cairo_fixed_to_double(point->x), _cairo_fixed_to_double(point->y)); + return CAIRO_STATUS_SUCCESS; +} + +static cairo_status_t +_cairo_path_to_quartz_path_curve_to (void *closure, cairo_point_t *p0, cairo_point_t *p1, cairo_point_t *p2) +{ + CGPathAddCurveToPoint ((CGMutablePathRef) closure, NULL, + _cairo_fixed_to_double(p0->x), _cairo_fixed_to_double(p0->y), + _cairo_fixed_to_double(p1->x), _cairo_fixed_to_double(p1->y), + _cairo_fixed_to_double(p2->x), _cairo_fixed_to_double(p2->y)); + return CAIRO_STATUS_SUCCESS; +} + +static cairo_status_t +_cairo_path_to_quartz_path_close_path (void *closure) +{ + CGPathCloseSubpath ((CGMutablePathRef) closure); + return CAIRO_STATUS_SUCCESS; +} /* cairo path -> execute in context */ static cairo_status_t _cairo_path_to_quartz_context_move_to (void *closure, cairo_point_t *point) { //ND((stderr, "moveto: %f %f\n", _cairo_fixed_to_double(point->x), _cairo_fixed_to_double(point->y))); - quartz_stroke_t *stroke = (quartz_stroke_t *)closure; - double x = _cairo_fixed_to_double (point->x); - double y = _cairo_fixed_to_double (point->y); - - if (stroke->ctm_inverse) - cairo_matrix_transform_point (stroke->ctm_inverse, &x, &y); - - CGContextMoveToPoint (stroke->cgContext, x, y); + CGContextMoveToPoint ((CGContextRef) closure, + _cairo_fixed_to_double(point->x), _cairo_fixed_to_double(point->y)); return CAIRO_STATUS_SUCCESS; } @@ -126,17 +149,12 @@ static cairo_status_t _cairo_path_to_quartz_context_line_to (void *closure, cairo_point_t *point) { //ND((stderr, "lineto: %f %f\n", _cairo_fixed_to_double(point->x), _cairo_fixed_to_double(point->y))); - quartz_stroke_t *stroke = (quartz_stroke_t *)closure; - double x = _cairo_fixed_to_double (point->x); - double y = _cairo_fixed_to_double (point->y); - - if (stroke->ctm_inverse) - cairo_matrix_transform_point (stroke->ctm_inverse, &x, &y); - - if (CGContextIsPathEmpty (stroke->cgContext)) - CGContextMoveToPoint (stroke->cgContext, x, y); + if (CGContextIsPathEmpty ((CGContextRef) closure)) + CGContextMoveToPoint ((CGContextRef) closure, + _cairo_fixed_to_double(point->x), _cairo_fixed_to_double(point->y)); else - CGContextAddLineToPoint (stroke->cgContext, x, y); + CGContextAddLineToPoint ((CGContextRef) closure, + _cairo_fixed_to_double(point->x), _cairo_fixed_to_double(point->y)); return CAIRO_STATUS_SUCCESS; } @@ -147,22 +165,11 @@ _cairo_path_to_quartz_context_curve_to (void *closure, cairo_point_t *p0, cairo_ // _cairo_fixed_to_double(p0->x), _cairo_fixed_to_double(p0->y), // _cairo_fixed_to_double(p1->x), _cairo_fixed_to_double(p1->y), // _cairo_fixed_to_double(p2->x), _cairo_fixed_to_double(p2->y))); - quartz_stroke_t *stroke = (quartz_stroke_t *)closure; - double x0 = _cairo_fixed_to_double (p0->x); - double y0 = _cairo_fixed_to_double (p0->y); - double x1 = _cairo_fixed_to_double (p1->x); - double y1 = _cairo_fixed_to_double (p1->y); - double x2 = _cairo_fixed_to_double (p2->x); - double y2 = _cairo_fixed_to_double (p2->y); - if (stroke->ctm_inverse) { - cairo_matrix_transform_point (stroke->ctm_inverse, &x0, &y0); - cairo_matrix_transform_point (stroke->ctm_inverse, &x1, &y1); - cairo_matrix_transform_point (stroke->ctm_inverse, &x2, &y2); - } - - CGContextAddCurveToPoint (stroke->cgContext, - x0, y0, x1, y1, x2, y2); + CGContextAddCurveToPoint ((CGContextRef) closure, + _cairo_fixed_to_double(p0->x), _cairo_fixed_to_double(p0->y), + _cairo_fixed_to_double(p1->x), _cairo_fixed_to_double(p1->y), + _cairo_fixed_to_double(p2->x), _cairo_fixed_to_double(p2->y)); return CAIRO_STATUS_SUCCESS; } @@ -170,14 +177,26 @@ static cairo_status_t _cairo_path_to_quartz_context_close_path (void *closure) { //ND((stderr, "closepath\n")); - quartz_stroke_t *stroke = (quartz_stroke_t *)closure; - CGContextClosePath (stroke->cgContext); + CGContextClosePath ((CGContextRef) closure); return CAIRO_STATUS_SUCCESS; } +static cairo_status_t +_cairo_quartz_cairo_path_to_quartz_path (cairo_path_fixed_t *path, + CGMutablePathRef cgPath) +{ + return _cairo_path_fixed_interpret (path, + CAIRO_DIRECTION_FORWARD, + _cairo_path_to_quartz_path_move_to, + _cairo_path_to_quartz_path_line_to, + _cairo_path_to_quartz_path_curve_to, + _cairo_path_to_quartz_path_close_path, + cgPath); +} + static cairo_status_t _cairo_quartz_cairo_path_to_quartz_context (cairo_path_fixed_t *path, - quartz_stroke_t *stroke) + CGContextRef cgc) { return _cairo_path_fixed_interpret (path, CAIRO_DIRECTION_FORWARD, @@ -185,7 +204,7 @@ _cairo_quartz_cairo_path_to_quartz_context (cairo_path_fixed_t *path, _cairo_path_to_quartz_context_line_to, _cairo_path_to_quartz_context_curve_to, _cairo_path_to_quartz_context_close_path, - stroke); + cgc); } /* @@ -267,8 +286,8 @@ _cairo_quartz_cairo_matrix_to_quartz (const cairo_matrix_t *src, CGAffineTransform *dst) { dst->a = src->xx; - dst->b = src->yx; - dst->c = src->xy; + dst->b = src->xy; + dst->c = src->yx; dst->d = src->yy; dst->tx = src->x0; dst->ty = src->y0; @@ -346,13 +365,6 @@ _cairo_quartz_cairo_gradient_pattern_to_quartz (cairo_pattern_t *abspat) abspat->type != CAIRO_PATTERN_TYPE_RADIAL) return NULL; - /* bandaid for mozilla bug 379321, also visible in the - * linear-gradient-reflect test. - */ - if (abspat->extend == CAIRO_EXTEND_REFLECT || - abspat->extend == CAIRO_EXTEND_REPEAT) - return NULL; - /* We can only do this if we have an identity pattern matrix; * otherwise fall back through to the generic pattern case. * XXXperf we could optimize this by creating a pattern with the shading; @@ -423,30 +435,38 @@ _cairo_quartz_cairo_gradient_pattern_to_quartz (cairo_pattern_t *abspat) return NULL; } -/* generic cairo surface -> cairo_quartz_surface_t function */ -static cairo_quartz_surface_t * -_cairo_quartz_surface_to_quartz (cairo_surface_t *target, cairo_surface_t *pat_surf) + +/* Generic cairo_pattern -> CGPattern function */ +static void +SurfacePatternDrawFunc (void *info, CGContextRef context) { + cairo_surface_pattern_t *spat = (cairo_surface_pattern_t *) info; + cairo_surface_t *pat_surf = spat->surface; + cairo_quartz_surface_t *quartz_surf = NULL; + cairo_bool_t flip = FALSE; + + CGImageRef img; + if (cairo_surface_get_type(pat_surf) != CAIRO_SURFACE_TYPE_QUARTZ) { - /* XXXtodo/perf don't use clone if the source surface is an image surface! Instead, + /* This sucks; we should really store a dummy quartz surface + * for passing in here + * XXXtodo store a dummy quartz surface somewhere for handing off to clone_similar + * XXXtodo/perf don't use clone if the source surface is an image surface! Instead, * just create the CGImage directly! */ - cairo_surface_t *ref_type = target; + cairo_surface_t *dummy = cairo_quartz_surface_create (CAIRO_FORMAT_ARGB32, 1, 1); cairo_surface_t *new_surf = NULL; cairo_rectangle_int16_t rect; - if (ref_type == NULL) - ref_type = cairo_quartz_surface_create (CAIRO_FORMAT_ARGB32, 1, 1); _cairo_surface_get_extents (pat_surf, &rect); - _cairo_surface_clone_similar (ref_type, pat_surf, rect.x, rect.y, + _cairo_surface_clone_similar (dummy, pat_surf, rect.x, rect.y, rect.width, rect.height, &new_surf); - if (target == NULL) - cairo_surface_destroy(ref_type); + cairo_surface_destroy(dummy); quartz_surf = (cairo_quartz_surface_t *) new_surf; } else { @@ -456,21 +476,15 @@ _cairo_quartz_surface_to_quartz (cairo_surface_t *target, cairo_surface_t *pat_s cairo_surface_reference (pat_surf); quartz_surf = (cairo_quartz_surface_t*) pat_surf; + /* XXXtodo WHY does this need to be flipped? Writing this stuff + * to disk shows that in both this path and the path above the source image + * has an identical orientation, and the destination context at all times has a Y + * flip. So why do we need to flip in this case? + */ + flip = TRUE; } - return quartz_surf; -} - -/* Generic cairo_pattern -> CGPattern function */ -static void -SurfacePatternDrawFunc (void *info, CGContextRef context) -{ - cairo_surface_pattern_t *spat = (cairo_surface_pattern_t *) info; - cairo_surface_t *pat_surf = spat->surface; - - cairo_quartz_surface_t *quartz_surf = _cairo_quartz_surface_to_quartz (NULL, pat_surf); - CGImageRef img = CGBitmapContextCreateImage (quartz_surf->cgContext); - CGRect imageBounds; + img = CGBitmapContextCreateImage (quartz_surf->cgContext); if (!img) { // ... give up. @@ -479,33 +493,17 @@ SurfacePatternDrawFunc (void *info, CGContextRef context) return; } - /* XXXtodo WHY does this need to be flipped? Writing this stuff - * to disk shows that in both this path and the path above the source image - * has an identical orientation, and the destination context at all times has a Y - * flip. So why do we need to flip in this case? - */ - if (cairo_surface_get_type(pat_surf) == CAIRO_SURFACE_TYPE_QUARTZ) { + if (flip) { CGContextTranslateCTM (context, 0, CGImageGetHeight(img)); CGContextScaleCTM (context, 1, -1); } + CGRect imageBounds; imageBounds.size = CGSizeMake (CGImageGetWidth(img), CGImageGetHeight(img)); imageBounds.origin.x = 0; imageBounds.origin.y = 0; CGContextDrawImage (context, imageBounds, img); - if (spat->base.extend == CAIRO_EXTEND_REFLECT) { - /* draw 3 more copies of the image, flipped. */ - CGContextTranslateCTM (context, 0, 2 * imageBounds.size.height); - CGContextScaleCTM (context, 1, -1); - CGContextDrawImage (context, imageBounds, img); - CGContextTranslateCTM (context, 2 * imageBounds.size.width, 0); - CGContextScaleCTM (context, -1, 1); - CGContextDrawImage (context, imageBounds, img); - CGContextTranslateCTM (context, 0, 2 * imageBounds.size.height); - CGContextScaleCTM (context, 1, -1); - CGContextDrawImage (context, imageBounds, img); - } CGImageRelease (img); @@ -517,11 +515,7 @@ 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 = @@ -569,24 +563,8 @@ _cairo_quartz_cairo_repeating_surface_pattern_to_quartz (cairo_quartz_surface_t _cairo_surface_get_extents (pat_surf, &extents); pbounds.origin.x = 0; pbounds.origin.y = 0; - - // kjs seems to indicate this should work (setting to 0,0 to avoid - // tiling); however, the pattern CTM scaling ends up being NaN in - // the pattern draw function if either rw or rh are 0. - // XXXtodo get pattern drawing working with extend options - // XXXtodo/perf optimize CAIRO_EXTEND_NONE to a single DrawImage instead of a pattern - if (spat->base.extend == CAIRO_EXTEND_REFLECT) { - /* XXX broken; need to emulate by reflecting the image into 4 quadrants - * and then tiling that - */ - pbounds.size.width = 2 * extents.width; - pbounds.size.height = 2 * extents.height; - } else { - pbounds.size.width = extents.width; - pbounds.size.height = extents.height; - } - rw = pbounds.size.width; - rh = pbounds.size.height; + pbounds.size.width = extents.width; + pbounds.size.height = extents.height; m = spat->base.matrix; cairo_matrix_invert(&m); @@ -606,6 +584,38 @@ _cairo_quartz_cairo_repeating_surface_pattern_to_quartz (cairo_quartz_surface_t ND((stderr, " context xform: t: %f %f xx: %f xy: %f yx: %f yy: %f\n", xform.tx, xform.ty, xform.a, xform.b, xform.c, xform.d)); #endif + // kjs seems to indicate this should work (setting to 0,0 to avoid + // tiling); however, the pattern CTM scaling ends up being NaN in + // the pattern draw function if either rw or rh are 0. + // XXXtodo get pattern drawing working with extend options + // XXXtodo/perf optimize CAIRO_EXTEND_NONE to a single DrawImage instead of a pattern +#if 0 + if (spat->base.extend == CAIRO_EXTEND_NONE) { + /* XXX wasteful; this will keep drawing the pattern in the + * original location. We need to set up the clip region + * instead to do this right. + */ + rw = 0; + rh = 0; + } else if (spat->base.extend == CAIRO_EXTEND_REPEAT) { + rw = extents.width; + rh = extents.height; + } else if (spat->base.extend == CAIRO_EXTEND_REFLECT) { + /* XXX broken; need to emulate by reflecting the image into 4 quadrants + * and then tiling that + */ + rw = extents.width; + rh = extents.height; + } else { + /* CAIRO_EXTEND_PAD */ + /* XXX broken. */ + rw = 0; + rh = 0; + } +#else + rw = extents.width; + rh = extents.height; +#endif /* XXX fixme: only do snapshots if the context is for printing, or get rid of the other block if it doesn't fafect performance */ @@ -632,13 +642,12 @@ typedef enum { DO_SOLID, DO_SHADING, DO_PATTERN, - DO_IMAGE, DO_UNSUPPORTED } cairo_quartz_action_t; static cairo_quartz_action_t _cairo_quartz_setup_source (cairo_quartz_surface_t *surface, - cairo_pattern_t *source) + cairo_pattern_t *source) { assert (!(surface->sourceImage || surface->sourceShading || surface->sourcePattern)); @@ -667,44 +676,19 @@ _cairo_quartz_setup_source (cairo_quartz_surface_t *surface, surface->sourceShading = shading; return DO_SHADING; - } else if (source->type == CAIRO_PATTERN_TYPE_SURFACE && - source->extend == CAIRO_EXTEND_NONE) - { - cairo_surface_pattern_t *spat = (cairo_surface_pattern_t *) source; - cairo_surface_t *pat_surf = spat->surface; - cairo_quartz_surface_t *quartz_surf = _cairo_quartz_surface_to_quartz ((cairo_surface_t *) surface, pat_surf); - CGImageRef img = CGBitmapContextCreateImage (quartz_surf->cgContext); - cairo_matrix_t m = spat->base.matrix; - cairo_rectangle_int16_t extents; - - if (!img) - return DO_UNSUPPORTED; - - surface->sourceImage = img; - - cairo_matrix_invert(&m); - _cairo_quartz_cairo_matrix_to_quartz (&m, &surface->sourceImageTransform); - - _cairo_surface_get_extents (pat_surf, &extents); - surface->sourceImageRect = CGRectMake (0, 0, extents.width, extents.height); - - surface->sourceImageSurface = (cairo_surface_t *)quartz_surf; - - return DO_IMAGE; } else if (source->type == CAIRO_PATTERN_TYPE_SURFACE) { - float patternAlpha = 1.0f; - CGColorSpaceRef patternSpace; - CGPatternRef pattern = _cairo_quartz_cairo_repeating_surface_pattern_to_quartz (surface, source); if (!pattern) return DO_UNSUPPORTED; + float patternAlpha = 1.0f; + // Save before we change the pattern, colorspace, etc. so that // we can restore and make sure that quartz releases our // pattern (which may be stack allocated) CGContextSaveGState(surface->cgContext); - patternSpace = CGColorSpaceCreatePattern(NULL); + CGColorSpaceRef patternSpace = CGColorSpaceCreatePattern(NULL); CGContextSetFillColorSpace (surface->cgContext, patternSpace); CGContextSetFillPattern (surface->cgContext, pattern, &patternAlpha); CGContextSetStrokeColorSpace (surface->cgContext, patternSpace); @@ -732,11 +716,7 @@ _cairo_quartz_teardown_source (cairo_quartz_surface_t *surface, cairo_pattern_t *source) { if (surface->sourceImage) { - CGImageRelease(surface->sourceImage); - surface->sourceImage = NULL; - - cairo_surface_destroy(surface->sourceImageSurface); - surface->sourceImageSurface = NULL; + // nothing to do; we don't use sourceImage yet } if (surface->sourceShading) { @@ -885,15 +865,6 @@ _cairo_quartz_surface_acquire_source_image (void *abstract_surface, return _cairo_quartz_get_image (surface, image_out, NULL); } -static void -_cairo_quartz_surface_release_source_image (void *abstract_surface, - cairo_image_surface_t *image, - void *image_extra) -{ - cairo_surface_destroy ((cairo_surface_t *) image); -} - - static cairo_status_t _cairo_quartz_surface_acquire_dest_image (void *abstract_surface, cairo_rectangle_int16_t *interest_rect, @@ -994,6 +965,7 @@ _cairo_quartz_surface_clone_similar (void *abstract_surface, int height, cairo_surface_t **clone_out) { + cairo_quartz_surface_t *surface = (cairo_quartz_surface_t *) abstract_surface; cairo_quartz_surface_t *new_surface = NULL; cairo_format_t new_format; @@ -1114,19 +1086,6 @@ _cairo_quartz_surface_paint (void *abstract_surface, surface->extents.height)); } else if (action == DO_SHADING) { CGContextDrawShading (surface->cgContext, surface->sourceShading); - } else if (action == DO_IMAGE) { - cairo_surface_pattern_t *surface_pattern = - (cairo_surface_pattern_t *) source; - cairo_surface_t *pat_surf = surface_pattern->surface; - CGContextSaveGState (surface->cgContext); - CGContextConcatCTM (surface->cgContext, surface->sourceImageTransform); - if (cairo_surface_get_type(pat_surf) == CAIRO_SURFACE_TYPE_QUARTZ) { - CGContextTranslateCTM (surface->cgContext, 0, CGImageGetHeight(surface->sourceImage)); - CGContextScaleCTM (surface->cgContext, 1, -1); - } - - CGContextDrawImage (surface->cgContext, surface->sourceImageRect, surface->sourceImage); - CGContextRestoreGState (surface->cgContext); } else { rv = CAIRO_INT_STATUS_UNSUPPORTED; } @@ -1149,7 +1108,6 @@ _cairo_quartz_surface_fill (void *abstract_surface, cairo_quartz_surface_t *surface = (cairo_quartz_surface_t *) abstract_surface; cairo_int_status_t rv = CAIRO_STATUS_SUCCESS; cairo_quartz_action_t action; - quartz_stroke_t stroke; ND((stderr, "%p _cairo_quartz_surface_fill op %d source->type %d\n", surface, op, source->type)); @@ -1168,10 +1126,7 @@ _cairo_quartz_surface_fill (void *abstract_surface, } CGContextBeginPath (surface->cgContext); - - stroke.cgContext = surface->cgContext; - stroke.ctm_inverse = NULL; - _cairo_quartz_cairo_path_to_quartz_context (path, &stroke); + _cairo_quartz_cairo_path_to_quartz_context (path, surface->cgContext); if (action == DO_SOLID || action == DO_PATTERN) { if (fill_rule == CAIRO_FILL_RULE_WINDING) @@ -1188,21 +1143,6 @@ _cairo_quartz_surface_fill (void *abstract_surface, CGContextEOClip (surface->cgContext); CGContextDrawShading (surface->cgContext, surface->sourceShading); - } else if (action == DO_IMAGE) { - cairo_surface_pattern_t *surface_pattern = - (cairo_surface_pattern_t *) source; - cairo_surface_t *pat_surf = surface_pattern->surface; - if (fill_rule == CAIRO_FILL_RULE_WINDING) - CGContextClip (surface->cgContext); - else - CGContextEOClip (surface->cgContext); - CGContextConcatCTM (surface->cgContext, surface->sourceImageTransform); - if (cairo_surface_get_type(pat_surf) == CAIRO_SURFACE_TYPE_QUARTZ) { - CGContextTranslateCTM (surface->cgContext, 0, CGImageGetHeight(surface->sourceImage)); - CGContextScaleCTM (surface->cgContext, 1, -1); - } - - CGContextDrawImage (surface->cgContext, surface->sourceImageRect, surface->sourceImage); } else { rv = CAIRO_INT_STATUS_UNSUPPORTED; } @@ -1229,8 +1169,6 @@ _cairo_quartz_surface_stroke (void *abstract_surface, cairo_quartz_surface_t *surface = (cairo_quartz_surface_t *) abstract_surface; cairo_int_status_t rv = CAIRO_STATUS_SUCCESS; cairo_quartz_action_t action; - quartz_stroke_t stroke; - CGAffineTransform strokeTransform; ND((stderr, "%p _cairo_quartz_surface_stroke op %d source->type %d\n", surface, op, source->type)); @@ -1246,8 +1184,6 @@ _cairo_quartz_surface_stroke (void *abstract_surface, CGContextSetLineCap (surface->cgContext, _cairo_quartz_cairo_line_cap_to_quartz (style->line_cap)); CGContextSetLineJoin (surface->cgContext, _cairo_quartz_cairo_line_join_to_quartz (style->line_join)); CGContextSetMiterLimit (surface->cgContext, style->miter_limit); - _cairo_quartz_cairo_matrix_to_quartz (ctm, &strokeTransform); - CGContextConcatCTM (surface->cgContext, strokeTransform); if (style->dash && style->num_dashes) { #define STATIC_DASH 32 @@ -1275,25 +1211,13 @@ _cairo_quartz_surface_stroke (void *abstract_surface, } CGContextBeginPath (surface->cgContext); - - stroke.cgContext = surface->cgContext; - stroke.ctm_inverse = ctm_inverse; - _cairo_quartz_cairo_path_to_quartz_context (path, &stroke); + _cairo_quartz_cairo_path_to_quartz_context (path, surface->cgContext); if (action == DO_SOLID || action == DO_PATTERN) { CGContextStrokePath (surface->cgContext); - } else if (action == DO_IMAGE) { - CGContextReplacePathWithStrokedPath (surface->cgContext); - CGContextClip (surface->cgContext); - - CGContextConcatCTM (surface->cgContext, surface->sourceImageTransform); - if (cairo_surface_get_type(((cairo_surface_pattern_t*)source)->surface) == CAIRO_SURFACE_TYPE_QUARTZ) { - CGContextTranslateCTM (surface->cgContext, 0, CGImageGetHeight(surface->sourceImage)); - CGContextScaleCTM (surface->cgContext, 1, -1); - } - - CGContextDrawImage (surface->cgContext, surface->sourceImageRect, surface->sourceImage); } else if (action == DO_SHADING) { + // we have to clip and then paint the shading; first we have to convert + // the stroke to a path that we can fill CGContextReplacePathWithStrokedPath (surface->cgContext); CGContextClip (surface->cgContext); @@ -1319,21 +1243,9 @@ _cairo_quartz_surface_show_glyphs (void *abstract_surface, int num_glyphs, cairo_scaled_font_t *scaled_font) { - ATSUFontID fid; - ATSFontRef atsfref; - CGFontRef cgfref; - CGAffineTransform cairoTextTransform, textTransform, ctm; - // XXXtodo/perf: stack storage for glyphs/sizes -#define STATIC_BUF_SIZE 64 - CGGlyph glyphs_static[STATIC_BUF_SIZE]; - CGSize cg_advances_static[STATIC_BUF_SIZE]; - CGGlyph *cg_glyphs = &glyphs_static[0]; - CGSize *cg_advances = &cg_advances_static[0]; - cairo_quartz_surface_t *surface = (cairo_quartz_surface_t *) abstract_surface; cairo_int_status_t rv = CAIRO_STATUS_SUCCESS; cairo_quartz_action_t action; - float xprev, yprev; int i; if (num_glyphs <= 0) @@ -1350,7 +1262,7 @@ _cairo_quartz_surface_show_glyphs (void *abstract_surface, action = _cairo_quartz_setup_source (surface, source); if (action == DO_SOLID || action == DO_PATTERN) { CGContextSetTextDrawingMode (surface->cgContext, kCGTextFill); - } else if (action == DO_IMAGE || action == DO_SHADING) { + } else if (action == DO_SHADING) { CGContextSetTextDrawingMode (surface->cgContext, kCGTextClip); } else { /* Unsupported */ @@ -1360,9 +1272,9 @@ _cairo_quartz_surface_show_glyphs (void *abstract_surface, CGContextSetCompositeOperation (surface->cgContext, _cairo_quartz_cairo_operator_to_quartz (op)); - fid = _cairo_atsui_scaled_font_get_atsu_font_id (scaled_font); - atsfref = FMGetATSFontRefFromFont (fid); - cgfref = CGFontCreateWithPlatformFont (&atsfref); + ATSUFontID fid = _cairo_atsui_scaled_font_get_atsu_font_id (scaled_font); + ATSFontRef atsfref = FMGetATSFontRefFromFont (fid); + CGFontRef cgfref = CGFontCreateWithPlatformFont (&atsfref); CGContextSetFont (surface->cgContext, cgfref); CGFontRelease (cgfref); @@ -1373,11 +1285,8 @@ _cairo_quartz_surface_show_glyphs (void *abstract_surface, * text matrix? */ //ND((stderr, "show_glyphs: glyph 0 at: %f, %f\n", glyphs[0].x, glyphs[0].y)); - cairoTextTransform = CGAffineTransformMake (scaled_font->font_matrix.xx, - scaled_font->font_matrix.yx, - scaled_font->font_matrix.xy, - scaled_font->font_matrix.yy, - 0., 0.); + CGAffineTransform cairoTextTransform, textTransform, ctm; + _cairo_quartz_cairo_matrix_to_quartz (&scaled_font->font_matrix, &cairoTextTransform); textTransform = CGAffineTransformMakeTranslation (glyphs[0].x, glyphs[0].y); textTransform = CGAffineTransformScale (textTransform, 1.0, -1.0); @@ -1393,27 +1302,51 @@ _cairo_quartz_surface_show_glyphs (void *abstract_surface, CGContextSetTextMatrix (surface->cgContext, textTransform); CGContextSetFontSize (surface->cgContext, 1.0); + // XXXtodo/perf: stack storage for glyphs/sizes +#define STATIC_BUF_SIZE 64 + CGGlyph glyphs_static[STATIC_BUF_SIZE]; + CGSize cg_advances_static[STATIC_BUF_SIZE]; + CGGlyph *cg_glyphs = &glyphs_static[0]; + CGSize *cg_advances = &cg_advances_static[0]; + if (num_glyphs > STATIC_BUF_SIZE) { cg_glyphs = (CGGlyph*) malloc(sizeof(CGGlyph) * num_glyphs); cg_advances = (CGSize*) malloc(sizeof(CGSize) * num_glyphs); } - xprev = glyphs[0].x; - yprev = glyphs[0].y; +#ifndef MOZILLA_CAIRO_NOT_DEFINED + float xprev = glyphs[0].x; + float yprev = glyphs[0].y; cg_glyphs[0] = glyphs[0].index; cg_advances[0].width = 0; cg_advances[0].height = 0; for (i = 1; i < num_glyphs; i++) { - float xf = glyphs[i].x; - float yf = glyphs[i].y; cg_glyphs[i] = glyphs[i].index; + float xf = glyphs[i].x; + float yf = glyphs[i].y; cg_advances[i-1].width = xf - xprev; cg_advances[i-1].height = yf - yprev; xprev = xf; yprev = yf; } +#else + double xprev = glyphs[0].x; + double yprev = glyphs[0].y; + + cg_glyphs[0] = glyphs[0].index; + cg_advances[0].width = 0; + cg_advances[0].height = 0; + + for (i = 1; i < num_glyphs; i++) { + cg_glyphs[i] = glyphs[i].index; + cg_advances[i-1].width = glyphs[i].x - xprev; + cg_advances[i-1].height = glyphs[i].y - yprev; + xprev = glyphs[i].x; + yprev = glyphs[i].y; + } +#endif /* MOZCAIRO */ #if 0 for (i = 0; i < num_glyphs; i++) { @@ -1431,17 +1364,8 @@ _cairo_quartz_surface_show_glyphs (void *abstract_surface, free (cg_advances); } - if (action == DO_IMAGE) { - CGContextConcatCTM (surface->cgContext, surface->sourceImageTransform); - if (cairo_surface_get_type(((cairo_surface_pattern_t*)source)->surface) == CAIRO_SURFACE_TYPE_QUARTZ) { - CGContextTranslateCTM (surface->cgContext, 0, CGImageGetHeight(surface->sourceImage)); - CGContextScaleCTM (surface->cgContext, 1, -1); - } - - CGContextDrawImage (surface->cgContext, surface->sourceImageRect, surface->sourceImage); - } else if (action == DO_SHADING) { + if (action == DO_SHADING) CGContextDrawShading (surface->cgContext, surface->sourceShading); - } _cairo_quartz_teardown_source (surface, source); @@ -1497,7 +1421,6 @@ _cairo_quartz_surface_intersect_clip_path (void *abstract_surface, cairo_antialias_t antialias) { cairo_quartz_surface_t *surface = (cairo_quartz_surface_t *) abstract_surface; - quartz_stroke_t stroke; ND((stderr, "%p _cairo_quartz_surface_intersect_clip_path path: %p\n", surface, path)); @@ -1513,9 +1436,7 @@ _cairo_quartz_surface_intersect_clip_path (void *abstract_surface, CGContextSaveGState (surface->cgContext); } else { CGContextBeginPath (surface->cgContext); - stroke.cgContext = surface->cgContext; - stroke.ctm_inverse = NULL; - _cairo_quartz_cairo_path_to_quartz_context (path, &stroke); + _cairo_quartz_cairo_path_to_quartz_context (path, surface->cgContext); if (fill_rule == CAIRO_FILL_RULE_WINDING) CGContextClip (surface->cgContext); else @@ -1534,7 +1455,7 @@ static const struct _cairo_surface_backend cairo_quartz_surface_backend = { _cairo_quartz_surface_create_similar, _cairo_quartz_surface_finish, _cairo_quartz_surface_acquire_source_image, - _cairo_quartz_surface_release_source_image, + NULL, /* release_source_image */ _cairo_quartz_surface_acquire_dest_image, _cairo_quartz_surface_release_dest_image, _cairo_quartz_surface_clone_similar, diff --git a/gfx/cairo/cairo/src/cairo-region.c b/gfx/cairo/cairo/src/cairo-region.c index c675a189501d..057f9fee84d0 100644 --- a/gfx/cairo/cairo/src/cairo-region.c +++ b/gfx/cairo/cairo/src/cairo-region.c @@ -33,7 +33,34 @@ * Owen Taylor */ -#include "cairoint.h" +#include + +/** + * _cairo_region_create_from_rectangle: + * @rect: a #cairo_rectangle_int16_t + * + * Creates a region with extents initialized from the given + * rectangle. + * + * Return value: a newly created #pixman_region16_t or %NULL if + * memory couldn't a allocated. + **/ +pixman_region16_t * +_cairo_region_create_from_rectangle (cairo_rectangle_int16_t *rect) +{ + /* We can't use pixman_region_create_simple(), because it doesn't + * have an error return + */ + pixman_region16_t *region = pixman_region_create (); + if (pixman_region_union_rect (region, region, + rect->x, rect->y, + rect->width, rect->height) != PIXMAN_REGION_STATUS_SUCCESS) { + pixman_region_destroy (region); + return NULL; + } + + return region; +} /** * _cairo_region_extents_rectangle: diff --git a/gfx/cairo/cairo/src/cairo-rename.h b/gfx/cairo/cairo/src/cairo-rename.h index 935f22df6d2e..d62c11815339 100644 --- a/gfx/cairo/cairo/src/cairo-rename.h +++ b/gfx/cairo/cairo/src/cairo-rename.h @@ -1,3 +1,4 @@ +#define _cairo_image_surface_nil_invalid_format __moz__cairo_image_surface_nil_invalid_format #define _cairo_pdf_test_force_fallbacks _moz__cairo_pdf_test_force_fallbacks #define _cairo_ps_test_force_fallbacks _moz__cairo_ps_test_force_fallbacks #define _cairo_scaled_font_test_set_max_glyphs_cached_per_font _moz__cairo_scaled_font_test_set_max_glyphs_cached_per_font @@ -258,6 +259,7 @@ #define cairo_version_string _moz_cairo_version_string #define cairo_win32_font_face_create_for_hfont _moz_cairo_win32_font_face_create_for_hfont #define cairo_win32_font_face_create_for_logfontw _moz_cairo_win32_font_face_create_for_logfontw +#define cairo_win32_font_face_create_for_logfontw_hfont _moz_cairo_win32_font_face_create_for_logfontw_hfont #define cairo_win32_scaled_font_done_font _moz_cairo_win32_scaled_font_done_font #define cairo_win32_scaled_font_get_device_to_logical _moz_cairo_win32_scaled_font_get_device_to_logical #define cairo_win32_scaled_font_get_logical_to_device _moz_cairo_win32_scaled_font_get_logical_to_device diff --git a/gfx/cairo/cairo/src/cairo-scaled-font-private.h b/gfx/cairo/cairo/src/cairo-scaled-font-private.h deleted file mode 100644 index fa71644ae389..000000000000 --- a/gfx/cairo/cairo/src/cairo-scaled-font-private.h +++ /dev/null @@ -1,112 +0,0 @@ -/* 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 - */ - -#ifndef CAIRO_SCALED_FONT_PRIVATE_H -#define CAIRO_SCALED_FONT_PRIVATE_H - -#include "cairo.h" - -#include "cairo-types-private.h" -#include "cairo-mutex-type-private.h" - -struct _cairo_scaled_font { - /* For most cairo objects, the rule for multiple threads is that - * the user is responsible for any locking if the same object is - * manipulated from multiple threads simultaneously. - * - * However, with the caching that cairo does for scaled fonts, a - * user can easily end up with the same cairo_scaled_font object - * being manipulated from multiple threads without the user ever - * being aware of this, (and in fact, unable to control it). - * - * So, as a special exception, the cairo implementation takes care - * of all locking needed for cairo_scaled_font_t. Most of what is - * in the scaled font is immutable, (which is what allows for the - * sharing in the first place). The things that are modified and - * the locks protecting them are as follows: - * - * 1. The reference count (scaled_font->ref_count) - * - * Modifications to the reference count are protected by the - * _cairo_scaled_font_map_mutex. This is because the reference - * count of a scaled font is intimately related with the font - * map itself, (and the magic holdovers array). - * - * 2. The cache of glyphs (scaled_font->glyphs) - * 3. The backend private data (scaled_font->surface_backend, - * scaled_font->surface_private) - * - * Modifications to these fields are protected with locks on - * scaled_font->mutex in the generic scaled_font code. - */ - - /* must be first to be stored in a hash table */ - cairo_hash_entry_t hash_entry; - - /* useful bits for _cairo_scaled_font_nil */ - cairo_status_t status; - unsigned int ref_count; - cairo_user_data_array_t user_data; - - /* hash key members */ - cairo_font_face_t *font_face; /* may be NULL */ - cairo_matrix_t font_matrix; /* font space => user space */ - cairo_matrix_t ctm; /* user space => device space */ - cairo_font_options_t options; - - /* "live" scaled_font members */ - cairo_matrix_t scale; /* font space => device space */ - cairo_font_extents_t extents; /* user space */ - - /* The mutex protects modification to all subsequent fields. */ - cairo_mutex_t mutex; - - cairo_cache_t *glyphs; /* glyph index -> cairo_scaled_glyph_t */ - - /* - * One surface backend may store data in each glyph. - * Whichever surface manages to store its pointer here - * first gets to store data in each glyph - */ - const cairo_surface_backend_t *surface_backend; - void *surface_private; - - /* font backend managing this scaled font */ - const cairo_scaled_font_backend_t *backend; -}; - -#endif /* CAIRO_SCALED_FONT_PRIVATE_H */ diff --git a/gfx/cairo/cairo/src/cairo-scaled-font-subsets-private.h b/gfx/cairo/cairo/src/cairo-scaled-font-subsets-private.h index 5b9467a9f95e..510434049ba4 100644 --- a/gfx/cairo/cairo/src/cairo-scaled-font-subsets-private.h +++ b/gfx/cairo/cairo/src/cairo-scaled-font-subsets-private.h @@ -39,17 +39,19 @@ #include "cairoint.h" -typedef struct _cairo_scaled_font_subsets_glyph { - unsigned int font_id; - unsigned int subset_id; - unsigned int subset_glyph_index; - cairo_bool_t is_scaled; - cairo_bool_t is_composite; - double x_advance; -} cairo_scaled_font_subsets_glyph_t; +typedef struct _cairo_scaled_font_subsets cairo_scaled_font_subsets_t; /** - * _cairo_scaled_font_subsets_create_scaled: + * _cairo_scaled_font_subsets_create: + * + * @max_glyphs_per_unscaled_subset: the maximum number of glyphs that + * should appear in any unscaled subset. A value of 0 indicates that + * no unscaled subset will be created. All glyphs will mapped to + * scaled subsets. + * + * @max_glyphs_per_scaled_subset: the maximum number of glyphs that + * should appear in any scaled subset. A value of 0 indicates that + * no scaled subset will be created. * * Create a new #cairo_scaled_font_subsets_t object which can be used * to create subsets of any number of cairo_scaled_font_t @@ -58,57 +60,16 @@ typedef struct _cairo_scaled_font_subsets_glyph { * subsets with glyph indices packed into the range * [0 .. max_glyphs_per_subset). * - * Return value: a pointer to the newly creates font subsets. The - * caller owns this object and should call - * _cairo_scaled_font_subsets_destroy() when done with it. - **/ -cairo_private cairo_scaled_font_subsets_t * -_cairo_scaled_font_subsets_create_scaled (void); - -/** - * _cairo_scaled_font_subsets_create_simple: - * - * Create a new #cairo_scaled_font_subsets_t object which can be used - * to create font subsets suitable for embedding as Postscript or PDF - * simple fonts. - * - * Glyphs with an outline path available will be mapped to one font - * subset for each font face. Glyphs from bitmap fonts will mapped to - * separate font subsets for each cairo_scaled_font_t object. - * - * The maximum number of glyphs per subset is 256. Each subset - * reserves the first glyph for the .notdef glyph. + * @max_glyphs_per_unscaled_subset and @max_glyphs_per_scaled_subset + * cannot both be 0. * * Return value: a pointer to the newly creates font subsets. The * caller owns this object and should call * _cairo_scaled_font_subsets_destroy() when done with it. **/ cairo_private cairo_scaled_font_subsets_t * -_cairo_scaled_font_subsets_create_simple (void); - -/** - * _cairo_scaled_font_subsets_create_composite: - * - * Create a new #cairo_scaled_font_subsets_t object which can be used - * to create font subsets suitable for embedding as Postscript or PDF - * composite fonts. - * - * Glyphs with an outline path available will be mapped to one font - * subset for each font face. Each unscaled subset has a maximum of - * 65536 glyphs except for Type1 fonts which have a maximum of 256 glyphs. - * - * Glyphs from bitmap fonts will mapped to separate font subsets for - * each cairo_scaled_font_t object. Each unscaled subset has a maximum - * of 256 glyphs. - * - * Each subset reserves the first glyph for the .notdef glyph. - * - * Return value: a pointer to the newly creates font subsets. The - * caller owns this object and should call - * _cairo_scaled_font_subsets_destroy() when done with it. - **/ -cairo_private cairo_scaled_font_subsets_t * -_cairo_scaled_font_subsets_create_composite (void); +_cairo_scaled_font_subsets_create (int max_glyphs_unscaled_per_subset, + int max_glyphs_scaled_per_subset); /** * _cairo_scaled_font_subsets_destroy: @@ -124,8 +85,6 @@ _cairo_scaled_font_subsets_destroy (cairo_scaled_font_subsets_t *font_subsets); * @font_subsets: a #cairo_scaled_font_subsets_t * @scaled_font: the font of the glyph to be mapped * @scaled_font_glyph_index: the index of the glyph to be mapped - * @subset_glyph_ret: return structure containing subset font and glyph id - * * @font_id_ret: return value giving the font ID of the mapped glyph * @subset_id_ret: return value giving the subset ID of the mapped glyph within the @font_id_ret * @subset_glyph_index_ret: return value giving the index of the mapped glyph within the @subset_id_ret subset @@ -167,17 +126,6 @@ _cairo_scaled_font_subsets_destroy (cairo_scaled_font_subsets_t *font_subsets); * used by #cairo_scaled_font_subset_t as provided by * _cairo_scaled_font_subsets_foreach. * - * The returned values in the cairo_scaled_font_subsets_glyph_t struct are: - * - * @font_id: The font ID of the mapped glyph - * @subset_id : The subset ID of the mapped glyph within the @font_id - * @subset_glyph_index: The index of the mapped glyph within the @subset_id subset - * @is_scaled: If true, the mapped glyph is from a bitmap font, and separate font - * subset is created for each font scale used. If false, the outline of the mapped glyph - * is available. One font subset for each font face is created. - * @x_advance: When @is_scaled is true, @x_advance contains the x_advance for the mapped glyph in device space. - * When @is_scaled is false, @x_advance contains the x_advance for the the mapped glyph from an unhinted 1 point font. - * * Return value: CAIRO_STATUS_SUCCESS if successful, or a non-zero * value indicating an error. Possible errors include * CAIRO_STATUS_NO_MEMORY. @@ -186,7 +134,9 @@ cairo_private cairo_status_t _cairo_scaled_font_subsets_map_glyph (cairo_scaled_font_subsets_t *font_subsets, cairo_scaled_font_t *scaled_font, unsigned long scaled_font_glyph_index, - cairo_scaled_font_subsets_glyph_t *subset_glyph_ret); + unsigned int *font_id_ret, + unsigned int *subset_id_ret, + unsigned int *subset_glyph_index_ret); typedef void (*cairo_scaled_font_subset_callback_func_t) (cairo_scaled_font_subset_t *font_subset, @@ -303,37 +253,6 @@ _cairo_cff_subset_init (cairo_cff_subset_t *cff_subset, cairo_private void _cairo_cff_subset_fini (cairo_cff_subset_t *cff_subset); -/** - * _cairo_cff_fallback_init: - * @cff_subset: a #cairo_cff_subset_t to initialize - * @font_subset: the #cairo_scaled_font_subset_t to initialize from - * - * If possible (depending on the format of the underlying - * cairo_scaled_font_t and the font backend in use) generate a cff - * file corresponding to @font_subset and initialize @cff_subset - * with information about the subset and the cff data. - * - * Return value: CAIRO_STATUS_SUCCESS if successful, - * CAIRO_INT_STATUS_UNSUPPORTED if the font can't be subset as a - * cff file, or an non-zero value indicating an error. Possible - * errors include CAIRO_STATUS_NO_MEMORY. - **/ -cairo_private cairo_status_t -_cairo_cff_fallback_init (cairo_cff_subset_t *cff_subset, - const char *name, - cairo_scaled_font_subset_t *font_subset); - -/** - * _cairo_cff_fallback_fini: - * @cff_subset: a #cairo_cff_subset_t - * - * Free all resources associated with @cff_subset. After this - * call, @cff_subset should not be used again without a - * subsequent call to _cairo_cff_subset_init() again first. - **/ -cairo_private void -_cairo_cff_fallback_fini (cairo_cff_subset_t *cff_subset); - typedef struct _cairo_truetype_subset { char *base_font; double *widths; @@ -422,15 +341,6 @@ _cairo_type1_subset_init (cairo_type1_subset_t *type_subset, cairo_private void _cairo_type1_subset_fini (cairo_type1_subset_t *subset); -/** - * _cairo_type1_scaled_font_is_type1: - * @scaled_font: a #cairo_scaled_font_t - * - * Return TRUE if @scaled_font is a Type 1 font, otherwise return FALSE. - **/ -cairo_private cairo_bool_t -_cairo_type1_scaled_font_is_type1 (cairo_scaled_font_t *scaled_font); - /** * _cairo_type1_fallback_init_binary: * @type1_subset: a #cairo_type1_subset_t to initialize @@ -484,43 +394,6 @@ _cairo_type1_fallback_init_hex (cairo_type1_subset_t *type_subset, cairo_private void _cairo_type1_fallback_fini (cairo_type1_subset_t *subset); -typedef struct _cairo_type2_charstrings { - int *widths; - long x_min, y_min, x_max, y_max; - long ascent, descent; - cairo_array_t charstrings; -} cairo_type2_charstrings_t; - -/** - * _cairo_type2_charstrings_init: - * @type2_subset: a #cairo_type2_subset_t to initialize - * @font_subset: the #cairo_scaled_font_subset_t to initialize from - * - * If possible (depending on the format of the underlying - * cairo_scaled_font_t and the font backend in use) generate type2 - * charstrings to @font_subset and initialize @type2_subset - * with information about the subset. - * - * Return value: CAIRO_STATUS_SUCCESS if successful, - * CAIRO_INT_STATUS_UNSUPPORTED if the font can't be subset as a type2 - * charstrings, or an non-zero value indicating an error. Possible errors - * include CAIRO_STATUS_NO_MEMORY. - **/ -cairo_private cairo_status_t -_cairo_type2_charstrings_init (cairo_type2_charstrings_t *charstrings, - cairo_scaled_font_subset_t *font_subset); - -/** - * _cairo_type2_charstrings_fini: - * @subset: a #cairo_type2_charstrings_t - * - * Free all resources associated with @type2_charstring. After this call, - * @type2_charstring should not be used again without a subsequent call to - * _cairo_type2_charstring_init() again first. - **/ -cairo_private void -_cairo_type2_charstrings_fini (cairo_type2_charstrings_t *charstrings); - /** * _cairo_truetype_create_glyph_to_unicode_map: * @font_subset: the #cairo_scaled_font_subset_t to initialize from diff --git a/gfx/cairo/cairo/src/cairo-scaled-font-subsets.c b/gfx/cairo/cairo/src/cairo-scaled-font-subsets.c index 65b1cdce2c13..d98cba2f862f 100644 --- a/gfx/cairo/cairo/src/cairo-scaled-font-subsets.c +++ b/gfx/cairo/cairo/src/cairo-scaled-font-subsets.c @@ -42,21 +42,12 @@ #include "cairoint.h" #include "cairo-scaled-font-subsets-private.h" -#define MAX_GLYPHS_PER_SIMPLE_FONT 256 -#define MAX_GLYPHS_PER_COMPOSITE_FONT 65536 - -typedef enum { - CAIRO_SUBSETS_SCALED, - CAIRO_SUBSETS_SIMPLE, - CAIRO_SUBSETS_COMPOSITE -} cairo_subsets_type_t; - struct _cairo_scaled_font_subsets { - cairo_subsets_type_t type; - + int max_glyphs_per_unscaled_subset_limit; int max_glyphs_per_unscaled_subset_used; cairo_hash_table_t *unscaled_sub_fonts; + int max_glyphs_per_scaled_subset_limit; int max_glyphs_per_scaled_subset_used; cairo_hash_table_t *scaled_sub_fonts; @@ -67,7 +58,6 @@ typedef struct _cairo_sub_font { cairo_hash_entry_t base; cairo_bool_t is_scaled; - cairo_bool_t is_composite; cairo_scaled_font_subsets_t *parent; cairo_scaled_font_t *scaled_font; unsigned int font_id; @@ -84,7 +74,6 @@ typedef struct _cairo_sub_font_glyph { unsigned int subset_id; unsigned int subset_glyph_index; - double x_advance; } cairo_sub_font_glyph_t; typedef struct _cairo_sub_font_collection { @@ -118,8 +107,7 @@ _cairo_sub_font_glyphs_equal (const void *key_a, const void *key_b) static cairo_sub_font_glyph_t * _cairo_sub_font_glyph_create (unsigned long scaled_font_glyph_index, unsigned int subset_id, - unsigned int subset_glyph_index, - double x_advance) + unsigned int subset_glyph_index) { cairo_sub_font_glyph_t *sub_font_glyph; @@ -130,7 +118,6 @@ _cairo_sub_font_glyph_create (unsigned long scaled_font_glyph_index, _cairo_sub_font_glyph_init_key (sub_font_glyph, scaled_font_glyph_index); sub_font_glyph->subset_id = subset_id; sub_font_glyph->subset_glyph_index = subset_glyph_index; - sub_font_glyph->x_advance = x_advance; return sub_font_glyph; } @@ -208,8 +195,7 @@ _cairo_sub_font_create (cairo_scaled_font_subsets_t *parent, cairo_scaled_font_t *scaled_font, unsigned int font_id, int max_glyphs_per_subset, - cairo_bool_t is_scaled, - cairo_bool_t is_composite) + cairo_bool_t is_scaled) { cairo_sub_font_t *sub_font; @@ -218,11 +204,10 @@ _cairo_sub_font_create (cairo_scaled_font_subsets_t *parent, return NULL; sub_font->is_scaled = is_scaled; - sub_font->is_composite = is_composite; _cairo_sub_font_init_key (sub_font, scaled_font); sub_font->parent = parent; - sub_font->scaled_font = scaled_font; + sub_font->scaled_font = cairo_scaled_font_reference (scaled_font); sub_font->font_id = font_id; sub_font->current_subset = 0; @@ -235,11 +220,6 @@ _cairo_sub_font_create (cairo_scaled_font_subsets_t *parent, return NULL; } - if (parent->type != CAIRO_SUBSETS_SCALED) { - /* Reserve first glyph in subset for the .notdef glyph */ - sub_font->num_glyphs_in_current_subset++; - } - return sub_font; } @@ -265,9 +245,10 @@ _cairo_sub_font_pluck (void *entry, void *closure) } static cairo_status_t -_cairo_sub_font_lookup_glyph (cairo_sub_font_t *sub_font, - unsigned long scaled_font_glyph_index, - cairo_scaled_font_subsets_glyph_t *subset_glyph) +_cairo_sub_font_lookup_glyph (cairo_sub_font_t *sub_font, + unsigned long scaled_font_glyph_index, + unsigned int *subset_id, + unsigned int *subset_glyph_index) { cairo_sub_font_glyph_t key, *sub_font_glyph; @@ -275,12 +256,8 @@ _cairo_sub_font_lookup_glyph (cairo_sub_font_t *sub_font, if (_cairo_hash_table_lookup (sub_font->sub_font_glyphs, &key.base, (cairo_hash_entry_t **) &sub_font_glyph)) { - subset_glyph->font_id = sub_font->font_id; - subset_glyph->subset_id = sub_font_glyph->subset_id; - subset_glyph->subset_glyph_index = sub_font_glyph->subset_glyph_index; - subset_glyph->is_scaled = sub_font->is_scaled; - subset_glyph->is_composite = sub_font->is_composite; - subset_glyph->x_advance = sub_font_glyph->x_advance; + *subset_id = sub_font_glyph->subset_id; + *subset_glyph_index = sub_font_glyph->subset_glyph_index; return CAIRO_STATUS_SUCCESS; } @@ -291,11 +268,11 @@ _cairo_sub_font_lookup_glyph (cairo_sub_font_t *sub_font, static cairo_status_t _cairo_sub_font_map_glyph (cairo_sub_font_t *sub_font, unsigned long scaled_font_glyph_index, - cairo_scaled_font_subsets_glyph_t *subset_glyph) + unsigned int *subset_id, + unsigned int *subset_glyph_index) { cairo_sub_font_glyph_t key, *sub_font_glyph; cairo_status_t status; - cairo_scaled_glyph_t *scaled_glyph; _cairo_sub_font_glyph_init_key (&key, scaled_font_glyph_index); if (! _cairo_hash_table_lookup (sub_font->sub_font_glyphs, &key.base, @@ -305,24 +282,11 @@ _cairo_sub_font_map_glyph (cairo_sub_font_t *sub_font, { sub_font->current_subset++; sub_font->num_glyphs_in_current_subset = 0; - - if (sub_font->parent->type != CAIRO_SUBSETS_SCALED) { - /* Reserve first glyph in subset for the .notdef glyph */ - sub_font->num_glyphs_in_current_subset++; - } } - status = _cairo_scaled_glyph_lookup (sub_font->scaled_font, - scaled_font_glyph_index, - CAIRO_SCALED_GLYPH_INFO_METRICS, - &scaled_glyph); - if (status) - return status; - - sub_font_glyph = _cairo_sub_font_glyph_create (scaled_font_glyph_index, + sub_font_glyph = _cairo_sub_font_glyph_create (scaled_font_glyph_index, sub_font->current_subset, - sub_font->num_glyphs_in_current_subset++, - scaled_glyph->metrics.x_advance); + sub_font->num_glyphs_in_current_subset++); if (sub_font_glyph == NULL) return CAIRO_STATUS_NO_MEMORY; @@ -338,18 +302,12 @@ _cairo_sub_font_map_glyph (cairo_sub_font_t *sub_font, } status = _cairo_hash_table_insert (sub_font->sub_font_glyphs, &sub_font_glyph->base); - if (status) { - _cairo_sub_font_glyph_destroy (sub_font_glyph); + if (status) return status; - } } - subset_glyph->font_id = sub_font->font_id; - subset_glyph->subset_id = sub_font_glyph->subset_id; - subset_glyph->subset_glyph_index = sub_font_glyph->subset_glyph_index; - subset_glyph->is_scaled = sub_font->is_scaled; - subset_glyph->is_composite = sub_font->is_composite; - subset_glyph->x_advance = sub_font_glyph->x_advance; + *subset_id = sub_font_glyph->subset_id; + *subset_glyph_index = sub_font_glyph->subset_glyph_index; return CAIRO_STATUS_SUCCESS; } @@ -366,24 +324,16 @@ _cairo_sub_font_collect (void *entry, void *closure) for (i = 0; i <= sub_font->current_subset; i++) { collection->subset_id = i; - if (sub_font->parent->type == CAIRO_SUBSETS_SCALED) { - collection->num_glyphs = 0; - collection->max_glyph = 0; - } else { - /* Assign .notdef glyph to the first glyph in the subset */ - collection->glyphs[0] = 0; - collection->num_glyphs = 1; - collection->max_glyph = 0; - } + collection->num_glyphs = 0; + collection->max_glyph = 0; _cairo_hash_table_foreach (sub_font->sub_font_glyphs, _cairo_sub_font_glyph_collect, collection); - /* Ensure the resulting array has no uninitialized holes */ + /* Ensure the resulting array has no uninitialized holes */ assert (collection->num_glyphs == collection->max_glyph + 1); subset.scaled_font = sub_font->scaled_font; - subset.is_composite = sub_font->is_composite; subset.font_id = sub_font->font_id; subset.subset_id = i; subset.glyphs = collection->glyphs; @@ -405,8 +355,9 @@ _cairo_sub_font_collect (void *entry, void *closure) } } -static cairo_scaled_font_subsets_t * -_cairo_scaled_font_subsets_create_internal (cairo_subsets_type_t type) +cairo_scaled_font_subsets_t * +_cairo_scaled_font_subsets_create (int max_glyphs_per_unscaled_subset, + int max_glyphs_per_scaled_subset) { cairo_scaled_font_subsets_t *subsets; @@ -414,9 +365,12 @@ _cairo_scaled_font_subsets_create_internal (cairo_subsets_type_t type) if (subsets == NULL) return NULL; - subsets->type = type; + subsets->max_glyphs_per_unscaled_subset_limit = max_glyphs_per_unscaled_subset; subsets->max_glyphs_per_unscaled_subset_used = 0; + + subsets->max_glyphs_per_scaled_subset_limit = max_glyphs_per_scaled_subset; subsets->max_glyphs_per_scaled_subset_used = 0; + subsets->num_sub_fonts = 0; subsets->unscaled_sub_fonts = _cairo_hash_table_create (_cairo_sub_fonts_equal); @@ -427,7 +381,7 @@ _cairo_scaled_font_subsets_create_internal (cairo_subsets_type_t type) subsets->scaled_sub_fonts = _cairo_hash_table_create (_cairo_sub_fonts_equal); if (! subsets->scaled_sub_fonts) { - _cairo_hash_table_destroy (subsets->unscaled_sub_fonts); + free (subsets->unscaled_sub_fonts); free (subsets); return NULL; } @@ -435,24 +389,6 @@ _cairo_scaled_font_subsets_create_internal (cairo_subsets_type_t type) return subsets; } -cairo_scaled_font_subsets_t * -_cairo_scaled_font_subsets_create_scaled (void) -{ - return _cairo_scaled_font_subsets_create_internal (CAIRO_SUBSETS_SCALED); -} - -cairo_scaled_font_subsets_t * -_cairo_scaled_font_subsets_create_simple (void) -{ - return _cairo_scaled_font_subsets_create_internal (CAIRO_SUBSETS_SIMPLE); -} - -cairo_scaled_font_subsets_t * -_cairo_scaled_font_subsets_create_composite (void) -{ - return _cairo_scaled_font_subsets_create_internal (CAIRO_SUBSETS_COMPOSITE); -} - void _cairo_scaled_font_subsets_destroy (cairo_scaled_font_subsets_t *subsets) { @@ -468,44 +404,44 @@ cairo_private cairo_status_t _cairo_scaled_font_subsets_map_glyph (cairo_scaled_font_subsets_t *subsets, cairo_scaled_font_t *scaled_font, unsigned long scaled_font_glyph_index, - cairo_scaled_font_subsets_glyph_t *subset_glyph) + unsigned int *font_id, + unsigned int *subset_id, + unsigned int *subset_glyph_index) { cairo_sub_font_t key, *sub_font; cairo_scaled_glyph_t *scaled_glyph; - cairo_font_face_t *font_face; - cairo_matrix_t identity; - cairo_font_options_t font_options; - cairo_scaled_font_t *unscaled_font; cairo_status_t status; - int max_glyphs; - cairo_bool_t type1_font; /* Lookup glyph in unscaled subsets */ - if (subsets->type != CAIRO_SUBSETS_SCALED) { + if (subsets->max_glyphs_per_unscaled_subset_limit > 0) { key.is_scaled = FALSE; _cairo_sub_font_init_key (&key, scaled_font); if (_cairo_hash_table_lookup (subsets->unscaled_sub_fonts, &key.base, (cairo_hash_entry_t **) &sub_font)) { - status = _cairo_sub_font_lookup_glyph (sub_font, - scaled_font_glyph_index, - subset_glyph); - if (status == CAIRO_STATUS_SUCCESS) + status = _cairo_sub_font_lookup_glyph (sub_font, scaled_font_glyph_index, + subset_id, subset_glyph_index); + if (status == CAIRO_STATUS_SUCCESS) { + *font_id = sub_font->font_id; return CAIRO_STATUS_SUCCESS; + } } } /* Lookup glyph in scaled subsets */ - key.is_scaled = TRUE; - _cairo_sub_font_init_key (&key, scaled_font); - if (_cairo_hash_table_lookup (subsets->scaled_sub_fonts, &key.base, - (cairo_hash_entry_t **) &sub_font)) - { - status = _cairo_sub_font_lookup_glyph (sub_font, - scaled_font_glyph_index, - subset_glyph); - if (status == CAIRO_STATUS_SUCCESS) - return CAIRO_STATUS_SUCCESS; + if (subsets->max_glyphs_per_scaled_subset_limit > 0) { + key.is_scaled = TRUE; + _cairo_sub_font_init_key (&key, scaled_font); + if (_cairo_hash_table_lookup (subsets->scaled_sub_fonts, &key.base, + (cairo_hash_entry_t **) &sub_font)) + { + status = _cairo_sub_font_lookup_glyph (sub_font, scaled_font_glyph_index, + subset_id, subset_glyph_index); + if (status == CAIRO_STATUS_SUCCESS) { + *font_id = sub_font->font_id; + return CAIRO_STATUS_SUCCESS; + } + } } /* Glyph not found. Determine whether the glyph is outline or @@ -514,96 +450,51 @@ _cairo_scaled_font_subsets_map_glyph (cairo_scaled_font_subsets_t *subsets, scaled_font_glyph_index, CAIRO_SCALED_GLYPH_INFO_PATH, &scaled_glyph); - if (status && status != CAIRO_INT_STATUS_UNSUPPORTED) - return status; - - if (status == 0 && subsets->type != CAIRO_SUBSETS_SCALED) { + if (status == 0 && subsets->max_glyphs_per_unscaled_subset_limit > 0) { /* Path available. Add to unscaled subset. */ key.is_scaled = FALSE; _cairo_sub_font_init_key (&key, scaled_font); if (! _cairo_hash_table_lookup (subsets->unscaled_sub_fonts, &key.base, (cairo_hash_entry_t **) &sub_font)) { - font_face = cairo_scaled_font_get_font_face (scaled_font); - cairo_matrix_init_identity (&identity); - _cairo_font_options_init_default (&font_options); - cairo_font_options_set_hint_style (&font_options, CAIRO_HINT_STYLE_NONE); - cairo_font_options_set_hint_metrics (&font_options, CAIRO_HINT_METRICS_OFF); - unscaled_font = cairo_scaled_font_create (font_face, - &identity, - &identity, - &font_options); - if (unscaled_font->status) - return unscaled_font->status; - - subset_glyph->is_scaled = FALSE; - type1_font = FALSE; -#if CAIRO_HAS_FT_FONT - type1_font = _cairo_type1_scaled_font_is_type1 (unscaled_font); -#endif - if (subsets->type == CAIRO_SUBSETS_COMPOSITE && !type1_font) { - max_glyphs = MAX_GLYPHS_PER_COMPOSITE_FONT; - subset_glyph->is_composite = TRUE; - } else { - max_glyphs = MAX_GLYPHS_PER_SIMPLE_FONT; - subset_glyph->is_composite = FALSE; - } - - sub_font = _cairo_sub_font_create (subsets, - unscaled_font, + sub_font = _cairo_sub_font_create (subsets, scaled_font, subsets->num_sub_fonts++, - max_glyphs, - subset_glyph->is_scaled, - subset_glyph->is_composite); - if (sub_font == NULL) { - cairo_scaled_font_destroy (unscaled_font); + subsets->max_glyphs_per_unscaled_subset_limit, + FALSE); + if (sub_font == NULL) return CAIRO_STATUS_NO_MEMORY; - } status = _cairo_hash_table_insert (subsets->unscaled_sub_fonts, &sub_font->base); - if (status) { - _cairo_sub_font_destroy (sub_font); + if (status) return status; - } } - } else { + } else if (subsets->max_glyphs_per_scaled_subset_limit > 0) { /* No path available. Add to scaled subset. */ key.is_scaled = TRUE; _cairo_sub_font_init_key (&key, scaled_font); if (! _cairo_hash_table_lookup (subsets->scaled_sub_fonts, &key.base, (cairo_hash_entry_t **) &sub_font)) { - subset_glyph->is_scaled = TRUE; - subset_glyph->is_composite = FALSE; - if (subsets->type == CAIRO_SUBSETS_SCALED) - max_glyphs = INT_MAX; - else - max_glyphs = MAX_GLYPHS_PER_SIMPLE_FONT; - - sub_font = _cairo_sub_font_create (subsets, - cairo_scaled_font_reference (scaled_font), + sub_font = _cairo_sub_font_create (subsets, scaled_font, subsets->num_sub_fonts++, - max_glyphs, - subset_glyph->is_scaled, - subset_glyph->is_composite); - if (sub_font == NULL) { - cairo_scaled_font_destroy (scaled_font); + subsets->max_glyphs_per_scaled_subset_limit, + TRUE); + if (sub_font == NULL) return CAIRO_STATUS_NO_MEMORY; - } status = _cairo_hash_table_insert (subsets->scaled_sub_fonts, &sub_font->base); - if (status) { - _cairo_sub_font_destroy (sub_font); + if (status) return status; - } } + } else { + return CAIRO_INT_STATUS_UNSUPPORTED; } + *font_id = sub_font->font_id; - return _cairo_sub_font_map_glyph (sub_font, - scaled_font_glyph_index, - subset_glyph); + return _cairo_sub_font_map_glyph (sub_font, scaled_font_glyph_index, + subset_id, subset_glyph_index); } static cairo_status_t @@ -618,10 +509,6 @@ _cairo_scaled_font_subsets_foreach_internal (cairo_scaled_font_subsets_t collection.glyphs_size = font_subsets->max_glyphs_per_scaled_subset_used; else collection.glyphs_size = font_subsets->max_glyphs_per_unscaled_subset_used; - - if (! collection.glyphs_size) - return CAIRO_STATUS_SUCCESS; - collection.glyphs = malloc (collection.glyphs_size * sizeof(unsigned long)); if (collection.glyphs == NULL) return CAIRO_STATUS_NO_MEMORY; @@ -653,7 +540,7 @@ _cairo_scaled_font_subsets_foreach_scaled (cairo_scaled_font_subsets_t *fon } cairo_private cairo_status_t -_cairo_scaled_font_subsets_foreach_unscaled (cairo_scaled_font_subsets_t *font_subsets, +_cairo_scaled_font_subsets_foreach_unscaled (cairo_scaled_font_subsets_t *font_subsets, cairo_scaled_font_subset_callback_func_t font_subset_callback, void *closure) { diff --git a/gfx/cairo/cairo/src/cairo-scaled-font.c b/gfx/cairo/cairo/src/cairo-scaled-font.c index 7a472191bf47..6efde8002e6b 100644 --- a/gfx/cairo/cairo/src/cairo-scaled-font.c +++ b/gfx/cairo/cairo/src/cairo-scaled-font.c @@ -37,7 +37,7 @@ */ #include "cairoint.h" -#include "cairo-scaled-font-private.h" +#include "cairo-scaled-font-test.h" static cairo_bool_t _cairo_scaled_glyph_keys_equal (const void *abstract_key_a, const void *abstract_key_b) @@ -135,9 +135,6 @@ _cairo_scaled_font_set_error (cairo_scaled_font_t *scaled_font, cairo_font_type_t cairo_scaled_font_get_type (cairo_scaled_font_t *scaled_font) { - if (scaled_font->ref_count == CAIRO_REF_COUNT_INVALID) - return CAIRO_FONT_TYPE_TOY; - return scaled_font->backend->type; } @@ -156,7 +153,6 @@ cairo_scaled_font_status (cairo_scaled_font_t *scaled_font) { return scaled_font->status; } -slim_hidden_def (cairo_scaled_font_status); /* Here we keep a unique mapping from * cairo_font_face_t/matrix/ctm/options => cairo_scaled_font_t. @@ -189,6 +185,8 @@ typedef struct _cairo_scaled_font_map { static cairo_scaled_font_map_t *cairo_scaled_font_map = NULL; +CAIRO_MUTEX_DECLARE (_cairo_scaled_font_map_mutex); + static int _cairo_scaled_font_keys_equal (const void *abstract_key_a, const void *abstract_key_b); @@ -215,7 +213,6 @@ _cairo_scaled_font_map_lock (void) CLEANUP_SCALED_FONT_MAP: free (cairo_scaled_font_map); - cairo_scaled_font_map = NULL; CLEANUP_MUTEX_LOCK: CAIRO_MUTEX_UNLOCK (_cairo_scaled_font_map_mutex); return NULL; @@ -334,7 +331,14 @@ _cairo_scaled_font_keys_equal (const void *abstract_key_a, const void *abstract_ * separately is probably not what we want anyway. Would probably be * much better to have a single cache for glyphs with random * replacement across all glyphs of all fonts. */ -#define MAX_GLYPHS_CACHED_PER_FONT 256 +static int max_glyphs_cached_per_font = 256; + +/* For internal testing purposes only. Not part of the supported API. */ +void +_cairo_scaled_font_test_set_max_glyphs_cached_per_font (int max) +{ + max_glyphs_cached_per_font = max; +} /* * Basic cairo_scaled_font_t object management @@ -348,40 +352,23 @@ _cairo_scaled_font_init (cairo_scaled_font_t *scaled_font, const cairo_font_options_t *options, const cairo_scaled_font_backend_t *backend) { - cairo_matrix_t inverse; - cairo_status_t status; + scaled_font->ref_count = 1; - status = cairo_font_options_status ((cairo_font_options_t *) options); - if (status) - return status; + _cairo_user_data_array_init (&scaled_font->user_data); - /* Initialize scaled_font->scale early for easier bail out on an - * invalid matrix. */ _cairo_scaled_font_init_key (scaled_font, font_face, font_matrix, ctm, options); + cairo_font_face_reference (font_face); + cairo_matrix_multiply (&scaled_font->scale, &scaled_font->font_matrix, &scaled_font->ctm); - inverse = scaled_font->scale; - status = cairo_matrix_invert (&inverse); - if (status) - return status; - + CAIRO_MUTEX_INIT (&scaled_font->mutex); scaled_font->glyphs = _cairo_cache_create (_cairo_scaled_glyph_keys_equal, _cairo_scaled_glyph_destroy, - MAX_GLYPHS_CACHED_PER_FONT); - if (scaled_font->glyphs == NULL) - return CAIRO_STATUS_NO_MEMORY; - - scaled_font->ref_count = 1; - - _cairo_user_data_array_init (&scaled_font->user_data); - - cairo_font_face_reference (font_face); - - CAIRO_MUTEX_INIT (scaled_font->mutex); + max_glyphs_cached_per_font); scaled_font->surface_backend = NULL; scaled_font->surface_private = NULL; @@ -409,7 +396,7 @@ _cairo_scaled_font_reset_cache (cairo_scaled_font_t *scaled_font) _cairo_cache_destroy (scaled_font->glyphs); scaled_font->glyphs = _cairo_cache_create (_cairo_scaled_glyph_keys_equal, _cairo_scaled_glyph_destroy, - MAX_GLYPHS_CACHED_PER_FONT); + max_glyphs_cached_per_font); } void @@ -443,7 +430,7 @@ _cairo_scaled_font_fini (cairo_scaled_font_t *scaled_font) if (scaled_font->glyphs != NULL) _cairo_cache_destroy (scaled_font->glyphs); - CAIRO_MUTEX_FINI (scaled_font->mutex); + CAIRO_MUTEX_FINI (&scaled_font->mutex); if (scaled_font->surface_backend != NULL && scaled_font->surface_backend->scaled_font_fini != NULL) @@ -487,12 +474,9 @@ cairo_scaled_font_create (cairo_font_face_t *font_face, if (font_face->status) return (cairo_scaled_font_t *)&_cairo_scaled_font_nil; - if (cairo_font_options_status ((cairo_font_options_t *) options)) - return (cairo_scaled_font_t *)&_cairo_scaled_font_nil; - font_map = _cairo_scaled_font_map_lock (); if (font_map == NULL) - return (cairo_scaled_font_t *)&_cairo_scaled_font_nil; + return NULL; _cairo_scaled_font_init_key (&key, font_face, font_matrix, ctm, options); @@ -517,44 +501,35 @@ cairo_scaled_font_create (cairo_font_face_t *font_face, memmove (&font_map->holdovers[i], &font_map->holdovers[i+1], (font_map->num_holdovers - i) * sizeof (cairo_scaled_font_t*)); - - /* reset any error status */ - scaled_font->status = CAIRO_STATUS_SUCCESS; } - if (scaled_font->status == CAIRO_STATUS_SUCCESS) { - /* We increment the reference count manually here, (rather - * than calling into cairo_scaled_font_reference), since we - * must modify the reference count while our lock is still - * held. */ - scaled_font->ref_count++; - _cairo_scaled_font_map_unlock (); - return scaled_font; - } - - /* the font has been put into an error status - abandon the cache */ - _cairo_hash_table_remove (font_map->hash_table, &key.hash_entry); - } - - /* Otherwise create it and insert it into the hash table. */ - status = font_face->backend->scaled_font_create (font_face, font_matrix, - ctm, options, &scaled_font); - if (status) { + /* We increment the reference count manually here, (rather + * than calling into cairo_scaled_font_reference), since we + * must modify the reference count while our lock is still + * held. */ + scaled_font->ref_count++; _cairo_scaled_font_map_unlock (); - return (cairo_scaled_font_t *)&_cairo_scaled_font_nil; - } + } else { + /* Otherwise create it and insert it into the hash table. */ + status = font_face->backend->scaled_font_create (font_face, font_matrix, + ctm, options, &scaled_font); + if (status) { + _cairo_scaled_font_map_unlock (); + return NULL; + } - status = _cairo_hash_table_insert (font_map->hash_table, - &scaled_font->hash_entry); - _cairo_scaled_font_map_unlock (); + status = _cairo_hash_table_insert (font_map->hash_table, + &scaled_font->hash_entry); + _cairo_scaled_font_map_unlock (); - if (status) { - /* We can't call _cairo_scaled_font_destroy here since it expects - * that the font has already been successfully inserted into the - * hash table. */ - _cairo_scaled_font_fini (scaled_font); - free (scaled_font); - return (cairo_scaled_font_t *)&_cairo_scaled_font_nil; + if (status) { + /* We can't call _cairo_scaled_font_destroy here since it expects + * that the font has already been successfully inserted into the + * hash table. */ + _cairo_scaled_font_fini (scaled_font); + free (scaled_font); + return NULL; + } } return scaled_font; @@ -773,13 +748,10 @@ cairo_scaled_font_text_extents (cairo_scaled_font_t *scaled_font, const char *utf8, cairo_text_extents_t *extents) { - cairo_status_t status; + cairo_status_t status = CAIRO_STATUS_SUCCESS; cairo_glyph_t *glyphs; int num_glyphs; - if (scaled_font->status) - return; - status = _cairo_scaled_font_text_to_glyphs (scaled_font, 0., 0., utf8, &glyphs, &num_glyphs); if (status) { _cairo_scaled_font_set_error (scaled_font, status); @@ -802,7 +774,7 @@ cairo_scaled_font_text_extents (cairo_scaled_font_t *scaled_font, * graphics state were set to the same font_face, font_matrix, ctm, * and font_options as @scaled_font). Additionally, the x_advance and * y_advance values indicate the amount by which the current point - * would be advanced by cairo_show_glyphs(). + * would be advanced by cairo_show_glyphs. * * Note that whitespace glyphs do not contribute to the size of the * rectangle (extents.width and extents.height). @@ -813,7 +785,7 @@ cairo_scaled_font_glyph_extents (cairo_scaled_font_t *scaled_font, int num_glyphs, cairo_text_extents_t *extents) { - cairo_status_t status; + cairo_status_t status = CAIRO_STATUS_SUCCESS; int i; double min_x = 0.0, min_y = 0.0, max_x = 0.0, max_y = 0.0; cairo_bool_t visible = FALSE; @@ -1128,7 +1100,7 @@ _cairo_scaled_font_show_glyphs (cairo_scaled_font_t *scaled_font, _cairo_pattern_fini (&glyph_pattern.base); if (status) - goto CLEANUP_MASK; + break; } if (mask != NULL) { @@ -1204,42 +1176,6 @@ _scaled_glyph_path_close_path (void *abstract_closure) return _cairo_path_fixed_close_path (closure->path); } -/* Add a single-device-unit rectangle to a path. */ -static cairo_status_t -_add_unit_rectangle_to_path (cairo_path_fixed_t *path, int x, int y) -{ - cairo_status_t status; - - status = _cairo_path_fixed_move_to (path, - _cairo_fixed_from_int (x), - _cairo_fixed_from_int (y)); - if (status) - return status; - - status = _cairo_path_fixed_rel_line_to (path, - _cairo_fixed_from_int (1), - _cairo_fixed_from_int (0)); - if (status) - return status; - - status = _cairo_path_fixed_rel_line_to (path, - _cairo_fixed_from_int (0), - _cairo_fixed_from_int (1)); - if (status) - return status; - - status = _cairo_path_fixed_rel_line_to (path, - _cairo_fixed_from_int (-1), - _cairo_fixed_from_int (0)); - if (status) - return status; - - status = _cairo_path_fixed_close_path (path); - if (status) - return status; - - return CAIRO_STATUS_SUCCESS; -} /** * _trace_mask_to_path: @@ -1262,7 +1198,6 @@ static cairo_status_t _trace_mask_to_path (cairo_image_surface_t *mask, cairo_path_fixed_t *path) { - cairo_status_t status; cairo_image_surface_t *a1_mask; unsigned char *row, *byte_ptr, byte; int rows, cols, bytes_per_row; @@ -1285,10 +1220,19 @@ _trace_mask_to_path (cairo_image_surface_t *mask, byte = CAIRO_BITSWAP8_IF_LITTLE_ENDIAN (*byte_ptr); for (bit = 7; bit >= 0 && x < a1_mask->width; bit--, x++) { if (byte & (1 << bit)) { - status = _add_unit_rectangle_to_path (path, - x + xoff, y + yoff); - if (status) - return status; + _cairo_path_fixed_move_to (path, + _cairo_fixed_from_int (x + xoff), + _cairo_fixed_from_int (y + yoff)); + _cairo_path_fixed_rel_line_to (path, + _cairo_fixed_from_int (1), + _cairo_fixed_from_int (0)); + _cairo_path_fixed_rel_line_to (path, + _cairo_fixed_from_int (0), + _cairo_fixed_from_int (1)); + _cairo_path_fixed_rel_line_to (path, + _cairo_fixed_from_int (-1), + _cairo_fixed_from_int (0)); + _cairo_path_fixed_close_path (path); } } } @@ -1334,8 +1278,6 @@ _cairo_scaled_font_glyph_path (cairo_scaled_font_t *scaled_font, glyphs[i].index, CAIRO_SCALED_GLYPH_INFO_SURFACE, &scaled_glyph); - if (status) - return status; glyph_path = _cairo_path_fixed_create (); if (glyph_path == NULL) @@ -1360,9 +1302,6 @@ _cairo_scaled_font_glyph_path (cairo_scaled_font_t *scaled_font, &closure); if (glyph_path != scaled_glyph->path) _cairo_path_fixed_destroy (glyph_path); - - if (status) - return status; } return CAIRO_STATUS_SUCCESS; @@ -1662,9 +1601,6 @@ void cairo_scaled_font_get_font_options (cairo_scaled_font_t *scaled_font, cairo_font_options_t *options) { - if (cairo_font_options_status (options)) - return; - if (scaled_font->status) { _cairo_font_options_init_default (options); return; diff --git a/gfx/cairo/cairo/src/cairo-skiplist-private.h b/gfx/cairo/cairo/src/cairo-skiplist-private.h index 3a948afcea82..b152f4b15de7 100644 --- a/gfx/cairo/cairo/src/cairo-skiplist-private.h +++ b/gfx/cairo/cairo/src/cairo-skiplist-private.h @@ -26,24 +26,7 @@ #include "cairoint.h" -/* - * Skip lists are described in detail here: - * - * http://citeseer.ist.psu.edu/pugh90skip.html - */ - -/* Note that random_level() called from alloc_node_for_level() depends on - * this being not more than 16. - */ -#define MAX_LEVEL 15 - -/* Returns the index of the free-list to use for a node at level 'level' */ -#define FREELIST_FOR_LEVEL(level) (((level) - 1) / 2) - -/* Returns the maximum level that uses the same free-list as 'level' does */ -#define FREELIST_MAX_LEVEL_FOR(level) (((level) + 1) & ~1) - -#define MAX_FREELIST_LEVEL (FREELIST_FOR_LEVEL (MAX_LEVEL - 1) + 1) +#define MAX_LEVEL 31 /* * Skip list element. In order to use the skip list, the caller must @@ -69,7 +52,7 @@ typedef struct _skip_list { size_t elt_size; size_t data_size; skip_elt_t *chains[MAX_LEVEL]; - skip_elt_t *freelists[MAX_FREELIST_LEVEL]; + skip_elt_t *freelists[MAX_LEVEL]; int max_level; } cairo_skip_list_t; diff --git a/gfx/cairo/cairo/src/cairo-skiplist.c b/gfx/cairo/cairo/src/cairo-skiplist.c index 72ca6ce156ed..451ecb06df0e 100644 --- a/gfx/cairo/cairo/src/cairo-skiplist.c +++ b/gfx/cairo/cairo/src/cairo-skiplist.c @@ -21,7 +21,11 @@ * OF THIS SOFTWARE. */ -#include "cairoint.h" +#include +#include +#include +#include +#include #include "cairo-skiplist-private.h" @@ -232,9 +236,6 @@ _cairo_skip_list_init (cairo_skip_list_t *list, for (i = 0; i < MAX_LEVEL; i++) { list->chains[i] = NULL; - } - - for (i = 0; i < MAX_FREELIST_LEVEL; i++) { list->freelists[i] = NULL; } @@ -250,7 +251,7 @@ _cairo_skip_list_fini (cairo_skip_list_t *list) while ((elt = list->chains[0])) { _cairo_skip_list_delete_given (list, elt); } - for (i=0; ifreelists[i]; while (elt) { skip_elt_t *nextfree = elt->prev; @@ -264,17 +265,14 @@ _cairo_skip_list_fini (cairo_skip_list_t *list) * Generate a random level number, distributed * so that each level is 1/4 as likely as the one before * - * Note that level numbers run 1 <= level < MAX_LEVEL + * Note that level numbers run 1 <= level <= MAX_LEVEL */ static int random_level (void) { + /* tricky bit -- each bit is '1' 75% of the time */ + long int bits = lfsr_random() | lfsr_random(); int level = 0; - /* tricky bit -- each bit is '1' 75% of the time. - * This works because we only use the lower MAX_LEVEL - * bits, and MAX_LEVEL < 16 */ - long int bits = lfsr_random(); - bits |= bits >> 16; while (++level < MAX_LEVEL) { @@ -288,23 +286,19 @@ random_level (void) static void * alloc_node_for_level (cairo_skip_list_t *list, unsigned level) { - int freelist_level = FREELIST_FOR_LEVEL (level); - if (list->freelists[freelist_level]) { - skip_elt_t *elt = list->freelists[freelist_level]; - list->freelists[freelist_level] = elt->prev; + if (list->freelists[level-1]) { + skip_elt_t *elt = list->freelists[level-1]; + list->freelists[level-1] = elt->prev; return ELT_DATA(elt); } - return malloc (list->elt_size - + (FREELIST_MAX_LEVEL_FOR (level) - 1) * sizeof (skip_elt_t *)); + return malloc (list->elt_size + (level-1) * sizeof (skip_elt_t *)); } static void free_elt (cairo_skip_list_t *list, skip_elt_t *elt) { - int level = elt->prev_index + 1; - int freelist_level = FREELIST_FOR_LEVEL (level); - elt->prev = list->freelists[freelist_level]; - list->freelists[freelist_level] = elt; + elt->prev = list->freelists[elt->prev_index]; + list->freelists[elt->prev_index] = elt; } /* @@ -355,8 +349,6 @@ _cairo_skip_list_insert (cairo_skip_list_t *list, void *data, int unique) } data_and_elt = alloc_node_for_level (list, level); - if (data_and_elt == NULL) - return NULL; memcpy (data_and_elt, data, list->data_size); elt = (skip_elt_t *) (data_and_elt + list->data_size); diff --git a/gfx/cairo/cairo/src/cairo-spline.c b/gfx/cairo/cairo/src/cairo-spline.c index bf87770031f6..3624bfc348ce 100644 --- a/gfx/cairo/cairo/src/cairo-spline.c +++ b/gfx/cairo/cairo/src/cairo-spline.c @@ -80,9 +80,9 @@ _cairo_spline_init (cairo_spline_t *spline, else _cairo_slope_init (&spline->final_slope, &spline->a, &spline->d); - spline->points = spline->points_embedded; - spline->points_size = ARRAY_LENGTH (spline->points_embedded); spline->num_points = 0; + spline->points_size = 0; + spline->points = NULL; return CAIRO_STATUS_SUCCESS; } @@ -90,11 +90,11 @@ _cairo_spline_init (cairo_spline_t *spline, void _cairo_spline_fini (cairo_spline_t *spline) { - if (spline->points != spline->points_embedded) + if (spline->points && spline->points != spline->points_embedded) free (spline->points); - spline->points = spline->points_embedded; - spline->points_size = ARRAY_LENGTH (spline->points_embedded); + spline->points = NULL; + spline->points_size = 0; spline->num_points = 0; } @@ -104,8 +104,17 @@ _cairo_spline_grow (cairo_spline_t *spline) { cairo_point_t *new_points; int old_size = spline->points_size; + int embedded_size = sizeof (spline->points_embedded) / sizeof (spline->points_embedded[0]); int new_size = 2 * MAX (old_size, 16); + /* we have a local buffer at spline->points_embedded. try to fulfill the request + * from there. */ + if (old_size < embedded_size) { + spline->points = spline->points_embedded; + spline->points_size = embedded_size; + return CAIRO_STATUS_SUCCESS; + } + assert (spline->num_points <= spline->points_size); if (spline->points == spline->points_embedded) { @@ -275,8 +284,9 @@ _cairo_spline_decompose (cairo_spline_t *spline, double tolerance) { cairo_status_t status; - /* reset the spline, but keep the buffer */ - spline->num_points = 0; + if (spline->points_size) { + _cairo_spline_fini (spline); + } status = _cairo_spline_decompose_into (spline, tolerance * tolerance, spline); if (status) diff --git a/gfx/cairo/cairo/src/cairo-surface-fallback.c b/gfx/cairo/cairo/src/cairo-surface-fallback.c index 8898aee1b2c2..1a7d6663c5f8 100644 --- a/gfx/cairo/cairo/src/cairo-surface-fallback.c +++ b/gfx/cairo/cairo/src/cairo-surface-fallback.c @@ -35,8 +35,6 @@ * Carl D. Worth */ -#include "cairoint.h" - #include "cairo-surface-fallback-private.h" #include "cairo-clip-private.h" @@ -365,8 +363,7 @@ _clip_and_composite (cairo_clip_t *clip, return CAIRO_STATUS_SUCCESS; if (op == CAIRO_OPERATOR_CLEAR) { - _cairo_pattern_init_solid (&solid_pattern.solid, CAIRO_COLOR_WHITE, - CAIRO_CONTENT_COLOR); + _cairo_pattern_init_solid (&solid_pattern.solid, CAIRO_COLOR_WHITE); src = &solid_pattern.base; op = CAIRO_OPERATOR_DEST_OUT; } @@ -421,8 +418,7 @@ _composite_trap_region (cairo_clip_t *clip, cairo_surface_t *clip_surface = clip ? clip->surface : NULL; if (clip_surface && op == CAIRO_OPERATOR_CLEAR) { - _cairo_pattern_init_solid (&solid_pattern.solid, CAIRO_COLOR_WHITE, - CAIRO_CONTENT_COLOR); + _cairo_pattern_init_solid (&solid_pattern.solid, CAIRO_COLOR_WHITE); src = &solid_pattern.base; op = CAIRO_OPERATOR_DEST_OUT; } @@ -456,11 +452,8 @@ _composite_trap_region (cairo_clip_t *clip, extents->width, extents->height); /* Restore the original clip if we modified it temporarily. */ - if (num_rects > 1) { - cairo_status_t status2 = _cairo_surface_set_clip (dst, clip); - if (status == CAIRO_STATUS_SUCCESS) - status = status2; - } + if (num_rects >1) + _cairo_surface_set_clip (dst, clip); if (clip_surface) _cairo_pattern_fini (&mask.base); @@ -492,8 +485,7 @@ _composite_traps_draw_func (void *closure, if (dst_x != 0 || dst_y != 0) _cairo_traps_translate (info->traps, - dst_x, - dst_y); - _cairo_pattern_init_solid (&pattern.solid, CAIRO_COLOR_WHITE, - CAIRO_CONTENT_COLOR); + _cairo_pattern_init_solid (&pattern.solid, CAIRO_COLOR_WHITE); if (!src) src = &pattern.base; @@ -519,156 +511,145 @@ _clip_and_composite_trapezoids (cairo_pattern_t *src, cairo_antialias_t antialias) { cairo_status_t status; - pixman_region16_t trap_region; - pixman_region16_t clear_region; - cairo_bool_t has_trap_region = FALSE; - cairo_bool_t has_clear_region = FALSE; + pixman_region16_t *trap_region = NULL; + pixman_region16_t *clear_region = NULL; cairo_rectangle_int16_t extents; cairo_composite_traps_info_t traps_info; if (traps->num_traps == 0) - return CAIRO_STATUS_SUCCESS; + return CAIRO_STATUS_SUCCESS; status = _cairo_surface_get_extents (dst, &extents); - if (status) - return status; + return status; status = _cairo_traps_extract_region (traps, &trap_region); + if (status) + return status; - if (CAIRO_INT_STATUS_UNSUPPORTED == status) { - has_trap_region = FALSE; - } else if (status) { - return status; - } else { - has_trap_region = TRUE; + if (_cairo_operator_bounded_by_mask (op)) + { + cairo_rectangle_int16_t trap_extents; + if (trap_region) { + status = _cairo_clip_intersect_to_region (clip, trap_region); + if (status) + goto out; + + _cairo_region_extents_rectangle (trap_region, &trap_extents); + } else { + cairo_box_t trap_box; + _cairo_traps_extents (traps, &trap_box); + _cairo_box_round_to_rectangle (&trap_box, &trap_extents); + } + + _cairo_rectangle_intersect (&extents, &trap_extents); + status = _cairo_clip_intersect_to_rectangle (clip, &extents); + if (status) + goto out; } + else + { + cairo_surface_t *clip_surface = clip ? clip->surface : NULL; - if (_cairo_operator_bounded_by_mask (op)) { - cairo_rectangle_int16_t trap_extents; + if (trap_region && !clip_surface) { + /* If we optimize drawing with an unbounded operator to + * _cairo_surface_fill_rectangles() or to drawing with a + * clip region, then we have an additional region to clear. + */ + clear_region = _cairo_region_create_from_rectangle (&extents); + if (clear_region == NULL) + return CAIRO_STATUS_NO_MEMORY; - if (has_trap_region) { - status = _cairo_clip_intersect_to_region (clip, &trap_region); + status = _cairo_clip_intersect_to_region (clip, clear_region); + if (status) + return status; - if (status) - goto out; + _cairo_region_extents_rectangle (clear_region, &extents); - _cairo_region_extents_rectangle (&trap_region, &trap_extents); - } else { - cairo_box_t trap_box; - _cairo_traps_extents (traps, &trap_box); - _cairo_box_round_to_rectangle (&trap_box, &trap_extents); - } + if (pixman_region_subtract (clear_region, clear_region, trap_region) != PIXMAN_REGION_STATUS_SUCCESS) + return CAIRO_STATUS_NO_MEMORY; - _cairo_rectangle_intersect (&extents, &trap_extents); - status = _cairo_clip_intersect_to_rectangle (clip, &extents); - - if (status) - goto out; - } else { - cairo_surface_t *clip_surface = clip ? clip->surface : NULL; - - if (has_trap_region && !clip_surface) { - /* If we optimize drawing with an unbounded operator to - * _cairo_surface_fill_rectangles() or to drawing with a - * clip region, then we have an additional region to clear. - */ - pixman_region_init_rect (&clear_region, - extents.x, extents.y, - extents.width, extents.height); - - has_clear_region = TRUE; - status = _cairo_clip_intersect_to_region (clip, &clear_region); - - if (status) - goto out; - - _cairo_region_extents_rectangle (&clear_region, &extents); - - if (PIXMAN_REGION_STATUS_SUCCESS != - pixman_region_subtract (&clear_region, &clear_region, &trap_region)) { - status = CAIRO_STATUS_NO_MEMORY; - goto out; - } - - if (!pixman_region_not_empty (&clear_region)) { - pixman_region_fini (&clear_region); - has_clear_region = FALSE; - } - } else { - status = _cairo_clip_intersect_to_rectangle (clip, &extents); - } + if (!pixman_region_not_empty (clear_region)) { + pixman_region_destroy (clear_region); + clear_region = NULL; + } + } else { + status = _cairo_clip_intersect_to_rectangle (clip, &extents); + if (status) + return status; + } } if (status) - goto out; + goto out; - if (has_trap_region) { - cairo_surface_t *clip_surface = clip ? clip->surface : NULL; + if (trap_region) + { + cairo_surface_t *clip_surface = clip ? clip->surface : NULL; - if ((src->type == CAIRO_PATTERN_TYPE_SOLID || - op == CAIRO_OPERATOR_CLEAR) && !clip_surface) { - const cairo_color_t *color; + if ((src->type == CAIRO_PATTERN_TYPE_SOLID || op == CAIRO_OPERATOR_CLEAR) && + !clip_surface) + { + const cairo_color_t *color; - if (op == CAIRO_OPERATOR_CLEAR) { - color = CAIRO_COLOR_TRANSPARENT; - } else { - color = &((cairo_solid_pattern_t *)src)->color; - } + if (op == CAIRO_OPERATOR_CLEAR) + color = CAIRO_COLOR_TRANSPARENT; + else + color = &((cairo_solid_pattern_t *)src)->color; - /* Solid rectangles special case */ - status = _cairo_surface_fill_region (dst, op, color, &trap_region); + /* Solid rectangles special case */ + status = _cairo_surface_fill_region (dst, op, color, trap_region); + if (!status && clear_region) + status = _cairo_surface_fill_region (dst, CAIRO_OPERATOR_CLEAR, + CAIRO_COLOR_TRANSPARENT, + clear_region); - if (!status && has_clear_region) - status = _cairo_surface_fill_region (dst, CAIRO_OPERATOR_CLEAR, - CAIRO_COLOR_TRANSPARENT, - &clear_region); + goto out; + } - goto out; - } - - if ((_cairo_operator_bounded_by_mask (op) && - op != CAIRO_OPERATOR_SOURCE) || !clip_surface) { - /* For a simple rectangle, we can just use composite(), for more - * rectangles, we have to set a clip region. The cost of rasterizing - * trapezoids is pretty high for most backends currently, so it's - * worthwhile even if a region is needed. - * - * If we have a clip surface, we set it as the mask; this only works - * for bounded operators other than SOURCE; for unbounded operators, - * clip and mask cannot be interchanged. For SOURCE, the operator - * as implemented by the backends is different in it's handling - * of the mask then what we want. - * - * CAIRO_INT_STATUS_UNSUPPORTED will be returned if the region has - * more than rectangle and the destination doesn't support clip - * regions. In that case, we fall through. - */ - status = _composite_trap_region (clip, src, op, dst, - &trap_region, &extents); - - if (status != CAIRO_INT_STATUS_UNSUPPORTED) { - if (!status && has_clear_region) - status = _cairo_surface_fill_region (dst, CAIRO_OPERATOR_CLEAR, - CAIRO_COLOR_TRANSPARENT, - &clear_region); - goto out; - } - } + if ((_cairo_operator_bounded_by_mask (op) && op != CAIRO_OPERATOR_SOURCE) || + !clip_surface) + { + /* For a simple rectangle, we can just use composite(), for more + * rectangles, we have to set a clip region. The cost of rasterizing + * trapezoids is pretty high for most backends currently, so it's + * worthwhile even if a region is needed. + * + * If we have a clip surface, we set it as the mask; this only works + * for bounded operators other than SOURCE; for unbounded operators, + * clip and mask cannot be interchanged. For SOURCE, the operator + * as implemented by the backends is different in it's handling + * of the mask then what we want. + * + * CAIRO_INT_STATUS_UNSUPPORTED will be returned if the region has + * more than rectangle and the destination doesn't support clip + * regions. In that case, we fall through. + */ + status = _composite_trap_region (clip, src, op, dst, + trap_region, &extents); + if (status != CAIRO_INT_STATUS_UNSUPPORTED) + { + if (!status && clear_region) + status = _cairo_surface_fill_region (dst, CAIRO_OPERATOR_CLEAR, + CAIRO_COLOR_TRANSPARENT, + clear_region); + goto out; + } + } } traps_info.traps = traps; traps_info.antialias = antialias; status = _clip_and_composite (clip, op, src, - _composite_traps_draw_func, - &traps_info, dst, &extents); + _composite_traps_draw_func, &traps_info, + dst, &extents); -out: - if (has_trap_region) - pixman_region_fini (&trap_region); - if (has_clear_region) - pixman_region_fini (&clear_region); + out: + if (trap_region) + pixman_region_destroy (trap_region); + if (clear_region) + pixman_region_destroy (clear_region); return status; } @@ -709,16 +690,16 @@ _cairo_surface_fallback_paint (cairo_surface_t *surface, if (status) return status; - status = _clip_and_composite_trapezoids (source, - op, - surface, - &traps, - surface->clip, - CAIRO_ANTIALIAS_NONE); + _clip_and_composite_trapezoids (source, + op, + surface, + &traps, + surface->clip, + CAIRO_ANTIALIAS_NONE); _cairo_traps_fini (&traps); - return status; + return CAIRO_STATUS_SUCCESS; } static cairo_status_t @@ -804,35 +785,9 @@ _cairo_surface_fallback_stroke (cairo_surface_t *surface, { cairo_status_t status; cairo_traps_t traps; - cairo_box_t box; - cairo_rectangle_int16_t extents; - - status = _cairo_surface_get_extents (surface, &extents); - if (status) - return status; - - if (_cairo_operator_bounded_by_source (op)) { - cairo_rectangle_int16_t source_extents; - status = _cairo_pattern_get_extents (source, &source_extents); - if (status) - return status; - - _cairo_rectangle_intersect (&extents, &source_extents); - } - - status = _cairo_clip_intersect_to_rectangle (surface->clip, &extents); - if (status) - return status; - - box.p1.x = _cairo_fixed_from_int (extents.x); - box.p1.y = _cairo_fixed_from_int (extents.y); - box.p2.x = _cairo_fixed_from_int (extents.x + extents.width); - box.p2.y = _cairo_fixed_from_int (extents.y + extents.height); _cairo_traps_init (&traps); - _cairo_traps_limit (&traps, &box); - status = _cairo_path_fixed_stroke_to_traps (path, stroke_style, ctm, ctm_inverse, @@ -843,16 +798,16 @@ _cairo_surface_fallback_stroke (cairo_surface_t *surface, return status; } - status = _clip_and_composite_trapezoids (source, - op, - surface, - &traps, - surface->clip, - antialias); + _clip_and_composite_trapezoids (source, + op, + surface, + &traps, + surface->clip, + antialias); _cairo_traps_fini (&traps); - return status; + return CAIRO_STATUS_SUCCESS; } cairo_status_t @@ -866,35 +821,9 @@ _cairo_surface_fallback_fill (cairo_surface_t *surface, { cairo_status_t status; cairo_traps_t traps; - cairo_box_t box; - cairo_rectangle_int16_t extents; - - status = _cairo_surface_get_extents (surface, &extents); - if (status) - return status; - - if (_cairo_operator_bounded_by_source (op)) { - cairo_rectangle_int16_t source_extents; - status = _cairo_pattern_get_extents (source, &source_extents); - if (status) - return status; - - _cairo_rectangle_intersect (&extents, &source_extents); - } - - status = _cairo_clip_intersect_to_rectangle (surface->clip, &extents); - if (status) - return status; - - box.p1.x = _cairo_fixed_from_int (extents.x); - box.p1.y = _cairo_fixed_from_int (extents.y); - box.p2.x = _cairo_fixed_from_int (extents.x + extents.width); - box.p2.y = _cairo_fixed_from_int (extents.y + extents.height); _cairo_traps_init (&traps); - _cairo_traps_limit (&traps, &box); - status = _cairo_path_fixed_fill_to_traps (path, fill_rule, tolerance, @@ -949,8 +878,7 @@ _cairo_surface_old_show_glyphs_draw_func (void *closure } } - _cairo_pattern_init_solid (&pattern.solid, CAIRO_COLOR_WHITE, - CAIRO_CONTENT_COLOR); + _cairo_pattern_init_solid (&pattern.solid, CAIRO_COLOR_WHITE); if (!src) src = &pattern.base; @@ -1051,21 +979,17 @@ _cairo_surface_fallback_snapshot (cairo_surface_t *surface) _cairo_pattern_init_for_surface (&pattern.surface, &image->base); - status = _cairo_surface_composite (CAIRO_OPERATOR_SOURCE, - &pattern.base, - NULL, - snapshot, - 0, 0, - 0, 0, - 0, 0, - image->width, - image->height); + _cairo_surface_composite (CAIRO_OPERATOR_SOURCE, + &pattern.base, + NULL, + snapshot, + 0, 0, + 0, 0, + 0, 0, + image->width, + image->height); _cairo_pattern_fini (&pattern.base); - if (status) { - cairo_surface_destroy (snapshot); - return (cairo_surface_t *) &_cairo_surface_nil; - } _cairo_surface_release_source_image (surface, image, &image_extra); @@ -1234,14 +1158,13 @@ _cairo_surface_fallback_composite_trapezoids (cairo_operator_t op, traps = offset_traps; } - status = _cairo_surface_composite_trapezoids (op, pattern, - &state.image->base, - antialias, - src_x, src_y, - dst_x - state.image_rect.x, - dst_y - state.image_rect.y, - width, height, - traps, num_traps); + _cairo_surface_composite_trapezoids (op, pattern, + &state.image->base, + antialias, + src_x, src_y, + dst_x - state.image_rect.x, + dst_y - state.image_rect.y, + width, height, traps, num_traps); if (offset_traps) free (offset_traps); diff --git a/gfx/cairo/cairo/src/cairo-surface-private.h b/gfx/cairo/cairo/src/cairo-surface-private.h deleted file mode 100644 index 6193cf805573..000000000000 --- a/gfx/cairo/cairo/src/cairo-surface-private.h +++ /dev/null @@ -1,96 +0,0 @@ -/* 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 - */ - -#ifndef CAIRO_SURFACE_PRIVATE_H -#define CAIRO_SURFACE_PRIVATE_H - -#include "cairo.h" - -#include "cairo-types-private.h" - -struct _cairo_surface { - const cairo_surface_backend_t *backend; - - /* We allow surfaces to override the backend->type by shoving something - * else into surface->type. This is for "wrapper" surfaces that want to - * hide their internal type from the user-level API. */ - cairo_surface_type_t type; - - cairo_content_t content; - - unsigned int ref_count; - cairo_status_t status; - cairo_bool_t finished; - cairo_user_data_array_t user_data; - - cairo_matrix_t device_transform; - cairo_matrix_t device_transform_inverse; - - double x_fallback_resolution; - double y_fallback_resolution; - - cairo_clip_t *clip; - - /* - * Each time a clip region is modified, it gets the next value in this - * sequence. This means that clip regions for this surface are uniquely - * identified and updates to the clip can be readily identified - */ - unsigned int next_clip_serial; - /* - * The serial number of the current clip. This is set when - * the surface clipping is set. The gstate can then cheaply - * check whether the surface clipping is already correct before - * performing a rendering operation. - * - * The special value '0' is reserved for the unclipped case. - */ - unsigned int current_clip_serial; - - /* A "snapshot" surface is immutable. See _cairo_surface_snapshot. */ - cairo_bool_t is_snapshot; - - /* - * Surface font options, falling back to backend's default options, - * and set using _cairo_surface_set_font_options(), and propagated by - * cairo_surface_create_similar(). - */ - cairo_bool_t has_font_options; - cairo_font_options_t font_options; -}; - -#endif /* CAIRO_SURFACE_PRIVATE_H */ diff --git a/gfx/cairo/cairo/src/cairo-surface.c b/gfx/cairo/cairo/src/cairo-surface.c index d7ef33f10e0b..92efa00571b7 100644 --- a/gfx/cairo/cairo/src/cairo-surface.c +++ b/gfx/cairo/cairo/src/cairo-surface.c @@ -35,8 +35,9 @@ * Carl D. Worth */ -#include "cairoint.h" +#include +#include "cairoint.h" #include "cairo-surface-fallback-private.h" #include "cairo-clip-private.h" @@ -80,7 +81,7 @@ DEFINE_NIL_SURFACE(CAIRO_STATUS_FILE_NOT_FOUND, _cairo_surface_nil_file_not_foun DEFINE_NIL_SURFACE(CAIRO_STATUS_READ_ERROR, _cairo_surface_nil_read_error); DEFINE_NIL_SURFACE(CAIRO_STATUS_WRITE_ERROR, _cairo_surface_nil_write_error); -static cairo_status_t +static void _cairo_surface_copy_pattern_for_destination (const cairo_pattern_t *pattern, cairo_surface_t *destination, cairo_pattern_t *pattern_out); @@ -179,10 +180,10 @@ _cairo_surface_init (cairo_surface_t *surface, const cairo_surface_backend_t *backend, cairo_content_t content) { - CAIRO_MUTEX_INITIALIZE (); - surface->backend = backend; + surface->content = content; + surface->type = backend->type; surface->ref_count = 1; @@ -288,8 +289,7 @@ cairo_surface_create_similar (cairo_surface_t *other, return _cairo_surface_create_similar_solid (other, content, width, height, - CAIRO_COLOR_TRANSPARENT, - NULL); + CAIRO_COLOR_TRANSPARENT); } slim_hidden_def (cairo_surface_create_similar); @@ -298,8 +298,7 @@ _cairo_surface_create_similar_solid (cairo_surface_t *other, cairo_content_t content, int width, int height, - const cairo_color_t *color, - cairo_pattern_t *pattern) + const cairo_color_t *color) { cairo_status_t status; cairo_surface_t *surface; @@ -312,23 +311,19 @@ _cairo_surface_create_similar_solid (cairo_surface_t *other, return (cairo_surface_t*) &_cairo_surface_nil; } - if (pattern == NULL) { - source = _cairo_pattern_create_solid (color, content); - if (source->status) { - cairo_surface_destroy (surface); - _cairo_error (CAIRO_STATUS_NO_MEMORY); - return (cairo_surface_t*) &_cairo_surface_nil; - } - } else - source = pattern; + source = _cairo_pattern_create_solid (color); + if (source->status) { + cairo_surface_destroy (surface); + _cairo_error (CAIRO_STATUS_NO_MEMORY); + return (cairo_surface_t*) &_cairo_surface_nil; + } status = _cairo_surface_paint (surface, color == CAIRO_COLOR_TRANSPARENT ? CAIRO_OPERATOR_CLEAR : CAIRO_OPERATOR_SOURCE, source); - if (source != pattern) - cairo_pattern_destroy (source); + cairo_pattern_destroy (source); if (status) { cairo_surface_destroy (surface); @@ -379,7 +374,7 @@ slim_hidden_def (cairo_surface_reference); /** * cairo_surface_destroy: - * @surface: a #cairo_surface_t + * @surface: a #cairo_t * * Decreases the reference count on @surface by one. If the result is * zero, then @surface and all associated resources are freed. See @@ -406,34 +401,6 @@ cairo_surface_destroy (cairo_surface_t *surface) } slim_hidden_def(cairo_surface_destroy); -/** - * cairo_surface_reset: - * @surface: a #cairo_surface_t - * - * Resets the surface back to defaults such that it may be reused in lieu - * of creating a new surface. - **/ -cairo_status_t -_cairo_surface_reset (cairo_surface_t *surface) -{ - if (surface == NULL || surface->ref_count == CAIRO_REF_COUNT_INVALID) - return CAIRO_STATUS_SUCCESS; - - assert (surface->ref_count == 1); - - _cairo_user_data_array_fini (&surface->user_data); - - if (surface->backend->reset != NULL) { - cairo_status_t status = surface->backend->reset (surface); - if (status) - return status; - } - - _cairo_surface_init (surface, surface->backend, surface->content); - - return CAIRO_STATUS_SUCCESS; -} - /** * cairo_surface_get_reference_count: * @surface: a #cairo_surface_t @@ -502,8 +469,10 @@ cairo_surface_finish (cairo_surface_t *surface) } status = surface->backend->finish (surface); - if (status) + if (status) { _cairo_surface_set_error (surface, status); + return; + } surface->finished = TRUE; } @@ -601,16 +570,13 @@ void cairo_surface_get_font_options (cairo_surface_t *surface, cairo_font_options_t *options) { - if (cairo_font_options_status (options)) - return; - if (!surface->has_font_options) { surface->has_font_options = TRUE; - _cairo_font_options_init_default (&surface->font_options); - if (!surface->finished && surface->backend->get_font_options) { surface->backend->get_font_options (surface, &surface->font_options); + } else { + _cairo_font_options_init_default (&surface->font_options); } } @@ -1091,35 +1057,6 @@ _cairo_surface_snapshot (cairo_surface_t *surface) return _cairo_surface_fallback_snapshot (surface); } -/** - * _cairo_surface_is_similar - * @surface_a: a #cairo_surface_t - * @surface_b: a #cairo_surface_t - * @content: a #cairo_content_t - * - * Find out whether the given surfaces share the same backend, - * and if so, whether they can be considered similar. - * - * The definition of "similar" depends on the backend. In - * general, it means that the surface is equivalent to one - * that would have been generated by a call to cairo_surface_create_similar. - * - * Return value: TRUE if the surfaces are similar. - **/ -cairo_bool_t -_cairo_surface_is_similar (cairo_surface_t *surface_a, - cairo_surface_t *surface_b, - cairo_content_t content) -{ - if (surface_a->backend != surface_b->backend) - return FALSE; - - if (surface_a->backend->is_similar != NULL) - return surface_a->backend->is_similar (surface_a, surface_b, content); - - return TRUE; -} - cairo_status_t _cairo_surface_composite (cairo_operator_t op, cairo_pattern_t *src, @@ -1233,7 +1170,6 @@ _cairo_surface_fill_region (cairo_surface_t *surface, { int num_rects = pixman_region_num_rects (region); pixman_box16_t *boxes = pixman_region_rects (region); - cairo_rectangle_int16_t stack_rects[CAIRO_STACK_BUFFER_SIZE / sizeof (cairo_rectangle_int16_t)]; cairo_rectangle_int16_t *rects; cairo_status_t status; int i; @@ -1243,12 +1179,9 @@ _cairo_surface_fill_region (cairo_surface_t *surface, if (!num_rects) return CAIRO_STATUS_SUCCESS; - rects = stack_rects; - if (num_rects > ARRAY_LENGTH (stack_rects)) { - rects = malloc (sizeof (cairo_rectangle_int16_t) * num_rects); - if (!rects) - return CAIRO_STATUS_NO_MEMORY; - } + rects = malloc (sizeof (pixman_rectangle_t) * num_rects); + if (!rects) + return CAIRO_STATUS_NO_MEMORY; for (i = 0; i < num_rects; i++) { rects[i].x = boxes[i].x1; @@ -1260,8 +1193,7 @@ _cairo_surface_fill_region (cairo_surface_t *surface, status = _cairo_surface_fill_rectangles (surface, op, color, rects, num_rects); - if (rects != stack_rects) - free (rects); + free (rects); return status; } @@ -1323,9 +1255,7 @@ _cairo_surface_paint (cairo_surface_t *surface, assert (! surface->is_snapshot); - status = _cairo_surface_copy_pattern_for_destination (source, surface, &dev_source.base); - if (status) - return status; + _cairo_surface_copy_pattern_for_destination (source, surface, &dev_source.base); if (surface->backend->paint) { status = surface->backend->paint (surface, op, &dev_source.base); @@ -1353,26 +1283,20 @@ _cairo_surface_mask (cairo_surface_t *surface, assert (! surface->is_snapshot); - status = _cairo_surface_copy_pattern_for_destination (source, surface, &dev_source.base); - if (status) - goto FINISH; - status = _cairo_surface_copy_pattern_for_destination (mask, surface, &dev_mask.base); - if (status) - goto CLEANUP_SOURCE; + _cairo_surface_copy_pattern_for_destination (source, surface, &dev_source.base); + _cairo_surface_copy_pattern_for_destination (mask, surface, &dev_mask.base); if (surface->backend->mask) { status = surface->backend->mask (surface, op, &dev_source.base, &dev_mask.base); if (status != CAIRO_INT_STATUS_UNSUPPORTED) - goto CLEANUP_MASK; + goto FINISH; } status = _cairo_surface_fallback_mask (surface, op, &dev_source.base, &dev_mask.base); - CLEANUP_MASK: - _cairo_pattern_fini (&dev_mask.base); - CLEANUP_SOURCE: - _cairo_pattern_fini (&dev_source.base); FINISH: + _cairo_pattern_fini (&dev_mask.base); + _cairo_pattern_fini (&dev_source.base); return status; } @@ -1397,9 +1321,7 @@ _cairo_surface_stroke (cairo_surface_t *surface, assert (! surface->is_snapshot); - status = _cairo_surface_copy_pattern_for_destination (source, surface, &dev_source.base); - if (status) - return status; + _cairo_surface_copy_pattern_for_destination (source, surface, &dev_source.base); if (surface->backend->stroke) { status = surface->backend->stroke (surface, op, &dev_source.base, @@ -1438,9 +1360,7 @@ _cairo_surface_fill (cairo_surface_t *surface, assert (! surface->is_snapshot); - status = _cairo_surface_copy_pattern_for_destination (source, surface, &dev_source.base); - if (status) - return status; + _cairo_surface_copy_pattern_for_destination (source, surface, &dev_source.base); if (surface->backend->fill) { status = surface->backend->fill (surface, op, &dev_source.base, @@ -1510,7 +1430,10 @@ _cairo_surface_composite_trapezoids (cairo_operator_t op, traps, num_traps); } -cairo_status_t +/* _copy_page and _show_page are unique among _cairo_surface functions + * in that they will actually return CAIRO_INT_STATUS_UNSUPPORTED + * rather than performing any fallbacks. */ +cairo_int_status_t _cairo_surface_copy_page (cairo_surface_t *surface) { assert (! surface->is_snapshot); @@ -1521,14 +1444,16 @@ _cairo_surface_copy_page (cairo_surface_t *surface) if (surface->finished) return CAIRO_STATUS_SURFACE_FINISHED; - /* It's fine if some backends don't implement copy_page */ if (surface->backend->copy_page == NULL) - return CAIRO_STATUS_SUCCESS; + return CAIRO_INT_STATUS_UNSUPPORTED; return surface->backend->copy_page (surface); } -cairo_status_t +/* _show_page and _copy_page are unique among _cairo_surface functions + * in that they will actually return CAIRO_INT_STATUS_UNSUPPORTED + * rather than performing any fallbacks. */ +cairo_int_status_t _cairo_surface_show_page (cairo_surface_t *surface) { assert (! surface->is_snapshot); @@ -1539,9 +1464,8 @@ _cairo_surface_show_page (cairo_surface_t *surface) if (surface->finished) return CAIRO_STATUS_SURFACE_FINISHED; - /* It's fine if some backends don't implement show_page */ if (surface->backend->show_page == NULL) - return CAIRO_STATUS_SUCCESS; + return CAIRO_INT_STATUS_UNSUPPORTED; return surface->backend->show_page (surface); } @@ -1776,9 +1700,9 @@ _cairo_surface_set_clip (cairo_surface_t *surface, cairo_clip_t *clip) clip->path, clip->serial); - if (clip->has_region) + if (clip->region) return _cairo_surface_set_clip_region (surface, - &clip->region, + clip->region, clip->serial); } @@ -1840,11 +1764,9 @@ _cairo_surface_show_glyphs (cairo_surface_t *surface, if (!num_glyphs) return CAIRO_STATUS_SUCCESS; - status = _cairo_surface_copy_pattern_for_destination (source, - surface, - &dev_source.base); - if (status) - return status; + _cairo_surface_copy_pattern_for_destination (source, + surface, + &dev_source.base); cairo_scaled_font_get_font_matrix (scaled_font, &font_matrix); @@ -1865,11 +1787,6 @@ _cairo_surface_show_glyphs (cairo_surface_t *surface, font_options); cairo_font_options_destroy (font_options); } - status = cairo_scaled_font_status (dev_scaled_font); - if (status) { - _cairo_pattern_fini (&dev_source.base); - return status; - } CAIRO_MUTEX_LOCK (dev_scaled_font->mutex); @@ -1948,11 +1865,9 @@ _cairo_surface_composite_fixup_unbounded_internal (cairo_surface_t *dst, { cairo_rectangle_int16_t dst_rectangle; cairo_rectangle_int16_t drawn_rectangle; - cairo_bool_t has_drawn_region = FALSE; - cairo_bool_t has_clear_region = FALSE; - pixman_region16_t drawn_region; - pixman_region16_t clear_region; - cairo_status_t status; + pixman_region16_t *drawn_region; + pixman_region16_t *clear_region; + cairo_status_t status = CAIRO_STATUS_SUCCESS; /* The area that was drawn is the area in the destination rectangle but not within * the source or the mask. @@ -1965,38 +1880,34 @@ _cairo_surface_composite_fixup_unbounded_internal (cairo_surface_t *dst, drawn_rectangle = dst_rectangle; if (src_rectangle) - _cairo_rectangle_intersect (&drawn_rectangle, src_rectangle); + _cairo_rectangle_intersect (&drawn_rectangle, src_rectangle); if (mask_rectangle) - _cairo_rectangle_intersect (&drawn_rectangle, mask_rectangle); + _cairo_rectangle_intersect (&drawn_rectangle, mask_rectangle); /* Now compute the area that is in dst_rectangle but not in drawn_rectangle */ - pixman_region_init_rect (&drawn_region, - drawn_rectangle.x, drawn_rectangle.y, - drawn_rectangle.width, drawn_rectangle.height); - pixman_region_init_rect (&clear_region, - dst_rectangle.x, dst_rectangle.y, - dst_rectangle.width, dst_rectangle.height); + drawn_region = _cairo_region_create_from_rectangle (&drawn_rectangle); + clear_region = _cairo_region_create_from_rectangle (&dst_rectangle); + if (!drawn_region || !clear_region) { + status = CAIRO_STATUS_NO_MEMORY; + goto CLEANUP_REGIONS; + } - has_drawn_region = TRUE; - has_clear_region = TRUE; - - if (PIXMAN_REGION_STATUS_SUCCESS != - pixman_region_subtract (&clear_region, &clear_region, &drawn_region)) { - status = CAIRO_STATUS_NO_MEMORY; - goto CLEANUP_REGIONS; + if (pixman_region_subtract (clear_region, clear_region, drawn_region) != PIXMAN_REGION_STATUS_SUCCESS) { + status = CAIRO_STATUS_NO_MEMORY; + goto CLEANUP_REGIONS; } status = _cairo_surface_fill_region (dst, CAIRO_OPERATOR_SOURCE, - CAIRO_COLOR_TRANSPARENT, - &clear_region); + CAIRO_COLOR_TRANSPARENT, + clear_region); -CLEANUP_REGIONS: - if (has_drawn_region) - pixman_region_fini (&drawn_region); - if (has_clear_region) - pixman_region_fini (&clear_region); + CLEANUP_REGIONS: + if (drawn_region) + pixman_region_destroy (drawn_region); + if (clear_region) + pixman_region_destroy (clear_region); return status; } @@ -2157,19 +2068,16 @@ _cairo_surface_composite_shape_fixup_unbounded (cairo_surface_t *dst, * Copies the given pattern, taking into account device scale and offsets * of the destination surface. */ -static cairo_status_t +void _cairo_surface_copy_pattern_for_destination (const cairo_pattern_t *pattern, cairo_surface_t *destination, cairo_pattern_t *pattern_out) { - cairo_status_t status; - - status = _cairo_pattern_init_copy (pattern_out, pattern); - if (status) - return status; + _cairo_pattern_init_copy (pattern_out, pattern); if (_cairo_surface_has_device_transform (destination)) { cairo_matrix_t device_to_surface = destination->device_transform; + cairo_status_t status; status = cairo_matrix_invert (&device_to_surface); /* We only ever allow for scaling (under the implementation's @@ -2179,8 +2087,6 @@ _cairo_surface_copy_pattern_for_destination (const cairo_pattern_t *pattern, _cairo_pattern_transform (pattern_out, &device_to_surface); } - - return CAIRO_STATUS_SUCCESS; } /* LocalWords: rasterized diff --git a/gfx/cairo/cairo/src/cairo-svg-surface-private.h b/gfx/cairo/cairo/src/cairo-svg-surface-private.h deleted file mode 100644 index e7cd4db8cf05..000000000000 --- a/gfx/cairo/cairo/src/cairo-svg-surface-private.h +++ /dev/null @@ -1,74 +0,0 @@ -/* cairo - a vector graphics library with display and print output - * - * Copyright © 2004 Red Hat, Inc - * Copyright © 2005-2006 Emmanuel Pacaud - * Copyright © 2006 Red Hat, Inc - * - * This library is free software; you can redistribute it and/or - * modify it either under the terms of the GNU Lesser General Public - * License version 2.1 as published by the Free Software Foundation - * (the "LGPL") or, at your option, under the terms of the Mozilla - * Public License Version 1.1 (the "MPL"). If you do not alter this - * notice, a recipient may use your version of this file under either - * the MPL or the LGPL. - * - * You should have received a copy of the LGPL along with this library - * in the file COPYING-LGPL-2.1; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * You should have received a copy of the MPL along with this library - * in the file COPYING-MPL-1.1 - * - * The contents of this file are subject to the Mozilla Public License - * Version 1.1 (the "License"); you may not use this file except in - * compliance with the License. You may obtain a copy of the License at - * http://www.mozilla.org/MPL/ - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY - * OF ANY KIND, either express or implied. See the LGPL or the MPL for - * the specific language governing rights and limitations. - * - * The Original Code is the cairo graphics library. - * - * The Initial Developer of the Original Code is University of Southern - * California. - * - * Contributor(s): - * Kristian Høgsberg - * Emmanuel Pacaud - * Carl Worth - */ - -#ifndef CAIRO_SVG_SURFACE_PRIVATE_H -#define CAIRO_SVG_SURFACE_PRIVATE_H - -#include "cairo-svg.h" - -#include "cairo-surface-private.h" - -typedef struct cairo_svg_document cairo_svg_document_t; - -typedef struct cairo_svg_surface { - cairo_surface_t base; - - cairo_content_t content; - - unsigned int id; - - double width; - double height; - - cairo_svg_document_t *document; - - cairo_output_stream_t *xml_node; - cairo_array_t page_set; - - unsigned int clip_level; - unsigned int base_clip; - cairo_bool_t is_base_clip_emitted; - - cairo_paginated_mode_t paginated_mode; - - cairo_bool_t force_fallbacks; -} cairo_svg_surface_t; - -#endif /* CAIRO_SVG_SURFACE_PRIVATE_H */ diff --git a/gfx/cairo/cairo/src/cairo-svg-surface.c b/gfx/cairo/cairo/src/cairo-svg-surface.c index 483440ff3d44..5cb9ce0b97f1 100644 --- a/gfx/cairo/cairo/src/cairo-svg-surface.c +++ b/gfx/cairo/cairo/src/cairo-svg-surface.c @@ -40,13 +40,15 @@ #include "cairoint.h" #include "cairo-svg.h" -#include "cairo-svg-surface-private.h" +#include "cairo-svg-test.h" #include "cairo-path-fixed-private.h" #include "cairo-meta-surface-private.h" -#include "cairo-paginated-private.h" +#include "cairo-paginated-surface-private.h" #include "cairo-scaled-font-subsets-private.h" #include "cairo-output-stream-private.h" +typedef struct cairo_svg_document cairo_svg_document_t; +typedef struct cairo_svg_surface cairo_svg_surface_t; typedef struct cairo_svg_page cairo_svg_page_t; static const int invalid_pattern_id = -1; @@ -57,7 +59,7 @@ static const cairo_svg_version_t _cairo_svg_versions[] = CAIRO_SVG_VERSION_1_2 }; -#define CAIRO_SVG_VERSION_LAST ARRAY_LENGTH (_cairo_svg_versions) +#define CAIRO_SVG_VERSION_LAST ((int)(sizeof (_cairo_svg_versions) / sizeof (_cairo_svg_versions[0]))) static cairo_bool_t _cairo_svg_version_has_page_set_support (cairo_svg_version_t version) @@ -79,6 +81,7 @@ static const char * _cairo_svg_internal_version_strings[CAIRO_SVG_VERSION_LAST] struct cairo_svg_page { unsigned int surface_id; + unsigned int clip_id; unsigned int clip_level; cairo_output_stream_t *xml_node; }; @@ -112,6 +115,27 @@ struct cairo_svg_document { cairo_scaled_font_subsets_t *font_subsets; }; +struct cairo_svg_surface { + cairo_surface_t base; + + cairo_content_t content; + + unsigned int id; + + double width; + double height; + + cairo_svg_document_t *document; + + cairo_output_stream_t *xml_node; + cairo_array_t page_set; + + unsigned int clip_level; + unsigned int base_clip; + + cairo_paginated_mode_t paginated_mode; +}; + typedef struct { unsigned int id; cairo_meta_surface_t *meta; @@ -354,7 +378,13 @@ _cairo_svg_surface_create_for_document (cairo_svg_document_t *document, surface->id = document->surface_id++; surface->base_clip = document->clip_id++; - surface->is_base_clip_emitted = FALSE; + + _cairo_output_stream_printf (document->xml_node_defs, + "\n" + " \n" + "\n", + surface->base_clip, + width, height); surface->xml_node = _cairo_memory_stream_create (); _cairo_array_init (&surface->page_set, sizeof (cairo_svg_page_t)); @@ -368,7 +398,6 @@ _cairo_svg_surface_create_for_document (cairo_svg_document_t *document, } surface->paginated_mode = CAIRO_PAGINATED_MODE_ANALYZE; - surface->force_fallbacks = FALSE; surface->content = content; return _cairo_paginated_surface_create (&surface->base, @@ -408,6 +437,7 @@ _cairo_svg_surface_store_page (cairo_svg_surface_t *surface) cairo_svg_page_t page; page.surface_id = surface->id; + page.clip_id = surface->base_clip; page.clip_level = surface->clip_level; page.xml_node = surface->xml_node; @@ -417,8 +447,7 @@ _cairo_svg_surface_store_page (cairo_svg_surface_t *surface) for (i = 0; i < page.clip_level; i++) _cairo_output_stream_printf (page.xml_node, "\n"); - if (_cairo_array_append (&surface->page_set, &page) != CAIRO_STATUS_SUCCESS) - return NULL; + _cairo_array_append (&surface->page_set, &page); return _cairo_array_index (&surface->page_set, surface->page_set.num_elements - 1); } @@ -677,27 +706,38 @@ _cairo_svg_document_emit_font_subset (cairo_scaled_font_subset_t *font_subset, } } -static cairo_status_t +static void _cairo_svg_document_emit_font_subsets (cairo_svg_document_t *document) { - cairo_status_t status; - - status = _cairo_scaled_font_subsets_foreach_scaled (document->font_subsets, - _cairo_svg_document_emit_font_subset, - document); - if (status) - return status; - + _cairo_scaled_font_subsets_foreach_scaled (document->font_subsets, + _cairo_svg_document_emit_font_subset, + document); _cairo_scaled_font_subsets_destroy (document->font_subsets); document->font_subsets = NULL; - - return CAIRO_STATUS_SUCCESS; } static cairo_bool_t cairo_svg_force_fallbacks = FALSE; +/** + * _cairo_svg_test_force_fallbacks + * + * Force the SVG surface backend to use image fallbacks for every + * operation. + * + * + * This function is only intended for internal + * testing use within the cairo distribution. It is not installed in + * any public header file. + * + **/ +void +_cairo_svg_test_force_fallbacks (void) +{ + cairo_svg_force_fallbacks = TRUE; +} + static cairo_int_status_t -_cairo_svg_surface_operation_supported (cairo_svg_surface_t *surface, +__cairo_svg_surface_operation_supported (cairo_svg_surface_t *surface, cairo_operator_t op, const cairo_pattern_t *pattern) { @@ -718,7 +758,7 @@ _cairo_svg_surface_analyze_operation (cairo_svg_surface_t *surface, cairo_operator_t op, const cairo_pattern_t *pattern) { - if (_cairo_svg_surface_operation_supported (surface, op, pattern)) + if (__cairo_svg_surface_operation_supported (surface, op, pattern)) return CAIRO_STATUS_SUCCESS; else return CAIRO_INT_STATUS_UNSUPPORTED; @@ -736,7 +776,7 @@ _cairo_svg_surface_create_similar (void *abstract_src, static cairo_status_t _cairo_svg_surface_finish (void *abstract_surface) { - cairo_status_t status, status2; + cairo_status_t status; cairo_svg_surface_t *surface = abstract_surface; cairo_svg_document_t *document = surface->document; cairo_svg_page_t *page; @@ -747,15 +787,11 @@ _cairo_svg_surface_finish (void *abstract_surface) else status = CAIRO_STATUS_SUCCESS; - status2 = _cairo_output_stream_destroy (surface->xml_node); - if (status == CAIRO_STATUS_SUCCESS) - status = status2; + _cairo_output_stream_destroy (surface->xml_node); for (i = 0; i < surface->page_set.num_elements; i++) { page = _cairo_array_index (&surface->page_set, i); - status2 = _cairo_output_stream_destroy (page->xml_node); - if (status == CAIRO_STATUS_SUCCESS) - status = status2; + _cairo_output_stream_destroy (page->xml_node); } _cairo_array_fini (&surface->page_set); @@ -905,9 +941,7 @@ _cairo_svg_surface_emit_composite_image_pattern (cairo_output_stream_t *outp return status; p2u = pattern->base.matrix; - status = cairo_matrix_invert (&p2u); - if (status) - return status; + cairo_matrix_invert (&p2u); if (pattern_id != invalid_pattern_id) { _cairo_output_stream_printf (output, @@ -944,14 +978,12 @@ _cairo_svg_surface_emit_composite_image_pattern (cairo_output_stream_t *outp return status; } -static cairo_status_t +static int _cairo_svg_surface_emit_meta_surface (cairo_svg_document_t *document, - cairo_meta_surface_t *surface, - int *id) + cairo_meta_surface_t *surface) { - cairo_status_t status; cairo_surface_t *paginated_surface; - cairo_svg_surface_t *svg_surface; + cairo_surface_t *svg_surface; cairo_meta_snapshot_t new_snapshot; cairo_array_t *page_set; @@ -959,7 +991,7 @@ _cairo_svg_surface_emit_meta_surface (cairo_svg_document_t *document, cairo_meta_surface_t *meta; cairo_meta_snapshot_t *snapshot; unsigned int num_elements; - unsigned int i; + unsigned int i, id; /* search in already emitted meta snapshots */ num_elements = document->meta_snapshots.num_elements; @@ -968,8 +1000,7 @@ _cairo_svg_surface_emit_meta_surface (cairo_svg_document_t *document, meta = snapshot->meta; if (meta->commands.num_elements == surface->commands.num_elements && _cairo_array_index (&meta->commands, 0) == _cairo_array_index (&surface->commands, 0)) { - *id = snapshot->id; - return CAIRO_STATUS_SUCCESS; + return snapshot->id; } } @@ -978,41 +1009,16 @@ _cairo_svg_surface_emit_meta_surface (cairo_svg_document_t *document, meta->content, meta->width_pixels, meta->height_pixels); - svg_surface = (cairo_svg_surface_t *) _cairo_paginated_surface_get_target (paginated_surface); + svg_surface = _cairo_paginated_surface_get_target (paginated_surface); cairo_surface_set_fallback_resolution (paginated_surface, document->owner->x_fallback_resolution, document->owner->y_fallback_resolution); - - status = _cairo_meta_surface_replay ((cairo_surface_t *)meta, paginated_surface); - if (status) { - cairo_surface_destroy (&meta->base); - return status; - } - - status = _cairo_surface_show_page (paginated_surface); - if (status) { - cairo_surface_destroy (&meta->base); - return status; - } + _cairo_meta_surface_replay ((cairo_surface_t *)meta, paginated_surface); + _cairo_surface_show_page (paginated_surface); new_snapshot.meta = meta; - new_snapshot.id = svg_surface->id; - status = _cairo_array_append (&document->meta_snapshots, &new_snapshot); - if (status) { - cairo_surface_destroy (&meta->base); - return status; - } - - if (!svg_surface->is_base_clip_emitted) { - svg_surface->is_base_clip_emitted = TRUE; - _cairo_output_stream_printf (document->xml_node_defs, - "\n" - " \n" - "\n", - svg_surface->base_clip, - svg_surface->width, - svg_surface->height); - } + new_snapshot.id = ((cairo_svg_surface_t *) svg_surface)->id; + _cairo_array_append (&document->meta_snapshots, &new_snapshot); if (meta->content == CAIRO_CONTENT_ALPHA) { _cairo_svg_surface_emit_alpha_filter (document); @@ -1020,21 +1026,21 @@ _cairo_svg_surface_emit_meta_surface (cairo_svg_document_t *document, "\n", - svg_surface->id, - svg_surface->base_clip); + ((cairo_svg_surface_t *) svg_surface)->id, + ((cairo_svg_surface_t *) svg_surface)->base_clip); } else { _cairo_output_stream_printf (document->xml_node_defs, "\n", - svg_surface->id, - svg_surface->base_clip); + ((cairo_svg_surface_t *) svg_surface)->id, + ((cairo_svg_surface_t *) svg_surface)->base_clip); } - contents = svg_surface->xml_node; - page_set = &svg_surface->page_set; + contents = ((cairo_svg_surface_t *) svg_surface)->xml_node; + page_set = &((cairo_svg_surface_t *) svg_surface)->page_set; if (_cairo_memory_stream_length (contents) > 0) - _cairo_svg_surface_store_page (svg_surface); + _cairo_svg_surface_store_page ((cairo_svg_surface_t *) svg_surface); if (page_set->num_elements > 0) { cairo_svg_page_t *page; @@ -1045,7 +1051,7 @@ _cairo_svg_surface_emit_meta_surface (cairo_svg_document_t *document, _cairo_output_stream_printf (document->xml_node_defs, "\n"); - *id = new_snapshot.id; + id = new_snapshot.id; cairo_surface_destroy (paginated_surface); @@ -1056,7 +1062,7 @@ _cairo_svg_surface_emit_meta_surface (cairo_svg_document_t *document, /* cairo_surface_destroy (svg_surface); */ - return CAIRO_STATUS_SUCCESS; + return id; } static cairo_status_t @@ -1069,19 +1075,14 @@ _cairo_svg_surface_emit_composite_meta_pattern (cairo_output_stream_t *output, cairo_svg_document_t *document = surface->document; cairo_meta_surface_t *meta_surface; cairo_matrix_t p2u; - cairo_status_t status; int id; - p2u = pattern->base.matrix; - status = cairo_matrix_invert (&p2u); - if (status) - return status; - meta_surface = (cairo_meta_surface_t *) pattern->surface; - status = _cairo_svg_surface_emit_meta_surface (document, meta_surface, &id); - if (status) - return status; + id = _cairo_svg_surface_emit_meta_surface (document, meta_surface); + + p2u = pattern->base.matrix; + cairo_matrix_invert (&p2u); if (pattern_id != invalid_pattern_id) { _cairo_output_stream_printf (output, @@ -1151,7 +1152,7 @@ _cairo_svg_surface_emit_operator (cairo_output_stream_t *output, _cairo_output_stream_printf (output, "comp-op: %s; ", op_str[op]); } -static cairo_status_t +static void _cairo_svg_surface_emit_solid_pattern (cairo_svg_surface_t *surface, cairo_solid_pattern_t *pattern, cairo_output_stream_t *style, @@ -1165,11 +1166,9 @@ _cairo_svg_surface_emit_solid_pattern (cairo_svg_surface_t *surface, pattern->color.green * 100.0, pattern->color.blue * 100.0, pattern->color.alpha); - - return CAIRO_STATUS_SUCCESS; } -static cairo_status_t +static void _cairo_svg_surface_emit_surface_pattern (cairo_svg_surface_t *surface, cairo_surface_pattern_t *pattern, cairo_output_stream_t *style, @@ -1186,8 +1185,6 @@ _cairo_svg_surface_emit_surface_pattern (cairo_svg_surface_t *surface, "%s: url(#pattern%d);", is_stroke ? "color" : "fill", pattern_id); - - return CAIRO_STATUS_SUCCESS; } static void @@ -1369,7 +1366,7 @@ _cairo_svg_surface_emit_pattern_extend (cairo_output_stream_t *output, } } -static cairo_status_t +static void _cairo_svg_surface_emit_linear_pattern (cairo_svg_surface_t *surface, cairo_linear_pattern_t *pattern, cairo_output_stream_t *style, @@ -1378,12 +1375,6 @@ _cairo_svg_surface_emit_linear_pattern (cairo_svg_surface_t *surface, cairo_svg_document_t *document = surface->document; double x0, y0, x1, y1; cairo_matrix_t p2u; - cairo_status_t status; - - p2u = pattern->base.base.matrix; - status = cairo_matrix_invert (&p2u); - if (status) - return status; x0 = _cairo_fixed_to_double (pattern->gradient.p1.x); y0 = _cairo_fixed_to_double (pattern->gradient.p1.y); @@ -1398,6 +1389,8 @@ _cairo_svg_surface_emit_linear_pattern (cairo_svg_surface_t *surface, x0, y0, x1, y1); _cairo_svg_surface_emit_pattern_extend (document->xml_node_defs, &pattern->base.base), + p2u = pattern->base.base.matrix; + cairo_matrix_invert (&p2u); _cairo_svg_surface_emit_transform (document->xml_node_defs, "gradientTransform", ">\n", &p2u); _cairo_svg_surface_emit_pattern_stops (document->xml_node_defs ,&pattern->base, 0.0, FALSE, FALSE); @@ -1411,11 +1404,9 @@ _cairo_svg_surface_emit_linear_pattern (cairo_svg_surface_t *surface, document->linear_pattern_id); document->linear_pattern_id++; - - return CAIRO_STATUS_SUCCESS; } -static cairo_status_t +static void _cairo_svg_surface_emit_radial_pattern (cairo_svg_surface_t *surface, cairo_radial_pattern_t *pattern, cairo_output_stream_t *style, @@ -1427,7 +1418,6 @@ _cairo_svg_surface_emit_radial_pattern (cairo_svg_surface_t *surface, double x0, y0, x1, y1, r0, r1; double fx, fy; cairo_bool_t reverse_stops; - cairo_status_t status; pixman_circle_t *c0, *c1; extend = pattern->base.base.extend; @@ -1450,9 +1440,7 @@ _cairo_svg_surface_emit_radial_pattern (cairo_svg_surface_t *surface, r1 = _cairo_fixed_to_double (c1->radius); p2u = pattern->base.base.matrix; - status = cairo_matrix_invert (&p2u); - if (status) - return status; + cairo_matrix_invert (&p2u); if (pattern->gradient.c1.radius == pattern->gradient.c2.radius) { _cairo_output_stream_printf (document->xml_node_defs, @@ -1583,28 +1571,29 @@ _cairo_svg_surface_emit_radial_pattern (cairo_svg_surface_t *surface, document->radial_pattern_id); document->radial_pattern_id++; - - return CAIRO_STATUS_SUCCESS; } -static cairo_status_t +static void _cairo_svg_surface_emit_pattern (cairo_svg_surface_t *surface, cairo_pattern_t *pattern, cairo_output_stream_t *output, cairo_bool_t is_stroke) { switch (pattern->type) { case CAIRO_PATTERN_TYPE_SOLID: - return _cairo_svg_surface_emit_solid_pattern (surface, (cairo_solid_pattern_t *) pattern, output, is_stroke); + _cairo_svg_surface_emit_solid_pattern (surface, (cairo_solid_pattern_t *) pattern, output, is_stroke); + break; case CAIRO_PATTERN_TYPE_SURFACE: - return _cairo_svg_surface_emit_surface_pattern (surface, (cairo_surface_pattern_t *) pattern, output, is_stroke); + _cairo_svg_surface_emit_surface_pattern (surface, (cairo_surface_pattern_t *) pattern, output, is_stroke); + break; case CAIRO_PATTERN_TYPE_LINEAR: - return _cairo_svg_surface_emit_linear_pattern (surface, (cairo_linear_pattern_t *) pattern, output, is_stroke); + _cairo_svg_surface_emit_linear_pattern (surface, (cairo_linear_pattern_t *) pattern, output, is_stroke); + break; case CAIRO_PATTERN_TYPE_RADIAL: - return _cairo_svg_surface_emit_radial_pattern (surface, (cairo_radial_pattern_t *) pattern, output, is_stroke); + _cairo_svg_surface_emit_radial_pattern (surface, (cairo_radial_pattern_t *) pattern, output, is_stroke); + break; } - return CAIRO_STATUS_SUCCESS; } static cairo_int_status_t @@ -1622,7 +1611,7 @@ _cairo_svg_surface_fill (void *abstract_surface, if (surface->paginated_mode == CAIRO_PAGINATED_MODE_ANALYZE) return _cairo_svg_surface_analyze_operation (surface, op, source); - assert (_cairo_svg_surface_operation_supported (surface, op, source)); + assert (__cairo_svg_surface_operation_supported (surface, op, source)); _cairo_output_stream_printf (surface->xml_node, "paginated_mode == CAIRO_PAGINATED_MODE_ANALYZE) @@ -1710,7 +1698,7 @@ _cairo_svg_surface_paint (void *abstract_surface, * possible only because there is nothing between the fallback * images and the paper, nor is anything painted above. */ /* - assert (_cairo_svg_surface_operation_supported (surface, op, source)); + assert (__cairo_svg_surface_operation_supported (surface, op, source)); */ /* Emulation of clear and source operators, when no clipping region @@ -1723,12 +1711,8 @@ _cairo_svg_surface_paint (void *abstract_surface, * and an optimiszation in meta surface. */ if (surface->clip_level == 0 && (op == CAIRO_OPERATOR_CLEAR || - op == CAIRO_OPERATOR_SOURCE)) - { - status = _cairo_output_stream_destroy (surface->xml_node); - if (status) - return status; - + op == CAIRO_OPERATOR_SOURCE)) { + _cairo_output_stream_destroy (surface->xml_node); surface->xml_node = _cairo_memory_stream_create (); if (op == CAIRO_OPERATOR_CLEAR) { @@ -1756,7 +1740,6 @@ _cairo_svg_surface_mask (void *abstract_surface, cairo_pattern_t *source, cairo_pattern_t *mask) { - cairo_status_t status; cairo_svg_surface_t *surface = abstract_surface; cairo_svg_document_t *document = surface->document; cairo_output_stream_t *mask_stream; @@ -1765,7 +1748,7 @@ _cairo_svg_surface_mask (void *abstract_surface, if (surface->paginated_mode == CAIRO_PAGINATED_MODE_ANALYZE) return _cairo_svg_surface_analyze_operation (surface, op, source); - assert (_cairo_svg_surface_operation_supported (surface, op, source)); + assert (__cairo_svg_surface_operation_supported (surface, op, source)); _cairo_svg_surface_emit_alpha_filter (document); @@ -1782,10 +1765,7 @@ _cairo_svg_surface_mask (void *abstract_surface, " \n" "\n"); _cairo_memory_stream_copy (mask_stream, document->xml_node_defs); - - status = _cairo_output_stream_destroy (mask_stream); - if (status) - return status; + _cairo_output_stream_destroy (mask_stream); snprintf (buffer, sizeof buffer, "mask=\"url(#mask%d);\"", document->mask_id); @@ -1815,7 +1795,7 @@ _cairo_svg_surface_stroke (void *abstract_dst, if (surface->paginated_mode == CAIRO_PAGINATED_MODE_ANALYZE) return _cairo_svg_surface_analyze_operation (surface, op, source); - assert (_cairo_svg_surface_operation_supported (surface, op, source)); + assert (__cairo_svg_surface_operation_supported (surface, op, source)); switch (stroke_style->line_cap) { case CAIRO_LINE_CAP_BUTT: @@ -1897,13 +1877,13 @@ _cairo_svg_surface_show_glyphs (void *abstract_surface, cairo_svg_document_t *document = surface->document; cairo_path_fixed_t path; cairo_status_t status; - cairo_scaled_font_subsets_glyph_t subset_glyph; + unsigned int font_id, subset_id, subset_glyph_index; int i; if (surface->paginated_mode == CAIRO_PAGINATED_MODE_ANALYZE) return _cairo_svg_surface_analyze_operation (surface, op, pattern); - assert (_cairo_svg_surface_operation_supported (surface, op, pattern)); + assert (__cairo_svg_surface_operation_supported (surface, op, pattern)); if (num_glyphs <= 0) return CAIRO_STATUS_SUCCESS; @@ -1921,7 +1901,7 @@ _cairo_svg_surface_show_glyphs (void *abstract_surface, for (i = 0; i < num_glyphs; i++) { status = _cairo_scaled_font_subsets_map_glyph (document->font_subsets, scaled_font, glyphs[i].index, - &subset_glyph); + &font_id, &subset_id, &subset_glyph_index); if (status) { glyphs += i; num_glyphs -= i; @@ -1931,8 +1911,7 @@ _cairo_svg_surface_show_glyphs (void *abstract_surface, _cairo_output_stream_printf (surface->xml_node, " \n", - subset_glyph.font_id, - subset_glyph.subset_glyph_index, + font_id, subset_glyph_index, glyphs[i].x, glyphs[i].y); } @@ -2055,7 +2034,7 @@ _cairo_svg_document_create (cairo_output_stream_t *output_stream, } /* The use of defs for font glyphs imposes no per-subset limit. */ - document->font_subsets = _cairo_scaled_font_subsets_create_scaled (); + document->font_subsets = _cairo_scaled_font_subsets_create (0, INT_MAX); if (document->font_subsets == NULL) { _cairo_error (CAIRO_STATUS_NO_MEMORY); free (document); @@ -2113,7 +2092,7 @@ _cairo_svg_document_destroy (cairo_svg_document_t *document) static cairo_status_t _cairo_svg_document_finish (cairo_svg_document_t *document) { - cairo_status_t status, status2; + cairo_status_t status; cairo_output_stream_t *output = document->output_stream; cairo_meta_snapshot_t *snapshot; cairo_svg_surface_t *surface; @@ -2133,10 +2112,7 @@ _cairo_svg_document_finish (cairo_svg_document_t *document) document->width, document->height, _cairo_svg_internal_version_strings [document->svg_version]); - status = _cairo_svg_document_emit_font_subsets (document); - if (status) - return status; - + _cairo_svg_document_emit_font_subsets (document); if (_cairo_memory_stream_length (document->xml_node_glyphs) > 0 || _cairo_memory_stream_length (document->xml_node_defs) > 0) { _cairo_output_stream_printf (output, "\n"); @@ -2160,8 +2136,10 @@ _cairo_svg_document_finish (cairo_svg_document_t *document) page = _cairo_array_index (&surface->page_set, i); _cairo_output_stream_printf (output, "\n"); _cairo_output_stream_printf (output, - "\n", - page->surface_id); + "\n", + page->surface_id, + page->clip_id); _cairo_memory_stream_copy (page->xml_node, output); _cairo_output_stream_printf (output, "\n\n"); } @@ -2169,23 +2147,20 @@ _cairo_svg_document_finish (cairo_svg_document_t *document) } else if (surface->page_set.num_elements > 0) { page = _cairo_array_index (&surface->page_set, surface->page_set.num_elements - 1); _cairo_output_stream_printf (output, - "\n", - page->surface_id); + "\n", + page->surface_id, + page->clip_id); _cairo_memory_stream_copy (page->xml_node, output); _cairo_output_stream_printf (output, "\n"); } _cairo_output_stream_printf (output, "\n"); - status = _cairo_output_stream_destroy (document->xml_node_glyphs); + _cairo_output_stream_destroy (document->xml_node_glyphs); + _cairo_output_stream_destroy (document->xml_node_defs); - status2 = _cairo_output_stream_destroy (document->xml_node_defs); - if (status == CAIRO_STATUS_SUCCESS) - status = status2; - - status2 = _cairo_output_stream_destroy (output); - if (status == CAIRO_STATUS_SUCCESS) - status = status2; + status = _cairo_output_stream_destroy (output); for (i = 0; i < document->meta_snapshots.num_elements; i++) { snapshot = _cairo_array_index (&document->meta_snapshots, i); diff --git a/gfx/cairo/cairo/src/cairo-traps.c b/gfx/cairo/cairo/src/cairo-traps.c index dd885c544643..062768304b26 100644 --- a/gfx/cairo/cairo/src/cairo-traps.c +++ b/gfx/cairo/cairo/src/cairo-traps.c @@ -43,7 +43,7 @@ static cairo_status_t _cairo_traps_grow (cairo_traps_t *traps); -static void +static cairo_status_t _cairo_traps_add_trap (cairo_traps_t *traps, cairo_fixed_t top, cairo_fixed_t bottom, cairo_line_t *left, cairo_line_t *right); @@ -57,21 +57,10 @@ _cairo_traps_init (cairo_traps_t *traps) traps->num_traps = 0; - traps->traps_size = ARRAY_LENGTH (traps->traps_embedded); - traps->traps = traps->traps_embedded; + traps->traps_size = 0; + traps->traps = NULL; traps->extents.p1.x = traps->extents.p1.y = INT32_MAX; traps->extents.p2.x = traps->extents.p2.y = INT32_MIN; - - traps->has_limits = FALSE; -} - -void -_cairo_traps_limit (cairo_traps_t *traps, - cairo_box_t *limits) -{ - traps->has_limits = TRUE; - - traps->limits = *limits; } void @@ -98,104 +87,45 @@ cairo_status_t _cairo_traps_init_box (cairo_traps_t *traps, cairo_box_t *box) { - _cairo_traps_init (traps); - - assert (traps->traps_size >= 1); - - traps->num_traps = 1; - - traps->traps[0].top = box->p1.y; - traps->traps[0].bottom = box->p2.y; - traps->traps[0].left.p1 = box->p1; - traps->traps[0].left.p2.x = box->p1.x; - traps->traps[0].left.p2.y = box->p2.y; - traps->traps[0].right.p1.x = box->p2.x; - traps->traps[0].right.p1.y = box->p1.y; - traps->traps[0].right.p2 = box->p2; - - traps->extents = *box; + _cairo_traps_init (traps); + traps->status = _cairo_traps_grow (traps); + if (traps->status) return traps->status; + + traps->num_traps = 1; + + traps->traps[0].top = box->p1.y; + traps->traps[0].bottom = box->p2.y; + traps->traps[0].left.p1 = box->p1; + traps->traps[0].left.p2.x = box->p1.x; + traps->traps[0].left.p2.y = box->p2.y; + traps->traps[0].right.p1.x = box->p2.x; + traps->traps[0].right.p1.y = box->p1.y; + traps->traps[0].right.p2 = box->p2; + + traps->extents = *box; + + return traps->status; } -cairo_status_t -_cairo_traps_status (cairo_traps_t *traps) -{ - return traps->status; -} - -static void +static cairo_status_t _cairo_traps_add_trap (cairo_traps_t *traps, cairo_fixed_t top, cairo_fixed_t bottom, cairo_line_t *left, cairo_line_t *right) { cairo_trapezoid_t *trap; if (traps->status) - return; + return traps->status; - /* Note: With the goofy trapezoid specification, (where an - * arbitrary two points on the lines can specified for the left - * and right edges), these limit checks would not work in - * general. For example, one can imagine a trapezoid entirely - * within the limits, but with two points used to specify the left - * edge entirely to the right of the limits. Fortunately, for our - * purposes, cairo will never generate such a crazy - * trapezoid. Instead, cairo always uses for its points the - * extreme positions of the edge that are visible on at least some - * trapezoid. With this constraint, it's impossible for both - * points to be outside the limits while the relevant edge is - * entirely inside the limits. - */ - if (traps->has_limits) { - /* Trivially reject if trapezoid is entirely to the right or - * to the left of the limits. */ - if (left->p1.x >= traps->limits.p2.x && - left->p2.x >= traps->limits.p2.x) - { - return; - } - - if (right->p1.x <= traps->limits.p1.x && - right->p2.x <= traps->limits.p1.x) - { - return; - } - - /* Otherwise, clip the trapezoid to the limits. We only clip - * where an edge is entirely outside the limits. If we wanted - * to be more clever, we could handle cases where a trapezoid - * edge intersects the edge of the limits, but that would - * require slicing this trapezoid into multiple trapezoids, - * and I'm not sure the effort would be worth it. */ - if (top < traps->limits.p1.y) - top = traps->limits.p1.y; - - if (bottom > traps->limits.p2.y) - bottom = traps->limits.p2.y; - - if (left->p1.x < traps->limits.p1.x && - left->p2.x < traps->limits.p1.x) - { - left->p1.x = traps->limits.p1.x; - left->p2.x = traps->limits.p1.x; - } - - if (right->p1.x > traps->limits.p2.x && - right->p2.x > traps->limits.p2.x) - { - right->p1.x = traps->limits.p2.x; - right->p2.x = traps->limits.p2.x; - } - } - - if (top >= bottom) { - return; + if (top == bottom) { + return CAIRO_STATUS_SUCCESS; } if (traps->num_traps >= traps->traps_size) { traps->status = _cairo_traps_grow (traps); if (traps->status) - return; + return traps->status; } trap = &traps->traps[traps->num_traps]; @@ -227,9 +157,11 @@ _cairo_traps_add_trap (cairo_traps_t *traps, cairo_fixed_t top, cairo_fixed_t bo traps->extents.p2.x = right->p2.x; traps->num_traps++; + + return traps->status; } -void +cairo_status_t _cairo_traps_add_trap_from_points (cairo_traps_t *traps, cairo_fixed_t top, cairo_fixed_t bottom, cairo_point_t left_p1, cairo_point_t left_p2, cairo_point_t right_p1, cairo_point_t right_p2) @@ -238,7 +170,7 @@ _cairo_traps_add_trap_from_points (cairo_traps_t *traps, cairo_fixed_t top, cair cairo_line_t right; if (traps->status) - return; + return traps->status; left.p1 = left_p1; left.p2 = left_p2; @@ -246,7 +178,7 @@ _cairo_traps_add_trap_from_points (cairo_traps_t *traps, cairo_fixed_t top, cair right.p1 = right_p1; right.p2 = right_p2; - _cairo_traps_add_trap (traps, top, bottom, &left, &right); + return _cairo_traps_add_trap (traps, top, bottom, &left, &right); } /* make room for at least one more trap */ @@ -254,7 +186,19 @@ static cairo_status_t _cairo_traps_grow (cairo_traps_t *traps) { cairo_trapezoid_t *new_traps; - int new_size = 2 * MAX (traps->traps_size, 16); + int old_size = traps->traps_size; + int embedded_size = sizeof (traps->traps_embedded) / sizeof (traps->traps_embedded[0]); + int new_size = 2 * MAX (old_size, 16); + + /* we have a local buffer at traps->traps_embedded. try to fulfill the request + * from there. */ + if (old_size < embedded_size) { + traps->traps = traps->traps_embedded; + traps->traps_size = embedded_size; + return traps->status; + } + + assert (traps->num_traps <= traps->traps_size); if (traps->status) return traps->status; @@ -262,7 +206,7 @@ _cairo_traps_grow (cairo_traps_t *traps) if (traps->traps == traps->traps_embedded) { new_traps = malloc (new_size * sizeof (cairo_trapezoid_t)); if (new_traps) - memcpy (new_traps, traps->traps, sizeof (traps->traps_embedded)); + memcpy (new_traps, traps->traps, old_size * sizeof (cairo_trapezoid_t)); } else { new_traps = realloc (traps->traps, new_size * sizeof (cairo_trapezoid_t)); } @@ -275,7 +219,7 @@ _cairo_traps_grow (cairo_traps_t *traps) traps->traps = new_traps; traps->traps_size = new_size; - return CAIRO_STATUS_SUCCESS; + return traps->status; } static int @@ -590,18 +534,21 @@ _cairo_traps_extents (cairo_traps_t *traps, cairo_box_t *extents) * Determines if a set of trapezoids are exactly representable as a * pixman region, and if so creates such a region. * - * Return value: %CAIRO_STATUS_SUCCESS, %CAIRO_INT_STATUS_UNSUPPORTED - * or %CAIRO_STATUS_NO_MEMORY + * Return value: %CAIRO_STATUS_SUCCESS or %CAIRO_STATUS_NO_MEMORY **/ -cairo_int_status_t -_cairo_traps_extract_region (cairo_traps_t *traps, - pixman_region16_t *region) +cairo_status_t +_cairo_traps_extract_region (cairo_traps_t *traps, + pixman_region16_t **region) { -#define NUM_STATIC_BOXES 16 - pixman_box16_t static_boxes[NUM_STATIC_BOXES]; - pixman_box16_t *boxes; - int i, box_count; - pixman_region_status_t status; + int i; + + /* Bail early if we have lots of traps, until we fix the code + * below to not use Union() + */ + if (traps->num_traps > 200) { + *region = NULL; + return CAIRO_STATUS_SUCCESS; + } for (i = 0; i < traps->num_traps; i++) if (!(traps->traps[i].left.p1.x == traps->traps[i].left.p2.x @@ -610,49 +557,30 @@ _cairo_traps_extract_region (cairo_traps_t *traps, && _cairo_fixed_is_integer(traps->traps[i].bottom) && _cairo_fixed_is_integer(traps->traps[i].left.p1.x) && _cairo_fixed_is_integer(traps->traps[i].right.p1.x))) { - return CAIRO_INT_STATUS_UNSUPPORTED; + *region = NULL; + return CAIRO_STATUS_SUCCESS; } - if (traps->num_traps <= NUM_STATIC_BOXES) { - boxes = static_boxes; - } else { - /*boxes = _cairo_malloc2 (traps->num_traps, sizeof(pixman_box16_t));*/ - boxes = malloc (traps->num_traps * sizeof(pixman_box16_t)); - - if (boxes == NULL) - return CAIRO_STATUS_NO_MEMORY; - } - - box_count = 0; + *region = pixman_region_create (); for (i = 0; i < traps->num_traps; i++) { - int x1 = _cairo_fixed_integer_part(traps->traps[i].left.p1.x); - int y1 = _cairo_fixed_integer_part(traps->traps[i].top); - int x2 = _cairo_fixed_integer_part(traps->traps[i].right.p1.x); - int y2 = _cairo_fixed_integer_part(traps->traps[i].bottom); + int x = _cairo_fixed_integer_part(traps->traps[i].left.p1.x); + int y = _cairo_fixed_integer_part(traps->traps[i].top); + int width = _cairo_fixed_integer_part(traps->traps[i].right.p1.x) - x; + int height = _cairo_fixed_integer_part(traps->traps[i].bottom) - y; - /* XXX: Sometimes we get degenerate trapezoids from the tesellator; - * skip these. + /* XXX: Sometimes we get degenerate trapezoids from the tesellator, + * if we call pixman_region_union_rect(), it bizarrly fails on such + * an empty rectangle, so skip them. */ - if (x1 == x2 || y1 == y2) - continue; + if (width == 0 || height == 0) + continue; - boxes[box_count].x1 = (short) x1; - boxes[box_count].y1 = (short) y1; - boxes[box_count].x2 = (short) x2; - boxes[box_count].y2 = (short) y2; - - box_count++; - } - - status = pixman_region_init_rects (region, boxes, box_count); - - if (boxes != static_boxes) - free (boxes); - - if (status != PIXMAN_REGION_STATUS_SUCCESS) { - pixman_region_fini (region); - return CAIRO_INT_STATUS_UNSUPPORTED; + if (pixman_region_union_rect (*region, *region, + x, y, width, height) != PIXMAN_REGION_STATUS_SUCCESS) { + pixman_region_destroy (*region); + return CAIRO_STATUS_NO_MEMORY; + } } return CAIRO_STATUS_SUCCESS; diff --git a/gfx/cairo/cairo/src/cairo-truetype-subset.c b/gfx/cairo/cairo/src/cairo-truetype-subset.c index 7f168a5352ab..7e77bb8aaae0 100644 --- a/gfx/cairo/cairo/src/cairo-truetype-subset.c +++ b/gfx/cairo/cairo/src/cairo-truetype-subset.c @@ -34,8 +34,8 @@ * Adrian Johnson */ +#include #include "cairoint.h" - #include "cairo-scaled-font-subsets-private.h" #include "cairo-truetype-subset-private.h" @@ -75,6 +75,8 @@ typedef struct _cairo_truetype_font { static int cairo_truetype_font_use_glyph (cairo_truetype_font_t *font, int glyph); +#define ARRAY_LENGTH(a) ( (sizeof (a)) / (sizeof ((a)[0])) ) + #define SFNT_VERSION 0x00010000 #define SFNT_STRING_MAX_LENGTH 65535 @@ -82,7 +84,7 @@ static cairo_status_t _cairo_truetype_font_create (cairo_scaled_font_subset_t *scaled_font_subset, cairo_truetype_font_t **font_return) { - cairo_status_t status; + cairo_status_t status = CAIRO_STATUS_NO_MEMORY; cairo_truetype_font_t *font; const cairo_scaled_font_backend_t *backend; tt_head_t head; @@ -129,22 +131,16 @@ _cairo_truetype_font_create (cairo_scaled_font_subset_t *scaled_font_subset, TT_TAG_name, 0, NULL, &size) != CAIRO_STATUS_SUCCESS) return CAIRO_INT_STATUS_UNSUPPORTED; - name = malloc(size); if (name == NULL) return CAIRO_STATUS_NO_MEMORY; - - status = backend->load_truetype_table (scaled_font_subset->scaled_font, - TT_TAG_name, 0, (unsigned char *) name, - &size); - if (status) - goto fail0; + backend->load_truetype_table (scaled_font_subset->scaled_font, + TT_TAG_name, 0, (unsigned char *) name, + &size); font = malloc (sizeof (cairo_truetype_font_t)); - if (font == NULL) { - status = CAIRO_STATUS_NO_MEMORY; + if (font == NULL) goto fail0; - } font->backend = backend; font->num_glyphs_in_face = be16_to_cpu (maxp.num_glyphs); @@ -153,21 +149,15 @@ _cairo_truetype_font_create (cairo_scaled_font_subset_t *scaled_font_subset, font->last_offset = 0; font->last_boundary = 0; _cairo_array_init (&font->output, sizeof (char)); - status = _cairo_array_grow_by (&font->output, 4096); - if (status) + if (_cairo_array_grow_by (&font->output, 4096) != CAIRO_STATUS_SUCCESS) goto fail1; - font->glyphs = calloc (font->num_glyphs_in_face + 1, sizeof (subset_glyph_t)); - if (font->glyphs == NULL) { - status = CAIRO_STATUS_NO_MEMORY; - goto fail1; - } + if (font->glyphs == NULL) + goto fail2; font->parent_to_subset = calloc (font->num_glyphs_in_face, sizeof (int)); - if (font->parent_to_subset == NULL) { - status = CAIRO_STATUS_NO_MEMORY; - goto fail2; - } + if (font->parent_to_subset == NULL) + goto fail3; font->base.num_glyphs = 0; font->base.x_min = (int16_t) be16_to_cpu (head.x_min); @@ -208,11 +198,8 @@ _cairo_truetype_font_create (cairo_scaled_font_subset_t *scaled_font_subset, if (font->base.base_font == NULL) { font->base.base_font = malloc (30); - if (font->base.base_font == NULL) { - status = CAIRO_STATUS_NO_MEMORY; - goto fail3; - } - + if (font->base.base_font == NULL) + goto fail4; snprintf(font->base.base_font, 30, "CairoFont-%u-%u", scaled_font_subset->font_id, scaled_font_subset->subset_id); @@ -226,15 +213,12 @@ _cairo_truetype_font_create (cairo_scaled_font_subset_t *scaled_font_subset, font->base.base_font[i] = '\0'; font->base.widths = calloc (font->num_glyphs_in_face, sizeof (int)); - if (font->base.widths == NULL) { - status = CAIRO_STATUS_NO_MEMORY; - goto fail4; - } + if (font->base.widths == NULL) + goto fail5; _cairo_array_init (&font->string_offsets, sizeof (unsigned long)); - status = _cairo_array_grow_by (&font->string_offsets, 10); - if (status) - goto fail5; + if (_cairo_array_grow_by (&font->string_offsets, 10) != CAIRO_STATUS_SUCCESS) + goto fail6; font->status = CAIRO_STATUS_SUCCESS; @@ -242,22 +226,21 @@ _cairo_truetype_font_create (cairo_scaled_font_subset_t *scaled_font_subset, return CAIRO_STATUS_SUCCESS; - fail5: - _cairo_array_fini (&font->string_offsets); + fail6: free (font->base.widths); - fail4: + fail5: free (font->base.base_font); - fail3: + fail4: free (font->parent_to_subset); - fail2: + fail3: free (font->glyphs); - fail1: + fail2: _cairo_array_fini (&font->output); + fail1: free (font); fail0: if (name) free (name); - return status; } @@ -339,27 +322,19 @@ cairo_truetype_font_align_output (cairo_truetype_font_t *font) return aligned; } -static cairo_status_t +static void cairo_truetype_font_check_boundary (cairo_truetype_font_t *font, unsigned long boundary) { - cairo_status_t status; - if (boundary - font->last_offset > SFNT_STRING_MAX_LENGTH) { - status = _cairo_array_append (&font->string_offsets, - &font->last_boundary); - if (status) - return status; - + _cairo_array_append(&font->string_offsets, &font->last_boundary); font->last_offset = font->last_boundary; } font->last_boundary = boundary; - - return CAIRO_STATUS_SUCCESS; } -static cairo_status_t +static int cairo_truetype_font_write_cmap_table (cairo_truetype_font_t *font, unsigned long tag) { @@ -385,12 +360,12 @@ cairo_truetype_font_write_cmap_table (cairo_truetype_font_t *font, cairo_truetype_font_write_be16 (font, 4); /* searchrange */ cairo_truetype_font_write_be16 (font, 1); /* entry selector */ cairo_truetype_font_write_be16 (font, 0); /* rangeshift */ - cairo_truetype_font_write_be16 (font, 0xf000 + font->base.num_glyphs - 1); /* end count[0] */ + cairo_truetype_font_write_be16 (font, 0xf000 + font->base.num_glyphs - 2); /* end count[0] */ cairo_truetype_font_write_be16 (font, 0xffff); /* end count[1] */ cairo_truetype_font_write_be16 (font, 0); /* reserved */ cairo_truetype_font_write_be16 (font, 0xf000); /* startCode[0] */ cairo_truetype_font_write_be16 (font, 0xffff); /* startCode[1] */ - cairo_truetype_font_write_be16 (font, 0x1000); /* delta[0] */ + cairo_truetype_font_write_be16 (font, 0x1001); /* delta[0] */ cairo_truetype_font_write_be16 (font, 1); /* delta[1] */ cairo_truetype_font_write_be16 (font, 0); /* rangeOffset[0] */ cairo_truetype_font_write_be16 (font, 0); /* rangeOffset[1] */ @@ -398,17 +373,17 @@ cairo_truetype_font_write_cmap_table (cairo_truetype_font_t *font, /* Output a format 6 encoding table. */ cairo_truetype_font_write_be16 (font, 6); - cairo_truetype_font_write_be16 (font, 10 + 2 * font->base.num_glyphs); + cairo_truetype_font_write_be16 (font, 10 + 2 * (font->base.num_glyphs - 1)); cairo_truetype_font_write_be16 (font, 0); cairo_truetype_font_write_be16 (font, 0); /* First character */ cairo_truetype_font_write_be16 (font, font->base.num_glyphs); for (i = 0; i < font->base.num_glyphs; i++) - cairo_truetype_font_write_be16 (font, i); + cairo_truetype_font_write_be16 (font, i + 1); return font->status; } -static cairo_status_t +static int cairo_truetype_font_write_generic_table (cairo_truetype_font_t *font, unsigned long tag) { @@ -422,17 +397,11 @@ cairo_truetype_font_write_generic_table (cairo_truetype_font_t *font, font->status = CAIRO_INT_STATUS_UNSUPPORTED; return font->status; } - status = cairo_truetype_font_allocate_write_buffer (font, size, &buffer); - if (status) - return status; - - status = font->backend->load_truetype_table (font->scaled_font_subset->scaled_font, - tag, 0, buffer, &size); - if (status) - return status; - - return CAIRO_STATUS_SUCCESS; + /* XXX: Need to check status here. */ + font->backend->load_truetype_table (font->scaled_font_subset->scaled_font, + tag, 0, buffer, &size); + return 0; } static void @@ -469,10 +438,11 @@ cairo_truetype_font_remap_composite_glyph (cairo_truetype_font_t *font, } while (has_more_components); } -static cairo_status_t +static int cairo_truetype_font_write_glyf_table (cairo_truetype_font_t *font, unsigned long tag) { + cairo_status_t status; unsigned long start_offset, index, size, next; tt_head_t header; unsigned long begin, end; @@ -485,11 +455,8 @@ cairo_truetype_font_write_glyf_table (cairo_truetype_font_t *font, } u; size = sizeof (tt_head_t); - font->status = font->backend->load_truetype_table (font->scaled_font_subset->scaled_font, - TT_TAG_head, 0, - (unsigned char*) &header, &size); - if (font->status) - return font->status; + font->backend->load_truetype_table (font->scaled_font_subset->scaled_font, + TT_TAG_head, 0, (unsigned char*) &header, &size); if (be16_to_cpu (header.index_to_loc_format) == 0) size = sizeof (int16_t) * (font->num_glyphs_in_face + 1); @@ -501,7 +468,6 @@ cairo_truetype_font_write_glyf_table (cairo_truetype_font_t *font, font->status = CAIRO_STATUS_NO_MEMORY; return font->status; } - if (font->backend->load_truetype_table (font->scaled_font_subset->scaled_font, TT_TAG_loca, 0, u.bytes, &size) != CAIRO_STATUS_SUCCESS) { font->status = CAIRO_INT_STATUS_UNSUPPORTED; @@ -523,23 +489,15 @@ cairo_truetype_font_write_glyf_table (cairo_truetype_font_t *font, size = end - begin; next = cairo_truetype_font_align_output (font); - - font->status = cairo_truetype_font_check_boundary (font, next); - if (font->status) - break; - + cairo_truetype_font_check_boundary (font, next); font->glyphs[i].location = next - start_offset; - font->status = cairo_truetype_font_allocate_write_buffer (font, size, &buffer); - if (font->status) + status = cairo_truetype_font_allocate_write_buffer (font, size, &buffer); + if (status) break; - if (size != 0) { - font->status = font->backend->load_truetype_table (font->scaled_font_subset->scaled_font, - TT_TAG_glyf, begin, buffer, &size); - if (font->status) - break; - + font->backend->load_truetype_table (font->scaled_font_subset->scaled_font, + TT_TAG_glyf, begin, buffer, &size); cairo_truetype_font_remap_composite_glyph (font, buffer); } } @@ -552,7 +510,7 @@ cairo_truetype_font_write_glyf_table (cairo_truetype_font_t *font, return font->status; } -static cairo_status_t +static int cairo_truetype_font_write_head_table (cairo_truetype_font_t *font, unsigned long tag) { @@ -560,52 +518,36 @@ cairo_truetype_font_write_head_table (cairo_truetype_font_t *font, unsigned long size; size = 0; - font->status = font->backend->load_truetype_table (font->scaled_font_subset->scaled_font, - tag, 0, NULL, &size); - if (font->status) - return font->status; - + font->backend->load_truetype_table (font->scaled_font_subset->scaled_font, + tag, 0, NULL, &size); font->checksum_index = _cairo_array_num_elements (&font->output) + 8; font->status = cairo_truetype_font_allocate_write_buffer (font, size, &buffer); - if (font->status) - return font->status; - - font->status = font->backend->load_truetype_table( font->scaled_font_subset->scaled_font, - tag, 0, buffer, &size); - if (font->status) - return font->status; - + font->backend->load_truetype_table( font->scaled_font_subset->scaled_font, + tag, 0, buffer, &size); /* set checkSumAdjustment to 0 for table checksum calcualtion */ *(uint32_t *)(buffer + 8) = 0; return font->status; } -static cairo_status_t -cairo_truetype_font_write_hhea_table (cairo_truetype_font_t *font, unsigned long tag) +static int cairo_truetype_font_write_hhea_table (cairo_truetype_font_t *font, unsigned long tag) { tt_hhea_t *hhea; unsigned long size; size = sizeof (tt_hhea_t); font->status = cairo_truetype_font_allocate_write_buffer (font, size, (unsigned char **) &hhea); - if (font->status) - return font->status; - - font->status = font->backend->load_truetype_table (font->scaled_font_subset->scaled_font, - tag, 0, (unsigned char *) hhea, &size); - if (font->status) - return font->status; - + font->backend->load_truetype_table (font->scaled_font_subset->scaled_font, + tag, 0, (unsigned char *) hhea, &size); hhea->num_hmetrics = cpu_to_be16 ((uint16_t)(font->base.num_glyphs)); - return font->status; } -static cairo_status_t +static int cairo_truetype_font_write_hmtx_table (cairo_truetype_font_t *font, unsigned long tag) { + cairo_status_t status; unsigned long size; unsigned long long_entry_size; unsigned long short_entry_size; @@ -615,22 +557,15 @@ cairo_truetype_font_write_hmtx_table (cairo_truetype_font_t *font, int num_hmetrics; size = sizeof (tt_hhea_t); - font->status = font->backend->load_truetype_table (font->scaled_font_subset->scaled_font, - TT_TAG_hhea, 0, - (unsigned char*) &hhea, &size); - if (font->status) - return font->status; - + font->backend->load_truetype_table (font->scaled_font_subset->scaled_font, + TT_TAG_hhea, 0, (unsigned char*) &hhea, &size); num_hmetrics = be16_to_cpu(hhea.num_hmetrics); for (i = 0; i < font->base.num_glyphs; i++) { long_entry_size = 2 * sizeof (int16_t); short_entry_size = sizeof (int16_t); - font->status = cairo_truetype_font_allocate_write_buffer (font, long_entry_size, - (unsigned char **) &p); - if (font->status) - return font->status; - + status = cairo_truetype_font_allocate_write_buffer (font, long_entry_size, + (unsigned char **) &p); if (font->glyphs[i].parent_index < num_hmetrics) { if (font->backend->load_truetype_table (font->scaled_font_subset->scaled_font, TT_TAG_hmtx, @@ -649,13 +584,11 @@ cairo_truetype_font_write_hmtx_table (cairo_truetype_font_t *font, font->status = CAIRO_INT_STATUS_UNSUPPORTED; return font->status; } - font->status = font->backend->load_truetype_table (font->scaled_font_subset->scaled_font, - TT_TAG_hmtx, - num_hmetrics * long_entry_size + - (font->glyphs[i].parent_index - num_hmetrics) * short_entry_size, - (unsigned char *) (p + 1), &short_entry_size); - if (font->status) - return font->status; + font->backend->load_truetype_table (font->scaled_font_subset->scaled_font, + TT_TAG_hmtx, + num_hmetrics * long_entry_size + + (font->glyphs[i].parent_index - num_hmetrics) * short_entry_size, + (unsigned char *) (p + 1), &short_entry_size); } font->base.widths[i] = be16_to_cpu (p[0]); } @@ -663,7 +596,7 @@ cairo_truetype_font_write_hmtx_table (cairo_truetype_font_t *font, return font->status; } -static cairo_status_t +static int cairo_truetype_font_write_loca_table (cairo_truetype_font_t *font, unsigned long tag) { @@ -672,11 +605,8 @@ cairo_truetype_font_write_loca_table (cairo_truetype_font_t *font, unsigned long size; size = sizeof(tt_head_t); - font->status = font->backend->load_truetype_table (font->scaled_font_subset->scaled_font, - TT_TAG_head, 0, - (unsigned char*) &header, &size); - if (font->status) - return font->status; + font->backend->load_truetype_table (font->scaled_font_subset->scaled_font, + TT_TAG_head, 0, (unsigned char*) &header, &size); if (be16_to_cpu (header.index_to_loc_format) == 0) { @@ -690,7 +620,7 @@ cairo_truetype_font_write_loca_table (cairo_truetype_font_t *font, return font->status; } -static cairo_status_t +static int cairo_truetype_font_write_maxp_table (cairo_truetype_font_t *font, unsigned long tag) { @@ -699,15 +629,39 @@ cairo_truetype_font_write_maxp_table (cairo_truetype_font_t *font, size = sizeof (tt_maxp_t); font->status = cairo_truetype_font_allocate_write_buffer (font, size, (unsigned char **) &maxp); - if (font->status) - return font->status; - - font->status = font->backend->load_truetype_table (font->scaled_font_subset->scaled_font, - tag, 0, (unsigned char *) maxp, &size); - if (font->status) - return font->status; - + font->backend->load_truetype_table (font->scaled_font_subset->scaled_font, + tag, 0, (unsigned char *) maxp, &size); maxp->num_glyphs = cpu_to_be16 (font->base.num_glyphs); + return font->status; +} + +static int +cairo_truetype_font_write_post_table (cairo_truetype_font_t *font, + unsigned long tag) +{ + char buf[10]; + int n; + unsigned i; + + cairo_truetype_font_write_be32 (font, 0x00020000); + cairo_truetype_font_write_be32 (font, 0); + cairo_truetype_font_write_be16 (font, 0); + cairo_truetype_font_write_be16 (font, 1); + cairo_truetype_font_write_be32 (font, 0); + cairo_truetype_font_write_be32 (font, 0); + cairo_truetype_font_write_be32 (font, 0); + cairo_truetype_font_write_be32 (font, 0); + cairo_truetype_font_write_be32 (font, 0); + cairo_truetype_font_write_be16 (font, font->base.num_glyphs); + cairo_truetype_font_write_be16 (font, 0); + for (i = 1; i < font->base.num_glyphs; i++) + cairo_truetype_font_write_be16 (font, i + 257); + + for (i = 1; i < font->base.num_glyphs; i++) { + n = snprintf(buf + 1, 9, "g%d", i - 1); + buf[0] = n; + cairo_truetype_font_write (font, buf, n + 1); + } return font->status; } @@ -715,7 +669,7 @@ cairo_truetype_font_write_maxp_table (cairo_truetype_font_t *font, typedef struct table table_t; struct table { unsigned long tag; - cairo_status_t (*write) (cairo_truetype_font_t *font, unsigned long tag); + int (*write) (cairo_truetype_font_t *font, unsigned long tag); int pos; /* position in the font directory */ }; @@ -738,7 +692,8 @@ static const table_t truetype_tables[] = { { TT_TAG_loca, cairo_truetype_font_write_loca_table, 7 }, { TT_TAG_maxp, cairo_truetype_font_write_maxp_table, 8 }, { TT_TAG_name, cairo_truetype_font_write_generic_table, 9 }, - { TT_TAG_prep, cairo_truetype_font_write_generic_table, 10 }, + { TT_TAG_post, cairo_truetype_font_write_post_table, 10 }, + { TT_TAG_prep, cairo_truetype_font_write_generic_table, 11 }, }; static cairo_status_t @@ -821,7 +776,6 @@ cairo_truetype_font_generate (cairo_truetype_font_t *font, const unsigned long **string_offsets, unsigned long *num_strings) { - cairo_status_t status; unsigned long start, end, next; uint32_t checksum, *checksum_location; unsigned int i; @@ -841,12 +795,7 @@ cairo_truetype_font_generate (cairo_truetype_font_t *font, next = cairo_truetype_font_align_output (font); cairo_truetype_font_update_entry (font, truetype_tables[i].pos, truetype_tables[i].tag, start, end); - status = cairo_truetype_font_check_boundary (font, next); - if (status) { - font->status = status; - goto fail; - } - + cairo_truetype_font_check_boundary (font, next); start = next; } @@ -883,7 +832,7 @@ cairo_status_t _cairo_truetype_subset_init (cairo_truetype_subset_t *truetype_subset, cairo_scaled_font_subset_t *font_subset) { - cairo_truetype_font_t *font = NULL; + cairo_truetype_font_t *font; cairo_status_t status; const char *data = NULL; /* squelch bogus compiler warning */ unsigned long length = 0; /* squelch bogus compiler warning */ @@ -896,6 +845,10 @@ _cairo_truetype_subset_init (cairo_truetype_subset_t *truetype_subset, if (status) return status; + /* Add the notdef glyph. This is required at glyph index 0 + * in the subsetted font. */ + cairo_truetype_font_use_glyph (font, 0); + for (i = 0; i < font->scaled_font_subset->num_glyphs; i++) { parent_glyph = font->scaled_font_subset->glyphs[i]; cairo_truetype_font_use_glyph (font, parent_glyph); @@ -907,22 +860,19 @@ _cairo_truetype_subset_init (cairo_truetype_subset_t *truetype_subset, goto fail1; truetype_subset->base_font = strdup (font->base.base_font); - if (truetype_subset->base_font == NULL) { - status = CAIRO_STATUS_NO_MEMORY; + if (truetype_subset->base_font == NULL) goto fail1; - } - /* The widths array returned must contain only widths for the - * glyphs in font_subset. Any subglyphs appended after - * font_subset->num_glyphs are omitted. */ + /* The widths array returned must contain only widths for + * the glyphs in font_subset. The notdef glyph at index 0 + * and any subglyphs appended after font_subset->num_glyphs + * are omitted. */ truetype_subset->widths = calloc (sizeof (double), font->scaled_font_subset->num_glyphs); - if (truetype_subset->widths == NULL) { - status = CAIRO_STATUS_NO_MEMORY; + if (truetype_subset->widths == NULL) goto fail2; - } for (i = 0; i < font->scaled_font_subset->num_glyphs; i++) - truetype_subset->widths[i] = (double)font->base.widths[i]/font->base.units_per_em; + truetype_subset->widths[i] = (double)font->base.widths[i + 1]/font->base.units_per_em; truetype_subset->x_min = (double)font->base.x_min/font->base.units_per_em; truetype_subset->y_min = (double)font->base.y_min/font->base.units_per_em; @@ -932,28 +882,19 @@ _cairo_truetype_subset_init (cairo_truetype_subset_t *truetype_subset, truetype_subset->descent = (double)font->base.descent/font->base.units_per_em; truetype_subset->data = malloc (length); - if (truetype_subset->data == NULL) { - status = CAIRO_STATUS_NO_MEMORY; + if (truetype_subset->data == NULL) goto fail3; - } memcpy (truetype_subset->data, data, length); truetype_subset->data_length = length; - if (num_strings) { - offsets_length = num_strings * sizeof (unsigned long); - truetype_subset->string_offsets = malloc (offsets_length); - if (truetype_subset->string_offsets == NULL) { - status = CAIRO_STATUS_NO_MEMORY; - goto fail4; - } + offsets_length = num_strings * sizeof (unsigned long); + truetype_subset->string_offsets = malloc (offsets_length); + if (truetype_subset->string_offsets == NULL) + goto fail4; - memcpy (truetype_subset->string_offsets, string_offsets, offsets_length); - truetype_subset->num_string_offsets = num_strings; - } else { - truetype_subset->string_offsets = NULL; - truetype_subset->num_string_offsets = 0; - } + memcpy (truetype_subset->string_offsets, string_offsets, offsets_length); + truetype_subset->num_string_offsets = num_strings; cairo_truetype_font_destroy (font); diff --git a/gfx/cairo/cairo/src/cairo-type1-fallback.c b/gfx/cairo/cairo/src/cairo-type1-fallback.c index 387277785ac7..a183b28b4973 100644 --- a/gfx/cairo/cairo/src/cairo-type1-fallback.c +++ b/gfx/cairo/cairo/src/cairo-type1-fallback.c @@ -39,11 +39,6 @@ #include "cairo-path-fixed-private.h" #include "cairo-output-stream-private.h" -typedef enum { - CAIRO_CHARSTRING_TYPE1, - CAIRO_CHARSTRING_TYPE2, -} cairo_charstring_type_t; - typedef struct _cairo_type1_font { int *widths; @@ -95,7 +90,7 @@ cairo_type1_font_create (cairo_scaled_font_subset_t *scaled_font_subset, font_face = cairo_scaled_font_get_font_face (scaled_font_subset->scaled_font); - cairo_matrix_init_scale (&font_matrix, 1000, -1000); + cairo_matrix_init_scale (&font_matrix, 1000, 1000); cairo_matrix_init_identity (&ctm); _cairo_font_options_init_default (&font_options); @@ -106,7 +101,7 @@ cairo_type1_font_create (cairo_scaled_font_subset_t *scaled_font_subset, &font_matrix, &ctm, &font_options); - if (font->type1_scaled_font->status) + if (font->type1_scaled_font == NULL) goto fail; _cairo_array_init (&font->contents, sizeof (unsigned char)); @@ -161,9 +156,7 @@ charstring_encode_command (cairo_array_t *data, int command) * bytes that will be used is 5. */ static void -charstring_encode_integer (cairo_array_t *data, - int i, - cairo_charstring_type_t type) +charstring_encode_integer (cairo_array_t *data, int i) { cairo_status_t status; int orig_size; @@ -181,19 +174,11 @@ charstring_encode_integer (cairo_array_t *data, *p++ = (i >> 8)+ 251; *p++ = i & 0xff; } else { - if (type == CAIRO_CHARSTRING_TYPE1) { - *p++ = 0xff; - *p++ = i >> 24; - *p++ = (i >> 16) & 0xff; - *p++ = (i >> 8) & 0xff; - *p++ = i & 0xff; - } else { - *p++ = 0xff; - *p++ = (i >> 8) & 0xff; - *p++ = i & 0xff; - *p++ = 0; - *p++ = 0; - } + *p++ = 0xff; + *p++ = i >> 24; + *p++ = (i >> 16) & 0xff; + *p++ = (i >> 8) & 0xff; + *p++ = i & 0xff; } /* Ensure the array doesn't grow, which allows this function to @@ -208,7 +193,6 @@ charstring_encode_integer (cairo_array_t *data, typedef struct _ps_path_info { cairo_array_t *data; int current_x, current_y; - cairo_charstring_type_t type; } t1_path_info_t; static cairo_status_t @@ -225,8 +209,8 @@ _charstring_move_to (void *closure, dx = _cairo_fixed_integer_part (point->x) - path_info->current_x; dy = _cairo_fixed_integer_part (point->y) - path_info->current_y; - charstring_encode_integer (path_info->data, dx, path_info->type); - charstring_encode_integer (path_info->data, dy, path_info->type); + charstring_encode_integer (path_info->data, dx); + charstring_encode_integer (path_info->data, dy); path_info->current_x += dx; path_info->current_y += dy; @@ -249,8 +233,8 @@ _charstring_line_to (void *closure, dx = _cairo_fixed_integer_part (point->x) - path_info->current_x; dy = _cairo_fixed_integer_part (point->y) - path_info->current_y; - charstring_encode_integer (path_info->data, dx, path_info->type); - charstring_encode_integer (path_info->data, dy, path_info->type); + charstring_encode_integer (path_info->data, dx); + charstring_encode_integer (path_info->data, dy); path_info->current_x += dx; path_info->current_y += dy; @@ -279,12 +263,12 @@ _charstring_curve_to (void *closure, dy2 = _cairo_fixed_integer_part (point2->y) - path_info->current_y - dy1; dx3 = _cairo_fixed_integer_part (point3->x) - path_info->current_x - dx1 - dx2; dy3 = _cairo_fixed_integer_part (point3->y) - path_info->current_y - dy1 - dy2; - charstring_encode_integer (path_info->data, dx1, path_info->type); - charstring_encode_integer (path_info->data, dy1, path_info->type); - charstring_encode_integer (path_info->data, dx2, path_info->type); - charstring_encode_integer (path_info->data, dy2, path_info->type); - charstring_encode_integer (path_info->data, dx3, path_info->type); - charstring_encode_integer (path_info->data, dy3, path_info->type); + charstring_encode_integer (path_info->data, dx1); + charstring_encode_integer (path_info->data, dy1); + charstring_encode_integer (path_info->data, dx2); + charstring_encode_integer (path_info->data, dy2); + charstring_encode_integer (path_info->data, dx3); + charstring_encode_integer (path_info->data, dy3); path_info->current_x += dx1 + dx2 + dx3; path_info->current_y += dy1 + dy2 + dy3; charstring_encode_command (path_info->data, CHARSTRING_rcurveto); @@ -298,9 +282,6 @@ _charstring_close_path (void *closure) cairo_status_t status; t1_path_info_t *path_info = (t1_path_info_t *) closure; - if (path_info->type == CAIRO_CHARSTRING_TYPE2) - return CAIRO_STATUS_SUCCESS; - status = _cairo_array_grow_by (path_info->data, 2); if (status) return status; @@ -328,7 +309,7 @@ charstring_encrypt (cairo_array_t *data) } static cairo_int_status_t -create_notdef_charstring (cairo_array_t *data, cairo_charstring_type_t type) +create_notdef_charstring (cairo_array_t *data) { cairo_status_t status; @@ -339,15 +320,13 @@ create_notdef_charstring (cairo_array_t *data, cairo_charstring_type_t type) if (status) return status; - if (type == CAIRO_CHARSTRING_TYPE1) { - charstring_encode_integer (data, 0, type); - charstring_encode_integer (data, 0, type); + charstring_encode_integer (data, 0); + charstring_encode_integer (data, 0); - /* The width and height is arbitrary. */ - charstring_encode_integer (data, 500, type); - charstring_encode_integer (data, 500, type); - charstring_encode_command (data, CHARSTRING_sbw); - } + /* The width and height is arbitrary. */ + charstring_encode_integer (data, 500); + charstring_encode_integer (data, 500); + charstring_encode_command (data, CHARSTRING_sbw); charstring_encode_command (data, CHARSTRING_endchar); @@ -355,11 +334,10 @@ create_notdef_charstring (cairo_array_t *data, cairo_charstring_type_t type) } static cairo_int_status_t -cairo_type1_font_create_charstring (cairo_type1_font_t *font, - int subset_index, - int glyph_index, - cairo_charstring_type_t type, - cairo_array_t *data) +cairo_type1_font_create_charstring (cairo_type1_font_t *font, + int subset_index, + int glyph_index, + cairo_array_t *data) { cairo_int_status_t status; cairo_scaled_glyph_t *scaled_glyph; @@ -391,29 +369,21 @@ cairo_type1_font_create_charstring (cairo_type1_font_t *font, if (metrics->y_bearing + metrics->height > font->y_max) font->y_max = metrics->y_bearing + metrics->height; } - font->widths[subset_index] = metrics->x_advance; + font->widths[subset_index] = metrics->width; status = _cairo_array_grow_by (data, 30); if (status) return status; - if (type == CAIRO_CHARSTRING_TYPE1) { - charstring_encode_integer (data, (int) scaled_glyph->metrics.x_bearing, type); - charstring_encode_integer (data, (int) scaled_glyph->metrics.y_bearing, type); - charstring_encode_integer (data, (int) scaled_glyph->metrics.width, type); - charstring_encode_integer (data, (int) scaled_glyph->metrics.height, type); - charstring_encode_command (data, CHARSTRING_sbw); + charstring_encode_integer (data, (int) scaled_glyph->metrics.x_bearing); + charstring_encode_integer (data, (int) scaled_glyph->metrics.y_bearing); + charstring_encode_integer (data, (int) scaled_glyph->metrics.width); + charstring_encode_integer (data, (int) scaled_glyph->metrics.height); + charstring_encode_command (data, CHARSTRING_sbw); - path_info.current_x = (int) scaled_glyph->metrics.x_bearing; - path_info.current_y = (int) scaled_glyph->metrics.y_bearing; - } else { - charstring_encode_integer (data, (int) scaled_glyph->metrics.width, type); - - path_info.current_x = 0; - path_info.current_y = 0; - } path_info.data = data; - path_info.type = type; + path_info.current_x = (int) scaled_glyph->metrics.x_bearing; + path_info.current_y = (int) scaled_glyph->metrics.y_bearing; status = _cairo_path_fixed_interpret (scaled_glyph->path, CAIRO_DIRECTION_FORWARD, _charstring_move_to, @@ -451,7 +421,7 @@ cairo_type1_font_write_charstrings (cairo_type1_font_t *font, "2 index /CharStrings %d dict dup begin\n", font->scaled_font_subset->num_glyphs + 1); - for (i = 1; i < font->scaled_font_subset->num_glyphs; i++) { + for (i = 0; i < font->scaled_font_subset->num_glyphs; i++) { _cairo_array_truncate (&data, 0); /* four "random" bytes required by encryption algorithm */ status = _cairo_array_append_multiple (&data, zeros, 4); @@ -459,7 +429,6 @@ cairo_type1_font_write_charstrings (cairo_type1_font_t *font, goto fail; status = cairo_type1_font_create_charstring (font, i, font->scaled_font_subset->glyphs[i], - CAIRO_CHARSTRING_TYPE1, &data); if (status) goto fail; @@ -479,7 +448,7 @@ cairo_type1_font_write_charstrings (cairo_type1_font_t *font, status = _cairo_array_append_multiple (&data, zeros, 4); if (status) goto fail; - status = create_notdef_charstring (&data, CAIRO_CHARSTRING_TYPE1); + status = create_notdef_charstring (&data); if (status) goto fail; charstring_encrypt (&data); @@ -499,18 +468,28 @@ static void cairo_type1_font_write_header (cairo_type1_font_t *font, const char *name) { + cairo_matrix_t matrix; unsigned int i; const char spaces[50] = " "; + matrix = font->type1_scaled_font->scale; + matrix.xy = -matrix.xy; + matrix.yy = -matrix.yy; + cairo_matrix_invert (&matrix); + _cairo_output_stream_printf (font->output, "%%!FontType1-1.1 %s 1.0\n" "11 dict begin\n" "/FontName /%s def\n" "/PaintType 0 def\n" "/FontType 1 def\n" - "/FontMatrix [0.001 0 0 0.001 0 0] readonly def\n", + "/FontMatrix [%f %f %f %f 0 0] readonly def\n", name, - name); + name, + matrix.xx, + matrix.yx, + matrix.xy, + matrix.yy); /* We don't know the bbox values until after the charstrings have * been generated. Reserve some space and fill in the bbox @@ -579,7 +558,6 @@ cairo_type1_font_write_private_dict (cairo_type1_font_t *font, const char *name) { cairo_int_status_t status; - cairo_status_t status2; cairo_output_stream_t *encrypted_output; font->eexec_key = CAIRO_TYPE1_PRIVATE_DICT_KEY; @@ -619,10 +597,10 @@ cairo_type1_font_write_private_dict (cairo_type1_font_t *font, "dup /FontName get exch definefont pop\n" "mark currentfile closefile\n"); - fail: - status2 = _cairo_output_stream_destroy (encrypted_output); if (status == CAIRO_STATUS_SUCCESS) - status = status2; + status = _cairo_output_stream_get_status (encrypted_output); + fail: + _cairo_output_stream_destroy (encrypted_output); return status; } @@ -694,18 +672,14 @@ cairo_type1_font_generate (cairo_type1_font_t *font, const char *name) return CAIRO_STATUS_SUCCESS; } -static cairo_status_t +static void cairo_type1_font_destroy (cairo_type1_font_t *font) { - cairo_status_t status; - free (font->widths); cairo_scaled_font_destroy (font->type1_scaled_font); _cairo_array_fini (&font->contents); - status = _cairo_output_stream_destroy (font->output); + _cairo_output_stream_destroy (font->output); free (font); - - return status; } static cairo_status_t @@ -771,14 +745,14 @@ _cairo_type1_fallback_init_internal (cairo_type1_subset_t *type1_subset, type1_subset->data_length = font->data_size; type1_subset->trailer_length = font->trailer_size; - return cairo_type1_font_destroy (font); + cairo_type1_font_destroy (font); + return CAIRO_STATUS_SUCCESS; fail3: free (type1_subset->widths); fail2: free (type1_subset->base_font); fail1: - /* status is already set, ignore further errors */ cairo_type1_font_destroy (font); return status; @@ -811,83 +785,3 @@ _cairo_type1_fallback_fini (cairo_type1_subset_t *subset) free (subset->widths); free (subset->data); } - -cairo_status_t -_cairo_type2_charstrings_init (cairo_type2_charstrings_t *type2_subset, - cairo_scaled_font_subset_t *scaled_font_subset) -{ - cairo_type1_font_t *font; - cairo_status_t status; - unsigned int i; - cairo_array_t charstring; - - status = cairo_type1_font_create (scaled_font_subset, &font, FALSE); - if (status) - return status; - - _cairo_array_init (&type2_subset->charstrings, sizeof (cairo_array_t)); - - type2_subset->widths = calloc (sizeof (int), font->scaled_font_subset->num_glyphs); - if (type2_subset->widths == NULL) { - status = CAIRO_STATUS_NO_MEMORY; - goto fail1; - } - - for (i = 0; i < font->scaled_font_subset->num_glyphs; i++) { - _cairo_array_init (&charstring, sizeof (unsigned char)); - status = _cairo_array_grow_by (&charstring, 32); - if (status) - goto fail2; - - if (i == 0) { - status = create_notdef_charstring (&charstring, CAIRO_CHARSTRING_TYPE2); - } else { - status = cairo_type1_font_create_charstring (font, i, - font->scaled_font_subset->glyphs[i], - CAIRO_CHARSTRING_TYPE2, - &charstring); - } - if (status) - goto fail2; - - status = _cairo_array_append (&type2_subset->charstrings, &charstring); - if (status) - goto fail2; - } - - for (i = 0; i < font->scaled_font_subset->num_glyphs; i++) - type2_subset->widths[i] = font->widths[i]; - - type2_subset->x_min = (int) font->x_min; - type2_subset->y_min = (int) font->y_min; - type2_subset->x_max = (int) font->x_max; - type2_subset->y_max = (int) font->y_max; - type2_subset->ascent = (int) font->y_max; - type2_subset->descent = (int) font->y_min; - - cairo_type1_font_destroy (font); - return CAIRO_STATUS_SUCCESS; - -fail2: - _cairo_array_fini (&charstring); - _cairo_type2_charstrings_fini (type2_subset); -fail1: - cairo_type1_font_destroy (font); - return status; -} - -void -_cairo_type2_charstrings_fini (cairo_type2_charstrings_t *type2_subset) -{ - unsigned int i, num_charstrings; - cairo_array_t *charstring; - - num_charstrings = _cairo_array_num_elements (&type2_subset->charstrings); - for (i = 0; i < num_charstrings; i++) { - charstring = _cairo_array_index (&type2_subset->charstrings, i); - _cairo_array_fini (charstring); - } - _cairo_array_fini (&type2_subset->charstrings); - - free (type2_subset->widths); -} diff --git a/gfx/cairo/cairo/src/cairo-type1-subset.c b/gfx/cairo/cairo/src/cairo-type1-subset.c index 919b1d5c7ac2..e4f5015dd7b0 100644 --- a/gfx/cairo/cairo/src/cairo-type1-subset.c +++ b/gfx/cairo/cairo/src/cairo-type1-subset.c @@ -46,8 +46,6 @@ #include FT_OUTLINE_H #include FT_TYPE1_TABLES_H -#include - typedef struct _cairo_type1_font_subset { cairo_scaled_font_subset_t *scaled_font_subset; @@ -1135,6 +1133,9 @@ _cairo_type1_subset_init (cairo_type1_subset_t *type1_subset, cairo_type1_font_subset_use_glyph (font, parent_glyph); } + /* Pull in the .notdef glyph */ + cairo_type1_font_subset_use_glyph (font, 0); + status = cairo_type1_font_subset_generate (font, name); if (status) goto fail1; @@ -1194,30 +1195,3 @@ _cairo_type1_subset_fini (cairo_type1_subset_t *subset) free (subset->widths); free (subset->data); } - -cairo_bool_t -_cairo_type1_scaled_font_is_type1 (cairo_scaled_font_t *scaled_font) -{ - cairo_ft_unscaled_font_t *unscaled; - FT_Face face; - PS_FontInfoRec font_info; - cairo_bool_t is_type1 = FALSE; - - unscaled = (cairo_ft_unscaled_font_t *) _cairo_ft_scaled_font_get_unscaled_font (scaled_font); - face = _cairo_ft_unscaled_font_lock_face (unscaled); - if (!face) - return FALSE; - - if (FT_Get_PS_Font_Info(face, &font_info) == 0) - is_type1 = TRUE; - - /* OpenType/CFF fonts also have a PS_FontInfoRec */ -#if HAVE_FT_LOAD_SFNT_TABLE - if (FT_IS_SFNT (face)) - is_type1 = FALSE; -#endif - - _cairo_ft_unscaled_font_unlock_face (unscaled); - - return is_type1; -} diff --git a/gfx/cairo/cairo/src/cairo-types-private.h b/gfx/cairo/cairo/src/cairo-types-private.h deleted file mode 100644 index 37b131e13f3f..000000000000 --- a/gfx/cairo/cairo/src/cairo-types-private.h +++ /dev/null @@ -1,128 +0,0 @@ -/* 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 - */ - -#ifndef CAIRO_TYPES_PRIVATE_H -#define CAIRO_TYPES_PRIVATE_H - -typedef struct _cairo_array cairo_array_t; -struct _cairo_array { - unsigned int size; - unsigned int num_elements; - unsigned int element_size; - char **elements; - - cairo_bool_t is_snapshot; -}; - -typedef cairo_array_t cairo_user_data_array_t; - -struct _cairo_font_options { - cairo_antialias_t antialias; - cairo_subpixel_order_t subpixel_order; - cairo_hint_style_t hint_style; - cairo_hint_metrics_t hint_metrics; -}; - -typedef struct _cairo_hash_table cairo_hash_table_t; - -typedef struct _cairo_cache { - cairo_hash_table_t *hash_table; - - cairo_destroy_func_t entry_destroy; - - unsigned long max_size; - unsigned long size; - - int freeze_count; -} cairo_cache_t; - -/** - * 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 struct _cairo_surface_backend cairo_surface_backend_t; -typedef struct _cairo_clip cairo_clip_t; -typedef struct _cairo_output_stream cairo_output_stream_t; -typedef struct _cairo_scaled_font_subsets cairo_scaled_font_subsets_t; -typedef struct _cairo_paginated_surface_backend cairo_paginated_surface_backend_t; -typedef struct _cairo_scaled_font_backend cairo_scaled_font_backend_t; -typedef struct _cairo_font_face_backend cairo_font_face_backend_t; - - -typedef struct _cairo_xlib_screen_info cairo_xlib_screen_info_t; - -typedef enum { - CAIRO_PAGINATED_MODE_ANALYZE, /* analyze page regions */ - CAIRO_PAGINATED_MODE_RENDER /* render page contents */ -} cairo_paginated_mode_t; - -#endif /* CAIRO_TYPES_PRIVATE_H */ diff --git a/gfx/cairo/cairo/src/cairo-unicode.c b/gfx/cairo/cairo/src/cairo-unicode.c index 9abb0ebca1d5..5ca51e1e2aa0 100644 --- a/gfx/cairo/cairo/src/cairo-unicode.c +++ b/gfx/cairo/cairo/src/cairo-unicode.c @@ -40,7 +40,9 @@ * Owen Taylor */ -#include "cairoint.h" +#include + +#include #define UTF8_COMPUTE(Char, Mask, Len) \ if (Char < 128) \ diff --git a/gfx/cairo/cairo/src/cairo-wideint-private.h b/gfx/cairo/cairo/src/cairo-wideint-private.h index 636d8a6b7df3..7d459ea36448 100644 --- a/gfx/cairo/cairo/src/cairo-wideint-private.h +++ b/gfx/cairo/cairo/src/cairo-wideint-private.h @@ -64,12 +64,6 @@ # ifndef UINT16_MAX # define UINT16_MAX (65535) # endif -# ifndef INT32_MIN -# define INT32_MIN (-2147483647-1) -# endif -# ifndef INT32_MAX -# define INT32_MAX (2147483647) -# endif #else #error Cannot find definitions for fixed-width integral types (uint8_t, uint32_t, etc.) #endif diff --git a/gfx/cairo/cairo/src/cairo-win32-font.c b/gfx/cairo/cairo/src/cairo-win32-font.c index 73878af14253..1fcb358b4ea3 100644 --- a/gfx/cairo/cairo/src/cairo-win32-font.c +++ b/gfx/cairo/cairo/src/cairo-win32-font.c @@ -1,4 +1,3 @@ -/* -*- Mode: c; tab-width: 8; c-basic-offset: 4; indent-tabs-mode: t; -*- */ /* cairo - a vector graphics library with display and print output * * Copyright © 2005 Red Hat, Inc @@ -33,8 +32,9 @@ * Contributor(s): */ +#include +#include #include "cairoint.h" - #include "cairo-win32-private.h" #ifndef SPI_GETFONTSMOOTHINGTYPE @@ -245,6 +245,8 @@ _win32_scaled_font_create (LOGFONTW *logfont, cairo_matrix_t scale; cairo_status_t status; + _cairo_win32_initialize (); + f = malloc (sizeof(cairo_win32_scaled_font_t)); if (f == NULL) return NULL; @@ -283,7 +285,6 @@ _win32_scaled_font_create (LOGFONTW *logfont, f->em_square = 0; f->scaled_hfont = NULL; f->unscaled_hfont = NULL; - if (f->quality == logfont->lfQuality || (logfont->lfQuality == DEFAULT_QUALITY && options->antialias == CAIRO_ANTIALIAS_DEFAULT)) { @@ -300,13 +301,11 @@ _win32_scaled_font_create (LOGFONTW *logfont, cairo_matrix_multiply (&scale, font_matrix, ctm); _compute_transform (f, &scale); - status = _cairo_scaled_font_init (&f->base, font_face, - font_matrix, ctm, options, - &cairo_win32_scaled_font_backend); - - if (status == CAIRO_STATUS_SUCCESS) - status = _cairo_win32_scaled_font_set_metrics (f); + _cairo_scaled_font_init (&f->base, font_face, + font_matrix, ctm, options, + &cairo_win32_scaled_font_backend); + status = _cairo_win32_scaled_font_set_metrics (f); if (status) { cairo_scaled_font_destroy (&f->base); return NULL; @@ -488,6 +487,8 @@ _cairo_win32_scaled_font_create_toy (cairo_toy_font_face_t *toy_face, int face_name_len; cairo_status_t status; + _cairo_win32_initialize (); + status = _cairo_utf8_to_utf16 (toy_face->family, -1, &face_name, &face_name_len); if (status) @@ -1470,14 +1471,16 @@ _cairo_win32_scaled_font_init_glyph_path (cairo_win32_scaled_font_t *scaled_font } free(buffer); +CLEANUP_FONT: + _cairo_scaled_glyph_set_path (scaled_glyph, &scaled_font->base, path); - CLEANUP_FONT: cairo_win32_scaled_font_done_font (&scaled_font->base); CLEANUP_PATH: + if (status != CAIRO_STATUS_SUCCESS) _cairo_path_fixed_destroy (path); @@ -1537,6 +1540,8 @@ _cairo_win32_font_face_scaled_font_create (void *abstract_face, cairo_win32_font_face_t *font_face = abstract_face; + _cairo_win32_initialize (); + if (font_face->hfont) { /* Check whether it's OK to go ahead and use the font-face's HFONT. */ if (_is_scale (ctm, 1.) && @@ -1585,6 +1590,8 @@ cairo_win32_font_face_create_for_logfontw_hfont (LOGFONTW *logfont, HFONT font) { cairo_win32_font_face_t *font_face; + _cairo_win32_initialize (); + font_face = malloc (sizeof (cairo_win32_font_face_t)); if (!font_face) { _cairo_error (CAIRO_STATUS_NO_MEMORY); diff --git a/gfx/cairo/cairo/src/cairo-win32-private.h b/gfx/cairo/cairo/src/cairo-win32-private.h index e360d8aea8ff..8256b20964f5 100644 --- a/gfx/cairo/cairo/src/cairo-win32-private.h +++ b/gfx/cairo/cairo/src/cairo-win32-private.h @@ -46,7 +46,11 @@ #define SB_NONE 0 #endif +#if MOZILLA_CAIRO_NOT_DEFINED +#define WIN32_FONT_LOGICAL_SCALE 32 +#else #define WIN32_FONT_LOGICAL_SCALE 1 +#endif typedef struct _cairo_win32_surface { cairo_surface_t base; @@ -105,4 +109,7 @@ _cairo_win32_print_gdi_error (const char *context); cairo_bool_t _cairo_surface_is_win32 (cairo_surface_t *surface); +void +_cairo_win32_initialize (void); + #endif /* CAIRO_WIN32_PRIVATE_H */ diff --git a/gfx/cairo/cairo/src/cairo-win32-surface.c b/gfx/cairo/cairo/src/cairo-win32-surface.c index 450887a1f512..58a698f14a5e 100644 --- a/gfx/cairo/cairo/src/cairo-win32-surface.c +++ b/gfx/cairo/cairo/src/cairo-win32-surface.c @@ -44,17 +44,12 @@ #if !defined(_WIN32_WINNT) || (_WIN32_WINNT < 0x0500) # define _WIN32_WINNT 0x0500 #endif - -#include "cairoint.h" - -#include "cairo-clip-private.h" -#include "cairo-win32-private.h" - #include -#if defined(__MINGW32__) && !defined(ETO_PDY) -# define ETO_PDY 0x2000 -#endif +#include +#include "cairoint.h" +#include "cairo-clip-private.h" +#include "cairo-win32-private.h" #undef DEBUG_COMPOSITE @@ -332,6 +327,8 @@ _cairo_win32_surface_create_for_dc (HDC original_dc, char *bits; int rowstride; + _cairo_win32_initialize (); + surface = malloc (sizeof (cairo_win32_surface_t)); if (surface == NULL) { _cairo_error (CAIRO_STATUS_NO_MEMORY); @@ -476,7 +473,12 @@ _cairo_win32_surface_get_subimage (cairo_win32_surface_t *surface, status = CAIRO_INT_STATUS_UNSUPPORTED; - if ((local->flags & CAIRO_WIN32_SURFACE_CAN_BITBLT) && + /* Check for SURFACE_IS_DISPLAY here, because there are a lot + * of printer drivers that lie and say they can BitBlt, but + * just spit out black instead. + */ + if ((local->flags & CAIRO_WIN32_SURFACE_IS_DISPLAY) && + (local->flags & CAIRO_WIN32_SURFACE_CAN_BITBLT) && BitBlt (local->dc, 0, 0, width, height, @@ -1638,6 +1640,8 @@ cairo_win32_surface_create (HDC hdc) int depth; cairo_format_t format; + _cairo_win32_initialize (); + /* Try to figure out the drawing bounds for the Device context */ if (GetClipBox (hdc, &rect) == ERROR) { @@ -1855,30 +1859,6 @@ cairo_win32_surface_get_image (cairo_surface_t *surface) return ((cairo_win32_surface_t*)surface)->image; } -static cairo_bool_t -_cairo_win32_surface_is_similar (void *surface_a, - void *surface_b, - cairo_content_t content) -{ - cairo_win32_surface_t *a = surface_a; - cairo_win32_surface_t *b = surface_b; - - return a->dc == b->dc; -} - -static cairo_status_t -_cairo_win32_surface_reset (void *abstract_surface) -{ - cairo_win32_surface_t *surface = abstract_surface; - cairo_status_t status; - - status = _cairo_win32_surface_set_clip_region (surface, NULL); - if (status) - return status; - - return CAIRO_STATUS_SUCCESS; -} - static const cairo_surface_backend_t cairo_win32_surface_backend = { CAIRO_SURFACE_TYPE_WIN32, _cairo_win32_surface_create_similar, @@ -1909,12 +1889,70 @@ static const cairo_surface_backend_t cairo_win32_surface_backend = { NULL, /* fill */ _cairo_win32_surface_show_glyphs, - NULL, /* snapshot */ - _cairo_win32_surface_is_similar, - - _cairo_win32_surface_reset + NULL /* snapshot */ }; +/* + * Without pthread, on win32 we need to initialize all the 'mutex'es + * before use. It is guaranteed that DllMain will get called single + * threaded before any other function. + * Initializing more than finally needed should not matter much. + */ +#if !defined(HAVE_PTHREAD_H) + +CRITICAL_SECTION _cairo_scaled_font_map_mutex; +#ifdef CAIRO_HAS_FT_FONT +CRITICAL_SECTION _cairo_ft_unscaled_font_map_mutex; +#endif +CRITICAL_SECTION _cairo_font_face_mutex; + +static int _cairo_win32_initialized = 0; + +void +_cairo_win32_initialize (void) { + if (_cairo_win32_initialized) + return; + + /* every 'mutex' from CAIRO_MUTEX_DECALRE needs to be initialized here */ + InitializeCriticalSection (&_cairo_scaled_font_map_mutex); +#ifdef CAIRO_HAS_FT_FONT + InitializeCriticalSection (&_cairo_ft_unscaled_font_map_mutex); +#endif + InitializeCriticalSection (&_cairo_font_face_mutex); + + _cairo_win32_initialized = 1; +} + +#if !defined(CAIRO_WIN32_STATIC_BUILD) +BOOL WINAPI +DllMain (HINSTANCE hinstDLL, + DWORD fdwReason, + LPVOID lpvReserved) +{ + switch (fdwReason) + { + case DLL_PROCESS_ATTACH: + _cairo_win32_initialize(); + break; + case DLL_PROCESS_DETACH: + DeleteCriticalSection (&_cairo_scaled_font_map_mutex); +#ifdef CAIRO_HAS_FT_FONT + DeleteCriticalSection (&_cairo_ft_unscaled_font_map_mutex); +#endif + DeleteCriticalSection (&_cairo_font_face_mutex); + break; + } + return TRUE; +} +#endif +#else +/* Need a function definition here too since it's called outside of ifdefs */ +void +_cairo_win32_initialize (void) +{ +} +#endif + /* Notes: * * Win32 alpha-understanding functions @@ -1928,33 +1966,3 @@ static const cairo_surface_backend_t cairo_win32_surface_backend = { * it will still copy over the src alpha, because the SCA value (255) will be * multiplied by all the src components. */ - - -#if !defined(CAIRO_WIN32_STATIC_BUILD) - -/* declare to avoid "no previous prototype for 'DllMain'" warning */ -BOOL WINAPI -DllMain (HINSTANCE hinstDLL, - DWORD fdwReason, - LPVOID lpvReserved); - -BOOL WINAPI -DllMain (HINSTANCE hinstDLL, - DWORD fdwReason, - LPVOID lpvReserved) -{ - switch (fdwReason) { - case DLL_PROCESS_ATTACH: - CAIRO_MUTEX_INITIALIZE (); - break; - - case DLL_PROCESS_DETACH: - CAIRO_MUTEX_FINALIZE (); - break; - } - - return TRUE; -} - -#endif - diff --git a/gfx/cairo/cairo/src/cairo-xcb-surface.c b/gfx/cairo/cairo/src/cairo-xcb-surface.c index f92904090b1a..08979611909a 100644 --- a/gfx/cairo/cairo/src/cairo-xcb-surface.c +++ b/gfx/cairo/cairo/src/cairo-xcb-surface.c @@ -1577,39 +1577,6 @@ _cairo_xcb_surface_show_glyphs (void *abstract_dst, int num_glyphs, cairo_scaled_font_t *scaled_font); -static cairo_bool_t -_cairo_xcb_surface_is_similar (void *surface_a, - void *surface_b, - cairo_content_t content) -{ - cairo_xcb_surface_t *a = surface_a; - cairo_xcb_surface_t *b = surface_b; - xcb_render_pictforminfo_t *xrender_format; - - if (! _cairo_xcb_surface_same_screen (a, b)) - return FALSE; - - /* now check that the target is a similar format */ - xrender_format = _CAIRO_FORMAT_TO_XRENDER_FORMAT (b->dpy, - _cairo_format_from_content (content)); - - return a->xrender_format.id == xrender_format->id; -} - -static cairo_status_t -_cairo_xcb_surface_reset (void *abstract_surface) -{ - cairo_xcb_surface_t *surface = abstract_surface; - cairo_status_t status; - - status = _cairo_xcb_surface_set_clip_region (surface, NULL); - if (status) - return status; - - return CAIRO_STATUS_SUCCESS; -} - - /* XXX: move this to the bottom of the file, XCB and Xlib */ static const cairo_surface_backend_t cairo_xcb_surface_backend = { @@ -1641,11 +1608,7 @@ static const cairo_surface_backend_t cairo_xcb_surface_backend = { NULL, /* stroke */ NULL, /* fill */ _cairo_xcb_surface_show_glyphs, - NULL, /* snapshot */ - - _cairo_xcb_surface_is_similar, - - _cairo_xcb_surface_reset + NULL /* snapshot */ }; /** @@ -2381,8 +2344,7 @@ _cairo_xcb_surface_show_glyphs (void *abstract_dst, * so PictOpClear was never used with CompositeText before. */ if (op == CAIRO_OPERATOR_CLEAR) { - _cairo_pattern_init_solid (&solid_pattern.solid, CAIRO_COLOR_WHITE, - CAIRO_CONTENT_COLOR); + _cairo_pattern_init_solid (&solid_pattern.solid, CAIRO_COLOR_WHITE); src_pattern = &solid_pattern.base; op = CAIRO_OPERATOR_DEST_OUT; } diff --git a/gfx/cairo/cairo/src/cairo-xlib-display.c b/gfx/cairo/cairo/src/cairo-xlib-display.c deleted file mode 100644 index c7c3c43cd5a0..000000000000 --- a/gfx/cairo/cairo/src/cairo-xlib-display.c +++ /dev/null @@ -1,453 +0,0 @@ -/* Cairo - a vector graphics library with display and print output - * - * Copyright © 2007 Chris Wilson - * - * 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 Chris Wilson. - * - */ - -#include "cairoint.h" - -#include "cairo-xlib-private.h" - -#include - -#include /* For XESetCloseDisplay */ -#include - -typedef int (*cairo_xlib_error_func_t) (Display *display, - XErrorEvent *event); - -struct _cairo_xlib_job { - cairo_xlib_job_t *next; - enum { - RESOURCE, - WORK - } type; - union { - struct { - cairo_xlib_notify_resource_func notify; - XID xid; - } resource; - struct { - cairo_xlib_notify_func notify; - void *data; - void (*destroy) (void *); - } work; - } func; -}; - -static cairo_xlib_display_t *_cairo_xlib_display_list; - -static void -_cairo_xlib_call_close_display_hooks (cairo_xlib_display_t *display) -{ - cairo_xlib_screen_info_t *screen; - cairo_xlib_hook_t *hooks, *list; - - /* call all registered shutdown routines */ - CAIRO_MUTEX_LOCK (display->mutex); - - for (screen = display->screens; screen != NULL; screen = screen->next) - _cairo_xlib_screen_info_close_display (screen); - - hooks = display->close_display_hooks; - while (hooks != NULL) { - display->close_display_hooks = NULL; - CAIRO_MUTEX_UNLOCK (display->mutex); - - list = hooks; - do { - cairo_xlib_hook_t *hook = list; - list = hook->next; - - hook->func (display->display, hook->data); - } while (list != NULL); - - CAIRO_MUTEX_LOCK (display->mutex); - do { - cairo_xlib_hook_t *hook = hooks; - hooks = hook->next; - - _cairo_freelist_free (&display->hook_freelist, hook); - } while (hooks != NULL); - - hooks = display->close_display_hooks; - } - display->closed = TRUE; - - CAIRO_MUTEX_UNLOCK (display->mutex); -} - -static void -_cairo_xlib_display_discard_screens (cairo_xlib_display_t *display) -{ - cairo_xlib_screen_info_t *screens; - - CAIRO_MUTEX_LOCK (display->mutex); - screens = display->screens; - display->screens = NULL; - CAIRO_MUTEX_UNLOCK (display->mutex); - - while (screens != NULL) { - cairo_xlib_screen_info_t *screen = screens; - screens = screen->next; - - _cairo_xlib_screen_info_destroy (screen); - } -} - -cairo_xlib_display_t * -_cairo_xlib_display_reference (cairo_xlib_display_t *display) -{ - if (display == NULL) - return NULL; - - /* use our mutex until we get a real atomic inc */ - CAIRO_MUTEX_LOCK (display->mutex); - - assert (display->ref_count > 0); - display->ref_count++; - - CAIRO_MUTEX_UNLOCK (display->mutex); - - return display; -} - -void -_cairo_xlib_display_destroy (cairo_xlib_display_t *display) -{ - if (display == NULL) - return; - - CAIRO_MUTEX_LOCK (display->mutex); - assert (display->ref_count > 0); - if (--display->ref_count == 0) { - /* destroy all outstanding notifies */ - while (display->workqueue != NULL) { - cairo_xlib_job_t *job = display->workqueue; - display->workqueue = job->next; - - if (job->type == WORK && job->func.work.destroy != NULL) - job->func.work.destroy (job->func.work.data); - - _cairo_freelist_free (&display->wq_freelist, job); - } - _cairo_freelist_fini (&display->wq_freelist); - _cairo_freelist_fini (&display->hook_freelist); - - CAIRO_MUTEX_UNLOCK (display->mutex); - - free (display); - } else - CAIRO_MUTEX_UNLOCK (display->mutex); -} - -static int -_noop_error_handler (Display *display, - XErrorEvent *event) -{ - return False; /* return value is ignored */ -} -static int -_cairo_xlib_close_display (Display *dpy, XExtCodes *codes) -{ - cairo_xlib_display_t *display, **prev, *next; - - /* - * Unhook from the global list - */ - CAIRO_MUTEX_LOCK (_cairo_xlib_display_mutex); - prev = &_cairo_xlib_display_list; - for (display = _cairo_xlib_display_list; display; display = next) { - next = display->next; - if (display->display == dpy) { - cairo_xlib_error_func_t old_handler; - - /* drop the list mutex whilst triggering the hooks */ - CAIRO_MUTEX_UNLOCK (_cairo_xlib_display_mutex); - - /* protect the notifies from triggering XErrors */ - XSync (dpy, False); - old_handler = XSetErrorHandler (_noop_error_handler); - - _cairo_xlib_display_notify (display); - _cairo_xlib_call_close_display_hooks (display); - _cairo_xlib_display_discard_screens (display); - - /* catch any that arrived before marking the display as closed */ - _cairo_xlib_display_notify (display); - - XSync (dpy, False); - XSetErrorHandler (old_handler); - - CAIRO_MUTEX_LOCK (_cairo_xlib_display_mutex); - _cairo_xlib_display_destroy (display); - *prev = next; - break; - } else - prev = &display->next; - } - CAIRO_MUTEX_UNLOCK (_cairo_xlib_display_mutex); - - /* Return value in accordance with requirements of - * XESetCloseDisplay */ - return 0; -} - -cairo_xlib_display_t * -_cairo_xlib_display_get (Display *dpy) -{ - cairo_xlib_display_t *display; - cairo_xlib_display_t **prev; - XExtCodes *codes; - - /* There is an apparent deadlock between this mutex and the - * mutex for the display, but it's actually safe. For the - * app to call XCloseDisplay() while any other thread is - * inside this function would be an error in the logic - * app, and the CloseDisplay hook is the only other place we - * acquire this mutex. - */ - CAIRO_MUTEX_LOCK (_cairo_xlib_display_mutex); - - for (prev = &_cairo_xlib_display_list; (display = *prev); prev = &(*prev)->next) - { - if (display->display == dpy) { - /* - * MRU the list - */ - if (prev != &_cairo_xlib_display_list) { - *prev = display->next; - display->next = _cairo_xlib_display_list; - _cairo_xlib_display_list = display; - } - break; - } - } - - if (display != NULL) { - display = _cairo_xlib_display_reference (display); - goto UNLOCK; - } - - display = malloc (sizeof (cairo_xlib_display_t)); - if (display == NULL) - goto UNLOCK; - - codes = XAddExtension (dpy); - if (codes == NULL) { - free (display); - display = NULL; - goto UNLOCK; - } - - XESetCloseDisplay (dpy, codes->extension, _cairo_xlib_close_display); - - _cairo_freelist_init (&display->wq_freelist, sizeof (cairo_xlib_job_t)); - _cairo_freelist_init (&display->hook_freelist, sizeof (cairo_xlib_hook_t)); - - display->ref_count = 2; /* add one for the CloseDisplay */ - CAIRO_MUTEX_INIT (display->mutex); - display->display = dpy; - display->screens = NULL; - display->workqueue = NULL; - display->close_display_hooks = NULL; - display->closed = FALSE; - - display->next = _cairo_xlib_display_list; - _cairo_xlib_display_list = display; - -UNLOCK: - CAIRO_MUTEX_UNLOCK (_cairo_xlib_display_mutex); - return display; -} - -cairo_bool_t -_cairo_xlib_add_close_display_hook (Display *dpy, void (*func) (Display *, void *), void *data, const void *key) -{ - cairo_xlib_display_t *display; - cairo_xlib_hook_t *hook; - cairo_bool_t ret = FALSE; - - display = _cairo_xlib_display_get (dpy); - if (display == NULL) - return FALSE; - - CAIRO_MUTEX_LOCK (display->mutex); - if (display->closed == FALSE) { - hook = _cairo_freelist_alloc (&display->hook_freelist); - if (hook != NULL) { - hook->func = func; - hook->data = data; - hook->key = key; - - hook->next = display->close_display_hooks; - display->close_display_hooks = hook; - ret = TRUE; - } - } - CAIRO_MUTEX_UNLOCK (display->mutex); - - _cairo_xlib_display_destroy (display); - - return ret; -} - -void -_cairo_xlib_remove_close_display_hooks (Display *dpy, const void *key) -{ - cairo_xlib_display_t *display; - cairo_xlib_hook_t *hook, *next, **prev; - - display = _cairo_xlib_display_get (dpy); - if (display == NULL) - return; - - CAIRO_MUTEX_LOCK (display->mutex); - prev = &display->close_display_hooks; - for (hook = display->close_display_hooks; hook != NULL; hook = next) { - next = hook->next; - if (hook->key == key) { - *prev = hook->next; - _cairo_freelist_free (&display->hook_freelist, hook); - } else - prev = &hook->next; - } - *prev = NULL; - CAIRO_MUTEX_UNLOCK (display->mutex); - - _cairo_xlib_display_destroy (display); -} - -cairo_status_t -_cairo_xlib_display_queue_resource (cairo_xlib_display_t *display, - cairo_xlib_notify_resource_func notify, - XID xid) -{ - cairo_xlib_job_t *job; - cairo_status_t status = CAIRO_STATUS_NO_MEMORY; - - CAIRO_MUTEX_LOCK (display->mutex); - if (display->closed == FALSE) { - job = _cairo_freelist_alloc (&display->wq_freelist); - if (job != NULL) { - job->type = RESOURCE; - job->func.resource.xid = xid; - job->func.resource.notify = notify; - - job->next = display->workqueue; - display->workqueue = job; - - status = CAIRO_STATUS_SUCCESS; - } - } - CAIRO_MUTEX_UNLOCK (display->mutex); - - return status; -} - -cairo_status_t -_cairo_xlib_display_queue_work (cairo_xlib_display_t *display, - cairo_xlib_notify_func notify, - void *data, - void (*destroy) (void *)) -{ - cairo_xlib_job_t *job; - cairo_status_t status = CAIRO_STATUS_NO_MEMORY; - - CAIRO_MUTEX_LOCK (display->mutex); - if (display->closed == FALSE) { - job = _cairo_freelist_alloc (&display->wq_freelist); - if (job != NULL) { - job->type = WORK; - job->func.work.data = data; - job->func.work.notify = notify; - job->func.work.destroy = destroy; - - job->next = display->workqueue; - display->workqueue = job; - - status = CAIRO_STATUS_SUCCESS; - } - } - CAIRO_MUTEX_UNLOCK (display->mutex); - - return status; -} - -void -_cairo_xlib_display_notify (cairo_xlib_display_t *display) -{ - cairo_xlib_job_t *jobs, *job, *freelist; - Display *dpy = display->display; - - CAIRO_MUTEX_LOCK (display->mutex); - jobs = display->workqueue; - while (jobs != NULL) { - display->workqueue = NULL; - CAIRO_MUTEX_UNLOCK (display->mutex); - - /* reverse the list to obtain FIFO order */ - job = NULL; - do { - cairo_xlib_job_t *next = jobs->next; - jobs->next = job; - job = jobs; - jobs = next; - } while (jobs != NULL); - freelist = jobs = job; - - do { - job = jobs; - jobs = job->next; - - switch (job->type){ - case WORK: - job->func.work.notify (dpy, job->func.work.data); - if (job->func.work.destroy != NULL) - job->func.work.destroy (job->func.work.data); - break; - - case RESOURCE: - job->func.resource.notify (dpy, job->func.resource.xid); - break; - } - } while (jobs != NULL); - - CAIRO_MUTEX_LOCK (display->mutex); - do { - job = freelist; - freelist = job->next; - _cairo_freelist_free (&display->wq_freelist, job); - } while (freelist != NULL); - - jobs = display->workqueue; - } - CAIRO_MUTEX_UNLOCK (display->mutex); -} diff --git a/gfx/cairo/cairo/src/cairo-xlib-private.h b/gfx/cairo/cairo/src/cairo-xlib-private.h index 6157775a4ecc..5dd91b0ac97b 100644 --- a/gfx/cairo/cairo/src/cairo-xlib-private.h +++ b/gfx/cairo/cairo/src/cairo-xlib-private.h @@ -35,97 +35,43 @@ #include "cairoint.h" #include "cairo-xlib.h" -#include "cairo-freelist-private.h" -typedef struct _cairo_xlib_display cairo_xlib_display_t; +typedef struct _cairo_xlib_screen_info cairo_xlib_screen_info_t; typedef struct _cairo_xlib_hook cairo_xlib_hook_t; -typedef struct _cairo_xlib_job cairo_xlib_job_t; -typedef void (*cairo_xlib_notify_func) (Display *, void *); -typedef void (*cairo_xlib_notify_resource_func) (Display *, XID); struct _cairo_xlib_hook { cairo_xlib_hook_t *next; void (*func) (Display *display, void *data); void *data; - const void *key; -}; - -struct _cairo_xlib_display { - cairo_xlib_display_t *next; - unsigned int ref_count; - cairo_mutex_t mutex; - - Display *display; - cairo_xlib_screen_info_t *screens; - - cairo_xlib_job_t *workqueue; - cairo_freelist_t wq_freelist; - - cairo_freelist_t hook_freelist; - cairo_xlib_hook_t *close_display_hooks; - unsigned int closed :1; + void *key; }; struct _cairo_xlib_screen_info { cairo_xlib_screen_info_t *next; - unsigned int ref_count; - cairo_xlib_display_t *display; + Display *display; Screen *screen; cairo_bool_t has_render; cairo_font_options_t font_options; - GC gc[9]; - unsigned int gc_needs_clip_reset; + cairo_xlib_hook_t *close_display_hooks; }; -cairo_private cairo_xlib_display_t * -_cairo_xlib_display_get (Display *display); - -cairo_private cairo_xlib_display_t * -_cairo_xlib_display_reference (cairo_xlib_display_t *info); -cairo_private void -_cairo_xlib_display_destroy (cairo_xlib_display_t *info); - -cairo_private cairo_bool_t -_cairo_xlib_add_close_display_hook (Display *display, void (*func) (Display *, void *), void *data, const void *key); -cairo_private void -_cairo_xlib_remove_close_display_hooks (Display *display, const void *key); - -cairo_private cairo_status_t -_cairo_xlib_display_queue_work (cairo_xlib_display_t *display, - cairo_xlib_notify_func notify, - void *data, - void (*destroy)(void *)); -cairo_private cairo_status_t -_cairo_xlib_display_queue_resource (cairo_xlib_display_t *display, - cairo_xlib_notify_resource_func notify, - XID resource); -cairo_private void -_cairo_xlib_display_notify (cairo_xlib_display_t *display); - cairo_private cairo_xlib_screen_info_t * _cairo_xlib_screen_info_get (Display *display, Screen *screen); -cairo_private cairo_xlib_screen_info_t * -_cairo_xlib_screen_info_reference (cairo_xlib_screen_info_t *info); +cairo_private cairo_bool_t +_cairo_xlib_add_close_display_hook (Display *display, void (*func) (Display *, void *), void *data, void *key); cairo_private void -_cairo_xlib_screen_info_destroy (cairo_xlib_screen_info_t *info); - -cairo_private void -_cairo_xlib_screen_info_close_display (cairo_xlib_screen_info_t *info); - -cairo_private GC -_cairo_xlib_screen_get_gc (cairo_xlib_screen_info_t *info, int depth); -cairo_private cairo_status_t -_cairo_xlib_screen_put_gc (cairo_xlib_screen_info_t *info, int depth, GC gc, cairo_bool_t reset_clip); +_cairo_xlib_remove_close_display_hook (Display *display, void *key); #if CAIRO_HAS_XLIB_XRENDER_SURFACE #include "cairo-xlib-xrender.h" +#ifdef MOZILLA_CAIRO_NOT_DEFINED slim_hidden_proto (cairo_xlib_surface_create_with_xrender_format); - +#endif #endif #endif /* CAIRO_XLIB_PRIVATE_H */ diff --git a/gfx/cairo/cairo/src/cairo-xlib-screen.c b/gfx/cairo/cairo/src/cairo-xlib-screen.c index 2e8c913d36bf..d3707414499d 100644 --- a/gfx/cairo/cairo/src/cairo-xlib-screen.c +++ b/gfx/cairo/cairo/src/cairo-xlib-screen.c @@ -51,13 +51,14 @@ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ - -#include "cairoint.h" +#include +#include #include "cairo-xlib-private.h" #include +#include /* For XESetCloseDisplay */ #include static int @@ -132,7 +133,7 @@ get_integer_default (Display *dpy, #endif static void -_cairo_xlib_init_screen_font_options (Display *dpy, cairo_xlib_screen_info_t *info) +_cairo_xlib_init_screen_font_options (cairo_xlib_screen_info_t *info) { cairo_bool_t xft_hinting; cairo_bool_t xft_antialias; @@ -142,23 +143,23 @@ _cairo_xlib_init_screen_font_options (Display *dpy, cairo_xlib_screen_info_t *in cairo_subpixel_order_t subpixel_order; cairo_hint_style_t hint_style; - if (!get_boolean_default (dpy, "antialias", &xft_antialias)) + if (!get_boolean_default (info->display, "antialias", &xft_antialias)) xft_antialias = TRUE; - if (!get_boolean_default (dpy, "hinting", &xft_hinting)) + if (!get_boolean_default (info->display, "hinting", &xft_hinting)) xft_hinting = TRUE; - if (!get_integer_default (dpy, "hintstyle", &xft_hintstyle)) + if (!get_integer_default (info->display, "hintstyle", &xft_hintstyle)) xft_hintstyle = FC_HINT_FULL; - if (!get_integer_default (dpy, "rgba", &xft_rgba)) + if (!get_integer_default (info->display, "rgba", &xft_rgba)) { xft_rgba = FC_RGBA_UNKNOWN; #if RENDER_MAJOR > 0 || RENDER_MINOR >= 6 if (info->has_render) { - int render_order = XRenderQuerySubpixelOrder (dpy, + int render_order = XRenderQuerySubpixelOrder (info->display, XScreenNumberOfScreen (info->screen)); switch (render_order) @@ -236,183 +237,235 @@ _cairo_xlib_init_screen_font_options (Display *dpy, cairo_xlib_screen_info_t *in antialias = CAIRO_ANTIALIAS_NONE; } + _cairo_font_options_init_default (&info->font_options); cairo_font_options_set_hint_style (&info->font_options, hint_style); cairo_font_options_set_antialias (&info->font_options, antialias); cairo_font_options_set_subpixel_order (&info->font_options, subpixel_order); - cairo_font_options_set_hint_metrics (&info->font_options, CAIRO_HINT_METRICS_ON); } -cairo_xlib_screen_info_t * -_cairo_xlib_screen_info_reference (cairo_xlib_screen_info_t *info) -{ - if (info == NULL) - return NULL; +CAIRO_MUTEX_DECLARE(_xlib_screen_mutex); - assert (info->ref_count > 0); - info->ref_count++; - - return info; -} - -void -_cairo_xlib_screen_info_close_display (cairo_xlib_screen_info_t *info) -{ - int i; - - for (i = 0; i < ARRAY_LENGTH (info->gc); i++) { - if (info->gc[i] != NULL) { - XFreeGC (info->display->display, info->gc[i]); - info->gc[i] = NULL; - } - } -} - -void -_cairo_xlib_screen_info_destroy (cairo_xlib_screen_info_t *info) -{ - cairo_xlib_screen_info_t **prev; - cairo_xlib_screen_info_t *list; - - if (info == NULL) - return; - - assert (info->ref_count > 0); - if (--info->ref_count) - return; - - CAIRO_MUTEX_LOCK (info->display->mutex); - for (prev = &info->display->screens; (list = *prev); prev = &list->next) { - if (list == info) { - *prev = info->next; - break; - } - } - CAIRO_MUTEX_UNLOCK (info->display->mutex); - - _cairo_xlib_screen_info_close_display (info); - - _cairo_xlib_display_destroy (info->display); - - free (info); -} - -cairo_xlib_screen_info_t * -_cairo_xlib_screen_info_get (Display *dpy, Screen *screen) -{ - cairo_xlib_display_t *display; - cairo_xlib_screen_info_t *info = NULL, **prev; - - display = _cairo_xlib_display_get (dpy); - if (display == NULL) - return NULL; - - CAIRO_MUTEX_LOCK (display->mutex); - if (display->closed) { - CAIRO_MUTEX_UNLOCK (display->mutex); - goto DONE; - } - - for (prev = &display->screens; (info = *prev); prev = &(*prev)->next) { - if (info->screen == screen) { - /* - * MRU the list - */ - if (prev != &display->screens) { - *prev = info->next; - info->next = display->screens; - display->screens = info; - } - break; - } - } - CAIRO_MUTEX_UNLOCK (display->mutex); - - if (info != NULL) { - info = _cairo_xlib_screen_info_reference (info); - } else { - info = malloc (sizeof (cairo_xlib_screen_info_t)); - if (info != NULL) { - info->ref_count = 2; /* Add one for display cache */ - info->display = _cairo_xlib_display_reference (display); - info->screen = screen; - info->has_render = FALSE; - _cairo_font_options_init_default (&info->font_options); - memset (info->gc, 0, sizeof (info->gc)); - info->gc_needs_clip_reset = 0; - - if (screen) { - int event_base, error_base; - info->has_render = (XRenderQueryExtension (dpy, &event_base, &error_base) && - (XRenderFindVisualFormat (dpy, DefaultVisual (dpy, DefaultScreen (dpy))) != 0)); - _cairo_xlib_init_screen_font_options (dpy, info); - } - - CAIRO_MUTEX_LOCK (display->mutex); - info->next = display->screens; - display->screens = info; - CAIRO_MUTEX_UNLOCK (display->mutex); - } - } - -DONE: - _cairo_xlib_display_destroy (display); - - return info; -} +static cairo_xlib_screen_info_t *_cairo_xlib_screen_list = NULL; static int -depth_to_index (int depth) +_cairo_xlib_close_display (Display *dpy, XExtCodes *codes) { - switch(depth){ - case 1: return 1; - case 8: return 2; - case 12: return 3; - case 15: return 4; - case 16: return 5; - case 24: return 6; - case 30: return 7; - case 32: return 8; + cairo_xlib_screen_info_t *info, **prev, *next; + + /* + * Unhook from the global list + */ + CAIRO_MUTEX_LOCK (_xlib_screen_mutex); + + prev = &_cairo_xlib_screen_list; + for (info = _cairo_xlib_screen_list; info; info = next) { + next = info->next; + if (info->display == dpy) { + *prev = next; + /* call all registered shutdown routines */ + while (info->close_display_hooks) { + cairo_xlib_hook_t *hook = info->close_display_hooks; + info->close_display_hooks = hook->next; + + hook->func (dpy, hook->data); + + free (hook); + } + free (info); + } else { + prev = &info->next; + } } + *prev = NULL; + CAIRO_MUTEX_UNLOCK (_xlib_screen_mutex); + + /* Return value in accordance with requirements of + * XESetCloseDisplay */ return 0; } -GC -_cairo_xlib_screen_get_gc (cairo_xlib_screen_info_t *info, int depth) +static void +_cairo_xlib_screen_info_reset (void) { - GC gc; + cairo_xlib_screen_info_t *info, *next; - depth = depth_to_index (depth); + /* + * Delete everything in the list. + */ + CAIRO_MUTEX_LOCK (_xlib_screen_mutex); - gc = info->gc[depth]; - info->gc[depth] = NULL; - - if (info->gc_needs_clip_reset & (1 << depth)) { - XSetClipMask(info->display->display, gc, None); - info->gc_needs_clip_reset &= ~(1 << depth); + for (info = _cairo_xlib_screen_list; info; info = next) { + next = info->next; + while (info->close_display_hooks) { + cairo_xlib_hook_t *hook = info->close_display_hooks; + info->close_display_hooks = hook->next; + free (hook); + } + free (info); } - return gc; + _cairo_xlib_screen_list = NULL; + + CAIRO_MUTEX_UNLOCK (_xlib_screen_mutex); + } -cairo_status_t -_cairo_xlib_screen_put_gc (cairo_xlib_screen_info_t *info, int depth, GC gc, cairo_bool_t reset_clip) +static cairo_xlib_screen_info_t * +_cairo_xlib_screen_info_get_unlocked (Display *dpy, Screen *screen) { - cairo_status_t status = CAIRO_STATUS_SUCCESS; + cairo_xlib_screen_info_t *info; + cairo_xlib_screen_info_t **prev; + int event_base, error_base; + XExtCodes *codes; + cairo_bool_t seen_display = FALSE; - depth = depth_to_index (depth); - - if (info->gc[depth] != NULL) { - status = _cairo_xlib_display_queue_work (info->display, - (cairo_xlib_notify_func) XFreeGC, - info->gc[depth], - NULL); + for (prev = &_cairo_xlib_screen_list; (info = *prev); prev = &(*prev)->next) + { + if (info->display == dpy) { + seen_display = TRUE; + if (info->screen == screen || screen == NULL) { + /* + * MRU the list + */ + if (prev != &_cairo_xlib_screen_list) { + *prev = info->next; + info->next = _cairo_xlib_screen_list; + _cairo_xlib_screen_list = info; + } + break; + } + } } - info->gc[depth] = gc; - if (reset_clip) - info->gc_needs_clip_reset |= 1 << depth; - else - info->gc_needs_clip_reset &= ~(1 << depth); + if (info) + return info; - return status; + if (screen == NULL) + return NULL; + + info = malloc (sizeof (cairo_xlib_screen_info_t)); + if (!info) + return NULL; + + if (!seen_display) { + codes = XAddExtension (dpy); + if (!codes) { + free (info); + return NULL; + } + + XESetCloseDisplay (dpy, codes->extension, _cairo_xlib_close_display); + } + + info->display = dpy; + info->screen = screen; + info->has_render = (XRenderQueryExtension (dpy, &event_base, &error_base) && + (XRenderFindVisualFormat (dpy, DefaultVisual (dpy, DefaultScreen (dpy))) != 0)); + + info->close_display_hooks = NULL; + + _cairo_xlib_init_screen_font_options (info); + + info->next = _cairo_xlib_screen_list; + _cairo_xlib_screen_list = info; + + return info; +} +cairo_xlib_screen_info_t * +_cairo_xlib_screen_info_get (Display *dpy, Screen *screen) +{ + cairo_xlib_screen_info_t *info; + + /* There is an apparent deadlock between this mutex and the + * mutex for the display, but it's actually safe. For the + * app to call XCloseDisplay() while any other thread is + * inside this function would be an error in the logic + * app, and the CloseDisplay hook is the only other place we + * acquire this mutex. + */ + CAIRO_MUTEX_LOCK (_xlib_screen_mutex); + + info = _cairo_xlib_screen_info_get_unlocked (dpy, screen); + + CAIRO_MUTEX_UNLOCK (_xlib_screen_mutex); + + return info; +} + +cairo_bool_t +_cairo_xlib_add_close_display_hook (Display *dpy, void (*func) (Display *, void *), void *data, void *key) +{ + cairo_xlib_screen_info_t *info; + cairo_xlib_hook_t *hook; + cairo_xlib_hook_t **prev; + cairo_bool_t success = FALSE; + + CAIRO_MUTEX_LOCK (_xlib_screen_mutex); + + info = _cairo_xlib_screen_info_get_unlocked (dpy, NULL); + if (!info) + goto unlock; + + for (prev = &info->close_display_hooks; (hook = *prev); prev = &hook->next) + { + if (hook->key == key) { + /* + * MRU the list + */ + if (prev != &info->close_display_hooks) { + *prev = hook->next; + hook->next = info->close_display_hooks; + info->close_display_hooks = hook; + } + break; + } + } + + if (!hook) { + hook = malloc (sizeof (cairo_xlib_hook_t)); + if (!hook) + goto unlock; + hook->func = func; + hook->data = data; + hook->key = key; + hook->next = info->close_display_hooks; + info->close_display_hooks = hook; + } + + success = TRUE; + unlock: + CAIRO_MUTEX_UNLOCK (_xlib_screen_mutex); + return success; +} + +void +_cairo_xlib_remove_close_display_hook (Display *dpy, void *key) +{ + cairo_xlib_screen_info_t *info; + cairo_xlib_hook_t *hook; + cairo_xlib_hook_t **prev; + + CAIRO_MUTEX_LOCK (_xlib_screen_mutex); + + info = _cairo_xlib_screen_info_get_unlocked (dpy, NULL); + if (!info) + goto unlock; + + for (prev = &info->close_display_hooks; (hook = *prev); prev = &hook->next) + { + if (hook->key == key) { + *prev = hook->next; + free (hook); + break; + } + } + +unlock: + CAIRO_MUTEX_UNLOCK (_xlib_screen_mutex); +} + +void +_cairo_xlib_screen_reset_static_data (void) +{ + _cairo_xlib_screen_info_reset (); } diff --git a/gfx/cairo/cairo/src/cairo-xlib-surface-private.h b/gfx/cairo/cairo/src/cairo-xlib-surface-private.h deleted file mode 100644 index 3bbf43e23593..000000000000 --- a/gfx/cairo/cairo/src/cairo-xlib-surface-private.h +++ /dev/null @@ -1,100 +0,0 @@ -/* Cairo - a vector graphics library with display and print output - * - * 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 Red Hat, Inc. - */ - -#ifndef CAIRO_XLIB_SURFACE_PRIVATE_H -#define CAIRO_XLIB_SURFACE_PRIVATE_H - -#include "cairo-xlib.h" - -#include "cairo-surface-private.h" - -typedef struct _cairo_xlib_surface cairo_xlib_surface_t; - -struct _cairo_xlib_surface { - cairo_surface_t base; - - Display *dpy; - cairo_xlib_screen_info_t *screen_info; - - GC gc; - Drawable drawable; - Screen *screen; - cairo_bool_t owns_pixmap; - Visual *visual; - - int use_pixmap; - - int render_major; - int render_minor; - - /* TRUE if the server has a bug with repeating pictures - * - * https://bugs.freedesktop.org/show_bug.cgi?id=3566 - * - * We can't test for this because it depends on whether the - * picture is in video memory or not. - * - * We also use this variable as a guard against a second - * independent bug with transformed repeating pictures: - * - * http://lists.freedesktop.org/archives/cairo/2004-September/001839.html - * - * Both are fixed in xorg >= 6.9 and hopefully in > 6.8.2, so - * we can reuse the test for now. - */ - cairo_bool_t buggy_repeat; - - int width; - int height; - int depth; - - Picture dst_picture, src_picture; - - unsigned int clip_dirty; - cairo_bool_t have_clip_rects; - XRectangle embedded_clip_rects[4]; - XRectangle *clip_rects; - int num_clip_rects; - - XRenderPictFormat *xrender_format; - cairo_filter_t filter; - int repeat; - XTransform xtransform; -}; - -enum { - CAIRO_XLIB_SURFACE_CLIP_DIRTY_GC = 0x01, - CAIRO_XLIB_SURFACE_CLIP_DIRTY_PICTURE = 0x02, - CAIRO_XLIB_SURFACE_CLIP_DIRTY_ALL = 0x03 -}; - -#endif /* CAIRO_XLIB_SURFACE_PRIVATE_H */ diff --git a/gfx/cairo/cairo/src/cairo-xlib-surface.c b/gfx/cairo/cairo/src/cairo-xlib-surface.c index 39175bdf1e0e..be285cd46a92 100644 --- a/gfx/cairo/cairo/src/cairo-xlib-surface.c +++ b/gfx/cairo/cairo/src/cairo-xlib-surface.c @@ -39,8 +39,8 @@ #include "cairoint.h" #include "cairo-xlib.h" #include "cairo-xlib-xrender.h" +#include "cairo-xlib-test.h" #include "cairo-xlib-private.h" -#include "cairo-xlib-surface-private.h" #include "cairo-clip-private.h" #include #include @@ -49,7 +49,9 @@ typedef int (*cairo_xlib_error_func_t) (Display *display, XErrorEvent *event); -static cairo_status_t +typedef struct _cairo_xlib_surface cairo_xlib_surface_t; + +static void _cairo_xlib_surface_ensure_gc (cairo_xlib_surface_t *surface); static void @@ -80,11 +82,52 @@ _cairo_xlib_surface_show_glyphs (void *abstract_dst, #define CAIRO_ASSUME_PIXMAP 20 -static const XTransform identity = { { - { 1 << 16, 0x00000, 0x00000 }, - { 0x00000, 1 << 16, 0x00000 }, - { 0x00000, 0x00000, 1 << 16 }, -} }; +struct _cairo_xlib_surface { + cairo_surface_t base; + + Display *dpy; + cairo_xlib_screen_info_t *screen_info; + + GC gc; + Drawable drawable; + Screen *screen; + cairo_bool_t owns_pixmap; + Visual *visual; + + int use_pixmap; + + int render_major; + int render_minor; + + /* TRUE if the server has a bug with repeating pictures + * + * https://bugs.freedesktop.org/show_bug.cgi?id=3566 + * + * We can't test for this because it depends on whether the + * picture is in video memory or not. + * + * We also use this variable as a guard against a second + * independent bug with transformed repeating pictures: + * + * http://lists.freedesktop.org/archives/cairo/2004-September/001839.html + * + * Both are fixed in xorg >= 6.9 and hopefully in > 6.8.2, so + * we can reuse the test for now. + */ + cairo_bool_t buggy_repeat; + + int width; + int height; + int depth; + + Picture dst_picture, src_picture; + + cairo_bool_t have_clip_rects; + XRectangle *clip_rects; + int num_clip_rects; + + XRenderPictFormat *xrender_format; +}; #define CAIRO_SURFACE_RENDER_AT_LEAST(surface, major, minor) \ (((surface)->render_major > major) || \ @@ -108,6 +151,25 @@ static const XTransform identity = { { #define CAIRO_SURFACE_RENDER_HAS_PICTURE_TRANSFORM(surface) CAIRO_SURFACE_RENDER_AT_LEAST((surface), 0, 6) #define CAIRO_SURFACE_RENDER_HAS_FILTERS(surface) CAIRO_SURFACE_RENDER_AT_LEAST((surface), 0, 6) +static cairo_bool_t cairo_xlib_render_disabled = FALSE; + +/** + * _cairo_xlib_test_disable_render: + * + * Disables the use of the RENDER extension. + * + * + * This function is only intended for internal + * testing use within the cairo distribution. It is not installed in + * any public header file. + * + **/ +void +_cairo_xlib_test_disable_render (void) +{ + cairo_xlib_render_disabled = TRUE; +} + static int _CAIRO_FORMAT_DEPTH (cairo_format_t format) { @@ -174,7 +236,6 @@ _cairo_xlib_surface_create_similar_with_format (void *abstract_src, xrender_format, width, height); if (surface->base.status != CAIRO_STATUS_SUCCESS) { - XFreePixmap (dpy, pix); _cairo_error (CAIRO_STATUS_NO_MEMORY); return (cairo_surface_t*) &_cairo_surface_nil; } @@ -220,8 +281,6 @@ _cairo_xlib_surface_create_similar (void *abstract_src, cairo_xlib_surface_t *surface; Pixmap pix; - _cairo_xlib_display_notify (src->screen_info->display); - /* Start by examining the surface's XRenderFormat, or if it * doesn't have one, then look one up through its visual (in the * case of a bitmap, it won't even have that). */ @@ -254,7 +313,6 @@ _cairo_xlib_surface_create_similar (void *abstract_src, xrender_format, width, height); if (surface->base.status != CAIRO_STATUS_SUCCESS) { - XFreePixmap (src->dpy, pix); _cairo_error (CAIRO_STATUS_NO_MEMORY); return (cairo_surface_t*) &_cairo_surface_nil; } @@ -268,73 +326,24 @@ static cairo_status_t _cairo_xlib_surface_finish (void *abstract_surface) { cairo_xlib_surface_t *surface = abstract_surface; - cairo_xlib_display_t *display = surface->screen_info ? - surface->screen_info->display : - NULL; - cairo_status_t status = CAIRO_STATUS_SUCCESS; + if (surface->dst_picture != None) + XRenderFreePicture (surface->dpy, surface->dst_picture); - if (surface->owns_pixmap) { - cairo_status_t status2; + if (surface->src_picture != None) + XRenderFreePicture (surface->dpy, surface->src_picture); - if (surface->dst_picture != None) { - status2 = _cairo_xlib_display_queue_resource (display, - XRenderFreePicture, - surface->dst_picture); - if (status2 == CAIRO_STATUS_SUCCESS) - surface->dst_picture = None; - else if (status == CAIRO_STATUS_SUCCESS) - status = status2; - } + if (surface->owns_pixmap) + XFreePixmap (surface->dpy, surface->drawable); - if (surface->src_picture != None) { - status2 = _cairo_xlib_display_queue_resource (display, - XRenderFreePicture, - surface->src_picture); - if (status2 == CAIRO_STATUS_SUCCESS) - surface->src_picture = None; - else if (status == CAIRO_STATUS_SUCCESS) - status = status2; - } + if (surface->gc != NULL) + XFreeGC (surface->dpy, surface->gc); - status2 = _cairo_xlib_display_queue_resource (display, - (cairo_xlib_notify_resource_func) XFreePixmap, - surface->drawable); - if (status2 == CAIRO_STATUS_SUCCESS) { - surface->owns_pixmap = FALSE; - surface->drawable = None; - } else if (status == CAIRO_STATUS_SUCCESS) - status = status2; - } else { - if (surface->dst_picture != None) - XRenderFreePicture (surface->dpy, surface->dst_picture); - - if (surface->src_picture != None) - XRenderFreePicture (surface->dpy, surface->src_picture); - } - - if (surface->gc != NULL) { - cairo_status_t status2; - status2 = _cairo_xlib_screen_put_gc (surface->screen_info, - surface->depth, - surface->gc, - surface->have_clip_rects); - surface->gc = NULL; - if (status == CAIRO_STATUS_SUCCESS) - status = status2; - } - - if (surface->clip_rects != surface->embedded_clip_rects) + if (surface->clip_rects != NULL) free (surface->clip_rects); - if (surface->screen_info != NULL) - _cairo_xlib_screen_info_destroy (surface->screen_info); + surface->dpy = NULL; - if (surface->dpy != NULL) { - _cairo_xlib_remove_close_display_hooks (surface->dpy, surface); - surface->dpy = NULL; - } - - return status; + return CAIRO_STATUS_SUCCESS; } static int @@ -578,27 +587,22 @@ _get_image_surface (cairo_xlib_surface_t *surface, * retry, but to keep things simple, we just create a * temporary pixmap */ - Pixmap pixmap; - cairo_status_t status = _cairo_xlib_surface_ensure_gc (surface); - if (status) - return status; - - pixmap = XCreatePixmap (surface->dpy, + Pixmap pixmap = XCreatePixmap (surface->dpy, surface->drawable, x2 - x1, y2 - y1, surface->depth); - if (pixmap) { - XCopyArea (surface->dpy, surface->drawable, pixmap, surface->gc, - x1, y1, x2 - x1, y2 - y1, 0, 0); + _cairo_xlib_surface_ensure_gc (surface); - ximage = XGetImage (surface->dpy, - pixmap, - 0, 0, - x2 - x1, y2 - y1, - AllPlanes, ZPixmap); + XCopyArea (surface->dpy, surface->drawable, pixmap, surface->gc, + x1, y1, x2 - x1, y2 - y1, 0, 0); - XFreePixmap (surface->dpy, pixmap); - } + ximage = XGetImage (surface->dpy, + pixmap, + 0, 0, + x2 - x1, y2 - y1, + AllPlanes, ZPixmap); + + XFreePixmap (surface->dpy, pixmap); } if (!ximage) return CAIRO_STATUS_NO_MEMORY; @@ -688,50 +692,30 @@ static void _cairo_xlib_surface_ensure_src_picture (cairo_xlib_surface_t *surface) { if (!surface->src_picture) - { - XRenderPictureAttributes pa; - int mask = 0; - - pa.subwindow_mode = IncludeInferiors; - mask |= CPSubwindowMode; - surface->src_picture = XRenderCreatePicture (surface->dpy, surface->drawable, surface->xrender_format, - mask, &pa); - } + 0, NULL); } static void _cairo_xlib_surface_set_picture_clip_rects (cairo_xlib_surface_t *surface) { - if (surface->have_clip_rects) { + if (surface->have_clip_rects) XRenderSetPictureClipRectangles (surface->dpy, surface->dst_picture, 0, 0, surface->clip_rects, surface->num_clip_rects); - } else { - XRenderPictureAttributes pa; - pa.clip_mask = None; - XRenderChangePicture (surface->dpy, surface->dst_picture, - CPClipMask, &pa); - } - - surface->clip_dirty &= ~CAIRO_XLIB_SURFACE_CLIP_DIRTY_PICTURE; } static void _cairo_xlib_surface_set_gc_clip_rects (cairo_xlib_surface_t *surface) { - if (surface->have_clip_rects) { + if (surface->have_clip_rects) XSetClipRectangles(surface->dpy, surface->gc, 0, 0, surface->clip_rects, surface->num_clip_rects, YXSorted); - } else - XSetClipMask (surface->dpy, surface->gc, None); - - surface->clip_dirty &= ~CAIRO_XLIB_SURFACE_CLIP_DIRTY_GC; } static void @@ -743,31 +727,22 @@ _cairo_xlib_surface_ensure_dst_picture (cairo_xlib_surface_t *surface) surface->xrender_format, 0, NULL); _cairo_xlib_surface_set_picture_clip_rects (surface); - } else if (surface->clip_dirty & CAIRO_XLIB_SURFACE_CLIP_DIRTY_PICTURE) - _cairo_xlib_surface_set_picture_clip_rects (surface); + } + } -static cairo_status_t +static void _cairo_xlib_surface_ensure_gc (cairo_xlib_surface_t *surface) { XGCValues gcv; - if (surface->gc == NULL) { - surface->gc = _cairo_xlib_screen_get_gc (surface->screen_info, - surface->depth); - if (surface->gc == NULL) { - gcv.graphics_exposures = False; - surface->gc = XCreateGC (surface->dpy, surface->drawable, - GCGraphicsExposures, &gcv); - if (!surface->gc) - return CAIRO_STATUS_NO_MEMORY; - } + if (surface->gc) + return; - _cairo_xlib_surface_set_gc_clip_rects (surface); - } else if (surface->clip_dirty & CAIRO_XLIB_SURFACE_CLIP_DIRTY_GC) - _cairo_xlib_surface_set_gc_clip_rects (surface); - - return CAIRO_STATUS_SUCCESS; + gcv.graphics_exposures = False; + surface->gc = XCreateGC (surface->dpy, surface->drawable, + GCGraphicsExposures, &gcv); + _cairo_xlib_surface_set_gc_clip_rects (surface); } static cairo_status_t @@ -783,7 +758,6 @@ _draw_image_surface (cairo_xlib_surface_t *surface, XImage ximage; unsigned int bpp, alpha, red, green, blue; int native_byte_order = _native_byte_order_lsb () ? LSBFirst : MSBFirst; - cairo_status_t status; pixman_format_get_masks (pixman_image_get_format (image->pixman_image), &bpp, &alpha, &red, &green, &blue); @@ -806,9 +780,7 @@ _draw_image_surface (cairo_xlib_surface_t *surface, XInitImage (&ximage); - status = _cairo_xlib_surface_ensure_gc (surface); - if (status) - return status; + _cairo_xlib_surface_ensure_gc (surface); XPutImage(surface->dpy, surface->drawable, surface->gc, &ximage, src_x, src_y, dst_x, dst_y, width, height); @@ -826,8 +798,6 @@ _cairo_xlib_surface_acquire_source_image (void *abstract_surf cairo_image_surface_t *image; cairo_status_t status; - _cairo_xlib_display_notify (surface->screen_info->display); - status = _get_image_surface (surface, NULL, &image, NULL); if (status) return status; @@ -857,8 +827,6 @@ _cairo_xlib_surface_acquire_dest_image (void *abstract_surfac cairo_image_surface_t *image; cairo_status_t status; - _cairo_xlib_display_notify (surface->screen_info->display); - status = _get_image_surface (surface, interest_rect, &image, image_rect_out); if (status) return status; @@ -908,9 +876,6 @@ _cairo_xlib_surface_clone_similar (void *abstract_surface, { cairo_xlib_surface_t *surface = abstract_surface; cairo_xlib_surface_t *clone; - cairo_status_t status; - - _cairo_xlib_display_notify (surface->screen_info->display); if (src->backend == surface->base.backend ) { cairo_xlib_surface_t *xlib_src = (cairo_xlib_surface_t *)src; @@ -932,12 +897,8 @@ _cairo_xlib_surface_clone_similar (void *abstract_surface, if (clone->base.status) return CAIRO_STATUS_NO_MEMORY; - status = _draw_image_surface (clone, image_src, src_x, src_y, - width, height, src_x, src_y); - if (status) { - cairo_surface_destroy (&clone->base); - return status; - } + _draw_image_surface (clone, image_src, src_x, src_y, + width, height, src_x, src_y); *clone_out = &clone->base; @@ -968,14 +929,21 @@ _cairo_xlib_surface_set_matrix (cairo_xlib_surface_t *surface, xtransform.matrix[2][1] = 0; xtransform.matrix[2][2] = _cairo_fixed_from_double (1); - if (memcmp (&xtransform, &surface->xtransform, sizeof (XTransform)) == 0) - return CAIRO_STATUS_SUCCESS; - if (!CAIRO_SURFACE_RENDER_HAS_PICTURE_TRANSFORM (surface)) + { + static const XTransform identity = { { + { 1 << 16, 0x00000, 0x00000 }, + { 0x00000, 1 << 16, 0x00000 }, + { 0x00000, 0x00000, 1 << 16 }, + } }; + + if (memcmp (&xtransform, &identity, sizeof (XTransform)) == 0) + return CAIRO_STATUS_SUCCESS; + return CAIRO_INT_STATUS_UNSUPPORTED; + } XRenderSetPictureTransform (surface->dpy, surface->src_picture, &xtransform); - surface->xtransform = xtransform; return CAIRO_STATUS_SUCCESS; } @@ -989,9 +957,6 @@ _cairo_xlib_surface_set_filter (cairo_xlib_surface_t *surface, if (!surface->src_picture) return CAIRO_STATUS_SUCCESS; - if (surface->filter == filter) - return CAIRO_STATUS_SUCCESS; - if (!CAIRO_SURFACE_RENDER_HAS_FILTERS (surface)) { if (filter == CAIRO_FILTER_FAST || filter == CAIRO_FILTER_NEAREST) @@ -1029,7 +994,6 @@ _cairo_xlib_surface_set_filter (cairo_xlib_surface_t *surface, XRenderSetPictureFilter (surface->dpy, surface->src_picture, (char *) render_filter, NULL, 0); - surface->filter = filter; return CAIRO_STATUS_SUCCESS; } @@ -1043,21 +1007,17 @@ _cairo_xlib_surface_set_repeat (cairo_xlib_surface_t *surface, int repeat) if (!surface->src_picture) return CAIRO_STATUS_SUCCESS; - if (surface->repeat == repeat) - return CAIRO_STATUS_SUCCESS; - mask = CPRepeat; pa.repeat = repeat; XRenderChangePicture (surface->dpy, surface->src_picture, mask, &pa); - surface->repeat = repeat; return CAIRO_STATUS_SUCCESS; } static cairo_int_status_t -_cairo_xlib_surface_set_attributes (cairo_xlib_surface_t *surface, - cairo_surface_attributes_t *attributes) +_cairo_xlib_surface_set_attributes (cairo_xlib_surface_t *surface, + cairo_surface_attributes_t *attributes) { cairo_int_status_t status; @@ -1069,17 +1029,15 @@ _cairo_xlib_surface_set_attributes (cairo_xlib_surface_t *surface, switch (attributes->extend) { case CAIRO_EXTEND_NONE: - status = _cairo_xlib_surface_set_repeat (surface, 0); + _cairo_xlib_surface_set_repeat (surface, 0); break; case CAIRO_EXTEND_REPEAT: - status = _cairo_xlib_surface_set_repeat (surface, 1); + _cairo_xlib_surface_set_repeat (surface, 1); break; case CAIRO_EXTEND_REFLECT: case CAIRO_EXTEND_PAD: - status = CAIRO_INT_STATUS_UNSUPPORTED; + return CAIRO_INT_STATUS_UNSUPPORTED; } - if (status) - return status; status = _cairo_xlib_surface_set_filter (surface, attributes->filter); if (status) @@ -1246,12 +1204,7 @@ _recategorize_composite_operation (cairo_xlib_surface_t *dst, { cairo_bool_t is_integer_translation = _cairo_matrix_is_integer_translation (&src_attr->matrix, NULL, NULL); - cairo_bool_t needs_alpha_composite; - - if (!_cairo_surface_is_xlib (&src->base)) - return DO_UNSUPPORTED; - - needs_alpha_composite = + cairo_bool_t needs_alpha_composite = _operator_needs_alpha_composite (op, _surface_has_alpha (src)); if (!have_mask && @@ -1344,9 +1297,6 @@ _cairo_xlib_surface_composite (cairo_operator_t op, cairo_int_status_t status; composite_operation_t operation; int itx, ity; - cairo_bool_t is_integer_translation; - - _cairo_xlib_display_notify (dst->screen_info->display); if (!CAIRO_SURFACE_RENDER_HAS_COMPOSITE (dst)) return CAIRO_INT_STATUS_UNSUPPORTED; @@ -1367,16 +1317,6 @@ _cairo_xlib_surface_composite (cairo_operator_t op, if (status) return status; - /* check for fallback surfaces that we cannot handle ... */ - if (!_cairo_surface_is_xlib (&src->base)) { - status = CAIRO_INT_STATUS_UNSUPPORTED; - goto BAIL; - } - if (mask != NULL && !_cairo_surface_is_xlib (&mask->base)) { - status = CAIRO_INT_STATUS_UNSUPPORTED; - goto BAIL; - } - operation = _recategorize_composite_operation (dst, op, src, &src_attr, mask_pattern != NULL); if (operation == DO_UNSUPPORTED) { @@ -1424,9 +1364,7 @@ _cairo_xlib_surface_composite (cairo_operator_t op, break; case DO_XCOPYAREA: - status = _cairo_xlib_surface_ensure_gc (dst); - if (status) - goto BAIL; + _cairo_xlib_surface_ensure_gc (dst); XCopyArea (dst->dpy, src->drawable, dst->drawable, @@ -1446,13 +1384,8 @@ _cairo_xlib_surface_composite (cairo_operator_t op, * _recategorize_composite_operation. */ - status = _cairo_xlib_surface_ensure_gc (dst); - if (status) - goto BAIL; - is_integer_translation = _cairo_matrix_is_integer_translation (&src_attr.matrix, - &itx, &ity); - /* This is a pre-condition for DO_XTILE. */ - assert (is_integer_translation); + _cairo_xlib_surface_ensure_gc (dst); + _cairo_matrix_is_integer_translation (&src_attr.matrix, &itx, &ity); XSetTSOrigin (dst->dpy, dst->gc, - (itx + src_attr.x_offset), - (ity + src_attr.y_offset)); @@ -1497,8 +1430,6 @@ _cairo_xlib_surface_fill_rectangles (void *abstract_surface, cairo_xlib_surface_t *surface = abstract_surface; XRenderColor render_color; - _cairo_xlib_display_notify (surface->screen_info->display); - if (!CAIRO_SURFACE_RENDER_HAS_FILL_RECTANGLE (surface)) return CAIRO_INT_STATUS_UNSUPPORTED; @@ -1631,8 +1562,6 @@ _cairo_xlib_surface_composite_trapezoids (cairo_operator_t op, int render_src_x, render_src_y; XRenderPictFormat *pict_format; - _cairo_xlib_display_notify (dst->screen_info->display); - if (!CAIRO_SURFACE_RENDER_HAS_TRAPEZOIDS (dst)) return CAIRO_INT_STATUS_UNSUPPORTED; @@ -1740,31 +1669,38 @@ static cairo_int_status_t _cairo_xlib_surface_set_clip_region (void *abstract_surface, pixman_region16_t *region) { - cairo_xlib_surface_t *surface = abstract_surface; + cairo_xlib_surface_t *surface = (cairo_xlib_surface_t *) abstract_surface; - if (surface->have_clip_rects == FALSE && region == NULL) - return CAIRO_STATUS_SUCCESS; - - if (surface->clip_rects != surface->embedded_clip_rects) { + if (surface->clip_rects) { free (surface->clip_rects); - surface->clip_rects = surface->embedded_clip_rects; + surface->clip_rects = NULL; } surface->have_clip_rects = FALSE; surface->num_clip_rects = 0; - if (region != NULL) { + if (region == NULL) { + if (surface->gc) + XSetClipMask (surface->dpy, surface->gc, None); + + if (surface->xrender_format && surface->dst_picture) { + XRenderPictureAttributes pa; + pa.clip_mask = None; + XRenderChangePicture (surface->dpy, surface->dst_picture, + CPClipMask, &pa); + } + } else { pixman_box16_t *boxes; XRectangle *rects = NULL; int n_boxes, i; n_boxes = pixman_region_num_rects (region); - if (n_boxes > ARRAY_LENGTH (surface->embedded_clip_rects)) { + if (n_boxes > 0) { rects = malloc (sizeof(XRectangle) * n_boxes); if (rects == NULL) return CAIRO_STATUS_NO_MEMORY; - }else { - rects = surface->embedded_clip_rects; + } else { + rects = NULL; } boxes = pixman_region_rects (region); @@ -1779,9 +1715,13 @@ _cairo_xlib_surface_set_clip_region (void *abstract_surface, surface->have_clip_rects = TRUE; surface->clip_rects = rects; surface->num_clip_rects = n_boxes; - } - surface->clip_dirty = CAIRO_XLIB_SURFACE_CLIP_DIRTY_ALL; + if (surface->gc) + _cairo_xlib_surface_set_gc_clip_rects (surface); + + if (surface->dst_picture) + _cairo_xlib_surface_set_picture_clip_rects (surface); + } return CAIRO_STATUS_SUCCESS; } @@ -1817,46 +1757,6 @@ static void _cairo_xlib_surface_scaled_glyph_fini (cairo_scaled_glyph_t *scaled_glyph, cairo_scaled_font_t *scaled_font); -static cairo_bool_t -_cairo_xlib_surface_is_similar (void *surface_a, - void *surface_b, - cairo_content_t content) -{ - cairo_xlib_surface_t *a = surface_a; - cairo_xlib_surface_t *b = surface_b; - XRenderPictFormat *xrender_format = b->xrender_format; - - if (!_cairo_xlib_surface_same_screen (a, b)) - return FALSE; - - /* now inspect the content to check that a is similar to b */ - if (xrender_format == NULL && b->visual != NULL) - xrender_format = XRenderFindVisualFormat (b->dpy, b->visual); - - if (xrender_format == NULL || - _xrender_format_to_content (xrender_format) != content) - { - xrender_format = _CAIRO_FORMAT_TO_XRENDER_FORMAT (b->dpy, - _cairo_format_from_content (content)); - } - - - return a->xrender_format == xrender_format; -} - -static cairo_status_t -_cairo_xlib_surface_reset (void *abstract_surface) -{ - cairo_xlib_surface_t *surface = abstract_surface; - cairo_status_t status; - - status = _cairo_xlib_surface_set_clip_region (surface, NULL); - if (status) - return status; - - return CAIRO_STATUS_SUCCESS; -} - static const cairo_surface_backend_t cairo_xlib_surface_backend = { CAIRO_SURFACE_TYPE_XLIB, _cairo_xlib_surface_create_similar, @@ -1886,10 +1786,7 @@ static const cairo_surface_backend_t cairo_xlib_surface_backend = { NULL, /* stroke */ NULL, /* fill */ _cairo_xlib_surface_show_glyphs, - NULL, /* snapshot */ - _cairo_xlib_surface_is_similar, - - _cairo_xlib_surface_reset + NULL /* snapshot */ }; /** @@ -1906,35 +1803,6 @@ _cairo_surface_is_xlib (cairo_surface_t *surface) return surface->backend == &cairo_xlib_surface_backend; } -static void -_cairo_xlib_surface_detach_display (Display *dpy, void *data) -{ - cairo_xlib_surface_t *surface = data; - - surface->dpy = NULL; - - if (surface->dst_picture != None) { - XRenderFreePicture (dpy, surface->dst_picture); - surface->dst_picture = None; - } - - if (surface->src_picture != None) { - XRenderFreePicture (dpy, surface->src_picture); - surface->src_picture = None; - } - - if (surface->owns_pixmap) { - XFreePixmap (dpy, surface->drawable); - surface->drawable = None; - surface->owns_pixmap = FALSE; - } - - if (surface->gc != NULL) { - XFreeGC (dpy, surface->gc); - surface->gc = NULL; - } -} - static cairo_surface_t * _cairo_xlib_surface_create_internal (Display *dpy, Drawable drawable, @@ -1956,15 +1824,6 @@ _cairo_xlib_surface_create_internal (Display *dpy, surface = malloc (sizeof (cairo_xlib_surface_t)); if (surface == NULL) { - _cairo_xlib_screen_info_destroy (screen_info); - _cairo_error (CAIRO_STATUS_NO_MEMORY); - return (cairo_surface_t*) &_cairo_surface_nil; - } - - if (! _cairo_xlib_add_close_display_hook (dpy, - _cairo_xlib_surface_detach_display, surface, surface)) { - free (surface); - _cairo_xlib_screen_info_destroy (screen_info); _cairo_error (CAIRO_STATUS_NO_MEMORY); return (cairo_surface_t*) &_cairo_surface_nil; } @@ -1990,7 +1849,8 @@ _cairo_xlib_surface_create_internal (Display *dpy, ; } - if (! XRenderQueryVersion (dpy, &surface->render_major, &surface->render_minor)) { + if (cairo_xlib_render_disabled || + ! XRenderQueryVersion (dpy, &surface->render_major, &surface->render_minor)) { surface->render_major = -1; surface->render_minor = -1; } @@ -2027,6 +1887,9 @@ _cairo_xlib_surface_create_internal (Display *dpy, } else if (strstr (ServerVendor (dpy), "XFree86") != NULL) { if (VendorRelease (dpy) <= 40500000) surface->buggy_repeat = TRUE; + } else if (strstr (ServerVendor (dpy), "Sun Microsystems, Inc.") != NULL) { + if (VendorRelease (dpy) <= 60900000) + surface->buggy_repeat = TRUE; } surface->dst_picture = None; @@ -2035,12 +1898,9 @@ _cairo_xlib_surface_create_internal (Display *dpy, surface->visual = visual; surface->xrender_format = xrender_format; surface->depth = depth; - surface->filter = CAIRO_FILTER_NEAREST; - surface->repeat = FALSE; - surface->xtransform = identity; surface->have_clip_rects = FALSE; - surface->clip_rects = surface->embedded_clip_rects; + surface->clip_rects = NULL; surface->num_clip_rects = 0; return (cairo_surface_t *) surface; @@ -2087,11 +1947,6 @@ _cairo_xlib_screen_from_visual (Display *dpy, Visual *visual) * cairo_xlib_surface_set_size must be called whenever the size of the * window changes. * - * When @drawable is a Window containing child windows then drawing to - * the created surface will be clipped by those child windows. When - * the created surface is used as a source, the contents of the - * children will be included. - * * Return value: the newly created surface **/ cairo_surface_t * @@ -2167,7 +2022,9 @@ cairo_xlib_surface_create_with_xrender_format (Display *dpy, return _cairo_xlib_surface_create_internal (dpy, drawable, screen, NULL, format, width, height, 0); } +#ifdef MOZILLA_CAIRO_NOT_DEFINED slim_hidden_def (cairo_xlib_surface_create_with_xrender_format); +#endif /** * cairo_xlib_surface_set_size: @@ -2222,7 +2079,6 @@ cairo_xlib_surface_set_drawable (cairo_surface_t *abstract_surface, int height) { cairo_xlib_surface_t *surface = (cairo_xlib_surface_t *)abstract_surface; - cairo_status_t status; if (! _cairo_surface_is_xlib (abstract_surface)) { _cairo_surface_set_error (abstract_surface, CAIRO_STATUS_SURFACE_TYPE_MISMATCH); @@ -2234,31 +2090,14 @@ cairo_xlib_surface_set_drawable (cairo_surface_t *abstract_surface, return; if (surface->drawable != drawable) { - if (surface->dst_picture != None) { - status = _cairo_xlib_display_queue_resource ( - surface->screen_info->display, - XRenderFreePicture, - surface->dst_picture); - if (status) { - _cairo_surface_set_error (&surface->base, status); - return; - } + if (surface->dst_picture) + XRenderFreePicture (surface->dpy, surface->dst_picture); - surface->dst_picture = None; - } + if (surface->src_picture) + XRenderFreePicture (surface->dpy, surface->src_picture); - if (surface->src_picture != None) { - status = _cairo_xlib_display_queue_resource ( - surface->screen_info->display, - XRenderFreePicture, - surface->src_picture); - if (status) { - _cairo_surface_set_error (&surface->base, status); - return; - } - - surface->src_picture = None; - } + surface->dst_picture = None; + surface->src_picture = None; surface->drawable = drawable; } @@ -2436,21 +2275,19 @@ typedef struct _cairo_xlib_surface_font_private { static void _cairo_xlib_surface_remove_scaled_font (Display *dpy, - void *data) + void *data) { cairo_scaled_font_t *scaled_font = data; - cairo_xlib_surface_font_private_t *font_private; - - CAIRO_MUTEX_LOCK (scaled_font->mutex); - font_private = scaled_font->surface_private; - scaled_font->surface_private = NULL; + cairo_xlib_surface_font_private_t *font_private = scaled_font->surface_private; _cairo_scaled_font_reset_cache (scaled_font); - CAIRO_MUTEX_UNLOCK (scaled_font->mutex); - if (font_private != NULL) { + /* separate function to avoid deadlock if we tried to remove the + * close display hook ala _cairo_xlib_surface_scaled_font_fini() */ + if (font_private) { XRenderFreeGlyphSet (font_private->dpy, font_private->glyphset); free (font_private); + scaled_font->surface_private = NULL; } } @@ -2461,18 +2298,15 @@ _cairo_xlib_surface_font_init (Display *dpy, { cairo_xlib_surface_font_private_t *font_private; + if (!_cairo_xlib_add_close_display_hook (dpy, + _cairo_xlib_surface_remove_scaled_font, + scaled_font, scaled_font)) + return CAIRO_STATUS_NO_MEMORY; + font_private = malloc (sizeof (cairo_xlib_surface_font_private_t)); if (!font_private) return CAIRO_STATUS_NO_MEMORY; - if (!_cairo_xlib_add_close_display_hook (dpy, - _cairo_xlib_surface_remove_scaled_font, - scaled_font, scaled_font)) { - free (font_private); - return CAIRO_STATUS_NO_MEMORY; - } - - font_private->dpy = dpy; font_private->format = format; font_private->xrender_format = _CAIRO_FORMAT_TO_XRENDER_FORMAT(dpy, format); @@ -2489,34 +2323,12 @@ _cairo_xlib_surface_scaled_font_fini (cairo_scaled_font_t *scaled_font) cairo_xlib_surface_font_private_t *font_private = scaled_font->surface_private; if (font_private) { - cairo_xlib_display_t *display; - - _cairo_xlib_remove_close_display_hooks (font_private->dpy, scaled_font); - - display = _cairo_xlib_display_get (font_private->dpy); - if (display != NULL) { - cairo_status_t status = _cairo_xlib_display_queue_resource (display, - XRenderFreeGlyphSet, - font_private->glyphset); - (void) status; /* XXX cannot propagate failure */ - _cairo_xlib_display_destroy (display); - } - + _cairo_xlib_remove_close_display_hook (font_private->dpy, scaled_font); + XRenderFreeGlyphSet (font_private->dpy, font_private->glyphset); free (font_private); } } -struct _cairo_xlib_render_free_glyphs { - GlyphSet glyphset; - unsigned long glyph_index; -}; -static void _cairo_xlib_render_free_glyphs (Display *dpy, struct _cairo_xlib_render_free_glyphs *arg) -{ - XRenderFreeGlyphs (dpy, - arg->glyphset, - &arg->glyph_index, 1); -} - static void _cairo_xlib_surface_scaled_glyph_fini (cairo_scaled_glyph_t *scaled_glyph, cairo_scaled_font_t *scaled_font) @@ -2524,26 +2336,10 @@ _cairo_xlib_surface_scaled_glyph_fini (cairo_scaled_glyph_t *scaled_glyph, cairo_xlib_surface_font_private_t *font_private = scaled_font->surface_private; if (font_private != NULL && scaled_glyph->surface_private != NULL) { - cairo_xlib_display_t *display = _cairo_xlib_display_get (font_private->dpy); - if (display != NULL) { - struct _cairo_xlib_render_free_glyphs *arg = malloc (sizeof (*arg)); - if (arg != NULL) { - cairo_status_t status; - arg->glyphset = font_private->glyphset; - arg->glyph_index = _cairo_scaled_glyph_index (scaled_glyph); - status = _cairo_xlib_display_queue_work (display, - (cairo_xlib_notify_func) _cairo_xlib_render_free_glyphs, - arg, - free); - if (status) { - /* XXX cannot propagate failure */ - free (arg); - } - } - - _cairo_xlib_display_destroy (display); - - } + unsigned long glyph_index = _cairo_scaled_glyph_index(scaled_glyph); + XRenderFreeGlyphs (font_private->dpy, + font_private->glyphset, + &glyph_index, 1); } } @@ -2905,7 +2701,6 @@ _cairo_xlib_surface_emit_glyphs (cairo_xlib_surface_t *dst, int request_size = 0; _cairo_xlib_surface_ensure_dst_picture (dst); - _cairo_xlib_display_notify (dst->screen_info->display); for (i = 0; i < num_glyphs; i++) { int this_x, this_y; @@ -3000,11 +2795,7 @@ _cairo_xlib_surface_emit_glyphs (cairo_xlib_surface_t *dst, /* Send unsent glyphs to the server */ if (scaled_glyph->surface_private == NULL) { - status = _cairo_xlib_surface_add_glyph (dst->dpy, - scaled_font, - scaled_glyph); - if (status) - return status; + _cairo_xlib_surface_add_glyph (dst->dpy, scaled_font, scaled_glyph); scaled_glyph->surface_private = (void *) 1; } @@ -3099,8 +2890,7 @@ _cairo_xlib_surface_show_glyphs (void *abstract_dst, * so PictOpClear was never used with CompositeText before. */ if (op == CAIRO_OPERATOR_CLEAR) { - _cairo_pattern_init_solid (&solid_pattern.solid, CAIRO_COLOR_WHITE, - CAIRO_CONTENT_COLOR); + _cairo_pattern_init_solid (&solid_pattern.solid, CAIRO_COLOR_WHITE); src_pattern = &solid_pattern.base; op = CAIRO_OPERATOR_DEST_OUT; } @@ -3110,8 +2900,6 @@ _cairo_xlib_surface_show_glyphs (void *abstract_dst, 0, 0, 1, 1, (cairo_surface_t **) &src, &attributes); - if (status) - goto BAIL0; } else { cairo_rectangle_int16_t glyph_extents; @@ -3120,43 +2908,38 @@ _cairo_xlib_surface_show_glyphs (void *abstract_dst, num_glyphs, &glyph_extents); if (status) - goto BAIL0; + goto BAIL; status = _cairo_pattern_acquire_surface (src_pattern, &dst->base, glyph_extents.x, glyph_extents.y, glyph_extents.width, glyph_extents.height, (cairo_surface_t **) &src, &attributes); - if (status) - goto BAIL0; } + if (status) + goto BAIL; + operation = _recategorize_composite_operation (dst, op, src, &attributes, TRUE); if (operation == DO_UNSUPPORTED) { status = CAIRO_INT_STATUS_UNSUPPORTED; - goto BAIL1; + goto BAIL; } status = _cairo_xlib_surface_set_attributes (src, &attributes); if (status) - goto BAIL1; + goto BAIL; - status = _cairo_xlib_surface_emit_glyphs (dst, - (cairo_xlib_glyph_t *) glyphs, - num_glyphs, - scaled_font, - op, - src, - &attributes); + _cairo_xlib_surface_emit_glyphs (dst, (cairo_xlib_glyph_t *) glyphs, num_glyphs, + scaled_font, op, src, &attributes); + + BAIL: + _cairo_scaled_font_thaw_cache (scaled_font); - BAIL1: if (src) _cairo_pattern_release_surface (src_pattern, &src->base, &attributes); if (src_pattern == &solid_pattern.base) _cairo_pattern_fini (&solid_pattern.base); - BAIL0: - _cairo_scaled_font_thaw_cache (scaled_font); - _cairo_xlib_display_notify (dst->screen_info->display); return status; } diff --git a/gfx/cairo/cairo/src/cairo-xlib-xrender.h b/gfx/cairo/cairo/src/cairo-xlib-xrender.h index f5c35dcd4685..f3b3726ef7a7 100644 --- a/gfx/cairo/cairo/src/cairo-xlib-xrender.h +++ b/gfx/cairo/cairo/src/cairo-xlib-xrender.h @@ -41,7 +41,6 @@ #if CAIRO_HAS_XLIB_SURFACE -#include #include CAIRO_BEGIN_DECLS diff --git a/gfx/cairo/cairo/src/cairo.c b/gfx/cairo/cairo/src/cairo.c index 6859e45b56c3..21303debd053 100644 --- a/gfx/cairo/cairo/src/cairo.c +++ b/gfx/cairo/cairo/src/cairo.c @@ -44,7 +44,7 @@ #define CAIRO_TOLERANCE_MINIMUM 0.0002 /* We're limited by 16 bits of sub-pixel precision */ -static const cairo_t _cairo_nil = { +static const cairo_t cairo_nil = { CAIRO_REF_COUNT_INVALID, /* ref_count */ CAIRO_STATUS_NO_MEMORY, /* status */ { 0, 0, 0, NULL }, /* user_data */ @@ -189,28 +189,25 @@ cairo_t * cairo_create (cairo_surface_t *target) { cairo_t *cr; - cairo_status_t status; - - /* special case OOM in order to avoid another allocation */ - if (target && target->status == CAIRO_STATUS_NO_MEMORY) - return (cairo_t *) &_cairo_nil; cr = malloc (sizeof (cairo_t)); if (cr == NULL) - return (cairo_t *) &_cairo_nil; + return (cairo_t *) &cairo_nil; cr->ref_count = 1; cr->status = CAIRO_STATUS_SUCCESS; _cairo_user_data_array_init (&cr->user_data); - _cairo_path_fixed_init (cr->path); cr->gstate = cr->gstate_tail; - status = _cairo_gstate_init (cr->gstate, target); + _cairo_gstate_init (cr->gstate, target); - if (status) - _cairo_set_error (cr, status); + _cairo_path_fixed_init (cr->path); + + if (target == NULL) { + _cairo_set_error (cr, CAIRO_STATUS_NULL_POINTER); + } return cr; } @@ -263,8 +260,10 @@ cairo_destroy (cairo_t *cr) return; while (cr->gstate != cr->gstate_tail) { - if (_cairo_gstate_restore (&cr->gstate)) - break; + cairo_gstate_t *tmp = cr->gstate; + cr->gstate = tmp->next; + + _cairo_gstate_destroy (tmp); } _cairo_gstate_fini (cr->gstate); @@ -369,15 +368,20 @@ cairo_get_reference_count (cairo_t *cr) void cairo_save (cairo_t *cr) { - cairo_status_t status; + cairo_gstate_t *top; if (cr->status) return; - status = _cairo_gstate_save (&cr->gstate); - if (status) { - _cairo_set_error (cr, status); + top = _cairo_gstate_clone (cr->gstate); + + if (top == NULL) { + _cairo_set_error (cr, CAIRO_STATUS_NO_MEMORY); + return; } + + top->next = cr->gstate; + cr->gstate = top; } slim_hidden_def(cairo_save); @@ -392,15 +396,20 @@ slim_hidden_def(cairo_save); void cairo_restore (cairo_t *cr) { - cairo_status_t status; + cairo_gstate_t *top; if (cr->status) return; - status = _cairo_gstate_restore (&cr->gstate); - if (status) { - _cairo_set_error (cr, status); + if (cr->gstate == cr->gstate_tail) { + _cairo_set_error (cr, CAIRO_STATUS_INVALID_RESTORE); + return; } + + top = cr->gstate; + cr->gstate = top->next; + + _cairo_gstate_destroy (top); } slim_hidden_def(cairo_restore); @@ -479,18 +488,12 @@ cairo_push_group_with_content (cairo_t *cr, cairo_content_t content) { cairo_status_t status; cairo_rectangle_int16_t extents; - cairo_surface_t *parent_surface, *group_surface = NULL; + cairo_surface_t *group_surface = NULL; - if (cr->status) - return; - - parent_surface = _cairo_gstate_get_target (cr->gstate); /* Get the extents that we'll use in creating our new group surface */ - status = _cairo_surface_get_extents (parent_surface, &extents); - if (status) - goto bail; + _cairo_surface_get_extents (_cairo_gstate_get_target (cr->gstate), &extents); status = _cairo_clip_intersect_to_rectangle (_cairo_gstate_get_clip (cr->gstate), &extents); - if (status) + if (status != CAIRO_STATUS_SUCCESS) goto bail; group_surface = cairo_surface_create_similar (_cairo_gstate_get_target (cr->gstate), @@ -507,15 +510,15 @@ cairo_push_group_with_content (cairo_t *cr, cairo_content_t content) * device offsets, so we want to set our own surface offsets from /that/, * and not from the device origin. */ cairo_surface_set_device_offset (group_surface, - parent_surface->device_transform.x0 - extents.x, - parent_surface->device_transform.y0 - extents.y); + cr->gstate->target->device_transform.x0 - extents.x, + cr->gstate->target->device_transform.y0 - extents.y); /* create a new gstate for the redirect */ cairo_save (cr); if (cr->status) goto bail; - status = _cairo_gstate_redirect_target (cr->gstate, group_surface); + _cairo_gstate_redirect_target (cr->gstate, group_surface); bail: cairo_surface_destroy (group_surface); @@ -552,9 +555,6 @@ cairo_pop_group (cairo_t *cr) cairo_pattern_t *group_pattern = NULL; cairo_matrix_t group_matrix; - if (cr->status) - return (cairo_pattern_t*) &_cairo_pattern_nil.base; - /* Grab the active surfaces */ group_surface = _cairo_gstate_get_target (cr->gstate); parent_target = _cairo_gstate_get_parent_target (cr->gstate); @@ -562,13 +562,13 @@ cairo_pop_group (cairo_t *cr) /* Verify that we are at the right nesting level */ if (parent_target == NULL) { _cairo_set_error (cr, CAIRO_STATUS_INVALID_POP_GROUP); - return (cairo_pattern_t*) &_cairo_pattern_nil.base; + return NULL; } /* We need to save group_surface before we restore; we don't need * to reference parent_target and original_target, since the * gstate will still hold refs to them once we restore. */ - group_surface = cairo_surface_reference (group_surface); + cairo_surface_reference (group_surface); cairo_restore (cr); @@ -576,8 +576,8 @@ cairo_pop_group (cairo_t *cr) goto done; group_pattern = cairo_pattern_create_for_surface (group_surface); - if (cairo_pattern_status (group_pattern)) { - _cairo_set_error (cr, cairo_pattern_status (group_pattern)); + if (!group_pattern) { + cr->status = CAIRO_STATUS_NO_MEMORY; goto done; } @@ -623,6 +623,9 @@ cairo_pop_group_to_source (cairo_t *cr) cairo_pattern_t *group_pattern; group_pattern = cairo_pop_group (cr); + if (!group_pattern) + return; + cairo_set_source (cr, group_pattern); cairo_pattern_destroy (group_pattern); } @@ -644,14 +647,12 @@ slim_hidden_def(cairo_pop_group_to_source); void cairo_set_operator (cairo_t *cr, cairo_operator_t op) { - cairo_status_t status; - if (cr->status) return; - status = _cairo_gstate_set_operator (cr->gstate, op); - if (status) - _cairo_set_error (cr, status); + cr->status = _cairo_gstate_set_operator (cr->gstate, op); + if (cr->status) + _cairo_set_error (cr, cr->status); } slim_hidden_def (cairo_set_operator); @@ -678,9 +679,6 @@ cairo_set_source_rgb (cairo_t *cr, double red, double green, double blue) if (cr->status) return; - /* push the current pattern to the freed lists */ - cairo_set_source (cr, (cairo_pattern_t *) &cairo_pattern_none); - pattern = cairo_pattern_create_rgb (red, green, blue); cairo_set_source (cr, pattern); cairo_pattern_destroy (pattern); @@ -712,9 +710,6 @@ cairo_set_source_rgba (cairo_t *cr, if (cr->status) return; - /* push the current pattern to the freed lists */ - cairo_set_source (cr, (cairo_pattern_t *) &cairo_pattern_none); - pattern = cairo_pattern_create_rgba (red, green, blue, alpha); cairo_set_source (cr, pattern); cairo_pattern_destroy (pattern); @@ -755,9 +750,6 @@ cairo_set_source_surface (cairo_t *cr, if (cr->status) return; - /* push the current pattern to the freed lists */ - cairo_set_source (cr, (cairo_pattern_t *) &cairo_pattern_none); - pattern = cairo_pattern_create_for_surface (surface); cairo_matrix_init_translate (&matrix, -x, -y); @@ -790,8 +782,6 @@ slim_hidden_def (cairo_set_source_surface); void cairo_set_source (cairo_t *cr, cairo_pattern_t *source) { - cairo_status_t status; - if (cr->status) return; @@ -805,9 +795,9 @@ cairo_set_source (cairo_t *cr, cairo_pattern_t *source) return; } - status = _cairo_gstate_set_source (cr->gstate, source); - if (status) - _cairo_set_error (cr, status); + cr->status = _cairo_gstate_set_source (cr->gstate, source); + if (cr->status) + _cairo_set_error (cr, cr->status); } slim_hidden_def (cairo_set_source); @@ -825,7 +815,7 @@ cairo_pattern_t * cairo_get_source (cairo_t *cr) { if (cr->status) - return (cairo_pattern_t*) &_cairo_pattern_nil.base; + return (cairo_pattern_t*) &cairo_pattern_nil.base; return _cairo_gstate_get_source (cr->gstate); } @@ -846,16 +836,14 @@ cairo_get_source (cairo_t *cr) void cairo_set_tolerance (cairo_t *cr, double tolerance) { - cairo_status_t status; - if (cr->status) return; _cairo_restrict_value (&tolerance, CAIRO_TOLERANCE_MINIMUM, tolerance); - status = _cairo_gstate_set_tolerance (cr->gstate, tolerance); - if (status) - _cairo_set_error (cr, status); + cr->status = _cairo_gstate_set_tolerance (cr->gstate, tolerance); + if (cr->status) + _cairo_set_error (cr, cr->status); } /** @@ -874,14 +862,12 @@ cairo_set_tolerance (cairo_t *cr, double tolerance) void cairo_set_antialias (cairo_t *cr, cairo_antialias_t antialias) { - cairo_status_t status; - if (cr->status) return; - status = _cairo_gstate_set_antialias (cr->gstate, antialias); - if (status) - _cairo_set_error (cr, status); + cr->status = _cairo_gstate_set_antialias (cr->gstate, antialias); + if (cr->status) + _cairo_set_error (cr, cr->status); } /** @@ -892,20 +878,18 @@ cairo_set_antialias (cairo_t *cr, cairo_antialias_t antialias) * Set the current fill rule within the cairo context. The fill rule * is used to determine which regions are inside or outside a complex * (potentially self-intersecting) path. The current fill rule affects - * both cairo_fill() and cairo_clip(). See #cairo_fill_rule_t for details + * both cairo_fill and cairo_clip. See #cairo_fill_rule_t for details * on the semantics of each available fill rule. **/ void cairo_set_fill_rule (cairo_t *cr, cairo_fill_rule_t fill_rule) { - cairo_status_t status; - if (cr->status) return; - status = _cairo_gstate_set_fill_rule (cr->gstate, fill_rule); - if (status) - _cairo_set_error (cr, status); + cr->status = _cairo_gstate_set_fill_rule (cr->gstate, fill_rule); + if (cr->status) + _cairo_set_error (cr, cr->status); } /** @@ -937,16 +921,14 @@ cairo_set_fill_rule (cairo_t *cr, cairo_fill_rule_t fill_rule) void cairo_set_line_width (cairo_t *cr, double width) { - cairo_status_t status; - if (cr->status) return; _cairo_restrict_value (&width, 0.0, width); - status = _cairo_gstate_set_line_width (cr->gstate, width); - if (status) - _cairo_set_error (cr, status); + cr->status = _cairo_gstate_set_line_width (cr->gstate, width); + if (cr->status) + _cairo_set_error (cr, cr->status); } /** @@ -966,14 +948,12 @@ cairo_set_line_width (cairo_t *cr, double width) void cairo_set_line_cap (cairo_t *cr, cairo_line_cap_t line_cap) { - cairo_status_t status; - if (cr->status) return; - status = _cairo_gstate_set_line_cap (cr->gstate, line_cap); - if (status) - _cairo_set_error (cr, status); + cr->status = _cairo_gstate_set_line_cap (cr->gstate, line_cap); + if (cr->status) + _cairo_set_error (cr, cr->status); } /** @@ -993,14 +973,12 @@ cairo_set_line_cap (cairo_t *cr, cairo_line_cap_t line_cap) void cairo_set_line_join (cairo_t *cr, cairo_line_join_t line_join) { - cairo_status_t status; - if (cr->status) return; - status = _cairo_gstate_set_line_join (cr->gstate, line_join); - if (status) - _cairo_set_error (cr, status); + cr->status = _cairo_gstate_set_line_join (cr->gstate, line_join); + if (cr->status) + _cairo_set_error (cr, cr->status); } /** @@ -1041,15 +1019,13 @@ cairo_set_dash (cairo_t *cr, int num_dashes, double offset) { - cairo_status_t status; - if (cr->status) return; - status = _cairo_gstate_set_dash (cr->gstate, - dashes, num_dashes, offset); - if (status) - _cairo_set_error (cr, status); + cr->status = _cairo_gstate_set_dash (cr->gstate, + dashes, num_dashes, offset); + if (cr->status) + _cairo_set_error (cr, cr->status); } /** @@ -1068,11 +1044,7 @@ cairo_set_dash (cairo_t *cr, int cairo_get_dash_count (cairo_t *cr) { - int num_dashes; - - _cairo_gstate_get_dash (cr->gstate, NULL, &num_dashes, NULL); - - return num_dashes; + return cr->gstate->stroke_style.num_dashes; } /** @@ -1092,7 +1064,13 @@ cairo_get_dash (cairo_t *cr, double *dashes, double *offset) { - _cairo_gstate_get_dash (cr->gstate, dashes, NULL, offset); + if (dashes) + memcpy (dashes, + cr->gstate->stroke_style.dash, + sizeof (double) * cr->gstate->stroke_style.num_dashes); + + if (offset) + *offset = cr->gstate->stroke_style.dash_offset; } /** @@ -1117,14 +1095,12 @@ cairo_get_dash (cairo_t *cr, void cairo_set_miter_limit (cairo_t *cr, double limit) { - cairo_status_t status; - if (cr->status) return; - status = _cairo_gstate_set_miter_limit (cr->gstate, limit); - if (status) - _cairo_set_error (cr, status); + cr->status = _cairo_gstate_set_miter_limit (cr->gstate, limit); + if (cr->status) + _cairo_set_error (cr, cr->status); } /** @@ -1142,14 +1118,12 @@ cairo_set_miter_limit (cairo_t *cr, double limit) void cairo_translate (cairo_t *cr, double tx, double ty) { - cairo_status_t status; - if (cr->status) return; - status = _cairo_gstate_translate (cr->gstate, tx, ty); - if (status) - _cairo_set_error (cr, status); + cr->status = _cairo_gstate_translate (cr->gstate, tx, ty); + if (cr->status) + _cairo_set_error (cr, cr->status); } /** @@ -1166,14 +1140,12 @@ cairo_translate (cairo_t *cr, double tx, double ty) void cairo_scale (cairo_t *cr, double sx, double sy) { - cairo_status_t status; - if (cr->status) return; - status = _cairo_gstate_scale (cr->gstate, sx, sy); - if (status) - _cairo_set_error (cr, status); + cr->status = _cairo_gstate_scale (cr->gstate, sx, sy); + if (cr->status) + _cairo_set_error (cr, cr->status); } slim_hidden_def (cairo_scale); @@ -1192,14 +1164,12 @@ slim_hidden_def (cairo_scale); void cairo_rotate (cairo_t *cr, double angle) { - cairo_status_t status; - if (cr->status) return; - status = _cairo_gstate_rotate (cr->gstate, angle); - if (status) - _cairo_set_error (cr, status); + cr->status = _cairo_gstate_rotate (cr->gstate, angle); + if (cr->status) + _cairo_set_error (cr, cr->status); } /** @@ -1215,14 +1185,12 @@ void cairo_transform (cairo_t *cr, const cairo_matrix_t *matrix) { - cairo_status_t status; - if (cr->status) return; - status = _cairo_gstate_transform (cr->gstate, matrix); - if (status) - _cairo_set_error (cr, status); + cr->status = _cairo_gstate_transform (cr->gstate, matrix); + if (cr->status) + _cairo_set_error (cr, cr->status); } /** @@ -1237,14 +1205,12 @@ void cairo_set_matrix (cairo_t *cr, const cairo_matrix_t *matrix) { - cairo_status_t status; - if (cr->status) return; - status = _cairo_gstate_set_matrix (cr->gstate, matrix); - if (status) - _cairo_set_error (cr, status); + cr->status = _cairo_gstate_set_matrix (cr->gstate, matrix); + if (cr->status) + _cairo_set_error (cr, cr->status); } /** @@ -1262,7 +1228,9 @@ cairo_identity_matrix (cairo_t *cr) if (cr->status) return; - _cairo_gstate_identity_matrix (cr->gstate); + cr->status = _cairo_gstate_identity_matrix (cr->gstate); + if (cr->status) + _cairo_set_error (cr, cr->status); } /** @@ -1281,7 +1249,9 @@ cairo_user_to_device (cairo_t *cr, double *x, double *y) if (cr->status) return; - _cairo_gstate_user_to_device (cr->gstate, x, y); + cr->status = _cairo_gstate_user_to_device (cr->gstate, x, y); + if (cr->status) + _cairo_set_error (cr, cr->status); } /** @@ -1301,7 +1271,9 @@ cairo_user_to_device_distance (cairo_t *cr, double *dx, double *dy) if (cr->status) return; - _cairo_gstate_user_to_device_distance (cr->gstate, dx, dy); + cr->status = _cairo_gstate_user_to_device_distance (cr->gstate, dx, dy); + if (cr->status) + _cairo_set_error (cr, cr->status); } /** @@ -1320,7 +1292,9 @@ cairo_device_to_user (cairo_t *cr, double *x, double *y) if (cr->status) return; - _cairo_gstate_device_to_user (cr->gstate, x, y); + cr->status = _cairo_gstate_device_to_user (cr->gstate, x, y); + if (cr->status) + _cairo_set_error (cr, cr->status); } /** @@ -1340,7 +1314,9 @@ cairo_device_to_user_distance (cairo_t *cr, double *dx, double *dy) if (cr->status) return; - _cairo_gstate_device_to_user_distance (cr->gstate, dx, dy); + cr->status = _cairo_gstate_device_to_user_distance (cr->gstate, dx, dy); + if (cr->status) + _cairo_set_error (cr, cr->status); } /** @@ -1372,7 +1348,6 @@ slim_hidden_def(cairo_new_path); void cairo_move_to (cairo_t *cr, double x, double y) { - cairo_status_t status; cairo_fixed_t x_fixed, y_fixed; if (cr->status) @@ -1382,9 +1357,9 @@ cairo_move_to (cairo_t *cr, double x, double y) x_fixed = _cairo_fixed_from_double (x); y_fixed = _cairo_fixed_from_double (y); - status = _cairo_path_fixed_move_to (cr->path, x_fixed, y_fixed); - if (status) - _cairo_set_error (cr, status); + cr->status = _cairo_path_fixed_move_to (cr->path, x_fixed, y_fixed); + if (cr->status) + _cairo_set_error (cr, cr->status); } slim_hidden_def(cairo_move_to); @@ -1431,7 +1406,6 @@ cairo_new_sub_path (cairo_t *cr) void cairo_line_to (cairo_t *cr, double x, double y) { - cairo_status_t status; cairo_fixed_t x_fixed, y_fixed; if (cr->status) @@ -1441,9 +1415,9 @@ cairo_line_to (cairo_t *cr, double x, double y) x_fixed = _cairo_fixed_from_double (x); y_fixed = _cairo_fixed_from_double (y); - status = _cairo_path_fixed_line_to (cr->path, x_fixed, y_fixed); - if (status) - _cairo_set_error (cr, status); + cr->status = _cairo_path_fixed_line_to (cr->path, x_fixed, y_fixed); + if (cr->status) + _cairo_set_error (cr, cr->status); } slim_hidden_def (cairo_line_to); @@ -1472,7 +1446,6 @@ cairo_curve_to (cairo_t *cr, double x2, double y2, double x3, double y3) { - cairo_status_t status; cairo_fixed_t x1_fixed, y1_fixed; cairo_fixed_t x2_fixed, y2_fixed; cairo_fixed_t x3_fixed, y3_fixed; @@ -1493,12 +1466,12 @@ cairo_curve_to (cairo_t *cr, x3_fixed = _cairo_fixed_from_double (x3); y3_fixed = _cairo_fixed_from_double (y3); - status = _cairo_path_fixed_curve_to (cr->path, - x1_fixed, y1_fixed, - x2_fixed, y2_fixed, - x3_fixed, y3_fixed); - if (status) - _cairo_set_error (cr, status); + cr->status = _cairo_path_fixed_curve_to (cr->path, + x1_fixed, y1_fixed, + x2_fixed, y2_fixed, + x3_fixed, y3_fixed); + if (cr->status) + _cairo_set_error (cr, cr->status); } slim_hidden_def (cairo_curve_to); @@ -1543,7 +1516,7 @@ slim_hidden_def (cairo_curve_to); * * cairo_save (cr); * cairo_translate (cr, x + width / 2., y + height / 2.); - * cairo_scale (cr, width / 2., height / 2.); + * cairo_scale (cr, 1. / (height / 2.), 1. / (width / 2.)); * cairo_arc (cr, 0., 0., 1., 0., 2 * M_PI); * cairo_restore (cr); * @@ -1585,7 +1558,7 @@ cairo_arc (cairo_t *cr, * arc is centered at (@xc, @yc), begins at @angle1 and proceeds in * the direction of decreasing angles to end at @angle2. If @angle2 is * greater than @angle1 it will be progressively decreased by 2*M_PI - * until it is less than @angle1. + * until it is greater than @angle1. * * See cairo_arc() for more details. This function differs only in the * direction of the arc between the two angles. @@ -1621,17 +1594,13 @@ cairo_arc_to (cairo_t *cr, double x2, double y2, double radius) { - cairo_status_t status; - if (cr->status) return; - status = _cairo_gstate_arc_to (cr->gstate, - x1, y1, - x2, y2, - radius); - if (status) - _cairo_set_error (cr, status); + cr->status = _cairo_gstate_arc_to (cr->gstate, + x1, y1, + x2, y2, + radius); } */ @@ -1655,19 +1624,17 @@ void cairo_rel_move_to (cairo_t *cr, double dx, double dy) { cairo_fixed_t dx_fixed, dy_fixed; - cairo_status_t status; if (cr->status) return; _cairo_gstate_user_to_device_distance (cr->gstate, &dx, &dy); - dx_fixed = _cairo_fixed_from_double (dx); dy_fixed = _cairo_fixed_from_double (dy); - status = _cairo_path_fixed_rel_move_to (cr->path, dx_fixed, dy_fixed); - if (status) - _cairo_set_error (cr, status); + cr->status = _cairo_path_fixed_rel_move_to (cr->path, dx_fixed, dy_fixed); + if (cr->status) + _cairo_set_error (cr, cr->status); } /** @@ -1692,19 +1659,17 @@ void cairo_rel_line_to (cairo_t *cr, double dx, double dy) { cairo_fixed_t dx_fixed, dy_fixed; - cairo_status_t status; if (cr->status) return; _cairo_gstate_user_to_device_distance (cr->gstate, &dx, &dy); - dx_fixed = _cairo_fixed_from_double (dx); dy_fixed = _cairo_fixed_from_double (dy); - status = _cairo_path_fixed_rel_line_to (cr->path, dx_fixed, dy_fixed); - if (status) - _cairo_set_error (cr, status); + cr->status = _cairo_path_fixed_rel_line_to (cr->path, dx_fixed, dy_fixed); + if (cr->status) + _cairo_set_error (cr, cr->status); } slim_hidden_def(cairo_rel_line_to); @@ -1743,7 +1708,6 @@ cairo_rel_curve_to (cairo_t *cr, cairo_fixed_t dx1_fixed, dy1_fixed; cairo_fixed_t dx2_fixed, dy2_fixed; cairo_fixed_t dx3_fixed, dy3_fixed; - cairo_status_t status; if (cr->status) return; @@ -1761,12 +1725,12 @@ cairo_rel_curve_to (cairo_t *cr, dx3_fixed = _cairo_fixed_from_double (dx3); dy3_fixed = _cairo_fixed_from_double (dy3); - status = _cairo_path_fixed_rel_curve_to (cr->path, - dx1_fixed, dy1_fixed, - dx2_fixed, dy2_fixed, - dx3_fixed, dy3_fixed); - if (status) - _cairo_set_error (cr, status); + cr->status = _cairo_path_fixed_rel_curve_to (cr->path, + dx1_fixed, dy1_fixed, + dx2_fixed, dy2_fixed, + dx3_fixed, dy3_fixed); + if (cr->status) + _cairo_set_error (cr, cr->status); } /** @@ -1808,14 +1772,12 @@ cairo_rectangle (cairo_t *cr, void cairo_stroke_to_path (cairo_t *cr) { - cairo_status_t status; - if (cr->status) return; - status = _cairo_gstate_stroke_path (cr->gstate); - if (status) - _cairo_set_error (cr, status); + cr->status = _cairo_gstate_stroke_path (cr->gstate); + if (cr->status) + _cairo_set_error (cr, cr->status); } */ @@ -1848,14 +1810,12 @@ cairo_stroke_to_path (cairo_t *cr) void cairo_close_path (cairo_t *cr) { - cairo_status_t status; - if (cr->status) return; - status = _cairo_path_fixed_close_path (cr->path); - if (status) - _cairo_set_error (cr, status); + cr->status = _cairo_path_fixed_close_path (cr->path); + if (cr->status) + _cairo_set_error (cr, cr->status); } slim_hidden_def(cairo_close_path); @@ -1869,14 +1829,12 @@ slim_hidden_def(cairo_close_path); void cairo_paint (cairo_t *cr) { - cairo_status_t status; - if (cr->status) return; - status = _cairo_gstate_paint (cr->gstate); - if (status) - _cairo_set_error (cr, status); + cr->status = _cairo_gstate_paint (cr->gstate); + if (cr->status) + _cairo_set_error (cr, cr->status); } slim_hidden_def (cairo_paint); @@ -1894,7 +1852,6 @@ void cairo_paint_with_alpha (cairo_t *cr, double alpha) { - cairo_status_t status; cairo_color_t color; cairo_pattern_union_t pattern; @@ -1911,11 +1868,11 @@ cairo_paint_with_alpha (cairo_t *cr, } _cairo_color_init_rgba (&color, 1., 1., 1., alpha); - _cairo_pattern_init_solid (&pattern.solid, &color, CAIRO_CONTENT_ALPHA); + _cairo_pattern_init_solid (&pattern.solid, &color); - status = _cairo_gstate_mask (cr->gstate, &pattern.base); - if (status) - _cairo_set_error (cr, status); + cr->status = _cairo_gstate_mask (cr->gstate, &pattern.base); + if (cr->status) + _cairo_set_error (cr, cr->status); _cairo_pattern_fini (&pattern.base); } @@ -1934,8 +1891,6 @@ void cairo_mask (cairo_t *cr, cairo_pattern_t *pattern) { - cairo_status_t status; - if (cr->status) return; @@ -1949,9 +1904,9 @@ cairo_mask (cairo_t *cr, return; } - status = _cairo_gstate_mask (cr->gstate, pattern); - if (status) - _cairo_set_error (cr, status); + cr->status = _cairo_gstate_mask (cr->gstate, pattern); + if (cr->status) + _cairo_set_error (cr, cr->status); } slim_hidden_def (cairo_mask); @@ -2045,14 +2000,12 @@ cairo_stroke (cairo_t *cr) void cairo_stroke_preserve (cairo_t *cr) { - cairo_status_t status; - if (cr->status) return; - status = _cairo_gstate_stroke (cr->gstate, cr->path); - if (status) - _cairo_set_error (cr, status); + cr->status = _cairo_gstate_stroke (cr->gstate, cr->path); + if (cr->status) + _cairo_set_error (cr, cr->status); } slim_hidden_def(cairo_stroke_preserve); @@ -2088,14 +2041,12 @@ cairo_fill (cairo_t *cr) void cairo_fill_preserve (cairo_t *cr) { - cairo_status_t status; - if (cr->status) return; - status = _cairo_gstate_fill (cr->gstate, cr->path); - if (status) - _cairo_set_error (cr, status); + cr->status = _cairo_gstate_fill (cr->gstate, cr->path); + if (cr->status) + _cairo_set_error (cr, cr->status); } slim_hidden_def(cairo_fill_preserve); @@ -2111,14 +2062,12 @@ slim_hidden_def(cairo_fill_preserve); void cairo_copy_page (cairo_t *cr) { - cairo_status_t status; - if (cr->status) return; - status = _cairo_gstate_copy_page (cr->gstate); - if (status) - _cairo_set_error (cr, status); + cr->status = _cairo_gstate_copy_page (cr->gstate); + if (cr->status) + _cairo_set_error (cr, cr->status); } /** @@ -2131,14 +2080,12 @@ cairo_copy_page (cairo_t *cr) void cairo_show_page (cairo_t *cr) { - cairo_status_t status; - if (cr->status) return; - status = _cairo_gstate_show_page (cr->gstate); - if (status) - _cairo_set_error (cr, status); + cr->status = _cairo_gstate_show_page (cr->gstate); + if (cr->status) + _cairo_set_error (cr, cr->status); } /** @@ -2149,8 +2096,7 @@ cairo_show_page (cairo_t *cr) * * Tests whether the given point is inside the area that would be * affected by a cairo_stroke() operation given the current path and - * stroking parameters. Surface dimensions and clipping are not taken - * into account. + * stroking parameters. * * See cairo_stroke(), cairo_set_line_width(), cairo_set_line_join(), * cairo_set_line_cap(), cairo_set_dash(), and @@ -2162,17 +2108,16 @@ cairo_show_page (cairo_t *cr) cairo_bool_t cairo_in_stroke (cairo_t *cr, double x, double y) { - cairo_status_t status; - cairo_bool_t inside = FALSE; + cairo_bool_t inside; if (cr->status) return 0; - status = _cairo_gstate_in_stroke (cr->gstate, - cr->path, - x, y, &inside); - if (status) - _cairo_set_error (cr, status); + cr->status = _cairo_gstate_in_stroke (cr->gstate, + cr->path, + x, y, &inside); + if (cr->status) + return 0; return inside; } @@ -2185,8 +2130,7 @@ cairo_in_stroke (cairo_t *cr, double x, double y) * * Tests whether the given point is inside the area that would be * affected by a cairo_fill() operation given the current path and - * filling parameters. Surface dimensions and clipping are not taken - * into account. + * filling parameters. * * See cairo_fill(), cairo_set_fill_rule() and cairo_fill_preserve(). * @@ -2196,17 +2140,18 @@ cairo_in_stroke (cairo_t *cr, double x, double y) cairo_bool_t cairo_in_fill (cairo_t *cr, double x, double y) { - cairo_status_t status; - cairo_bool_t inside = FALSE; + cairo_bool_t inside; if (cr->status) return 0; - status = _cairo_gstate_in_fill (cr->gstate, - cr->path, - x, y, &inside); - if (status) - _cairo_set_error (cr, status); + cr->status = _cairo_gstate_in_fill (cr->gstate, + cr->path, + x, y, &inside); + if (cr->status) { + _cairo_set_error (cr, cr->status); + return 0; + } return inside; } @@ -2233,16 +2178,14 @@ void cairo_stroke_extents (cairo_t *cr, double *x1, double *y1, double *x2, double *y2) { - cairo_status_t status; - if (cr->status) return; - status = _cairo_gstate_stroke_extents (cr->gstate, - cr->path, - x1, y1, x2, y2); - if (status) - _cairo_set_error (cr, status); + cr->status = _cairo_gstate_stroke_extents (cr->gstate, + cr->path, + x1, y1, x2, y2); + if (cr->status) + _cairo_set_error (cr, cr->status); } /** @@ -2265,16 +2208,14 @@ void cairo_fill_extents (cairo_t *cr, double *x1, double *y1, double *x2, double *y2) { - cairo_status_t status; - if (cr->status) return; - status = _cairo_gstate_fill_extents (cr->gstate, - cr->path, - x1, y1, x2, y2); - if (status) - _cairo_set_error (cr, status); + cr->status = _cairo_gstate_fill_extents (cr->gstate, + cr->path, + x1, y1, x2, y2); + if (cr->status) + _cairo_set_error (cr, cr->status); } /** @@ -2332,14 +2273,12 @@ cairo_clip (cairo_t *cr) void cairo_clip_preserve (cairo_t *cr) { - cairo_status_t status; - if (cr->status) return; - status = _cairo_gstate_clip (cr->gstate, cr->path); - if (status) - _cairo_set_error (cr, status); + cr->status = _cairo_gstate_clip (cr->gstate, cr->path); + if (cr->status) + _cairo_set_error (cr, cr->status); } slim_hidden_def(cairo_clip_preserve); @@ -2362,14 +2301,12 @@ slim_hidden_def(cairo_clip_preserve); void cairo_reset_clip (cairo_t *cr) { - cairo_status_t status; - if (cr->status) return; - status = _cairo_gstate_reset_clip (cr->gstate); - if (status) - _cairo_set_error (cr, status); + cr->status = _cairo_gstate_reset_clip (cr->gstate); + if (cr->status) + _cairo_set_error (cr, cr->status); } /** @@ -2390,14 +2327,12 @@ cairo_clip_extents (cairo_t *cr, double *x1, double *y1, double *x2, double *y2) { - cairo_status_t status; - if (cr->status) return; - status = _cairo_gstate_clip_extents (cr->gstate, x1, y1, x2, y2); - if (status) - _cairo_set_error (cr, status); + cr->status = _cairo_gstate_clip_extents (cr->gstate, x1, y1, x2, y2); + if (cr->status) + _cairo_set_error (cr, cr->status); } static cairo_rectangle_list_t * @@ -2405,9 +2340,6 @@ _cairo_rectangle_list_create_in_error (cairo_status_t status) { cairo_rectangle_list_t *list; - if (status == CAIRO_STATUS_NO_MEMORY) - return (cairo_rectangle_list_t*) &_cairo_rectangles_nil; - list = malloc (sizeof (cairo_rectangle_list_t)); if (list == NULL) return (cairo_rectangle_list_t*) &_cairo_rectangles_nil; @@ -2466,14 +2398,12 @@ cairo_select_font_face (cairo_t *cr, cairo_font_slant_t slant, cairo_font_weight_t weight) { - cairo_status_t status; - if (cr->status) return; - status = _cairo_gstate_select_font_face (cr->gstate, family, slant, weight); - if (status) - _cairo_set_error (cr, status); + cr->status = _cairo_gstate_select_font_face (cr->gstate, family, slant, weight); + if (cr->status) + _cairo_set_error (cr, cr->status); } /** @@ -2488,14 +2418,12 @@ void cairo_font_extents (cairo_t *cr, cairo_font_extents_t *extents) { - cairo_status_t status; - if (cr->status) return; - status = _cairo_gstate_get_font_extents (cr->gstate, extents); - if (status) - _cairo_set_error (cr, status); + cr->status = _cairo_gstate_get_font_extents (cr->gstate, extents); + if (cr->status) + _cairo_set_error (cr, cr->status); } /** @@ -2511,14 +2439,12 @@ void cairo_set_font_face (cairo_t *cr, cairo_font_face_t *font_face) { - cairo_status_t status; - if (cr->status) return; - status = _cairo_gstate_set_font_face (cr->gstate, font_face); - if (status) - _cairo_set_error (cr, status); + cr->status = _cairo_gstate_set_font_face (cr->gstate, font_face); + if (cr->status) + _cairo_set_error (cr, cr->status); } /** @@ -2542,15 +2468,14 @@ cairo_set_font_face (cairo_t *cr, cairo_font_face_t * cairo_get_font_face (cairo_t *cr) { - cairo_status_t status; cairo_font_face_t *font_face; if (cr->status) return (cairo_font_face_t*) &_cairo_font_face_nil; - status = _cairo_gstate_get_font_face (cr->gstate, &font_face); - if (status) { - _cairo_set_error (cr, status); + cr->status = _cairo_gstate_get_font_face (cr->gstate, &font_face); + if (cr->status) { + _cairo_set_error (cr, cr->status); return (cairo_font_face_t*) &_cairo_font_face_nil; } @@ -2571,14 +2496,12 @@ cairo_get_font_face (cairo_t *cr) void cairo_set_font_size (cairo_t *cr, double size) { - cairo_status_t status; - if (cr->status) return; - status = _cairo_gstate_set_font_size (cr->gstate, size); - if (status) - _cairo_set_error (cr, status); + cr->status = _cairo_gstate_set_font_size (cr->gstate, size); + if (cr->status) + _cairo_set_error (cr, cr->status); } /** @@ -2598,14 +2521,12 @@ void cairo_set_font_matrix (cairo_t *cr, const cairo_matrix_t *matrix) { - cairo_status_t status; - if (cr->status) return; - status = _cairo_gstate_set_font_matrix (cr->gstate, matrix); - if (status) - _cairo_set_error (cr, status); + cr->status = _cairo_gstate_set_font_matrix (cr->gstate, matrix); + if (cr->status) + _cairo_set_error (cr, cr->status); } /** @@ -2637,18 +2558,12 @@ void cairo_set_font_options (cairo_t *cr, const cairo_font_options_t *options) { - cairo_status_t status; - if (cr->status) return; - status = cairo_font_options_status ((cairo_font_options_t *) options); - if (status) { - _cairo_set_error (cr, status); - return; - } - - _cairo_gstate_set_font_options (cr->gstate, options); + cr->status = _cairo_gstate_set_font_options (cr->gstate, options); + if (cr->status) + _cairo_set_error (cr, cr->status); } /** @@ -2666,10 +2581,6 @@ void cairo_get_font_options (cairo_t *cr, cairo_font_options_t *options) { - /* check that we aren't trying to overwrite the nil object */ - if (cairo_font_options_status (options)) - return; - _cairo_gstate_get_font_options (cr->gstate, options); } @@ -2690,29 +2601,29 @@ void cairo_set_scaled_font (cairo_t *cr, const cairo_scaled_font_t *scaled_font) { - cairo_status_t status; - if (cr->status) return; - status = scaled_font->status; - if (status) + cr->status = scaled_font->status; + if (cr->status) goto BAIL; - status = _cairo_gstate_set_font_face (cr->gstate, scaled_font->font_face); - if (status) + cr->status = _cairo_gstate_set_font_face (cr->gstate, scaled_font->font_face); + if (cr->status) goto BAIL; - status = _cairo_gstate_set_font_matrix (cr->gstate, &scaled_font->font_matrix); - if (status) + cr->status = _cairo_gstate_set_font_matrix (cr->gstate, &scaled_font->font_matrix); + if (cr->status) goto BAIL; - _cairo_gstate_set_font_options (cr->gstate, &scaled_font->options); + cr->status = _cairo_gstate_set_font_options (cr->gstate, &scaled_font->options); + if (cr->status) + goto BAIL; return; BAIL: - _cairo_set_error (cr, status); + _cairo_set_error (cr, cr->status); } /** @@ -2738,15 +2649,14 @@ BAIL: cairo_scaled_font_t * cairo_get_scaled_font (cairo_t *cr) { - cairo_status_t status; cairo_scaled_font_t *scaled_font; if (cr->status) return (cairo_scaled_font_t *)&_cairo_scaled_font_nil; - status = _cairo_gstate_get_scaled_font (cr->gstate, &scaled_font); - if (status) { - _cairo_set_error (cr, status); + cr->status = _cairo_gstate_get_scaled_font (cr->gstate, &scaled_font); + if (cr->status) { + _cairo_set_error (cr, cr->status); return (cairo_scaled_font_t *)&_cairo_scaled_font_nil; } @@ -2778,7 +2688,6 @@ cairo_text_extents (cairo_t *cr, const char *utf8, cairo_text_extents_t *extents) { - cairo_status_t status; cairo_glyph_t *glyphs = NULL; int num_glyphs; double x, y; @@ -2798,23 +2707,23 @@ cairo_text_extents (cairo_t *cr, cairo_get_current_point (cr, &x, &y); - status = _cairo_gstate_text_to_glyphs (cr->gstate, utf8, - x, y, - &glyphs, &num_glyphs); + cr->status = _cairo_gstate_text_to_glyphs (cr->gstate, utf8, + x, y, + &glyphs, &num_glyphs); - if (status) { + if (cr->status) { if (glyphs) free (glyphs); - _cairo_set_error (cr, status); + _cairo_set_error (cr, cr->status); return; } - status = _cairo_gstate_glyph_extents (cr->gstate, glyphs, num_glyphs, extents); + cr->status = _cairo_gstate_glyph_extents (cr->gstate, glyphs, num_glyphs, extents); if (glyphs) free (glyphs); - if (status) - _cairo_set_error (cr, status); + if (cr->status) + _cairo_set_error (cr, cr->status); } /** @@ -2841,15 +2750,13 @@ cairo_glyph_extents (cairo_t *cr, int num_glyphs, cairo_text_extents_t *extents) { - cairo_status_t status; - if (cr->status) return; - status = _cairo_gstate_glyph_extents (cr->gstate, glyphs, num_glyphs, - extents); - if (status) - _cairo_set_error (cr, status); + cr->status = _cairo_gstate_glyph_extents (cr->gstate, glyphs, num_glyphs, + extents); + if (cr->status) + _cairo_set_error (cr, cr->status); } /** @@ -2883,7 +2790,6 @@ void cairo_show_text (cairo_t *cr, const char *utf8) { cairo_text_extents_t extents; - cairo_status_t status; cairo_glyph_t *glyphs = NULL, *last_glyph; int num_glyphs; double x, y; @@ -2896,24 +2802,24 @@ cairo_show_text (cairo_t *cr, const char *utf8) cairo_get_current_point (cr, &x, &y); - status = _cairo_gstate_text_to_glyphs (cr->gstate, utf8, + cr->status = _cairo_gstate_text_to_glyphs (cr->gstate, utf8, x, y, &glyphs, &num_glyphs); - if (status) + if (cr->status) goto BAIL; if (num_glyphs == 0) return; - status = _cairo_gstate_show_glyphs (cr->gstate, glyphs, num_glyphs); - if (status) + cr->status = _cairo_gstate_show_glyphs (cr->gstate, glyphs, num_glyphs); + if (cr->status) goto BAIL; last_glyph = &glyphs[num_glyphs - 1]; - status = _cairo_gstate_glyph_extents (cr->gstate, - last_glyph, 1, - &extents); - if (status) + cr->status = _cairo_gstate_glyph_extents (cr->gstate, + last_glyph, 1, + &extents); + if (cr->status) goto BAIL; x = last_glyph->x + extents.x_advance; @@ -2924,8 +2830,8 @@ cairo_show_text (cairo_t *cr, const char *utf8) if (glyphs) free (glyphs); - if (status) - _cairo_set_error (cr, status); + if (cr->status) + _cairo_set_error (cr, cr->status); } /** @@ -2934,24 +2840,22 @@ cairo_show_text (cairo_t *cr, const char *utf8) * @glyphs: array of glyphs to show * @num_glyphs: number of glyphs to show * - * A drawing operator that generates the shape from an array of glyphs, + * A drawing operator that generates the shape from an array of glyphs, * rendered according to the current font_face, font_size * (font_matrix), and font_options. **/ void cairo_show_glyphs (cairo_t *cr, const cairo_glyph_t *glyphs, int num_glyphs) { - cairo_status_t status; - if (cr->status) return; if (num_glyphs == 0) return; - status = _cairo_gstate_show_glyphs (cr->gstate, glyphs, num_glyphs); - if (status) - _cairo_set_error (cr, status); + cr->status = _cairo_gstate_show_glyphs (cr->gstate, glyphs, num_glyphs); + if (cr->status) + _cairo_set_error (cr, cr->status); } /** @@ -2981,7 +2885,6 @@ cairo_show_glyphs (cairo_t *cr, const cairo_glyph_t *glyphs, int num_glyphs) void cairo_text_path (cairo_t *cr, const char *utf8) { - cairo_status_t status; cairo_text_extents_t extents; cairo_glyph_t *glyphs = NULL, *last_glyph; int num_glyphs; @@ -2992,29 +2895,29 @@ cairo_text_path (cairo_t *cr, const char *utf8) cairo_get_current_point (cr, &x, &y); - status = _cairo_gstate_text_to_glyphs (cr->gstate, utf8, - x, y, - &glyphs, &num_glyphs); + cr->status = _cairo_gstate_text_to_glyphs (cr->gstate, utf8, + x, y, + &glyphs, &num_glyphs); - if (status) + if (cr->status) goto BAIL; if (num_glyphs == 0) return; - status = _cairo_gstate_glyph_path (cr->gstate, - glyphs, num_glyphs, - cr->path); + cr->status = _cairo_gstate_glyph_path (cr->gstate, + glyphs, num_glyphs, + cr->path); - if (status) + if (cr->status) goto BAIL; last_glyph = &glyphs[num_glyphs - 1]; - status = _cairo_gstate_glyph_extents (cr->gstate, - last_glyph, 1, - &extents); + cr->status = _cairo_gstate_glyph_extents (cr->gstate, + last_glyph, 1, + &extents); - if (status) + if (cr->status) goto BAIL; x = last_glyph->x + extents.x_advance; @@ -3025,8 +2928,8 @@ cairo_text_path (cairo_t *cr, const char *utf8) if (glyphs) free (glyphs); - if (status) - _cairo_set_error (cr, status); + if (cr->status) + _cairo_set_error (cr, cr->status); } /** @@ -3042,16 +2945,14 @@ cairo_text_path (cairo_t *cr, const char *utf8) void cairo_glyph_path (cairo_t *cr, const cairo_glyph_t *glyphs, int num_glyphs) { - cairo_status_t status; - if (cr->status) return; - status = _cairo_gstate_glyph_path (cr->gstate, - glyphs, num_glyphs, - cr->path); - if (status) - _cairo_set_error (cr, status); + cr->status = _cairo_gstate_glyph_path (cr->gstate, + glyphs, num_glyphs, + cr->path); + if (cr->status) + _cairo_set_error (cr, cr->status); } /** @@ -3112,19 +3013,11 @@ cairo_get_antialias (cairo_t *cr) * * Most path construction functions alter the current point. See the * following for details on how they affect the current point: - * cairo_new_path(), cairo_new_sub_path(), - * cairo_append_path(), cairo_close_path(), - * cairo_move_to(), cairo_line_to(), cairo_curve_to(), - * cairo_rel_move_to(), cairo_rel_line_to(), cairo_rel_curve_to(), - * cairo_arc(), cairo_arc_negative(), cairo_rectangle(), - * cairo_text_path(), cairo_glyph_path(), cairo_stroke_to_path() * - * Some functions use and alter the current point but do not otherwise - * change current path: - * cairo_show_text(), cairo_show_glyphs(). - * - * Some functions unset the current path and as a result, current point: - * cairo_fill(), cairo_stroke(). + * cairo_new_path(), cairo_move_to(), cairo_line_to(), + * cairo_curve_to(), cairo_arc(), cairo_rel_move_to(), + * cairo_rel_line_to(), cairo_rel_curve_to(), cairo_arc(), + * cairo_text_path(), cairo_stroke_to_path() **/ void cairo_get_current_point (cairo_t *cr, double *x_ret, double *y_ret) @@ -3386,8 +3279,6 @@ void cairo_append_path (cairo_t *cr, const cairo_path_t *path) { - cairo_status_t status; - if (cr->status) return; @@ -3410,9 +3301,9 @@ cairo_append_path (cairo_t *cr, return; } - status = _cairo_path_append_to_context (path, cr); - if (status) - _cairo_set_error (cr, status); + cr->status = _cairo_path_append_to_context (path, cr); + if (cr->status) + _cairo_set_error (cr, cr->status); } /** diff --git a/gfx/cairo/cairo/src/cairo.h b/gfx/cairo/cairo/src/cairo.h index 8c3718f73261..a80efde210e2 100644 --- a/gfx/cairo/cairo/src/cairo.h +++ b/gfx/cairo/cairo/src/cairo.h @@ -895,7 +895,7 @@ typedef enum _cairo_subpixel_order { /** * cairo_hint_style_t: * @CAIRO_HINT_STYLE_DEFAULT: Use the default hint style for - * font backend and target device + * for font backend and target device * @CAIRO_HINT_STYLE_NONE: Do not hint outlines * @CAIRO_HINT_STYLE_SLIGHT: Hint outlines slightly to improve * contrast while retaining good fidelity to the original diff --git a/gfx/cairo/cairo/src/cairoint.h b/gfx/cairo/cairo/src/cairoint.h index 3ac46704115f..895515ab14be 100644 --- a/gfx/cairo/cairo/src/cairoint.h +++ b/gfx/cairo/cairo/src/cairoint.h @@ -54,7 +54,6 @@ #include #include #include -#include #ifdef _MSC_VER #define _USE_MATH_DEFINES @@ -75,13 +74,13 @@ CAIRO_BEGIN_DECLS #if __GNUC__ >= 3 && defined(__ELF__) && !defined(__sun) -# define slim_hidden_proto(name) slim_hidden_proto1(name, slim_hidden_int_name(name)) cairo_private -# define slim_hidden_proto_no_warn(name) slim_hidden_proto1(name, slim_hidden_int_name(name)) cairo_private_no_warn -# define slim_hidden_def(name) slim_hidden_def1(name, slim_hidden_int_name(name)) +# define slim_hidden_proto(name) slim_hidden_proto1(name, slim_hidden_int_name(name)) +# define slim_hidden_def(name) slim_hidden_def1(name, slim_hidden_int_name(name)) # define slim_hidden_int_name(name) INT_##name # define slim_hidden_proto1(name, internal) \ extern __typeof (name) name \ - __asm__ (slim_hidden_asmname (internal)) + __asm__ (slim_hidden_asmname (internal)) \ + cairo_private # define slim_hidden_def1(name, internal) \ extern __typeof (name) EXT_##name __asm__(slim_hidden_asmname(name)) \ __attribute__((__alias__(slim_hidden_asmname(internal)))) @@ -91,9 +90,8 @@ CAIRO_BEGIN_DECLS # define slim_hidden_asmname(name) slim_hidden_asmname1(name) # define slim_hidden_asmname1(name) slim_hidden_ulp #name #else -# define slim_hidden_proto(name) int _cairo_dummy_prototype(void) -# define slim_hidden_proto_no_warn(name) int _cairo_dummy_prototype(void) -# define slim_hidden_def(name) int _cairo_dummy_prototype(void) +# define slim_hidden_proto(name) int _cairo_dummy_prototype(void) +# define slim_hidden_def(name) int _cairo_dummy_prototype(void) #endif #if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ > 4) @@ -105,20 +103,13 @@ CAIRO_BEGIN_DECLS /* slim_internal.h */ #if (__GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 3)) && defined(__ELF__) && !defined(__sun) -#define cairo_private_no_warn __attribute__((__visibility__("hidden"))) +#define cairo_private __attribute__((__visibility__("hidden"))) #elif defined(__SUNPRO_C) && (__SUNPRO_C >= 0x550) -#define cairo_private_no_warn __hidden +#define cairo_private __hidden #else /* not gcc >= 3.3 and not Sun Studio >= 8 */ -#define cairo_private_no_warn +#define cairo_private #endif -#ifndef WARN_UNUSED_RESULT -#define WARN_UNUSED_RESULT -#endif -/* Add attribute(warn_unused_result) if supported */ -#define cairo_warn WARN_UNUSED_RESULT -#define cairo_private cairo_private_no_warn cairo_warn - /* This macro allow us to deprecate a function by providing an alias for the old function name to the new function name. With this macro, binary compatibility is preserved. The macro only works on @@ -143,6 +134,93 @@ CAIRO_BEGIN_DECLS #define __attribute__(x) #endif +#if MOZILLA_CAIRO_NOT_DEFINED +#if HAVE_PTHREAD_H +# include +# define CAIRO_MUTEX_DECLARE(name) static pthread_mutex_t name = PTHREAD_MUTEX_INITIALIZER +# define CAIRO_MUTEX_DECLARE_GLOBAL(name) pthread_mutex_t name = PTHREAD_MUTEX_INITIALIZER +# define CAIRO_MUTEX_LOCK(name) pthread_mutex_lock (&name) +# define CAIRO_MUTEX_UNLOCK(name) pthread_mutex_unlock (&name) +typedef pthread_mutex_t cairo_mutex_t; +#define CAIRO_MUTEX_INIT(mutex) do { \ + pthread_mutex_t tmp_mutex = PTHREAD_MUTEX_INITIALIZER; \ + memcpy (mutex, &tmp_mutex, sizeof (tmp_mutex)); \ +} while (0) +# define CAIRO_MUTEX_FINI(mutex) pthread_mutex_destroy (mutex) +# define CAIRO_MUTEX_NIL_INITIALIZER PTHREAD_MUTEX_INITIALIZER +#endif + +#if !defined(CAIRO_MUTEX_DECLARE) && defined CAIRO_HAS_WIN32_SURFACE +# define WIN32_LEAN_AND_MEAN +/* We require Windows 2000 features. Although we don't use them here, things + * should still work if this header file ends up being the one to include + * windows.h into a source file, so: */ +# if !defined(WINVER) || (WINVER < 0x0500) +# define WINVER 0x0500 +# endif +# if !defined(_WIN32_WINNT) || (_WIN32_WINNT < 0x0500) +# define _WIN32_WINNT 0x0500 +# endif +# include + /* the real initialization must take place in DllMain */ +# define CAIRO_MUTEX_DECLARE(name) extern CRITICAL_SECTION name; +# define CAIRO_MUTEX_DECLARE_GLOBAL(name) extern LPCRITICAL_SECTION name; +# define CAIRO_MUTEX_LOCK(name) EnterCriticalSection (&name) +# define CAIRO_MUTEX_UNLOCK(name) LeaveCriticalSection (&name) +typedef CRITICAL_SECTION cairo_mutex_t; +# define CAIRO_MUTEX_INIT(mutex) InitializeCriticalSection (mutex) +# define CAIRO_MUTEX_FINI(mutex) DeleteCriticalSection (mutex) +# define CAIRO_MUTEX_NIL_INITIALIZER { 0 } +#endif + +#if defined(__OS2__) && !defined(CAIRO_MUTEX_DECLARE) +# define INCL_BASE +# define INCL_PM +# include + +# define CAIRO_MUTEX_DECLARE(name) extern HMTX name +# define CAIRO_MUTEX_DECLARE_GLOBAL(name) extern HMTX name +# define CAIRO_MUTEX_LOCK(name) DosRequestMutexSem(name, SEM_INDEFINITE_WAIT) +# define CAIRO_MUTEX_UNLOCK(name) DosReleaseMutexSem(name) +typedef HMTX cairo_mutex_t; +# define CAIRO_MUTEX_INIT(mutex) DosCreateMutexSem (NULL, mutex, 0L, FALSE) +# define CAIRO_MUTEX_FINI(mutex) DosCloseMutexSem (*(mutex)) +# define CAIRO_MUTEX_NIL_INITIALIZER 0 +#endif + +#if !defined(CAIRO_MUTEX_DECLARE) && defined CAIRO_HAS_BEOS_SURFACE +cairo_private void _cairo_beos_lock(void*); +cairo_private void _cairo_beos_unlock(void*); + /* the real initialization takes place in a global constructor */ +# define CAIRO_MUTEX_DECLARE(name) extern void* name; +# define CAIRO_MUTEX_DECLARE_GLOBAL(name) extern void* name; +# define CAIRO_MUTEX_LOCK(name) _cairo_beos_lock (&name) +# define CAIRO_MUTEX_UNLOCK(name) _cairo_beos_unlock (&name) +# error "XXX: Someone who understands BeOS needs to add definitions for" \ + " cairo_mutex_t, CAIRO_MUTEX_INIT, and CAIRO_MUTEX_FINI," \ + " to cairoint.h" +typedef ??? cairo_mutex_t; +# define CAIRO_MUTEX_INIT(mutex) ??? +# define CAIRO_MUTEX_FINI(mutex) ??? +# define CAIRO_MUTEX_NIL_INITIALIZER {} +#endif +#endif /* MOZILLA_CAIRO_NOT_REACHED */ + +#ifndef CAIRO_MUTEX_DECLARE +#if MOZILLA_CAIRO_NOT_DEFINED +# error "No mutex declarations. Cairo will not work with multiple threads." \ + "(Remove this #error directive to acknowledge & accept this limitation)." +#endif +typedef void *cairo_mutex_t; +# define CAIRO_MUTEX_DECLARE(name) +# define CAIRO_MUTEX_DECLARE_GLOBAL(name) +# define CAIRO_MUTEX_LOCK(name) +# define CAIRO_MUTEX_UNLOCK(name) +#define CAIRO_MUTEX_INIT(mutex) (*(mutex) = 0) +#define CAIRO_MUTEX_FINI(mutex) +#define CAIRO_MUTEX_NIL_INITIALIZER 0 +#endif + #undef MIN #define MIN(a, b) ((a) < (b) ? (a) : (b)) @@ -161,15 +239,24 @@ CAIRO_BEGIN_DECLS #define M_PI 3.14159265358979323846 #endif +#ifndef MOZILLA_CAIRO_NOT_DEFINED +/* Make assertions non-fatal */ #ifndef NDEBUG #undef assert #define assert(expr) \ do { if (!(expr)) fprintf(stderr, "Assertion failed at %s:%d: %s\n", \ __FILE__, __LINE__, #expr); } while (0) #endif - -#undef ARRAY_LENGTH -#define ARRAY_LENGTH(__array) ((int) (sizeof (__array) / sizeof (__array[0]))) +#ifndef INT32_MAX +# ifdef INT_MAX +# define INT32_MAX INT_MAX +# define INT32_MIN INT_MIN +# else +# define INT32_MAX 2147483647 +# define INT32_MIN (-2147483647 - 1) +# endif +#endif +#endif /* Size in bytes of buffer to use off the stack per functions. * Mostly used by text functions. For larger allocations, they'll @@ -186,7 +273,6 @@ do { \ #define CAIRO_REF_COUNT_INVALID ((unsigned int) -1) -#include "cairo-mutex-private.h" #include "cairo-wideint-private.h" typedef int32_t cairo_fixed_16_16_t; @@ -199,11 +285,8 @@ typedef cairo_int128_t cairo_fixed_96_32_t; typedef cairo_fixed_16_16_t cairo_fixed_t; #define CAIRO_ALPHA_IS_OPAQUE(alpha) ((alpha) >= ((double)0xff00 / (double)0xffff)) -#define CAIRO_ALPHA_SHORT_IS_OPAQUE(alpha) ((alpha) >= 0xff00) #define CAIRO_ALPHA_IS_ZERO(alpha) ((alpha) <= 0.0) -#define CAIRO_COLOR_IS_OPAQUE(color) CAIRO_ALPHA_SHORT_IS_OPAQUE ((color)->alpha_short) - /* Reverse the bits in a byte with 7 operations (no 64-bit): * Devised by Sean Anderson, July 13, 2001. * Source: http://graphics.stanford.edu/~seander/bithacks.html#ReverseByteWith32Bits @@ -251,7 +334,6 @@ be32_to_cpu(uint32_t v) #endif -#include "cairo-types-private.h" #include "cairo-hash-private.h" #include "cairo-cache-private.h" @@ -315,43 +397,33 @@ typedef enum cairo_internal_surface_type { CAIRO_INTERNAL_SURFACE_TYPE_TEST_PAGINATED } cairo_internal_surface_type_t; -/* For xlib fallbacks, we need image surfaces with formats that match - * the visual of the X server. There are a few common X server visuals - * for which we do not have corresponding public cairo_format_t - * values, since we do not plan on always guaranteeing that cairo will - * be able to draw to these formats. +/* For xlib fallbacks, we use image surfaces with formats that match + * the visual of the X server. There are a couple of common X server + * visuals for which we do not have corresponding public + * cairo_format_t values, since we do not plan on always guaranteeing + * that cairo will be able to draw to these formats. * - * Currently pixman does advertise support for these formats, (with an - * interface to construct a format from a set of masks---but pixman - * may not actually have code to support any arbitrary set of - * maskes). So we lodge a cairo_internal_format_t in the internal - * cairo image surface to indicate what's going on. The value isn't - * actually used for much, since it is the set of pixman masks that - * control the rendering. + * So, currently pixman does provide support for these formats. It's + * possible that in the future we will change the implementation to + * instead convert to a supported format. This would allow us to be + * able to simplify pixman to handle fewer formats. * - * But even though the value isn't used, it's still useful to maintain - * this list, as it indicates to use visual formats that have been - * encountered in practice. We can take advantage of this for future - * rewrites of pixman that might support a limited set of formats - * instead of general mask-based rendering, (or at least optimized - * rendering for a limited set of formats). - * - * Another approach that could be taken here is to convert the data at - * the time of the fallback to a supported format. This is similar to - * what needs to be done to support PseudoColor visuals, for example. + * The RGB16_565 case could probably have been handled this same way, + * (and in fact we could still change it to do so, and maybe just + * leave the value in the enum but deprecate it entirely). We can't + * drop the value since it did appear in cairo 1.2.0 so it might + * appear in code, (particularly bindings which are thorough about + * things like that). But we did neglect to update CAIRO_FORMAT_VALID + * for 1.2 so we know that no functional code is out there relying on + * being able to create an image surface with a 565 format, (which is + * good since things like write_to_png are missing support for the 565 + * format. * * NOTE: The implementation of CAIRO_FORMAT_VALID *must* *not* - * consider these internal formats as valid. - * - * NOTE: When adding a value to this list, be sure to add it to - * _cairo_format_from_pixman_format, (which is probably the assert - * failure you're wanting to eliminate), but also don't forget to add - * it to cairo_content_from_format. - */ + * consider these internal formats as valid. */ typedef enum cairo_internal_format { CAIRO_INTERNAL_FORMAT_ABGR32 = 0x1000, - CAIRO_INTERNAL_FORMAT_BGR24, - CAIRO_INTERNAL_FORMAT_RGB16_565 + CAIRO_INTERNAL_FORMAT_BGR24 } cairo_internal_format_t; typedef enum cairo_direction { @@ -366,6 +438,7 @@ typedef enum _cairo_clip_mode { CAIRO_CLIP_MODE_MASK } cairo_clip_mode_t; typedef struct _cairo_clip_path cairo_clip_path_t; +typedef struct _cairo_clip cairo_clip_t; typedef struct _cairo_edge { cairo_line_t edge; @@ -375,8 +448,6 @@ typedef struct _cairo_edge { } cairo_edge_t; typedef struct _cairo_polygon { - cairo_status_t status; - cairo_point_t first_point; cairo_point_t current_point; cairo_bool_t has_current_point; @@ -417,6 +488,8 @@ typedef struct _cairo_pen { typedef struct _cairo_color cairo_color_t; typedef struct _cairo_image_surface cairo_image_surface_t; +typedef struct _cairo_surface_backend cairo_surface_backend_t; + cairo_private void _cairo_box_round_to_rectangle (cairo_box_t *box, cairo_rectangle_int16_t *rectangle); @@ -425,6 +498,16 @@ _cairo_rectangle_intersect (cairo_rectangle_int16_t *dest, cairo_rectangle_int16 /* cairo_array.c structures and functions */ +typedef struct _cairo_array cairo_array_t; +struct _cairo_array { + unsigned int size; + unsigned int num_elements; + unsigned int element_size; + char **elements; + + cairo_bool_t is_snapshot; +}; + cairo_private void _cairo_array_init (cairo_array_t *array, int element_size); @@ -466,6 +549,8 @@ _cairo_array_num_elements (cairo_array_t *array); cairo_private int _cairo_array_size (cairo_array_t *array); +typedef cairo_array_t cairo_user_data_array_t; + cairo_private void _cairo_user_data_array_init (cairo_user_data_array_t *array); @@ -486,6 +571,8 @@ cairo_private unsigned long _cairo_hash_string (const char *c); typedef struct _cairo_unscaled_font_backend cairo_unscaled_font_backend_t; +typedef struct _cairo_scaled_font_backend cairo_scaled_font_backend_t; +typedef struct _cairo_font_face_backend cairo_font_face_backend_t; /* * A cairo_unscaled_font_t is just an opaque handle we use in the @@ -497,6 +584,13 @@ typedef struct _cairo_unscaled_font { const cairo_unscaled_font_backend_t *backend; } cairo_unscaled_font_t; +struct _cairo_font_options { + cairo_antialias_t antialias; + cairo_subpixel_order_t subpixel_order; + cairo_hint_style_t hint_style; + cairo_hint_metrics_t hint_metrics; +}; + typedef struct _cairo_scaled_glyph { cairo_cache_entry_t cache_entry; /* hash is glyph index */ cairo_scaled_font_t *scaled_font; /* font the glyph lives in */ @@ -512,7 +606,71 @@ typedef struct _cairo_scaled_glyph { #define _cairo_scaled_glyph_index(g) ((g)->cache_entry.hash) #define _cairo_scaled_glyph_set_index(g,i) ((g)->cache_entry.hash = (i)) -#include "cairo-scaled-font-private.h" +struct _cairo_scaled_font { + /* For most cairo objects, the rule for multiple threads is that + * the user is responsible for any locking if the same object is + * manipulated from multiple threads simultaneously. + * + * However, with the caching that cairo does for scaled fonts, a + * user can easily end up with the same cairo_scaled_font object + * being manipulated from multiple threads without the user ever + * being aware of this, (and in fact, unable to control it). + * + * So, as a special exception, the cairo implementation takes care + * of all locking needed for cairo_scaled_font_t. Most of what is + * in the scaled font is immutable, (which is what allows for the + * sharing in the first place). The things that are modified and + * the locks protecting them are as follows: + * + * 1. The reference count (scaled_font->ref_count) + * + * Modifications to the reference count are protected by the + * _cairo_scaled_font_map_mutex. This is because the reference + * count of a scaled font is intimately related with the font + * map itself, (and the magic holdovers array). + * + * 2. The cache of glyphs (scaled_font->glyphs) + * 3. The backend private data (scaled_font->surface_backend, + * scaled_font->surface_private) + * + * Modifications to these fields are protected with locks on + * scaled_font->mutex in the generic scaled_font code. + */ + + /* must be first to be stored in a hash table */ + cairo_hash_entry_t hash_entry; + + /* useful bits for _cairo_scaled_font_nil */ + cairo_status_t status; + unsigned int ref_count; + cairo_user_data_array_t user_data; + + /* hash key members */ + cairo_font_face_t *font_face; /* may be NULL */ + cairo_matrix_t font_matrix; /* font space => user space */ + cairo_matrix_t ctm; /* user space => device space */ + cairo_font_options_t options; + + /* "live" scaled_font members */ + cairo_matrix_t scale; /* font space => device space */ + cairo_font_extents_t extents; /* user space */ + + /* The mutex protects modification to all subsequent fields. */ + cairo_mutex_t mutex; + + cairo_cache_t *glyphs; /* glyph index -> cairo_scaled_glyph_t */ + + /* + * One surface backend may store data in each glyph. + * Whichever surface manages to store its pointer here + * first gets to store data in each glyph + */ + const cairo_surface_backend_t *surface_backend; + void *surface_private; + + /* font backend managing this scaled font */ + const cairo_scaled_font_backend_t *backend; +}; struct _cairo_font_face { /* hash_entry must be first */ @@ -529,6 +687,12 @@ _cairo_font_reset_static_data (void); cairo_private void _cairo_ft_font_reset_static_data (void); +cairo_private void +_cairo_xlib_surface_reset_static_data (void); + +cairo_private void +_cairo_xlib_screen_reset_static_data (void); + /* the font backend interface */ struct _cairo_unscaled_font_backend { @@ -564,13 +728,12 @@ typedef struct _cairo_scaled_font_subset { unsigned long *glyphs; unsigned long *to_unicode; unsigned int num_glyphs; - cairo_bool_t is_composite; } cairo_scaled_font_subset_t; struct _cairo_scaled_font_backend { cairo_font_type_t type; - cairo_warn cairo_status_t + cairo_status_t (*create_toy) (cairo_toy_font_face_t *toy_face, const cairo_matrix_t *font_matrix, const cairo_matrix_t *ctm, @@ -580,7 +743,7 @@ struct _cairo_scaled_font_backend { void (*fini) (void *scaled_font); - cairo_warn cairo_int_status_t + cairo_int_status_t (*scaled_glyph_init) (void *scaled_font, cairo_scaled_glyph_t *scaled_glyph, cairo_scaled_glyph_info_t info); @@ -589,7 +752,7 @@ struct _cairo_scaled_font_backend { * both. This allows the backend to do something more sophisticated * then just converting characters one by one. */ - cairo_warn cairo_int_status_t + cairo_int_status_t (*text_to_glyphs) (void *scaled_font, double x, double y, @@ -600,7 +763,7 @@ struct _cairo_scaled_font_backend { unsigned long (*ucs4_to_index) (void *scaled_font, uint32_t ucs4); - cairo_warn cairo_int_status_t + cairo_int_status_t (*show_glyphs) (void *scaled_font, cairo_operator_t op, cairo_pattern_t *pattern, @@ -614,7 +777,7 @@ struct _cairo_scaled_font_backend { cairo_glyph_t *glyphs, int num_glyphs); - cairo_warn cairo_int_status_t + cairo_int_status_t (*load_truetype_table)(void *scaled_font, unsigned long tag, long offset, @@ -636,7 +799,7 @@ struct _cairo_font_face_backend { void (*destroy) (void *font_face); - cairo_warn cairo_status_t + cairo_status_t (*scaled_font_create) (void *font_face, const cairo_matrix_t *font_matrix, const cairo_matrix_t *ctm, @@ -682,10 +845,10 @@ struct _cairo_surface_backend { int width, int height); - cairo_warn cairo_status_t + cairo_status_t (*finish) (void *surface); - cairo_warn cairo_status_t + cairo_status_t (*acquire_source_image) (void *abstract_surface, cairo_image_surface_t **image_out, void **image_extra); @@ -695,7 +858,7 @@ struct _cairo_surface_backend { cairo_image_surface_t *image, void *image_extra); - cairo_warn cairo_status_t + cairo_status_t (*acquire_dest_image) (void *abstract_surface, cairo_rectangle_int16_t *interest_rect, cairo_image_surface_t **image_out, @@ -719,7 +882,7 @@ struct _cairo_surface_backend { * * 3. It has the same contents as @src within the given rectangle. */ - cairo_warn cairo_status_t + cairo_status_t (*clone_similar) (void *surface, cairo_surface_t *src, int src_x, @@ -729,7 +892,7 @@ struct _cairo_surface_backend { cairo_surface_t **clone_out); /* XXX: dst should be the first argument for consistency */ - cairo_warn cairo_int_status_t + cairo_int_status_t (*composite) (cairo_operator_t op, cairo_pattern_t *src, cairo_pattern_t *mask, @@ -743,7 +906,7 @@ struct _cairo_surface_backend { unsigned int width, unsigned int height); - cairo_warn cairo_int_status_t + cairo_int_status_t (*fill_rectangles) (void *surface, cairo_operator_t op, const cairo_color_t *color, @@ -751,7 +914,7 @@ struct _cairo_surface_backend { int num_rects); /* XXX: dst should be the first argument for consistency */ - cairo_warn cairo_int_status_t + cairo_int_status_t (*composite_trapezoids) (cairo_operator_t op, cairo_pattern_t *pattern, void *dst, @@ -765,10 +928,10 @@ struct _cairo_surface_backend { cairo_trapezoid_t *traps, int num_traps); - cairo_warn cairo_int_status_t + cairo_int_status_t (*copy_page) (void *surface); - cairo_warn cairo_int_status_t + cairo_int_status_t (*show_page) (void *surface); /* Set given region as the clip region for the surface, replacing @@ -784,7 +947,7 @@ struct _cairo_surface_backend { * this is not possible, cairo will use mask surfaces for * clipping. */ - cairo_warn cairo_int_status_t + cairo_int_status_t (*set_clip_region) (void *surface, pixman_region16_t *region); @@ -802,7 +965,7 @@ struct _cairo_surface_backend { * function is not implemented cairo will use set_clip_region() * (if available) and mask surfaces for clipping. */ - cairo_warn cairo_int_status_t + cairo_int_status_t (*intersect_clip_path) (void *dst, cairo_path_fixed_t *path, cairo_fill_rule_t fill_rule, @@ -819,7 +982,7 @@ struct _cairo_surface_backend { * into the specific surface->get_extents if there is no current * clip. */ - cairo_warn cairo_int_status_t + cairo_int_status_t (*get_extents) (void *surface, cairo_rectangle_int16_t *rectangle); @@ -828,7 +991,7 @@ struct _cairo_surface_backend { * resources. If null, render against this surface, using image * surfaces as glyphs. */ - cairo_warn cairo_int_status_t + cairo_int_status_t (*old_show_glyphs) (cairo_scaled_font_t *font, cairo_operator_t op, cairo_pattern_t *pattern, @@ -846,10 +1009,10 @@ struct _cairo_surface_backend { (*get_font_options) (void *surface, cairo_font_options_t *options); - cairo_warn cairo_status_t + cairo_status_t (*flush) (void *surface); - cairo_warn cairo_status_t + cairo_status_t (*mark_dirty_rectangle) (void *surface, int x, int y, @@ -866,18 +1029,18 @@ struct _cairo_surface_backend { /* OK, I'm starting over somewhat by defining the 5 top-level * drawing operators for the surface backend here with consistent * naming and argument-order conventions. */ - cairo_warn cairo_int_status_t + cairo_int_status_t (*paint) (void *surface, cairo_operator_t op, cairo_pattern_t *source); - cairo_warn cairo_int_status_t + cairo_int_status_t (*mask) (void *surface, cairo_operator_t op, cairo_pattern_t *source, cairo_pattern_t *mask); - cairo_warn cairo_int_status_t + cairo_int_status_t (*stroke) (void *surface, cairo_operator_t op, cairo_pattern_t *source, @@ -888,7 +1051,7 @@ struct _cairo_surface_backend { double tolerance, cairo_antialias_t antialias); - cairo_warn cairo_int_status_t + cairo_int_status_t (*fill) (void *surface, cairo_operator_t op, cairo_pattern_t *source, @@ -897,7 +1060,7 @@ struct _cairo_surface_backend { double tolerance, cairo_antialias_t antialias); - cairo_warn cairo_int_status_t + cairo_int_status_t (*show_glyphs) (void *surface, cairo_operator_t op, cairo_pattern_t *source, @@ -907,14 +1070,6 @@ struct _cairo_surface_backend { cairo_surface_t * (*snapshot) (void *surface); - - cairo_bool_t - (*is_similar) (void *surface_a, - void *surface_b, - cairo_content_t content); - - cairo_warn cairo_status_t - (*reset) (void *surface); }; typedef struct _cairo_format_masks { @@ -925,7 +1080,56 @@ typedef struct _cairo_format_masks { unsigned long blue_mask; } cairo_format_masks_t; -#include "cairo-surface-private.h" +struct _cairo_surface { + const cairo_surface_backend_t *backend; + + /* We allow surfaces to override the backend->type by shoving something + * else into surface->type. This is for "wrapper" surfaces that want to + * hide their internal type from the user-level API. */ + cairo_surface_type_t type; + + cairo_content_t content; + + unsigned int ref_count; + cairo_status_t status; + cairo_bool_t finished; + cairo_user_data_array_t user_data; + + cairo_matrix_t device_transform; + cairo_matrix_t device_transform_inverse; + + double x_fallback_resolution; + double y_fallback_resolution; + + cairo_clip_t *clip; + + /* + * Each time a clip region is modified, it gets the next value in this + * sequence. This means that clip regions for this surface are uniquely + * identified and updates to the clip can be readily identified + */ + unsigned int next_clip_serial; + /* + * The serial number of the current clip. This is set when + * the surface clipping is set. The gstate can then cheaply + * check whether the surface clipping is already correct before + * performing a rendering operation. + * + * The special value '0' is reserved for the unclipped case. + */ + unsigned int current_clip_serial; + + /* A "snapshot" surface is immutable. See _cairo_surface_snapshot. */ + cairo_bool_t is_snapshot; + + /* + * Surface font options, falling back to backend's default options, + * and set using _cairo_surface_set_font_options(), and propagated by + * cairo_surface_create_similar(). + */ + cairo_bool_t has_font_options; + cairo_font_options_t font_options; +}; struct _cairo_image_surface { cairo_surface_t base; @@ -988,11 +1192,9 @@ struct _cairo_pattern { typedef struct _cairo_solid_pattern { cairo_pattern_t base; cairo_color_t color; - cairo_content_t content; } cairo_solid_pattern_t; -extern const cairo_private cairo_solid_pattern_t _cairo_pattern_nil; -extern const cairo_private cairo_solid_pattern_t cairo_pattern_none; +extern const cairo_private cairo_solid_pattern_t cairo_pattern_nil; typedef struct _cairo_surface_pattern { cairo_pattern_t base; @@ -1055,9 +1257,6 @@ typedef struct _cairo_traps { int traps_size; cairo_trapezoid_t *traps; cairo_trapezoid_t traps_embedded[1]; - - cairo_bool_t has_limits; - cairo_box_t limits; } cairo_traps_t; #define CAIRO_FONT_SLANT_DEFAULT CAIRO_FONT_SLANT_NORMAL @@ -1147,16 +1346,16 @@ _cairo_gstate_init (cairo_gstate_t *gstate, cairo_private void _cairo_gstate_fini (cairo_gstate_t *gstate); -cairo_private cairo_status_t -_cairo_gstate_save (cairo_gstate_t **gstate); +cairo_private cairo_gstate_t * +_cairo_gstate_clone (cairo_gstate_t *gstate); -cairo_private cairo_status_t -_cairo_gstate_restore (cairo_gstate_t **gstate); +cairo_private void +_cairo_gstate_destroy (cairo_gstate_t *gstate); cairo_private cairo_bool_t _cairo_gstate_is_redirected (cairo_gstate_t *gstate); -cairo_private cairo_status_t +cairo_private void _cairo_gstate_redirect_target (cairo_gstate_t *gstate, cairo_surface_t *child); cairo_private cairo_surface_t * @@ -1216,9 +1415,6 @@ _cairo_gstate_get_line_join (cairo_gstate_t *gstate); cairo_private cairo_status_t _cairo_gstate_set_dash (cairo_gstate_t *gstate, const double *dash, int num_dashes, double offset); -cairo_private void -_cairo_gstate_get_dash (cairo_gstate_t *gstate, double *dash, int *num_dashes, double *offset); - cairo_private cairo_status_t _cairo_gstate_set_miter_limit (cairo_gstate_t *gstate, double limit); @@ -1245,19 +1441,19 @@ cairo_private cairo_status_t _cairo_gstate_set_matrix (cairo_gstate_t *gstate, const cairo_matrix_t *matrix); -cairo_private void +cairo_private cairo_status_t _cairo_gstate_identity_matrix (cairo_gstate_t *gstate); -cairo_private void +cairo_private cairo_status_t _cairo_gstate_user_to_device (cairo_gstate_t *gstate, double *x, double *y); -cairo_private void +cairo_private cairo_status_t _cairo_gstate_user_to_device_distance (cairo_gstate_t *gstate, double *dx, double *dy); -cairo_private void +cairo_private cairo_status_t _cairo_gstate_device_to_user (cairo_gstate_t *gstate, double *x, double *y); -cairo_private void +cairo_private cairo_status_t _cairo_gstate_device_to_user_distance (cairo_gstate_t *gstate, double *dx, double *dy); cairo_private void @@ -1363,7 +1559,7 @@ cairo_private void _cairo_gstate_get_font_options (cairo_gstate_t *gstate, cairo_font_options_t *options); -cairo_private void +cairo_private cairo_status_t _cairo_gstate_set_font_options (cairo_gstate_t *gstate, const cairo_font_options_t *options); @@ -1455,11 +1651,7 @@ _cairo_color_get_rgba_premultiplied (cairo_color_t *color, double *blue, double *alpha); -cairo_private cairo_bool_t -_cairo_color_equal (const cairo_color_t *color_a, - const cairo_color_t *color_b); - -/* cairo-font-face.c */ +/* cairo-font.c */ cairo_private void _cairo_scaled_font_freeze_cache (cairo_scaled_font_t *scaled_font); @@ -1490,7 +1682,7 @@ cairo_private void _cairo_unscaled_font_init (cairo_unscaled_font_t *font, const cairo_unscaled_font_backend_t *backend); -cairo_private_no_warn cairo_unscaled_font_t * +cairo_private cairo_unscaled_font_t * _cairo_unscaled_font_reference (cairo_unscaled_font_t *font); cairo_private void @@ -1739,16 +1931,12 @@ _cairo_surface_create_similar_scratch (cairo_surface_t *other, int width, int height); -/* Note: the color_pattern argument is optional - if provided it will reuse - * that pattern instead of creating a very short-lived fresh solid pattern - */ cairo_private cairo_surface_t * _cairo_surface_create_similar_solid (cairo_surface_t *other, cairo_content_t content, int width, int height, - const cairo_color_t *color, - cairo_pattern_t *color_pattern); + const cairo_color_t *color); cairo_private void _cairo_surface_init (cairo_surface_t *surface, @@ -1851,10 +2039,10 @@ _cairo_surface_composite_trapezoids (cairo_operator_t op, cairo_trapezoid_t *traps, int ntraps); -cairo_private cairo_status_t +cairo_private cairo_int_status_t _cairo_surface_copy_page (cairo_surface_t *surface); -cairo_private cairo_status_t +cairo_private cairo_int_status_t _cairo_surface_show_page (cairo_surface_t *surface); cairo_private cairo_status_t @@ -1893,14 +2081,6 @@ _cairo_surface_clone_similar (cairo_surface_t *surface, cairo_private cairo_surface_t * _cairo_surface_snapshot (cairo_surface_t *surface); -cairo_private cairo_bool_t -_cairo_surface_is_similar (cairo_surface_t *surface_a, - cairo_surface_t *surface_b, - cairo_content_t content); - -cairo_private cairo_status_t -_cairo_surface_reset (cairo_surface_t *surface); - cairo_private unsigned int _cairo_surface_get_current_clip_serial (cairo_surface_t *surface); @@ -2089,7 +2269,7 @@ _cairo_pen_init (cairo_pen_t *pen, double tolerance, cairo_matrix_t *ctm); -cairo_private void +cairo_private cairo_status_t _cairo_pen_init_empty (cairo_pen_t *pen); cairo_private cairo_status_t @@ -2132,18 +2312,15 @@ cairo_private void _cairo_polygon_fini (cairo_polygon_t *polygon); cairo_private cairo_status_t -_cairo_polygon_status (cairo_polygon_t *polygon); - -cairo_private void _cairo_polygon_add_edge (cairo_polygon_t *polygon, cairo_point_t *p1, cairo_point_t *p2); -cairo_private void +cairo_private cairo_status_t _cairo_polygon_move_to (cairo_polygon_t *polygon, cairo_point_t *point); -cairo_private void +cairo_private cairo_status_t _cairo_polygon_line_to (cairo_polygon_t *polygon, cairo_point_t *point); -cairo_private void +cairo_private cairo_status_t _cairo_polygon_close (cairo_polygon_t *polygon); /* cairo_spline.c */ @@ -2176,7 +2353,7 @@ _cairo_matrix_transform_bounding_box (const cairo_matrix_t *matrix, cairo_private void _cairo_matrix_compute_determinant (const cairo_matrix_t *matrix, double *det); -cairo_private void +cairo_private cairo_status_t _cairo_matrix_compute_scale_factors (const cairo_matrix_t *matrix, double *sx, double *sy, int x_major); @@ -2201,10 +2378,6 @@ _cairo_matrix_to_pixman_matrix (const cairo_matrix_t *matrix, cairo_private void _cairo_traps_init (cairo_traps_t *traps); -cairo_private void -_cairo_traps_limit (cairo_traps_t *traps, - cairo_box_t *limits); - cairo_private cairo_status_t _cairo_traps_init_box (cairo_traps_t *traps, cairo_box_t *box); @@ -2212,9 +2385,6 @@ _cairo_traps_init_box (cairo_traps_t *traps, cairo_private void _cairo_traps_fini (cairo_traps_t *traps); -cairo_private cairo_status_t -_cairo_traps_status (cairo_traps_t *traps); - cairo_private void _cairo_traps_translate (cairo_traps_t *traps, int x, int y); @@ -2229,7 +2399,7 @@ _cairo_traps_tessellate_polygon (cairo_traps_t *traps, cairo_polygon_t *poly, cairo_fill_rule_t fill_rule); -cairo_private void +cairo_private cairo_status_t _cairo_traps_add_trap_from_points (cairo_traps_t *traps, cairo_fixed_t top, cairo_fixed_t bottom, cairo_point_t left_p1, cairo_point_t left_p2, cairo_point_t right_p1, cairo_point_t right_p2); @@ -2245,9 +2415,9 @@ _cairo_traps_contain (cairo_traps_t *traps, double x, double y); cairo_private void _cairo_traps_extents (cairo_traps_t *traps, cairo_box_t *extents); -cairo_private cairo_int_status_t -_cairo_traps_extract_region (cairo_traps_t *tr, - pixman_region16_t *region); +cairo_private cairo_status_t +_cairo_traps_extract_region (cairo_traps_t *tr, + pixman_region16_t **region); cairo_private void _cairo_trapezoid_array_translate_and_scale (cairo_trapezoid_t *offset_traps, @@ -2271,14 +2441,13 @@ _cairo_slope_counter_clockwise (cairo_slope_t *a, cairo_slope_t *b); /* cairo_pattern.c */ -cairo_private cairo_status_t +cairo_private void _cairo_pattern_init_copy (cairo_pattern_t *pattern, const cairo_pattern_t *other); cairo_private void -_cairo_pattern_init_solid (cairo_solid_pattern_t *pattern, - const cairo_color_t *color, - cairo_content_t content); +_cairo_pattern_init_solid (cairo_solid_pattern_t *pattern, + const cairo_color_t *color); cairo_private void _cairo_pattern_init_for_surface (cairo_surface_pattern_t *pattern, @@ -2297,8 +2466,7 @@ cairo_private void _cairo_pattern_fini (cairo_pattern_t *pattern); cairo_private cairo_pattern_t * -_cairo_pattern_create_solid (const cairo_color_t *color, - cairo_content_t content); +_cairo_pattern_create_solid (const cairo_color_t *color); cairo_private void _cairo_pattern_transform (cairo_pattern_t *pattern, @@ -2344,9 +2512,6 @@ cairo_private cairo_status_t _cairo_pattern_get_extents (cairo_pattern_t *pattern, cairo_rectangle_int16_t *extents); -cairo_private void -_cairo_pattern_reset_static_data (void); - cairo_private cairo_status_t _cairo_gstate_set_antialias (cairo_gstate_t *gstate, cairo_antialias_t antialias); @@ -2356,6 +2521,9 @@ _cairo_gstate_get_antialias (cairo_gstate_t *gstate); /* cairo-region.c */ +cairo_private pixman_region16_t * +_cairo_region_create_from_rectangle (cairo_rectangle_int16_t *rect); + cairo_private void _cairo_region_extents_rectangle (pixman_region16_t *region, cairo_rectangle_int16_t *rect); @@ -2377,6 +2545,9 @@ _cairo_utf8_to_utf16 (const unsigned char *str, cairo_private void _cairo_error (cairo_status_t status); +cairo_private int +_cairo_dtostr (char *buffer, size_t size, double d); + /* Avoid unnecessary PLT entries. */ slim_hidden_proto (cairo_clip_preserve); slim_hidden_proto (cairo_close_path); @@ -2385,7 +2556,7 @@ slim_hidden_proto (cairo_curve_to); slim_hidden_proto (cairo_destroy); slim_hidden_proto (cairo_fill_preserve); slim_hidden_proto (cairo_font_face_destroy); -slim_hidden_proto_no_warn (cairo_font_face_reference); +slim_hidden_proto (cairo_font_face_reference); slim_hidden_proto (cairo_font_options_create); slim_hidden_proto (cairo_font_options_destroy); slim_hidden_proto (cairo_font_options_equal); @@ -2395,7 +2566,6 @@ slim_hidden_proto (cairo_font_options_set_antialias); slim_hidden_proto (cairo_font_options_set_hint_metrics); slim_hidden_proto (cairo_font_options_set_hint_style); slim_hidden_proto (cairo_font_options_set_subpixel_order); -slim_hidden_proto (cairo_font_options_status); slim_hidden_proto (cairo_get_current_point); slim_hidden_proto (cairo_get_matrix); slim_hidden_proto (cairo_get_tolerance); @@ -2425,7 +2595,7 @@ slim_hidden_proto (cairo_pattern_create_rgba); slim_hidden_proto (cairo_pattern_destroy); slim_hidden_proto (cairo_pattern_get_extend); slim_hidden_proto (cairo_pattern_get_type); -slim_hidden_proto_no_warn (cairo_pattern_reference); +slim_hidden_proto (cairo_pattern_reference); slim_hidden_proto (cairo_pattern_set_matrix); slim_hidden_proto (cairo_pattern_status); slim_hidden_proto (cairo_pop_group); @@ -2444,8 +2614,7 @@ slim_hidden_proto (cairo_scaled_font_get_font_face); slim_hidden_proto (cairo_scaled_font_get_font_matrix); slim_hidden_proto (cairo_scaled_font_get_font_options); slim_hidden_proto (cairo_scaled_font_glyph_extents); -slim_hidden_proto_no_warn (cairo_scaled_font_reference); -slim_hidden_proto (cairo_scaled_font_status); +slim_hidden_proto (cairo_scaled_font_reference); slim_hidden_proto (cairo_set_operator); slim_hidden_proto (cairo_set_source); slim_hidden_proto (cairo_set_source_surface); @@ -2459,7 +2628,7 @@ slim_hidden_proto (cairo_surface_get_device_offset); slim_hidden_proto (cairo_surface_get_font_options); slim_hidden_proto (cairo_surface_get_type); slim_hidden_proto (cairo_surface_mark_dirty_rectangle); -slim_hidden_proto_no_warn (cairo_surface_reference); +slim_hidden_proto (cairo_surface_reference); slim_hidden_proto (cairo_surface_set_device_offset); slim_hidden_proto (cairo_surface_set_fallback_resolution); slim_hidden_proto (cairo_surface_status); diff --git a/gfx/cairo/cairo/src/filterpublic.awk b/gfx/cairo/cairo/src/filterpublic.awk index d35a6b5e5163..da645d605a2c 100644 --- a/gfx/cairo/cairo/src/filterpublic.awk +++ b/gfx/cairo/cairo/src/filterpublic.awk @@ -16,4 +16,5 @@ BEGIN { state = "public"; } # catch some one-off things END { + print "#define _cairo_image_surface_nil_invalid_format __moz__cairo_image_surface_nil_invalid_format"; } diff --git a/gfx/cairo/cairo/src/test-fallback-surface.c b/gfx/cairo/cairo/src/test-fallback-surface.c index b2fa03ef6245..21ee19077fbd 100644 --- a/gfx/cairo/cairo/src/test-fallback-surface.c +++ b/gfx/cairo/cairo/src/test-fallback-surface.c @@ -51,10 +51,10 @@ * there. */ -#include "cairoint.h" - #include "test-fallback-surface.h" +#include "cairoint.h" + typedef struct _test_fallback_surface { cairo_surface_t base; @@ -80,7 +80,6 @@ _cairo_test_fallback_surface_create (cairo_content_t content, surface = malloc (sizeof (test_fallback_surface_t)); if (surface == NULL) { - cairo_surface_destroy (backing); _cairo_error (CAIRO_STATUS_NO_MEMORY); return (cairo_surface_t*) &_cairo_surface_nil; } @@ -170,26 +169,6 @@ _test_fallback_surface_release_dest_image (void *abstract_surface, image_extra); } -static cairo_status_t -_test_fallback_surface_clone_similar (void *abstract_surface, - cairo_surface_t *src, - int src_x, - int src_y, - int width, - int height, - cairo_surface_t **clone_out) -{ - test_fallback_surface_t *surface = abstract_surface; - - if (src->backend == surface->base.backend) { - *clone_out = cairo_surface_reference (src); - - return CAIRO_STATUS_SUCCESS; - } - - return CAIRO_INT_STATUS_UNSUPPORTED; -} - static cairo_int_status_t _test_fallback_surface_get_extents (void *abstract_surface, cairo_rectangle_int16_t *rectangle) @@ -207,7 +186,7 @@ const cairo_surface_backend_t test_fallback_surface_backend = { _test_fallback_surface_release_source_image, _test_fallback_surface_acquire_dest_image, _test_fallback_surface_release_dest_image, - _test_fallback_surface_clone_similar, + NULL, /* clone_similar */ NULL, /* composite */ NULL, /* fill_rectangles */ NULL, /* composite_trapezoids */ diff --git a/gfx/cairo/cairo/src/test-meta-surface.c b/gfx/cairo/cairo/src/test-meta-surface.c index e2f6a0977bf7..6c5877971edc 100644 --- a/gfx/cairo/cairo/src/test-meta-surface.c +++ b/gfx/cairo/cairo/src/test-meta-surface.c @@ -45,10 +45,9 @@ * backend. */ -#include "cairoint.h" - #include "test-meta-surface.h" +#include "cairoint.h" #include "cairo-meta-surface-private.h" typedef struct _test_meta_surface { @@ -144,14 +143,11 @@ static cairo_int_status_t _test_meta_surface_show_page (void *abstract_surface) { test_meta_surface_t *surface = abstract_surface; - cairo_status_t status; if (surface->image_reflects_meta) return CAIRO_STATUS_SUCCESS; - status = _cairo_meta_surface_replay (surface->meta, surface->image); - if (status) - return status; + _cairo_meta_surface_replay (surface->meta, surface->image); surface->image_reflects_meta = TRUE; @@ -283,7 +279,6 @@ static cairo_surface_t * _test_meta_surface_snapshot (void *abstract_other) { test_meta_surface_t *other = abstract_other; - cairo_status_t status; /* XXX: Just making a snapshot of other->meta is what we really * want. But this currently triggers a bug somewhere (the "mask" @@ -303,20 +298,14 @@ _test_meta_surface_snapshot (void *abstract_other) cairo_rectangle_int16_t extents; cairo_surface_t *surface; - status = _cairo_surface_get_extents (other->image, &extents); - if (status) - return (cairo_surface_t*) &_cairo_surface_nil; + _cairo_surface_get_extents (other->image, &extents); surface = cairo_surface_create_similar (other->image, CAIRO_CONTENT_COLOR_ALPHA, 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 diff --git a/gfx/cairo/cairo/src/test-paginated-surface.c b/gfx/cairo/cairo/src/test-paginated-surface.c index 53e97eba66ec..d82749f69d9c 100644 --- a/gfx/cairo/cairo/src/test-paginated-surface.c +++ b/gfx/cairo/cairo/src/test-paginated-surface.c @@ -45,11 +45,11 @@ * backend. */ -#include "cairoint.h" - #include "test-paginated-surface.h" -#include "cairo-paginated-private.h" +#include "cairoint.h" + +#include "cairo-paginated-surface-private.h" typedef struct _test_paginated_surface { cairo_surface_t base; diff --git a/gfx/cairo/fbcompose-bandaid.patch b/gfx/cairo/fbcompose-bandaid.patch index 2f4754d6af8e..e72494c43dcb 100644 --- a/gfx/cairo/fbcompose-bandaid.patch +++ b/gfx/cairo/fbcompose-bandaid.patch @@ -1,15 +1,34 @@ -diff -r 37dcf8c8ef5e gfx/cairo/libpixman/src/fbcompose.c ---- a/gfx/cairo/libpixman/src/fbcompose.c Fri Jun 08 17:16:14 2007 -0700 -+++ b/gfx/cairo/libpixman/src/fbcompose.c Fri Jun 08 17:18:31 2007 -0700 -@@ -28,6 +28,7 @@ - +Index: fbcompose.c +=================================================================== +RCS file: /cvsroot/mozilla/gfx/cairo/libpixman/src/fbcompose.c,v +retrieving revision 1.6 +diff -u -8 -p -r1.6 fbcompose.c +--- pixman/src/fbcompose.c 11 Jan 2006 00:48:57 -0000 1.6 ++++ pixman/src/fbcompose.c 8 Feb 2006 00:27:16 -0000 +@@ -23,16 +23,17 @@ + * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS + * SOFTWARE. + */ + #ifdef HAVE_CONFIG_H + #include + #endif #include "pixman-xserver-compat.h" #include "fbpict.h" +#include "fbmmx.h" #ifdef RENDER -@@ -4093,6 +4094,24 @@ fbCompositeRect (const FbComposeData *da + #include "pixregionint.h" + + #ifdef _MSC_VER + #define _USE_MATH_DEFINES + #endif +@@ -3756,16 +3757,34 @@ fbCompositeRect (const FbComposeData *da + data->mask->componentAlpha && + PICT_FORMAT_RGB (data->mask->format_code)) + { + CARD32 *mask_buffer = dest_buffer + data->width; + CombineFuncC compose = composeFunctions.combineC[data->op]; if (!compose) return; @@ -34,3 +53,8 @@ diff -r 37dcf8c8ef5e gfx/cairo/libpixman/src/fbcompose.c for (i = 0; i < data->height; ++i) { /* fill first half of scanline with source */ if (fetchSrc) + { + if (fetchMask) + { + /* fetch mask before source so that fetching of + source can be optimized */ diff --git a/gfx/cairo/libpixman/src/fbcompose.c b/gfx/cairo/libpixman/src/fbcompose.c index 24b8ecef72c2..ef0be03567f7 100644 --- a/gfx/cairo/libpixman/src/fbcompose.c +++ b/gfx/cairo/libpixman/src/fbcompose.c @@ -23,12 +23,14 @@ * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS * SOFTWARE. */ - -#include "pixmanint.h" - +#ifdef HAVE_CONFIG_H +#include +#endif #include "pixman-xserver-compat.h" #include "fbpict.h" +#ifndef MOZILLA_CAIRO_NOT_DEFINED #include "fbmmx.h" +#endif /* MOZCAIRO */ #ifdef RENDER @@ -1742,7 +1744,7 @@ fbCombineSaturateU (CARD32 *dest, const CARD32 *src, int width) #define CombineXor (CombineAOut|CombineBOut) /* portion covered by a but not b */ -static inline CARD8 +static INLINE CARD8 fbCombineDisjointOutPart (CARD8 a, CARD8 b) { /* min (1, (1-b) / a) */ @@ -1754,7 +1756,7 @@ fbCombineDisjointOutPart (CARD8 a, CARD8 b) } /* portion covered by both a and b */ -static inline CARD8 +static INLINE CARD8 fbCombineDisjointInPart (CARD8 a, CARD8 b) { /* max (1-(1-b)/a,0) */ @@ -1882,7 +1884,7 @@ fbCombineDisjointXorU (CARD32 *dest, const CARD32 *src, int width) } /* portion covered by a but not b */ -static inline CARD8 +static INLINE CARD8 fbCombineConjointOutPart (CARD8 a, CARD8 b) { /* max (1-b/a,0) */ @@ -1896,7 +1898,7 @@ fbCombineConjointOutPart (CARD8 a, CARD8 b) } /* portion covered by both a and b */ -static inline CARD8 +static INLINE CARD8 fbCombineConjointInPart (CARD8 a, CARD8 b) { /* min (1,b/a) */ @@ -2057,80 +2059,89 @@ static CombineFuncU fbCombineFuncU[] = { fbCombineConjointXorU, }; -static inline void -fbCombineMaskC (CARD32 *src, CARD32 *mask) +static FASTCALL void +fbCombineMaskC (CARD32 *src, CARD32 *mask, int width) { - CARD32 a = *mask; + int i; + for (i = 0; i < width; ++i) { + CARD32 a = mask[i]; - CARD32 x; - CARD16 xa; + CARD32 x; + CARD16 xa; - if (!a) - { - *src = 0; - return; + if (!a) + { + src[i] = 0; + continue; + } + + x = src[i]; + if (a == 0xffffffff) + { + x = x >> 24; + x |= x << 8; + x |= x << 16; + mask[i] = x; + continue; + } + + xa = x >> 24; + FbByteMulC(x, a); + src[i] = x; + FbByteMul(a, xa); + mask[i] = a; } - - x = *src; - if (a == 0xffffffff) - { - x = x >> 24; - x |= x << 8; - x |= x << 16; - *mask = x; - return; - } - - xa = x >> 24; - FbByteMulC(x, a); - *src = x; - FbByteMul(a, xa); - *mask = a; } -static inline void -fbCombineMaskValueC (CARD32 *src, const CARD32 *mask) +static FASTCALL void +fbCombineMaskValueC (CARD32 *src, const CARD32 *mask, int width) { - CARD32 a = *mask; - CARD32 x; + int i; + for (i = 0; i < width; ++i) { + CARD32 a = mask[i]; + CARD32 x; - if (!a) - { - *src = 0; - return; + if (!a) + { + src[i] = 0; + continue; + } + + if (a == 0xffffffff) + continue; + + x = src[i]; + FbByteMulC(x, a); + src[i] = x; } - - if (a == 0xffffffff) - return; - - x = *src; - FbByteMulC(x, a); - *src = x; } -static inline void -fbCombineMaskAlphaC (const CARD32 *src, CARD32 *mask) +static FASTCALL void +fbCombineMaskAlphaC (const CARD32 *src, CARD32 *mask, int width) { - CARD32 a = *mask; - CARD32 x; + int i; + for (i = 0; i < width; ++i) { + CARD32 a = mask[i]; + CARD32 x; - if (!a) - return; + if (!a) + continue; - x = *src >> 24; - if (x == 0xff) - return; - if (a == 0xffffffff) - { - x = x >> 24; - x |= x << 8; - x |= x << 16; - *mask = x; - return; + x = src[i] >> 24; + if (x == 0xff) + continue; + if (a == 0xffffffff) + { + x = x >> 24; + x |= x << 8; + x |= x << 16; + mask[i] = x; + continue; + } + + FbByteMul(a, x); + mask[i] = a; } - - FbByteMul(a, x); - *mask = a; } static FASTCALL void @@ -2142,31 +2153,19 @@ fbCombineClearC (CARD32 *dest, CARD32 *src, CARD32 *mask, int width) static FASTCALL void fbCombineSrcC (CARD32 *dest, CARD32 *src, CARD32 *mask, int width) { - int i; - - for (i = 0; i < width; ++i) { - CARD32 s = src[i]; - CARD32 m = mask[i]; - - fbCombineMaskValueC (&s, &m); - - *dest = s; - } + fbCombineMaskValueC(src, mask, width); + memcpy(dest, src, width*sizeof(CARD32)); } static FASTCALL void fbCombineOverC (CARD32 *dest, CARD32 *src, CARD32 *mask, int width) { int i; - + fbCombineMaskC(src, mask, width); for (i = 0; i < width; ++i) { - CARD32 s = src[i]; - CARD32 m = mask[i]; - CARD32 a; + CARD32 s = src[i]; + CARD32 a = ~mask[i]; - fbCombineMaskC (&s, &m); - - a = ~m; if (a != 0xffffffff) { if (a) @@ -2184,7 +2183,7 @@ static FASTCALL void fbCombineOverReverseC (CARD32 *dest, CARD32 *src, CARD32 *mask, int width) { int i; - + fbCombineMaskValueC(src, mask, width); for (i = 0; i < width; ++i) { CARD32 d = dest[i]; CARD32 a = ~d >> 24; @@ -2192,10 +2191,6 @@ fbCombineOverReverseC (CARD32 *dest, CARD32 *src, CARD32 *mask, int width) if (a) { CARD32 s = src[i]; - CARD32 m = mask[i]; - - fbCombineMaskValueC (&s, &m); - if (a != 0xff) { FbByteMulAdd(s, a, d); @@ -2209,17 +2204,14 @@ static FASTCALL void fbCombineInC (CARD32 *dest, CARD32 *src, CARD32 *mask, int width) { int i; - + fbCombineMaskValueC(src, mask, width); for (i = 0; i < width; ++i) { CARD32 d = dest[i]; CARD16 a = d >> 24; CARD32 s = 0; if (a) { - CARD32 m = mask[i]; - - s = src[i]; - fbCombineMaskValueC (&s, &m); + s = src[i]; if (a != 0xff) { FbByteMul(s, a); @@ -2233,15 +2225,10 @@ static FASTCALL void fbCombineInReverseC (CARD32 *dest, CARD32 *src, CARD32 *mask, int width) { int i; - + fbCombineMaskAlphaC(src, mask, width); for (i = 0; i < width; ++i) { - CARD32 s = src[i]; - CARD32 m = mask[i]; - CARD32 a; + CARD32 a = mask[i]; - fbCombineMaskAlphaC (&s, &m); - - a = m; if (a != 0xffffffff) { CARD32 d = 0; @@ -2259,18 +2246,14 @@ static FASTCALL void fbCombineOutC (CARD32 *dest, CARD32 *src, CARD32 *mask, int width) { int i; - + fbCombineMaskValueC(src, mask, width); for (i = 0; i < width; ++i) { CARD32 d = dest[i]; CARD16 a = ~d >> 24; CARD32 s = 0; if (a) { - CARD32 m = mask[i]; - - s = src[i]; - fbCombineMaskValueC (&s, &m); - + s = src[i]; if (a != 0xff) { FbByteMul(s, a); @@ -2284,15 +2267,10 @@ static FASTCALL void fbCombineOutReverseC (CARD32 *dest, CARD32 *src, CARD32 *mask, int width) { int i; - + fbCombineMaskAlphaC(src, mask, width); for (i = 0; i < width; ++i) { - CARD32 s = src[i]; - CARD32 m = mask[i]; - CARD32 a; + CARD32 a = ~mask[i]; - fbCombineMaskAlphaC (&s, &m); - - a = ~m; if (a != 0xffffffff) { CARD32 d = 0; @@ -2310,18 +2288,12 @@ static FASTCALL void fbCombineAtopC (CARD32 *dest, CARD32 *src, CARD32 *mask, int width) { int i; - + fbCombineMaskC(src, mask, width); for (i = 0; i < width; ++i) { CARD32 d = dest[i]; CARD32 s = src[i]; - CARD32 m = mask[i]; - CARD32 ad; + CARD32 ad = ~mask[i]; CARD16 as = d >> 24; - - fbCombineMaskC (&s, &m); - - ad = ~m; - FbByteAddMulC(d, ad, s, as); dest[i] = d; } @@ -2331,19 +2303,13 @@ static FASTCALL void fbCombineAtopReverseC (CARD32 *dest, CARD32 *src, CARD32 *mask, int width) { int i; - + fbCombineMaskC(src, mask, width); for (i = 0; i < width; ++i) { CARD32 d = dest[i]; CARD32 s = src[i]; - CARD32 m = mask[i]; - CARD32 ad; + CARD32 ad = mask[i]; CARD16 as = ~d >> 24; - - fbCombineMaskC (&s, &m); - - ad = m; - FbByteAddMulC(d, ad, s, as); dest[i] = d; } @@ -2353,18 +2319,12 @@ static FASTCALL void fbCombineXorC (CARD32 *dest, CARD32 *src, CARD32 *mask, int width) { int i; - + fbCombineMaskC(src, mask, width); for (i = 0; i < width; ++i) { CARD32 d = dest[i]; CARD32 s = src[i]; - CARD32 m = mask[i]; - CARD32 ad; + CARD32 ad = ~mask[i]; CARD16 as = ~d >> 24; - - fbCombineMaskC (&s, &m); - - ad = ~m; - FbByteAddMulC(d, ad, s, as); dest[i] = d; } @@ -2374,14 +2334,10 @@ static FASTCALL void fbCombineAddC (CARD32 *dest, CARD32 *src, CARD32 *mask, int width) { int i; - + fbCombineMaskValueC(src, mask, width); for (i = 0; i < width; ++i) { CARD32 s = src[i]; - CARD32 m = mask[i]; CARD32 d = dest[i]; - - fbCombineMaskValueC (&s, &m); - FbByteAdd(d, s); dest[i] = d; } @@ -2391,7 +2347,7 @@ static FASTCALL void fbCombineSaturateC (CARD32 *dest, CARD32 *src, CARD32 *mask, int width) { int i; - + fbCombineMaskC(src, mask, width); for (i = 0; i < width; ++i) { CARD32 s, d; CARD16 sa, sr, sg, sb, da; @@ -2400,14 +2356,10 @@ fbCombineSaturateC (CARD32 *dest, CARD32 *src, CARD32 *mask, int width) d = dest[i]; s = src[i]; - m = mask[i]; - - fbCombineMaskC (&s, &m); - - sa = (m >> 24); - sr = (m >> 16) & 0xff; - sg = (m >> 8) & 0xff; - sb = (m ) & 0xff; + sa = (mask[i] >> 24); + sr = (mask[i] >> 16) & 0xff; + sg = (mask[i] >> 8) & 0xff; + sb = (mask[i] ) & 0xff; da = ~d >> 24; if (sb <= da) @@ -2438,7 +2390,7 @@ static FASTCALL void fbCombineDisjointGeneralC (CARD32 *dest, CARD32 *src, CARD32 *mask, int width, CARD8 combine) { int i; - + fbCombineMaskC(src, mask, width); for (i = 0; i < width; ++i) { CARD32 s, d; CARD32 m,n,o,p; @@ -2448,14 +2400,10 @@ fbCombineDisjointGeneralC (CARD32 *dest, CARD32 *src, CARD32 *mask, int width, C CARD8 da; s = src[i]; - m = mask[i]; + sa = mask[i]; d = dest[i]; da = d >> 24; - fbCombineMaskC (&s, &m); - - sa = m; - switch (combine & CombineA) { default: Fa = 0; @@ -2562,7 +2510,7 @@ static FASTCALL void fbCombineConjointGeneralC (CARD32 *dest, CARD32 *src, CARD32 *mask, int width, CARD8 combine) { int i; - + fbCombineMaskC(src, mask, width); for (i = 0; i < width; ++i) { CARD32 s, d; CARD32 m,n,o,p; @@ -2572,14 +2520,10 @@ fbCombineConjointGeneralC (CARD32 *dest, CARD32 *src, CARD32 *mask, int width, C CARD8 da; s = src[i]; - m = mask[i]; + sa = mask[i]; d = dest[i]; da = d >> 24; - fbCombineMaskC (&s, &m); - - sa = m; - switch (combine & CombineA) { default: Fa = 0; @@ -3431,8 +3375,8 @@ static void fbFetchTransformed(PicturePtr pict, int x, int y, int width, CARD32 if (pict->filter == PIXMAN_FILTER_NEAREST || pict->filter == PIXMAN_FILTER_FAST) { if (pict->repeat == RepeatNormal) { - if (PIXREGION_NUM_RECTS(&pict->sourceClip) == 1) { - box = pict->sourceClip.extents; + if (PIXREGION_NUM_RECTS(pict->pSourceClip) == 1) { + box = pict->pSourceClip->extents; for (i = 0; i < width; ++i) { if (!mask || mask[i] & maskBits) { @@ -3467,7 +3411,7 @@ static void fbFetchTransformed(PicturePtr pict, int x, int y, int width, CARD32 y = MOD(v.vector[1]>>16, pict->pDrawable->height); x = MOD(v.vector[0]>>16, pict->pDrawable->width); } - if (pixman_region_contains_point (&pict->sourceClip, x, y, &box)) + if (pixman_region_contains_point (pict->pSourceClip, x, y, &box)) buffer[i] = fetch(bits + (y + pict->pDrawable->y)*stride, x + pict->pDrawable->x, indexed); else buffer[i] = 0; @@ -3479,8 +3423,8 @@ static void fbFetchTransformed(PicturePtr pict, int x, int y, int width, CARD32 } } } else { - if (PIXREGION_NUM_RECTS(&pict->sourceClip) == 1) { - box = pict->sourceClip.extents; + if (PIXREGION_NUM_RECTS(pict->pSourceClip) == 1) { + box = pict->pSourceClip->extents; for (i = 0; i < width; ++i) { if (!mask || mask[i] & maskBits) { @@ -3514,7 +3458,7 @@ static void fbFetchTransformed(PicturePtr pict, int x, int y, int width, CARD32 y = v.vector[1]>>16; x = v.vector[0]>>16; } - if (pixman_region_contains_point (&pict->sourceClip, x, y, &box)) + if (pixman_region_contains_point (pict->pSourceClip, x, y, &box)) buffer[i] = fetch(bits + (y + pict->pDrawable->y)*stride, x + pict->pDrawable->x, indexed); else buffer[i] = 0; @@ -3533,8 +3477,8 @@ static void fbFetchTransformed(PicturePtr pict, int x, int y, int width, CARD32 unit.vector[1] -= unit.vector[2]/2; if (pict->repeat == RepeatNormal) { - if (PIXREGION_NUM_RECTS(&pict->sourceClip) == 1) { - box = pict->sourceClip.extents; + if (PIXREGION_NUM_RECTS(pict->pSourceClip) == 1) { + box = pict->pSourceClip->extents; for (i = 0; i < width; ++i) { if (!mask || mask[i] & maskBits) { @@ -3637,14 +3581,14 @@ static void fbFetchTransformed(PicturePtr pict, int x, int y, int width, CARD32 b = bits + (y1 + pict->pDrawable->y)*stride; - tl = pixman_region_contains_point(&pict->sourceClip, x1, y1, &box) + tl = pixman_region_contains_point(pict->pSourceClip, x1, y1, &box) ? fetch(b, x1 + pict->pDrawable->x, indexed) : 0; - tr = pixman_region_contains_point(&pict->sourceClip, x2, y1, &box) + tr = pixman_region_contains_point(pict->pSourceClip, x2, y1, &box) ? fetch(b, x2 + pict->pDrawable->x, indexed) : 0; b = bits + (y2 + pict->pDrawable->y)*stride; - bl = pixman_region_contains_point(&pict->sourceClip, x1, y2, &box) + bl = pixman_region_contains_point(pict->pSourceClip, x1, y2, &box) ? fetch(b, x1 + pict->pDrawable->x, indexed) : 0; - br = pixman_region_contains_point(&pict->sourceClip, x2, y2, &box) + br = pixman_region_contains_point(pict->pSourceClip, x2, y2, &box) ? fetch(b, x2 + pict->pDrawable->x, indexed) : 0; ft = FbGet8(tl,0) * idistx + FbGet8(tr,0) * distx; @@ -3668,8 +3612,8 @@ static void fbFetchTransformed(PicturePtr pict, int x, int y, int width, CARD32 } } } else { - if (PIXREGION_NUM_RECTS(&pict->sourceClip) == 1) { - box = pict->sourceClip.extents; + if (PIXREGION_NUM_RECTS(pict->pSourceClip) == 1) { + box = pict->pSourceClip->extents; for (i = 0; i < width; ++i) { if (!mask || mask[i] & maskBits) { @@ -3770,14 +3714,14 @@ static void fbFetchTransformed(PicturePtr pict, int x, int y, int width, CARD32 b = bits + (y1 + pict->pDrawable->y)*stride; x_off = x1 + pict->pDrawable->x; - tl = pixman_region_contains_point(&pict->sourceClip, x1, y1, &box) + tl = pixman_region_contains_point(pict->pSourceClip, x1, y1, &box) ? fetch(b, x_off, indexed) : 0; - tr = pixman_region_contains_point(&pict->sourceClip, x2, y1, &box) + tr = pixman_region_contains_point(pict->pSourceClip, x2, y1, &box) ? fetch(b, x_off + 1, indexed) : 0; b += stride; - bl = pixman_region_contains_point(&pict->sourceClip, x1, y2, &box) + bl = pixman_region_contains_point(pict->pSourceClip, x1, y2, &box) ? fetch(b, x_off, indexed) : 0; - br = pixman_region_contains_point(&pict->sourceClip, x2, y2, &box) + br = pixman_region_contains_point(pict->pSourceClip, x2, y2, &box) ? fetch(b, x_off + 1, indexed) : 0; ft = FbGet8(tl,0) * idistx + FbGet8(tr,0) * distx; @@ -3839,7 +3783,7 @@ static void fbFetchTransformed(PicturePtr pict, int x, int y, int width, CARD32 for (x = x1; x < x2; x++) { if (*p) { int tx = (pict->repeat == RepeatNormal) ? MOD (x, pict->pDrawable->width) : x; - if (pixman_region_contains_point (&pict->sourceClip, tx, ty, &box)) { + if (pixman_region_contains_point (pict->pSourceClip, tx, ty, &box)) { FbBits *b = bits + (ty + pict->pDrawable->y)*stride; CARD32 c = fetch(b, tx + pict->pDrawable->x, indexed); @@ -4094,6 +4038,7 @@ fbCompositeRect (const FbComposeData *data, CARD32 *scanline_buffer) if (!compose) return; +#ifndef MOZILLA_CAIRO_NOT_DEFINED /* XXX: The non-MMX version of some of the fbCompose functions * overwrite the source or mask data (ones that use * fbCombineMaskC, fbCombineMaskAlphaC, or fbCombineMaskValueC @@ -4111,6 +4056,7 @@ fbCompositeRect (const FbComposeData *data, CARD32 *scanline_buffer) srcClass = SourcePictClassUnknown; maskClass = SourcePictClassUnknown; } +#endif /* MOZCAIRO */ for (i = 0; i < data->height; ++i) { /* fill first half of scanline with source */ @@ -4273,7 +4219,7 @@ pixman_compositeGeneral (pixman_operator_t op, CARD16 width, CARD16 height) { - pixman_region16_t region; + pixman_region16_t *region; int n; BoxPtr pbox; Bool srcRepeat = FALSE; @@ -4294,11 +4240,22 @@ pixman_compositeGeneral (pixman_operator_t op, if (op == PIXMAN_OPERATOR_OVER && !pMask && !pSrc->transform && !PICT_FORMAT_A(pSrc->format_code) && !pSrc->alphaMap) op = PIXMAN_OPERATOR_SRC; - pixman_region_init_rect (®ion, xDst, yDst, width, height); + region = pixman_region_create(); + pixman_region_union_rect (region, region, xDst, yDst, width, height); - if (!FbComputeCompositeRegion (®ion, pSrc, pMask, pDst, xSrc, ySrc, - xMask, yMask, xDst, yDst, width, height)) - goto CLEANUP_REGION; + if (!FbComputeCompositeRegion (region, + pSrc, + pMask, + pDst, + xSrc, + ySrc, + xMask, + yMask, + xDst, + yDst, + width, + height)) + return; compose_data.op = op; compose_data.src = pSrc; @@ -4307,8 +4264,8 @@ pixman_compositeGeneral (pixman_operator_t op, if (width > SCANLINE_BUFFER_LENGTH) scanline_buffer = (CARD32 *) malloc(width * 3 * sizeof(CARD32)); - n = pixman_region_num_rects (®ion); - pbox = pixman_region_rects (®ion); + n = pixman_region_num_rects (region); + pbox = pixman_region_rects (region); while (n--) { h = pbox->y2 - pbox->y1; @@ -4362,12 +4319,10 @@ pixman_compositeGeneral (pixman_operator_t op, } pbox++; } + pixman_region_destroy (region); if (scanline_buffer != _scanline_buffer) free(scanline_buffer); - -CLEANUP_REGION: - pixman_region_fini (®ion); } #endif diff --git a/gfx/cairo/libpixman/src/fbedge.c b/gfx/cairo/libpixman/src/fbedge.c index 1552dfcb6151..e06ed20b8df7 100644 --- a/gfx/cairo/libpixman/src/fbedge.c +++ b/gfx/cairo/libpixman/src/fbedge.c @@ -20,8 +20,6 @@ * PERFORMANCE OF THIS SOFTWARE. */ -#include "pixmanint.h" - #include #include "pixman-xserver-compat.h" @@ -79,14 +77,14 @@ * 8 bit alpha */ -static inline CARD8 +static INLINE CARD8 clip255 (int x) { if (x > 255) return 255; return x; } -static inline void +static INLINE void add_saturate_8 (CARD8 *buf, int value, int length) { while (length--) diff --git a/gfx/cairo/libpixman/src/fbmmx.c b/gfx/cairo/libpixman/src/fbmmx.c index 57dcd14b259a..387d4b46e68c 100644 --- a/gfx/cairo/libpixman/src/fbmmx.c +++ b/gfx/cairo/libpixman/src/fbmmx.c @@ -29,7 +29,9 @@ * Based on work by Owen Taylor */ -#include "pixmanint.h" +#ifdef HAVE_CONFIG_H +#include +#endif #include #include "fbpict.h" @@ -145,8 +147,7 @@ static const MMXData c = }; #ifdef _MSC_VER -#undef inline -#define inline __forceinline +#define __inline__ __forceinline #endif #ifdef __GNUC__ @@ -161,7 +162,7 @@ static const MMXData c = */ #define M64(x) (*(__m64*)(void*)(&x)) -static inline __m64 +static __inline__ __m64 shift (__m64 v, int s) { if (s > 0) @@ -172,13 +173,13 @@ shift (__m64 v, int s) return v; } -static inline __m64 +static __inline__ __m64 negate (__m64 mask) { return _mm_xor_si64 (mask, MC(4x00ff)); } -static inline __m64 +static __inline__ __m64 pix_multiply (__m64 a, __m64 b) { __m64 res; @@ -191,7 +192,7 @@ pix_multiply (__m64 a, __m64 b) return res; } -static inline __m64 +static __inline__ __m64 pix_add (__m64 a, __m64 b) { return _mm_adds_pu8 (a, b); @@ -199,19 +200,19 @@ pix_add (__m64 a, __m64 b) #ifdef USE_SSE -static inline __m64 +static __inline__ __m64 expand_alpha (__m64 pixel) { return _mm_shuffle_pi16 (pixel, _MM_SHUFFLE(3, 3, 3, 3)); } -static inline __m64 +static __inline__ __m64 expand_alpha_rev (__m64 pixel) { return _mm_shuffle_pi16 (pixel, _MM_SHUFFLE(0, 0, 0, 0)); } -static inline __m64 +static __inline__ __m64 invert_colors (__m64 pixel) { return _mm_shuffle_pi16 (pixel, _MM_SHUFFLE(3, 0, 1, 2)); @@ -219,7 +220,7 @@ invert_colors (__m64 pixel) #else -static inline __m64 +static __inline__ __m64 expand_alpha (__m64 pixel) { __m64 t1, t2; @@ -233,7 +234,7 @@ expand_alpha (__m64 pixel) return t1; } -static inline __m64 +static __inline__ __m64 expand_alpha_rev (__m64 pixel) { __m64 t1, t2; @@ -250,7 +251,7 @@ expand_alpha_rev (__m64 pixel) return t1; } -static inline __m64 +static __inline__ __m64 invert_colors (__m64 pixel) { __m64 x, y, z; @@ -272,13 +273,13 @@ invert_colors (__m64 pixel) #endif -static inline __m64 +static __inline__ __m64 over (__m64 src, __m64 srca, __m64 dest) { return _mm_adds_pu8 (src, pix_multiply(dest, negate(srca))); } -static inline __m64 +static __inline__ __m64 over_rev_non_pre (__m64 src, __m64 dest) { __m64 srca = expand_alpha (src); @@ -287,7 +288,7 @@ over_rev_non_pre (__m64 src, __m64 dest) return over(pix_multiply(invert_colors(src), srcfaaa), srca, dest); } -static inline __m64 +static __inline__ __m64 in (__m64 src, __m64 mask) { @@ -295,7 +296,7 @@ in (__m64 src, } #ifndef _MSC_VER -static inline __m64 +static __inline__ __m64 in_over (__m64 src, __m64 srca, __m64 mask, @@ -307,19 +308,19 @@ in_over (__m64 src, #define in_over(src, srca, mask, dest) over(in(src, mask), pix_multiply(srca, mask), dest) #endif -static inline __m64 +static __inline__ __m64 load8888 (CARD32 v) { return _mm_unpacklo_pi8 (_mm_cvtsi32_si64 (v), _mm_setzero_si64()); } -static inline __m64 +static __inline__ __m64 pack8888 (__m64 lo, __m64 hi) { return _mm_packs_pu16 (lo, hi); } -static inline CARD32 +static __inline__ CARD32 store8888 (__m64 v) { return _mm_cvtsi64_si32(pack8888(v, _mm_setzero_si64())); @@ -339,7 +340,7 @@ store8888 (__m64 v) * Note the trick here - the top word is shifted by another nibble to * avoid it bumping into the middle word */ -static inline __m64 +static __inline__ __m64 expand565 (__m64 pixel, int pos) { __m64 p = pixel; @@ -359,7 +360,7 @@ expand565 (__m64 pixel, int pos) return _mm_srli_pi16 (pixel, 8); } -static inline __m64 +static __inline__ __m64 expand8888 (__m64 in, int pos) { if (pos == 0) @@ -368,7 +369,7 @@ expand8888 (__m64 in, int pos) return _mm_unpackhi_pi8 (in, _mm_setzero_si64()); } -static inline __m64 +static __inline__ __m64 pack565 (__m64 pixel, __m64 target, int pos) { __m64 p = pixel; @@ -399,7 +400,7 @@ pack565 (__m64 pixel, __m64 target, int pos) } #ifndef _MSC_VER -static inline __m64 +static __inline__ __m64 pix_add_mul (__m64 x, __m64 a, __m64 y, __m64 b) { x = _mm_mullo_pi16 (x, a); @@ -1194,9 +1195,10 @@ fbCompositeSrc_8888x8x8888mmx (pixman_operator_t op, { CARD32 *dstLine, *dst; CARD32 *srcLine, *src; + CARD8 *maskLine; CARD32 mask; __m64 vmask; - FbStride dstStride, srcStride; + FbStride dstStride, srcStride, maskStride; CARD16 w; __m64 srca; @@ -1204,9 +1206,9 @@ fbCompositeSrc_8888x8x8888mmx (pixman_operator_t op, fbComposeGetStart (pDst, xDst, yDst, CARD32, dstStride, dstLine, 1); fbComposeGetStart (pSrc, xSrc, ySrc, CARD32, srcStride, srcLine, 1); + fbComposeGetStart (pMask, xMask, yMask, CARD8, maskStride, maskLine, 1); - fbComposeGetSolid (pMask, pDst, mask); - mask = mask | mask >> 8 | mask >> 16 | mask >> 24; + mask = *maskLine << 24 | *maskLine << 16 | *maskLine << 8 | *maskLine; vmask = load8888 (mask); srca = MC(4x00ff); @@ -1223,7 +1225,7 @@ fbCompositeSrc_8888x8x8888mmx (pixman_operator_t op, __m64 s = load8888 (*src); __m64 d = load8888 (*dst); - *dst = store8888 (in_over (s, expand_alpha (s), vmask, d)); + *dst = store8888 (over (s, expand_alpha (s), d)); w--; dst++; @@ -1232,8 +1234,8 @@ fbCompositeSrc_8888x8x8888mmx (pixman_operator_t op, while (w >= 2) { - __m64 vs = *(__m64 *)src; - __m64 vd = *(__m64 *)dst; + __m64 vs = *(__m64 *)dst; + __m64 vd = *(__m64 *)src; __m64 vsrc0 = expand8888 (vs, 0); __m64 vsrc1 = expand8888 (vs, 1); @@ -1278,9 +1280,10 @@ fbCompositeSrc_x888x8x8888mmx (pixman_operator_t op, { CARD32 *dstLine, *dst; CARD32 *srcLine, *src; + CARD8 *maskLine; CARD32 mask; __m64 vmask; - FbStride dstStride, srcStride; + FbStride dstStride, srcStride, maskStride; CARD16 w; __m64 srca; @@ -1288,9 +1291,9 @@ fbCompositeSrc_x888x8x8888mmx (pixman_operator_t op, fbComposeGetStart (pDst, xDst, yDst, CARD32, dstStride, dstLine, 1); fbComposeGetStart (pSrc, xSrc, ySrc, CARD32, srcStride, srcLine, 1); - fbComposeGetSolid (pMask, pDst, mask); + fbComposeGetStart (pMask, xMask, yMask, CARD8, maskStride, maskLine, 1); - mask = mask | mask >> 8 | mask >> 16 | mask >> 24; + mask = *maskLine << 24 | *maskLine << 16 | *maskLine << 8 | *maskLine; vmask = load8888 (mask); srca = MC(4x00ff); @@ -1654,102 +1657,6 @@ fbCompositeSolidMask_nx8x8888mmx (pixman_operator_t op, _mm_empty(); } -static void -fbSolidFillmmx (FbPixels *pDraw, - int x, - int y, - int width, - int height, - FbBits xor) -{ - FbStride stride; - int bpp; - ullong fill; - __m64 vfill; - CARD32 byte_width; - CARD8 *byte_line; - FbBits *bits; - int xoff, yoff; - - CHECKPOINT(); - - fbGetDrawable(pDraw, bits, stride, bpp, xoff, yoff); - - assert (bpp == 32 || (xor >> 16 == (xor & 0xffff))); - assert (bpp == 16 || bpp == 32); - - if (bpp == 16) - { - stride = stride * sizeof (FbBits) / 2; - byte_line = (CARD8 *)(((CARD16 *)bits) + stride * (y + yoff) + (x + xoff)); - byte_width = 2 * width; - stride *= 2; - } - else - { - stride = stride * sizeof (FbBits) / 4; - byte_line = (CARD8 *)(((CARD32 *)bits) + stride * (y + yoff) + (x + xoff)); - byte_width = 4 * width; - stride *= 4; - } - - fill = ((ullong)xor << 32) | xor; - vfill = M64(fill); - - while (height--) - { - unsigned int w; - CARD8 *d = byte_line; - byte_line += stride; - w = byte_width; - - while (w >= 2 && ((unsigned long)d & 3)) - { - *(CARD16 *)d = xor; - w -= 2; - d += 2; - } - - while (w >= 4 && ((unsigned long)d & 7)) - { - *(CARD32 *)d = xor; - - w -= 4; - d += 4; - } - - while (w >= 64) - { - *(__m64*) (d + 0) = vfill; - *(__m64*) (d + 8) = vfill; - *(__m64*) (d + 16) = vfill; - *(__m64*) (d + 24) = vfill; - *(__m64*) (d + 32) = vfill; - *(__m64*) (d + 40) = vfill; - *(__m64*) (d + 48) = vfill; - *(__m64*) (d + 56) = vfill; - - w -= 64; - d += 64; - } - while (w >= 4) - { - *(CARD32 *)d = xor; - - w -= 4; - d += 4; - } - if (w >= 2) - { - *(CARD16 *)d = xor; - w -= 2; - d += 2; - } - } - - _mm_empty(); -} - void fbCompositeSolidMaskSrc_nx8x8888mmx (pixman_operator_t op, PicturePtr pSrc, @@ -1779,8 +1686,8 @@ fbCompositeSolidMaskSrc_nx8x8888mmx (pixman_operator_t op, srca = src >> 24; if (srca == 0) { - fbSolidFillmmx (pDst->pDrawable, xDst, yDst, width, height, 0); - return; + if (fbSolidFillmmx (pDst->pDrawable, xDst, yDst, width, height, 0)) + return; } srcsrc = (ullong)src << 32 | src; @@ -2684,7 +2591,107 @@ fbCompositeSrcAdd_8888x8888mmx (pixman_operator_t op, _mm_empty(); } -static void +Bool +fbSolidFillmmx (FbPixels *pDraw, + int x, + int y, + int width, + int height, + FbBits xor) +{ + FbStride stride; + int bpp; + ullong fill; + __m64 vfill; + CARD32 byte_width; + CARD8 *byte_line; + FbBits *bits; + int xoff, yoff; + + CHECKPOINT(); + + fbGetDrawable(pDraw, bits, stride, bpp, xoff, yoff); + + if (bpp == 16 && (xor >> 16 != (xor & 0xffff))) + return FALSE; + + if (bpp != 16 && bpp != 32) + return FALSE; + + if (bpp == 16) + { + stride = stride * sizeof (FbBits) / 2; + byte_line = (CARD8 *)(((CARD16 *)bits) + stride * (y + yoff) + (x + xoff)); + byte_width = 2 * width; + stride *= 2; + } + else + { + stride = stride * sizeof (FbBits) / 4; + byte_line = (CARD8 *)(((CARD32 *)bits) + stride * (y + yoff) + (x + xoff)); + byte_width = 4 * width; + stride *= 4; + } + + fill = ((ullong)xor << 32) | xor; + vfill = M64(fill); + + while (height--) + { + unsigned int w; + CARD8 *d = byte_line; + byte_line += stride; + w = byte_width; + + while (w >= 2 && ((unsigned long)d & 3)) + { + *(CARD16 *)d = xor; + w -= 2; + d += 2; + } + + while (w >= 4 && ((unsigned long)d & 7)) + { + *(CARD32 *)d = xor; + + w -= 4; + d += 4; + } + + while (w >= 64) + { + *(__m64*) (d + 0) = vfill; + *(__m64*) (d + 8) = vfill; + *(__m64*) (d + 16) = vfill; + *(__m64*) (d + 24) = vfill; + *(__m64*) (d + 32) = vfill; + *(__m64*) (d + 40) = vfill; + *(__m64*) (d + 48) = vfill; + *(__m64*) (d + 56) = vfill; + + w -= 64; + d += 64; + } + while (w >= 4) + { + *(CARD32 *)d = xor; + + w -= 4; + d += 4; + } + if (w >= 2) + { + *(CARD16 *)d = xor; + w -= 2; + d += 2; + } + } + + _mm_empty(); + return TRUE; +} + +Bool fbCopyAreammx (FbPixels *pSrc, FbPixels *pDst, int src_x, @@ -2713,8 +2720,16 @@ fbCopyAreammx (FbPixels *pSrc, fbGetDrawable(pSrc, src_bits, src_stride, src_bpp, src_xoff, src_yoff); fbGetDrawable(pDst, dst_bits, dst_stride, dst_bpp, dst_xoff, dst_yoff); - assert (src_bpp == dst_bpp); - assert (src_bpp == 16 || src_bpp == 32); + if (src_bpp != 16 && src_bpp != 32) + return FALSE; + + if (dst_bpp != 16 && dst_bpp != 32) + return FALSE; + + if (src_bpp != dst_bpp) + { + return FALSE; + } if (src_bpp == 16) { @@ -2795,6 +2810,7 @@ fbCopyAreammx (FbPixels *pSrc, } _mm_empty(); + return TRUE; } void diff --git a/gfx/cairo/libpixman/src/fbmmx.h b/gfx/cairo/libpixman/src/fbmmx.h index 9c20cd6a7319..054ac0b73cd6 100644 --- a/gfx/cairo/libpixman/src/fbmmx.h +++ b/gfx/cairo/libpixman/src/fbmmx.h @@ -283,6 +283,16 @@ void fbCompositeSrc_8888x8888mmx (pixman_operator_t op, CARD16 width, CARD16 height); pixman_private +Bool fbCopyAreammx (FbPixels *pSrc, + FbPixels *pDst, + int src_x, + int src_y, + int dst_x, + int dst_y, + int width, + int height); + +pixman_private void fbCompositeCopyAreammx (pixman_operator_t op, PicturePtr pSrc, PicturePtr pMask, @@ -295,4 +305,13 @@ void fbCompositeCopyAreammx (pixman_operator_t op, INT16 yDst, CARD16 width, CARD16 height); + +pixman_private +Bool fbSolidFillmmx (FbPixels *pDraw, + int x, + int y, + int width, + int height, + FbBits xor); + #endif /* USE_MMX */ diff --git a/gfx/cairo/libpixman/src/fbpict.c b/gfx/cairo/libpixman/src/fbpict.c index 2d71402f5b0c..0bd989fe08df 100644 --- a/gfx/cairo/libpixman/src/fbpict.c +++ b/gfx/cairo/libpixman/src/fbpict.c @@ -21,8 +21,9 @@ * Author: Keith Packard, SuSE, Inc. */ -#include "pixmanint.h" - +#ifdef HAVE_CONFIG_H +#include +#endif #include "pixman-xserver-compat.h" #ifdef RENDER @@ -1388,7 +1389,7 @@ pixman_composite (pixman_operator_t op, int width, int height) { - pixman_region16_t region; + pixman_region16_t *region; int n; pixman_box16_t *pbox; CompositeFunc func = NULL; @@ -1642,23 +1643,19 @@ pixman_composite (pixman_operator_t op, break; #ifdef USE_MMX case PICT_x8r8g8b8: - if ((pDst->format_code == PICT_a8r8g8b8 || - pDst->format_code == PICT_x8r8g8b8) && - pMask->format_code == PICT_a8 && fbHaveMMX()) - func = fbCompositeSrc_x888x8x8888mmx; - break; case PICT_x8b8g8r8: - if ((pDst->format_code == PICT_a8b8g8r8 || - pDst->format_code == PICT_x8b8g8r8) && + if (pDst->format_code == pSrc->format_code && pMask->format_code == PICT_a8 && fbHaveMMX()) func = fbCompositeSrc_x888x8x8888mmx; break; +#if 0 /* This case fails rendercheck for me */ case PICT_a8r8g8b8: - if ((pDst->format_code == PICT_a8r8g8b8 || - pDst->format_code == PICT_x8r8g8b8) && - pMask->format_code == PICT_a8 && fbHaveMMX()) + if ((pDst->format == PICT_a8r8g8b8 || + pDst->format == PICT_x8r8g8b8) && + pMask->format == PICT_a8 && fbHaveMMX()) func = fbCompositeSrc_8888x8x8888mmx; break; +#endif case PICT_a8b8g8r8: if ((pDst->format_code == PICT_a8b8g8r8 || pDst->format_code == PICT_x8b8g8r8) && @@ -1935,14 +1932,25 @@ pixman_composite (pixman_operator_t op, if (maskTransform) maskRepeat = 0; - pixman_region_init_rect (®ion, xDst, yDst, width, height); + region = pixman_region_create(); + pixman_region_union_rect (region, region, xDst, yDst, width, height); - if (!FbComputeCompositeRegion (®ion, pSrc, pMask, pDst, xSrc, ySrc, - xMask, yMask, xDst, yDst, width, height)) - goto CLEANUP_REGION; + if (!FbComputeCompositeRegion (region, + pSrc, + pMask, + pDst, + xSrc, + ySrc, + xMask, + yMask, + xDst, + yDst, + width, + height)) + return; - n = pixman_region_num_rects (®ion); - pbox = pixman_region_rects (®ion); + n = pixman_region_num_rects (region); + pbox = pixman_region_rects (region); while (n--) { h = pbox->y2 - pbox->y1; @@ -1998,9 +2006,7 @@ pixman_composite (pixman_operator_t op, } pbox++; } - -CLEANUP_REGION: - pixman_region_fini (®ion); + pixman_region_destroy (region); } /* The CPU detection code needs to be in a file not compiled with diff --git a/gfx/cairo/libpixman/src/fbpict.h b/gfx/cairo/libpixman/src/fbpict.h index 79bd9f54cbad..0ff0c1123d32 100644 --- a/gfx/cairo/libpixman/src/fbpict.h +++ b/gfx/cairo/libpixman/src/fbpict.h @@ -327,6 +327,12 @@ #define FASTCALL #endif +#if defined(__GNUC__) +#define INLINE __inline__ +#else +#define INLINE +#endif + typedef struct _FbComposeData { CARD8 op; PicturePtr src; diff --git a/gfx/cairo/libpixman/src/fbtrap.c b/gfx/cairo/libpixman/src/fbtrap.c index 201c1f710088..b0ae5282ecc8 100644 --- a/gfx/cairo/libpixman/src/fbtrap.c +++ b/gfx/cairo/libpixman/src/fbtrap.c @@ -1,4 +1,6 @@ /* + * $Id: fbtrap.c,v 1.19 2007/06/30 10:45:12 vladimir%pobox.com Exp $ + * * Copyright © 2004 Keith Packard * * Permission to use, copy, modify, distribute, and sell this software and its @@ -20,8 +22,6 @@ * PERFORMANCE OF THIS SOFTWARE. */ -#include "pixmanint.h" - #include "pixman-xserver-compat.h" #ifdef RENDER diff --git a/gfx/cairo/libpixman/src/icblt.c b/gfx/cairo/libpixman/src/icblt.c index 69d194514461..4f0c98e31ae1 100644 --- a/gfx/cairo/libpixman/src/icblt.c +++ b/gfx/cairo/libpixman/src/icblt.c @@ -22,8 +22,6 @@ * PERFORMANCE OF THIS SOFTWARE. */ -#include "pixmanint.h" - #include "pixman-xserver-compat.h" #define InitializeShifts(sx,dx,ls,rs) { \ diff --git a/gfx/cairo/libpixman/src/icbltone.c b/gfx/cairo/libpixman/src/icbltone.c index bdf42b604957..d67e75d8a348 100644 --- a/gfx/cairo/libpixman/src/icbltone.c +++ b/gfx/cairo/libpixman/src/icbltone.c @@ -22,8 +22,6 @@ * PERFORMANCE OF THIS SOFTWARE. */ -#include "pixmanint.h" - #include "pixman-xserver-compat.h" /* diff --git a/gfx/cairo/libpixman/src/iccolor.c b/gfx/cairo/libpixman/src/iccolor.c index df11fa968958..9dd8f5e42c11 100644 --- a/gfx/cairo/libpixman/src/iccolor.c +++ b/gfx/cairo/libpixman/src/iccolor.c @@ -21,7 +21,7 @@ * Author: Keith Packard, SuSE, Inc. */ -#include "pixmanint.h" +#include "icint.h" #ifdef ICINT_NEED_IC_ONES /* Fall back on HACKMEM 169. */ diff --git a/gfx/cairo/libpixman/src/icformat.c b/gfx/cairo/libpixman/src/icformat.c index a7b2954599e7..bf93a6c9461f 100644 --- a/gfx/cairo/libpixman/src/icformat.c +++ b/gfx/cairo/libpixman/src/icformat.c @@ -21,92 +21,70 @@ * Author: Keith Packard, SuSE, Inc. */ -#include "pixmanint.h" +#include "icint.h" #define Mask(n) ((n) == 32 ? 0xffffffff : (unsigned) ((1 << (n))-1)) -int -pixman_format_init (pixman_format_t *format, pixman_format_name_t name) +pixman_format_t * +pixman_format_create (pixman_format_name_t name) { switch (name) { case PIXMAN_FORMAT_NAME_ARGB32: - pixman_format_init_masks (format, 32, - 0xff000000, - 0x00ff0000, - 0x0000ff00, - 0x000000ff); - break; - + return pixman_format_create_masks (32, + 0xff000000, + 0x00ff0000, + 0x0000ff00, + 0x000000ff); case PIXMAN_FORMAT_NAME_RGB24: - pixman_format_init_masks (format, 32, - 0x0, - 0xff0000, - 0x00ff00, - 0x0000ff); - break; - + return pixman_format_create_masks (32, + 0x0, + 0xff0000, + 0x00ff00, + 0x0000ff); case PIXMAN_FORMAT_NAME_A8: - pixman_format_init_masks (format, 8, - 0xff, - 0, - 0, - 0); - break; - + return pixman_format_create_masks (8, 0xff, + 0, 0, 0); case PIXMAN_FORMAT_NAME_A1: - pixman_format_init_masks (format, 1, - 0x1, - 0, - 0, - 0); - break; - + return pixman_format_create_masks (1, 0x1, + 0, 0, 0); case PIXMAN_FORMAT_NAME_RGB16_565: - pixman_format_init_masks (format, 16, - 0x0, - 0xf800, - 0x07e0, - 0x001f); - break; - + return pixman_format_create_masks (16, + 0x0, + 0xf800, + 0x07e0, + 0x001f); case PIXMAN_FORMAT_NAME_ABGR32: - pixman_format_init_masks (format, 32, - 0xff000000, - 0x000000ff, - 0x0000ff00, - 0x00ff0000); - break; - + return pixman_format_create_masks (32, + 0xff000000, + 0x000000ff, + 0x0000ff00, + 0x00ff0000); case PIXMAN_FORMAT_NAME_BGR24: - pixman_format_init_masks (format, 32, - 0x0, - 0x000000ff, - 0x0000ff00, - 0x00ff0000); - break; - - default: - return 0; + return pixman_format_create_masks (32, + 0x0, + 0x000000ff, + 0x0000ff00, + 0x00ff0000); } - return 1; + return NULL; } /* XXX: There's some nonsense going on here. The macros above help pixman_format_create_masks to encode a format into an int, while - immediately afterwards pixman_format_init_code goes through the effort of + immediately afterwards pixman_format_init goes through the effort of decoding it. This should all be disentagled, (it's probably possible to just eliminate the encoding macros altogether). */ -void -pixman_format_init_masks (pixman_format_t *format, - int bpp, - int alpha_mask, - int red_mask, - int green_mask, - int blue_mask) +pixman_format_t * +pixman_format_create_masks (int bpp, + int alpha_mask, + int red_mask, + int green_mask, + int blue_mask) { int type; int format_code; + pixman_format_t *format; if (red_mask == 0 && green_mask == 0 && blue_mask == 0) type = PICT_TYPE_A; @@ -121,11 +99,17 @@ pixman_format_init_masks (pixman_format_t *format, _FbOnes (green_mask), _FbOnes (blue_mask)); - pixman_format_init_code (format, format_code); + format = malloc (sizeof (pixman_format_t)); + if (format == NULL) + return NULL; + + pixman_format_init (format, format_code); + + return format; } void -pixman_format_init_code (pixman_format_t *format, int format_code) +pixman_format_init (pixman_format_t *format, int format_code) { memset (format, 0, sizeof (pixman_format_t)); @@ -188,6 +172,12 @@ pixman_format_init_code (pixman_format_t *format, int format_code) (format->greenMask << format->green)); } +void +pixman_format_destroy (pixman_format_t *format) +{ + free (format); +} + void pixman_format_get_masks (pixman_format_t *format, unsigned int *bpp, diff --git a/gfx/cairo/libpixman/src/icimage.c b/gfx/cairo/libpixman/src/icimage.c index 61a84c5c4c92..4d957a0fc379 100644 --- a/gfx/cairo/libpixman/src/icimage.c +++ b/gfx/cairo/libpixman/src/icimage.c @@ -21,8 +21,6 @@ * Author: Keith Packard, SuSE, Inc. */ -#include "pixmanint.h" - #include "pixman-xserver-compat.h" pixman_image_t * @@ -189,8 +187,6 @@ _pixman_create_source_image (void) pixman_image_t *image; image = (pixman_image_t *) malloc (sizeof (pixman_image_t)); - if (image == NULL) - return NULL; image->pDrawable = NULL; image->pixels = NULL; image->format_code = PICT_a8r8g8b8; @@ -307,8 +303,8 @@ pixman_image_init (pixman_image_t *image) * In the server this was 0 because the composite clip list * can be referenced from a window (and often is) */ - image->hasCompositeClip = 0; - image->hasSourceClip = 0; + image->freeCompClip = 0; + image->freeSourceClip = 0; image->clientClipType = CT_NONE; image->componentAlpha = 0; image->compositeClipSource = 0; @@ -319,6 +315,7 @@ pixman_image_init (pixman_image_t *image) image->clipOrigin.x = 0; image->clipOrigin.y = 0; + image->clientClip = NULL; image->dither = 0L; @@ -327,16 +324,24 @@ pixman_image_init (pixman_image_t *image) image->serialNumber = GC_CHANGE_SERIAL_BIT; */ - if (image->pixels) { - pixman_region_init_rect (&image->compositeClip, - 0, 0, image->pixels->width, - image->pixels->height); - image->hasCompositeClip = 1; + if (image->pixels) + { + image->pCompositeClip = pixman_region_create(); + pixman_region_union_rect (image->pCompositeClip, image->pCompositeClip, + 0, 0, image->pixels->width, + image->pixels->height); + image->freeCompClip = 1; - pixman_region_init_rect (&image->sourceClip, - 0, 0, image->pixels->width, - image->pixels->height); - image->hasSourceClip = 1; + image->pSourceClip = pixman_region_create (); + pixman_region_union_rect (image->pSourceClip, image->pSourceClip, + 0, 0, image->pixels->width, + image->pixels->height); + image->freeSourceClip = 1; + } + else + { + image->pCompositeClip = NULL; + image->pSourceClip = NULL; } image->transform = NULL; @@ -464,14 +469,14 @@ pixman_image_destroy (pixman_image_t *image) { pixman_image_destroyClip (image); - if (image->hasCompositeClip) { - pixman_region_fini (&image->compositeClip); - image->hasCompositeClip = 0; + if (image->freeCompClip) { + pixman_region_destroy (image->pCompositeClip); + image->pCompositeClip = NULL; } - if (image->hasSourceClip) { - pixman_region_fini (&image->sourceClip); - image->hasSourceClip = 0; + if (image->freeSourceClip) { + pixman_region_destroy (image->pSourceClip); + image->pSourceClip = NULL; } if (image->owns_pixels) { @@ -495,9 +500,17 @@ pixman_image_destroy (pixman_image_t *image) void pixman_image_destroyClip (pixman_image_t *image) { - if (CT_NONE != image->clientClipType) - pixman_region_fini (&image->clientClip); - + switch (image->clientClipType) { + case CT_NONE: + return; + case CT_PIXMAP: + pixman_image_destroy (image->clientClip); + break; + default: + pixman_region_destroy (image->clientClip); + break; + } + image->clientClip = NULL; image->clientClipType = CT_NONE; } @@ -506,14 +519,9 @@ pixman_image_set_clip_region (pixman_image_t *image, pixman_region16_t *region) { pixman_image_destroyClip (image); - if (region) { - pixman_region_init (&image->clientClip); - if (pixman_region_copy (&image->clientClip, region) != - PIXMAN_REGION_STATUS_SUCCESS) { - pixman_region_fini (&image->clientClip); - return 1; - } + image->clientClip = pixman_region_create (); + pixman_region_copy (image->clientClip, region); image->clientClipType = CT_REGION; } @@ -521,28 +529,20 @@ pixman_image_set_clip_region (pixman_image_t *image, if (image->pSourcePict) return 0; - if (image->hasCompositeClip) - pixman_region_fini (&image->compositeClip); - - pixman_region_init_rect (&image->compositeClip, 0, 0, - image->pixels->width, - image->pixels->height); - - image->hasCompositeClip = 1; - + if (image->freeCompClip) + pixman_region_destroy (image->pCompositeClip); + image->pCompositeClip = pixman_region_create(); + pixman_region_union_rect (image->pCompositeClip, image->pCompositeClip, + 0, 0, image->pixels->width, image->pixels->height); + image->freeCompClip = 1; if (region) { - pixman_region_translate (&image->compositeClip, + pixman_region_translate (image->pCompositeClip, - image->clipOrigin.x, - image->clipOrigin.y); - if (pixman_region_intersect (&image->compositeClip, - &image->compositeClip, - region) != PIXMAN_REGION_STATUS_SUCCESS) { - pixman_image_destroyClip (image); - pixman_region_fini (&image->compositeClip); - image->hasCompositeClip = 0; - return 1; - } - pixman_region_translate (&image->compositeClip, + pixman_region_intersect (image->pCompositeClip, + image->pCompositeClip, + region); + pixman_region_translate (image->pCompositeClip, image->clipOrigin.x, image->clipOrigin.y); } @@ -552,13 +552,12 @@ pixman_image_set_clip_region (pixman_image_t *image, #define BOUND(v) (int16_t) ((v) < MINSHORT ? MINSHORT : (v) > MAXSHORT ? MAXSHORT : (v)) -static inline int +static __inline int FbClipImageReg (pixman_region16_t *region, pixman_region16_t *clip, int dx, int dy) { - int ret = 1; if (pixman_region_num_rects (region) == 1 && pixman_region_num_rects (clip) == 1) { @@ -582,17 +581,14 @@ FbClipImageReg (pixman_region16_t *region, } else { - pixman_region_status_t status; - pixman_region_translate (region, dx, dy); - status = pixman_region_intersect (region, clip, region); - ret = status == PIXMAN_REGION_STATUS_SUCCESS; + pixman_region_intersect (region, clip, region); pixman_region_translate (region, -dx, -dy); } - return ret; + return 1; } -static inline int +static __inline int FbClipImageSrc (pixman_region16_t *region, pixman_image_t *image, int dx, @@ -601,43 +597,225 @@ FbClipImageSrc (pixman_region16_t *region, /* XXX what to do with clipping from transformed pictures? */ if (image->transform) return 1; - /* XXX davidr hates this, wants to never use source-based clipping */ - if (image->repeat != PIXMAN_REPEAT_NONE || image->pSourcePict) { - int ret = 1; + if (image->repeat != PIXMAN_REPEAT_NONE || image->pSourcePict) + { /* XXX no source clipping */ if (image->compositeClipSource && - image->clientClipType != CT_NONE) { - pixman_region_status_t status; - + image->clientClipType != CT_NONE) + { pixman_region_translate (region, dx - image->clipOrigin.x, dy - image->clipOrigin.y); - status = pixman_region_intersect (region, - &image->clientClip, - region); - ret = status == PIXMAN_REGION_STATUS_SUCCESS; + pixman_region_intersect (region, image->clientClip, region); pixman_region_translate (region, - (dx - image->clipOrigin.x), - (dy - image->clipOrigin.y)); } - - return ret; - } else { - pixman_region16_t *clip; - - if (image->compositeClipSource) { - clip = (image->hasCompositeClip ? &image->compositeClip : NULL); - } else { - clip = (image->hasSourceClip ? &image->sourceClip : NULL); - } - - return FbClipImageReg (region, clip, dx, dy); + return 1; } + else + { + pixman_region16_t *clip; + if (image->compositeClipSource) + clip = image->pCompositeClip; + else + clip = image->pSourceClip; + return FbClipImageReg (region, + clip, + dx, + dy); + } return 1; } +/* XXX: Need to decide what to do with this +#define NEXT_VAL(_type) (vlist ? (_type) *vlist++ : (_type) ulist++->val) + +#define NEXT_PTR(_type) ((_type) ulist++->ptr) + +int +pixman_image_change (pixman_image_t *image, + Mask vmask, + unsigned int *vlist, + DevUnion *ulist, + int *error_value) +{ + BITS32 index2; + int error = 0; + BITS32 maskQ; + + maskQ = vmask; + while (vmask && !error) + { + index2 = (BITS32) lowbit (vmask); + vmask &= ~index2; + image->stateChanges |= index2; + switch (index2) + { + case CPRepeat: + { + unsigned int newr; + newr = NEXT_VAL(unsigned int); + if (newr <= xTrue) + image->repeat = newr; + else + { + *error_value = newr; + error = BadValue; + } + } + break; + case CPAlphaMap: + { + pixman_image_t *iAlpha; + + iAlpha = NEXT_PTR(pixman_image_t *); + if (iAlpha) + iAlpha->refcnt++; + if (image->alphaMap) + pixman_image_destroy ((void *) image->alphaMap); + image->alphaMap = iAlpha; + } + break; + case CPAlphaXOrigin: + image->alphaOrigin.x = NEXT_VAL(int16_t); + break; + case CPAlphaYOrigin: + image->alphaOrigin.y = NEXT_VAL(int16_t); + break; + case CPClipXOrigin: + image->clipOrigin.x = NEXT_VAL(int16_t); + break; + case CPClipYOrigin: + image->clipOrigin.y = NEXT_VAL(int16_t); + break; + case CPClipMask: + { + pixman_image_t *mask; + int clipType; + + mask = NEXT_PTR(pixman_image_t *); + if (mask) { + clipType = CT_PIXMAP; + mask->refcnt++; + } else { + clipType = CT_NONE; + } + error = pixman_image_change_clip (image, clipType, + (void *)mask, 0); + break; + } + case CPGraphicsExposure: + { + unsigned int newe; + newe = NEXT_VAL(unsigned int); + if (newe <= xTrue) + image->graphicsExposures = newe; + else + { + *error_value = newe; + error = BadValue; + } + } + break; + case CPSubwindowMode: + { + unsigned int news; + news = NEXT_VAL(unsigned int); + if (news == ClipByChildren || news == IncludeInferiors) + image->subWindowMode = news; + else + { + *error_value = news; + error = BadValue; + } + } + break; + case CPPolyEdge: + { + unsigned int newe; + newe = NEXT_VAL(unsigned int); + if (newe == PolyEdgeSharp || newe == PolyEdgeSmooth) + image->polyEdge = newe; + else + { + *error_value = newe; + error = BadValue; + } + } + break; + case CPPolyMode: + { + unsigned int newm; + newm = NEXT_VAL(unsigned int); + if (newm == PolyModePrecise || newm == PolyModeImprecise) + image->polyMode = newm; + else + { + *error_value = newm; + error = BadValue; + } + } + break; + case CPDither: + image->dither = NEXT_VAL(unsigned long); + break; + case CPComponentAlpha: + { + unsigned int newca; + + newca = NEXT_VAL (unsigned int); + if (newca <= xTrue) + image->componentAlpha = newca; + else + { + *error_value = newca; + error = BadValue; + } + } + break; + default: + *error_value = maskQ; + error = BadValue; + break; + } + } + return error; +} +*/ + +/* XXX: Do we need this? +int +SetPictureClipRects (PicturePtr pPicture, + int xOrigin, + int yOrigin, + int nRect, + xRectangle *rects) +{ + ScreenPtr pScreen = pPicture->pDrawable->pScreen; + PictureScreenPtr ps = GetPictureScreen(pScreen); + pixman_region16_t *clientClip; + int result; + + clientClip = RECTS_TO_REGION(pScreen, + nRect, rects, CT_UNSORTED); + if (!clientClip) + return 1; + result =(*ps->ChangePictureClip) (pPicture, CT_REGION, + (void *) clientClip, 0); + if (result == 0) + { + pPicture->clipOrigin.x = xOrigin; + pPicture->clipOrigin.y = yOrigin; + pPicture->stateChanges |= CPClipXOrigin|CPClipYOrigin|CPClipMask; + pPicture->serialNumber |= GC_CHANGE_SERIAL_BIT; + } + return result; +} +*/ + int FbComputeCompositeRegion (pixman_region16_t *region, pixman_image_t *iSrc, @@ -666,48 +844,63 @@ FbComputeCompositeRegion (pixman_region16_t *region, y1 = yDst; v = yDst + height; y2 = BOUND(v); - /* Check for empty operation */ - if (x1 >= x2 || y1 >= y2) { + if (x1 >= x2 || + y1 >= y2) + { pixman_region_empty (region); return 1; } - /* clip against src */ if (!FbClipImageSrc (region, iSrc, xDst - xSrc, yDst - ySrc)) + { + pixman_region_destroy (region); return 0; - - if (iSrc->alphaMap && - !FbClipImageSrc (region, iSrc->alphaMap, - xDst - (xSrc + iSrc->alphaOrigin.x), - yDst - (ySrc + iSrc->alphaOrigin.y))) - return 0; - - /* clip against mask */ - if (iMask) { - if (!FbClipImageSrc (region, iMask, xDst - xMask, yDst - yMask)) - return 0; - - if (iMask->alphaMap && - !FbClipImageSrc (region, iMask->alphaMap, - xDst - (xMask + iMask->alphaOrigin.x), - yDst - (yMask + iMask->alphaOrigin.y))) - return 0; } - - if (!FbClipImageReg (region, - iDst->hasCompositeClip ? - &iDst->compositeClip : NULL, - 0, 0)) + if (iSrc->alphaMap) + { + if (!FbClipImageSrc (region, iSrc->alphaMap, + xDst - (xSrc + iSrc->alphaOrigin.x), + yDst - (ySrc + iSrc->alphaOrigin.y))) + { + pixman_region_destroy (region); + return 0; + } + } + /* clip against mask */ + if (iMask) + { + if (!FbClipImageSrc (region, iMask, xDst - xMask, yDst - yMask)) + { + pixman_region_destroy (region); + return 0; + } + if (iMask->alphaMap) + { + if (!FbClipImageSrc (region, iMask->alphaMap, + xDst - (xMask + iMask->alphaOrigin.x), + yDst - (yMask + iMask->alphaOrigin.y))) + { + pixman_region_destroy (region); + return 0; + } + } + } + if (!FbClipImageReg (region, iDst->pCompositeClip, 0, 0)) + { + pixman_region_destroy (region); return 0; - - if (iDst->alphaMap && - !FbClipImageReg (region, - iDst->hasCompositeClip ? - &iDst->alphaMap->compositeClip : NULL, - -iDst->alphaOrigin.x, -iDst->alphaOrigin.y)) - return 0; - + } + if (iDst->alphaMap) + { + if (!FbClipImageReg (region, iDst->alphaMap->pCompositeClip, + -iDst->alphaOrigin.x, + -iDst->alphaOrigin.y)) + { + pixman_region_destroy (region); + return 0; + } + } return 1; } diff --git a/gfx/cairo/libpixman/src/icimage.h b/gfx/cairo/libpixman/src/icimage.h index b983429675ae..bbf41b99c02f 100644 --- a/gfx/cairo/libpixman/src/icimage.h +++ b/gfx/cairo/libpixman/src/icimage.h @@ -143,8 +143,8 @@ struct pixman_image { unsigned int subWindowMode : 1; unsigned int polyEdge : 1; unsigned int polyMode : 1; - unsigned int hasCompositeClip : 1; - unsigned int hasSourceClip : 1; + unsigned int freeCompClip : 1; + unsigned int freeSourceClip : 1; unsigned int clientClipType : 2; unsigned int componentAlpha : 1; unsigned int compositeClipSource : 1; @@ -154,15 +154,15 @@ struct pixman_image { FbPoint alphaOrigin; FbPoint clipOrigin; + void *clientClip; unsigned long dither; unsigned long stateChanges; unsigned long serialNumber; - pixman_region16_t clientClip; - pixman_region16_t compositeClip; - pixman_region16_t sourceClip; + pixman_region16_t *pCompositeClip; + pixman_region16_t *pSourceClip; pixman_transform_t *transform; diff --git a/gfx/cairo/libpixman/src/icpixels.c b/gfx/cairo/libpixman/src/icpixels.c index 89759715dc90..605214e71f57 100644 --- a/gfx/cairo/libpixman/src/icpixels.c +++ b/gfx/cairo/libpixman/src/icpixels.c @@ -20,8 +20,6 @@ * PERFORMANCE OF THIS SOFTWARE. */ -#include "pixmanint.h" - #include "pixman-xserver-compat.h" static void diff --git a/gfx/cairo/libpixman/src/icrect.c b/gfx/cairo/libpixman/src/icrect.c index 2ce58968438c..e4d0c12aade2 100644 --- a/gfx/cairo/libpixman/src/icrect.c +++ b/gfx/cairo/libpixman/src/icrect.c @@ -20,7 +20,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -#include "pixmanint.h" +#include "icint.h" typedef void (*FillFunc) (pixman_image_t *dst, int16_t xDst, @@ -176,7 +176,7 @@ pixman_fill_rect_general (pixman_image_t *dst, } } -static int +static void pixman_color_rects (pixman_image_t *dst, pixman_image_t *clipPict, pixman_color_t *color, @@ -185,13 +185,12 @@ pixman_color_rects (pixman_image_t *dst, int xoff, int yoff) { - pixman_bits_t pixel; - pixman_region16_t clip; - pixman_region16_t rects_as_region; + pixman_bits_t pixel; + pixman_region16_t *clip; + pixman_region16_t *rects_as_region; pixman_box16_t *clipped_rects; int i, n_clipped_rects; FillFunc func; - pixman_region_status_t status; pixman_color_to_pixel (&dst->image_format, color, @@ -201,34 +200,19 @@ pixman_color_rects (pixman_image_t *dst, xoff -= dst->pixels->x; yoff -= dst->pixels->y; - pixman_region_init_rect (&clip, - dst->pixels->x, dst->pixels->y, - dst->pixels->width, dst->pixels->height); + clip = pixman_region_create(); + pixman_region_union_rect (clip, clip, + dst->pixels->x, dst->pixels->y, + dst->pixels->width, dst->pixels->height); - status = pixman_region_intersect (&clip, &clip, - clipPict->hasCompositeClip ? - &clipPict->compositeClip : - NULL); - if (status != PIXMAN_REGION_STATUS_SUCCESS) - { - pixman_region_fini (&clip); - return 1; - } + pixman_region_intersect (clip, clip, clipPict->pCompositeClip); if (clipPict->alphaMap) { - pixman_region_translate (&clip, + pixman_region_translate (clip, -clipPict->alphaOrigin.x, -clipPict->alphaOrigin.y); - status = pixman_region_intersect (&clip, &clip, - clipPict->alphaMap->hasCompositeClip ? - &clipPict->alphaMap->compositeClip : - NULL); - if (status != PIXMAN_REGION_STATUS_SUCCESS) - { - pixman_region_fini (&clip); - return 1; - } - pixman_region_translate (&clip, + pixman_region_intersect (clip, clip, clipPict->alphaMap->pCompositeClip); + pixman_region_translate (clip, clipPict->alphaOrigin.x, clipPict->alphaOrigin.y); } @@ -242,32 +226,19 @@ pixman_color_rects (pixman_image_t *dst, } } - pixman_region_init (&rects_as_region); - + rects_as_region = pixman_region_create (); for (i = 0; i < nRect; i++) { - status = pixman_region_union_rect (&rects_as_region, &rects_as_region, - rects[i].x, rects[i].y, - rects[i].width, rects[i].height); - if (status != PIXMAN_REGION_STATUS_SUCCESS) - { - break; - } + pixman_region_union_rect (rects_as_region, rects_as_region, + rects[i].x, rects[i].y, + rects[i].width, rects[i].height); } - /* any earlier failure will also trigger a failure here... */ - status = pixman_region_intersect (&rects_as_region, - &rects_as_region, - &clip); - pixman_region_fini (&clip); - if (status != PIXMAN_REGION_STATUS_SUCCESS) - { - pixman_region_fini (&rects_as_region); - return 1; - } + pixman_region_intersect (rects_as_region, rects_as_region, clip); + pixman_region_destroy (clip); - n_clipped_rects = pixman_region_num_rects (&rects_as_region); - clipped_rects = pixman_region_rects (&rects_as_region); + n_clipped_rects = pixman_region_num_rects (rects_as_region); + clipped_rects = pixman_region_rects (rects_as_region); if (dst->pixels->bpp == 8) func = pixman_fill_rect_8bpp; @@ -287,7 +258,7 @@ pixman_color_rects (pixman_image_t *dst, &pixel); } - pixman_region_fini (&rects_as_region); + pixman_region_destroy (rects_as_region); if (xoff || yoff) { @@ -297,11 +268,9 @@ pixman_color_rects (pixman_image_t *dst, rects[i].y += yoff; } } - - return 0; } -int pixman_fill_rectangle (pixman_operator_t op, +void pixman_fill_rectangle (pixman_operator_t op, pixman_image_t *dst, const pixman_color_t *color, int x, @@ -316,17 +285,16 @@ int pixman_fill_rectangle (pixman_operator_t op, rect.width = width; rect.height = height; - return pixman_fill_rectangles (op, dst, color, &rect, 1); + pixman_fill_rectangles (op, dst, color, &rect, 1); } -int +void pixman_fill_rectangles (pixman_operator_t op, pixman_image_t *dst, const pixman_color_t *color, const pixman_rectangle_t *rects, int nRects) { - int ret = 1; pixman_color_t color_s = *color; if (color_s.alpha == 0xffff) @@ -341,16 +309,12 @@ pixman_fill_rectangles (pixman_operator_t op, { /* We cast away the constness of rects here, because pixman_color_rects temporarily modifies it */ - ret = pixman_color_rects (dst, dst, - &color_s, - nRects, (pixman_rectangle_t *)rects, - 0, 0); - if (!ret && dst->alphaMap) - ret = pixman_color_rects (dst->alphaMap, dst, - &color_s, - nRects, (pixman_rectangle_t *)rects, - dst->alphaOrigin.x, - dst->alphaOrigin.y); + pixman_color_rects (dst, dst, &color_s, nRects, (pixman_rectangle_t *)rects, 0, 0); + if (dst->alphaMap) + pixman_color_rects (dst->alphaMap, dst, + &color_s, nRects, (pixman_rectangle_t *)rects, + dst->alphaOrigin.x, + dst->alphaOrigin.y); } else { @@ -359,7 +323,7 @@ pixman_fill_rectangles (pixman_operator_t op, pixman_image_t *src; pixman_bits_t pixel; - pixman_format_init_code (&rgbaFormat, PICT_a8r8g8b8); + pixman_format_init (&rgbaFormat, PICT_a8r8g8b8); pixels = FbPixelsCreate (1, 1, rgbaFormat.depth); if (!pixels) @@ -393,12 +357,9 @@ pixman_fill_rectangles (pixman_operator_t op, } pixman_image_destroy (src); - ret = 0; bail2: FbPixelsDestroy (pixels); bail1: ; } - - return ret; } diff --git a/gfx/cairo/libpixman/src/icstipple.c b/gfx/cairo/libpixman/src/icstipple.c index d14e5aa9301c..8074d7a98fe1 100644 --- a/gfx/cairo/libpixman/src/icstipple.c +++ b/gfx/cairo/libpixman/src/icstipple.c @@ -22,8 +22,6 @@ * PERFORMANCE OF THIS SOFTWARE. */ -#include "pixmanint.h" - #include "pixman-xserver-compat.h" #ifndef ICNOPIXADDR diff --git a/gfx/cairo/libpixman/src/ictransform.c b/gfx/cairo/libpixman/src/ictransform.c index 5ee1f0b00be7..013c8caa5ac5 100644 --- a/gfx/cairo/libpixman/src/ictransform.c +++ b/gfx/cairo/libpixman/src/ictransform.c @@ -21,7 +21,7 @@ * Author: Keith Packard, SuSE, Inc. */ -#include "pixmanint.h" +#include "icint.h" #define MAX_FIXED_48_16 ((xFixed_48_16) 0x7fffffff) #define MIN_FIXED_48_16 (-((xFixed_48_16) 1 << 31)) diff --git a/gfx/cairo/libpixman/src/ictrap.c b/gfx/cairo/libpixman/src/ictrap.c index 6ef19cf6ce96..5a33ab828414 100644 --- a/gfx/cairo/libpixman/src/ictrap.c +++ b/gfx/cairo/libpixman/src/ictrap.c @@ -20,9 +20,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -#include "pixmanint.h" - -#include +#include "icint.h" pixman_image_t * FbCreateAlphaPicture (pixman_image_t *dst, @@ -30,24 +28,30 @@ FbCreateAlphaPicture (pixman_image_t *dst, uint16_t width, uint16_t height) { - pixman_format_t local_format; + pixman_image_t *image; + int own_format = 0; if (width > 32767 || height > 32767) return NULL; if (!format) { - int ret; - format = &local_format; + own_format = 1; if (dst->polyEdge == PolyEdgeSharp) - ret = pixman_format_init (format, PIXMAN_FORMAT_NAME_A1); + format = pixman_format_create (PIXMAN_FORMAT_NAME_A1); else - ret = pixman_format_init (format, PIXMAN_FORMAT_NAME_A8); - assert (ret); + format = pixman_format_create (PIXMAN_FORMAT_NAME_A8); + if (!format) + return NULL; } /* pixman_image_create zeroes out the pixels, so we don't have to */ - return pixman_image_create (format, width, height); + image = pixman_image_create (format, width, height); + + if (own_format) + pixman_format_destroy (format); + + return image; } static pixman_fixed16_16_t @@ -94,7 +98,10 @@ pixman_trapezoid_bounds (int ntrap, const pixman_trapezoid_t *traps, pixman_box1 } } -int +/* XXX: There are failure cases in this function. Don't we need to + * propagate the errors out? + */ +void pixman_composite_trapezoids (pixman_operator_t op, pixman_image_t *src, pixman_image_t *dst, @@ -103,17 +110,15 @@ pixman_composite_trapezoids (pixman_operator_t op, const pixman_trapezoid_t *traps, int ntraps) { - pixman_image_t *image = NULL; - pixman_box16_t traps_bounds, dst_bounds, bounds; - pixman_region16_t traps_region, dst_region; - int16_t xDst, yDst; - int16_t xRel, yRel; - pixman_format_t format; - pixman_region_status_t status; - int ret; + pixman_image_t *image = NULL; + pixman_box16_t traps_bounds, dst_bounds, bounds; + pixman_region16_t *traps_region, *dst_region; + int16_t xDst, yDst; + int16_t xRel, yRel; + pixman_format_t *format; if (ntraps == 0) - return 0; + return; /* * Check for solid alpha add @@ -122,14 +127,15 @@ pixman_composite_trapezoids (pixman_operator_t op, { for (; ntraps; ntraps--, traps++) fbRasterizeTrapezoid (dst, traps, 0, 0); - return 0; + return; } xDst = traps[0].left.p1.x >> 16; yDst = traps[0].left.p1.y >> 16; pixman_trapezoid_bounds (ntraps, traps, &traps_bounds); - pixman_region_init_with_extents (&traps_region, &traps_bounds); + + traps_region = pixman_region_create_simple (&traps_bounds); /* XXX: If the image has a clip region set, we should really be * fetching it here instead, but it looks like we don't yet expose @@ -139,30 +145,30 @@ pixman_composite_trapezoids (pixman_operator_t op, dst_bounds.x2 = pixman_image_get_width (dst); dst_bounds.y2 = pixman_image_get_height (dst); - pixman_region_init_with_extents (&dst_region, &dst_bounds); - status = pixman_region_intersect (&traps_region, &traps_region, &dst_region); - if (status != PIXMAN_REGION_STATUS_SUCCESS) { - pixman_region_fini (&traps_region); - pixman_region_fini (&dst_region); - return 1; - } + dst_region = pixman_region_create_simple (&dst_bounds); - bounds = *(pixman_region_extents (&traps_region)); + pixman_region_intersect (traps_region, traps_region, dst_region); - pixman_region_fini (&traps_region); - pixman_region_fini (&dst_region); + bounds = *(pixman_region_extents (traps_region)); + + pixman_region_destroy (traps_region); + pixman_region_destroy (dst_region); if (bounds.y1 >= bounds.y2 || bounds.x1 >= bounds.x2) - return 0; + return; - ret = pixman_format_init (&format, PIXMAN_FORMAT_NAME_A8); - assert (ret); + format = pixman_format_create (PIXMAN_FORMAT_NAME_A8); + if (!format) + return; - image = FbCreateAlphaPicture (dst, &format, + image = FbCreateAlphaPicture (dst, format, bounds.x2 - bounds.x1, bounds.y2 - bounds.y1); if (!image) - return 1; + { + pixman_format_destroy (format); + return; + } for (; ntraps; ntraps--, traps++) { @@ -180,7 +186,7 @@ pixman_composite_trapezoids (pixman_operator_t op, bounds.y2 - bounds.y1); pixman_image_destroy (image); - return 0; + pixman_format_destroy (format); } void diff --git a/gfx/cairo/libpixman/src/ictri.c b/gfx/cairo/libpixman/src/ictri.c index 7fb76a5c587b..408023994fba 100644 --- a/gfx/cairo/libpixman/src/ictri.c +++ b/gfx/cairo/libpixman/src/ictri.c @@ -20,9 +20,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -#include "pixmanint.h" - -#include +#include "icint.h" static void pixman_point_fixed_bounds (int npoint, const pixman_point_fixed_t *points, pixman_box16_t *bounds) @@ -149,38 +147,62 @@ pixman_composite_triangles (pixman_operator_t op, pixman_image_t *image = NULL; int xDst, yDst; int xRel, yRel; - pixman_format_t format; - int ret; + pixman_format_t *format; xDst = tris[0].p1.x >> 16; yDst = tris[0].p1.y >> 16; - ret = pixman_format_init (&format, PIXMAN_FORMAT_NAME_A8); - assert (ret); - - pixman_triangle_bounds (ntris, tris, &bounds); - if (bounds.x2 <= bounds.x1 || bounds.y2 <= bounds.y1) - return; - - image = FbCreateAlphaPicture (dst, - &format, - bounds.x2 - bounds.x1, - bounds.y2 - bounds.y1); - if (!image) - return; + format = pixman_format_create (PIXMAN_FORMAT_NAME_A8); + if (format) + { + pixman_triangle_bounds (ntris, tris, &bounds); + if (bounds.x2 <= bounds.x1 || bounds.y2 <= bounds.y1) + return; + image = FbCreateAlphaPicture (dst, + format, + bounds.x2 - bounds.x1, + bounds.y2 - bounds.y1); + if (!image) + return; + } for (; ntris; ntris--, tris++) { + if (!format) + { + pixman_triangle_bounds (1, tris, &bounds); + if (bounds.x2 <= bounds.x1 || bounds.y2 <= bounds.y1) + continue; + image = FbCreateAlphaPicture (dst, + format, + bounds.x2 - bounds.x1, + bounds.y2 - bounds.y1); + if (!image) + break; + } FbRasterizeTriangle (image, tris, -bounds.x1, -bounds.y1); + if (!format) + { + xRel = bounds.x1 + xSrc - xDst; + yRel = bounds.y1 + ySrc - yDst; + pixman_composite (op, src, image, dst, + xRel, yRel, 0, 0, bounds.x1, bounds.y1, + bounds.x2 - bounds.x1, bounds.y2 - bounds.y1); + pixman_image_destroy (image); + } /* XXX adjust xSrc and ySrc */ } + if (format) + { + xRel = bounds.x1 + xSrc - xDst; + yRel = bounds.y1 + ySrc - yDst; + pixman_composite (op, src, image, dst, + xRel, yRel, 0, 0, bounds.x1, bounds.y1, + bounds.x2 - bounds.x1, bounds.y2 - bounds.y1); + pixman_image_destroy (image); + } - xRel = bounds.x1 + xSrc - xDst; - yRel = bounds.y1 + ySrc - yDst; - pixman_composite (op, src, image, dst, - xRel, yRel, 0, 0, bounds.x1, bounds.y1, - bounds.x2 - bounds.x1, bounds.y2 - bounds.y1); - pixman_image_destroy (image); + pixman_format_destroy (format); } void @@ -197,8 +219,7 @@ pixman_composite_tri_strip (pixman_operator_t op, pixman_image_t *image = NULL; int xDst, yDst; int xRel, yRel; - pixman_format_t format; - int ret; + pixman_format_t *format; if (npoints < 3) return; @@ -206,34 +227,59 @@ pixman_composite_tri_strip (pixman_operator_t op, xDst = points[0].x >> 16; yDst = points[0].y >> 16; - ret = pixman_format_init (&format, PIXMAN_FORMAT_NAME_A8); - assert (ret); - - pixman_point_fixed_bounds (npoints, points, &bounds); - if (bounds.x2 <= bounds.x1 || bounds.y2 <= bounds.y1) - return; - - image = FbCreateAlphaPicture (dst, - &format, - bounds.x2 - bounds.x1, - bounds.y2 - bounds.y1); - if (!image) - return; + format = pixman_format_create (PIXMAN_FORMAT_NAME_A8); + if (format) + { + pixman_point_fixed_bounds (npoints, points, &bounds); + if (bounds.x2 <= bounds.x1 || bounds.y2 <= bounds.y1) + return; + image = FbCreateAlphaPicture (dst, + format, + bounds.x2 - bounds.x1, + bounds.y2 - bounds.y1); + if (!image) + return; + } for (; npoints >= 3; npoints--, points++) { tri.p1 = points[0]; tri.p2 = points[1]; tri.p3 = points[2]; + if (!format) + { + pixman_triangle_bounds (1, &tri, &bounds); + if (bounds.x2 <= bounds.x1 || bounds.y2 <= bounds.y1) + continue; + image = FbCreateAlphaPicture (dst, + format, + bounds.x2 - bounds.x1, + bounds.y2 - bounds.y1); + if (!image) + continue; + } FbRasterizeTriangle (image, &tri, -bounds.x1, -bounds.y1); + if (!format) + { + xRel = bounds.x1 + xSrc - xDst; + yRel = bounds.y1 + ySrc - yDst; + pixman_composite (op, src, image, dst, + xRel, yRel, 0, 0, bounds.x1, bounds.y1, + bounds.x2 - bounds.x1, bounds.y2 - bounds.y1); + pixman_image_destroy (image); + } + } + if (format) + { + xRel = bounds.x1 + xSrc - xDst; + yRel = bounds.y1 + ySrc - yDst; + pixman_composite (op, src, image, dst, + xRel, yRel, 0, 0, bounds.x1, bounds.y1, + bounds.x2 - bounds.x1, bounds.y2 - bounds.y1); + pixman_image_destroy (image); } - xRel = bounds.x1 + xSrc - xDst; - yRel = bounds.y1 + ySrc - yDst; - pixman_composite (op, src, image, dst, - xRel, yRel, 0, 0, bounds.x1, bounds.y1, - bounds.x2 - bounds.x1, bounds.y2 - bounds.y1); - pixman_image_destroy (image); + pixman_format_destroy (format); } void @@ -251,8 +297,7 @@ pixman_composite_tri_fan (pixman_operator_t op, const pixman_point_fixed_t *first; int xDst, yDst; int xRel, yRel; - pixman_format_t format; - int ret; + pixman_format_t *format; if (npoints < 3) return; @@ -260,20 +305,20 @@ pixman_composite_tri_fan (pixman_operator_t op, xDst = points[0].x >> 16; yDst = points[0].y >> 16; - ret = pixman_format_init (&format, PIXMAN_FORMAT_NAME_A8); - assert (ret); - - pixman_point_fixed_bounds (npoints, points, &bounds); - if (bounds.x2 <= bounds.x1 || bounds.y2 <= bounds.y1) - return; - - image = FbCreateAlphaPicture (dst, - &format, - bounds.x2 - bounds.x1, - bounds.y2 - bounds.y1); - if (!image) - return; + format = pixman_format_create (PIXMAN_FORMAT_NAME_A8); + if (format) + { + pixman_point_fixed_bounds (npoints, points, &bounds); + if (bounds.x2 <= bounds.x1 || bounds.y2 <= bounds.y1) + return; + image = FbCreateAlphaPicture (dst, + format, + bounds.x2 - bounds.x1, + bounds.y2 - bounds.y1); + if (!image) + return; + } first = points++; npoints--; for (; npoints >= 2; npoints--, points++) @@ -281,13 +326,38 @@ pixman_composite_tri_fan (pixman_operator_t op, tri.p1 = *first; tri.p2 = points[0]; tri.p3 = points[1]; + if (!format) + { + pixman_triangle_bounds (1, &tri, &bounds); + if (bounds.x2 <= bounds.x1 || bounds.y2 <= bounds.y1) + continue; + image = FbCreateAlphaPicture (dst, + format, + bounds.x2 - bounds.x1, + bounds.y2 - bounds.y1); + if (!image) + continue; + } FbRasterizeTriangle (image, &tri, -bounds.x1, -bounds.y1); + if (!format) + { + xRel = bounds.x1 + xSrc - xDst; + yRel = bounds.y1 + ySrc - yDst; + pixman_composite (op, src, image, dst, + xRel, yRel, 0, 0, bounds.x1, bounds.y1, + bounds.x2 - bounds.x1, bounds.y2 - bounds.y1); + pixman_image_destroy (image); + } + } + if (format) + { + xRel = bounds.x1 + xSrc - xDst; + yRel = bounds.y1 + ySrc - yDst; + pixman_composite (op, src, image, dst, + xRel, yRel, 0, 0, bounds.x1, bounds.y1, + bounds.x2 - bounds.x1, bounds.y2 - bounds.y1); + pixman_image_destroy (image); } - xRel = bounds.x1 + xSrc - xDst; - yRel = bounds.y1 + ySrc - yDst; - pixman_composite (op, src, image, dst, - xRel, yRel, 0, 0, bounds.x1, bounds.y1, - bounds.x2 - bounds.x1, bounds.y2 - bounds.y1); - pixman_image_destroy (image); + pixman_format_destroy (format); } diff --git a/gfx/cairo/libpixman/src/icutil.c b/gfx/cairo/libpixman/src/icutil.c index e9f561c34e5e..55ee293428f1 100644 --- a/gfx/cairo/libpixman/src/icutil.c +++ b/gfx/cairo/libpixman/src/icutil.c @@ -22,8 +22,6 @@ * PERFORMANCE OF THIS SOFTWARE. */ -#include "pixmanint.h" - #include "pixman-xserver-compat.h" pixman_bits_t diff --git a/gfx/cairo/libpixman/src/pixman-remap.h b/gfx/cairo/libpixman/src/pixman-remap.h index 237b7bf153a9..290df3281235 100644 --- a/gfx/cairo/libpixman/src/pixman-remap.h +++ b/gfx/cairo/libpixman/src/pixman-remap.h @@ -56,11 +56,9 @@ #define pixman_region_contains_point _cairo_pixman_region_contains_point #define pixman_region_contains_rectangle _cairo_pixman_region_contains_rectangle #define pixman_region_copy _cairo_pixman_region_copy -#define pixman_region_init _cairo_pixman_region_init -#define pixman_region_init_rect _cairo_pixman_region_init_rect -#define pixman_region_init_rects _cairo_pixman_region_init_rects -#define pixman_region_init_with_extents _cairo_pixman_region_init_with_extents -#define pixman_region_fini _cairo_pixman_region_fini +#define pixman_region_create _cairo_pixman_region_create +#define pixman_region_create_simple _cairo_pixman_region_create_simple +#define pixman_region_destroy _cairo_pixman_region_destroy #define pixman_region_empty _cairo_pixman_region_empty #define pixman_region_extents _cairo_pixman_region_extents #define pixman_region_intersect _cairo_pixman_region_intersect @@ -79,3 +77,4 @@ #define RenderLineFixedEdgeInit _cairo_pixman_render_line_fixed_edge_init #define RenderSampleCeilY _cairo_pixman_render_sample_ceil_y #define RenderSampleFloorY _cairo_pixman_render_sample_floor_y +#define fbSolidFillmmx _cairo_pixman_solid_fill_mmx diff --git a/gfx/cairo/libpixman/src/pixman-xserver-compat.h b/gfx/cairo/libpixman/src/pixman-xserver-compat.h index e475f314d747..a09367d2dc33 100644 --- a/gfx/cairo/libpixman/src/pixman-xserver-compat.h +++ b/gfx/cairo/libpixman/src/pixman-xserver-compat.h @@ -44,7 +44,7 @@ /* First, include the primary internal header file for libpixman. */ -#include "pixmanint.h" +#include "icint.h" /* Then, define any names that the server code will be expecting in * terms of libpixman names. */ @@ -109,7 +109,7 @@ typedef pixman_vector_t* PictVectorPtr; /* And finally, this one prototype must come after the include of * renderedge.h, so it can't live alongside the other prototypes in - * the horrible mess that is pixmanint.h. + * the horrible mess that is icint.h. */ pixman_private void diff --git a/gfx/cairo/libpixman/src/pixman.h b/gfx/cairo/libpixman/src/pixman.h index feaf60aea83e..9120eb6ed1e4 100644 --- a/gfx/cairo/libpixman/src/pixman.h +++ b/gfx/cairo/libpixman/src/pixman.h @@ -74,6 +74,10 @@ SOFTWARE. * PERFORMANCE OF THIS SOFTWARE. */ +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + #if HAVE_STDINT_H # include #elif HAVE_INTTYPES_H @@ -96,37 +100,25 @@ SOFTWARE. #include "pixman-remap.h" #if (__GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 3)) && defined(__ELF__) && !defined(__sun__) -#define pixman_private_no_warn __attribute__((__visibility__("hidden"))) +#define pixman_private __attribute__((__visibility__("hidden"))) #elif defined(__SUNPRO_C) && (__SUNPRO_C >= 0x550) -#define pixman_private_no_warn __hidden +#define pixman_private __hidden #else /* not gcc >= 3.3 and not Sun Studio >= 8 */ -#define pixman_private_no_warn +#define pixman_private #endif -#ifndef WARN_UNUSED_RESULT -#define WARN_UNUSED_RESULT -#endif -/* Add attribute(warn_unused_result) if supported */ -#define pixman_warn WARN_UNUSED_RESULT -#define pixman_private pixman_private_no_warn pixman_warn - #if defined(__cplusplus) || defined(c_plusplus) extern "C" { #endif /* pixregion.h */ -typedef struct pixman_region16_data pixman_region16_data_t; +typedef struct pixman_region16 pixman_region16_t; typedef struct pixman_box16 { short x1, y1, x2, y2; } pixman_box16_t; -typedef struct pixman_region16 { - pixman_box16_t extents; - pixman_region16_data_t *data; -} pixman_region16_t; - typedef enum { PIXMAN_REGION_STATUS_FAILURE, PIXMAN_REGION_STATUS_SUCCESS @@ -134,17 +126,14 @@ typedef enum { /* creation/destruction */ +pixman_private pixman_region16_t * +pixman_region_create (void); + +pixman_private pixman_region16_t * +pixman_region_create_simple (pixman_box16_t *extents); + pixman_private void -pixman_region_init(pixman_region16_t *region); -pixman_private void -pixman_region_init_rect(pixman_region16_t *region, - int x, int y, unsigned int width, unsigned int height); -pixman_private void -pixman_region_init_with_extents(pixman_region16_t *region, pixman_box16_t *extents); -pixman_private pixman_region_status_t -pixman_region_init_rects(pixman_region16_t *region, pixman_box16_t *boxes, int count); -pixman_private void -pixman_region_fini (pixman_region16_t *region); +pixman_region_destroy (pixman_region16_t *region); /* manipulation */ @@ -251,27 +240,20 @@ typedef enum pixman_format_name { PIXMAN_FORMAT_NAME_BGR24 } pixman_format_name_t; -/* XXX: Is depth redundant here? */ -typedef struct pixman_format { - int format_code; - int depth; - int red, redMask; - int green, greenMask; - int blue, blueMask; - int alpha, alphaMask; -} pixman_format_t; +typedef struct pixman_format pixman_format_t; +pixman_private pixman_format_t * +pixman_format_create (pixman_format_name_t name); -pixman_private int -pixman_format_init (pixman_format_t *format, pixman_format_name_t name); +pixman_private pixman_format_t * +pixman_format_create_masks (int bpp, + int alpha_mask, + int red_mask, + int green_mask, + int blue_mask); pixman_private void -pixman_format_init_masks (pixman_format_t *format, - int bpp, - int alpha_mask, - int red_mask, - int green_mask, - int blue_mask); +pixman_format_destroy (pixman_format_t *format); pixman_private void pixman_format_get_masks (pixman_format_t *format, @@ -460,7 +442,7 @@ pixman_pixel_to_color (const pixman_format_t *format, /* icrect.c */ -pixman_private int +pixman_private void pixman_fill_rectangle (pixman_operator_t op, pixman_image_t *dst, const pixman_color_t *color, @@ -469,7 +451,7 @@ pixman_fill_rectangle (pixman_operator_t op, unsigned int width, unsigned int height); -pixman_private int +pixman_private void pixman_fill_rectangles (pixman_operator_t op, pixman_image_t *dst, const pixman_color_t *color, @@ -478,7 +460,7 @@ pixman_fill_rectangles (pixman_operator_t op, /* ictrap.c */ -pixman_private int +pixman_private void pixman_composite_trapezoids (pixman_operator_t op, pixman_image_t *src, pixman_image_t *dst, diff --git a/gfx/cairo/libpixman/src/pixmanint.h b/gfx/cairo/libpixman/src/pixmanint.h deleted file mode 100644 index a10a8342fc3b..000000000000 --- a/gfx/cairo/libpixman/src/pixmanint.h +++ /dev/null @@ -1,1076 +0,0 @@ -/* - * Copyright © 2003 Carl Worth - * - * Permission to use, copy, modify, distribute, and sell this software and its - * documentation for any purpose is hereby granted without fee, provided that - * the above copyright notice appear in all copies and that both that - * copyright notice and this permission notice appear in supporting - * documentation, and that the name of Carl Worth not be used in - * advertising or publicity pertaining to distribution of the software without - * specific, written prior permission. Carl Worth makes no - * representations about the suitability of this software for any purpose. It - * is provided "as is" without express or implied warranty. - * - * CARL WORTH DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, - * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO - * EVENT SHALL CARL WORTH 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. - */ - -#ifndef _PIXMANINT_H_ -#define _PIXMANINT_H_ - -#ifdef HAVE_CONFIG_H -# include "config.h" -#endif - -#include -#include -#include - -#ifdef _MSC_VER -#define snprintf _snprintf -#undef inline -#define inline __inline -#endif - -#include "pixman.h" - -#undef MIN -#define MIN(a,b) ((a) < (b) ? (a) : (b)) -#undef MAX -#define MAX(a,b) ((a) > (b) ? (a) : (b)) - -/* C89 has implementation-defined behavior for % with negative operands. - C99 has well-defined behavior which is that / with integers rounds toward zero - and a%b is defined so that (a/b)*b + a%b == a. - - The C99 version gives negative remainders rather than the modulus - in [0 .. b-1] that we want. This macro avoids using % with negative - operands to avoid both problems. - - a and b are integers. b > 0. -*/ -#define MOD(a, b) ((b) == 1 ? 0 : (a) >= 0 ? (a) % (b) : (b) - (-(a) - 1) % (b) - 1) - -typedef struct _FbPoint { - int16_t x,y ; -} FbPoint; - -typedef unsigned int Mask; - -#define GXcopy 0x3 -#define GXor 0x7 -#define ClipByChildren 0 -#define PolyEdgeSharp 0 -#define PolyModePrecise 0 -#define CPClipMask (1 << 6) -#define CPLastBit 11 - -/* Define any names that the server code will be expecting in - * terms of libpixman names. */ - -typedef uint8_t CARD8; -typedef uint16_t CARD16; -typedef uint32_t CARD32; -typedef int16_t INT16; - -typedef int Bool; -#define FALSE 0 -#define TRUE 1 - -typedef pixman_bits_t FbBits; -typedef pixman_image_t* PicturePtr; -typedef pixman_box16_t BoxRec; -typedef pixman_box16_t* BoxPtr; - -typedef pixman_point_fixed_t xPointFixed; -typedef pixman_line_fixed_t xLineFixed; -typedef pixman_trapezoid_t xTrapezoid; -typedef pixman_triangle_t xTriangle; - -/* These few definitions avoid me needing to include servermd.h and misc.h from Xserver/include */ -#ifndef BITMAP_SCANLINE_PAD -#define BITMAP_SCANLINE_PAD 32 -#define LOG2_BITMAP_PAD 5 -#define LOG2_BYTES_PER_SCANLINE_PAD 2 -#endif - -#define LSBFirst 0 -#define MSBFirst 1 - -#ifdef WORDS_BIGENDIAN -# define IMAGE_BYTE_ORDER MSBFirst -# define BITMAP_BIT_ORDER MSBFirst -#else -# define IMAGE_BYTE_ORDER LSBFirst -# define BITMAP_BIT_ORDER LSBFirst -#endif - -#define MAXSHORT SHRT_MAX -#define MINSHORT SHRT_MIN - -/* XXX: What do we need from here? -#include "picture.h" -*/ - -#include "pixman.h" - -/* XXX: Most of this file is straight from fb.h and I imagine we can - drop quite a bit of it. Once the real ic code starts to come - together I can probably figure out what is not needed here. */ - -#define FB_UNIT (1 << FB_SHIFT) -#define FB_HALFUNIT (1 << (FB_SHIFT-1)) -#define FB_MASK (FB_UNIT - 1) -#define FB_ALLONES ((pixman_bits_t) -1) - -/* whether to bother to include 24bpp support */ -#ifndef ICNO24BIT -#define FB_24BIT -#endif - -/* - * Unless otherwise instructed, ic includes code to advertise 24bpp - * windows with 32bpp image format for application compatibility - */ - -#ifdef FB_24BIT -#ifndef ICNO24_32 -#define FB_24_32BIT -#endif -#endif - -#define FB_STIP_SHIFT LOG2_BITMAP_PAD -#define FB_STIP_UNIT (1 << FB_STIP_SHIFT) -#define FB_STIP_MASK (FB_STIP_UNIT - 1) -#define FB_STIP_ALLONES ((FbStip) -1) - -#define FB_STIP_ODDSTRIDE(s) (((s) & (FB_MASK >> FB_STIP_SHIFT)) != 0) -#define FB_STIP_ODDPTR(p) ((((long) (p)) & (FB_MASK >> 3)) != 0) - -#define FbStipStrideToBitsStride(s) (((s) >> (FB_SHIFT - FB_STIP_SHIFT))) -#define FbBitsStrideToStipStride(s) (((s) << (FB_SHIFT - FB_STIP_SHIFT))) - -#define FbFullMask(n) ((n) == FB_UNIT ? FB_ALLONES : ((((FbBits) 1) << n) - 1)) - -typedef uint32_t FbStip; -typedef int FbStride; - -#ifdef FB_DEBUG -extern void fbValidateDrawable(DrawablePtr d); -extern void fbInitializeDrawable(DrawablePtr d); -extern void fbSetBits (FbStip *bits, int stride, FbStip data); -#define FB_HEAD_BITS (FbStip) (0xbaadf00d) -#define FB_TAIL_BITS (FbStip) (0xbaddf0ad) -#else -#define fbValidateDrawable(d) -#define fdInitializeDrawable(d) -#endif - -#if BITMAP_BIT_ORDER == LSBFirst -#define FbScrLeft(x,n) ((x) >> (n)) -#define FbScrRight(x,n) ((x) << (n)) -/* #define FbLeftBits(x,n) ((x) & ((((FbBits) 1) << (n)) - 1)) */ -#define FbLeftStipBits(x,n) ((x) & ((((FbStip) 1) << (n)) - 1)) -#define FbStipMoveLsb(x,s,n) (FbStipRight (x,(s)-(n))) -#define FbPatternOffsetBits 0 -#else -#define FbScrLeft(x,n) ((x) << (n)) -#define FbScrRight(x,n) ((x) >> (n)) -/* #define FbLeftBits(x,n) ((x) >> (FB_UNIT - (n))) */ -#define FbLeftStipBits(x,n) ((x) >> (FB_STIP_UNIT - (n))) -#define FbStipMoveLsb(x,s,n) (x) -#define FbPatternOffsetBits (sizeof (FbBits) - 1) -#endif - -#define FbStipLeft(x,n) FbScrLeft(x,n) -#define FbStipRight(x,n) FbScrRight(x,n) - -#define FbRotLeft(x,n) FbScrLeft(x,n) | (n ? FbScrRight(x,FB_UNIT-n) : 0) -#define FbRotRight(x,n) FbScrRight(x,n) | (n ? FbScrLeft(x,FB_UNIT-n) : 0) - -#define FbRotStipLeft(x,n) FbStipLeft(x,n) | (n ? FbStipRight(x,FB_STIP_UNIT-n) : 0) -#define FbRotStipRight(x,n) FbStipRight(x,n) | (n ? FbStipLeft(x,FB_STIP_UNIT-n) : 0) - -#define FbLeftMask(x) ( ((x) & FB_MASK) ? \ - FbScrRight(FB_ALLONES,(x) & FB_MASK) : 0) -#define FbRightMask(x) ( ((FB_UNIT - (x)) & FB_MASK) ? \ - FbScrLeft(FB_ALLONES,(FB_UNIT - (x)) & FB_MASK) : 0) - -#define FbLeftStipMask(x) ( ((x) & FB_STIP_MASK) ? \ - FbStipRight(FB_STIP_ALLONES,(x) & FB_STIP_MASK) : 0) -#define FbRightStipMask(x) ( ((FB_STIP_UNIT - (x)) & FB_STIP_MASK) ? \ - FbScrLeft(FB_STIP_ALLONES,(FB_STIP_UNIT - (x)) & FB_STIP_MASK) : 0) - -#define FbBitsMask(x,w) (FbScrRight(FB_ALLONES,(x) & FB_MASK) & \ - FbScrLeft(FB_ALLONES,(FB_UNIT - ((x) + (w))) & FB_MASK)) - -#define FbStipMask(x,w) (FbStipRight(FB_STIP_ALLONES,(x) & FB_STIP_MASK) & \ - FbStipLeft(FB_STIP_ALLONES,(FB_STIP_UNIT - ((x)+(w))) & FB_STIP_MASK)) - -#define FbMaskBits(x,w,l,n,r) { \ - n = (w); \ - r = FbRightMask((x)+n); \ - l = FbLeftMask(x); \ - if (l) { \ - n -= FB_UNIT - ((x) & FB_MASK); \ - if (n < 0) { \ - n = 0; \ - l &= r; \ - r = 0; \ - } \ - } \ - n >>= FB_SHIFT; \ -} - -#ifdef ICNOPIXADDR -#define FbMaskBitsBytes(x,w,copy,l,lb,n,r,rb) FbMaskBits(x,w,l,n,r) -#define FbDoLeftMaskByteRRop(dst,lb,l,and,xor) { \ - *dst = FbDoMaskRRop(*dst,and,xor,l); \ -} -#define FbDoRightMaskByteRRop(dst,rb,r,and,xor) { \ - *dst = FbDoMaskRRop(*dst,and,xor,r); \ -} -#else - -#define FbByteMaskInvalid 0x10 - -#define FbPatternOffset(o,t) ((o) ^ (FbPatternOffsetBits & ~(sizeof (t) - 1))) - -#define FbPtrOffset(p,o,t) ((t *) ((CARD8 *) (p) + (o))) -#define FbSelectPatternPart(xor,o,t) ((xor) >> (FbPatternOffset (o,t) << 3)) -#define FbStorePart(dst,off,t,xor) (*FbPtrOffset(dst,off,t) = \ - FbSelectPart(xor,off,t)) -#ifndef FbSelectPart -#define FbSelectPart(x,o,t) FbSelectPatternPart(x,o,t) -#endif - -#define FbMaskBitsBytes(x,w,copy,l,lb,n,r,rb) { \ - n = (w); \ - lb = 0; \ - rb = 0; \ - r = FbRightMask((x)+n); \ - if (r) { \ - /* compute right byte length */ \ - if ((copy) && (((x) + n) & 7) == 0) { \ - rb = (((x) + n) & FB_MASK) >> 3; \ - } else { \ - rb = FbByteMaskInvalid; \ - } \ - } \ - l = FbLeftMask(x); \ - if (l) { \ - /* compute left byte length */ \ - if ((copy) && ((x) & 7) == 0) { \ - lb = ((x) & FB_MASK) >> 3; \ - } else { \ - lb = FbByteMaskInvalid; \ - } \ - /* subtract out the portion painted by leftMask */ \ - n -= FB_UNIT - ((x) & FB_MASK); \ - if (n < 0) { \ - if (lb != FbByteMaskInvalid) { \ - if (rb == FbByteMaskInvalid) { \ - lb = FbByteMaskInvalid; \ - } else if (rb) { \ - lb |= (rb - lb) << (FB_SHIFT - 3); \ - rb = 0; \ - } \ - } \ - n = 0; \ - l &= r; \ - r = 0; \ - }\ - } \ - n >>= FB_SHIFT; \ -} - -#if FB_SHIFT == 6 -#define FbDoLeftMaskByteRRop6Cases(dst,xor) \ - case (sizeof (FbBits) - 7) | (1 << (FB_SHIFT - 3)): \ - FbStorePart(dst,sizeof (FbBits) - 7,CARD8,xor); \ - break; \ - case (sizeof (FbBits) - 7) | (2 << (FB_SHIFT - 3)): \ - FbStorePart(dst,sizeof (FbBits) - 7,CARD8,xor); \ - FbStorePart(dst,sizeof (FbBits) - 6,CARD8,xor); \ - break; \ - case (sizeof (FbBits) - 7) | (3 << (FB_SHIFT - 3)): \ - FbStorePart(dst,sizeof (FbBits) - 7,CARD8,xor); \ - FbStorePart(dst,sizeof (FbBits) - 6,CARD16,xor); \ - break; \ - case (sizeof (FbBits) - 7) | (4 << (FB_SHIFT - 3)): \ - FbStorePart(dst,sizeof (FbBits) - 7,CARD8,xor); \ - FbStorePart(dst,sizeof (FbBits) - 6,CARD16,xor); \ - FbStorePart(dst,sizeof (FbBits) - 4,CARD8,xor); \ - break; \ - case (sizeof (FbBits) - 7) | (5 << (FB_SHIFT - 3)): \ - FbStorePart(dst,sizeof (FbBits) - 7,CARD8,xor); \ - FbStorePart(dst,sizeof (FbBits) - 6,CARD16,xor); \ - FbStorePart(dst,sizeof (FbBits) - 4,CARD16,xor); \ - break; \ - case (sizeof (FbBits) - 7) | (6 << (FB_SHIFT - 3)): \ - FbStorePart(dst,sizeof (FbBits) - 7,CARD8,xor); \ - FbStorePart(dst,sizeof (FbBits) - 6,CARD16,xor); \ - FbStorePart(dst,sizeof (FbBits) - 4,CARD16,xor); \ - FbStorePart(dst,sizeof (FbBits) - 2,CARD8,xor); \ - break; \ - case (sizeof (FbBits) - 7): \ - FbStorePart(dst,sizeof (FbBits) - 7,CARD8,xor); \ - FbStorePart(dst,sizeof (FbBits) - 6,CARD16,xor); \ - FbStorePart(dst,sizeof (FbBits) - 4,CARD32,xor); \ - break; \ - case (sizeof (FbBits) - 6) | (1 << (FB_SHIFT - 3)): \ - FbStorePart(dst,sizeof (FbBits) - 6,CARD8,xor); \ - break; \ - case (sizeof (FbBits) - 6) | (2 << (FB_SHIFT - 3)): \ - FbStorePart(dst,sizeof (FbBits) - 6,CARD16,xor); \ - break; \ - case (sizeof (FbBits) - 6) | (3 << (FB_SHIFT - 3)): \ - FbStorePart(dst,sizeof (FbBits) - 6,CARD16,xor); \ - FbStorePart(dst,sizeof (FbBits) - 4,CARD8,xor); \ - break; \ - case (sizeof (FbBits) - 6) | (4 << (FB_SHIFT - 3)): \ - FbStorePart(dst,sizeof (FbBits) - 6,CARD16,xor); \ - FbStorePart(dst,sizeof (FbBits) - 4,CARD16,xor); \ - break; \ - case (sizeof (FbBits) - 6) | (5 << (FB_SHIFT - 3)): \ - FbStorePart(dst,sizeof (FbBits) - 6,CARD16,xor); \ - FbStorePart(dst,sizeof (FbBits) - 4,CARD16,xor); \ - FbStorePart(dst,sizeof (FbBits) - 2,CARD8,xor); \ - break; \ - case (sizeof (FbBits) - 6): \ - FbStorePart(dst,sizeof (FbBits) - 6,CARD16,xor); \ - FbStorePart(dst,sizeof (FbBits) - 4,CARD32,xor); \ - break; \ - case (sizeof (FbBits) - 5) | (1 << (FB_SHIFT - 3)): \ - FbStorePart(dst,sizeof (FbBits) - 5,CARD8,xor); \ - break; \ - case (sizeof (FbBits) - 5) | (2 << (FB_SHIFT - 3)): \ - FbStorePart(dst,sizeof (FbBits) - 5,CARD8,xor); \ - FbStorePart(dst,sizeof (FbBits) - 4,CARD8,xor); \ - break; \ - case (sizeof (FbBits) - 5) | (3 << (FB_SHIFT - 3)): \ - FbStorePart(dst,sizeof (FbBits) - 5,CARD8,xor); \ - FbStorePart(dst,sizeof (FbBits) - 4,CARD16,xor); \ - break; \ - case (sizeof (FbBits) - 5) | (4 << (FB_SHIFT - 3)): \ - FbStorePart(dst,sizeof (FbBits) - 5,CARD8,xor); \ - FbStorePart(dst,sizeof (FbBits) - 4,CARD16,xor); \ - FbStorePart(dst,sizeof (FbBits) - 2,CARD8,xor); \ - break; \ - case (sizeof (FbBits) - 5): \ - FbStorePart(dst,sizeof (FbBits) - 5,CARD8,xor); \ - FbStorePart(dst,sizeof (FbBits) - 4,CARD32,xor); \ - break; \ - case (sizeof (FbBits) - 4) | (1 << (FB_SHIFT - 3)): \ - FbStorePart(dst,sizeof (FbBits) - 4,CARD8,xor); \ - break; \ - case (sizeof (FbBits) - 4) | (2 << (FB_SHIFT - 3)): \ - FbStorePart(dst,sizeof (FbBits) - 4,CARD16,xor); \ - break; \ - case (sizeof (FbBits) - 4) | (3 << (FB_SHIFT - 3)): \ - FbStorePart(dst,sizeof (FbBits) - 4,CARD16,xor); \ - FbStorePart(dst,sizeof (FbBits) - 2,CARD8,xor); \ - break; \ - case (sizeof (FbBits) - 4): \ - FbStorePart(dst,sizeof (FbBits) - 4,CARD32,xor); \ - break; - -#define FbDoRightMaskByteRRop6Cases(dst,xor) \ - case 4: \ - FbStorePart(dst,0,CARD32,xor); \ - break; \ - case 5: \ - FbStorePart(dst,0,CARD32,xor); \ - FbStorePart(dst,4,CARD8,xor); \ - break; \ - case 6: \ - FbStorePart(dst,0,CARD32,xor); \ - FbStorePart(dst,4,CARD16,xor); \ - break; \ - case 7: \ - FbStorePart(dst,0,CARD32,xor); \ - FbStorePart(dst,4,CARD16,xor); \ - FbStorePart(dst,6,CARD8,xor); \ - break; -#else -#define FbDoLeftMaskByteRRop6Cases(dst,xor) -#define FbDoRightMaskByteRRop6Cases(dst,xor) -#endif - -#define FbDoLeftMaskByteRRop(dst,lb,l,and,xor) { \ - switch (lb) { \ - FbDoLeftMaskByteRRop6Cases(dst,xor) \ - case (sizeof (FbBits) - 3) | (1 << (FB_SHIFT - 3)): \ - FbStorePart(dst,sizeof (FbBits) - 3,CARD8,xor); \ - break; \ - case (sizeof (FbBits) - 3) | (2 << (FB_SHIFT - 3)): \ - FbStorePart(dst,sizeof (FbBits) - 3,CARD8,xor); \ - FbStorePart(dst,sizeof (FbBits) - 2,CARD8,xor); \ - break; \ - case (sizeof (FbBits) - 2) | (1 << (FB_SHIFT - 3)): \ - FbStorePart(dst,sizeof (FbBits) - 2,CARD8,xor); \ - break; \ - case sizeof (FbBits) - 3: \ - FbStorePart(dst,sizeof (FbBits) - 3,CARD8,xor); \ - case sizeof (FbBits) - 2: \ - FbStorePart(dst,sizeof (FbBits) - 2,CARD16,xor); \ - break; \ - case sizeof (FbBits) - 1: \ - FbStorePart(dst,sizeof (FbBits) - 1,CARD8,xor); \ - break; \ - default: \ - *dst = FbDoMaskRRop(*dst, and, xor, l); \ - break; \ - } \ -} - -#define FbDoRightMaskByteRRop(dst,rb,r,and,xor) { \ - switch (rb) { \ - case 1: \ - FbStorePart(dst,0,CARD8,xor); \ - break; \ - case 2: \ - FbStorePart(dst,0,CARD16,xor); \ - break; \ - case 3: \ - FbStorePart(dst,0,CARD16,xor); \ - FbStorePart(dst,2,CARD8,xor); \ - break; \ - FbDoRightMaskByteRRop6Cases(dst,xor) \ - default: \ - *dst = FbDoMaskRRop (*dst, and, xor, r); \ - } \ -} -#endif - -#define FbMaskStip(x,w,l,n,r) { \ - n = (w); \ - r = FbRightStipMask((x)+n); \ - l = FbLeftStipMask(x); \ - if (l) { \ - n -= FB_STIP_UNIT - ((x) & FB_STIP_MASK); \ - if (n < 0) { \ - n = 0; \ - l &= r; \ - r = 0; \ - } \ - } \ - n >>= FB_STIP_SHIFT; \ -} - -/* - * These macros are used to transparently stipple - * in copy mode; the expected usage is with 'n' constant - * so all of the conditional parts collapse into a minimal - * sequence of partial word writes - * - * 'n' is the bytemask of which bytes to store, 'a' is the address - * of the FbBits base unit, 'o' is the offset within that unit - * - * The term "lane" comes from the hardware term "byte-lane" which - */ - -#define FbLaneCase1(n,a,o) ((n) == 0x01 ? \ - (*(CARD8 *) ((a)+FbPatternOffset(o,CARD8)) = \ - fgxor) : 0) -#define FbLaneCase2(n,a,o) ((n) == 0x03 ? \ - (*(CARD16 *) ((a)+FbPatternOffset(o,CARD16)) = \ - fgxor) : \ - ((void)FbLaneCase1((n)&1,a,o), \ - FbLaneCase1((n)>>1,a,(o)+1))) -#define FbLaneCase4(n,a,o) ((n) == 0x0f ? \ - (*(CARD32 *) ((a)+FbPatternOffset(o,CARD32)) = \ - fgxor) : \ - ((void)FbLaneCase2((n)&3,a,o), \ - FbLaneCase2((n)>>2,a,(o)+2))) -#define FbLaneCase8(n,a,o) ((n) == 0x0ff ? (*(FbBits *) ((a)+(o)) = fgxor) : \ - ((void)FbLaneCase4((n)&15,a,o), \ - FbLaneCase4((n)>>4,a,(o)+4))) - -#if FB_SHIFT == 6 -#define FbLaneCase(n,a) FbLaneCase8(n,(CARD8 *) (a),0) -#endif - -#if FB_SHIFT == 5 -#define FbLaneCase(n,a) FbLaneCase4(n,(CARD8 *) (a),0) -#endif - -/* Rotate a filled pixel value to the specified alignement */ -#define FbRot24(p,b) (FbScrRight(p,b) | FbScrLeft(p,24-(b))) -#define FbRot24Stip(p,b) (FbStipRight(p,b) | FbStipLeft(p,24-(b))) - -/* step a filled pixel value to the next/previous FB_UNIT alignment */ -#define FbNext24Pix(p) (FbRot24(p,(24-FB_UNIT%24))) -#define FbPrev24Pix(p) (FbRot24(p,FB_UNIT%24)) -#define FbNext24Stip(p) (FbRot24(p,(24-FB_STIP_UNIT%24))) -#define FbPrev24Stip(p) (FbRot24(p,FB_STIP_UNIT%24)) - -/* step a rotation value to the next/previous rotation value */ -#if FB_UNIT == 64 -#define FbNext24Rot(r) ((r) == 16 ? 0 : (r) + 8) -#define FbPrev24Rot(r) ((r) == 0 ? 16 : (r) - 8) - -#if IMAGE_BYTE_ORDER == MSBFirst -#define FbFirst24Rot(x) (((x) + 8) % 24) -#else -#define FbFirst24Rot(x) ((x) % 24) -#endif - -#endif - -#if FB_UNIT == 32 -#define FbNext24Rot(r) ((r) == 0 ? 16 : (r) - 8) -#define FbPrev24Rot(r) ((r) == 16 ? 0 : (r) + 8) - -#if IMAGE_BYTE_ORDER == MSBFirst -#define FbFirst24Rot(x) (((x) + 16) % 24) -#else -#define FbFirst24Rot(x) ((x) % 24) -#endif -#endif - -#define FbNext24RotStip(r) ((r) == 0 ? 16 : (r) - 8) -#define FbPrev24RotStip(r) ((r) == 16 ? 0 : (r) + 8) - -/* Whether 24-bit specific code is needed for this filled pixel value */ -#define FbCheck24Pix(p) ((p) == FbNext24Pix(p)) - -#define FbGetPixels(icpixels, pointer, _stride_, _bpp_, xoff, yoff) { \ - (pointer) = icpixels->data; \ - (_stride_) = icpixels->stride / sizeof(pixman_bits_t); \ - (_bpp_) = icpixels->bpp; \ - (xoff) = icpixels->x; /* XXX: fb.h had this ifdef'd to constant 0. Why? */ \ - (yoff) = icpixels->y; /* XXX: fb.h had this ifdef'd to constant 0. Why? */ \ -} - -#define FbGetStipPixels(icpixels, pointer, _stride_, _bpp_, xoff, yoff) { \ - (pointer) = (FbStip *) icpixels->data; \ - (_stride_) = icpixels->stride / sizeof(FbStip); \ - (_bpp_) = icpixels->bpp; \ - (xoff) = icpixels->x; \ - (yoff) = icpixels->y; \ -} - -#ifdef FB_OLD_SCREEN -#define BitsPerPixel(d) (\ - ((1 << PixmapWidthPaddingInfo[d].padBytesLog2) * 8 / \ - (PixmapWidthPaddingInfo[d].padRoundUp+1))) -#endif - -#define FbPowerOfTwo(w) (((w) & ((w) - 1)) == 0) -/* - * Accelerated tiles are power of 2 width <= FB_UNIT - */ -#define FbEvenTile(w) ((w) <= FB_UNIT && FbPowerOfTwo(w)) -/* - * Accelerated stipples are power of 2 width and <= FB_UNIT/dstBpp - * with dstBpp a power of 2 as well - */ -#define FbEvenStip(w,bpp) ((w) * (bpp) <= FB_UNIT && FbPowerOfTwo(w) && FbPowerOfTwo(bpp)) - -/* - * icblt.c - */ -pixman_private void -fbBlt (pixman_bits_t *src, - FbStride srcStride, - int srcX, - - FbBits *dst, - FbStride dstStride, - int dstX, - - int width, - int height, - - int alu, - FbBits pm, - int bpp, - - Bool reverse, - Bool upsidedown); - -pixman_private void -fbBlt24 (pixman_bits_t *srcLine, - FbStride srcStride, - int srcX, - - FbBits *dstLine, - FbStride dstStride, - int dstX, - - int width, - int height, - - int alu, - FbBits pm, - - Bool reverse, - Bool upsidedown); - -pixman_private void -fbBltStip (FbStip *src, - FbStride srcStride, /* in FbStip units, not FbBits units */ - int srcX, - - FbStip *dst, - FbStride dstStride, /* in FbStip units, not FbBits units */ - int dstX, - - int width, - int height, - - int alu, - FbBits pm, - int bpp); - -/* - * icbltone.c - */ -pixman_private void -fbBltOne (FbStip *src, - FbStride srcStride, - int srcX, - FbBits *dst, - FbStride dstStride, - int dstX, - int dstBpp, - - int width, - int height, - - FbBits fgand, - FbBits fbxor, - FbBits bgand, - FbBits bgxor); - -#ifdef FB_24BIT -pixman_private void -fbBltOne24 (FbStip *src, - FbStride srcStride, /* FbStip units per scanline */ - int srcX, /* bit position of source */ - FbBits *dst, - FbStride dstStride, /* FbBits units per scanline */ - int dstX, /* bit position of dest */ - int dstBpp, /* bits per destination unit */ - - int width, /* width in bits of destination */ - int height, /* height in scanlines */ - - FbBits fgand, /* rrop values */ - FbBits fgxor, - FbBits bgand, - FbBits bgxor); -#endif - -/* - * icstipple.c - */ - -pixman_private void -fbTransparentSpan (pixman_bits_t *dst, - pixman_bits_t stip, - pixman_bits_t fgxor, - int n); - -pixman_private void -fbEvenStipple (pixman_bits_t *dst, - FbStride dstStride, - int dstX, - int dstBpp, - - int width, - int height, - - FbStip *stip, - FbStride stipStride, - int stipHeight, - - FbBits fgand, - FbBits fgxor, - FbBits bgand, - FbBits bgxor, - - int xRot, - int yRot); - -pixman_private void -fbOddStipple (pixman_bits_t *dst, - FbStride dstStride, - int dstX, - int dstBpp, - - int width, - int height, - - FbStip *stip, - FbStride stipStride, - int stipWidth, - int stipHeight, - - FbBits fgand, - FbBits fgxor, - FbBits bgand, - FbBits bgxor, - - int xRot, - int yRot); - -pixman_private void -fbStipple (pixman_bits_t *dst, - FbStride dstStride, - int dstX, - int dstBpp, - - int width, - int height, - - FbStip *stip, - FbStride stipStride, - int stipWidth, - int stipHeight, - Bool even, - - FbBits fgand, - FbBits fgxor, - FbBits bgand, - FbBits bgxor, - - int xRot, - int yRot); - -typedef struct _FbPixels { - pixman_bits_t *data; - unsigned int width; - unsigned int height; - unsigned int depth; - unsigned int bpp; - unsigned int stride; - int x; - int y; - unsigned int refcnt; -} FbPixels; - -/* XXX: This is to avoid including colormap.h from the server includes */ -typedef uint32_t Pixel; - -/* icutil.c */ -pixman_private pixman_bits_t -fbReplicatePixel (Pixel p, int bpp); - -/* fbtrap.c */ - -pixman_private void -fbRasterizeTrapezoid (pixman_image_t *pMask, - const pixman_trapezoid_t *pTrap, - int x_off, - int y_off); - -/* XXX: This is to avoid including gc.h from the server includes */ -/* clientClipType field in GC */ -#define CT_NONE 0 -/* #define CT_PIXMAP 1 (not used anymore) */ -#define CT_REGION 2 -#define CT_UNSORTED 6 -#define CT_YSORTED 10 -#define CT_YXSORTED 14 -#define CT_YXBANDED 18 - -#include "icimage.h" - -/* iccolor.c */ - -/* GCC 3.4 supports a "population count" builtin, which on many targets is - implemented with a single instruction. There is a fallback definition - in libgcc in case a target does not have one, which should be just as - good as the static function below. */ -#if __GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) -static inline int -_FbOnes(unsigned int mask) -{ - return __builtin_popcount(mask); -} -#else -# define ICINT_NEED_IC_ONES -pixman_private int -_FbOnes(unsigned int mask); -#endif - -/* icformat.c */ - -pixman_private void -pixman_format_init_code (pixman_format_t *format, int format_code); - -/* icimage.c */ - -pixman_private pixman_image_t * -pixman_image_createForPixels (FbPixels *pixels, - pixman_format_t *format); - -pixman_private uint32_t -pixman_gradient_color (pixman_gradient_stop_t *stop1, - pixman_gradient_stop_t *stop2, - uint32_t x); - -#define PictureGradientColor pixman_gradient_color - -/* icpixels.c */ - -pixman_private FbPixels * -FbPixelsCreate (int width, int height, int depth); - -pixman_private FbPixels * -FbPixelsCreateForData (pixman_bits_t *data, int width, int height, int depth, int bpp, int stride); - -pixman_private void -FbPixelsDestroy (FbPixels *pixels); - -/* ictransform.c */ - -pixman_private int -pixman_transform_point (pixman_transform_t *transform, - pixman_vector_t *vector); - -#include "icrop.h" - -/* XXX: For now, I'm just wholesale pasting Xserver/render/picture.h here: */ -#ifndef _PICTURE_H_ -#define _PICTURE_H_ - -typedef struct _DirectFormat *DirectFormatPtr; -typedef struct _PictFormat *PictFormatPtr; - -/* - * While the protocol is generous in format support, the - * sample implementation allows only packed RGB and GBR - * representations for data to simplify software rendering, - */ -#define PICT_FORMAT(bpp,type,a,r,g,b) (((bpp) << 24) | \ - ((type) << 16) | \ - ((a) << 12) | \ - ((r) << 8) | \ - ((g) << 4) | \ - ((b))) - -/* - * gray/color formats use a visual index instead of argb - */ -#define PICT_VISFORMAT(bpp,type,vi) (((bpp) << 24) | \ - ((type) << 16) | \ - ((vi))) - -#define PICT_FORMAT_BPP(f) (((f) >> 24) ) -#define PICT_FORMAT_TYPE(f) (((f) >> 16) & 0xff) -#define PICT_FORMAT_A(f) (((f) >> 12) & 0x0f) -#define PICT_FORMAT_R(f) (((f) >> 8) & 0x0f) -#define PICT_FORMAT_G(f) (((f) >> 4) & 0x0f) -#define PICT_FORMAT_B(f) (((f) ) & 0x0f) -#define PICT_FORMAT_RGB(f) (((f) ) & 0xfff) -#define PICT_FORMAT_VIS(f) (((f) ) & 0xffff) - -#define PICT_TYPE_OTHER 0 -#define PICT_TYPE_A 1 -#define PICT_TYPE_ARGB 2 -#define PICT_TYPE_ABGR 3 -#define PICT_TYPE_COLOR 4 -#define PICT_TYPE_GRAY 5 - -#define PICT_FORMAT_COLOR(f) (PICT_FORMAT_TYPE(f) & 2) - -/* 32bpp formats */ -#define PICT_a8r8g8b8 PICT_FORMAT(32,PICT_TYPE_ARGB,8,8,8,8) -#define PICT_x8r8g8b8 PICT_FORMAT(32,PICT_TYPE_ARGB,0,8,8,8) -#define PICT_a8b8g8r8 PICT_FORMAT(32,PICT_TYPE_ABGR,8,8,8,8) -#define PICT_x8b8g8r8 PICT_FORMAT(32,PICT_TYPE_ABGR,0,8,8,8) - -/* 24bpp formats */ -#define PICT_r8g8b8 PICT_FORMAT(24,PICT_TYPE_ARGB,0,8,8,8) -#define PICT_b8g8r8 PICT_FORMAT(24,PICT_TYPE_ABGR,0,8,8,8) - -/* 16bpp formats */ -#define PICT_r5g6b5 PICT_FORMAT(16,PICT_TYPE_ARGB,0,5,6,5) -#define PICT_b5g6r5 PICT_FORMAT(16,PICT_TYPE_ABGR,0,5,6,5) - -#define PICT_a1r5g5b5 PICT_FORMAT(16,PICT_TYPE_ARGB,1,5,5,5) -#define PICT_x1r5g5b5 PICT_FORMAT(16,PICT_TYPE_ARGB,0,5,5,5) -#define PICT_a1b5g5r5 PICT_FORMAT(16,PICT_TYPE_ABGR,1,5,5,5) -#define PICT_x1b5g5r5 PICT_FORMAT(16,PICT_TYPE_ABGR,0,5,5,5) -#define PICT_a4r4g4b4 PICT_FORMAT(16,PICT_TYPE_ARGB,4,4,4,4) -#define PICT_x4r4g4b4 PICT_FORMAT(16,PICT_TYPE_ARGB,0,4,4,4) -#define PICT_a4b4g4r4 PICT_FORMAT(16,PICT_TYPE_ABGR,4,4,4,4) -#define PICT_x4b4g4r4 PICT_FORMAT(16,PICT_TYPE_ABGR,0,4,4,4) - -/* 8bpp formats */ -#define PICT_a8 PICT_FORMAT(8,PICT_TYPE_A,8,0,0,0) -#define PICT_r3g3b2 PICT_FORMAT(8,PICT_TYPE_ARGB,0,3,3,2) -#define PICT_b2g3r3 PICT_FORMAT(8,PICT_TYPE_ABGR,0,3,3,2) -#define PICT_a2r2g2b2 PICT_FORMAT(8,PICT_TYPE_ARGB,2,2,2,2) -#define PICT_a2b2g2r2 PICT_FORMAT(8,PICT_TYPE_ABGR,2,2,2,2) - -#define PICT_c8 PICT_FORMAT(8,PICT_TYPE_COLOR,0,0,0,0) -#define PICT_g8 PICT_FORMAT(8,PICT_TYPE_GRAY,0,0,0,0) - -/* 4bpp formats */ -#define PICT_a4 PICT_FORMAT(4,PICT_TYPE_A,4,0,0,0) -#define PICT_r1g2b1 PICT_FORMAT(4,PICT_TYPE_ARGB,0,1,2,1) -#define PICT_b1g2r1 PICT_FORMAT(4,PICT_TYPE_ABGR,0,1,2,1) -#define PICT_a1r1g1b1 PICT_FORMAT(4,PICT_TYPE_ARGB,1,1,1,1) -#define PICT_a1b1g1r1 PICT_FORMAT(4,PICT_TYPE_ABGR,1,1,1,1) - -#define PICT_c4 PICT_FORMAT(4,PICT_TYPE_COLOR,0,0,0,0) -#define PICT_g4 PICT_FORMAT(4,PICT_TYPE_GRAY,0,0,0,0) - -/* 1bpp formats */ -#define PICT_a1 PICT_FORMAT(1,PICT_TYPE_A,1,0,0,0) - -#define PICT_g1 PICT_FORMAT(1,PICT_TYPE_GRAY,0,0,0,0) - -/* - * For dynamic indexed visuals (GrayScale and PseudoColor), these control the - * selection of colors allocated for drawing to Pictures. The default - * policy depends on the size of the colormap: - * - * Size Default Policy - * ---------------------------- - * < 64 PolicyMono - * < 256 PolicyGray - * 256 PolicyColor (only on PseudoColor) - * - * The actual allocation code lives in miindex.c, and so is - * austensibly server dependent, but that code does: - * - * PolicyMono Allocate no additional colors, use black and white - * PolicyGray Allocate 13 gray levels (11 cells used) - * PolicyColor Allocate a 4x4x4 cube and 13 gray levels (71 cells used) - * PolicyAll Allocate as big a cube as possible, fill with gray (all) - * - * Here's a picture to help understand how many colors are - * actually allocated (this is just the gray ramp): - * - * gray level - * all 0000 1555 2aaa 4000 5555 6aaa 8000 9555 aaaa bfff d555 eaaa ffff - * b/w 0000 ffff - * 4x4x4 5555 aaaa - * extra 1555 2aaa 4000 6aaa 8000 9555 bfff d555 eaaa - * - * The default colormap supplies two gray levels (black/white), the - * 4x4x4 cube allocates another two and nine more are allocated to fill - * in the 13 levels. When the 4x4x4 cube is not allocated, a total of - * 11 cells are allocated. - */ - -#define PictureCmapPolicyInvalid -1 -#define PictureCmapPolicyDefault 0 -#define PictureCmapPolicyMono 1 -#define PictureCmapPolicyGray 2 -#define PictureCmapPolicyColor 3 -#define PictureCmapPolicyAll 4 - -extern pixman_private int PictureCmapPolicy; - -int PictureParseCmapPolicy (const char *name); - -/* Fixed point updates from Carl Worth, USC, Information Sciences Institute */ - -#ifdef WIN32 -typedef __int64 xFixed_32_32; -#else -# if defined(__alpha__) || defined(__alpha) || \ - defined(ia64) || defined(__ia64__) || \ - defined(__sparc64__) || \ - defined(__s390x__) || \ - defined(x86_64) || defined (__x86_64__) -typedef long xFixed_32_32; -# else -# if defined(__GNUC__) && \ - ((__GNUC__ > 2) || \ - ((__GNUC__ == 2) && defined(__GNUC_MINOR__) && (__GNUC_MINOR__ > 7))) -__extension__ -# endif -typedef long long int xFixed_32_32; -# endif -#endif - -typedef xFixed_32_32 xFixed_48_16; -typedef uint32_t xFixed_1_31; -typedef uint32_t xFixed_1_16; -typedef int32_t xFixed_16_16; - -/* - * An unadorned "xFixed" is the same as xFixed_16_16, - * (since it's quite common in the code) - */ -typedef xFixed_16_16 xFixed; -#define XFIXED_BITS 16 - -#define xFixedToInt(f) (int) ((f) >> XFIXED_BITS) -#define IntToxFixed(i) ((xFixed) (i) << XFIXED_BITS) -#define xFixedE ((xFixed) 1) -#define xFixed1 (IntToxFixed(1)) -#define xFixedToDouble(f) (double) ((f) / (double) xFixed1) -#define xFixed1MinusE (xFixed1 - xFixedE) -#define xFixedFrac(f) ((f) & xFixed1MinusE) -#define xFixedFloor(f) ((f) & ~xFixed1MinusE) -#define xFixedCeil(f) xFixedFloor((f) + xFixed1MinusE) - -#define xFixedFraction(f) ((f) & xFixed1MinusE) -#define xFixedMod2(f) ((f) & (xFixed1 | xFixed1MinusE)) - -/* whether 't' is a well defined not obviously empty trapezoid */ -#define xTrapezoidValid(t) ((t)->left.p1.y != (t)->left.p2.y && \ - (t)->right.p1.y != (t)->right.p2.y && \ - (int) ((t)->bottom - (t)->top) > 0) - -/* - * Standard NTSC luminance conversions: - * - * y = r * 0.299 + g * 0.587 + b * 0.114 - * - * Approximate this for a bit more speed: - * - * y = (r * 153 + g * 301 + b * 58) / 512 - * - * This gives 17 bits of luminance; to get 15 bits, lop the low two - */ - -#define CvtR8G8B8toY15(s) (((((s) >> 16) & 0xff) * 153 + \ - (((s) >> 8) & 0xff) * 301 + \ - (((s) ) & 0xff) * 58) >> 2) - -#endif /* _PICTURE_H_ */ - -/* Macros needed by fbpict.c */ - -#define cvt8888to0565(s) ((((s) >> 3) & 0x001f) | \ - (((s) >> 5) & 0x07e0) | \ - (((s) >> 8) & 0xf800)) -#define cvt0565to0888(s) (((((s) << 3) & 0xf8) | (((s) >> 2) & 0x7)) | \ - ((((s) << 5) & 0xfc00) | (((s) >> 1) & 0x300)) | \ - ((((s) << 8) & 0xf80000) | (((s) << 3) & 0x70000))) - -#if IMAGE_BYTE_ORDER == MSBFirst -#define Fetch24(a) ((unsigned long) (a) & 1 ? \ - ((*(a) << 16) | *((CARD16 *) ((a)+1))) : \ - ((*((CARD16 *) (a)) << 8) | *((a)+2))) -#define Store24(a,v) ((unsigned long) (a) & 1 ? \ - ((*(a) = (CARD8) ((v) >> 16)), \ - (*((CARD16 *) ((a)+1)) = (CARD16) (v))) : \ - ((*((CARD16 *) (a)) = (CARD16) ((v) >> 8)), \ - (*((a)+2) = (CARD8) (v)))) -#else -#define Fetch24(a) ((unsigned long) (a) & 1 ? \ - ((*(a)) | (*((CARD16 *) ((a)+1)) << 8)) : \ - ((*((CARD16 *) (a))) | (*((a)+2) << 16))) -#define Store24(a,v) ((unsigned long) (a) & 1 ? \ - ((*(a) = (CARD8) (v)), \ - (*((CARD16 *) ((a)+1)) = (CARD16) ((v) >> 8))) : \ - ((*((CARD16 *) (a)) = (CARD16) (v)),\ - (*((a)+2) = (CARD8) ((v) >> 16)))) -#endif - -#endif /* _PIXMANINT_H_ */ diff --git a/gfx/cairo/libpixman/src/pixregion.c b/gfx/cairo/libpixman/src/pixregion.c index 4cd08e59c41a..0404dff4445a 100644 --- a/gfx/cairo/libpixman/src/pixregion.c +++ b/gfx/cairo/libpixman/src/pixregion.c @@ -45,14 +45,18 @@ SOFTWARE. ******************************************************************/ -#include "pixmanint.h" - #include #include #include #include "pixregionint.h" +#if defined (__GNUC__) && !defined (NO_INLINES) +#define INLINE __inline +#else +#define INLINE +#endif + #undef assert #ifdef DEBUG_PIXREGION #define assert(expr) {if (!(expr)) \ @@ -73,11 +77,16 @@ static pixman_box16_t pixman_region_emptyBox = {0, 0, 0, 0}; static pixman_region16_data_t pixman_region_emptyData = {0, 0}; static pixman_region16_data_t pixman_brokendata = {0, 0}; +static pixman_region16_t pixman_brokenregion = { { 0, 0, 0, 0 }, &pixman_brokendata }; static pixman_region_status_t pixman_break (pixman_region16_t *pReg); -static pixman_region_status_t -pixman_rect_alloc(pixman_region16_t * region, int n); + +static void +pixman_init (pixman_region16_t *region, pixman_box16_t *rect); + +static void +pixman_uninit (pixman_region16_t *region); /* * The functions in this file implement the Region abstraction used extensively @@ -288,65 +297,68 @@ pixman_region16_valid(reg) #endif /* DEBUG_PIXREGION */ -void -pixman_region_init(pixman_region16_t *region) +/* Create a new empty region */ +pixman_region16_t * +pixman_region_create (void) { - region->extents = pixman_region_emptyBox; - region->data = &pixman_region_emptyData; + return pixman_region_create_simple (NULL); } -void -pixman_region_init_rect(pixman_region16_t *region, - int x, int y, unsigned int width, unsigned int height) +/***************************************************************** + * pixman_region_create_simple (extents) + * This routine creates a pixman_region16_t for a simple + * rectangular region. + *****************************************************************/ +pixman_region16_t * +pixman_region_create_simple (pixman_box16_t *extents) { - region->extents.x1 = x; - region->extents.y1 = y; - region->extents.x2 = x + width; - region->extents.y2 = y + height; - region->data = NULL; + pixman_region16_t *region; + + region = malloc (sizeof (pixman_region16_t)); + if (region == NULL) + return &pixman_brokenregion; + + pixman_init (region, extents); + + return region; } -void -pixman_region_init_with_extents(pixman_region16_t *region, pixman_box16_t *extents) -{ - region->extents = *extents; - region->data = NULL; -} +/***************************************************************** + * RegionInit(pReg, rect, size) + * Outer region rect is statically allocated. + *****************************************************************/ -pixman_region_status_t -pixman_region_init_rects(pixman_region16_t *region, pixman_box16_t *boxes, int count) +static void +pixman_init(pixman_region16_t *region, pixman_box16_t *extents) { - int overlap; - - if (count == 1) { - pixman_region_init_rect(region, - boxes[0].x1, - boxes[0].y1, - boxes[0].x2 - boxes[0].x1, - boxes[0].y2 - boxes[0].y1); - return PIXMAN_REGION_STATUS_SUCCESS; + if (extents) + { + region->extents = *extents; + region->data = NULL; + } + else + { + region->extents = pixman_region_emptyBox; + region->data = &pixman_region_emptyData; } - - pixman_region_init(region); - if (!pixman_rect_alloc(region, count)) - return PIXMAN_REGION_STATUS_FAILURE; - - /* Copy in the rects */ - memcpy (PIXREGION_RECTS(region), boxes, sizeof(pixman_box16_t) * count); - region->data->numRects = count; - - /* Validate */ - region->extents.x1 = region->extents.x2 = 0; - return pixman_region_validate (region, &overlap); } -void -pixman_region_fini (pixman_region16_t *region) +static void +pixman_uninit (pixman_region16_t *region) { good (region); freeData (region); } +void +pixman_region_destroy (pixman_region16_t *region) +{ + pixman_uninit (region); + + if (region != &pixman_brokenregion) + free (region); +} + int pixman_region_num_rects (pixman_region16_t *region) { @@ -457,7 +469,7 @@ pixman_region_copy(pixman_region16_t *dst, pixman_region16_t *src) * *----------------------------------------------------------------------- */ -static inline int +INLINE static int pixman_coalesce ( pixman_region16_t * region, /* Region to coalesce */ int prevStart, /* Index of start of previous band */ @@ -540,7 +552,7 @@ pixman_coalesce ( *----------------------------------------------------------------------- */ -static inline pixman_region_status_t +INLINE static pixman_region_status_t pixman_region_appendNonO ( pixman_region16_t * region, pixman_box16_t * r, @@ -582,7 +594,7 @@ pixman_region_appendNonO ( { \ int newRects; \ if ((newRects = rEnd - r)) { \ - RECTALLOC_BAIL(newReg, newRects, bail); \ + RECTALLOC(newReg, newRects); \ memmove((char *)PIXREGION_TOP(newReg),(char *)r, \ newRects * sizeof(pixman_box16_t)); \ newReg->data->numRects += newRects; \ @@ -699,13 +711,9 @@ pixman_op( newReg->data = &pixman_region_emptyData; else if (newReg->data->size) newReg->data->numRects = 0; - if (newSize > newReg->data->size) { - if (!pixman_rect_alloc(newReg, newSize)) { - if (oldData) - free (oldData); + if (newSize > newReg->data->size) + if (!pixman_rect_alloc(newReg, newSize)) return PIXMAN_REGION_STATUS_FAILURE; - } - } /* * Initialize ybot. @@ -762,8 +770,7 @@ pixman_op( bot = MIN(r1->y2, r2y1); if (top != bot) { curBand = newReg->data->numRects; - if (!pixman_region_appendNonO(newReg, r1, r1BandEnd, top, bot)) - goto bail; + pixman_region_appendNonO(newReg, r1, r1BandEnd, top, bot); Coalesce(newReg, prevBand, curBand); } } @@ -774,8 +781,7 @@ pixman_op( bot = MIN(r2->y2, r1y1); if (top != bot) { curBand = newReg->data->numRects; - if (!pixman_region_appendNonO(newReg, r2, r2BandEnd, top, bot)) - goto bail; + pixman_region_appendNonO(newReg, r2, r2BandEnd, top, bot); Coalesce(newReg, prevBand, curBand); } } @@ -791,9 +797,8 @@ pixman_op( ybot = MIN(r1->y2, r2->y2); if (ybot > ytop) { curBand = newReg->data->numRects; - if (!(* overlapFunc)(newReg, r1, r1BandEnd, r2, r2BandEnd, ytop, ybot, - pOverlap)) - goto bail; + (* overlapFunc)(newReg, r1, r1BandEnd, r2, r2BandEnd, ytop, ybot, + pOverlap); Coalesce(newReg, prevBand, curBand); } @@ -818,8 +823,7 @@ pixman_op( /* Do first nonOverlap1Func call, which may be able to coalesce */ FindBand(r1, r1BandEnd, r1End, r1y1); curBand = newReg->data->numRects; - if (!pixman_region_appendNonO(newReg, r1, r1BandEnd, MAX(r1y1, ybot), r1->y2)) - goto bail; + pixman_region_appendNonO(newReg, r1, r1BandEnd, MAX(r1y1, ybot), r1->y2); Coalesce(newReg, prevBand, curBand); /* Just append the rest of the boxes */ AppendRegions(newReg, r1BandEnd, r1End); @@ -828,8 +832,7 @@ pixman_op( /* Do first nonOverlap2Func call, which may be able to coalesce */ FindBand(r2, r2BandEnd, r2End, r2y1); curBand = newReg->data->numRects; - if (!pixman_region_appendNonO(newReg, r2, r2BandEnd, MAX(r2y1, ybot), r2->y2)) - goto bail; + pixman_region_appendNonO(newReg, r2, r2BandEnd, MAX(r2y1, ybot), r2->y2); Coalesce(newReg, prevBand, curBand); /* Append rest of boxes */ AppendRegions(newReg, r2BandEnd, r2End); @@ -855,11 +858,6 @@ pixman_op( } return PIXMAN_REGION_STATUS_SUCCESS; - -bail: - if (oldData) - free(oldData); - return PIXMAN_REGION_STATUS_FAILURE; } /*- @@ -1139,7 +1137,7 @@ pixman_region_unionO ( /* Convenience function for performing union of region with a single rectangle */ pixman_region_status_t pixman_region_union_rect(pixman_region16_t *dest, pixman_region16_t *source, - int x, int y, unsigned int width, unsigned int height) + int x, int y, unsigned int width, unsigned int height) { pixman_region16_t region; diff --git a/gfx/cairo/libpixman/src/pixregionint.h b/gfx/cairo/libpixman/src/pixregionint.h index 385a7f23460b..b5b53fd2257b 100644 --- a/gfx/cairo/libpixman/src/pixregionint.h +++ b/gfx/cairo/libpixman/src/pixregionint.h @@ -48,11 +48,16 @@ SOFTWARE. #include "pixman.h" -struct pixman_region16_data { +typedef struct pixman_region16_data { long size; long numRects; /* XXX: And why, exactly, do we have this bogus struct definition? */ /* pixman_box16_t rects[size]; in memory but not explicitly declared */ +} pixman_region16_data_t; + +struct pixman_region16 { + pixman_box16_t extents; + pixman_region16_data_t *data; }; typedef struct pixman_region16_point { diff --git a/gfx/cairo/libpixman/src/renderedge.c b/gfx/cairo/libpixman/src/renderedge.c index 47d08c6276f0..563a4e2119cb 100644 --- a/gfx/cairo/libpixman/src/renderedge.c +++ b/gfx/cairo/libpixman/src/renderedge.c @@ -20,8 +20,6 @@ * PERFORMANCE OF THIS SOFTWARE. */ -#include "pixmanint.h" - #include "pixman-xserver-compat.h" /* diff --git a/gfx/cairo/nonfatal-assertions.patch b/gfx/cairo/nonfatal-assertions.patch index dcbb904abd26..e8d8751654a4 100644 --- a/gfx/cairo/nonfatal-assertions.patch +++ b/gfx/cairo/nonfatal-assertions.patch @@ -1,17 +1,39 @@ -diff -r b79d47dad1ea gfx/cairo/cairo/src/cairoint.h ---- a/gfx/cairo/cairo/src/cairoint.h Fri Jun 08 18:09:53 2007 -0700 -+++ b/gfx/cairo/cairo/src/cairoint.h Fri Jun 29 09:18:02 2007 +0200 -@@ -159,6 +159,13 @@ CAIRO_BEGIN_DECLS +Index: gfx/cairo/cairo/src/cairoint.h +=================================================================== +RCS file: /cvsroot/mozilla/gfx/cairo/cairo/src/cairoint.h,v +retrieving revision 1.34 +diff -u -p -1 -2 -r1.34 cairoint.h +--- gfx/cairo/cairo/src/cairoint.h 4 Apr 2007 01:09:16 -0000 1.34 ++++ gfx/cairo/cairo/src/cairoint.h 1 Jun 2007 02:05:18 -0000 +@@ -231,24 +231,31 @@ typedef void *cairo_mutex_t; + #define FALSE 0 + #endif + + #ifndef TRUE + #define TRUE 1 + #endif #ifndef M_PI #define M_PI 3.14159265358979323846 -+#endif -+ + #endif + + #ifndef MOZILLA_CAIRO_NOT_DEFINED ++/* Make assertions non-fatal */ +#ifndef NDEBUG +#undef assert +#define assert(expr) \ + do { if (!(expr)) fprintf(stderr, "Assertion failed at %s:%d: %s\n", \ + __FILE__, __LINE__, #expr); } while (0) ++#endif + #ifndef INT32_MAX + # ifdef INT_MAX + # define INT32_MAX INT_MAX + # define INT32_MIN INT_MIN + # else + # define INT32_MAX 2147483647 + # define INT32_MIN (-2147483647 - 1) + # endif + #endif #endif - #undef ARRAY_LENGTH + /* Size in bytes of buffer to use off the stack per functions. diff --git a/gfx/cairo/quartz-glyph-rounding.patch b/gfx/cairo/quartz-glyph-rounding.patch new file mode 100755 index 000000000000..0a29a84d9c01 --- /dev/null +++ b/gfx/cairo/quartz-glyph-rounding.patch @@ -0,0 +1,53 @@ +Index: gfx/cairo/cairo/src/cairo-quartz-surface.c +=================================================================== +RCS file: /cvsroot/mozilla/gfx/cairo/cairo/src/cairo-quartz-surface.c,v +retrieving revision 1.9 +diff -u -p -1 -2 -r1.9 cairo-quartz-surface.c +--- gfx/cairo/cairo/src/cairo-quartz-surface.c 24 Jan 2007 23:53:03 -0000 1.9 ++++ gfx/cairo/cairo/src/cairo-quartz-surface.c 15 Mar 2007 03:34:48 -0000 +@@ -1407,37 +1407,39 @@ _cairo_quartz_surface_show_glyphs (void + // XXXtodo/perf: stack storage for glyphs/sizes + #define STATIC_BUF_SIZE 64 + CGGlyph glyphs_static[STATIC_BUF_SIZE]; + CGSize cg_advances_static[STATIC_BUF_SIZE]; + CGGlyph *cg_glyphs = &glyphs_static[0]; + CGSize *cg_advances = &cg_advances_static[0]; + + if (num_glyphs > STATIC_BUF_SIZE) { + cg_glyphs = (CGGlyph*) malloc(sizeof(CGGlyph) * num_glyphs); + cg_advances = (CGSize*) malloc(sizeof(CGSize) * num_glyphs); + } + +- double xprev = glyphs[0].x; +- double yprev = glyphs[0].y; ++ float xprev = glyphs[0].x; ++ float yprev = glyphs[0].y; + + cg_glyphs[0] = glyphs[0].index; + cg_advances[0].width = 0; + cg_advances[0].height = 0; + + for (i = 1; i < num_glyphs; i++) { + cg_glyphs[i] = glyphs[i].index; +- cg_advances[i-1].width = glyphs[i].x - xprev; +- cg_advances[i-1].height = glyphs[i].y - yprev; +- xprev = glyphs[i].x; +- yprev = glyphs[i].y; ++ float xf = glyphs[i].x; ++ float yf = glyphs[i].y; ++ cg_advances[i-1].width = xf - xprev; ++ cg_advances[i-1].height = yf - yprev; ++ xprev = xf; ++ yprev = yf; + } + + #if 0 + for (i = 0; i < num_glyphs; i++) { + ND((stderr, "[%d: %d %f,%f]\n", i, cg_glyphs[i], cg_advances[i].width, cg_advances[i].height)); + } + #endif + + CGContextShowGlyphsWithAdvances (surface->cgContext, + cg_glyphs, + cg_advances, + num_glyphs); diff --git a/gfx/cairo/win32-logical-font-scale.patch b/gfx/cairo/win32-logical-font-scale.patch deleted file mode 100644 index b1135c41d196..000000000000 --- a/gfx/cairo/win32-logical-font-scale.patch +++ /dev/null @@ -1,12 +0,0 @@ -diff -r e10a8066a62c gfx/cairo/cairo/src/cairo-win32-private.h ---- a/gfx/cairo/cairo/src/cairo-win32-private.h Fri Jun 08 17:39:38 2007 -0700 -+++ b/gfx/cairo/cairo/src/cairo-win32-private.h Fri Jun 29 09:14:35 2007 +0200 -@@ -46,7 +46,7 @@ - #define SB_NONE 0 - #endif - --#define WIN32_FONT_LOGICAL_SCALE 32 -+#define WIN32_FONT_LOGICAL_SCALE 1 - - typedef struct _cairo_win32_surface { - cairo_surface_t base; diff --git a/gfx/cairo/win32-no-printer-bitblt.patch b/gfx/cairo/win32-no-printer-bitblt.patch deleted file mode 100644 index a46076375252..000000000000 --- a/gfx/cairo/win32-no-printer-bitblt.patch +++ /dev/null @@ -1,17 +0,0 @@ -diff -r 0a3ea2430215 gfx/cairo/cairo/src/cairo-win32-surface.c ---- a/gfx/cairo/cairo/src/cairo-win32-surface.c Fri Jun 08 18:04:18 2007 -0700 -+++ b/gfx/cairo/cairo/src/cairo-win32-surface.c Fri Jun 08 18:06:00 2007 -0700 -@@ -476,7 +476,12 @@ _cairo_win32_surface_get_subimage (cairo - - status = CAIRO_INT_STATUS_UNSUPPORTED; - -- if ((local->flags & CAIRO_WIN32_SURFACE_CAN_BITBLT) && -+ /* Check for SURFACE_IS_DISPLAY here, because there are a lot -+ * of printer drivers that lie and say they can BitBlt, but -+ * just spit out black instead. -+ */ -+ if ((local->flags & CAIRO_WIN32_SURFACE_IS_DISPLAY) && -+ (local->flags & CAIRO_WIN32_SURFACE_CAN_BITBLT) && - BitBlt (local->dc, - 0, 0, - width, height, diff --git a/gfx/cairo/win32-scaled-font-size.patch b/gfx/cairo/win32-scaled-font-size.patch index 6ca614019df5..7e67d919481d 100755 --- a/gfx/cairo/win32-scaled-font-size.patch +++ b/gfx/cairo/win32-scaled-font-size.patch @@ -1,12 +1,20 @@ -diff -r 1b568972e0a3 gfx/cairo/cairo/src/cairo-win32-font.c ---- a/gfx/cairo/cairo/src/cairo-win32-font.c Fri Jun 08 17:27:06 2007 -0700 -+++ b/gfx/cairo/cairo/src/cairo-win32-font.c Fri Jun 08 17:35:16 2007 -0700 -@@ -1,3 +1,4 @@ -+/* -*- Mode: c; tab-width: 8; c-basic-offset: 4; indent-tabs-mode: t; -*- */ - /* cairo - a vector graphics library with display and print output - * - * Copyright © 2005 Red Hat, Inc -@@ -226,9 +227,15 @@ _get_system_quality (void) +Index: gfx/cairo/cairo/src/cairo-win32-font.c +=================================================================== +RCS file: /cvsroot/mozilla/gfx/cairo/cairo/src/cairo-win32-font.c,v +retrieving revision 1.21 +diff -u -p -1 -2 -r1.21 cairo-win32-font.c +--- gfx/cairo/cairo/src/cairo-win32-font.c 4 Apr 2007 01:09:15 -0000 1.21 ++++ gfx/cairo/cairo/src/cairo-win32-font.c 14 Apr 2007 09:05:25 -0000 +@@ -218,27 +218,33 @@ _get_system_quality (void) + } + + if (smoothing_type == FE_FONTSMOOTHINGCLEARTYPE) + return CLEARTYPE_QUALITY; + } + + return ANTIALIASED_QUALITY; + } else { + return DEFAULT_QUALITY; } } @@ -23,14 +31,32 @@ diff -r 1b568972e0a3 gfx/cairo/cairo/src/cairo-win32-font.c cairo_font_face_t *font_face, const cairo_matrix_t *font_matrix, const cairo_matrix_t *ctm, -@@ -274,11 +281,21 @@ _win32_scaled_font_create (LOGFONTW + const cairo_font_options_t *options) + { + cairo_win32_scaled_font_t *f; + cairo_matrix_t scale; + cairo_status_t status; + + _cairo_win32_initialize (); + + f = malloc (sizeof(cairo_win32_scaled_font_t)); +@@ -268,29 +274,38 @@ _win32_scaled_font_create (LOGFONTW + case CAIRO_ANTIALIAS_SUBPIXEL: + if (_have_cleartype_quality ()) + f->quality = CLEARTYPE_QUALITY; + else + f->quality = ANTIALIASED_QUALITY; + break; + case CAIRO_ANTIALIAS_DEFAULT: + ASSERT_NOT_REACHED; + } } f->em_square = 0; - f->scaled_hfont = hfont; + f->scaled_hfont = NULL; f->unscaled_hfont = NULL; - +- - /* don't delete the hfont if it was passed in to us */ - f->delete_scaled_hfont = !hfont; + if (f->quality == logfont->lfQuality || @@ -48,7 +74,25 @@ diff -r 1b568972e0a3 gfx/cairo/cairo/src/cairo-win32-font.c cairo_matrix_multiply (&scale, font_matrix, ctm); _compute_transform (f, &scale); -@@ -1483,6 +1500,11 @@ const cairo_scaled_font_backend_t cairo_ + + _cairo_scaled_font_init (&f->base, font_face, + font_matrix, ctm, options, + &cairo_win32_scaled_font_backend); + + status = _cairo_win32_scaled_font_set_metrics (f); + if (status) { + cairo_scaled_font_destroy (&f->base); + return NULL; +@@ -1479,133 +1494,177 @@ const cairo_scaled_font_backend_t cairo_ + _cairo_win32_scaled_font_glyph_init, + _cairo_win32_scaled_font_text_to_glyphs, + NULL, /* ucs4_to_index */ + _cairo_win32_scaled_font_show_glyphs, + _cairo_win32_scaled_font_load_truetype_table, + _cairo_win32_scaled_font_map_glyphs_to_unicode, + }; + + /* cairo_win32_font_face_t */ typedef struct _cairo_win32_font_face cairo_win32_font_face_t; @@ -60,22 +104,28 @@ diff -r 1b568972e0a3 gfx/cairo/cairo/src/cairo-win32-font.c struct _cairo_win32_font_face { cairo_font_face_t base; LOGFONTW logfont; -@@ -1494,6 +1516,14 @@ static void + HFONT hfont; + }; + + /* implement the platform-specific interface */ + static void _cairo_win32_font_face_destroy (void *abstract_face) { -+} -+ + } + +static cairo_bool_t +_is_scale (const cairo_matrix_t *matrix, double scale) +{ + return matrix->xx == scale && matrix->yy == scale && + matrix->xy == 0. && matrix->yx == 0. && + matrix->x0 == 0. && matrix->y0 == 0.; - } - ++} ++ static cairo_status_t -@@ -1503,10 +1533,20 @@ _cairo_win32_font_face_scaled_font_creat + _cairo_win32_font_face_scaled_font_create (void *abstract_face, + const cairo_matrix_t *font_matrix, + const cairo_matrix_t *ctm, const cairo_font_options_t *options, cairo_scaled_font_t **font) { @@ -83,6 +133,8 @@ diff -r 1b568972e0a3 gfx/cairo/cairo/src/cairo-win32-font.c + cairo_win32_font_face_t *font_face = abstract_face; + _cairo_win32_initialize (); + + if (font_face->hfont) { + /* Check whether it's OK to go ahead and use the font-face's HFONT. */ + if (_is_scale (ctm, 1.) && @@ -97,7 +149,15 @@ diff -r 1b568972e0a3 gfx/cairo/cairo/src/cairo-win32-font.c &font_face->base, font_matrix, ctm, options); if (*font) -@@ -1522,10 +1562,13 @@ static const cairo_font_face_backend_t _ + return CAIRO_STATUS_SUCCESS; + else + return CAIRO_STATUS_NO_MEMORY; + } + + static const cairo_font_face_backend_t _cairo_win32_font_face_backend = { + CAIRO_FONT_TYPE_WIN32, + _cairo_win32_font_face_destroy, + _cairo_win32_font_face_scaled_font_create }; /** @@ -114,7 +174,12 @@ diff -r 1b568972e0a3 gfx/cairo/cairo/src/cairo-win32-font.c * * Creates a new font for the Win32 font backend based on a * #LOGFONT. This font can then be used with -@@ -1538,22 +1581,44 @@ static const cairo_font_face_backend_t _ + * cairo_set_font_face() or cairo_scaled_font_create(). + * The #cairo_scaled_font_t + * returned from cairo_scaled_font_create() is also for the Win32 backend + * and can be used with functions such as cairo_win32_scaled_font_select_font(). + * + * Return value: a newly created #cairo_font_face_t. Free with * cairo_font_face_destroy() when you are done using it. **/ cairo_font_face_t * @@ -123,6 +188,8 @@ diff -r 1b568972e0a3 gfx/cairo/cairo/src/cairo-win32-font.c { cairo_win32_font_face_t *font_face; + _cairo_win32_initialize (); + font_face = malloc (sizeof (cairo_win32_font_face_t)); if (!font_face) { - _cairo_error (CAIRO_STATUS_NO_MEMORY); @@ -138,9 +205,9 @@ diff -r 1b568972e0a3 gfx/cairo/cairo/src/cairo-win32-font.c _cairo_font_face_init (&font_face->base, &_cairo_win32_font_face_backend); return &font_face->base; -+} -+ -+/** + } + + /** + * cairo_win32_font_face_create_for_logfontw: + * @logfont: A #LOGFONTW structure specifying the font to use. + * The lfHeight, lfWidth, lfOrientation and lfEscapement @@ -160,44 +227,77 @@ diff -r 1b568972e0a3 gfx/cairo/cairo/src/cairo-win32-font.c +cairo_win32_font_face_create_for_logfontw (LOGFONTW *logfont) +{ + return cairo_win32_font_face_create_for_logfontw_hfont (logfont, NULL); - } - - /** -@@ -1573,19 +1638,17 @@ cairo_font_face_t * ++} ++ ++/** + * cairo_win32_font_face_create_for_hfont: + * @font: An #HFONT structure specifying the font to use. + * + * Creates a new font for the Win32 font backend based on a + * #HFONT. This font can then be used with + * cairo_set_font_face() or cairo_scaled_font_create(). + * The #cairo_scaled_font_t + * returned from cairo_scaled_font_create() is also for the Win32 backend + * and can be used with functions such as cairo_win32_scaled_font_select_font(). + * + * Return value: a newly created #cairo_font_face_t. Free with + * cairo_font_face_destroy() when you are done using it. + **/ cairo_font_face_t * cairo_win32_font_face_create_for_hfont (HFONT font) { - cairo_win32_font_face_t *font_face; - +- _cairo_win32_initialize (); ++ LOGFONTW logfont; ++ GetObject (font, sizeof(logfont), &logfont); + - font_face = malloc (sizeof (cairo_win32_font_face_t)); - if (!font_face) { - _cairo_error (CAIRO_STATUS_NO_MEMORY); - return (cairo_font_face_t *)&_cairo_font_face_nil; -- } -- -- font_face->hfont = font; -- -- _cairo_font_face_init (&font_face->base, &_cairo_win32_font_face_backend); -- -- return &font_face->base; -+ LOGFONTW logfont; -+ GetObject (font, sizeof(logfont), &logfont); -+ + if (logfont.lfEscapement != 0 || logfont.lfOrientation != 0 || + logfont.lfWidth != 0) { + /* We can't use this font because that optimization requires that + * lfEscapement, lfOrientation and lfWidth be zero. */ + font = NULL; -+ } -+ + } + +- font_face->hfont = font; +- +- _cairo_font_face_init (&font_face->base, &_cairo_win32_font_face_backend); +- +- return &font_face->base; + return cairo_win32_font_face_create_for_logfontw_hfont (&logfont, font); } /** -diff -r 1b568972e0a3 gfx/cairo/cairo/src/cairo-win32.h ---- a/gfx/cairo/cairo/src/cairo-win32.h Fri Jun 08 17:27:06 2007 -0700 -+++ b/gfx/cairo/cairo/src/cairo-win32.h Fri Jun 08 17:35:16 2007 -0700 -@@ -70,6 +70,9 @@ cairo_public cairo_font_face_t * + * cairo_win32_scaled_font_select_font: + * @scaled_font: A #cairo_scaled_font_t from the Win32 font backend. Such an + * object can be created with cairo_win32_scaled_font_create_for_logfontw(). + * @hdc: a device context + * + * Selects the font into the given device context and changes the + * map mode and world transformation of the device context to match + * that of the font. This function is intended for use when using + * layout APIs such as Uniscribe to do text layout with the +Index: gfx/cairo/cairo/src/cairo-win32.h +=================================================================== +RCS file: /cvsroot/mozilla/gfx/cairo/cairo/src/cairo-win32.h,v +retrieving revision 1.14 +diff -u -p -1 -2 -r1.14 cairo-win32.h +--- gfx/cairo/cairo/src/cairo-win32.h 24 Jan 2007 23:53:03 -0000 1.14 ++++ gfx/cairo/cairo/src/cairo-win32.h 14 Apr 2007 09:05:25 -0000 +@@ -61,24 +61,27 @@ cairo_win32_surface_create_with_dib (cai + cairo_public HDC + cairo_win32_surface_get_dc (cairo_surface_t *surface); + + cairo_public cairo_surface_t * + cairo_win32_surface_get_image (cairo_surface_t *surface); + + cairo_public cairo_font_face_t * + cairo_win32_font_face_create_for_logfontw (LOGFONTW *logfont); + cairo_public cairo_font_face_t * cairo_win32_font_face_create_for_hfont (HFONT font); @@ -207,3 +307,12 @@ diff -r 1b568972e0a3 gfx/cairo/cairo/src/cairo-win32.h cairo_public cairo_status_t cairo_win32_scaled_font_select_font (cairo_scaled_font_t *scaled_font, HDC hdc); + + cairo_public void + cairo_win32_scaled_font_done_font (cairo_scaled_font_t *scaled_font); + + cairo_public double + cairo_win32_scaled_font_get_metrics_factor (cairo_scaled_font_t *scaled_font); + + cairo_public void + cairo_win32_scaled_font_get_logical_to_device (cairo_scaled_font_t *scaled_font,