зеркало из https://github.com/mozilla/pjs.git
backing out cairo update, again
This commit is contained in:
Родитель
eb55e7a193
Коммит
ae59053b45
|
@ -7,8 +7,7 @@ http://www.cairographics.org/.
|
|||
|
||||
VERSIONS:
|
||||
|
||||
cairo (1.5.x - c0a7d33ac6c81dd74ee2a9daaa3749a346ef4897)
|
||||
pixman (0.9.3 - 0c80a0cd84f30616563cef5910df9deb4f8ed687)
|
||||
cairo (1.4.2)
|
||||
glitz 0.5.2 (cvs - 2006-01-10)
|
||||
|
||||
***** NOTE FOR VISUAL C++ 6.0 *****
|
||||
|
@ -17,22 +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 obviously not be defined).
|
||||
All patches in the cairo tree are surrounded by "MOZILLA_CAIRO_NOT_DEFINED" (which should NOT be defined).
|
||||
|
||||
Some specific things:
|
||||
|
||||
max-font-size.patch: Clamp freetype font size to 1000 to avoid overflow issues
|
||||
|
||||
fbcompose-bandaid.patch: Disable "optimized" code in non-MMX case due to bugs
|
||||
|
||||
quartz-glyph-rounding.patch: Round glyph positions, not advances, to float
|
||||
|
||||
win32-scaled-font-size.patch: Add cairo_win32_font_face_create_for_logfontw_hfont,
|
||||
allow win32 scaled_fonts to rescale themselves properly to the required CTM
|
||||
and only use the font_face's hfont if we're sure it's appropriate
|
||||
|
||||
win32-logical-font-scale.patch: set CAIRO_WIN32_LOGICAL_FONT_SCALE to 1
|
||||
|
||||
win32-no-printer-bitblt.patch: If we need to BitBlt from a DC (to do
|
||||
fallback), only bother trying if the IS_DISPLAY flag is set -- many
|
||||
printers lie about their support for BitBlt, and we end up getting
|
||||
black instead of what we want.
|
||||
|
||||
nonfatal-assertions.patch: Make assertions non-fatal
|
||||
|
|
|
@ -81,7 +81,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 \
|
||||
|
@ -91,7 +91,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 \
|
||||
|
@ -166,8 +165,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
|
||||
|
||||
|
@ -198,7 +196,3 @@ DEFINES += -DPACKAGE_VERSION="\"moz\"" -DPACKAGE_BUGREPORT="\"http://bugzilla.mo
|
|||
ifeq ($(MOZ_WIDGET_TOOLKIT),windows)
|
||||
DEFINES += -DCAIRO_WIN32_STATIC_BUILD
|
||||
endif
|
||||
|
||||
ifdef MOZ_TREE_CAIRO
|
||||
DEFINES += -DMOZ_TREE_CAIRO
|
||||
endif
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
/*
|
||||
/* $Id: cairo-analysis-surface-private.h,v 1.10 2007-07-24 19:24:27 vladimir%pobox.com Exp $
|
||||
*
|
||||
* Copyright © 2005 Keith Packard
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
|
@ -42,10 +43,10 @@ _cairo_analysis_surface_create (cairo_surface_t *target,
|
|||
int width,
|
||||
int height);
|
||||
|
||||
cairo_private cairo_region_t *
|
||||
cairo_private pixman_region16_t *
|
||||
_cairo_analysis_surface_get_supported (cairo_surface_t *surface);
|
||||
|
||||
cairo_private cairo_region_t *
|
||||
cairo_private pixman_region16_t *
|
||||
_cairo_analysis_surface_get_unsupported (cairo_surface_t *unsupported);
|
||||
|
||||
cairo_private cairo_bool_t
|
||||
|
|
|
@ -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;
|
||||
|
@ -49,7 +49,7 @@ typedef struct {
|
|||
|
||||
static cairo_int_status_t
|
||||
_cairo_analysis_surface_get_extents (void *abstract_surface,
|
||||
cairo_rectangle_int_t *rectangle)
|
||||
cairo_rectangle_int16_t *rectangle)
|
||||
{
|
||||
cairo_analysis_surface_t *surface = abstract_surface;
|
||||
|
||||
|
@ -234,14 +234,14 @@ FAIL:
|
|||
return NULL;
|
||||
}
|
||||
|
||||
cairo_private cairo_region_t *
|
||||
cairo_private pixman_region16_t *
|
||||
_cairo_analysis_surface_get_supported (cairo_surface_t *abstract_surface)
|
||||
{
|
||||
/* XXX */
|
||||
return NULL;
|
||||
}
|
||||
|
||||
cairo_private cairo_region_t *
|
||||
cairo_private pixman_region16_t *
|
||||
_cairo_analysis_surface_get_unsupported (cairo_surface_t *abstract_surface)
|
||||
{
|
||||
/* XXX */
|
||||
|
|
|
@ -34,8 +34,6 @@
|
|||
* Carl D. Worth <cworth@cworth.org>
|
||||
*/
|
||||
|
||||
#include "cairoint.h"
|
||||
|
||||
#include "cairo-arc-private.h"
|
||||
|
||||
/* Spline deviation from the circle in radius would be given by:
|
||||
|
@ -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)
|
||||
|
|
|
@ -34,10 +34,11 @@
|
|||
* Calum Robinson <calumr@mac.com>
|
||||
*/
|
||||
|
||||
#include "cairoint.h"
|
||||
|
||||
#include "cairo.h"
|
||||
#include <stdlib.h>
|
||||
#include <math.h>
|
||||
#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 */
|
||||
{
|
||||
|
@ -809,7 +868,7 @@ _cairo_atsui_font_text_to_glyphs (void *abstract_font,
|
|||
|
||||
*num_glyphs = glyphCount - 1;
|
||||
*glyphs =
|
||||
(cairo_glyph_t *) _cairo_malloc_ab(*num_glyphs, sizeof (cairo_glyph_t));
|
||||
(cairo_glyph_t *) malloc(*num_glyphs * (sizeof (cairo_glyph_t)));
|
||||
if (*glyphs == NULL) {
|
||||
return CAIRO_STATUS_NO_MEMORY;
|
||||
}
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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 = _cairo_malloc_ab (num_events, sizeof (cairo_bo_event_t) + sizeof(cairo_bo_event_t*));
|
||||
if (events == NULL)
|
||||
events = malloc (num_events * sizeof(cairo_bo_event_t));
|
||||
sorted_event_ptrs = malloc (num_events * sizeof(cairo_bo_event_t*));
|
||||
if (!events || !sorted_event_ptrs) {
|
||||
if (events) free(events);
|
||||
if (sorted_event_ptrs) free(sorted_event_ptrs);
|
||||
return CAIRO_STATUS_NO_MEMORY;
|
||||
|
||||
sorted_event_ptrs = (cairo_bo_event_t **) (events + num_events);
|
||||
}
|
||||
event_queue->startstop_events = events;
|
||||
event_queue->sorted_startstop_event_ptrs = sorted_event_ptrs;
|
||||
event_queue->num_startstop_events = num_events;
|
||||
event_queue->num_startstop_events = (unsigned)(num_events);
|
||||
event_queue->next_startstop_event_index = 0;
|
||||
|
||||
for (i = 0; i < num_edges; i++) {
|
||||
|
@ -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 = _cairo_malloc_ab (polygon->num_edges, sizeof (cairo_bo_edge_t));
|
||||
if (edges == NULL)
|
||||
return CAIRO_STATUS_NO_MEMORY;
|
||||
}
|
||||
edges = malloc (polygon->num_edges * sizeof (cairo_bo_edge_t));
|
||||
if (edges == NULL)
|
||||
return CAIRO_STATUS_NO_MEMORY;
|
||||
|
||||
/* Figure out the bounding box of the input coordinates and
|
||||
* validate that we're not given invalid polygon edges. */
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -1757,7 +1732,7 @@ run_test (const char *test_name,
|
|||
while (intersections) {
|
||||
int num_edges = _cairo_array_num_elements (&intersected_edges);
|
||||
passes++;
|
||||
edges = _cairo_malloc_ab (num_edges, sizeof (cairo_bo_edge_t));
|
||||
edges = malloc (num_edges * sizeof (cairo_bo_edge_t));
|
||||
assert (edges != NULL);
|
||||
memcpy (edges, _cairo_array_index (&intersected_edges, 0), num_edges * sizeof (cairo_bo_edge_t));
|
||||
_cairo_array_fini (&intersected_edges);
|
||||
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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);
|
||||
|
|
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
|
@ -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;
|
||||
|
@ -63,7 +63,7 @@ struct _cairo_clip {
|
|||
* clip paths
|
||||
*/
|
||||
cairo_surface_t *surface;
|
||||
cairo_rectangle_int_t surface_rect;
|
||||
cairo_rectangle_int16_t surface_rect;
|
||||
/*
|
||||
* Surface clip serial number to store
|
||||
* in the surface when this clip is set
|
||||
|
@ -72,8 +72,7 @@ struct _cairo_clip {
|
|||
/*
|
||||
* A clip region that can be placed in the surface
|
||||
*/
|
||||
cairo_region_t region;
|
||||
cairo_bool_t has_region;
|
||||
pixman_region16_t *region;
|
||||
/*
|
||||
* If the surface supports path clipping, we store the list of
|
||||
* clipping paths that has been set here as a linked list.
|
||||
|
@ -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
|
||||
|
@ -105,11 +107,11 @@ _cairo_clip_clip (cairo_clip_t *clip,
|
|||
|
||||
cairo_private cairo_status_t
|
||||
_cairo_clip_intersect_to_rectangle (cairo_clip_t *clip,
|
||||
cairo_rectangle_int_t *rectangle);
|
||||
cairo_rectangle_int16_t *rectangle);
|
||||
|
||||
cairo_private cairo_status_t
|
||||
_cairo_clip_intersect_to_region (cairo_clip_t *clip,
|
||||
cairo_region_t *region);
|
||||
pixman_region16_t *region);
|
||||
|
||||
cairo_private cairo_status_t
|
||||
_cairo_clip_combine_to_surface (cairo_clip_t *clip,
|
||||
|
@ -117,7 +119,7 @@ _cairo_clip_combine_to_surface (cairo_clip_t *clip,
|
|||
cairo_surface_t *dst,
|
||||
int dst_x,
|
||||
int dst_y,
|
||||
const cairo_rectangle_int_t *extents);
|
||||
const cairo_rectangle_int16_t *extents);
|
||||
|
||||
cairo_private void
|
||||
_cairo_clip_translate (cairo_clip_t *clip,
|
||||
|
|
|
@ -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 © 2002 University of Southern California
|
||||
|
@ -62,13 +61,28 @@ _cairo_clip_init (cairo_clip_t *clip, cairo_surface_t *target)
|
|||
|
||||
clip->serial = 0;
|
||||
|
||||
_cairo_region_init (&clip->region);
|
||||
clip->has_region = FALSE;
|
||||
clip->region = NULL;
|
||||
|
||||
clip->path = NULL;
|
||||
}
|
||||
|
||||
cairo_status_t
|
||||
void
|
||||
_cairo_clip_fini (cairo_clip_t *clip)
|
||||
{
|
||||
cairo_surface_destroy (clip->surface);
|
||||
clip->surface = NULL;
|
||||
|
||||
clip->serial = 0;
|
||||
|
||||
if (clip->region)
|
||||
pixman_region_destroy (clip->region);
|
||||
clip->region = NULL;
|
||||
|
||||
_cairo_clip_path_destroy (clip->path);
|
||||
clip->path = NULL;
|
||||
}
|
||||
|
||||
void
|
||||
_cairo_clip_init_copy (cairo_clip_t *clip, cairo_clip_t *other)
|
||||
{
|
||||
clip->mode = other->mode;
|
||||
|
@ -78,27 +92,17 @@ _cairo_clip_init_copy (cairo_clip_t *clip, cairo_clip_t *other)
|
|||
|
||||
clip->serial = other->serial;
|
||||
|
||||
_cairo_region_init (&clip->region);
|
||||
|
||||
if (other->has_region) {
|
||||
if (_cairo_region_copy (&clip->region, &other->region) !=
|
||||
CAIRO_STATUS_SUCCESS)
|
||||
{
|
||||
_cairo_region_fini (&clip->region);
|
||||
cairo_surface_destroy (clip->surface);
|
||||
return CAIRO_STATUS_NO_MEMORY;
|
||||
}
|
||||
clip->has_region = TRUE;
|
||||
if (other->region == NULL) {
|
||||
clip->region = other->region;
|
||||
} else {
|
||||
clip->has_region = FALSE;
|
||||
clip->region = pixman_region_create ();
|
||||
pixman_region_copy (clip->region, other->region);
|
||||
}
|
||||
|
||||
clip->path = _cairo_clip_path_reference (other->path);
|
||||
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
void
|
||||
cairo_status_t
|
||||
_cairo_clip_reset (cairo_clip_t *clip)
|
||||
{
|
||||
/* destroy any existing clip-region artifacts */
|
||||
|
@ -107,29 +111,25 @@ _cairo_clip_reset (cairo_clip_t *clip)
|
|||
|
||||
clip->serial = 0;
|
||||
|
||||
if (clip->has_region) {
|
||||
/* _cairo_region_fini just releases the resources used but
|
||||
* doesn't bother with leaving the region in a valid state.
|
||||
* So _cairo_region_init has to be called afterwards. */
|
||||
_cairo_region_fini (&clip->region);
|
||||
_cairo_region_init (&clip->region);
|
||||
|
||||
clip->has_region = FALSE;
|
||||
}
|
||||
if (clip->region)
|
||||
pixman_region_destroy (clip->region);
|
||||
clip->region = NULL;
|
||||
|
||||
_cairo_clip_path_destroy (clip->path);
|
||||
clip->path = NULL;
|
||||
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
static cairo_status_t
|
||||
_cairo_clip_path_intersect_to_rectangle (cairo_clip_path_t *clip_path,
|
||||
cairo_rectangle_int_t *rectangle)
|
||||
cairo_rectangle_int16_t *rectangle)
|
||||
{
|
||||
while (clip_path) {
|
||||
cairo_status_t status;
|
||||
cairo_traps_t traps;
|
||||
cairo_box_t extents;
|
||||
cairo_rectangle_int_t extents_rect;
|
||||
cairo_rectangle_int16_t extents_rect;
|
||||
|
||||
_cairo_traps_init (&traps);
|
||||
|
||||
|
@ -156,7 +156,7 @@ _cairo_clip_path_intersect_to_rectangle (cairo_clip_path_t *clip_path,
|
|||
|
||||
cairo_status_t
|
||||
_cairo_clip_intersect_to_rectangle (cairo_clip_t *clip,
|
||||
cairo_rectangle_int_t *rectangle)
|
||||
cairo_rectangle_int16_t *rectangle)
|
||||
{
|
||||
if (!clip)
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
|
@ -170,22 +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;
|
||||
cairo_region_t intersection;
|
||||
pixman_region_status_t pixman_status;
|
||||
|
||||
_cairo_region_init_rect (&intersection, rectangle);
|
||||
intersection = _cairo_region_create_from_rectangle (rectangle);
|
||||
if (intersection == NULL)
|
||||
return CAIRO_STATUS_NO_MEMORY;
|
||||
|
||||
status = _cairo_region_intersect (&intersection, &clip->region,
|
||||
&intersection);
|
||||
pixman_status = pixman_region_intersect (intersection,
|
||||
clip->region,
|
||||
intersection);
|
||||
if (pixman_status == PIXMAN_REGION_STATUS_SUCCESS)
|
||||
_cairo_region_extents_rectangle (intersection, rectangle);
|
||||
else
|
||||
status = CAIRO_STATUS_NO_MEMORY;
|
||||
|
||||
if (!status)
|
||||
_cairo_region_get_extents (&intersection, rectangle);
|
||||
pixman_region_destroy (intersection);
|
||||
|
||||
_cairo_region_fini (&intersection);
|
||||
|
||||
if (status)
|
||||
return status;
|
||||
if (status)
|
||||
return status;
|
||||
}
|
||||
|
||||
if (clip->surface)
|
||||
|
@ -196,10 +201,8 @@ _cairo_clip_intersect_to_rectangle (cairo_clip_t *clip,
|
|||
|
||||
cairo_status_t
|
||||
_cairo_clip_intersect_to_region (cairo_clip_t *clip,
|
||||
cairo_region_t *region)
|
||||
pixman_region16_t *region)
|
||||
{
|
||||
cairo_status_t status;
|
||||
|
||||
if (!clip)
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
|
||||
|
@ -207,23 +210,28 @@ _cairo_clip_intersect_to_region (cairo_clip_t *clip,
|
|||
/* Intersect clip path into region. */
|
||||
}
|
||||
|
||||
if (clip->has_region) {
|
||||
status = _cairo_region_intersect (region, &clip->region, region);
|
||||
if (status)
|
||||
return status;
|
||||
}
|
||||
if (clip->region)
|
||||
pixman_region_intersect (region, clip->region, region);
|
||||
|
||||
if (clip->surface) {
|
||||
cairo_region_t clip_rect;
|
||||
pixman_region16_t *clip_rect;
|
||||
pixman_region_status_t pixman_status;
|
||||
cairo_status_t status = CAIRO_STATUS_SUCCESS;
|
||||
|
||||
_cairo_region_init_rect (&clip_rect, &clip->surface_rect);
|
||||
clip_rect = _cairo_region_create_from_rectangle (&clip->surface_rect);
|
||||
if (clip_rect == NULL)
|
||||
return CAIRO_STATUS_NO_MEMORY;
|
||||
|
||||
status = _cairo_region_intersect (region, &clip_rect, region);
|
||||
pixman_status = pixman_region_intersect (region,
|
||||
clip_rect,
|
||||
region);
|
||||
if (pixman_status != PIXMAN_REGION_STATUS_SUCCESS)
|
||||
status = CAIRO_STATUS_NO_MEMORY;
|
||||
|
||||
_cairo_region_fini (&clip_rect);
|
||||
pixman_region_destroy (clip_rect);
|
||||
|
||||
if (status)
|
||||
return status;
|
||||
if (status)
|
||||
return status;
|
||||
}
|
||||
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
|
@ -239,7 +247,7 @@ _cairo_clip_combine_to_surface (cairo_clip_t *clip,
|
|||
cairo_surface_t *dst,
|
||||
int dst_x,
|
||||
int dst_y,
|
||||
const cairo_rectangle_int_t *extents)
|
||||
const cairo_rectangle_int16_t *extents)
|
||||
{
|
||||
cairo_pattern_union_t pattern;
|
||||
cairo_status_t status;
|
||||
|
@ -321,44 +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)
|
||||
{
|
||||
cairo_region_t region;
|
||||
cairo_int_status_t status;
|
||||
pixman_region16_t *region;
|
||||
cairo_status_t status;
|
||||
|
||||
if (clip->mode != CAIRO_CLIP_MODE_REGION)
|
||||
return CAIRO_INT_STATUS_UNSUPPORTED;
|
||||
|
||||
status = _cairo_traps_extract_region (traps, ®ion);
|
||||
|
||||
if (status)
|
||||
return status;
|
||||
|
||||
if (region == NULL)
|
||||
return CAIRO_INT_STATUS_UNSUPPORTED;
|
||||
|
||||
status = CAIRO_STATUS_SUCCESS;
|
||||
|
||||
if (!clip->has_region) {
|
||||
status = _cairo_region_copy (&clip->region, ®ion);
|
||||
if (status == CAIRO_STATUS_SUCCESS)
|
||||
clip->has_region = TRUE;
|
||||
if (clip->region == NULL) {
|
||||
clip->region = region;
|
||||
} else {
|
||||
cairo_region_t intersection;
|
||||
_cairo_region_init (&intersection);
|
||||
pixman_region16_t *intersection = pixman_region_create();
|
||||
|
||||
status = _cairo_region_intersect (&intersection,
|
||||
&clip->region,
|
||||
®ion);
|
||||
|
||||
if (status == CAIRO_STATUS_SUCCESS)
|
||||
status = _cairo_region_copy (&clip->region, &intersection);
|
||||
|
||||
_cairo_region_fini (&intersection);
|
||||
if (pixman_region_intersect (intersection,
|
||||
clip->region, region)
|
||||
== PIXMAN_REGION_STATUS_SUCCESS) {
|
||||
pixman_region_destroy (clip->region);
|
||||
clip->region = intersection;
|
||||
} else {
|
||||
status = CAIRO_STATUS_NO_MEMORY;
|
||||
}
|
||||
pixman_region_destroy (region);
|
||||
}
|
||||
|
||||
clip->serial = _cairo_surface_allocate_clip_serial (target);
|
||||
_cairo_region_fini (®ion);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
@ -371,7 +377,7 @@ _cairo_clip_intersect_mask (cairo_clip_t *clip,
|
|||
{
|
||||
cairo_pattern_union_t pattern;
|
||||
cairo_box_t extents;
|
||||
cairo_rectangle_int_t surface_rect, target_rect;
|
||||
cairo_rectangle_int16_t surface_rect, target_rect;
|
||||
cairo_surface_t *surface;
|
||||
cairo_status_t status;
|
||||
|
||||
|
@ -396,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,
|
||||
|
@ -505,8 +509,8 @@ _cairo_clip_translate (cairo_clip_t *clip,
|
|||
cairo_fixed_t tx,
|
||||
cairo_fixed_t ty)
|
||||
{
|
||||
if (clip->has_region) {
|
||||
_cairo_region_translate (&clip->region,
|
||||
if (clip->region) {
|
||||
pixman_region_translate (clip->region,
|
||||
_cairo_fixed_integer_part (tx),
|
||||
_cairo_fixed_integer_part (ty));
|
||||
}
|
||||
|
@ -545,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)
|
||||
|
@ -556,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 (_cairo_region_copy (&clip->region, &other->region) !=
|
||||
CAIRO_STATUS_SUCCESS)
|
||||
goto BAIL;
|
||||
clip->has_region = TRUE;
|
||||
if (other->region) {
|
||||
clip->region = pixman_region_create ();
|
||||
pixman_region_copy (clip->region, other->region);
|
||||
}
|
||||
|
||||
if (other->surface) {
|
||||
if (_cairo_surface_clone_similar (target, other->surface,
|
||||
_cairo_surface_clone_similar (target, other->surface,
|
||||
other->surface_rect.x,
|
||||
other->surface_rect.y,
|
||||
other->surface_rect.width,
|
||||
other->surface_rect.height,
|
||||
&clip->surface) !=
|
||||
CAIRO_STATUS_SUCCESS)
|
||||
goto BAIL;
|
||||
&clip->surface);
|
||||
clip->surface_rect = other->surface_rect;
|
||||
}
|
||||
|
||||
|
@ -579,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)
|
||||
_cairo_region_fini (&clip->region);
|
||||
if (clip->surface)
|
||||
cairo_surface_destroy (clip->surface);
|
||||
|
||||
return CAIRO_STATUS_NO_MEMORY;
|
||||
}
|
||||
|
||||
const cairo_rectangle_list_t _cairo_rectangles_nil =
|
||||
|
@ -597,24 +587,19 @@ static const cairo_rectangle_list_t _cairo_rectangles_not_representable =
|
|||
{ CAIRO_STATUS_CLIP_NOT_REPRESENTABLE, NULL, 0 };
|
||||
|
||||
static cairo_bool_t
|
||||
_cairo_clip_int_rect_to_user (cairo_gstate_t *gstate,
|
||||
cairo_rectangle_int_t *clip_rect,
|
||||
cairo_rectangle_t *user_rect)
|
||||
_cairo_clip_rect_to_user (cairo_gstate_t *gstate,
|
||||
double x, double y, double width, double height,
|
||||
cairo_rectangle_t *rectangle)
|
||||
{
|
||||
double x2 = x + width;
|
||||
double y2 = y + height;
|
||||
cairo_bool_t is_tight;
|
||||
|
||||
double x1 = clip_rect->x;
|
||||
double y1 = clip_rect->y;
|
||||
double x2 = clip_rect->x + clip_rect->width;
|
||||
double y2 = clip_rect->y + clip_rect->height;
|
||||
|
||||
_cairo_gstate_backend_to_user_rectangle (gstate, &x1, &y1, &x2, &y2, &is_tight);
|
||||
|
||||
user_rect->x = x1;
|
||||
user_rect->y = y1;
|
||||
user_rect->width = x2 - x1;
|
||||
user_rect->height = y2 - y1;
|
||||
|
||||
_cairo_gstate_backend_to_user_rectangle (gstate, &x, &y, &x2, &y2, &is_tight);
|
||||
rectangle->x = x;
|
||||
rectangle->y = y;
|
||||
rectangle->width = x2 - x;
|
||||
rectangle->height = y2 - y;
|
||||
return is_tight;
|
||||
}
|
||||
|
||||
|
@ -622,51 +607,42 @@ cairo_private cairo_rectangle_list_t*
|
|||
_cairo_clip_copy_rectangle_list (cairo_clip_t *clip, cairo_gstate_t *gstate)
|
||||
{
|
||||
cairo_rectangle_list_t *list;
|
||||
cairo_rectangle_t *rectangles = NULL;
|
||||
cairo_rectangle_t *rectangles;
|
||||
int n_boxes;
|
||||
|
||||
if (clip->path || clip->surface)
|
||||
return (cairo_rectangle_list_t*) &_cairo_rectangles_not_representable;
|
||||
return (cairo_rectangle_list_t*) &_cairo_rectangles_not_representable;
|
||||
|
||||
if (clip->has_region) {
|
||||
cairo_box_int_t *boxes;
|
||||
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->region) {
|
||||
pixman_box16_t *boxes;
|
||||
int i;
|
||||
|
||||
if (_cairo_region_get_boxes (&clip->region, &n_boxes, &boxes) != CAIRO_STATUS_SUCCESS)
|
||||
return (cairo_rectangle_list_t*) &_cairo_rectangles_nil;
|
||||
|
||||
rectangles = _cairo_malloc_ab (n_boxes, sizeof (cairo_rectangle_t));
|
||||
if (rectangles == NULL) {
|
||||
_cairo_region_boxes_fini (&clip->region, boxes);
|
||||
return (cairo_rectangle_list_t*) &_cairo_rectangles_nil;
|
||||
}
|
||||
|
||||
|
||||
boxes = pixman_region_rects (clip->region);
|
||||
for (i = 0; i < n_boxes; ++i) {
|
||||
cairo_rectangle_int_t clip_rect = { boxes[i].p1.x, boxes[i].p1.y,
|
||||
boxes[i].p2.x - boxes[i].p1.x,
|
||||
boxes[i].p2.y - boxes[i].p1.y };
|
||||
|
||||
if (!_cairo_clip_int_rect_to_user(gstate, &clip_rect, &rectangles[i])) {
|
||||
_cairo_region_boxes_fini (&clip->region, boxes);
|
||||
free (rectangles);
|
||||
return (cairo_rectangle_list_t*) &_cairo_rectangles_not_representable;
|
||||
}
|
||||
if (!_cairo_clip_rect_to_user(gstate, boxes[i].x1, boxes[i].y1,
|
||||
boxes[i].x2 - boxes[i].x1,
|
||||
boxes[i].y2 - boxes[i].y1,
|
||||
&rectangles[i])) {
|
||||
free (rectangles);
|
||||
return (cairo_rectangle_list_t*)
|
||||
&_cairo_rectangles_not_representable;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
cairo_rectangle_int_t extents;
|
||||
|
||||
n_boxes = 1;
|
||||
|
||||
rectangles = malloc(sizeof (cairo_rectangle_t));
|
||||
if (rectangles == NULL)
|
||||
return (cairo_rectangle_list_t*) &_cairo_rectangles_nil;
|
||||
|
||||
if (_cairo_surface_get_extents (_cairo_gstate_get_target (gstate), &extents) ||
|
||||
!_cairo_clip_int_rect_to_user(gstate, &extents, rectangles))
|
||||
{
|
||||
free (rectangles);
|
||||
return (cairo_rectangle_list_t*) &_cairo_rectangles_not_representable;
|
||||
}
|
||||
cairo_rectangle_int16_t extents;
|
||||
_cairo_surface_get_extents (_cairo_gstate_get_target (gstate), &extents);
|
||||
if (!_cairo_clip_rect_to_user(gstate, extents.x, extents.y,
|
||||
extents.width, extents.height,
|
||||
rectangles)) {
|
||||
free (rectangles);
|
||||
return (cairo_rectangle_list_t*)
|
||||
&_cairo_rectangles_not_representable;
|
||||
}
|
||||
}
|
||||
|
||||
list = malloc (sizeof (cairo_rectangle_list_t));
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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 ();
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -35,9 +35,10 @@
|
|||
* Claudio Ciccani <klan@users.sf.net>
|
||||
*/
|
||||
|
||||
#include "cairoint.h"
|
||||
|
||||
#include "cairo-directfb.h"
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <math.h>
|
||||
#include <assert.h>
|
||||
|
||||
#include <directfb.h>
|
||||
|
||||
|
@ -46,6 +47,9 @@
|
|||
#include <direct/memcpy.h>
|
||||
#include <direct/util.h>
|
||||
|
||||
#include "cairo-directfb.h"
|
||||
#include "cairoint.h"
|
||||
|
||||
|
||||
/*
|
||||
* Rectangle causes problems (see bugs 361377, 359553, 359243 in Gnome BTS).
|
||||
|
@ -320,9 +324,9 @@ _directfb_buffer_surface_create (IDirectFB *dfb,
|
|||
|
||||
static cairo_status_t
|
||||
_directfb_acquire_surface (cairo_directfb_surface_t *surface,
|
||||
cairo_rectangle_int_t *intrest_rec,
|
||||
cairo_rectangle_int16_t *intrest_rec,
|
||||
cairo_image_surface_t **image_out,
|
||||
cairo_rectangle_int_t *image_rect_out,
|
||||
cairo_rectangle_int16_t *image_rect_out,
|
||||
void **image_extra,
|
||||
DFBSurfaceLockFlags lock_flags)
|
||||
{
|
||||
|
@ -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;
|
||||
|
@ -499,9 +503,9 @@ _cairo_directfb_surface_release_source_image (void *abstract_su
|
|||
|
||||
static cairo_status_t
|
||||
_cairo_directfb_surface_acquire_dest_image (void *abstract_surface,
|
||||
cairo_rectangle_int_t *interest_rect,
|
||||
cairo_rectangle_int16_t *interest_rect,
|
||||
cairo_image_surface_t **image_out,
|
||||
cairo_rectangle_int_t *image_rect_out,
|
||||
cairo_rectangle_int16_t *image_rect_out,
|
||||
void **image_extra)
|
||||
{
|
||||
cairo_directfb_surface_t *surface = abstract_surface;
|
||||
|
@ -515,9 +519,9 @@ _cairo_directfb_surface_acquire_dest_image (void *abstract_sur
|
|||
|
||||
static void
|
||||
_cairo_directfb_surface_release_dest_image (void *abstract_surface,
|
||||
cairo_rectangle_int_t *interest_rect,
|
||||
cairo_rectangle_int16_t *interest_rect,
|
||||
cairo_image_surface_t *image,
|
||||
cairo_rectangle_int_t *image_rect,
|
||||
cairo_rectangle_int16_t *image_rect,
|
||||
void *image_extra)
|
||||
{
|
||||
cairo_directfb_surface_t *surface = abstract_surface;
|
||||
|
@ -911,7 +915,7 @@ static cairo_int_status_t
|
|||
_cairo_directfb_surface_fill_rectangles (void *abstract_surface,
|
||||
cairo_operator_t op,
|
||||
const cairo_color_t *color,
|
||||
cairo_rectangle_int_t *rects,
|
||||
cairo_rectangle_int16_t *rects,
|
||||
int n_rects)
|
||||
{
|
||||
cairo_directfb_surface_t *dst = abstract_surface;
|
||||
|
@ -1095,8 +1099,8 @@ _cairo_directfb_surface_composite_trapezoids (cairo_operator_t op,
|
|||
#endif /* DFB_COMPOSITE_TRAPEZOIDS */
|
||||
|
||||
static cairo_int_status_t
|
||||
_cairo_directfb_surface_set_clip_region (void *abstract_surface,
|
||||
cairo_region_t *region)
|
||||
_cairo_directfb_surface_set_clip_region (void *abstract_surface,
|
||||
pixman_region16_t *region)
|
||||
{
|
||||
cairo_directfb_surface_t *surface = abstract_surface;
|
||||
|
||||
|
@ -1105,19 +1109,16 @@ _cairo_directfb_surface_set_clip_region (void *abstract_surface,
|
|||
__FUNCTION__, surface, region);
|
||||
|
||||
if (region) {
|
||||
cairo_box_int_t *boxes;
|
||||
int n_boxes, i;
|
||||
|
||||
if (_cairo_region_get_boxes (region, &n_boxes, &boxes) != CAIRO_STATUS_SUCCESS)
|
||||
return CAIRO_STATUS_NO_MEMORY;
|
||||
|
||||
pixman_box16_t *boxes = pixman_region_rects (region);
|
||||
int n_boxes = pixman_region_num_rects (region);
|
||||
int i;
|
||||
|
||||
if (surface->n_clips != n_boxes) {
|
||||
if( surface->clips )
|
||||
free (surface->clips);
|
||||
|
||||
surface->clips = _cairo_malloc_ab (n_boxes, sizeof(DFBRegion));
|
||||
surface->clips = malloc (n_boxes * sizeof(DFBRegion));
|
||||
if (!surface->clips) {
|
||||
_cairo_region_boxes_fini (region, boxes);
|
||||
surface->n_clips = 0;
|
||||
return CAIRO_STATUS_NO_MEMORY;
|
||||
}
|
||||
|
@ -1126,13 +1127,11 @@ _cairo_directfb_surface_set_clip_region (void *abstract_surface,
|
|||
}
|
||||
|
||||
for (i = 0; i < n_boxes; i++) {
|
||||
surface->clips[i].x1 = boxes[i].p1.x;
|
||||
surface->clips[i].y1 = boxes[i].p1.y;
|
||||
surface->clips[i].x2 = boxes[i].p2.x;
|
||||
surface->clips[i].y2 = boxes[i].p2.y;
|
||||
surface->clips[i].x1 = boxes[i].x1;
|
||||
surface->clips[i].y1 = boxes[i].y1;
|
||||
surface->clips[i].x2 = boxes[i].x2;
|
||||
surface->clips[i].y2 = boxes[i].y2;
|
||||
}
|
||||
|
||||
_cairo_region_boxes_fini (region, boxes);
|
||||
}
|
||||
else {
|
||||
if (surface->clips) {
|
||||
|
@ -1147,7 +1146,7 @@ _cairo_directfb_surface_set_clip_region (void *abstract_surface,
|
|||
|
||||
static cairo_int_status_t
|
||||
_cairo_directfb_abstract_surface_get_extents (void *abstract_surface,
|
||||
cairo_rectangle_int_t *rectangle)
|
||||
cairo_rectangle_int16_t *rectangle)
|
||||
{
|
||||
cairo_directfb_surface_t *surface = abstract_surface;
|
||||
|
||||
|
@ -1516,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*/
|
||||
|
@ -1576,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 */
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -41,8 +41,6 @@
|
|||
|
||||
#ifdef CAIRO_HAS_DIRECTFB_SURFACE
|
||||
|
||||
#include <directfb.h>
|
||||
|
||||
CAIRO_BEGIN_DECLS
|
||||
|
||||
cairo_public cairo_surface_t *
|
||||
|
|
|
@ -52,10 +52,10 @@
|
|||
#endif
|
||||
|
||||
#define CAIRO_VERSION_MAJOR 1
|
||||
#define CAIRO_VERSION_MINOR 5
|
||||
#define CAIRO_VERSION_MICRO 1
|
||||
#define CAIRO_VERSION_MINOR 4
|
||||
#define CAIRO_VERSION_MICRO 2
|
||||
|
||||
#define CAIRO_VERSION_STRING "1.5.1"
|
||||
#define CAIRO_VERSION_STRING "1.4.2"
|
||||
|
||||
@PS_SURFACE_FEATURE@
|
||||
|
||||
|
@ -65,8 +65,6 @@
|
|||
|
||||
@XLIB_SURFACE_FEATURE@
|
||||
|
||||
@XLIB_XRENDER_SURFACE_FEATURE@
|
||||
|
||||
@QUARTZ_SURFACE_FEATURE@
|
||||
|
||||
@XCB_SURFACE_FEATURE@
|
||||
|
|
|
@ -36,4 +36,102 @@
|
|||
|
||||
#include "cairoint.h"
|
||||
|
||||
#include "cairo-fixed-private.h"
|
||||
cairo_fixed_t
|
||||
_cairo_fixed_from_int (int i)
|
||||
{
|
||||
return i << 16;
|
||||
}
|
||||
|
||||
/* This is the "magic number" approach to converting a double into fixed
|
||||
* point as described here:
|
||||
*
|
||||
* http://www.stereopsis.com/sree/fpu2006.html (an overview)
|
||||
* http://www.d6.com/users/checker/pdfs/gdmfp.pdf (in detail)
|
||||
*
|
||||
* The basic idea is to add a large enough number to the double that the
|
||||
* literal floating point is moved up to the extent that it forces the
|
||||
* double's value to be shifted down to the bottom of the mantissa (to make
|
||||
* room for the large number being added in). Since the mantissa is, at a
|
||||
* given moment in time, a fixed point integer itself, one can convert a
|
||||
* float to various fixed point representations by moving around the point
|
||||
* of a floating point number through arithmetic operations. This behavior
|
||||
* is reliable on most modern platforms as it is mandated by the IEEE-754
|
||||
* standard for floating point arithmetic.
|
||||
*
|
||||
* For our purposes, a "magic number" must be carefully selected that is
|
||||
* both large enough to produce the desired point-shifting effect, and also
|
||||
* has no lower bits in its representation that would interfere with our
|
||||
* value at the bottom of the mantissa. The magic number is calculated as
|
||||
* follows:
|
||||
*
|
||||
* (2 ^ (MANTISSA_SIZE - FRACTIONAL_SIZE)) * 1.5
|
||||
*
|
||||
* where in our case:
|
||||
* - MANTISSA_SIZE for 64-bit doubles is 52
|
||||
* - FRACTIONAL_SIZE for 16.16 fixed point is 16
|
||||
*
|
||||
* Although this approach provides a very large speedup of this function
|
||||
* on a wide-array of systems, it does come with two caveats:
|
||||
*
|
||||
* 1) It uses banker's rounding as opposed to arithmetic rounding.
|
||||
* 2) It doesn't function properly if the FPU is in single-precision
|
||||
* mode.
|
||||
*/
|
||||
#define CAIRO_MAGIC_NUMBER_FIXED_16_16 (103079215104.0)
|
||||
cairo_fixed_t
|
||||
_cairo_fixed_from_double (double d)
|
||||
{
|
||||
union {
|
||||
double d;
|
||||
int32_t i[2];
|
||||
} u;
|
||||
|
||||
u.d = d + CAIRO_MAGIC_NUMBER_FIXED_16_16;
|
||||
#ifdef FLOAT_WORDS_BIGENDIAN
|
||||
return u.i[1];
|
||||
#else
|
||||
return u.i[0];
|
||||
#endif
|
||||
}
|
||||
|
||||
cairo_fixed_t
|
||||
_cairo_fixed_from_26_6 (uint32_t i)
|
||||
{
|
||||
return i << 10;
|
||||
}
|
||||
|
||||
double
|
||||
_cairo_fixed_to_double (cairo_fixed_t f)
|
||||
{
|
||||
return ((double) f) / 65536.0;
|
||||
}
|
||||
|
||||
int
|
||||
_cairo_fixed_is_integer (cairo_fixed_t f)
|
||||
{
|
||||
return (f & 0xFFFF) == 0;
|
||||
}
|
||||
|
||||
int
|
||||
_cairo_fixed_integer_part (cairo_fixed_t f)
|
||||
{
|
||||
return f >> 16;
|
||||
}
|
||||
|
||||
int
|
||||
_cairo_fixed_integer_floor (cairo_fixed_t f)
|
||||
{
|
||||
if (f >= 0)
|
||||
return f >> 16;
|
||||
else
|
||||
return -((-f - 1) >> 16) - 1;
|
||||
}
|
||||
|
||||
int
|
||||
_cairo_fixed_integer_ceil (cairo_fixed_t f)
|
||||
{
|
||||
if (f > 0)
|
||||
return ((f - 1)>>16) + 1;
|
||||
else
|
||||
return - (-f >> 16);
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -26,6 +26,8 @@
|
|||
#include <stddef.h>
|
||||
|
||||
/* Opaque implementation types. */
|
||||
struct _cairo_freelist;
|
||||
struct _cairo_freelist_node;
|
||||
typedef struct _cairo_freelist cairo_freelist_t;
|
||||
typedef struct _cairo_freelist_node cairo_freelist_node_t;
|
||||
|
||||
|
|
|
@ -19,9 +19,8 @@
|
|||
* TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
|
||||
* OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "cairoint.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include "cairo-freelist-private.h"
|
||||
|
||||
void
|
||||
|
|
|
@ -37,12 +37,10 @@
|
|||
* Carl Worth <cworth@cworth.org>
|
||||
*/
|
||||
|
||||
#include "cairoint.h"
|
||||
#include <float.h>
|
||||
|
||||
#include "cairo-ft-private.h"
|
||||
|
||||
#include <float.h>
|
||||
|
||||
#include <fontconfig/fontconfig.h>
|
||||
#include <fontconfig/fcfreetype.h>
|
||||
|
||||
|
@ -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
|
||||
|
@ -755,11 +752,9 @@ _get_bitmap_surface (FT_Bitmap *bitmap,
|
|||
data = bitmap->buffer;
|
||||
assert (stride == bitmap->pitch);
|
||||
} else {
|
||||
data = _cairo_malloc_ab (height, stride);
|
||||
if (!data) {
|
||||
_cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
data = malloc (stride * height);
|
||||
if (!data)
|
||||
return CAIRO_STATUS_NO_MEMORY;
|
||||
}
|
||||
|
||||
if (stride == bitmap->pitch) {
|
||||
memcpy (data, bitmap->buffer, stride * height);
|
||||
|
@ -805,11 +800,9 @@ _get_bitmap_surface (FT_Bitmap *bitmap,
|
|||
if (own_buffer) {
|
||||
data = bitmap->buffer;
|
||||
} else {
|
||||
data = _cairo_malloc_ab (height, stride);
|
||||
if (!data) {
|
||||
_cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
data = malloc (stride * height);
|
||||
if (!data)
|
||||
return CAIRO_STATUS_NO_MEMORY;
|
||||
}
|
||||
memcpy (data, bitmap->buffer, stride * height);
|
||||
}
|
||||
format = CAIRO_FORMAT_A8;
|
||||
|
@ -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
|
||||
|
|
|
@ -33,8 +33,7 @@ typedef struct _cairo_glitz_surface {
|
|||
|
||||
glitz_surface_t *surface;
|
||||
glitz_format_t *format;
|
||||
cairo_bool_t has_clip;
|
||||
cairo_region_t clip;
|
||||
pixman_region16_t *clip;
|
||||
} cairo_glitz_surface_t;
|
||||
|
||||
static const cairo_surface_backend_t *
|
||||
|
@ -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);
|
||||
_cairo_region_fini (&surface->clip);
|
||||
if (surface->clip)
|
||||
{
|
||||
glitz_surface_set_clip_region (surface->surface, 0, 0, NULL, 0);
|
||||
pixman_region_destroy (surface->clip);
|
||||
}
|
||||
|
||||
glitz_surface_destroy (surface->surface);
|
||||
|
@ -110,90 +110,19 @@ _cairo_glitz_surface_create_similar (void *abstract_src,
|
|||
return crsurface;
|
||||
}
|
||||
|
||||
static cairo_bool_t
|
||||
_CAIRO_MASK_FORMAT (cairo_format_masks_t *masks, cairo_format_t *format)
|
||||
{
|
||||
switch (masks->bpp) {
|
||||
case 32:
|
||||
if (masks->alpha_mask == 0xff000000 &&
|
||||
masks->red_mask == 0x00ff0000 &&
|
||||
masks->green_mask == 0x0000ff00 &&
|
||||
masks->blue_mask == 0x000000ff)
|
||||
{
|
||||
*format = CAIRO_FORMAT_ARGB32;
|
||||
return TRUE;
|
||||
}
|
||||
if (masks->alpha_mask == 0x00000000 &&
|
||||
masks->red_mask == 0x00ff0000 &&
|
||||
masks->green_mask == 0x0000ff00 &&
|
||||
masks->blue_mask == 0x000000ff)
|
||||
{
|
||||
*format = CAIRO_FORMAT_RGB24;
|
||||
return TRUE;
|
||||
}
|
||||
break;
|
||||
case 8:
|
||||
if (masks->alpha_mask == 0xff)
|
||||
{
|
||||
*format = CAIRO_FORMAT_A8;
|
||||
return TRUE;
|
||||
}
|
||||
break;
|
||||
case 1:
|
||||
if (masks->alpha_mask == 0x1)
|
||||
{
|
||||
*format = CAIRO_FORMAT_A1;
|
||||
return TRUE;
|
||||
}
|
||||
break;
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static glitz_box_t *
|
||||
_cairo_glitz_get_boxes_from_region (cairo_region_t *region, int *nboxes)
|
||||
{
|
||||
cairo_box_int_t *cboxes;
|
||||
glitz_box_t *gboxes;
|
||||
int n, i;
|
||||
|
||||
if (_cairo_region_get_boxes (&surface->clip, &n, &cboxes) != CAIRO_STATUS_SUCCESS)
|
||||
return NULL;
|
||||
|
||||
*nboxes = n;
|
||||
if (n == 0)
|
||||
return NULL;
|
||||
|
||||
gboxes = _cairo_malloc_ab (n, sizeof(glitz_box_t));
|
||||
if (gboxes == NULL)
|
||||
goto done;
|
||||
|
||||
for (i = 0; i < n; i++) {
|
||||
gboxes[i].x1 = cboxes[i].p1.x;
|
||||
gboxes[i].y1 = cboxes[i].p1.y;
|
||||
gboxes[i].x2 = cboxes[i].p2.x;
|
||||
gboxes[i].y2 = cboxes[i].p2.y;
|
||||
}
|
||||
|
||||
done:
|
||||
_cairo_region_boxes_fini (&sruface->clip, &cboxes);
|
||||
return gboxes;
|
||||
}
|
||||
|
||||
static cairo_status_t
|
||||
_cairo_glitz_surface_get_image (cairo_glitz_surface_t *surface,
|
||||
cairo_rectangle_int_t *interest,
|
||||
cairo_rectangle_int16_t *interest,
|
||||
cairo_image_surface_t **image_out,
|
||||
cairo_rectangle_int_t *rect_out)
|
||||
cairo_rectangle_int16_t *rect_out)
|
||||
{
|
||||
cairo_image_surface_t *image;
|
||||
int x1, y1, x2, y2;
|
||||
int width, height;
|
||||
unsigned char *pixels;
|
||||
cairo_format_masks_t masks;
|
||||
cairo_format_masks_t format;
|
||||
glitz_buffer_t *buffer;
|
||||
glitz_pixel_format_t pf;
|
||||
cairo_format_t format;
|
||||
|
||||
x1 = 0;
|
||||
y1 = 0;
|
||||
|
@ -231,44 +160,44 @@ _cairo_glitz_surface_get_image (cairo_glitz_surface_t *surface,
|
|||
|
||||
if (surface->format->color.fourcc == GLITZ_FOURCC_RGB) {
|
||||
if (surface->format->color.red_size > 0) {
|
||||
masks.bpp = 32;
|
||||
format.bpp = 32;
|
||||
|
||||
if (surface->format->color.alpha_size > 0)
|
||||
masks.alpha_mask = 0xff000000;
|
||||
format.alpha_mask = 0xff000000;
|
||||
else
|
||||
masks.alpha_mask = 0x0;
|
||||
format.alpha_mask = 0x0;
|
||||
|
||||
masks.red_mask = 0xff0000;
|
||||
masks.green_mask = 0xff00;
|
||||
masks.blue_mask = 0xff;
|
||||
format.red_mask = 0xff0000;
|
||||
format.green_mask = 0xff00;
|
||||
format.blue_mask = 0xff;
|
||||
} else {
|
||||
masks.bpp = 8;
|
||||
masks.blue_mask = masks.green_mask = masks.red_mask = 0x0;
|
||||
masks.alpha_mask = 0xff;
|
||||
format.bpp = 8;
|
||||
format.blue_mask = format.green_mask = format.red_mask = 0x0;
|
||||
format.alpha_mask = 0xff;
|
||||
}
|
||||
} else {
|
||||
masks.bpp = 32;
|
||||
masks.alpha_mask = 0xff000000;
|
||||
masks.red_mask = 0xff0000;
|
||||
masks.green_mask = 0xff00;
|
||||
masks.blue_mask = 0xff;
|
||||
format.bpp = 32;
|
||||
format.alpha_mask = 0xff000000;
|
||||
format.red_mask = 0xff0000;
|
||||
format.green_mask = 0xff00;
|
||||
format.blue_mask = 0xff;
|
||||
}
|
||||
|
||||
pf.fourcc = GLITZ_FOURCC_RGB;
|
||||
pf.masks.bpp = masks.bpp;
|
||||
pf.masks.alpha_mask = masks.alpha_mask;
|
||||
pf.masks.red_mask = masks.red_mask;
|
||||
pf.masks.green_mask = masks.green_mask;
|
||||
pf.masks.blue_mask = masks.blue_mask;
|
||||
pf.masks.bpp = format.bpp;
|
||||
pf.masks.alpha_mask = format.alpha_mask;
|
||||
pf.masks.red_mask = format.red_mask;
|
||||
pf.masks.green_mask = format.green_mask;
|
||||
pf.masks.blue_mask = format.blue_mask;
|
||||
pf.xoffset = 0;
|
||||
pf.skip_lines = 0;
|
||||
|
||||
/* XXX: we should eventually return images with negative stride,
|
||||
need to verify that libpixman have no problem with this first. */
|
||||
pf.bytes_per_line = (((width * masks.bpp) / 8) + 3) & -4;
|
||||
pf.bytes_per_line = (((width * format.bpp) / 8) + 3) & -4;
|
||||
pf.scanline_order = GLITZ_PIXEL_SCANLINE_ORDER_TOP_DOWN;
|
||||
|
||||
pixels = _cairo_malloc_ab (height, pf.bytes_per_line);
|
||||
pixels = malloc (height * pf.bytes_per_line);
|
||||
if (!pixels)
|
||||
return CAIRO_STATUS_NO_MEMORY;
|
||||
|
||||
|
@ -279,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);
|
||||
|
||||
|
@ -292,49 +221,24 @@ _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 = _cairo_glitz_get_boxes_from_region (&surface->clip, &n);
|
||||
if (box == NULL && n != 0) {
|
||||
free (pixels);
|
||||
return CAIRO_STATUS_NO_MEMORY;
|
||||
}
|
||||
int n;
|
||||
|
||||
box = (glitz_box_t *) pixman_region_rects (surface->clip);
|
||||
n = pixman_region_num_rects (surface->clip);
|
||||
glitz_surface_set_clip_region (surface->surface, 0, 0, box, n);
|
||||
|
||||
free (box);
|
||||
}
|
||||
|
||||
/*
|
||||
* Prefer to use a standard pixman format instead of the
|
||||
* general masks case.
|
||||
*/
|
||||
if (_CAIRO_MASK_FORMAT (&masks, &format)) {
|
||||
image = (cairo_image_surface_t *)
|
||||
cairo_image_surface_create_for_data (pixels,
|
||||
format,
|
||||
x2 - x1,
|
||||
y2 - y1,
|
||||
pf.bytes_per_line);
|
||||
if (image->base.status)
|
||||
goto FAIL;
|
||||
} else {
|
||||
/*
|
||||
* XXX This can't work. We must convert the data to one of the
|
||||
* supported pixman formats. Pixman needs another function
|
||||
* which takes data in an arbitrary format and converts it
|
||||
* to something supported by that library.
|
||||
*/
|
||||
image = (cairo_image_surface_t *)
|
||||
_cairo_image_surface_create_with_masks (pixels,
|
||||
&masks,
|
||||
x2 - x1,
|
||||
y2 - y1,
|
||||
pf.bytes_per_line);
|
||||
if (image->base.status)
|
||||
goto FAIL;
|
||||
image = (cairo_image_surface_t *)
|
||||
_cairo_image_surface_create_with_masks (pixels,
|
||||
&format,
|
||||
width, height,
|
||||
pf.bytes_per_line);
|
||||
if (image->base.status)
|
||||
{
|
||||
free (pixels);
|
||||
return CAIRO_STATUS_NO_MEMORY;
|
||||
}
|
||||
|
||||
_cairo_image_surface_assume_ownership_of_data (image);
|
||||
|
@ -342,47 +246,6 @@ _cairo_glitz_surface_get_image (cairo_glitz_surface_t *surface,
|
|||
*image_out = image;
|
||||
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
|
||||
FAIL:
|
||||
free (pixels);
|
||||
return CAIRO_STATUS_NO_MEMORY;
|
||||
}
|
||||
|
||||
static void
|
||||
cairo_format_get_masks (cairo_format_t format,
|
||||
uint32_t *bpp,
|
||||
uint32_t *alpha,
|
||||
uint32_t *red,
|
||||
uint32_t *green,
|
||||
uint32_t *blue)
|
||||
{
|
||||
*red = 0x0;
|
||||
*green = 0x0;
|
||||
*blue = 0x0;
|
||||
*alpha = 0x0;
|
||||
|
||||
switch (format)
|
||||
{
|
||||
case CAIRO_FORMAT_ARGB32:
|
||||
*alpha = 0xff000000;
|
||||
case CAIRO_FORMAT_RGB24:
|
||||
default:
|
||||
*bpp = 32;
|
||||
*red = 0x00ff0000;
|
||||
*green = 0x0000ff00;
|
||||
*blue = 0x000000ff;
|
||||
break;
|
||||
|
||||
case CAIRO_FORMAT_A8:
|
||||
*bpp = 8;
|
||||
*alpha = 0xff;
|
||||
break;
|
||||
|
||||
case CAIRO_FORMAT_A1:
|
||||
*bpp = 1;
|
||||
*alpha = 0x1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static cairo_status_t
|
||||
|
@ -398,10 +261,15 @@ _cairo_glitz_surface_set_image (void *abstract_surface,
|
|||
cairo_glitz_surface_t *surface = abstract_surface;
|
||||
glitz_buffer_t *buffer;
|
||||
glitz_pixel_format_t pf;
|
||||
uint32_t bpp, am, rm, gm, bm;
|
||||
pixman_format_t *format;
|
||||
unsigned int bpp, am, rm, gm, bm;
|
||||
char *data;
|
||||
|
||||
cairo_format_get_masks (image->format, &bpp, &am, &rm, &gm, &bm);
|
||||
format = pixman_image_get_format (image->pixman_image);
|
||||
if (!format)
|
||||
return CAIRO_STATUS_NO_MEMORY;
|
||||
|
||||
pixman_format_get_masks (format, &bpp, &am, &rm, &gm, &bm);
|
||||
|
||||
pf.fourcc = GLITZ_FOURCC_RGB;
|
||||
pf.masks.bpp = bpp;
|
||||
|
@ -463,9 +331,9 @@ _cairo_glitz_surface_release_source_image (void *abstract_surface,
|
|||
|
||||
static cairo_status_t
|
||||
_cairo_glitz_surface_acquire_dest_image (void *abstract_surface,
|
||||
cairo_rectangle_int_t *interest_rect,
|
||||
cairo_rectangle_int16_t *interest_rect,
|
||||
cairo_image_surface_t **image_out,
|
||||
cairo_rectangle_int_t *image_rect_out,
|
||||
cairo_rectangle_int16_t *image_rect_out,
|
||||
void **image_extra)
|
||||
{
|
||||
cairo_glitz_surface_t *surface = abstract_surface;
|
||||
|
@ -485,9 +353,9 @@ _cairo_glitz_surface_acquire_dest_image (void *abstract_surfa
|
|||
|
||||
static void
|
||||
_cairo_glitz_surface_release_dest_image (void *abstract_surface,
|
||||
cairo_rectangle_int_t *interest_rect,
|
||||
cairo_rectangle_int16_t *interest_rect,
|
||||
cairo_image_surface_t *image,
|
||||
cairo_rectangle_int_t *image_rect,
|
||||
cairo_rectangle_int16_t *image_rect,
|
||||
void *image_extra)
|
||||
{
|
||||
cairo_glitz_surface_t *surface = abstract_surface;
|
||||
|
@ -524,8 +392,8 @@ _cairo_glitz_surface_clone_similar (void *abstract_surface,
|
|||
{
|
||||
cairo_image_surface_t *image_src = (cairo_image_surface_t *) src;
|
||||
cairo_content_t content;
|
||||
cairo_rectangle_int_t image_extent;
|
||||
cairo_rectangle_int_t extent;
|
||||
cairo_rectangle_int16_t image_extent;
|
||||
cairo_rectangle_int16_t extent;
|
||||
|
||||
content = _cairo_content_from_format (image_src->format);
|
||||
|
||||
|
@ -722,7 +590,7 @@ _cairo_glitz_pattern_acquire_surface (cairo_pattern_t *pattern,
|
|||
(cairo_gradient_pattern_t *) pattern;
|
||||
char *data;
|
||||
glitz_fixed16_16_t *params;
|
||||
unsigned int n_params;
|
||||
int n_params;
|
||||
unsigned int *pixels;
|
||||
unsigned int i, n_base_params;
|
||||
glitz_buffer_t *buffer;
|
||||
|
@ -759,22 +627,8 @@ _cairo_glitz_pattern_acquire_surface (cairo_pattern_t *pattern,
|
|||
|
||||
n_params = gradient->n_stops * 3 + n_base_params;
|
||||
|
||||
/* check for int overflow */
|
||||
{
|
||||
int size1, size2;
|
||||
if (n_params >= INT32_MAX / sizeof (glitz_fixed16_16_t) ||
|
||||
gradient->n_stops >= INT32_MAX / sizeof (unsigned int))
|
||||
return CAIRO_STATUS_NO_MEMORY;
|
||||
|
||||
size1 = n_params * sizeof (glitz_fixed16_16_t);
|
||||
size2 = gradient->n_stops * sizeof (unsigned int);
|
||||
|
||||
if (size1 >= INT32_MAX - size2)
|
||||
return CAIRO_STATUS_NO_MEMORY;
|
||||
|
||||
data = malloc (size1 + size2);
|
||||
}
|
||||
|
||||
data = malloc (sizeof (glitz_fixed16_16_t) * n_params +
|
||||
sizeof (unsigned int) * gradient->n_stops);
|
||||
if (!data)
|
||||
return CAIRO_STATUS_NO_MEMORY;
|
||||
|
||||
|
@ -814,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,22 +676,22 @@ _cairo_glitz_pattern_acquire_surface (cairo_pattern_t *pattern,
|
|||
{
|
||||
cairo_linear_pattern_t *grad = (cairo_linear_pattern_t *) pattern;
|
||||
|
||||
params[0] = grad->p1.x;
|
||||
params[1] = grad->p1.y;
|
||||
params[2] = grad->p2.x;
|
||||
params[3] = grad->p2.y;
|
||||
params[0] = grad->gradient.p1.x;
|
||||
params[1] = grad->gradient.p1.y;
|
||||
params[2] = grad->gradient.p2.x;
|
||||
params[3] = grad->gradient.p2.y;
|
||||
attr->filter = GLITZ_FILTER_LINEAR_GRADIENT;
|
||||
}
|
||||
else
|
||||
{
|
||||
cairo_radial_pattern_t *grad = (cairo_radial_pattern_t *) pattern;
|
||||
|
||||
params[0] = grad->c1.x;
|
||||
params[1] = grad->c1.y;
|
||||
params[2] = grad->radius1;
|
||||
params[3] = grad->c2.x;
|
||||
params[4] = grad->c2.y;
|
||||
params[5] = grad->radius2;
|
||||
params[0] = grad->gradient.c1.x;
|
||||
params[1] = grad->gradient.c1.y;
|
||||
params[2] = grad->gradient.c1.radius;
|
||||
params[3] = grad->gradient.c2.x;
|
||||
params[4] = grad->gradient.c2.y;
|
||||
params[5] = grad->gradient.c2.radius;
|
||||
attr->filter = GLITZ_FILTER_RADIAL_GRADIENT;
|
||||
}
|
||||
|
||||
|
@ -968,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,
|
||||
|
@ -992,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,
|
||||
|
@ -1110,7 +957,7 @@ static cairo_int_status_t
|
|||
_cairo_glitz_surface_fill_rectangles (void *abstract_dst,
|
||||
cairo_operator_t op,
|
||||
const cairo_color_t *color,
|
||||
cairo_rectangle_int_t *rects,
|
||||
cairo_rectangle_int16_t *rects,
|
||||
int n_rects)
|
||||
{
|
||||
cairo_glitz_surface_t *dst = abstract_dst;
|
||||
|
@ -1155,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;
|
||||
|
||||
|
@ -1225,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,
|
||||
|
@ -1372,7 +1216,7 @@ _cairo_glitz_surface_composite_trapezoids (cairo_operator_t op,
|
|||
}
|
||||
|
||||
pixman_add_trapezoids (image->pixman_image, -dst_x, -dst_y,
|
||||
n_traps, (pixman_trapezoid_t *) traps);
|
||||
(pixman_trapezoid_t *) traps, n_traps);
|
||||
|
||||
mask = (cairo_glitz_surface_t *)
|
||||
_cairo_surface_create_similar_scratch (&dst->base,
|
||||
|
@ -1430,47 +1274,35 @@ _cairo_glitz_surface_composite_trapezoids (cairo_operator_t op,
|
|||
|
||||
static cairo_int_status_t
|
||||
_cairo_glitz_surface_set_clip_region (void *abstract_surface,
|
||||
cairo_region_t *region);
|
||||
pixman_region16_t *region)
|
||||
{
|
||||
cairo_glitz_surface_t *surface = abstract_surface;
|
||||
|
||||
if (region)
|
||||
|
||||
{
|
||||
glitz_box_t *box;
|
||||
int n;
|
||||
|
||||
if (!surface->has_clip) {
|
||||
_cairo_region_init (&surface->clip);
|
||||
surface->has_clip = TRUE;
|
||||
}
|
||||
|
||||
if (_cairo_region_copy (&surface->clip, region) != CAIRO_STATUS_SUCCESS)
|
||||
{
|
||||
_cairo_region_fini (&surface->clip);
|
||||
surface->has_clip = FALSE;
|
||||
return CAIRO_STATUS_NO_MEMORY;
|
||||
}
|
||||
|
||||
box = _cairo_glitz_get_boxes_from_region (&surface->clip, &n);
|
||||
if (box == NULL && n != 0) {
|
||||
_cairo_region_fini (&surface->clip);
|
||||
surface->has_clip = FALSE;
|
||||
return CAIRO_STATUS_NO_MEMORY;
|
||||
}
|
||||
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);
|
||||
|
||||
free (box);
|
||||
}
|
||||
else
|
||||
{
|
||||
glitz_surface_set_clip_region (surface->surface, 0, 0, NULL, 0);
|
||||
|
||||
if (surface->has_clip) {
|
||||
_cairo_region_fini (&surface->clip);
|
||||
surface->has_clip = FALSE;
|
||||
}
|
||||
if (surface->clip)
|
||||
pixman_region_destroy (surface->clip);
|
||||
|
||||
surface->clip = NULL;
|
||||
}
|
||||
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
|
@ -1478,7 +1310,7 @@ _cairo_glitz_surface_set_clip_region (void *abstract_surface,
|
|||
|
||||
static cairo_int_status_t
|
||||
_cairo_glitz_surface_get_extents (void *abstract_surface,
|
||||
cairo_rectangle_int_t *rectangle)
|
||||
cairo_rectangle_int16_t *rectangle)
|
||||
{
|
||||
cairo_glitz_surface_t *surface = abstract_surface;
|
||||
|
||||
|
@ -1980,6 +1812,7 @@ _cairo_glitz_surface_add_glyph (cairo_glitz_surface_t *surface,
|
|||
glitz_point_fixed_t p1, p2;
|
||||
glitz_pixel_format_t pf;
|
||||
glitz_buffer_t *buffer;
|
||||
pixman_format_t *format;
|
||||
unsigned int bpp, am, rm, gm, bm;
|
||||
cairo_int_status_t status;
|
||||
|
||||
|
@ -2016,6 +1849,10 @@ _cairo_glitz_surface_add_glyph (cairo_glitz_surface_t *surface,
|
|||
return CAIRO_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
format = pixman_image_get_format (glyph_surface->pixman_image);
|
||||
if (!format)
|
||||
return CAIRO_STATUS_NO_MEMORY;
|
||||
|
||||
if (_cairo_glitz_area_find (font_private->root.area,
|
||||
glyph_surface->width,
|
||||
glyph_surface->height,
|
||||
|
@ -2035,7 +1872,7 @@ _cairo_glitz_surface_add_glyph (cairo_glitz_surface_t *surface,
|
|||
return CAIRO_STATUS_NO_MEMORY;
|
||||
}
|
||||
|
||||
cairo_format_get_masks (glyph_surface->format, &bpp, &am, &rm, &gm, &bm);
|
||||
pixman_format_get_masks (format, &bpp, &am, &rm, &gm, &bm);
|
||||
|
||||
pf.fourcc = GLITZ_FOURCC_RGB;
|
||||
pf.masks.bpp = bpp;
|
||||
|
@ -2139,19 +1976,9 @@ _cairo_glitz_surface_old_show_glyphs (cairo_scaled_font_t *scaled_font,
|
|||
if (num_glyphs > N_STACK_BUF)
|
||||
{
|
||||
char *data;
|
||||
size_t size1, size2;
|
||||
|
||||
if ((size_t)num_glyphs >= INT32_MAX / sizeof(void*) ||
|
||||
(size_t)num_glyphs >= INT32_MAX / sizeof(glitz_float_t) ||
|
||||
((size_t)num_glyphs * sizeof(glitz_float_t)) >= INT32_MAX / 16)
|
||||
goto FAIL1;
|
||||
|
||||
size1 = num_glyphs * sizeof(void *);
|
||||
size2 = num_glyphs * sizeof(glitz_float_t) * 16;
|
||||
if (size1 >= INT32_MAX - size2)
|
||||
goto FAIL1;
|
||||
|
||||
data = malloc (size1 + size2);
|
||||
data = malloc (num_glyphs * sizeof (void *) +
|
||||
num_glyphs * sizeof (glitz_float_t) * 16);
|
||||
if (!data)
|
||||
goto FAIL1;
|
||||
|
||||
|
@ -2345,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,
|
||||
|
@ -2394,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 *
|
||||
|
@ -2451,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;
|
||||
}
|
||||
|
|
|
@ -35,6 +35,8 @@
|
|||
* Carl D. Worth <cworth@cworth.org>
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
#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;
|
||||
|
@ -530,7 +474,7 @@ _cairo_gstate_set_dash (cairo_gstate_t *gstate, const double *dash, int num_dash
|
|||
return CAIRO_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
gstate->stroke_style.dash = _cairo_malloc_ab (gstate->stroke_style.num_dashes, sizeof (double));
|
||||
gstate->stroke_style.dash = malloc (gstate->stroke_style.num_dashes * sizeof (double));
|
||||
if (gstate->stroke_style.dash == NULL) {
|
||||
gstate->stroke_style.num_dashes = 0;
|
||||
return CAIRO_STATUS_NO_MEMORY;
|
||||
|
@ -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
|
||||
|
@ -1214,7 +1143,7 @@ _cairo_gstate_clip_extents (cairo_gstate_t *gstate,
|
|||
double *x2,
|
||||
double *y2)
|
||||
{
|
||||
cairo_rectangle_int_t extents;
|
||||
cairo_rectangle_int16_t extents;
|
||||
cairo_status_t status;
|
||||
|
||||
status = _cairo_surface_get_extents (gstate->target, &extents);
|
||||
|
@ -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)))
|
||||
|
@ -1570,7 +1497,7 @@ _cairo_gstate_show_glyphs (cairo_gstate_t *gstate,
|
|||
if (num_glyphs <= STACK_GLYPHS_LEN) {
|
||||
transformed_glyphs = stack_transformed_glyphs;
|
||||
} else {
|
||||
transformed_glyphs = _cairo_malloc_ab (num_glyphs, sizeof(cairo_glyph_t));
|
||||
transformed_glyphs = malloc (num_glyphs * sizeof(cairo_glyph_t));
|
||||
if (transformed_glyphs == NULL)
|
||||
return CAIRO_STATUS_NO_MEMORY;
|
||||
}
|
||||
|
@ -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);
|
||||
|
||||
|
@ -1615,7 +1539,7 @@ _cairo_gstate_glyph_path (cairo_gstate_t *gstate,
|
|||
if (num_glyphs < STACK_GLYPHS_LEN)
|
||||
transformed_glyphs = stack_transformed_glyphs;
|
||||
else
|
||||
transformed_glyphs = _cairo_malloc_ab (num_glyphs, sizeof(cairo_glyph_t));
|
||||
transformed_glyphs = malloc (num_glyphs * sizeof(cairo_glyph_t));
|
||||
if (transformed_glyphs == NULL)
|
||||
return CAIRO_STATUS_NO_MEMORY;
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -62,7 +62,7 @@ _cairo_hull_create (cairo_pen_vertex_t *vertices, int num_vertices)
|
|||
*extremum = vertices[0].point;
|
||||
vertices[0].point = tmp;
|
||||
|
||||
hull = _cairo_malloc_ab (num_vertices, sizeof (cairo_hull_t));
|
||||
hull = malloc (num_vertices * sizeof (cairo_hull_t));
|
||||
if (hull == NULL)
|
||||
return NULL;
|
||||
|
||||
|
|
|
@ -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 © 2003 University of Southern California
|
||||
|
@ -37,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,
|
||||
|
@ -83,6 +82,23 @@ static const cairo_image_surface_t _cairo_image_surface_nil_invalid_format = {
|
|||
};
|
||||
|
||||
|
||||
static int
|
||||
_cairo_format_bpp (cairo_format_t format)
|
||||
{
|
||||
switch (format) {
|
||||
case CAIRO_FORMAT_A1:
|
||||
return 1;
|
||||
case CAIRO_FORMAT_A8:
|
||||
return 8;
|
||||
case CAIRO_FORMAT_RGB24:
|
||||
case CAIRO_FORMAT_ARGB32:
|
||||
return 32;
|
||||
}
|
||||
|
||||
ASSERT_NOT_REACHED;
|
||||
return 32;
|
||||
}
|
||||
|
||||
cairo_surface_t *
|
||||
_cairo_image_surface_create_for_pixman_image (pixman_image_t *pixman_image,
|
||||
cairo_format_t format)
|
||||
|
@ -113,47 +129,75 @@ _cairo_image_surface_create_for_pixman_image (pixman_image_t *pixman_image,
|
|||
return &surface->base;
|
||||
}
|
||||
|
||||
static cairo_bool_t
|
||||
_CAIRO_MASK_FORMAT (cairo_format_masks_t *masks, cairo_format_t *format)
|
||||
/* Try to recover a cairo_format_t from a pixman_format
|
||||
* by looking at the bpp and masks values. */
|
||||
static cairo_format_t
|
||||
_cairo_format_from_pixman_format (pixman_format_t *pixman_format)
|
||||
{
|
||||
/* XXX: many formats are simply not supported by pixman, so this function
|
||||
* converts the masks into something we know will be supported.
|
||||
*/
|
||||
switch (masks->bpp) {
|
||||
unsigned int bpp, am, rm, gm, bm;
|
||||
|
||||
pixman_format_get_masks (pixman_format, &bpp, &am, &rm, &gm, &bm);
|
||||
|
||||
/* See definition of cairo_internal_format_t for an explanation of
|
||||
* the CAIRO_INTERNAL_FORMAT values used here. */
|
||||
switch (bpp) {
|
||||
case 32:
|
||||
if (masks->alpha_mask == 0xff000000 &&
|
||||
masks->red_mask == 0x00ff0000 &&
|
||||
masks->green_mask == 0x0000ff00 &&
|
||||
masks->blue_mask == 0x000000ff)
|
||||
{
|
||||
*format = CAIRO_FORMAT_ARGB32;
|
||||
return TRUE;
|
||||
}
|
||||
if (masks->alpha_mask == 0x00000000 &&
|
||||
masks->red_mask == 0x00ff0000 &&
|
||||
masks->green_mask == 0x0000ff00 &&
|
||||
masks->blue_mask == 0x000000ff)
|
||||
{
|
||||
*format = CAIRO_FORMAT_RGB24;
|
||||
return TRUE;
|
||||
if (am == 0xff000000) {
|
||||
if (rm == 0x00ff0000 &&
|
||||
gm == 0x0000ff00 &&
|
||||
bm == 0x000000ff)
|
||||
return CAIRO_FORMAT_ARGB32;
|
||||
if (rm == 0x000000ff &&
|
||||
gm == 0x0000ff00 &&
|
||||
bm == 0x00ff0000)
|
||||
return CAIRO_INTERNAL_FORMAT_ABGR32;
|
||||
} else if (am == 0x0) {
|
||||
if (rm == 0x00ff0000 &&
|
||||
gm == 0x0000ff00 &&
|
||||
bm == 0x000000ff)
|
||||
return CAIRO_FORMAT_RGB24;
|
||||
if (rm == 0x000000ff &&
|
||||
gm == 0x0000ff00 &&
|
||||
bm == 0x00ff0000)
|
||||
return CAIRO_INTERNAL_FORMAT_BGR24;
|
||||
}
|
||||
break;
|
||||
case 16:
|
||||
if (am == 0x0 &&
|
||||
rm == 0xf800 &&
|
||||
gm == 0x07e0 &&
|
||||
bm == 0x001f)
|
||||
return CAIRO_FORMAT_RGB16_565;
|
||||
break;
|
||||
case 8:
|
||||
if (masks->alpha_mask == 0xff)
|
||||
{
|
||||
*format = CAIRO_FORMAT_A8;
|
||||
return TRUE;
|
||||
}
|
||||
if (am == 0xff &&
|
||||
rm == 0x0 &&
|
||||
gm == 0x0 &&
|
||||
bm == 0x0)
|
||||
return CAIRO_FORMAT_A8;
|
||||
break;
|
||||
case 1:
|
||||
if (masks->alpha_mask == 0x1)
|
||||
{
|
||||
*format = CAIRO_FORMAT_A1;
|
||||
return TRUE;
|
||||
}
|
||||
if (am == 0x1 &&
|
||||
rm == 0x0 &&
|
||||
gm == 0x0 &&
|
||||
bm == 0x0)
|
||||
return CAIRO_FORMAT_A1;
|
||||
break;
|
||||
}
|
||||
return FALSE;
|
||||
|
||||
fprintf (stderr,
|
||||
"Error: Cairo " PACKAGE_VERSION " does not yet support the requested image format:\n"
|
||||
"\tDepth: %d\n"
|
||||
"\tAlpha mask: 0x%08x\n"
|
||||
"\tRed mask: 0x%08x\n"
|
||||
"\tGreen mask: 0x%08x\n"
|
||||
"\tBlue mask: 0x%08x\n"
|
||||
"Please file an enhancement request (quoting the above) at:\n"
|
||||
PACKAGE_BUGREPORT "\n",
|
||||
bpp, am, rm, gm, bm);
|
||||
|
||||
ASSERT_NOT_REACHED;
|
||||
return (cairo_format_t) -1;
|
||||
}
|
||||
|
||||
/* XXX: This function really should be eliminated. We don't really
|
||||
|
@ -162,46 +206,63 @@ _CAIRO_MASK_FORMAT (cairo_format_masks_t *masks, cairo_format_t *format)
|
|||
* that accepts a cairo_internal_format_t rather than mask values. */
|
||||
cairo_surface_t *
|
||||
_cairo_image_surface_create_with_masks (unsigned char *data,
|
||||
cairo_format_masks_t *masks,
|
||||
cairo_format_masks_t *format,
|
||||
int width,
|
||||
int height,
|
||||
int stride)
|
||||
{
|
||||
cairo_format_t format;
|
||||
|
||||
if (!_CAIRO_MASK_FORMAT (masks, &format)) {
|
||||
_cairo_error (CAIRO_STATUS_INVALID_FORMAT);
|
||||
cairo_surface_t *surface;
|
||||
pixman_format_t *pixman_format;
|
||||
pixman_image_t *pixman_image;
|
||||
cairo_format_t cairo_format;
|
||||
|
||||
pixman_format = pixman_format_create_masks (format->bpp,
|
||||
format->alpha_mask,
|
||||
format->red_mask,
|
||||
format->green_mask,
|
||||
format->blue_mask);
|
||||
|
||||
if (pixman_format == NULL) {
|
||||
_cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
return (cairo_surface_t*) &_cairo_surface_nil;
|
||||
}
|
||||
|
||||
return cairo_image_surface_create_for_data (data,
|
||||
format,
|
||||
width,
|
||||
height,
|
||||
stride);
|
||||
cairo_format = _cairo_format_from_pixman_format (pixman_format);
|
||||
|
||||
pixman_image = pixman_image_create_for_data ((pixman_bits_t *) data, pixman_format,
|
||||
width, height, format->bpp, stride);
|
||||
|
||||
pixman_format_destroy (pixman_format);
|
||||
|
||||
if (pixman_image == NULL) {
|
||||
_cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
return (cairo_surface_t*) &_cairo_surface_nil;
|
||||
}
|
||||
|
||||
surface = _cairo_image_surface_create_for_pixman_image (pixman_image,
|
||||
cairo_format);
|
||||
|
||||
return surface;
|
||||
}
|
||||
|
||||
static pixman_format_code_t
|
||||
_cairo_format_to_pixman_format_code (cairo_format_t format)
|
||||
static pixman_format_t *
|
||||
_create_pixman_format (cairo_format_t format)
|
||||
{
|
||||
int ret = 0;
|
||||
switch (format) {
|
||||
case CAIRO_FORMAT_A1:
|
||||
ret = PIXMAN_a1;
|
||||
return pixman_format_create (PIXMAN_FORMAT_NAME_A1);
|
||||
break;
|
||||
case CAIRO_FORMAT_A8:
|
||||
ret = PIXMAN_a8;
|
||||
return pixman_format_create (PIXMAN_FORMAT_NAME_A8);
|
||||
break;
|
||||
case CAIRO_FORMAT_RGB24:
|
||||
ret = PIXMAN_x8r8g8b8;
|
||||
return pixman_format_create (PIXMAN_FORMAT_NAME_RGB24);
|
||||
break;
|
||||
case CAIRO_FORMAT_ARGB32:
|
||||
default:
|
||||
ret = PIXMAN_a8r8g8b8;
|
||||
return pixman_format_create (PIXMAN_FORMAT_NAME_ARGB32);
|
||||
break;
|
||||
}
|
||||
assert (ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -229,28 +290,31 @@ cairo_image_surface_create (cairo_format_t format,
|
|||
int width,
|
||||
int height)
|
||||
{
|
||||
cairo_surface_t *surface;
|
||||
pixman_format_code_t pixman_format;
|
||||
pixman_image_t *pixman_image;
|
||||
cairo_surface_t *surface;
|
||||
pixman_format_t *pixman_format;
|
||||
pixman_image_t *pixman_image;
|
||||
|
||||
if (! CAIRO_FORMAT_VALID (format)) {
|
||||
_cairo_error (CAIRO_STATUS_INVALID_FORMAT);
|
||||
return (cairo_surface_t*) &_cairo_image_surface_nil_invalid_format;
|
||||
}
|
||||
|
||||
pixman_format = _cairo_format_to_pixman_format_code (format);
|
||||
|
||||
pixman_image = pixman_image_create_bits (pixman_format, width, height,
|
||||
NULL, -1);
|
||||
pixman_format = _create_pixman_format (format);
|
||||
if (pixman_format == NULL) {
|
||||
_cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
return (cairo_surface_t*) &_cairo_surface_nil;
|
||||
}
|
||||
|
||||
pixman_image = pixman_image_create (pixman_format, width, height);
|
||||
|
||||
pixman_format_destroy (pixman_format);
|
||||
|
||||
if (pixman_image == NULL) {
|
||||
_cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
return (cairo_surface_t*) &_cairo_surface_nil;
|
||||
}
|
||||
|
||||
surface = _cairo_image_surface_create_for_pixman_image (pixman_image, format);
|
||||
if (cairo_surface_status (surface)) {
|
||||
pixman_image_unref (pixman_image);
|
||||
}
|
||||
|
||||
return surface;
|
||||
}
|
||||
|
@ -305,27 +369,32 @@ cairo_image_surface_create_for_data (unsigned char *data,
|
|||
int height,
|
||||
int stride)
|
||||
{
|
||||
cairo_surface_t *surface;
|
||||
pixman_format_code_t pixman_format;
|
||||
pixman_image_t *pixman_image;
|
||||
cairo_surface_t *surface;
|
||||
pixman_format_t *pixman_format;
|
||||
pixman_image_t *pixman_image;
|
||||
|
||||
if (! CAIRO_FORMAT_VALID (format))
|
||||
return (cairo_surface_t*) &_cairo_surface_nil;
|
||||
|
||||
pixman_format = _cairo_format_to_pixman_format_code (format);
|
||||
pixman_format = _create_pixman_format (format);
|
||||
if (pixman_format == NULL) {
|
||||
_cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
return (cairo_surface_t*) &_cairo_surface_nil;
|
||||
}
|
||||
|
||||
pixman_image = pixman_image_create_for_data ((pixman_bits_t *) data, pixman_format,
|
||||
width, height,
|
||||
_cairo_format_bpp (format),
|
||||
stride);
|
||||
|
||||
pixman_format_destroy (pixman_format);
|
||||
|
||||
pixman_image = pixman_image_create_bits (pixman_format, width, height,
|
||||
(uint32_t *) data, stride);
|
||||
|
||||
if (pixman_image == NULL) {
|
||||
_cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
return (cairo_surface_t*) &_cairo_surface_nil;
|
||||
}
|
||||
|
||||
surface = _cairo_image_surface_create_for_pixman_image (pixman_image, format);
|
||||
if (cairo_surface_status (surface)) {
|
||||
pixman_image_unref (pixman_image);
|
||||
}
|
||||
|
||||
return surface;
|
||||
}
|
||||
|
@ -498,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:
|
||||
|
@ -528,7 +597,7 @@ _cairo_image_surface_finish (void *abstract_surface)
|
|||
cairo_image_surface_t *surface = abstract_surface;
|
||||
|
||||
if (surface->pixman_image) {
|
||||
pixman_image_unref (surface->pixman_image);
|
||||
pixman_image_destroy (surface->pixman_image);
|
||||
surface->pixman_image = NULL;
|
||||
}
|
||||
|
||||
|
@ -566,9 +635,9 @@ _cairo_image_surface_release_source_image (void *abstract_surf
|
|||
|
||||
static cairo_status_t
|
||||
_cairo_image_surface_acquire_dest_image (void *abstract_surface,
|
||||
cairo_rectangle_int_t *interest_rect,
|
||||
cairo_rectangle_int16_t *interest_rect,
|
||||
cairo_image_surface_t **image_out,
|
||||
cairo_rectangle_int_t *image_rect_out,
|
||||
cairo_rectangle_int16_t *image_rect_out,
|
||||
void **image_extra)
|
||||
{
|
||||
cairo_image_surface_t *surface = abstract_surface;
|
||||
|
@ -586,9 +655,9 @@ _cairo_image_surface_acquire_dest_image (void *abstract_surfa
|
|||
|
||||
static void
|
||||
_cairo_image_surface_release_dest_image (void *abstract_surface,
|
||||
cairo_rectangle_int_t *interest_rect,
|
||||
cairo_rectangle_int16_t *interest_rect,
|
||||
cairo_image_surface_t *image,
|
||||
cairo_rectangle_int_t *image_rect,
|
||||
cairo_rectangle_int16_t *image_rect,
|
||||
void *image_extra)
|
||||
{
|
||||
}
|
||||
|
@ -621,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;
|
||||
}
|
||||
|
@ -658,7 +726,7 @@ _cairo_image_surface_set_filter (cairo_image_surface_t *surface, cairo_filter_t
|
|||
pixman_filter = PIXMAN_FILTER_BEST;
|
||||
}
|
||||
|
||||
pixman_image_set_filter (surface->pixman_image, pixman_filter, NULL, 0);
|
||||
pixman_image_set_filter (surface->pixman_image, pixman_filter);
|
||||
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
}
|
||||
|
@ -698,43 +766,43 @@ _cairo_image_surface_set_attributes (cairo_image_surface_t *surface,
|
|||
* time the X server is ported to pixman, (which will change a lot of
|
||||
* things in pixman I think).
|
||||
*/
|
||||
static pixman_op_t
|
||||
static pixman_operator_t
|
||||
_pixman_operator (cairo_operator_t op)
|
||||
{
|
||||
switch (op) {
|
||||
case CAIRO_OPERATOR_CLEAR:
|
||||
return PIXMAN_OP_CLEAR;
|
||||
return PIXMAN_OPERATOR_CLEAR;
|
||||
|
||||
case CAIRO_OPERATOR_SOURCE:
|
||||
return PIXMAN_OP_SRC;
|
||||
return PIXMAN_OPERATOR_SRC;
|
||||
case CAIRO_OPERATOR_OVER:
|
||||
return PIXMAN_OP_OVER;
|
||||
return PIXMAN_OPERATOR_OVER;
|
||||
case CAIRO_OPERATOR_IN:
|
||||
return PIXMAN_OP_IN;
|
||||
return PIXMAN_OPERATOR_IN;
|
||||
case CAIRO_OPERATOR_OUT:
|
||||
return PIXMAN_OP_OUT;
|
||||
return PIXMAN_OPERATOR_OUT;
|
||||
case CAIRO_OPERATOR_ATOP:
|
||||
return PIXMAN_OP_ATOP;
|
||||
return PIXMAN_OPERATOR_ATOP;
|
||||
|
||||
case CAIRO_OPERATOR_DEST:
|
||||
return PIXMAN_OP_DST;
|
||||
return PIXMAN_OPERATOR_DST;
|
||||
case CAIRO_OPERATOR_DEST_OVER:
|
||||
return PIXMAN_OP_OVER_REVERSE;
|
||||
return PIXMAN_OPERATOR_OVER_REVERSE;
|
||||
case CAIRO_OPERATOR_DEST_IN:
|
||||
return PIXMAN_OP_IN_REVERSE;
|
||||
return PIXMAN_OPERATOR_IN_REVERSE;
|
||||
case CAIRO_OPERATOR_DEST_OUT:
|
||||
return PIXMAN_OP_OUT_REVERSE;
|
||||
return PIXMAN_OPERATOR_OUT_REVERSE;
|
||||
case CAIRO_OPERATOR_DEST_ATOP:
|
||||
return PIXMAN_OP_ATOP_REVERSE;
|
||||
return PIXMAN_OPERATOR_ATOP_REVERSE;
|
||||
|
||||
case CAIRO_OPERATOR_XOR:
|
||||
return PIXMAN_OP_XOR;
|
||||
return PIXMAN_OPERATOR_XOR;
|
||||
case CAIRO_OPERATOR_ADD:
|
||||
return PIXMAN_OP_ADD;
|
||||
return PIXMAN_OPERATOR_ADD;
|
||||
case CAIRO_OPERATOR_SATURATE:
|
||||
return PIXMAN_OP_SATURATE;
|
||||
return PIXMAN_OPERATOR_SATURATE;
|
||||
default:
|
||||
return PIXMAN_OP_OVER;
|
||||
return PIXMAN_OPERATOR_OVER;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -779,28 +847,28 @@ _cairo_image_surface_composite (cairo_operator_t op,
|
|||
if (status)
|
||||
goto CLEANUP_SURFACES;
|
||||
|
||||
pixman_image_composite (_pixman_operator (op),
|
||||
src->pixman_image,
|
||||
mask->pixman_image,
|
||||
dst->pixman_image,
|
||||
src_x + src_attr.x_offset,
|
||||
src_y + src_attr.y_offset,
|
||||
mask_x + mask_attr.x_offset,
|
||||
mask_y + mask_attr.y_offset,
|
||||
dst_x, dst_y,
|
||||
width, height);
|
||||
pixman_composite (_pixman_operator (op),
|
||||
src->pixman_image,
|
||||
mask->pixman_image,
|
||||
dst->pixman_image,
|
||||
src_x + src_attr.x_offset,
|
||||
src_y + src_attr.y_offset,
|
||||
mask_x + mask_attr.x_offset,
|
||||
mask_y + mask_attr.y_offset,
|
||||
dst_x, dst_y,
|
||||
width, height);
|
||||
}
|
||||
else
|
||||
{
|
||||
pixman_image_composite (_pixman_operator (op),
|
||||
src->pixman_image,
|
||||
NULL,
|
||||
dst->pixman_image,
|
||||
src_x + src_attr.x_offset,
|
||||
src_y + src_attr.y_offset,
|
||||
0, 0,
|
||||
dst_x, dst_y,
|
||||
width, height);
|
||||
pixman_composite (_pixman_operator (op),
|
||||
src->pixman_image,
|
||||
NULL,
|
||||
dst->pixman_image,
|
||||
src_x + src_attr.x_offset,
|
||||
src_y + src_attr.y_offset,
|
||||
0, 0,
|
||||
dst_x, dst_y,
|
||||
width, height);
|
||||
}
|
||||
|
||||
if (!_cairo_operator_bounded_by_source (op))
|
||||
|
@ -822,60 +890,29 @@ _cairo_image_surface_composite (cairo_operator_t op,
|
|||
return status;
|
||||
}
|
||||
|
||||
#define STACK_RECTS_LEN (CAIRO_STACK_BUFFER_SIZE / sizeof(pixman_rectangle16_t))
|
||||
|
||||
static cairo_int_status_t
|
||||
_cairo_image_surface_fill_rectangles (void *abstract_surface,
|
||||
cairo_operator_t op,
|
||||
const cairo_color_t *color,
|
||||
cairo_rectangle_int_t *rects,
|
||||
cairo_rectangle_int16_t *rects,
|
||||
int num_rects)
|
||||
{
|
||||
cairo_image_surface_t *surface = abstract_surface;
|
||||
|
||||
pixman_color_t pixman_color;
|
||||
pixman_rectangle16_t stack_rects[STACK_RECTS_LEN];
|
||||
pixman_rectangle16_t *pixman_rects = stack_rects;
|
||||
int i;
|
||||
|
||||
cairo_int_status_t status = CAIRO_STATUS_SUCCESS;
|
||||
|
||||
pixman_color.red = color->red_short;
|
||||
pixman_color.green = color->green_short;
|
||||
pixman_color.blue = color->blue_short;
|
||||
pixman_color.alpha = color->alpha_short;
|
||||
|
||||
if (num_rects > ARRAY_LENGTH(stack_rects)) {
|
||||
pixman_rects = _cairo_malloc_ab (num_rects, sizeof(pixman_rectangle16_t));
|
||||
if (pixman_rects == NULL)
|
||||
return CAIRO_STATUS_NO_MEMORY;
|
||||
}
|
||||
/* XXX: The pixman_rectangle_t cast is evil... it needs to go away somehow. */
|
||||
pixman_fill_rectangles (_pixman_operator(op), surface->pixman_image,
|
||||
&pixman_color, (pixman_rectangle_t *) rects, num_rects);
|
||||
|
||||
for (i = 0; i < num_rects; i++) {
|
||||
pixman_rects[i].x = rects[i].x;
|
||||
pixman_rects[i].y = rects[i].y;
|
||||
pixman_rects[i].width = rects[i].width;
|
||||
pixman_rects[i].height = rects[i].height;
|
||||
}
|
||||
|
||||
/* XXX: pixman_fill_rectangles() should be implemented */
|
||||
if (!pixman_image_fill_rectangles (_pixman_operator(op),
|
||||
surface->pixman_image,
|
||||
&pixman_color,
|
||||
num_rects,
|
||||
pixman_rects))
|
||||
status = CAIRO_STATUS_NO_MEMORY;
|
||||
|
||||
if (pixman_rects != stack_rects)
|
||||
free (pixman_rects);
|
||||
|
||||
return status;
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
#undef STACK_RECTS_LEN
|
||||
|
||||
#define STACK_TRAPS_LEN ((int) (CAIRO_STACK_BUFFER_SIZE / sizeof(pixman_trapezoid_t)))
|
||||
|
||||
static cairo_int_status_t
|
||||
_cairo_image_surface_composite_trapezoids (cairo_operator_t op,
|
||||
cairo_pattern_t *pattern,
|
||||
|
@ -895,33 +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_code_t format;
|
||||
uint32_t *mask_data;
|
||||
pixman_trapezoid_t stack_traps[STACK_TRAPS_LEN];
|
||||
pixman_trapezoid_t *pixman_traps = stack_traps;
|
||||
int mask_stride;
|
||||
int mask_bpp;
|
||||
int ret, i;
|
||||
|
||||
/* Convert traps to pixman traps */
|
||||
if (num_traps > ARRAY_LENGTH(stack_traps)) {
|
||||
pixman_traps = _cairo_malloc_ab (num_traps, sizeof(pixman_trapezoid_t));
|
||||
if (pixman_traps == NULL)
|
||||
return CAIRO_STATUS_NO_MEMORY;
|
||||
}
|
||||
|
||||
for (i = 0; i < num_traps; i++) {
|
||||
pixman_traps[i].top = _cairo_fixed_to_16_16 (traps[i].top);
|
||||
pixman_traps[i].bottom = _cairo_fixed_to_16_16 (traps[i].bottom);
|
||||
pixman_traps[i].left.p1.x = _cairo_fixed_to_16_16 (traps[i].left.p1.x);
|
||||
pixman_traps[i].left.p1.y = _cairo_fixed_to_16_16 (traps[i].left.p1.y);
|
||||
pixman_traps[i].left.p2.x = _cairo_fixed_to_16_16 (traps[i].left.p2.x);
|
||||
pixman_traps[i].left.p2.y = _cairo_fixed_to_16_16 (traps[i].left.p2.y);
|
||||
pixman_traps[i].right.p1.x = _cairo_fixed_to_16_16 (traps[i].right.p1.x);
|
||||
pixman_traps[i].right.p1.y = _cairo_fixed_to_16_16 (traps[i].right.p1.y);
|
||||
pixman_traps[i].right.p2.x = _cairo_fixed_to_16_16 (traps[i].right.p2.x);
|
||||
pixman_traps[i].right.p2.y = _cairo_fixed_to_16_16 (traps[i].right.p2.y);
|
||||
}
|
||||
pixman_format_t *format;
|
||||
pixman_bits_t *mask_data;
|
||||
int mask_stride;
|
||||
int mask_bpp;
|
||||
|
||||
/* Special case adding trapezoids onto a mask surface; we want to avoid
|
||||
* creating an intermediate temporary mask unecessarily.
|
||||
|
@ -943,9 +957,8 @@ _cairo_image_surface_composite_trapezoids (cairo_operator_t op,
|
|||
antialias != CAIRO_ANTIALIAS_NONE)
|
||||
{
|
||||
pixman_add_trapezoids (dst->pixman_image, 0, 0,
|
||||
num_traps, pixman_traps);
|
||||
status = CAIRO_STATUS_SUCCESS;
|
||||
goto finish;
|
||||
(pixman_trapezoid_t *) traps, num_traps);
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
status = _cairo_pattern_acquire_surface (pattern, &dst->base,
|
||||
|
@ -953,7 +966,7 @@ _cairo_image_surface_composite_trapezoids (cairo_operator_t op,
|
|||
(cairo_surface_t **) &src,
|
||||
&attributes);
|
||||
if (status)
|
||||
goto finish;
|
||||
return status;
|
||||
|
||||
status = _cairo_image_surface_set_attributes (src, &attributes);
|
||||
if (status)
|
||||
|
@ -961,50 +974,54 @@ _cairo_image_surface_composite_trapezoids (cairo_operator_t op,
|
|||
|
||||
switch (antialias) {
|
||||
case CAIRO_ANTIALIAS_NONE:
|
||||
format = PIXMAN_a1;
|
||||
ret = 1;
|
||||
assert (ret);
|
||||
mask_stride = ((width + 31) / 8) & ~0x03;
|
||||
format = pixman_format_create (PIXMAN_FORMAT_NAME_A1);
|
||||
mask_stride = (width + 31)/8;
|
||||
mask_bpp = 1;
|
||||
break;
|
||||
case CAIRO_ANTIALIAS_GRAY:
|
||||
case CAIRO_ANTIALIAS_SUBPIXEL:
|
||||
case CAIRO_ANTIALIAS_DEFAULT:
|
||||
default:
|
||||
format = PIXMAN_a8;
|
||||
ret = 1;
|
||||
assert (ret);
|
||||
format = pixman_format_create (PIXMAN_FORMAT_NAME_A8);
|
||||
mask_stride = (width + 3) & ~3;
|
||||
mask_bpp = 8;
|
||||
break;
|
||||
}
|
||||
|
||||
/* The image must be initially transparent */
|
||||
mask_data = calloc (1, mask_stride * height);
|
||||
if (mask_data == NULL) {
|
||||
if (!format) {
|
||||
status = CAIRO_STATUS_NO_MEMORY;
|
||||
goto CLEANUP_SOURCE;
|
||||
}
|
||||
|
||||
mask = pixman_image_create_bits (format, width, height,
|
||||
mask_data, mask_stride);
|
||||
if (mask == NULL) {
|
||||
/* The image must be initially transparent */
|
||||
mask_data = calloc (1, mask_stride * height);
|
||||
if (!mask_data) {
|
||||
status = CAIRO_STATUS_NO_MEMORY;
|
||||
pixman_format_destroy (format);
|
||||
goto CLEANUP_SOURCE;
|
||||
}
|
||||
|
||||
mask = pixman_image_create_for_data (mask_data, format, width, height,
|
||||
mask_bpp, mask_stride);
|
||||
pixman_format_destroy (format);
|
||||
if (!mask) {
|
||||
status = CAIRO_STATUS_NO_MEMORY;
|
||||
goto CLEANUP_IMAGE_DATA;
|
||||
}
|
||||
|
||||
/* XXX: The pixman_trapezoid_t cast is evil and needs to go away
|
||||
* somehow. */
|
||||
pixman_add_trapezoids (mask, - dst_x, - dst_y,
|
||||
num_traps, pixman_traps);
|
||||
(pixman_trapezoid_t *) traps, num_traps);
|
||||
|
||||
pixman_image_composite (_pixman_operator (op),
|
||||
src->pixman_image,
|
||||
mask,
|
||||
dst->pixman_image,
|
||||
src_x + attributes.x_offset,
|
||||
src_y + attributes.y_offset,
|
||||
0, 0,
|
||||
dst_x, dst_y,
|
||||
width, height);
|
||||
pixman_composite (_pixman_operator (op),
|
||||
src->pixman_image,
|
||||
mask,
|
||||
dst->pixman_image,
|
||||
src_x + attributes.x_offset,
|
||||
src_y + attributes.y_offset,
|
||||
0, 0,
|
||||
dst_x, dst_y,
|
||||
width, height);
|
||||
|
||||
if (!_cairo_operator_bounded_by_mask (op))
|
||||
status = _cairo_surface_composite_shape_fixup_unbounded (&dst->base,
|
||||
|
@ -1013,7 +1030,7 @@ _cairo_image_surface_composite_trapezoids (cairo_operator_t op,
|
|||
src_x, src_y,
|
||||
0, 0,
|
||||
dst_x, dst_y, width, height);
|
||||
pixman_image_unref (mask);
|
||||
pixman_image_destroy (mask);
|
||||
|
||||
CLEANUP_IMAGE_DATA:
|
||||
free (mask_data);
|
||||
|
@ -1021,23 +1038,16 @@ _cairo_image_surface_composite_trapezoids (cairo_operator_t op,
|
|||
CLEANUP_SOURCE:
|
||||
_cairo_pattern_release_surface (pattern, &src->base, &attributes);
|
||||
|
||||
finish:
|
||||
if (pixman_traps != stack_traps)
|
||||
free (pixman_traps);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
#undef STACK_TRAPS_LEN
|
||||
|
||||
cairo_int_status_t
|
||||
_cairo_image_surface_set_clip_region (void *abstract_surface,
|
||||
cairo_region_t *region)
|
||||
pixman_region16_t *region)
|
||||
{
|
||||
cairo_image_surface_t *surface = (cairo_image_surface_t *) abstract_surface;
|
||||
|
||||
if (!pixman_image_set_clip_region (surface->pixman_image, ®ion->rgn))
|
||||
return CAIRO_STATUS_NO_MEMORY;
|
||||
pixman_image_set_clip_region (surface->pixman_image, region);
|
||||
|
||||
surface->has_clip = region != NULL;
|
||||
|
||||
|
@ -1046,7 +1056,7 @@ _cairo_image_surface_set_clip_region (void *abstract_surface,
|
|||
|
||||
static cairo_int_status_t
|
||||
_cairo_image_surface_get_extents (void *abstract_surface,
|
||||
cairo_rectangle_int_t *rectangle)
|
||||
cairo_rectangle_int16_t *rectangle)
|
||||
{
|
||||
cairo_image_surface_t *surface = abstract_surface;
|
||||
|
||||
|
@ -1058,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
|
||||
|
@ -1111,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
|
||||
|
|
|
@ -35,6 +35,7 @@
|
|||
*/
|
||||
|
||||
#define _GNU_SOURCE
|
||||
#include <stdlib.h>
|
||||
|
||||
#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.
|
||||
**/
|
||||
|
@ -475,10 +476,6 @@ cairo_matrix_invert (cairo_matrix_t *matrix)
|
|||
if (det == 0)
|
||||
return CAIRO_STATUS_INVALID_MATRIX;
|
||||
|
||||
/* this weird construct is for detecting NaNs */
|
||||
if (! (det * det > 0.))
|
||||
return CAIRO_STATUS_INVALID_MATRIX;
|
||||
|
||||
_cairo_matrix_compute_adjoint (matrix);
|
||||
_cairo_matrix_scalar_multiply (matrix, 1 / det);
|
||||
|
||||
|
@ -499,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)
|
||||
{
|
||||
|
@ -539,6 +536,8 @@ _cairo_matrix_compute_scale_factors (const cairo_matrix_t *matrix,
|
|||
*sy = major;
|
||||
}
|
||||
}
|
||||
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
cairo_bool_t
|
||||
|
@ -736,13 +735,13 @@ _cairo_matrix_to_pixman_matrix (const cairo_matrix_t *matrix,
|
|||
*pixman_transform = pixman_identity_transform;
|
||||
}
|
||||
else {
|
||||
pixman_transform->matrix[0][0] = _cairo_fixed_16_16_from_double (matrix->xx);
|
||||
pixman_transform->matrix[0][1] = _cairo_fixed_16_16_from_double (matrix->xy);
|
||||
pixman_transform->matrix[0][2] = _cairo_fixed_16_16_from_double (matrix->x0);
|
||||
pixman_transform->matrix[0][0] = _cairo_fixed_from_double (matrix->xx);
|
||||
pixman_transform->matrix[0][1] = _cairo_fixed_from_double (matrix->xy);
|
||||
pixman_transform->matrix[0][2] = _cairo_fixed_from_double (matrix->x0);
|
||||
|
||||
pixman_transform->matrix[1][0] = _cairo_fixed_16_16_from_double (matrix->yx);
|
||||
pixman_transform->matrix[1][1] = _cairo_fixed_16_16_from_double (matrix->yy);
|
||||
pixman_transform->matrix[1][2] = _cairo_fixed_16_16_from_double (matrix->y0);
|
||||
pixman_transform->matrix[1][0] = _cairo_fixed_from_double (matrix->yx);
|
||||
pixman_transform->matrix[1][1] = _cairo_fixed_from_double (matrix->yy);
|
||||
pixman_transform->matrix[1][2] = _cairo_fixed_from_double (matrix->y0);
|
||||
|
||||
pixman_transform->matrix[2][0] = 0;
|
||||
pixman_transform->matrix[2][1] = 0;
|
||||
|
|
|
@ -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 =
|
||||
|
@ -439,7 +435,7 @@ _cairo_meta_surface_show_glyphs (void *abstract_surface,
|
|||
if (status)
|
||||
goto CLEANUP_COMMAND;
|
||||
|
||||
command->glyphs = _cairo_malloc_ab (num_glyphs, sizeof (cairo_glyph_t));
|
||||
command->glyphs = malloc (sizeof (cairo_glyph_t) * num_glyphs);
|
||||
if (command->glyphs == NULL) {
|
||||
status = CAIRO_STATUS_NO_MEMORY;
|
||||
goto CLEANUP_SOURCE;
|
||||
|
@ -556,7 +552,7 @@ _cairo_meta_surface_intersect_clip_path (void *dst,
|
|||
*/
|
||||
static cairo_int_status_t
|
||||
_cairo_meta_surface_get_extents (void *abstract_surface,
|
||||
cairo_rectangle_int_t *rectangle)
|
||||
cairo_rectangle_int16_t *rectangle)
|
||||
{
|
||||
cairo_meta_surface_t *surface = abstract_surface;
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -735,7 +726,7 @@ _cairo_meta_surface_replay (cairo_surface_t *surface,
|
|||
int i, num_glyphs = command->show_glyphs.num_glyphs;
|
||||
|
||||
if (has_device_transform) {
|
||||
dev_glyphs = _cairo_malloc_ab (num_glyphs, sizeof (cairo_glyph_t));
|
||||
dev_glyphs = malloc (sizeof (cairo_glyph_t) * num_glyphs);
|
||||
if (dev_glyphs == NULL) {
|
||||
status = CAIRO_STATUS_NO_MEMORY;
|
||||
break;
|
||||
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -35,12 +35,8 @@
|
|||
* Peter Weilbacher <mozilla@Weilbacher.org>
|
||||
*/
|
||||
|
||||
#include "cairoint.h"
|
||||
|
||||
#include "cairo-os2-private.h"
|
||||
|
||||
#include <fontconfig/fontconfig.h>
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <float.h>
|
||||
#ifdef BUILD_CAIRO_DLL
|
||||
# define INCL_WIN
|
||||
|
@ -53,6 +49,9 @@
|
|||
# include <emx/startup.h>
|
||||
# endif
|
||||
#endif
|
||||
#include "cairoint.h"
|
||||
#include "cairo-os2-private.h"
|
||||
#include "fontconfig/fontconfig.h"
|
||||
|
||||
/*
|
||||
* Here comes the extra API for the OS/2 platform. Currently it consists
|
||||
|
@ -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 ();
|
||||
|
@ -296,9 +334,8 @@ _cairo_os2_surface_blit_pixels (cairo_os2_surface_t *surface,
|
|||
ULONG ulPixels;
|
||||
|
||||
/* allocate temporary pixel buffer */
|
||||
pchPixBuf = (unsigned char *) _cairo_malloc_abc (surface->bitmap_info.cy,
|
||||
surface->bitmap_info.cx,
|
||||
3);
|
||||
pchPixBuf = (unsigned char *) malloc (3 * surface->bitmap_info.cx *
|
||||
surface->bitmap_info.cy);
|
||||
pchPixSource = surface->pixels; /* start at beginning of pixel buffer */
|
||||
pBufStart = pchPixBuf; /* remember beginning of the new pixel buffer */
|
||||
|
||||
|
@ -517,9 +554,9 @@ _cairo_os2_surface_release_source_image (void *abstract_surface
|
|||
|
||||
static cairo_status_t
|
||||
_cairo_os2_surface_acquire_dest_image (void *abstract_surface,
|
||||
cairo_rectangle_int_t *interest_rect,
|
||||
cairo_rectangle_int16_t *interest_rect,
|
||||
cairo_image_surface_t **image_out,
|
||||
cairo_rectangle_int_t *image_rect,
|
||||
cairo_rectangle_int16_t *image_rect,
|
||||
void **image_extra)
|
||||
{
|
||||
cairo_os2_surface_t *local_os2_surface;
|
||||
|
@ -552,9 +589,9 @@ _cairo_os2_surface_acquire_dest_image (void *abstract_surfac
|
|||
|
||||
static void
|
||||
_cairo_os2_surface_release_dest_image (void *abstract_surface,
|
||||
cairo_rectangle_int_t *interest_rect,
|
||||
cairo_rectangle_int16_t *interest_rect,
|
||||
cairo_image_surface_t *image,
|
||||
cairo_rectangle_int_t *image_rect,
|
||||
cairo_rectangle_int16_t *image_rect,
|
||||
void *image_extra)
|
||||
{
|
||||
cairo_os2_surface_t *local_os2_surface;
|
||||
|
@ -628,7 +665,7 @@ _cairo_os2_surface_release_dest_image (void *abstract_surface
|
|||
|
||||
static cairo_int_status_t
|
||||
_cairo_os2_surface_get_extents (void *abstract_surface,
|
||||
cairo_rectangle_int_t *rectangle)
|
||||
cairo_rectangle_int16_t *rectangle)
|
||||
{
|
||||
cairo_os2_surface_t *local_os2_surface;
|
||||
|
||||
|
@ -714,7 +751,7 @@ cairo_os2_surface_create (HPS hps_client_window,
|
|||
local_os2_surface->bitmap_info.cBitCount = 32;
|
||||
|
||||
/* Allocate memory for pixels */
|
||||
local_os2_surface->pixels = (unsigned char *) _cairo_malloc_abc (height, width, 4);
|
||||
local_os2_surface->pixels = (unsigned char *) malloc (width * height * 4);
|
||||
if (!(local_os2_surface->pixels)) {
|
||||
/* Not enough memory for the pixels! */
|
||||
DosCloseEventSem (local_os2_surface->hev_pixel_array_came_back);
|
||||
|
@ -784,7 +821,7 @@ cairo_os2_surface_set_size (cairo_surface_t *surface,
|
|||
}
|
||||
|
||||
/* Allocate memory for new stuffs */
|
||||
pchNewPixels = (unsigned char *) _cairo_malloc_abc (new_height, new_width, 4);
|
||||
pchNewPixels = (unsigned char *) malloc (new_width * new_height * 4);
|
||||
if (!pchNewPixels) {
|
||||
/* Not enough memory for the pixels!
|
||||
* Everything remains the same!
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -34,12 +34,11 @@
|
|||
* Kristian Høgsberg <krh@redhat.com>
|
||||
*/
|
||||
|
||||
#include "cairoint.h"
|
||||
|
||||
#include "cairo-output-stream-private.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <locale.h>
|
||||
#include <ctype.h>
|
||||
#include "cairoint.h"
|
||||
#include "cairo-output-stream-private.h"
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#define snprintf _snprintf
|
||||
|
@ -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 <krh@redhat.com>
|
||||
*/
|
||||
void
|
||||
|
||||
int
|
||||
_cairo_dtostr (char *buffer, size_t size, double d)
|
||||
{
|
||||
struct lconv *locale_data;
|
||||
const char *decimal_point;
|
||||
int decimal_point_len;
|
||||
char *p;
|
||||
int decimal_len;
|
||||
struct lconv *locale_data;
|
||||
const char *decimal_point;
|
||||
int decimal_point_len;
|
||||
char *p;
|
||||
int decimal_len;
|
||||
|
||||
/* Omit the minus sign from negative zero. */
|
||||
if (d == 0.0)
|
||||
d = 0.0;
|
||||
/* Omit the minus sign from negative zero. */
|
||||
if (d == 0.0)
|
||||
d = 0.0;
|
||||
|
||||
snprintf (buffer, size, "%f", d);
|
||||
snprintf (buffer, size, "%f", d);
|
||||
|
||||
locale_data = localeconv ();
|
||||
decimal_point = locale_data->decimal_point;
|
||||
decimal_point_len = strlen (decimal_point);
|
||||
locale_data = localeconv ();
|
||||
decimal_point = locale_data->decimal_point;
|
||||
decimal_point_len = strlen (decimal_point);
|
||||
|
||||
assert (decimal_point_len != 0);
|
||||
p = buffer;
|
||||
assert (decimal_point_len != 0);
|
||||
p = buffer;
|
||||
|
||||
if (*p == '+' || *p == '-')
|
||||
p++;
|
||||
if (*p == '+' || *p == '-')
|
||||
p++;
|
||||
|
||||
while (isdigit (*p))
|
||||
p++;
|
||||
while (isdigit (*p))
|
||||
p++;
|
||||
|
||||
if (strncmp (p, decimal_point, decimal_point_len) == 0) {
|
||||
*p = '.';
|
||||
decimal_len = strlen (p + decimal_point_len);
|
||||
memmove (p + 1, p + decimal_point_len, decimal_len);
|
||||
p[1 + decimal_len] = 0;
|
||||
if (strncmp (p, decimal_point, decimal_point_len) == 0) {
|
||||
*p = '.';
|
||||
decimal_len = strlen (p + decimal_point_len);
|
||||
memmove (p + 1, p + decimal_point_len, decimal_len);
|
||||
p[1 + decimal_len] = 0;
|
||||
|
||||
/* Remove trailing zeros and decimal point if possible. */
|
||||
for (p = p + decimal_len; *p == '0'; p--)
|
||||
*p = 0;
|
||||
/* Remove trailing zeros and decimal point if possible. */
|
||||
for (p = p + decimal_len; *p == '0'; p--)
|
||||
*p = 0;
|
||||
|
||||
if (*p == '.') {
|
||||
*p = 0;
|
||||
p--;
|
||||
}
|
||||
}
|
||||
if (*p == '.') {
|
||||
*p = 0;
|
||||
p--;
|
||||
}
|
||||
}
|
||||
|
||||
return p + 1 - buffer;
|
||||
}
|
||||
|
||||
enum {
|
||||
|
@ -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);
|
||||
|
|
|
@ -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_<foo>_surface_create. The paginated backend will be careful
|
||||
* to not let the user see that they really got a "wrapped"
|
||||
* surface. See test-paginated-surface.c for a fairly minimal example
|
||||
* of a paginated-using surface. That should be a reasonable example
|
||||
* to follow.
|
||||
*
|
||||
* What the paginated surface does is first save all drawing
|
||||
* operations for a page into a meta-surface. Then when the user calls
|
||||
* cairo_show_page, the paginated surface performs the following
|
||||
* sequence of operations (using the backend functions passed to
|
||||
* cairo_paginated_surface_create):
|
||||
*
|
||||
* 1. Calls start_page (if non NULL). At this point, it is appropriate
|
||||
* for the target to emit any page-specific header information into
|
||||
* its output.
|
||||
*
|
||||
* 2. Calls set_paginated_mode with an argument of CAIRO_PAGINATED_MODE_ANALYZE
|
||||
*
|
||||
* 3. Replays the meta-surface to the target surface, (with an
|
||||
* analysis surface inserted between which watches the return value
|
||||
* from each operation). This analysis stage is used to decide which
|
||||
* operations will require fallbacks.
|
||||
*
|
||||
* 4. Calls set_paginated_mode with an argument of CAIRO_PAGINATED_MODE_RENDER
|
||||
*
|
||||
* 5. Replays a subset of the meta-surface operations to the target surface
|
||||
*
|
||||
* 6. Replays the remaining operations to an image surface, sets an
|
||||
* appropriate clip on the target, then paints the resulting image
|
||||
* surface to the target.
|
||||
*
|
||||
* So, the target will see drawing operations during two separate
|
||||
* stages, (ANALYZE and RENDER). During the ANALYZE phase the target
|
||||
* should not actually perform any rendering, (for example, if
|
||||
* performing output to a file, no output should be generated during
|
||||
* this stage). Instead the drawing functions simply need to return
|
||||
* CAIRO_STATUS_SUCCESS or CAIRO_INT_STATUS_UNSUPPORTED to indicate
|
||||
* whether rendering would be supported. And it should do this as
|
||||
* quickly as possible.
|
||||
*
|
||||
* NOTE: The paginated surface layer assumes that the target surface
|
||||
* is "blank" by default at the beginning of each page, without any
|
||||
* need for an explicit erasea operation, (as opposed to an image
|
||||
* surface, for example, which might have uninitialized content
|
||||
* originally). As such, it optimizes away CLEAR operations that
|
||||
* happen at the beginning of each page---the target surface will not
|
||||
* even see these operations.
|
||||
*/
|
||||
cairo_private cairo_surface_t *
|
||||
_cairo_paginated_surface_create (cairo_surface_t *target,
|
||||
cairo_content_t content,
|
||||
int width,
|
||||
int height,
|
||||
const cairo_paginated_surface_backend_t *backend);
|
||||
|
||||
/* 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 */
|
||||
|
|
|
@ -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_int_t extents;
|
||||
cairo_rectangle_int16_t extents;
|
||||
|
||||
status = _cairo_surface_get_extents (surface->target, &extents);
|
||||
if (status)
|
||||
return status;
|
||||
_cairo_surface_get_extents (surface->target, &extents);
|
||||
|
||||
image = _cairo_paginated_surface_create_image_surface (surface,
|
||||
extents.width,
|
||||
extents.height);
|
||||
|
||||
status = _cairo_meta_surface_replay (surface->meta, image);
|
||||
if (status) {
|
||||
cairo_surface_destroy (image);
|
||||
return status;
|
||||
}
|
||||
_cairo_meta_surface_replay (surface->meta, image);
|
||||
|
||||
*image_out = (cairo_image_surface_t*) image;
|
||||
*image_extra = NULL;
|
||||
|
@ -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);
|
||||
|
||||
|
@ -354,7 +356,7 @@ _cairo_paginated_surface_intersect_clip_path (void *abstract_surface,
|
|||
|
||||
static cairo_int_status_t
|
||||
_cairo_paginated_surface_get_extents (void *abstract_surface,
|
||||
cairo_rectangle_int_t *rectangle)
|
||||
cairo_rectangle_int16_t *rectangle)
|
||||
{
|
||||
cairo_paginated_surface_t *surface = abstract_surface;
|
||||
|
||||
|
@ -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
|
||||
|
@ -501,22 +502,16 @@ _cairo_paginated_surface_snapshot (void *abstract_other)
|
|||
#if 0
|
||||
return _cairo_surface_snapshot (other->meta);
|
||||
#else
|
||||
cairo_rectangle_int_t extents;
|
||||
cairo_rectangle_int16_t extents;
|
||||
cairo_surface_t *surface;
|
||||
|
||||
status = _cairo_surface_get_extents (other->target, &extents);
|
||||
if (status)
|
||||
return (cairo_surface_t*) &_cairo_surface_nil;
|
||||
_cairo_surface_get_extents (other->target, &extents);
|
||||
|
||||
surface = _cairo_paginated_surface_create_image_surface (other,
|
||||
extents.width,
|
||||
extents.height);
|
||||
|
||||
status = _cairo_meta_surface_replay (other->meta, surface);
|
||||
if (status) {
|
||||
cairo_surface_destroy (surface);
|
||||
surface = (cairo_surface_t*) &_cairo_surface_nil;
|
||||
}
|
||||
_cairo_meta_surface_replay (other->meta, surface);
|
||||
|
||||
return surface;
|
||||
#endif
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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 © 2002 University of Southern California
|
||||
|
@ -36,6 +35,7 @@
|
|||
* Carl D. Worth <cworth@cworth.org>
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include "cairoint.h"
|
||||
|
||||
#include "cairo-path-fixed-private.h"
|
||||
|
@ -356,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;
|
||||
|
||||
|
@ -510,19 +510,25 @@ _cairo_path_fixed_offset_and_scale (cairo_path_fixed_t *path,
|
|||
{
|
||||
cairo_path_buf_t *buf = path->buf_head;
|
||||
int i;
|
||||
cairo_int64_t i64temp;
|
||||
cairo_fixed_t fixedtemp;
|
||||
|
||||
while (buf) {
|
||||
for (i = 0; i < buf->num_points; i++) {
|
||||
if (scalex == CAIRO_FIXED_ONE) {
|
||||
buf->points[i].x += offx;
|
||||
} else {
|
||||
buf->points[i].x = _cairo_fixed_mul (buf->points[i].x + offx, scalex);
|
||||
fixedtemp = buf->points[i].x + offx;
|
||||
i64temp = _cairo_int32x32_64_mul (fixedtemp, scalex);
|
||||
buf->points[i].x = _cairo_int64_to_int32(_cairo_int64_rsl (i64temp, 16));
|
||||
}
|
||||
|
||||
if (scaley == CAIRO_FIXED_ONE) {
|
||||
buf->points[i].y += offy;
|
||||
} else {
|
||||
buf->points[i].y = _cairo_fixed_mul (buf->points[i].y + offy, scaley);
|
||||
fixedtemp = buf->points[i].y + offy;
|
||||
i64temp = _cairo_int32x32_64_mul (fixedtemp, scaley);
|
||||
buf->points[i].y = _cairo_int64_to_int32(_cairo_int64_rsl (i64temp, 16));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -34,10 +34,9 @@
|
|||
* Carl D. Worth <cworth@redhat.com>
|
||||
*/
|
||||
|
||||
#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,21 +360,18 @@ _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 = _cairo_malloc_ab (path->num_data, sizeof (cairo_path_data_t));
|
||||
path->data = malloc (path->num_data * sizeof (cairo_path_data_t));
|
||||
if (path->data == NULL) {
|
||||
free (path);
|
||||
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;
|
||||
|
|
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
|
@ -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
|
||||
|
@ -78,7 +80,7 @@ _cairo_pen_init (cairo_pen_t *pen,
|
|||
radius,
|
||||
ctm);
|
||||
|
||||
pen->vertices = _cairo_malloc_ab (pen->num_vertices, sizeof (cairo_pen_vertex_t));
|
||||
pen->vertices = malloc (pen->num_vertices * sizeof (cairo_pen_vertex_t));
|
||||
if (pen->vertices == NULL) {
|
||||
return CAIRO_STATUS_NO_MEMORY;
|
||||
}
|
||||
|
@ -119,7 +121,7 @@ _cairo_pen_init_copy (cairo_pen_t *pen, cairo_pen_t *other)
|
|||
*pen = *other;
|
||||
|
||||
if (pen->num_vertices) {
|
||||
pen->vertices = _cairo_malloc_ab (pen->num_vertices, sizeof (cairo_pen_vertex_t));
|
||||
pen->vertices = malloc (pen->num_vertices * sizeof (cairo_pen_vertex_t));
|
||||
if (pen->vertices == NULL) {
|
||||
return CAIRO_STATUS_NO_MEMORY;
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -35,9 +35,8 @@
|
|||
* Kristian Høgsberg <krh@redhat.com>
|
||||
*/
|
||||
|
||||
#include "cairoint.h"
|
||||
|
||||
#include <errno.h>
|
||||
#include "cairoint.h"
|
||||
#include <png.h>
|
||||
|
||||
/* 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,
|
||||
|
@ -128,7 +108,7 @@ write_png (cairo_surface_t *surface,
|
|||
else if (status != CAIRO_STATUS_SUCCESS)
|
||||
return CAIRO_STATUS_SURFACE_TYPE_MISMATCH;
|
||||
|
||||
rows = _cairo_malloc_ab (image->height, sizeof(png_byte*));
|
||||
rows = malloc (image->height * sizeof(png_byte*));
|
||||
if (rows == NULL) {
|
||||
status = CAIRO_STATUS_NO_MEMORY;
|
||||
goto BAIL1;
|
||||
|
@ -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);
|
||||
|
@ -429,11 +399,11 @@ read_png (png_rw_ptr read_func,
|
|||
png_read_update_info (png, info);
|
||||
|
||||
pixel_size = 4;
|
||||
data = _cairo_malloc_abc (png_height, png_width, pixel_size);
|
||||
data = malloc (png_width * png_height * pixel_size);
|
||||
if (data == NULL)
|
||||
goto BAIL;
|
||||
|
||||
row_pointers = _cairo_malloc_ab (png_height, sizeof(char *));
|
||||
row_pointers = malloc (png_height * sizeof(char *));
|
||||
if (row_pointers == NULL)
|
||||
goto BAIL;
|
||||
|
||||
|
@ -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");
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -34,6 +34,7 @@
|
|||
* Carl D. Worth <cworth@cworth.org>
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#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
|
||||
|
@ -93,7 +86,7 @@ _cairo_polygon_grow (cairo_polygon_t *polygon)
|
|||
assert (polygon->num_edges <= polygon->edges_size);
|
||||
|
||||
if (polygon->edges == polygon->edges_embedded) {
|
||||
new_edges = _cairo_malloc_ab (new_size, sizeof (cairo_edge_t));
|
||||
new_edges = malloc (new_size * sizeof (cairo_edge_t));
|
||||
if (new_edges)
|
||||
memcpy (new_edges, polygon->edges, old_size * sizeof (cairo_edge_t));
|
||||
} else {
|
||||
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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.
|
||||
*
|
||||
* <note>
|
||||
* This function is <emphasis>only</emphasis> intended for internal
|
||||
* testing use within the cairo distribution. It is not installed in
|
||||
* any public header file.
|
||||
* </note>
|
||||
**/
|
||||
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;
|
||||
|
@ -1583,7 +1619,7 @@ _cairo_ps_surface_emit_image (cairo_ps_surface_t *surface,
|
|||
|
||||
i = 0;
|
||||
for (y = 0; y < opaque_image->height; y++) {
|
||||
uint32_t *pixel = (uint32_t *) (opaque_image->data + y * opaque_image->stride);
|
||||
pixman_bits_t *pixel = (pixman_bits_t *) (opaque_image->data + y * opaque_image->stride);
|
||||
for (x = 0; x < opaque_image->width; x++, pixel++) {
|
||||
rgb[i++] = (*pixel & 0x00ff0000) >> 16;
|
||||
rgb[i++] = (*pixel & 0x0000ff00) >> 8;
|
||||
|
@ -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
|
||||
|
@ -1878,7 +1894,7 @@ _cairo_ps_surface_intersect_clip_path (void *abstract_surface,
|
|||
|
||||
static cairo_int_status_t
|
||||
_cairo_ps_surface_get_extents (void *abstract_surface,
|
||||
cairo_rectangle_int_t *rectangle)
|
||||
cairo_rectangle_int16_t *rectangle)
|
||||
{
|
||||
cairo_ps_surface_t *surface = abstract_surface;
|
||||
|
||||
|
@ -1913,8 +1929,7 @@ _cairo_ps_surface_paint (void *abstract_surface,
|
|||
{
|
||||
cairo_ps_surface_t *surface = abstract_surface;
|
||||
cairo_output_stream_t *stream = surface->stream;
|
||||
cairo_rectangle_int_t extents, pattern_extents;
|
||||
cairo_status_t status;
|
||||
cairo_rectangle_int16_t extents, pattern_extents;
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
|
@ -2037,7 +2043,7 @@ _cairo_ps_surface_stroke (void *abstract_surface,
|
|||
* can modify some of the values.
|
||||
*/
|
||||
if (num_dashes % 2) {
|
||||
dash = _cairo_malloc_abc (num_dashes, 2, sizeof (double));
|
||||
dash = malloc (2 * num_dashes * sizeof (double));
|
||||
if (dash == NULL)
|
||||
return CAIRO_STATUS_NO_MEMORY;
|
||||
|
||||
|
@ -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;
|
||||
|
@ -2215,18 +2221,18 @@ _cairo_ps_surface_show_glyphs (void *abstract_surface,
|
|||
num_glyphs_unsigned = num_glyphs;
|
||||
|
||||
_cairo_ps_surface_emit_pattern (surface, source);
|
||||
glyph_ids = _cairo_malloc_ab (num_glyphs_unsigned, sizeof (cairo_ps_glyph_id_t));
|
||||
glyph_ids = malloc (num_glyphs_unsigned*sizeof (cairo_ps_glyph_id_t));
|
||||
if (glyph_ids == NULL)
|
||||
return CAIRO_STATUS_NO_MEMORY;
|
||||
|
||||
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,
|
||||
|
|
|
@ -51,16 +51,13 @@ typedef struct cairo_quartz_surface {
|
|||
CGContextRef cgContext;
|
||||
CGAffineTransform cgContextBaseCTM;
|
||||
|
||||
cairo_rectangle_int_t extents;
|
||||
cairo_rectangle_int16_t extents;
|
||||
|
||||
/* 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;
|
||||
|
|
|
@ -34,12 +34,12 @@
|
|||
* Vladimir Vukicevic <vladimir@mozilla.com>
|
||||
*/
|
||||
|
||||
#include <Carbon/Carbon.h>
|
||||
|
||||
#include "cairoint.h"
|
||||
|
||||
#include "cairo-quartz-private.h"
|
||||
|
||||
#include <Carbon/Carbon.h>
|
||||
|
||||
#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;
|
||||
|
@ -282,7 +301,7 @@ static void
|
|||
ComputeGradientValue (void *info, const float *in, float *out)
|
||||
{
|
||||
float fdist = *in; /* 0.0 .. 1.0 */
|
||||
cairo_fixed_t fdist_fix = _cairo_fixed_from_double(*in);
|
||||
cairo_fixed_16_16_t fdist_fix = _cairo_fixed_from_double(*in);
|
||||
cairo_gradient_pattern_t *grad = (cairo_gradient_pattern_t*) info;
|
||||
unsigned int i;
|
||||
|
||||
|
@ -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;
|
||||
|
@ -374,10 +386,10 @@ _cairo_quartz_cairo_gradient_pattern_to_quartz (cairo_pattern_t *abspat)
|
|||
CGFunctionRef gradFunc;
|
||||
CGColorSpaceRef rgb = CGColorSpaceCreateDeviceRGB();
|
||||
|
||||
start = CGPointMake (_cairo_fixed_to_double (lpat->p1.x) - x0,
|
||||
_cairo_fixed_to_double (lpat->p1.y) - y0);
|
||||
end = CGPointMake (_cairo_fixed_to_double (lpat->p2.x) - x0,
|
||||
_cairo_fixed_to_double (lpat->p2.y) - y0);
|
||||
start = CGPointMake (_cairo_fixed_to_double (lpat->gradient.p1.x) - x0,
|
||||
_cairo_fixed_to_double (lpat->gradient.p1.y) - y0);
|
||||
end = CGPointMake (_cairo_fixed_to_double (lpat->gradient.p2.x) - x0,
|
||||
_cairo_fixed_to_double (lpat->gradient.p2.y) - y0);
|
||||
|
||||
cairo_pattern_reference (abspat);
|
||||
gradFunc = CreateGradientFunction ((cairo_gradient_pattern_t*) lpat);
|
||||
|
@ -398,18 +410,18 @@ _cairo_quartz_cairo_gradient_pattern_to_quartz (cairo_pattern_t *abspat)
|
|||
CGFunctionRef gradFunc;
|
||||
CGColorSpaceRef rgb = CGColorSpaceCreateDeviceRGB();
|
||||
|
||||
start = CGPointMake (_cairo_fixed_to_double (rpat->c1.x) - x0,
|
||||
_cairo_fixed_to_double (rpat->c1.y) - y0);
|
||||
end = CGPointMake (_cairo_fixed_to_double (rpat->c2.x) - x0,
|
||||
_cairo_fixed_to_double (rpat->c2.y) - y0);
|
||||
start = CGPointMake (_cairo_fixed_to_double (rpat->gradient.c1.x) - x0,
|
||||
_cairo_fixed_to_double (rpat->gradient.c1.y) - y0);
|
||||
end = CGPointMake (_cairo_fixed_to_double (rpat->gradient.c2.x) - x0,
|
||||
_cairo_fixed_to_double (rpat->gradient.c2.y) - y0);
|
||||
|
||||
cairo_pattern_reference (abspat);
|
||||
gradFunc = CreateGradientFunction ((cairo_gradient_pattern_t*) rpat);
|
||||
shading = CGShadingCreateRadial (rgb,
|
||||
start,
|
||||
_cairo_fixed_to_double (rpat->r1),
|
||||
_cairo_fixed_to_double (rpat->gradient.c1.radius),
|
||||
end,
|
||||
_cairo_fixed_to_double (rpat->r2),
|
||||
_cairo_fixed_to_double (rpat->gradient.c2.radius),
|
||||
gradFunc,
|
||||
true, true);
|
||||
CGColorSpaceRelease(rgb);
|
||||
|
@ -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_int_t rect;
|
||||
if (ref_type == NULL)
|
||||
ref_type = cairo_quartz_surface_create (CAIRO_FORMAT_ARGB32, 1, 1);
|
||||
cairo_rectangle_int16_t rect;
|
||||
|
||||
_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 =
|
||||
|
@ -545,7 +539,7 @@ _cairo_quartz_cairo_repeating_surface_pattern_to_quartz (cairo_quartz_surface_t
|
|||
{
|
||||
cairo_surface_pattern_t *spat;
|
||||
cairo_surface_t *pat_surf;
|
||||
cairo_rectangle_int_t extents;
|
||||
cairo_rectangle_int16_t extents;
|
||||
|
||||
CGRect pbounds;
|
||||
CGAffineTransform ptransform, stransform;
|
||||
|
@ -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_int_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,21 +865,12 @@ _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_int_t *interest_rect,
|
||||
cairo_image_surface_t **image_out,
|
||||
cairo_rectangle_int_t *image_rect,
|
||||
void **image_extra)
|
||||
cairo_rectangle_int16_t *interest_rect,
|
||||
cairo_image_surface_t **image_out,
|
||||
cairo_rectangle_int16_t *image_rect,
|
||||
void **image_extra)
|
||||
{
|
||||
cairo_quartz_surface_t *surface = (cairo_quartz_surface_t *) abstract_surface;
|
||||
cairo_int_status_t status;
|
||||
|
@ -920,10 +891,10 @@ _cairo_quartz_surface_acquire_dest_image (void *abstract_surface,
|
|||
|
||||
static void
|
||||
_cairo_quartz_surface_release_dest_image (void *abstract_surface,
|
||||
cairo_rectangle_int_t *interest_rect,
|
||||
cairo_image_surface_t *image,
|
||||
cairo_rectangle_int_t *image_rect,
|
||||
void *image_extra)
|
||||
cairo_rectangle_int16_t *interest_rect,
|
||||
cairo_image_surface_t *image,
|
||||
cairo_rectangle_int16_t *image_rect,
|
||||
void *image_extra)
|
||||
{
|
||||
cairo_quartz_surface_t *surface = (cairo_quartz_surface_t *) abstract_surface;
|
||||
unsigned char *imageData = (unsigned char *) image_extra;
|
||||
|
@ -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;
|
||||
|
||||
|
@ -1080,7 +1052,7 @@ _cairo_quartz_surface_clone_similar (void *abstract_surface,
|
|||
|
||||
static cairo_int_status_t
|
||||
_cairo_quartz_surface_get_extents (void *abstract_surface,
|
||||
cairo_rectangle_int_t *extents)
|
||||
cairo_rectangle_int16_t *extents)
|
||||
{
|
||||
cairo_quartz_surface_t *surface = (cairo_quartz_surface_t *) abstract_surface;
|
||||
|
||||
|
@ -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
|
||||
|
@ -1255,7 +1191,7 @@ _cairo_quartz_surface_stroke (void *abstract_surface,
|
|||
float *fdash = sdash;
|
||||
unsigned int k;
|
||||
if (style->num_dashes > STATIC_DASH)
|
||||
fdash = _cairo_malloc_ab (style->num_dashes, sizeof (float));
|
||||
fdash = malloc (sizeof(float)*style->num_dashes);
|
||||
|
||||
for (k = 0; k < style->num_dashes; k++)
|
||||
fdash[k] = (float) style->dash[k];
|
||||
|
@ -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*) _cairo_malloc_ab (num_glyphs, sizeof(CGGlyph));
|
||||
cg_advances = (CGSize*) _cairo_malloc_ab (num_glyphs, sizeof(CGSize));
|
||||
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,
|
||||
|
@ -1711,7 +1632,7 @@ cairo_quartz_surface_create (cairo_format_t format,
|
|||
return (cairo_surface_t*) &_cairo_surface_nil;
|
||||
}
|
||||
|
||||
imageData = _cairo_malloc_ab (height, stride);
|
||||
imageData = malloc (height * stride);
|
||||
if (!imageData) {
|
||||
CGColorSpaceRelease (cgColorspace);
|
||||
_cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
|
|
|
@ -41,19 +41,19 @@
|
|||
/* XXX We currently have a confusing mix of boxes and rectangles as
|
||||
* exemplified by this function. A cairo_box_t is a rectangular area
|
||||
* represented by the coordinates of the upper left and lower right
|
||||
* corners, expressed in fixed point numbers. A cairo_rectangle_int_t is
|
||||
* corners, expressed in fixed point numbers. A cairo_rectangle_int16_t is
|
||||
* also a rectangular area, but represented by the upper left corner
|
||||
* and the width and the height, as integer numbers.
|
||||
*
|
||||
* This function converts a cairo_box_t to a cairo_rectangle_int_t by
|
||||
* This function converts a cairo_box_t to a cairo_rectangle_int16_t by
|
||||
* increasing the area to the nearest integer coordinates. We should
|
||||
* standardize on cairo_rectangle_fixed_t and cairo_rectangle_int_t, and
|
||||
* standardize on cairo_rectangle_int16_t and cairo_rectangle_int16_t, and
|
||||
* this function could be renamed to the more reasonable
|
||||
* _cairo_rectangle_fixed_round.
|
||||
*/
|
||||
|
||||
void
|
||||
_cairo_box_round_to_rectangle (cairo_box_t *box, cairo_rectangle_int_t *rectangle)
|
||||
_cairo_box_round_to_rectangle (cairo_box_t *box, cairo_rectangle_int16_t *rectangle)
|
||||
{
|
||||
rectangle->x = _cairo_fixed_integer_floor (box->p1.x);
|
||||
rectangle->y = _cairo_fixed_integer_floor (box->p1.y);
|
||||
|
@ -62,7 +62,7 @@ _cairo_box_round_to_rectangle (cairo_box_t *box, cairo_rectangle_int_t *rectangl
|
|||
}
|
||||
|
||||
void
|
||||
_cairo_rectangle_intersect (cairo_rectangle_int_t *dest, cairo_rectangle_int_t *src)
|
||||
_cairo_rectangle_intersect (cairo_rectangle_int16_t *dest, cairo_rectangle_int16_t *src)
|
||||
{
|
||||
int x1, y1, x2, y2;
|
||||
|
||||
|
|
|
@ -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.
|
||||
|
@ -32,178 +31,52 @@
|
|||
*
|
||||
* Contributor(s):
|
||||
* Owen Taylor <otaylor@redhat.com>
|
||||
* Vladimir Vukicevic <vladimir@pobox.com>
|
||||
*/
|
||||
|
||||
#include "cairoint.h"
|
||||
#include <cairoint.h>
|
||||
|
||||
void
|
||||
_cairo_region_init (cairo_region_t *region)
|
||||
/**
|
||||
* _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)
|
||||
{
|
||||
pixman_region_init (®ion->rgn);
|
||||
}
|
||||
|
||||
void
|
||||
_cairo_region_init_rect (cairo_region_t *region,
|
||||
cairo_rectangle_int_t *rect)
|
||||
{
|
||||
pixman_region_init_rect (®ion->rgn,
|
||||
rect->x, rect->y,
|
||||
rect->width, rect->height);
|
||||
}
|
||||
|
||||
#define STACK_BOXES_LEN ((int) (CAIRO_STACK_BUFFER_SIZE / sizeof(pixman_box16_t)))
|
||||
|
||||
cairo_int_status_t
|
||||
_cairo_region_init_boxes (cairo_region_t *region,
|
||||
cairo_box_int_t *boxes,
|
||||
int count)
|
||||
{
|
||||
pixman_box16_t stack_pboxes[STACK_BOXES_LEN];
|
||||
pixman_box16_t *pboxes = stack_pboxes;
|
||||
cairo_int_status_t status = CAIRO_STATUS_SUCCESS;
|
||||
int i;
|
||||
|
||||
if (count > ARRAY_LENGTH(stack_pboxes)) {
|
||||
pboxes = _cairo_malloc_ab (count, sizeof(pixman_box16_t));
|
||||
if (pboxes == NULL)
|
||||
return CAIRO_STATUS_NO_MEMORY;
|
||||
/* 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;
|
||||
}
|
||||
|
||||
for (i = 0; i < count; i++) {
|
||||
pboxes[i].x1 = boxes[i].p1.x;
|
||||
pboxes[i].y1 = boxes[i].p1.y;
|
||||
pboxes[i].x2 = boxes[i].p2.x;
|
||||
pboxes[i].y2 = boxes[i].p2.y;
|
||||
}
|
||||
|
||||
if (!pixman_region_init_rects (®ion->rgn, pboxes, count))
|
||||
status = CAIRO_STATUS_NO_MEMORY;
|
||||
|
||||
if (pboxes != stack_pboxes)
|
||||
free (pboxes);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
void
|
||||
_cairo_region_fini (cairo_region_t *region)
|
||||
{
|
||||
pixman_region_fini (®ion->rgn);
|
||||
}
|
||||
|
||||
cairo_int_status_t
|
||||
_cairo_region_copy (cairo_region_t *dst, cairo_region_t *src)
|
||||
{
|
||||
if (!pixman_region_copy (&dst->rgn, &src->rgn))
|
||||
return CAIRO_STATUS_NO_MEMORY;
|
||||
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
int
|
||||
_cairo_region_num_boxes (cairo_region_t *region)
|
||||
{
|
||||
return pixman_region_n_rects (®ion->rgn);
|
||||
}
|
||||
|
||||
cairo_int_status_t
|
||||
_cairo_region_get_boxes (cairo_region_t *region, int *num_boxes, cairo_box_int_t **boxes)
|
||||
{
|
||||
int nboxes;
|
||||
pixman_box16_t *pboxes;
|
||||
cairo_box_int_t *cboxes;
|
||||
int i;
|
||||
|
||||
pboxes = pixman_region_rectangles (®ion->rgn, &nboxes);
|
||||
|
||||
if (nboxes == 0) {
|
||||
*num_boxes = 0;
|
||||
*boxes = NULL;
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
cboxes = _cairo_malloc_ab (nboxes, sizeof(cairo_box_int_t));
|
||||
if (cboxes == NULL)
|
||||
return CAIRO_STATUS_NO_MEMORY;
|
||||
|
||||
for (i = 0; i < nboxes; i++) {
|
||||
cboxes[i].p1.x = pboxes[i].x1;
|
||||
cboxes[i].p1.y = pboxes[i].y1;
|
||||
cboxes[i].p2.x = pboxes[i].x2;
|
||||
cboxes[i].p2.y = pboxes[i].y2;
|
||||
}
|
||||
|
||||
*num_boxes = nboxes;
|
||||
*boxes = cboxes;
|
||||
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
void
|
||||
_cairo_region_boxes_fini (cairo_region_t *region, cairo_box_int_t *boxes)
|
||||
{
|
||||
free (boxes);
|
||||
return region;
|
||||
}
|
||||
|
||||
/**
|
||||
* _cairo_region_get_extents:
|
||||
* @region: a #cairo_region_t
|
||||
* _cairo_region_extents_rectangle:
|
||||
* @region: a #pixman_region16_t
|
||||
* @rect: rectangle into which to store the extents
|
||||
*
|
||||
* Gets the bounding box of a region as a cairo_rectangle_int_t
|
||||
* Gets the bounding box of a region as a cairo_rectangle_int16_t
|
||||
**/
|
||||
void
|
||||
_cairo_region_get_extents (cairo_region_t *region, cairo_rectangle_int_t *extents)
|
||||
_cairo_region_extents_rectangle (pixman_region16_t *region,
|
||||
cairo_rectangle_int16_t *rect)
|
||||
{
|
||||
pixman_box16_t *pextents = pixman_region_extents (®ion->rgn);
|
||||
pixman_box16_t *region_extents = pixman_region_extents (region);
|
||||
|
||||
extents->x = pextents->x1;
|
||||
extents->y = pextents->y1;
|
||||
extents->width = pextents->x2 - pextents->x1;
|
||||
extents->height = pextents->y2 - pextents->y1;
|
||||
}
|
||||
|
||||
cairo_int_status_t
|
||||
_cairo_region_subtract (cairo_region_t *dst, cairo_region_t *a, cairo_region_t *b)
|
||||
{
|
||||
if (!pixman_region_subtract (&dst->rgn, &a->rgn, &b->rgn))
|
||||
return CAIRO_STATUS_NO_MEMORY;
|
||||
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
cairo_int_status_t
|
||||
_cairo_region_intersect (cairo_region_t *dst, cairo_region_t *a, cairo_region_t *b)
|
||||
{
|
||||
if (!pixman_region_intersect (&dst->rgn, &a->rgn, &b->rgn))
|
||||
return CAIRO_STATUS_NO_MEMORY;
|
||||
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
cairo_int_status_t
|
||||
_cairo_region_union_rect (cairo_region_t *dst,
|
||||
cairo_region_t *src,
|
||||
cairo_rectangle_int_t *rect)
|
||||
{
|
||||
if (!pixman_region_union_rect (&dst->rgn, &src->rgn,
|
||||
rect->x, rect->y,
|
||||
rect->width, rect->height))
|
||||
return CAIRO_STATUS_NO_MEMORY;
|
||||
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
cairo_bool_t
|
||||
_cairo_region_not_empty (cairo_region_t *region)
|
||||
{
|
||||
return (cairo_bool_t) pixman_region_not_empty (®ion->rgn);
|
||||
}
|
||||
|
||||
void
|
||||
_cairo_region_translate (cairo_region_t *region,
|
||||
int x, int y)
|
||||
{
|
||||
pixman_region_translate (®ion->rgn, x, y);
|
||||
rect->x = region_extents->x1;
|
||||
rect->y = region_extents->y1;
|
||||
rect->width = region_extents->x2 - region_extents->x1;
|
||||
rect->height = region_extents->y2 - region_extents->y1;
|
||||
}
|
||||
|
|
|
@ -1,4 +1,9 @@
|
|||
#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
|
||||
#define _cairo_svg_test_force_fallbacks _moz__cairo_svg_test_force_fallbacks
|
||||
#define _cairo_xlib_test_disable_render _moz__cairo_xlib_test_disable_render
|
||||
#define cairo_append_path _moz_cairo_append_path
|
||||
#define cairo_arc _moz_cairo_arc
|
||||
#define cairo_arc_negative _moz_cairo_arc_negative
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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,31 +324,23 @@ _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;
|
||||
subset.num_glyphs = collection->num_glyphs;
|
||||
/* No need to check for out of memory here. If to_unicode is NULL, the PDF
|
||||
* surface does not emit an ToUnicode stream */
|
||||
subset.to_unicode = _cairo_malloc_ab (collection->num_glyphs, sizeof (unsigned long));
|
||||
subset.to_unicode = malloc (collection->num_glyphs*sizeof(unsigned long));
|
||||
if (subset.to_unicode) {
|
||||
for (j = 0; j < collection->num_glyphs; j++) {
|
||||
/* default unicode character required when mapping fails */
|
||||
|
@ -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,11 +509,7 @@ _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 = _cairo_malloc_ab (collection.glyphs_size, sizeof(unsigned long));
|
||||
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)
|
||||
{
|
||||
|
|
|
@ -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;
|
||||
|
@ -927,7 +899,7 @@ _cairo_scaled_font_text_to_glyphs (cairo_scaled_font_t *scaled_font,
|
|||
if (status)
|
||||
goto DONE;
|
||||
|
||||
*glyphs = (cairo_glyph_t *) _cairo_malloc_ab ((*num_glyphs), sizeof (cairo_glyph_t));
|
||||
*glyphs = (cairo_glyph_t *) malloc ((*num_glyphs) * (sizeof (cairo_glyph_t)));
|
||||
|
||||
if (*glyphs == NULL) {
|
||||
status = CAIRO_STATUS_NO_MEMORY;
|
||||
|
@ -974,8 +946,8 @@ _cairo_scaled_font_glyph_device_extents (cairo_scaled_font_t *scaled_font,
|
|||
{
|
||||
cairo_status_t status = CAIRO_STATUS_SUCCESS;
|
||||
int i;
|
||||
short min_x = INT16_MAX, max_x = INT16_MIN;
|
||||
short min_y = INT16_MAX, max_y = INT16_MIN;
|
||||
int min_x = INT16_MAX, max_x = INT16_MIN;
|
||||
int min_y = INT16_MAX, max_y = INT16_MIN;
|
||||
|
||||
if (scaled_font->status)
|
||||
return scaled_font->status;
|
||||
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -21,7 +21,11 @@
|
|||
* OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "cairoint.h"
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <stddef.h>
|
||||
#include <string.h>
|
||||
#include <assert.h>
|
||||
|
||||
#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; i<MAX_FREELIST_LEVEL; i++) {
|
||||
for (i=0; i<MAX_LEVEL; i++) {
|
||||
elt = list->freelists[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);
|
||||
|
||||
|
|
|
@ -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,12 +104,21 @@ _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) {
|
||||
new_points = _cairo_malloc_ab (new_size, sizeof (cairo_point_t));
|
||||
new_points = malloc (new_size * sizeof (cairo_point_t));
|
||||
if (new_points)
|
||||
memcpy (new_points, spline->points, old_size * sizeof (cairo_point_t));
|
||||
} else {
|
||||
|
@ -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)
|
||||
|
|
|
@ -62,7 +62,7 @@ _cairo_stroke_style_init_copy (cairo_stroke_style_t *style,
|
|||
if (other->dash == NULL) {
|
||||
style->dash = NULL;
|
||||
} else {
|
||||
style->dash = _cairo_malloc_ab (style->num_dashes, sizeof (double));
|
||||
style->dash = malloc (style->num_dashes * sizeof (double));
|
||||
if (style->dash == NULL)
|
||||
return CAIRO_STATUS_NO_MEMORY;
|
||||
|
||||
|
|
|
@ -99,7 +99,7 @@ cairo_private cairo_status_t
|
|||
_cairo_surface_fallback_fill_rectangles (cairo_surface_t *surface,
|
||||
cairo_operator_t op,
|
||||
const cairo_color_t *color,
|
||||
cairo_rectangle_int_t *rects,
|
||||
cairo_rectangle_int16_t *rects,
|
||||
int num_rects);
|
||||
|
||||
cairo_private cairo_status_t
|
||||
|
|
|
@ -35,16 +35,14 @@
|
|||
* Carl D. Worth <cworth@cworth.org>
|
||||
*/
|
||||
|
||||
#include "cairoint.h"
|
||||
|
||||
#include "cairo-surface-fallback-private.h"
|
||||
#include "cairo-clip-private.h"
|
||||
|
||||
typedef struct {
|
||||
cairo_surface_t *dst;
|
||||
cairo_rectangle_int_t extents;
|
||||
cairo_rectangle_int16_t extents;
|
||||
cairo_image_surface_t *image;
|
||||
cairo_rectangle_int_t image_rect;
|
||||
cairo_rectangle_int16_t image_rect;
|
||||
void *image_extra;
|
||||
} fallback_state_t;
|
||||
|
||||
|
@ -106,7 +104,7 @@ typedef cairo_status_t (*cairo_draw_func_t) (void *clos
|
|||
cairo_surface_t *dst,
|
||||
int dst_x,
|
||||
int dst_y,
|
||||
const cairo_rectangle_int_t *extents);
|
||||
const cairo_rectangle_int16_t *extents);
|
||||
|
||||
static cairo_status_t
|
||||
_create_composite_mask_pattern (cairo_surface_pattern_t *mask_pattern,
|
||||
|
@ -114,7 +112,7 @@ _create_composite_mask_pattern (cairo_surface_pattern_t *mask_pattern,
|
|||
cairo_draw_func_t draw_func,
|
||||
void *draw_closure,
|
||||
cairo_surface_t *dst,
|
||||
const cairo_rectangle_int_t *extents)
|
||||
const cairo_rectangle_int16_t *extents)
|
||||
{
|
||||
cairo_surface_t *mask;
|
||||
cairo_status_t status;
|
||||
|
@ -159,7 +157,7 @@ _clip_and_composite_with_mask (cairo_clip_t *clip,
|
|||
cairo_draw_func_t draw_func,
|
||||
void *draw_closure,
|
||||
cairo_surface_t *dst,
|
||||
const cairo_rectangle_int_t *extents)
|
||||
const cairo_rectangle_int16_t *extents)
|
||||
{
|
||||
cairo_surface_pattern_t mask_pattern;
|
||||
cairo_status_t status;
|
||||
|
@ -193,7 +191,7 @@ _clip_and_composite_combine (cairo_clip_t *clip,
|
|||
cairo_draw_func_t draw_func,
|
||||
void *draw_closure,
|
||||
cairo_surface_t *dst,
|
||||
const cairo_rectangle_int_t *extents)
|
||||
const cairo_rectangle_int16_t *extents)
|
||||
{
|
||||
cairo_surface_t *intermediate;
|
||||
cairo_surface_pattern_t dst_pattern;
|
||||
|
@ -281,7 +279,7 @@ _clip_and_composite_source (cairo_clip_t *clip,
|
|||
cairo_draw_func_t draw_func,
|
||||
void *draw_closure,
|
||||
cairo_surface_t *dst,
|
||||
const cairo_rectangle_int_t *extents)
|
||||
const cairo_rectangle_int16_t *extents)
|
||||
{
|
||||
cairo_surface_pattern_t mask_pattern;
|
||||
cairo_status_t status;
|
||||
|
@ -322,7 +320,7 @@ _clip_and_composite_source (cairo_clip_t *clip,
|
|||
}
|
||||
|
||||
static int
|
||||
_cairo_rectangle_empty (const cairo_rectangle_int_t *rect)
|
||||
_cairo_rectangle_empty (const cairo_rectangle_int16_t *rect)
|
||||
{
|
||||
return rect->width == 0 || rect->height == 0;
|
||||
}
|
||||
|
@ -355,7 +353,7 @@ _clip_and_composite (cairo_clip_t *clip,
|
|||
cairo_draw_func_t draw_func,
|
||||
void *draw_closure,
|
||||
cairo_surface_t *dst,
|
||||
const cairo_rectangle_int_t *extents)
|
||||
const cairo_rectangle_int16_t *extents)
|
||||
{
|
||||
cairo_pattern_union_t solid_pattern;
|
||||
cairo_status_t status;
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -410,19 +407,18 @@ _composite_trap_region (cairo_clip_t *clip,
|
|||
cairo_pattern_t *src,
|
||||
cairo_operator_t op,
|
||||
cairo_surface_t *dst,
|
||||
cairo_region_t *trap_region,
|
||||
cairo_rectangle_int_t *extents)
|
||||
pixman_region16_t *trap_region,
|
||||
cairo_rectangle_int16_t *extents)
|
||||
{
|
||||
cairo_status_t status;
|
||||
cairo_pattern_union_t solid_pattern;
|
||||
cairo_pattern_union_t mask;
|
||||
int num_rects = _cairo_region_num_boxes (trap_region);
|
||||
int num_rects = pixman_region_num_rects (trap_region);
|
||||
unsigned int clip_serial;
|
||||
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);
|
||||
|
@ -483,7 +476,7 @@ _composite_traps_draw_func (void *closure,
|
|||
cairo_surface_t *dst,
|
||||
int dst_x,
|
||||
int dst_y,
|
||||
const cairo_rectangle_int_t *extents)
|
||||
const cairo_rectangle_int16_t *extents)
|
||||
{
|
||||
cairo_composite_traps_info_t *info = closure;
|
||||
cairo_pattern_union_t pattern;
|
||||
|
@ -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,152 +511,145 @@ _clip_and_composite_trapezoids (cairo_pattern_t *src,
|
|||
cairo_antialias_t antialias)
|
||||
{
|
||||
cairo_status_t status;
|
||||
cairo_region_t trap_region;
|
||||
cairo_region_t clear_region;
|
||||
cairo_bool_t has_trap_region = FALSE;
|
||||
cairo_bool_t has_clear_region = FALSE;
|
||||
cairo_rectangle_int_t extents;
|
||||
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_int_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_get_extents (&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.
|
||||
*/
|
||||
_cairo_region_init_rect (&clear_region, &extents);
|
||||
|
||||
has_clear_region = TRUE;
|
||||
status = _cairo_clip_intersect_to_region (clip, &clear_region);
|
||||
|
||||
if (status)
|
||||
goto out;
|
||||
|
||||
_cairo_region_get_extents (&clear_region, &extents);
|
||||
|
||||
status = _cairo_region_subtract (&clear_region, &clear_region, &trap_region);
|
||||
if (status)
|
||||
goto out;
|
||||
|
||||
if (!_cairo_region_not_empty (&clear_region)) {
|
||||
_cairo_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)
|
||||
_cairo_region_fini (&trap_region);
|
||||
if (has_clear_region)
|
||||
_cairo_region_fini (&clear_region);
|
||||
out:
|
||||
if (trap_region)
|
||||
pixman_region_destroy (trap_region);
|
||||
if (clear_region)
|
||||
pixman_region_destroy (clear_region);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
@ -675,7 +660,7 @@ _cairo_surface_fallback_paint (cairo_surface_t *surface,
|
|||
cairo_pattern_t *source)
|
||||
{
|
||||
cairo_status_t status;
|
||||
cairo_rectangle_int_t extents;
|
||||
cairo_rectangle_int16_t extents;
|
||||
cairo_box_t box;
|
||||
cairo_traps_t traps;
|
||||
|
||||
|
@ -684,7 +669,7 @@ _cairo_surface_fallback_paint (cairo_surface_t *surface,
|
|||
return status;
|
||||
|
||||
if (_cairo_operator_bounded_by_source (op)) {
|
||||
cairo_rectangle_int_t source_extents;
|
||||
cairo_rectangle_int16_t source_extents;
|
||||
status = _cairo_pattern_get_extents (source, &source_extents);
|
||||
if (status)
|
||||
return status;
|
||||
|
@ -705,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
|
||||
|
@ -724,7 +709,7 @@ _cairo_surface_mask_draw_func (void *closure,
|
|||
cairo_surface_t *dst,
|
||||
int dst_x,
|
||||
int dst_y,
|
||||
const cairo_rectangle_int_t *extents)
|
||||
const cairo_rectangle_int16_t *extents)
|
||||
{
|
||||
cairo_pattern_t *mask = closure;
|
||||
|
||||
|
@ -751,7 +736,7 @@ _cairo_surface_fallback_mask (cairo_surface_t *surface,
|
|||
cairo_pattern_t *mask)
|
||||
{
|
||||
cairo_status_t status;
|
||||
cairo_rectangle_int_t extents, source_extents, mask_extents;
|
||||
cairo_rectangle_int16_t extents, source_extents, mask_extents;
|
||||
|
||||
status = _cairo_surface_get_extents (surface, &extents);
|
||||
if (status)
|
||||
|
@ -800,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_int_t extents;
|
||||
|
||||
status = _cairo_surface_get_extents (surface, &extents);
|
||||
if (status)
|
||||
return status;
|
||||
|
||||
if (_cairo_operator_bounded_by_source (op)) {
|
||||
cairo_rectangle_int_t source_extents;
|
||||
status = _cairo_pattern_get_extents (source, &source_extents);
|
||||
if (status)
|
||||
return status;
|
||||
|
||||
_cairo_rectangle_intersect (&extents, &source_extents);
|
||||
}
|
||||
|
||||
status = _cairo_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,
|
||||
|
@ -839,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
|
||||
|
@ -862,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_int_t extents;
|
||||
|
||||
status = _cairo_surface_get_extents (surface, &extents);
|
||||
if (status)
|
||||
return status;
|
||||
|
||||
if (_cairo_operator_bounded_by_source (op)) {
|
||||
cairo_rectangle_int_t source_extents;
|
||||
status = _cairo_pattern_get_extents (source, &source_extents);
|
||||
if (status)
|
||||
return status;
|
||||
|
||||
_cairo_rectangle_intersect (&extents, &source_extents);
|
||||
}
|
||||
|
||||
status = _cairo_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,
|
||||
|
@ -925,7 +858,7 @@ _cairo_surface_old_show_glyphs_draw_func (void *closure
|
|||
cairo_surface_t *dst,
|
||||
int dst_x,
|
||||
int dst_y,
|
||||
const cairo_rectangle_int_t *extents)
|
||||
const cairo_rectangle_int16_t *extents)
|
||||
{
|
||||
cairo_show_glyphs_info_t *glyph_info = closure;
|
||||
cairo_pattern_union_t pattern;
|
||||
|
@ -945,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;
|
||||
|
||||
|
@ -988,7 +920,7 @@ _cairo_surface_fallback_show_glyphs (cairo_surface_t *surface,
|
|||
cairo_scaled_font_t *scaled_font)
|
||||
{
|
||||
cairo_status_t status;
|
||||
cairo_rectangle_int_t extents;
|
||||
cairo_rectangle_int16_t extents, glyph_extents;
|
||||
cairo_show_glyphs_info_t glyph_info;
|
||||
|
||||
status = _cairo_surface_get_extents (surface, &extents);
|
||||
|
@ -996,8 +928,6 @@ _cairo_surface_fallback_show_glyphs (cairo_surface_t *surface,
|
|||
return status;
|
||||
|
||||
if (_cairo_operator_bounded_by_mask (op)) {
|
||||
cairo_rectangle_int16_t glyph_extents;
|
||||
cairo_rectangle_int_t glyph_extents_full;
|
||||
status = _cairo_scaled_font_glyph_device_extents (scaled_font,
|
||||
glyphs,
|
||||
num_glyphs,
|
||||
|
@ -1005,11 +935,7 @@ _cairo_surface_fallback_show_glyphs (cairo_surface_t *surface,
|
|||
if (status)
|
||||
return status;
|
||||
|
||||
glyph_extents_full.x = glyph_extents.x;
|
||||
glyph_extents_full.y = glyph_extents.y;
|
||||
glyph_extents_full.width = glyph_extents.width;
|
||||
glyph_extents_full.height = glyph_extents.height;
|
||||
_cairo_rectangle_intersect (&extents, &glyph_extents_full);
|
||||
_cairo_rectangle_intersect (&extents, &glyph_extents);
|
||||
}
|
||||
|
||||
status = _cairo_clip_intersect_to_rectangle (surface->clip, &extents);
|
||||
|
@ -1053,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);
|
||||
|
@ -1124,11 +1046,11 @@ cairo_status_t
|
|||
_cairo_surface_fallback_fill_rectangles (cairo_surface_t *surface,
|
||||
cairo_operator_t op,
|
||||
const cairo_color_t *color,
|
||||
cairo_rectangle_int_t *rects,
|
||||
cairo_rectangle_int16_t *rects,
|
||||
int num_rects)
|
||||
{
|
||||
fallback_state_t state;
|
||||
cairo_rectangle_int_t *offset_rects = NULL;
|
||||
cairo_rectangle_int16_t *offset_rects = NULL;
|
||||
cairo_status_t status;
|
||||
int x1, y1, x2, y2;
|
||||
int i;
|
||||
|
@ -1168,7 +1090,7 @@ _cairo_surface_fallback_fill_rectangles (cairo_surface_t *surface,
|
|||
/* If the fetched image isn't at 0,0, we need to offset the rectangles */
|
||||
|
||||
if (state.image_rect.x != 0 || state.image_rect.y != 0) {
|
||||
offset_rects = _cairo_malloc_ab (num_rects, sizeof (cairo_rectangle_int_t));
|
||||
offset_rects = malloc (sizeof (cairo_rectangle_int16_t) * num_rects);
|
||||
if (offset_rects == NULL) {
|
||||
status = CAIRO_STATUS_NO_MEMORY;
|
||||
goto DONE;
|
||||
|
@ -1224,7 +1146,7 @@ _cairo_surface_fallback_composite_trapezoids (cairo_operator_t op,
|
|||
/* If the destination image isn't at 0,0, we need to offset the trapezoids */
|
||||
|
||||
if (state.image_rect.x != 0 || state.image_rect.y != 0) {
|
||||
offset_traps = _cairo_malloc_ab (num_traps, sizeof (cairo_trapezoid_t));
|
||||
offset_traps = malloc (sizeof (cairo_trapezoid_t) * num_traps);
|
||||
if (!offset_traps) {
|
||||
status = CAIRO_STATUS_NO_MEMORY;
|
||||
goto DONE;
|
||||
|
@ -1236,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);
|
||||
|
||||
|
|
|
@ -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 © 2002 University of Southern California
|
||||
|
@ -36,8 +35,9 @@
|
|||
* Carl D. Worth <cworth@cworth.org>
|
||||
*/
|
||||
|
||||
#include "cairoint.h"
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "cairoint.h"
|
||||
#include "cairo-surface-fallback-private.h"
|
||||
#include "cairo-clip-private.h"
|
||||
|
||||
|
@ -81,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);
|
||||
|
@ -180,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;
|
||||
|
@ -289,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);
|
||||
|
||||
|
@ -299,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;
|
||||
|
@ -313,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);
|
||||
|
@ -380,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
|
||||
|
@ -407,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
|
||||
|
@ -503,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;
|
||||
}
|
||||
|
@ -602,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);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -957,9 +922,9 @@ _cairo_surface_release_source_image (cairo_surface_t *surface,
|
|||
**/
|
||||
cairo_status_t
|
||||
_cairo_surface_acquire_dest_image (cairo_surface_t *surface,
|
||||
cairo_rectangle_int_t *interest_rect,
|
||||
cairo_rectangle_int16_t *interest_rect,
|
||||
cairo_image_surface_t **image_out,
|
||||
cairo_rectangle_int_t *image_rect,
|
||||
cairo_rectangle_int16_t *image_rect,
|
||||
void **image_extra)
|
||||
{
|
||||
assert (!surface->finished);
|
||||
|
@ -983,9 +948,9 @@ _cairo_surface_acquire_dest_image (cairo_surface_t *surface,
|
|||
**/
|
||||
void
|
||||
_cairo_surface_release_dest_image (cairo_surface_t *surface,
|
||||
cairo_rectangle_int_t *interest_rect,
|
||||
cairo_rectangle_int16_t *interest_rect,
|
||||
cairo_image_surface_t *image,
|
||||
cairo_rectangle_int_t *image_rect,
|
||||
cairo_rectangle_int16_t *image_rect,
|
||||
void *image_extra)
|
||||
{
|
||||
assert (!surface->finished);
|
||||
|
@ -1092,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,
|
||||
|
@ -1195,7 +1131,7 @@ _cairo_surface_fill_rectangle (cairo_surface_t *surface,
|
|||
int width,
|
||||
int height)
|
||||
{
|
||||
cairo_rectangle_int_t rect;
|
||||
cairo_rectangle_int16_t rect;
|
||||
|
||||
assert (! surface->is_snapshot);
|
||||
|
||||
|
@ -1221,7 +1157,7 @@ _cairo_surface_fill_rectangle (cairo_surface_t *surface,
|
|||
* @region: the region to modify, in backend coordinates
|
||||
*
|
||||
* Applies an operator to a set of rectangles specified as a
|
||||
* #cairo_region_t using a solid color as the source.
|
||||
* #pixman_region16_t using a solid color as the source.
|
||||
* See _cairo_surface_fill_rectangles() for full details.
|
||||
*
|
||||
* Return value: %CAIRO_STATUS_SUCCESS or the error that occurred
|
||||
|
@ -1230,47 +1166,34 @@ cairo_status_t
|
|||
_cairo_surface_fill_region (cairo_surface_t *surface,
|
||||
cairo_operator_t op,
|
||||
const cairo_color_t *color,
|
||||
cairo_region_t *region)
|
||||
pixman_region16_t *region)
|
||||
{
|
||||
int num_boxes;
|
||||
cairo_box_int_t *boxes;
|
||||
cairo_rectangle_int_t stack_rects[CAIRO_STACK_BUFFER_SIZE / sizeof (cairo_rectangle_int_t)];
|
||||
cairo_rectangle_int_t *rects;
|
||||
int num_rects = pixman_region_num_rects (region);
|
||||
pixman_box16_t *boxes = pixman_region_rects (region);
|
||||
cairo_rectangle_int16_t *rects;
|
||||
cairo_status_t status;
|
||||
int i;
|
||||
|
||||
assert (! surface->is_snapshot);
|
||||
|
||||
status = _cairo_region_get_boxes (region, &num_boxes, &boxes);
|
||||
if (status)
|
||||
return status;
|
||||
|
||||
if (num_boxes == 0)
|
||||
if (!num_rects)
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
|
||||
rects = stack_rects;
|
||||
if (num_boxes > ARRAY_LENGTH (stack_rects)) {
|
||||
rects = _cairo_malloc_ab (num_boxes, sizeof (cairo_rectangle_int_t));
|
||||
if (!rects) {
|
||||
_cairo_region_boxes_fini (region, boxes);
|
||||
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_boxes; i++) {
|
||||
rects[i].x = boxes[i].p1.x;
|
||||
rects[i].y = boxes[i].p1.y;
|
||||
rects[i].width = boxes[i].p2.x - boxes[i].p1.x;
|
||||
rects[i].height = boxes[i].p2.y - boxes[i].p1.y;
|
||||
for (i = 0; i < num_rects; i++) {
|
||||
rects[i].x = boxes[i].x1;
|
||||
rects[i].y = boxes[i].y1;
|
||||
rects[i].width = boxes[i].x2 - boxes[i].x1;
|
||||
rects[i].height = boxes[i].y2 - boxes[i].y1;
|
||||
}
|
||||
|
||||
status = _cairo_surface_fill_rectangles (surface, op,
|
||||
color, rects, num_boxes);
|
||||
color, rects, num_rects);
|
||||
|
||||
_cairo_region_boxes_fini (region, boxes);
|
||||
|
||||
if (rects != stack_rects)
|
||||
free (rects);
|
||||
free (rects);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
@ -1295,7 +1218,7 @@ cairo_status_t
|
|||
_cairo_surface_fill_rectangles (cairo_surface_t *surface,
|
||||
cairo_operator_t op,
|
||||
const cairo_color_t *color,
|
||||
cairo_rectangle_int_t *rects,
|
||||
cairo_rectangle_int16_t *rects,
|
||||
int num_rects)
|
||||
{
|
||||
cairo_int_status_t status;
|
||||
|
@ -1332,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);
|
||||
|
@ -1362,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;
|
||||
}
|
||||
|
@ -1406,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,
|
||||
|
@ -1447,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,
|
||||
|
@ -1519,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);
|
||||
|
@ -1530,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);
|
||||
|
@ -1548,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);
|
||||
}
|
||||
|
@ -1637,7 +1552,7 @@ _cairo_surface_reset_clip (cairo_surface_t *surface)
|
|||
/**
|
||||
* _cairo_surface_set_clip_region:
|
||||
* @surface: the #cairo_surface_t to reset the clip on
|
||||
* @region: the #cairo_region_t to use for clipping
|
||||
* @region: the #pixman_region16_t to use for clipping
|
||||
* @serial: the clip serial number associated with the region
|
||||
*
|
||||
* This function sets the clipping for the surface to
|
||||
|
@ -1646,7 +1561,7 @@ _cairo_surface_reset_clip (cairo_surface_t *surface)
|
|||
*/
|
||||
cairo_status_t
|
||||
_cairo_surface_set_clip_region (cairo_surface_t *surface,
|
||||
cairo_region_t *region,
|
||||
pixman_region16_t *region,
|
||||
unsigned int serial)
|
||||
{
|
||||
cairo_status_t status;
|
||||
|
@ -1785,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);
|
||||
}
|
||||
|
||||
|
@ -1820,7 +1735,7 @@ _cairo_surface_set_clip (cairo_surface_t *surface, cairo_clip_t *clip)
|
|||
*/
|
||||
cairo_status_t
|
||||
_cairo_surface_get_extents (cairo_surface_t *surface,
|
||||
cairo_rectangle_int_t *rectangle)
|
||||
cairo_rectangle_int16_t *rectangle)
|
||||
{
|
||||
if (surface->status)
|
||||
return surface->status;
|
||||
|
@ -1849,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);
|
||||
|
||||
|
@ -1874,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,20 +1856,18 @@ _cairo_surface_old_show_glyphs (cairo_scaled_font_t *scaled_font,
|
|||
|
||||
static cairo_status_t
|
||||
_cairo_surface_composite_fixup_unbounded_internal (cairo_surface_t *dst,
|
||||
cairo_rectangle_int_t *src_rectangle,
|
||||
cairo_rectangle_int_t *mask_rectangle,
|
||||
cairo_rectangle_int16_t *src_rectangle,
|
||||
cairo_rectangle_int16_t *mask_rectangle,
|
||||
int dst_x,
|
||||
int dst_y,
|
||||
unsigned int width,
|
||||
unsigned int height)
|
||||
{
|
||||
cairo_rectangle_int_t dst_rectangle;
|
||||
cairo_rectangle_int_t drawn_rectangle;
|
||||
cairo_bool_t has_drawn_region = FALSE;
|
||||
cairo_bool_t has_clear_region = FALSE;
|
||||
cairo_region_t drawn_region;
|
||||
cairo_region_t clear_region;
|
||||
cairo_status_t status;
|
||||
cairo_rectangle_int16_t dst_rectangle;
|
||||
cairo_rectangle_int16_t drawn_rectangle;
|
||||
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.
|
||||
|
@ -1974,35 +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
|
||||
*/
|
||||
_cairo_region_init_rect (&drawn_region, &drawn_rectangle);
|
||||
_cairo_region_init_rect (&clear_region, &dst_rectangle);
|
||||
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 (_cairo_region_subtract (&clear_region, &clear_region, &drawn_region)
|
||||
!= CAIRO_STATUS_SUCCESS)
|
||||
{
|
||||
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)
|
||||
_cairo_region_fini (&drawn_region);
|
||||
if (has_clear_region)
|
||||
_cairo_region_fini (&clear_region);
|
||||
CLEANUP_REGIONS:
|
||||
if (drawn_region)
|
||||
pixman_region_destroy (drawn_region);
|
||||
if (clear_region)
|
||||
pixman_region_destroy (clear_region);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
@ -2048,9 +1953,9 @@ _cairo_surface_composite_fixup_unbounded (cairo_surface_t *dst,
|
|||
unsigned int width,
|
||||
unsigned int height)
|
||||
{
|
||||
cairo_rectangle_int_t src_tmp, mask_tmp;
|
||||
cairo_rectangle_int_t *src_rectangle = NULL;
|
||||
cairo_rectangle_int_t *mask_rectangle = NULL;
|
||||
cairo_rectangle_int16_t src_tmp, mask_tmp;
|
||||
cairo_rectangle_int16_t *src_rectangle = NULL;
|
||||
cairo_rectangle_int16_t *mask_rectangle = NULL;
|
||||
|
||||
assert (! dst->is_snapshot);
|
||||
|
||||
|
@ -2123,9 +2028,9 @@ _cairo_surface_composite_shape_fixup_unbounded (cairo_surface_t *dst,
|
|||
unsigned int width,
|
||||
unsigned int height)
|
||||
{
|
||||
cairo_rectangle_int_t src_tmp, mask_tmp;
|
||||
cairo_rectangle_int_t *src_rectangle = NULL;
|
||||
cairo_rectangle_int_t *mask_rectangle = NULL;
|
||||
cairo_rectangle_int16_t src_tmp, mask_tmp;
|
||||
cairo_rectangle_int16_t *src_rectangle = NULL;
|
||||
cairo_rectangle_int16_t *mask_rectangle = NULL;
|
||||
|
||||
assert (! dst->is_snapshot);
|
||||
|
||||
|
@ -2163,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
|
||||
|
@ -2185,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
|
||||
|
|
|
@ -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 © 2004 Red Hat, Inc
|
||||
|
@ -41,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;
|
||||
|
@ -58,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)
|
||||
|
@ -80,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;
|
||||
};
|
||||
|
@ -113,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;
|
||||
|
@ -355,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,
|
||||
"<clipPath id=\"clip%d\">\n"
|
||||
" <rect width=\"%f\" height=\"%f\"/>\n"
|
||||
"</clipPath>\n",
|
||||
surface->base_clip,
|
||||
width, height);
|
||||
|
||||
surface->xml_node = _cairo_memory_stream_create ();
|
||||
_cairo_array_init (&surface->page_set, sizeof (cairo_svg_page_t));
|
||||
|
@ -369,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,
|
||||
|
@ -409,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;
|
||||
|
||||
|
@ -418,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, "</g>\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);
|
||||
}
|
||||
|
@ -678,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.
|
||||
*
|
||||
* <note>
|
||||
* This function is <emphasis>only</emphasis> intended for internal
|
||||
* testing use within the cairo distribution. It is not installed in
|
||||
* any public header file.
|
||||
* </note>
|
||||
**/
|
||||
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)
|
||||
{
|
||||
|
@ -719,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;
|
||||
|
@ -737,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;
|
||||
|
@ -748,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);
|
||||
|
||||
|
@ -889,7 +924,7 @@ _cairo_svg_surface_emit_composite_image_pattern (cairo_output_stream_t *outp
|
|||
{
|
||||
cairo_surface_t *surface;
|
||||
cairo_surface_attributes_t surface_attr;
|
||||
cairo_rectangle_int_t extents;
|
||||
cairo_rectangle_int16_t extents;
|
||||
cairo_status_t status;
|
||||
cairo_matrix_t p2u;
|
||||
|
||||
|
@ -906,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,
|
||||
|
@ -945,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;
|
||||
|
||||
|
@ -960,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;
|
||||
|
@ -969,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;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -979,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,
|
||||
"<clipPath id=\"clip%d\">\n"
|
||||
" <rect width=\"%f\" height=\"%f\"/>\n"
|
||||
"</clipPath>\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);
|
||||
|
@ -1021,21 +1026,21 @@ _cairo_svg_surface_emit_meta_surface (cairo_svg_document_t *document,
|
|||
"<g id=\"surface%d\" "
|
||||
"clip-path=\"url(#clip%d)\" "
|
||||
"filter=\"url(#alpha)\">\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,
|
||||
"<g id=\"surface%d\" "
|
||||
"clip-path=\"url(#clip%d)\">\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;
|
||||
|
@ -1046,7 +1051,7 @@ _cairo_svg_surface_emit_meta_surface (cairo_svg_document_t *document,
|
|||
|
||||
_cairo_output_stream_printf (document->xml_node_defs, "</g>\n");
|
||||
|
||||
*id = new_snapshot.id;
|
||||
id = new_snapshot.id;
|
||||
|
||||
cairo_surface_destroy (paginated_surface);
|
||||
|
||||
|
@ -1057,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
|
||||
|
@ -1070,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,
|
||||
|
@ -1152,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,
|
||||
|
@ -1166,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,
|
||||
|
@ -1187,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
|
||||
|
@ -1198,7 +1194,7 @@ _cairo_svg_surface_emit_pattern_stops (cairo_output_stream_t *output,
|
|||
cairo_bool_t reverse_stops,
|
||||
cairo_bool_t emulate_reflect)
|
||||
{
|
||||
cairo_gradient_stop_t *stops;
|
||||
pixman_gradient_stop_t *stops;
|
||||
double offset;
|
||||
unsigned int n_stops;
|
||||
unsigned int i;
|
||||
|
@ -1212,16 +1208,16 @@ _cairo_svg_surface_emit_pattern_stops (cairo_output_stream_t *output,
|
|||
"stop-color: rgb(%f%%,%f%%,%f%%); "
|
||||
"stop-opacity: %f;\"/>\n",
|
||||
_cairo_fixed_to_double (pattern->stops[0].x),
|
||||
pattern->stops[0].color.red * 100.0,
|
||||
pattern->stops[0].color.green * 100.0,
|
||||
pattern->stops[0].color.blue * 100.0,
|
||||
pattern->stops[0].color.alpha);
|
||||
pattern->stops[0].color.red / 655.35,
|
||||
pattern->stops[0].color.green / 655.35,
|
||||
pattern->stops[0].color.blue / 655.35,
|
||||
pattern->stops[0].color.alpha / 65535.0);
|
||||
return;
|
||||
}
|
||||
|
||||
if (emulate_reflect || reverse_stops) {
|
||||
n_stops = emulate_reflect ? pattern->n_stops * 2 - 2: pattern->n_stops;
|
||||
stops = _cairo_malloc_ab (n_stops, sizeof (cairo_gradient_stop_t));
|
||||
stops = malloc (sizeof (pixman_gradient_stop_t) * n_stops);
|
||||
|
||||
for (i = 0; i < pattern->n_stops; i++) {
|
||||
if (reverse_stops) {
|
||||
|
@ -1260,22 +1256,22 @@ _cairo_svg_surface_emit_pattern_stops (cairo_output_stream_t *output,
|
|||
"stop-color: rgb(%f%%,%f%%,%f%%); "
|
||||
"stop-opacity: %f;\"/>\n",
|
||||
offset,
|
||||
stops[i].color.red * 100.0,
|
||||
stops[i].color.green * 100.0,
|
||||
stops[i].color.blue * 100.0,
|
||||
stops[i].color.alpha);
|
||||
stops[i].color.red / 655.35,
|
||||
stops[i].color.green / 655.35,
|
||||
stops[i].color.blue / 655.35,
|
||||
stops[i].color.alpha / 65535.0);
|
||||
}
|
||||
else {
|
||||
cairo_bool_t found = FALSE;
|
||||
unsigned int offset_index;
|
||||
cairo_color_t offset_color_start, offset_color_stop;
|
||||
pixman_color_t offset_color_start, offset_color_stop;
|
||||
|
||||
for (i = 0; i < n_stops; i++) {
|
||||
if (_cairo_fixed_to_double (stops[i].x) >= -start_offset) {
|
||||
if (i > 0) {
|
||||
if (stops[i].x != stops[i-1].x) {
|
||||
double x0, x1;
|
||||
cairo_color_t *color0, *color1;
|
||||
pixman_color_t *color0, *color1;
|
||||
|
||||
x0 = _cairo_fixed_to_double (stops[i-1].x);
|
||||
x1 = _cairo_fixed_to_double (stops[i].x);
|
||||
|
@ -1311,20 +1307,20 @@ _cairo_svg_surface_emit_pattern_stops (cairo_output_stream_t *output,
|
|||
"<stop offset=\"0\" style=\""
|
||||
"stop-color: rgb(%f%%,%f%%,%f%%); "
|
||||
"stop-opacity: %f;\"/>\n",
|
||||
offset_color_start.red * 100.0,
|
||||
offset_color_start.green * 100.0,
|
||||
offset_color_start.blue * 100.0,
|
||||
offset_color_start.alpha);
|
||||
offset_color_start.red / 655.35,
|
||||
offset_color_start.green / 655.35,
|
||||
offset_color_start.blue / 655.35,
|
||||
offset_color_start.alpha / 65535.0);
|
||||
for (i = offset_index; i < n_stops; i++) {
|
||||
_cairo_output_stream_printf (output,
|
||||
"<stop offset=\"%f\" style=\""
|
||||
"stop-color: rgb(%f%%,%f%%,%f%%); "
|
||||
"stop-opacity: %f;\"/>\n",
|
||||
_cairo_fixed_to_double (stops[i].x) + start_offset,
|
||||
stops[i].color.red * 100.0,
|
||||
stops[i].color.green * 100.0,
|
||||
stops[i].color.blue * 100.0,
|
||||
stops[i].color.alpha);
|
||||
stops[i].color.red / 655.35,
|
||||
stops[i].color.green / 655.35,
|
||||
stops[i].color.blue / 655.35,
|
||||
stops[i].color.alpha / 65535.0);
|
||||
}
|
||||
for (i = 0; i < offset_index; i++) {
|
||||
_cairo_output_stream_printf (output,
|
||||
|
@ -1332,20 +1328,20 @@ _cairo_svg_surface_emit_pattern_stops (cairo_output_stream_t *output,
|
|||
"stop-color: rgb(%f%%,%f%%,%f%%); "
|
||||
"stop-opacity: %f;\"/>\n",
|
||||
1.0 + _cairo_fixed_to_double (stops[i].x) + start_offset,
|
||||
stops[i].color.red * 100.0,
|
||||
stops[i].color.green * 100.0,
|
||||
stops[i].color.blue * 100.0,
|
||||
stops[i].color.alpha);
|
||||
stops[i].color.red / 655.35,
|
||||
stops[i].color.green / 655.35,
|
||||
stops[i].color.blue / 655.35,
|
||||
stops[i].color.alpha / 65535.0);
|
||||
}
|
||||
|
||||
_cairo_output_stream_printf (output,
|
||||
"<stop offset=\"1\" style=\""
|
||||
"stop-color: rgb(%f%%,%f%%,%f%%); "
|
||||
"stop-opacity: %f;\"/>\n",
|
||||
offset_color_stop.red * 100.0,
|
||||
offset_color_stop.green * 100.0,
|
||||
offset_color_stop.blue * 100.0,
|
||||
offset_color_stop.alpha);
|
||||
offset_color_stop.red / 655.35,
|
||||
offset_color_stop.green / 655.35,
|
||||
offset_color_stop.blue / 655.35,
|
||||
offset_color_stop.alpha / 65535.0);
|
||||
|
||||
}
|
||||
|
||||
|
@ -1370,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,
|
||||
|
@ -1379,17 +1375,11 @@ _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->p1.x);
|
||||
y0 = _cairo_fixed_to_double (pattern->p1.y);
|
||||
x1 = _cairo_fixed_to_double (pattern->p2.x);
|
||||
y1 = _cairo_fixed_to_double (pattern->p2.y);
|
||||
x0 = _cairo_fixed_to_double (pattern->gradient.p1.x);
|
||||
y0 = _cairo_fixed_to_double (pattern->gradient.p1.y);
|
||||
x1 = _cairo_fixed_to_double (pattern->gradient.p2.x);
|
||||
y1 = _cairo_fixed_to_double (pattern->gradient.p2.y);
|
||||
|
||||
_cairo_output_stream_printf (document->xml_node_defs,
|
||||
"<linearGradient id=\"linear%d\" "
|
||||
|
@ -1399,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);
|
||||
|
@ -1412,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,
|
||||
|
@ -1428,39 +1418,31 @@ _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;
|
||||
cairo_point_t *c0, *c1;
|
||||
cairo_fixed_t radius0, radius1;
|
||||
pixman_circle_t *c0, *c1;
|
||||
|
||||
extend = pattern->base.base.extend;
|
||||
|
||||
if (pattern->r1 < pattern->r2) {
|
||||
c0 = &pattern->c1;
|
||||
c1 = &pattern->c2;
|
||||
radius0 = pattern->r1;
|
||||
radius1 = pattern->r2;
|
||||
if (pattern->gradient.c1.radius < pattern->gradient.c2.radius) {
|
||||
c0 = &pattern->gradient.c1;
|
||||
c1 = &pattern->gradient.c2;
|
||||
reverse_stops = FALSE;
|
||||
} else {
|
||||
c0 = &pattern->c2;
|
||||
c1 = &pattern->c1;
|
||||
radius0 = pattern->r2;
|
||||
radius1 = pattern->r1;
|
||||
c0 = &pattern->gradient.c2;
|
||||
c1 = &pattern->gradient.c1;
|
||||
reverse_stops = TRUE;
|
||||
}
|
||||
|
||||
x0 = _cairo_fixed_to_double (c0->x);
|
||||
y0 = _cairo_fixed_to_double (c0->y);
|
||||
r0 = _cairo_fixed_to_double (radius0);
|
||||
r0 = _cairo_fixed_to_double (c0->radius);
|
||||
x1 = _cairo_fixed_to_double (c1->x);
|
||||
y1 = _cairo_fixed_to_double (c1->y);
|
||||
r1 = _cairo_fixed_to_double (radius1);
|
||||
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->r1 == pattern->r2) {
|
||||
if (pattern->gradient.c1.radius == pattern->gradient.c2.radius) {
|
||||
_cairo_output_stream_printf (document->xml_node_defs,
|
||||
"<radialGradient id=\"radial%d\" "
|
||||
"gradientUnits=\"userSpaceOnUse\" "
|
||||
|
@ -1483,19 +1465,19 @@ _cairo_svg_surface_emit_radial_pattern (cairo_svg_surface_t *surface,
|
|||
"<stop offset=\"0\" style=\""
|
||||
"stop-color: rgb(%f%%,%f%%,%f%%); "
|
||||
"stop-opacity: %f;\"/>\n",
|
||||
pattern->base.stops[0].color.red * 100.0,
|
||||
pattern->base.stops[0].color.green * 100.0,
|
||||
pattern->base.stops[0].color.blue * 100.0,
|
||||
pattern->base.stops[0].color.alpha);
|
||||
pattern->base.stops[0].color.red / 655.35,
|
||||
pattern->base.stops[0].color.green / 655.35,
|
||||
pattern->base.stops[0].color.blue / 655.35,
|
||||
pattern->base.stops[0].color.alpha / 65535.0);
|
||||
if (pattern->base.n_stops > 1)
|
||||
_cairo_output_stream_printf (document->xml_node_defs,
|
||||
"<stop offset=\"0\" style=\""
|
||||
"stop-color: rgb(%f%%,%f%%,%f%%); "
|
||||
"stop-opacity: %f;\"/>\n",
|
||||
pattern->base.stops[1].color.red * 100.0,
|
||||
pattern->base.stops[1].color.green * 100.0,
|
||||
pattern->base.stops[1].color.blue * 100.0,
|
||||
pattern->base.stops[1].color.alpha);
|
||||
pattern->base.stops[1].color.red / 655.35,
|
||||
pattern->base.stops[1].color.green / 655.35,
|
||||
pattern->base.stops[1].color.blue / 655.35,
|
||||
pattern->base.stops[1].color.alpha / 65535.0);
|
||||
}
|
||||
|
||||
} else {
|
||||
|
@ -1589,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
|
||||
|
@ -1628,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,
|
||||
"<path style=\"stroke: none; "
|
||||
|
@ -1648,7 +1631,7 @@ _cairo_svg_surface_fill (void *abstract_surface,
|
|||
|
||||
static cairo_int_status_t
|
||||
_cairo_svg_surface_get_extents (void *abstract_surface,
|
||||
cairo_rectangle_int_t *rectangle)
|
||||
cairo_rectangle_int16_t *rectangle)
|
||||
{
|
||||
cairo_svg_surface_t *surface = abstract_surface;
|
||||
|
||||
|
@ -1703,7 +1686,6 @@ _cairo_svg_surface_paint (void *abstract_surface,
|
|||
cairo_operator_t op,
|
||||
cairo_pattern_t *source)
|
||||
{
|
||||
cairo_status_t status;
|
||||
cairo_svg_surface_t *surface = abstract_surface;
|
||||
|
||||
if (surface->paginated_mode == CAIRO_PAGINATED_MODE_ANALYZE)
|
||||
|
@ -1716,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
|
||||
|
@ -1729,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) {
|
||||
|
@ -1762,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;
|
||||
|
@ -1771,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);
|
||||
|
||||
|
@ -1788,10 +1765,7 @@ _cairo_svg_surface_mask (void *abstract_surface,
|
|||
" </g>\n"
|
||||
"</mask>\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);
|
||||
|
@ -1821,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:
|
||||
|
@ -1903,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;
|
||||
|
@ -1927,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;
|
||||
|
@ -1937,8 +1911,7 @@ _cairo_svg_surface_show_glyphs (void *abstract_surface,
|
|||
_cairo_output_stream_printf (surface->xml_node,
|
||||
" <use xlink:href=\"#glyph%d-%d\" "
|
||||
"x=\"%f\" y=\"%f\"/>\n",
|
||||
subset_glyph.font_id,
|
||||
subset_glyph.subset_glyph_index,
|
||||
font_id, subset_glyph_index,
|
||||
glyphs[i].x, glyphs[i].y);
|
||||
}
|
||||
|
||||
|
@ -2061,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);
|
||||
|
@ -2119,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;
|
||||
|
@ -2139,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, "<defs>\n");
|
||||
|
@ -2166,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, "<page>\n");
|
||||
_cairo_output_stream_printf (output,
|
||||
"<g id=\"surface%d\">\n",
|
||||
page->surface_id);
|
||||
"<g id=\"surface%d\" "
|
||||
"clip-path=\"url(#clip%d)\">\n",
|
||||
page->surface_id,
|
||||
page->clip_id);
|
||||
_cairo_memory_stream_copy (page->xml_node, output);
|
||||
_cairo_output_stream_printf (output, "</g>\n</page>\n");
|
||||
}
|
||||
|
@ -2175,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,
|
||||
"<g id=\"surface%d\">\n",
|
||||
page->surface_id);
|
||||
"<g id=\"surface%d\" "
|
||||
"clip-path=\"url(#clip%d)\">\n",
|
||||
page->surface_id,
|
||||
page->clip_id);
|
||||
_cairo_memory_stream_copy (page->xml_node, output);
|
||||
_cairo_output_stream_printf (output, "</g>\n");
|
||||
}
|
||||
|
||||
_cairo_output_stream_printf (output, "</svg>\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);
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
/* -*- Mode: c; tab-width: 8; c-basic-offset: 4; indent-tabs-mode: t; -*- */
|
||||
/*
|
||||
* Copyright © 2002 Keith Packard
|
||||
* Copyright © 2007 Red Hat, Inc.
|
||||
|
@ -44,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);
|
||||
|
||||
|
@ -58,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
|
||||
|
@ -99,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];
|
||||
|
@ -228,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)
|
||||
|
@ -239,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;
|
||||
|
@ -247,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 */
|
||||
|
@ -255,15 +186,27 @@ 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;
|
||||
|
||||
if (traps->traps == traps->traps_embedded) {
|
||||
new_traps = _cairo_malloc_ab (new_size, sizeof (cairo_trapezoid_t));
|
||||
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));
|
||||
}
|
||||
|
@ -276,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
|
||||
|
@ -349,16 +292,21 @@ _cairo_trapezoid_array_translate_and_scale (cairo_trapezoid_t *offset_traps,
|
|||
cairo_fixed_t ysc = _cairo_fixed_from_double (sy);
|
||||
|
||||
for (i = 0; i < num_traps; i++) {
|
||||
offset_traps[i].top = _cairo_fixed_mul (src_traps[i].top + yoff, ysc);
|
||||
offset_traps[i].bottom = _cairo_fixed_mul (src_traps[i].bottom + yoff, ysc);
|
||||
offset_traps[i].left.p1.x = _cairo_fixed_mul (src_traps[i].left.p1.x + xoff, xsc);
|
||||
offset_traps[i].left.p1.y = _cairo_fixed_mul (src_traps[i].left.p1.y + yoff, ysc);
|
||||
offset_traps[i].left.p2.x = _cairo_fixed_mul (src_traps[i].left.p2.x + xoff, xsc);
|
||||
offset_traps[i].left.p2.y = _cairo_fixed_mul (src_traps[i].left.p2.y + yoff, ysc);
|
||||
offset_traps[i].right.p1.x = _cairo_fixed_mul (src_traps[i].right.p1.x + xoff, xsc);
|
||||
offset_traps[i].right.p1.y = _cairo_fixed_mul (src_traps[i].right.p1.y + yoff, ysc);
|
||||
offset_traps[i].right.p2.x = _cairo_fixed_mul (src_traps[i].right.p2.x + xoff, xsc);
|
||||
offset_traps[i].right.p2.y = _cairo_fixed_mul (src_traps[i].right.p2.y + yoff, ysc);
|
||||
#define FIXED_MUL(_a, _b) \
|
||||
(_cairo_int64_to_int32(_cairo_int64_rsl(_cairo_int32x32_64_mul((_a), (_b)), 16)))
|
||||
|
||||
offset_traps[i].top = FIXED_MUL(src_traps[i].top + yoff, ysc);
|
||||
offset_traps[i].bottom = FIXED_MUL(src_traps[i].bottom + yoff, ysc);
|
||||
offset_traps[i].left.p1.x = FIXED_MUL(src_traps[i].left.p1.x + xoff, xsc);
|
||||
offset_traps[i].left.p1.y = FIXED_MUL(src_traps[i].left.p1.y + yoff, ysc);
|
||||
offset_traps[i].left.p2.x = FIXED_MUL(src_traps[i].left.p2.x + xoff, xsc);
|
||||
offset_traps[i].left.p2.y = FIXED_MUL(src_traps[i].left.p2.y + yoff, ysc);
|
||||
offset_traps[i].right.p1.x = FIXED_MUL(src_traps[i].right.p1.x + xoff, xsc);
|
||||
offset_traps[i].right.p1.y = FIXED_MUL(src_traps[i].right.p1.y + yoff, ysc);
|
||||
offset_traps[i].right.p2.x = FIXED_MUL(src_traps[i].right.p2.x + xoff, xsc);
|
||||
offset_traps[i].right.p2.y = FIXED_MUL(src_traps[i].right.p2.y + yoff, ysc);
|
||||
|
||||
#undef FIXED_MUL
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -575,30 +523,32 @@ _cairo_traps_extents (cairo_traps_t *traps, cairo_box_t *extents)
|
|||
*extents = traps->extents;
|
||||
}
|
||||
|
||||
#define STACK_BOXES_LEN ((int) (CAIRO_STACK_BUFFER_SIZE / sizeof(cairo_box_int_t)))
|
||||
|
||||
/**
|
||||
* _cairo_traps_extract_region:
|
||||
* @traps: a #cairo_traps_t
|
||||
* @region: a #cairo_region_t
|
||||
* @region: on return, %NULL is stored here if the trapezoids aren't
|
||||
* exactly representable as a pixman region, otherwise a
|
||||
* a pointer to such a region, newly allocated.
|
||||
* (free with pixman region destroy)
|
||||
*
|
||||
* Determines if a set of trapezoids are exactly representable as a
|
||||
* cairo region. If so, the passed-in region is initialized to
|
||||
* the area representing the given traps. It should be finalized
|
||||
* with _cairo_region_fini(). If not, %CAIRO_INT_STATUS_UNSUPPORTED
|
||||
* is returned.
|
||||
* 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,
|
||||
cairo_region_t *region)
|
||||
cairo_status_t
|
||||
_cairo_traps_extract_region (cairo_traps_t *traps,
|
||||
pixman_region16_t **region)
|
||||
{
|
||||
cairo_box_int_t stack_boxes[STACK_BOXES_LEN];
|
||||
cairo_box_int_t *boxes = stack_boxes;
|
||||
int i, box_count;
|
||||
cairo_int_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
|
||||
|
@ -607,45 +557,31 @@ _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 > ARRAY_LENGTH(stack_boxes)) {
|
||||
boxes = _cairo_malloc_ab (traps->num_traps, sizeof(cairo_box_int_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].p1.x = x1;
|
||||
boxes[box_count].p1.y = y1;
|
||||
boxes[box_count].p2.x = x2;
|
||||
boxes[box_count].p2.y = y2;
|
||||
|
||||
box_count++;
|
||||
if (pixman_region_union_rect (*region, *region,
|
||||
x, y, width, height) != PIXMAN_REGION_STATUS_SUCCESS) {
|
||||
pixman_region_destroy (*region);
|
||||
return CAIRO_STATUS_NO_MEMORY;
|
||||
}
|
||||
}
|
||||
|
||||
status = _cairo_region_init_boxes (region, boxes, box_count);
|
||||
|
||||
if (boxes != stack_boxes)
|
||||
free (boxes);
|
||||
|
||||
if (status)
|
||||
_cairo_region_fini (region);
|
||||
|
||||
return status;
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
}
|
||||
|
|
|
@ -34,8 +34,8 @@
|
|||
* Adrian Johnson <ajohnson@redneon.com>
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
#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);
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -46,8 +46,6 @@
|
|||
#include FT_OUTLINE_H
|
||||
#include FT_TYPE1_TABLES_H
|
||||
|
||||
#include <ctype.h>
|
||||
|
||||
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;
|
||||
}
|
||||
|
|
|
@ -40,7 +40,9 @@
|
|||
* Owen Taylor <otaylor@redhat.com>
|
||||
*/
|
||||
|
||||
#include "cairoint.h"
|
||||
#include <limits.h>
|
||||
|
||||
#include <cairoint.h>
|
||||
|
||||
#define UTF8_COMPUTE(Char, Mask, Len) \
|
||||
if (Char < 128) \
|
||||
|
@ -240,7 +242,7 @@ _cairo_utf8_to_ucs4 (const unsigned char *str,
|
|||
in = UTF8_NEXT_CHAR (in);
|
||||
}
|
||||
|
||||
str32 = _cairo_malloc_ab (n_chars + 1, sizeof (uint32_t));
|
||||
str32 = malloc (sizeof (uint32_t) * (n_chars + 1));
|
||||
if (!str32)
|
||||
return CAIRO_STATUS_NO_MEMORY;
|
||||
|
||||
|
@ -307,7 +309,7 @@ _cairo_utf8_to_utf16 (const unsigned char *str,
|
|||
in = UTF8_NEXT_CHAR (in);
|
||||
}
|
||||
|
||||
str16 = _cairo_malloc_ab (n16 + 1, sizeof (uint16_t));
|
||||
str16 = malloc (sizeof (uint16_t) * (n16 + 1));
|
||||
if (!str16)
|
||||
return CAIRO_STATUS_NO_MEMORY;
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 <string.h>
|
||||
#include <stdio.h>
|
||||
#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)
|
||||
|
@ -630,8 +631,8 @@ _cairo_win32_scaled_font_text_to_glyphs (void *abstract_font,
|
|||
dx = NULL;
|
||||
}
|
||||
|
||||
glyph_indices = _cairo_malloc_ab (buffer_size, sizeof (WCHAR));
|
||||
dx = _cairo_malloc_ab (buffer_size, sizeof (int));
|
||||
glyph_indices = malloc (sizeof (WCHAR) * buffer_size);
|
||||
dx = malloc (sizeof (int) * buffer_size);
|
||||
if (!glyph_indices || !dx) {
|
||||
status = CAIRO_STATUS_NO_MEMORY;
|
||||
goto FAIL2;
|
||||
|
@ -662,7 +663,7 @@ _cairo_win32_scaled_font_text_to_glyphs (void *abstract_font,
|
|||
}
|
||||
|
||||
*num_glyphs = gcp_results.nGlyphs;
|
||||
*glyphs = _cairo_malloc_ab (gcp_results.nGlyphs, sizeof (cairo_glyph_t));
|
||||
*glyphs = malloc (sizeof (cairo_glyph_t) * gcp_results.nGlyphs);
|
||||
if (!*glyphs) {
|
||||
status = CAIRO_STATUS_NO_MEMORY;
|
||||
goto FAIL2;
|
||||
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
@ -71,11 +75,11 @@ typedef struct _cairo_win32_surface {
|
|||
|
||||
cairo_surface_t *image;
|
||||
|
||||
cairo_rectangle_int_t clip_rect;
|
||||
cairo_rectangle_int16_t clip_rect;
|
||||
|
||||
HRGN saved_clip;
|
||||
|
||||
cairo_rectangle_int_t extents;
|
||||
cairo_rectangle_int16_t extents;
|
||||
|
||||
/* Surface DC flags */
|
||||
uint32_t flags;
|
||||
|
@ -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 */
|
||||
|
|
|
@ -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 <windows.h>
|
||||
|
||||
#if defined(__MINGW32__) && !defined(ETO_PDY)
|
||||
# define ETO_PDY 0x2000
|
||||
#endif
|
||||
#include <stdio.h>
|
||||
#include "cairoint.h"
|
||||
#include "cairo-clip-private.h"
|
||||
#include "cairo-win32-private.h"
|
||||
|
||||
#undef DEBUG_COMPOSITE
|
||||
|
||||
|
@ -186,7 +181,7 @@ _create_dc_and_bitmap (cairo_win32_surface_t *surface,
|
|||
}
|
||||
|
||||
if (num_palette > 2) {
|
||||
bitmap_info = _cairo_malloc_ab_plus_c (num_palette, sizeof(RGBQUAD), sizeof(BITMAPINFOHEADER));
|
||||
bitmap_info = malloc (sizeof (BITMAPINFOHEADER) + num_palette * sizeof (RGBQUAD));
|
||||
if (!bitmap_info)
|
||||
return CAIRO_STATUS_NO_MEMORY;
|
||||
} else {
|
||||
|
@ -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,
|
||||
|
@ -547,9 +549,9 @@ _cairo_win32_surface_release_source_image (void *abstract_surf
|
|||
|
||||
static cairo_status_t
|
||||
_cairo_win32_surface_acquire_dest_image (void *abstract_surface,
|
||||
cairo_rectangle_int_t *interest_rect,
|
||||
cairo_rectangle_int16_t *interest_rect,
|
||||
cairo_image_surface_t **image_out,
|
||||
cairo_rectangle_int_t *image_rect,
|
||||
cairo_rectangle_int16_t *image_rect,
|
||||
void **image_extra)
|
||||
{
|
||||
cairo_win32_surface_t *surface = abstract_surface;
|
||||
|
@ -615,9 +617,9 @@ _cairo_win32_surface_acquire_dest_image (void *abstract_surfa
|
|||
|
||||
static void
|
||||
_cairo_win32_surface_release_dest_image (void *abstract_surface,
|
||||
cairo_rectangle_int_t *interest_rect,
|
||||
cairo_rectangle_int16_t *interest_rect,
|
||||
cairo_image_surface_t *image,
|
||||
cairo_rectangle_int_t *image_rect,
|
||||
cairo_rectangle_int16_t *image_rect,
|
||||
void *image_extra)
|
||||
{
|
||||
cairo_win32_surface_t *surface = abstract_surface;
|
||||
|
@ -736,7 +738,7 @@ static cairo_int_status_t
|
|||
_cairo_win32_surface_composite_inner (cairo_win32_surface_t *src,
|
||||
cairo_image_surface_t *src_image,
|
||||
cairo_win32_surface_t *dst,
|
||||
cairo_rectangle_int_t src_extents,
|
||||
cairo_rectangle_int16_t src_extents,
|
||||
cairo_rectangle_int32_t src_r,
|
||||
cairo_rectangle_int32_t dst_r,
|
||||
int alpha,
|
||||
|
@ -844,7 +846,7 @@ _cairo_win32_surface_composite (cairo_operator_t op,
|
|||
cairo_image_surface_t *src_image = NULL;
|
||||
|
||||
cairo_format_t src_format;
|
||||
cairo_rectangle_int_t src_extents;
|
||||
cairo_rectangle_int16_t src_extents;
|
||||
|
||||
cairo_rectangle_int32_t src_r = { src_x, src_y, width, height };
|
||||
cairo_rectangle_int32_t dst_r = { dst_x, dst_y, width, height };
|
||||
|
@ -1312,7 +1314,7 @@ static cairo_int_status_t
|
|||
_cairo_win32_surface_fill_rectangles (void *abstract_surface,
|
||||
cairo_operator_t op,
|
||||
const cairo_color_t *color,
|
||||
cairo_rectangle_int_t *rects,
|
||||
cairo_rectangle_int16_t *rects,
|
||||
int num_rects)
|
||||
{
|
||||
cairo_win32_surface_t *surface = abstract_surface;
|
||||
|
@ -1374,8 +1376,8 @@ _cairo_win32_surface_fill_rectangles (void *abstract_surface,
|
|||
}
|
||||
|
||||
static cairo_int_status_t
|
||||
_cairo_win32_surface_set_clip_region (void *abstract_surface,
|
||||
cairo_region_t *region)
|
||||
_cairo_win32_surface_set_clip_region (void *abstract_surface,
|
||||
pixman_region16_t *region)
|
||||
{
|
||||
cairo_win32_surface_t *surface = abstract_surface;
|
||||
cairo_status_t status;
|
||||
|
@ -1404,9 +1406,9 @@ _cairo_win32_surface_set_clip_region (void *abstract_surface,
|
|||
return CAIRO_STATUS_SUCCESS;
|
||||
|
||||
} else {
|
||||
cairo_rectangle_int_t extents;
|
||||
cairo_box_int_t *boxes;
|
||||
int num_boxes;
|
||||
pixman_box16_t *boxes = pixman_region_rects (region);
|
||||
int num_boxes = pixman_region_num_rects (region);
|
||||
pixman_box16_t *extents = pixman_region_extents (region);
|
||||
RGNDATA *data;
|
||||
size_t data_size;
|
||||
RECT *rects;
|
||||
|
@ -1415,36 +1417,28 @@ _cairo_win32_surface_set_clip_region (void *abstract_surface,
|
|||
|
||||
/* Create a GDI region for the cairo region */
|
||||
|
||||
_cairo_region_get_extents (region, &extents);
|
||||
if (_cairo_region_get_boxes (region, &num_boxes, &boxes) != CAIRO_STATUS_SUCCESS)
|
||||
return CAIRO_STATUS_NO_MEMORY;
|
||||
|
||||
data_size = sizeof (RGNDATAHEADER) + num_boxes * sizeof (RECT);
|
||||
data = malloc (data_size);
|
||||
if (!data) {
|
||||
_cairo_region_boxes_fini (region, boxes);
|
||||
if (!data)
|
||||
return CAIRO_STATUS_NO_MEMORY;
|
||||
}
|
||||
rects = (RECT *)data->Buffer;
|
||||
|
||||
data->rdh.dwSize = sizeof (RGNDATAHEADER);
|
||||
data->rdh.iType = RDH_RECTANGLES;
|
||||
data->rdh.nCount = num_boxes;
|
||||
data->rdh.nRgnSize = num_boxes * sizeof (RECT);
|
||||
data->rdh.rcBound.left = extents.x;
|
||||
data->rdh.rcBound.top = extents.y;
|
||||
data->rdh.rcBound.right = extents.x + extents.width;
|
||||
data->rdh.rcBound.bottom = extents.y + extents.height;
|
||||
data->rdh.rcBound.left = extents->x1;
|
||||
data->rdh.rcBound.top = extents->y1;
|
||||
data->rdh.rcBound.right = extents->x2;
|
||||
data->rdh.rcBound.bottom = extents->y2;
|
||||
|
||||
for (i = 0; i < num_boxes; i++) {
|
||||
rects[i].left = boxes[i].p1.x;
|
||||
rects[i].top = boxes[i].p1.y;
|
||||
rects[i].right = boxes[i].p2.x;
|
||||
rects[i].bottom = boxes[i].p2.y;
|
||||
rects[i].left = boxes[i].x1;
|
||||
rects[i].top = boxes[i].y1;
|
||||
rects[i].right = boxes[i].x2;
|
||||
rects[i].bottom = boxes[i].y2;
|
||||
}
|
||||
|
||||
_cairo_region_boxes_fini (region, boxes);
|
||||
|
||||
gdi_region = ExtCreateRegion (NULL, data_size, data);
|
||||
free (data);
|
||||
|
||||
|
@ -1473,7 +1467,7 @@ _cairo_win32_surface_set_clip_region (void *abstract_surface,
|
|||
|
||||
static cairo_int_status_t
|
||||
_cairo_win32_surface_get_extents (void *abstract_surface,
|
||||
cairo_rectangle_int_t *rectangle)
|
||||
cairo_rectangle_int16_t *rectangle)
|
||||
{
|
||||
cairo_win32_surface_t *surface = abstract_surface;
|
||||
|
||||
|
@ -1554,8 +1548,8 @@ _cairo_win32_surface_show_glyphs (void *surface,
|
|||
SetBkMode(dst->dc, TRANSPARENT);
|
||||
|
||||
if (num_glyphs > STACK_GLYPH_SIZE) {
|
||||
glyph_buf = (WORD *) _cairo_malloc_ab (num_glyphs, sizeof(WORD));
|
||||
dxy_buf = (int *) _cairo_malloc_abc (num_glyphs, sizeof(int), 2);
|
||||
glyph_buf = (WORD *)malloc(num_glyphs * sizeof(WORD));
|
||||
dxy_buf = (int *)malloc(num_glyphs * 2 * sizeof(int));
|
||||
}
|
||||
|
||||
/* It is vital that dx values for dxy_buf are calculated from the delta of
|
||||
|
@ -1646,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) {
|
||||
|
@ -1863,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,
|
||||
|
@ -1917,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
|
||||
|
@ -1936,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
|
||||
|
||||
|
|
|
@ -297,14 +297,14 @@ _CAIRO_MASK_FORMAT (cairo_format_masks_t *masks, cairo_format_t *format)
|
|||
|
||||
static cairo_status_t
|
||||
_get_image_surface (cairo_xcb_surface_t *surface,
|
||||
cairo_rectangle_int_t *interest_rect,
|
||||
cairo_rectangle_int16_t *interest_rect,
|
||||
cairo_image_surface_t **image_out,
|
||||
cairo_rectangle_int_t *image_rect)
|
||||
cairo_rectangle_int16_t *image_rect)
|
||||
{
|
||||
cairo_image_surface_t *image;
|
||||
xcb_get_image_reply_t *imagerep;
|
||||
int bpp, bytes_per_line;
|
||||
short x1, y1, x2, y2;
|
||||
int x1, y1, x2, y2;
|
||||
unsigned char *data;
|
||||
cairo_format_masks_t masks;
|
||||
cairo_format_t format;
|
||||
|
@ -403,7 +403,7 @@ _get_image_surface (cairo_xcb_surface_t *surface,
|
|||
bpp = _bits_per_pixel(surface->dpy, imagerep->depth);
|
||||
bytes_per_line = _bytes_per_line(surface->dpy, surface->width, bpp);
|
||||
|
||||
data = _cairo_malloc_ab (surface->height, bytes_per_line);
|
||||
data = malloc (bytes_per_line * surface->height);
|
||||
if (data == NULL) {
|
||||
free (imagerep);
|
||||
return CAIRO_STATUS_NO_MEMORY;
|
||||
|
@ -642,9 +642,9 @@ _cairo_xcb_surface_release_source_image (void *abstract_surfac
|
|||
|
||||
static cairo_status_t
|
||||
_cairo_xcb_surface_acquire_dest_image (void *abstract_surface,
|
||||
cairo_rectangle_int_t *interest_rect,
|
||||
cairo_rectangle_int16_t *interest_rect,
|
||||
cairo_image_surface_t **image_out,
|
||||
cairo_rectangle_int_t *image_rect_out,
|
||||
cairo_rectangle_int16_t *image_rect_out,
|
||||
void **image_extra)
|
||||
{
|
||||
cairo_xcb_surface_t *surface = abstract_surface;
|
||||
|
@ -663,9 +663,9 @@ _cairo_xcb_surface_acquire_dest_image (void *abstract_surface
|
|||
|
||||
static void
|
||||
_cairo_xcb_surface_release_dest_image (void *abstract_surface,
|
||||
cairo_rectangle_int_t *interest_rect,
|
||||
cairo_rectangle_int16_t *interest_rect,
|
||||
cairo_image_surface_t *image,
|
||||
cairo_rectangle_int_t *image_rect,
|
||||
cairo_rectangle_int16_t *image_rect,
|
||||
void *image_extra)
|
||||
{
|
||||
cairo_xcb_surface_t *surface = abstract_surface;
|
||||
|
@ -742,17 +742,17 @@ _cairo_xcb_surface_set_matrix (cairo_xcb_surface_t *surface,
|
|||
if (!surface->src_picture)
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
|
||||
xtransform.matrix11 = _cairo_fixed_16_16_from_double (matrix->xx);
|
||||
xtransform.matrix12 = _cairo_fixed_16_16_from_double (matrix->xy);
|
||||
xtransform.matrix13 = _cairo_fixed_16_16_from_double (matrix->x0);
|
||||
xtransform.matrix11 = _cairo_fixed_from_double (matrix->xx);
|
||||
xtransform.matrix12 = _cairo_fixed_from_double (matrix->xy);
|
||||
xtransform.matrix13 = _cairo_fixed_from_double (matrix->x0);
|
||||
|
||||
xtransform.matrix21 = _cairo_fixed_16_16_from_double (matrix->yx);
|
||||
xtransform.matrix22 = _cairo_fixed_16_16_from_double (matrix->yy);
|
||||
xtransform.matrix23 = _cairo_fixed_16_16_from_double (matrix->y0);
|
||||
xtransform.matrix21 = _cairo_fixed_from_double (matrix->yx);
|
||||
xtransform.matrix22 = _cairo_fixed_from_double (matrix->yy);
|
||||
xtransform.matrix23 = _cairo_fixed_from_double (matrix->y0);
|
||||
|
||||
xtransform.matrix31 = 0;
|
||||
xtransform.matrix32 = 0;
|
||||
xtransform.matrix33 = 1 << 16;
|
||||
xtransform.matrix33 = _cairo_fixed_from_double (1);
|
||||
|
||||
if (!CAIRO_SURFACE_RENDER_HAS_PICTURE_TRANSFORM (surface))
|
||||
{
|
||||
|
@ -1246,14 +1246,11 @@ static cairo_int_status_t
|
|||
_cairo_xcb_surface_fill_rectangles (void *abstract_surface,
|
||||
cairo_operator_t op,
|
||||
const cairo_color_t * color,
|
||||
cairo_rectangle_int_t *rects,
|
||||
cairo_rectangle_int16_t *rects,
|
||||
int num_rects)
|
||||
{
|
||||
cairo_xcb_surface_t *surface = abstract_surface;
|
||||
xcb_render_color_t render_color;
|
||||
xcb_rectangle_t static_xrects[16];
|
||||
xcb_rectangle_t *xrects = static_xrects;
|
||||
int i;
|
||||
|
||||
if (!CAIRO_SURFACE_RENDER_HAS_FILL_RECTANGLE (surface))
|
||||
return CAIRO_INT_STATUS_UNSUPPORTED;
|
||||
|
@ -1263,27 +1260,12 @@ _cairo_xcb_surface_fill_rectangles (void *abstract_surface,
|
|||
render_color.blue = color->blue_short;
|
||||
render_color.alpha = color->alpha_short;
|
||||
|
||||
if (num_rects > ARRAY_LENGTH(static_xrects)) {
|
||||
xrects = _cairo_malloc_ab (num_rects, sizeof(xcb_rectangle_t));
|
||||
if (xrects == NULL)
|
||||
return CAIRO_STATUS_NO_MEMORY;
|
||||
}
|
||||
|
||||
for (i = 0; i < num_rects; i++) {
|
||||
xrects[i].x = rects[i].x;
|
||||
xrects[i].y = rects[i].y;
|
||||
xrects[i].width = rects[i].width;
|
||||
xrects[i].height = rects[i].height;
|
||||
}
|
||||
|
||||
/* XXX: This xcb_rectangle_t cast is evil... it needs to go away somehow. */
|
||||
_cairo_xcb_surface_ensure_dst_picture (surface);
|
||||
xcb_render_fill_rectangles (surface->dpy,
|
||||
_render_operator (op),
|
||||
surface->dst_picture,
|
||||
render_color, num_rects, xrects);
|
||||
|
||||
if (xrects != static_xrects)
|
||||
free(xrects);
|
||||
render_color, num_rects, (xcb_rectangle_t *) rects);
|
||||
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
}
|
||||
|
@ -1346,21 +1328,21 @@ _create_trapezoid_mask (cairo_xcb_surface_t *dst,
|
|||
mask_picture = _create_a8_picture (dst, &transparent, width, height, FALSE);
|
||||
solid_picture = _create_a8_picture (dst, &solid, width, height, TRUE);
|
||||
|
||||
offset_traps = _cairo_malloc_ab (num_traps, sizeof (xcb_render_trapezoid_t));
|
||||
offset_traps = malloc (sizeof (xcb_render_trapezoid_t) * num_traps);
|
||||
if (!offset_traps)
|
||||
return XCB_NONE;
|
||||
|
||||
for (i = 0; i < num_traps; i++) {
|
||||
offset_traps[i].top = _cairo_fixed_to_16_16(traps[i].top) - 0x10000 * dst_y;
|
||||
offset_traps[i].bottom = _cairo_fixed_to_16_16(traps[i].bottom) - 0x10000 * dst_y;
|
||||
offset_traps[i].left.p1.x = _cairo_fixed_to_16_16(traps[i].left.p1.x) - 0x10000 * dst_x;
|
||||
offset_traps[i].left.p1.y = _cairo_fixed_to_16_16(traps[i].left.p1.y) - 0x10000 * dst_y;
|
||||
offset_traps[i].left.p2.x = _cairo_fixed_to_16_16(traps[i].left.p2.x) - 0x10000 * dst_x;
|
||||
offset_traps[i].left.p2.y = _cairo_fixed_to_16_16(traps[i].left.p2.y) - 0x10000 * dst_y;
|
||||
offset_traps[i].right.p1.x = _cairo_fixed_to_16_16(traps[i].right.p1.x) - 0x10000 * dst_x;
|
||||
offset_traps[i].right.p1.y = _cairo_fixed_to_16_16(traps[i].right.p1.y) - 0x10000 * dst_y;
|
||||
offset_traps[i].right.p2.x = _cairo_fixed_to_16_16(traps[i].right.p2.x) - 0x10000 * dst_x;
|
||||
offset_traps[i].right.p2.y = _cairo_fixed_to_16_16(traps[i].right.p2.y) - 0x10000 * dst_y;
|
||||
offset_traps[i].top = traps[i].top - 0x10000 * dst_y;
|
||||
offset_traps[i].bottom = traps[i].bottom - 0x10000 * dst_y;
|
||||
offset_traps[i].left.p1.x = traps[i].left.p1.x - 0x10000 * dst_x;
|
||||
offset_traps[i].left.p1.y = traps[i].left.p1.y - 0x10000 * dst_y;
|
||||
offset_traps[i].left.p2.x = traps[i].left.p2.x - 0x10000 * dst_x;
|
||||
offset_traps[i].left.p2.y = traps[i].left.p2.y - 0x10000 * dst_y;
|
||||
offset_traps[i].right.p1.x = traps[i].right.p1.x - 0x10000 * dst_x;
|
||||
offset_traps[i].right.p1.y = traps[i].right.p1.y - 0x10000 * dst_y;
|
||||
offset_traps[i].right.p2.x = traps[i].right.p2.x - 0x10000 * dst_x;
|
||||
offset_traps[i].right.p2.y = traps[i].right.p2.y - 0x10000 * dst_y;
|
||||
}
|
||||
|
||||
xcb_render_trapezoids (dst->dpy, XCB_RENDER_PICT_OP_ADD,
|
||||
|
@ -1488,41 +1470,14 @@ _cairo_xcb_surface_composite_trapezoids (cairo_operator_t op,
|
|||
dst_x, dst_y, width, height);
|
||||
|
||||
} else {
|
||||
xcb_render_trapezoid_t xtraps_stack[16];
|
||||
xcb_render_trapezoid_t *xtraps = xtraps_stack;
|
||||
int i;
|
||||
|
||||
if (num_traps > ARRAY_LENGTH(xtraps_stack)) {
|
||||
xtraps = _cairo_malloc_ab (num_traps, sizeof(xcb_render_trapezoid_t));
|
||||
if (xtraps == NULL) {
|
||||
status = CAIRO_STATUS_NO_MEMORY;
|
||||
goto BAIL;
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0; i < num_traps; i++) {
|
||||
xtraps[i].top = _cairo_fixed_to_16_16(traps[i].top);
|
||||
xtraps[i].bottom = _cairo_fixed_to_16_16(traps[i].bottom);
|
||||
xtraps[i].left.p1.x = _cairo_fixed_to_16_16(traps[i].left.p1.x);
|
||||
xtraps[i].left.p1.y = _cairo_fixed_to_16_16(traps[i].left.p1.y);
|
||||
xtraps[i].left.p2.x = _cairo_fixed_to_16_16(traps[i].left.p2.x);
|
||||
xtraps[i].left.p2.y = _cairo_fixed_to_16_16(traps[i].left.p2.y);
|
||||
xtraps[i].right.p1.x = _cairo_fixed_to_16_16(traps[i].right.p1.x);
|
||||
xtraps[i].right.p1.y = _cairo_fixed_to_16_16(traps[i].right.p1.y);
|
||||
xtraps[i].right.p2.x = _cairo_fixed_to_16_16(traps[i].right.p2.x);
|
||||
xtraps[i].right.p2.y = _cairo_fixed_to_16_16(traps[i].right.p2.y);
|
||||
}
|
||||
|
||||
/* XXX: The XTrapezoid cast is evil and needs to go away somehow. */
|
||||
xcb_render_trapezoids (dst->dpy,
|
||||
_render_operator (op),
|
||||
src->src_picture, dst->dst_picture,
|
||||
render_format->id,
|
||||
render_src_x + attributes.x_offset,
|
||||
render_src_y + attributes.y_offset,
|
||||
num_traps, xtraps);
|
||||
|
||||
if (xtraps != xtraps_stack)
|
||||
free(xtraps);
|
||||
num_traps, (xcb_render_trapezoid_t *) traps);
|
||||
}
|
||||
|
||||
BAIL:
|
||||
|
@ -1532,8 +1487,8 @@ _cairo_xcb_surface_composite_trapezoids (cairo_operator_t op,
|
|||
}
|
||||
|
||||
static cairo_int_status_t
|
||||
_cairo_xcb_surface_set_clip_region (void *abstract_surface,
|
||||
cairo_region_t *region)
|
||||
_cairo_xcb_surface_set_clip_region (void *abstract_surface,
|
||||
pixman_region16_t *region)
|
||||
{
|
||||
cairo_xcb_surface_t *surface = abstract_surface;
|
||||
|
||||
|
@ -1554,31 +1509,27 @@ _cairo_xcb_surface_set_clip_region (void *abstract_surface,
|
|||
xcb_render_change_picture (surface->dpy, surface->dst_picture,
|
||||
XCB_RENDER_CP_CLIP_MASK, none);
|
||||
} else {
|
||||
cairo_box_int_t *boxes;
|
||||
pixman_box16_t *boxes;
|
||||
xcb_rectangle_t *rects = NULL;
|
||||
int n_boxes, i;
|
||||
|
||||
if (_cairo_region_get_boxes (region, &n_boxes, &boxes) != CAIRO_STATUS_SUCCESS)
|
||||
return CAIRO_STATUS_NO_MEMORY;
|
||||
|
||||
n_boxes = pixman_region_num_rects (region);
|
||||
if (n_boxes > 0) {
|
||||
rects = _cairo_malloc_ab (n_boxes, sizeof(xcb_rectangle_t));
|
||||
if (rects == NULL) {
|
||||
_cairo_region_boxes_fini (region, boxes);
|
||||
rects = malloc (sizeof(xcb_rectangle_t) * n_boxes);
|
||||
if (rects == NULL)
|
||||
return CAIRO_STATUS_NO_MEMORY;
|
||||
}
|
||||
} else {
|
||||
rects = NULL;
|
||||
}
|
||||
|
||||
for (i = 0; i < n_boxes; i++) {
|
||||
rects[i].x = boxes[i].p1.x;
|
||||
rects[i].y = boxes[i].p1.y;
|
||||
rects[i].width = boxes[i].p2.x - boxes[i].p1.x;
|
||||
rects[i].height = boxes[i].p2.y - boxes[i].p1.y;
|
||||
}
|
||||
boxes = pixman_region_rects (region);
|
||||
|
||||
_cairo_region_boxes_fini (region, boxes);
|
||||
for (i = 0; i < n_boxes; i++) {
|
||||
rects[i].x = boxes[i].x1;
|
||||
rects[i].y = boxes[i].y1;
|
||||
rects[i].width = boxes[i].x2 - boxes[i].x1;
|
||||
rects[i].height = boxes[i].y2 - boxes[i].y1;
|
||||
}
|
||||
|
||||
surface->have_clip_rects = TRUE;
|
||||
surface->clip_rects = rects;
|
||||
|
@ -1596,7 +1547,7 @@ _cairo_xcb_surface_set_clip_region (void *abstract_surface,
|
|||
|
||||
static cairo_int_status_t
|
||||
_cairo_xcb_surface_get_extents (void *abstract_surface,
|
||||
cairo_rectangle_int_t *rectangle)
|
||||
cairo_rectangle_int16_t *rectangle)
|
||||
{
|
||||
cairo_xcb_surface_t *surface = abstract_surface;
|
||||
|
||||
|
@ -1626,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 = {
|
||||
|
@ -1690,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 */
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -2409,7 +2323,7 @@ _cairo_xcb_surface_show_glyphs (void *abstract_dst,
|
|||
/* We make a copy of the glyphs so that we can elide any size-zero
|
||||
* glyphs to workaround an X server bug, (present in at least Xorg
|
||||
* 7.1 without EXA). */
|
||||
output_glyphs = _cairo_malloc_ab (num_glyphs, sizeof (cairo_glyph_t));
|
||||
output_glyphs = malloc (num_glyphs * sizeof (cairo_glyph_t));
|
||||
if (output_glyphs == NULL)
|
||||
return CAIRO_STATUS_NO_MEMORY;
|
||||
|
||||
|
@ -2430,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;
|
||||
}
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -51,13 +51,14 @@
|
|||
* TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
||||
* PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "cairoint.h"
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "cairo-xlib-private.h"
|
||||
|
||||
#include <fontconfig/fontconfig.h>
|
||||
|
||||
#include <X11/Xlibint.h> /* For XESetCloseDisplay */
|
||||
#include <X11/extensions/Xrender.h>
|
||||
|
||||
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 ();
|
||||
}
|
||||
|
|
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
|
@ -41,7 +41,6 @@
|
|||
|
||||
#if CAIRO_HAS_XLIB_SURFACE
|
||||
|
||||
#include <X11/Xlib.h>
|
||||
#include <X11/extensions/Xrender.h>
|
||||
|
||||
CAIRO_BEGIN_DECLS
|
||||
|
|
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
|
@ -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
|
||||
|
|
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
|
@ -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;
|
||||
}
|
||||
|
@ -140,9 +139,9 @@ _test_fallback_surface_release_source_image (void *abstract_surface,
|
|||
|
||||
static cairo_status_t
|
||||
_test_fallback_surface_acquire_dest_image (void *abstract_surface,
|
||||
cairo_rectangle_int_t *interest_rect,
|
||||
cairo_rectangle_int16_t *interest_rect,
|
||||
cairo_image_surface_t **image_out,
|
||||
cairo_rectangle_int_t *image_rect_out,
|
||||
cairo_rectangle_int16_t *image_rect_out,
|
||||
void **image_extra)
|
||||
{
|
||||
test_fallback_surface_t *surface = abstract_surface;
|
||||
|
@ -156,9 +155,9 @@ _test_fallback_surface_acquire_dest_image (void *abstract_surface,
|
|||
|
||||
static void
|
||||
_test_fallback_surface_release_dest_image (void *abstract_surface,
|
||||
cairo_rectangle_int_t *interest_rect,
|
||||
cairo_rectangle_int16_t *interest_rect,
|
||||
cairo_image_surface_t *image,
|
||||
cairo_rectangle_int_t *image_rect,
|
||||
cairo_rectangle_int16_t *image_rect,
|
||||
void *image_extra)
|
||||
{
|
||||
test_fallback_surface_t *surface = abstract_surface;
|
||||
|
@ -170,29 +169,9 @@ _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_int_t *rectangle)
|
||||
_test_fallback_surface_get_extents (void *abstract_surface,
|
||||
cairo_rectangle_int16_t *rectangle)
|
||||
{
|
||||
test_fallback_surface_t *surface = abstract_surface;
|
||||
|
||||
|
@ -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 */
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
@ -174,7 +170,7 @@ _test_meta_surface_intersect_clip_path (void *abstract_surface,
|
|||
|
||||
static cairo_int_status_t
|
||||
_test_meta_surface_get_extents (void *abstract_surface,
|
||||
cairo_rectangle_int_t *rectangle)
|
||||
cairo_rectangle_int16_t *rectangle)
|
||||
{
|
||||
test_meta_surface_t *surface = abstract_surface;
|
||||
|
||||
|
@ -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"
|
||||
|
@ -300,23 +295,17 @@ _test_meta_surface_snapshot (void *abstract_other)
|
|||
#if 0
|
||||
return _cairo_surface_snapshot (other->meta);
|
||||
#else
|
||||
cairo_rectangle_int_t extents;
|
||||
cairo_rectangle_int16_t extents;
|
||||
cairo_surface_t *surface;
|
||||
|
||||
status = _cairo_surface_get_extents (other->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
|
||||
|
|
|
@ -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;
|
||||
|
@ -107,7 +107,7 @@ _test_paginated_surface_finish (void *abstract_surface)
|
|||
|
||||
static cairo_int_status_t
|
||||
_test_paginated_surface_set_clip_region (void *abstract_surface,
|
||||
cairo_region_t *region)
|
||||
pixman_region16_t *region)
|
||||
{
|
||||
test_paginated_surface_t *surface = abstract_surface;
|
||||
|
||||
|
@ -149,7 +149,7 @@ _test_paginated_surface_set_clip_region (void *abstract_surface,
|
|||
|
||||
static cairo_int_status_t
|
||||
_test_paginated_surface_get_extents (void *abstract_surface,
|
||||
cairo_rectangle_int_t *rectangle)
|
||||
cairo_rectangle_int16_t *rectangle)
|
||||
{
|
||||
test_paginated_surface_t *surface = abstract_surface;
|
||||
|
||||
|
|
|
@ -0,0 +1,19 @@
|
|||
David R Bacon <dbacon@cis.ksu.edu> Fixes to compile on x86_64.
|
||||
Billy Biggs <vektor@dumbterm.net> Fix to use stdint datatypes.
|
||||
Dave Beckett <Dave.Beckett@bristol.ac.uk> Combined libpixregion, libic, and slim.
|
||||
Jakub Bogusz <qboosh@pld-linux.org> Fixes for 64-bit machines.
|
||||
Anders Carlsson <andersca@gnome.org> Build fixes. New accessor functions.
|
||||
Richard Henderson <rth@twiddle.net> "slim" macros for better shared libraries
|
||||
Owen Taylor <otaylor@redhat.com> Support for both transform and repeat
|
||||
Keith Packard <keithp@keithp.com> The original implementation of the compositing code.
|
||||
David Reveman <c99drn@cs.umu.se> Byte-order, clipping and format fixes.
|
||||
Vladimir Vukicevic <vladimir@pobox.com> Bug fix.
|
||||
Bryan Worth <bryan@theworths.org> Cleanups to not depend on X header files.
|
||||
Carl Worth <carl@theworths.org> General maintenance. Original port from X server code.
|
||||
Richard Worth <richard@theworths.org> Build fixes for cygwin.
|
||||
|
||||
and the "X Window System authors" (pixregion code)
|
||||
|
||||
(Please let us know if we have missed anyone. I would be interested in
|
||||
having more precise attribution for the pixregion code if anyone knows
|
||||
who wrote that.)
|
|
@ -0,0 +1,92 @@
|
|||
libpixregion
|
||||
|
||||
Copyright 1987, 1998 The Open Group
|
||||
|
||||
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.
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
|
||||
AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
Except as contained in this notice, the name of The Open Group shall not be
|
||||
used in advertising or otherwise to promote the sale, use or other dealings
|
||||
in this Software without prior written authorization from The Open Group.
|
||||
|
||||
|
||||
Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts.
|
||||
|
||||
All Rights Reserved
|
||||
|
||||
Permission to use, copy, modify, and distribute this software and its
|
||||
documentation for any purpose and without fee is hereby granted,
|
||||
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 Digital not be
|
||||
used in advertising or publicity pertaining to distribution of the
|
||||
software without specific, written prior permission.
|
||||
|
||||
DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
|
||||
ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
|
||||
DIGITAL 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.
|
||||
|
||||
----------------------------------------------------------------------
|
||||
libic
|
||||
|
||||
Copyright © 2001 Keith Packard
|
||||
|
||||
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 Keith Packard not be used in
|
||||
advertising or publicity pertaining to distribution of the software without
|
||||
specific, written prior permission. Keith Packard makes no
|
||||
representations about the suitability of this software for any purpose. It
|
||||
is provided "as is" without express or implied warranty.
|
||||
|
||||
KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
|
||||
INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
|
||||
EVENT SHALL KEITH PACKARD 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.
|
||||
|
||||
----------------------------------------------------------------------
|
||||
slim
|
||||
|
||||
slim is Copyright © 2003 Richard Henderson
|
||||
|
||||
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 Richard Henderson not be
|
||||
used in advertising or publicity pertaining to distribution of the
|
||||
software without specific, written prior permission. Richard Henderson
|
||||
makes no representations about the suitability of this software for
|
||||
any purpose. It is provided "as is" without express or implied
|
||||
warranty.
|
||||
|
||||
RICHARD HENDERSON DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
|
||||
INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
|
||||
EVENT SHALL RICHARD HENDERSON 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.
|
||||
|
|
@ -1,234 +1,9 @@
|
|||
Installation Instructions
|
||||
*************************
|
||||
This code uses automake, in order to generate the Makefiles use:
|
||||
|
||||
Copyright (C) 1994, 1995, 1996, 1999, 2000, 2001, 2002, 2004, 2005,
|
||||
2006 Free Software Foundation, Inc.
|
||||
$ autogen.sh
|
||||
|
||||
This file is free documentation; the Free Software Foundation gives
|
||||
unlimited permission to copy, distribute and modify it.
|
||||
After that, standard build procedures apply:
|
||||
|
||||
Basic Installation
|
||||
==================
|
||||
|
||||
Briefly, the shell commands `./configure; make; make install' should
|
||||
configure, build, and install this package. The following
|
||||
more-detailed instructions are generic; see the `README' file for
|
||||
instructions specific to this package.
|
||||
|
||||
The `configure' shell script attempts to guess correct values for
|
||||
various system-dependent variables used during compilation. It uses
|
||||
those values to create a `Makefile' in each directory of the package.
|
||||
It may also create one or more `.h' files containing system-dependent
|
||||
definitions. Finally, it creates a shell script `config.status' that
|
||||
you can run in the future to recreate the current configuration, and a
|
||||
file `config.log' containing compiler output (useful mainly for
|
||||
debugging `configure').
|
||||
|
||||
It can also use an optional file (typically called `config.cache'
|
||||
and enabled with `--cache-file=config.cache' or simply `-C') that saves
|
||||
the results of its tests to speed up reconfiguring. Caching is
|
||||
disabled by default to prevent problems with accidental use of stale
|
||||
cache files.
|
||||
|
||||
If you need to do unusual things to compile the package, please try
|
||||
to figure out how `configure' could check whether to do them, and mail
|
||||
diffs or instructions to the address given in the `README' so they can
|
||||
be considered for the next release. If you are using the cache, and at
|
||||
some point `config.cache' contains results you don't want to keep, you
|
||||
may remove or edit it.
|
||||
|
||||
The file `configure.ac' (or `configure.in') is used to create
|
||||
`configure' by a program called `autoconf'. You need `configure.ac' if
|
||||
you want to change it or regenerate `configure' using a newer version
|
||||
of `autoconf'.
|
||||
|
||||
The simplest way to compile this package is:
|
||||
|
||||
1. `cd' to the directory containing the package's source code and type
|
||||
`./configure' to configure the package for your system.
|
||||
|
||||
Running `configure' might take a while. While running, it prints
|
||||
some messages telling which features it is checking for.
|
||||
|
||||
2. Type `make' to compile the package.
|
||||
|
||||
3. Optionally, type `make check' to run any self-tests that come with
|
||||
the package.
|
||||
|
||||
4. Type `make install' to install the programs and any data files and
|
||||
documentation.
|
||||
|
||||
5. You can remove the program binaries and object files from the
|
||||
source code directory by typing `make clean'. To also remove the
|
||||
files that `configure' created (so you can compile the package for
|
||||
a different kind of computer), type `make distclean'. There is
|
||||
also a `make maintainer-clean' target, but that is intended mainly
|
||||
for the package's developers. If you use it, you may have to get
|
||||
all sorts of other programs in order to regenerate files that came
|
||||
with the distribution.
|
||||
|
||||
Compilers and Options
|
||||
=====================
|
||||
|
||||
Some systems require unusual options for compilation or linking that the
|
||||
`configure' script does not know about. Run `./configure --help' for
|
||||
details on some of the pertinent environment variables.
|
||||
|
||||
You can give `configure' initial values for configuration parameters
|
||||
by setting variables in the command line or in the environment. Here
|
||||
is an example:
|
||||
|
||||
./configure CC=c99 CFLAGS=-g LIBS=-lposix
|
||||
|
||||
*Note Defining Variables::, for more details.
|
||||
|
||||
Compiling For Multiple Architectures
|
||||
====================================
|
||||
|
||||
You can compile the package for more than one kind of computer at the
|
||||
same time, by placing the object files for each architecture in their
|
||||
own directory. To do this, you can use GNU `make'. `cd' to the
|
||||
directory where you want the object files and executables to go and run
|
||||
the `configure' script. `configure' automatically checks for the
|
||||
source code in the directory that `configure' is in and in `..'.
|
||||
|
||||
With a non-GNU `make', it is safer to compile the package for one
|
||||
architecture at a time in the source code directory. After you have
|
||||
installed the package for one architecture, use `make distclean' before
|
||||
reconfiguring for another architecture.
|
||||
|
||||
Installation Names
|
||||
==================
|
||||
|
||||
By default, `make install' installs the package's commands under
|
||||
`/usr/local/bin', include files under `/usr/local/include', etc. You
|
||||
can specify an installation prefix other than `/usr/local' by giving
|
||||
`configure' the option `--prefix=PREFIX'.
|
||||
|
||||
You can specify separate installation prefixes for
|
||||
architecture-specific files and architecture-independent files. If you
|
||||
pass the option `--exec-prefix=PREFIX' to `configure', the package uses
|
||||
PREFIX as the prefix for installing programs and libraries.
|
||||
Documentation and other data files still use the regular prefix.
|
||||
|
||||
In addition, if you use an unusual directory layout you can give
|
||||
options like `--bindir=DIR' to specify different values for particular
|
||||
kinds of files. Run `configure --help' for a list of the directories
|
||||
you can set and what kinds of files go in them.
|
||||
|
||||
If the package supports it, you can cause programs to be installed
|
||||
with an extra prefix or suffix on their names by giving `configure' the
|
||||
option `--program-prefix=PREFIX' or `--program-suffix=SUFFIX'.
|
||||
|
||||
Optional Features
|
||||
=================
|
||||
|
||||
Some packages pay attention to `--enable-FEATURE' options to
|
||||
`configure', where FEATURE indicates an optional part of the package.
|
||||
They may also pay attention to `--with-PACKAGE' options, where PACKAGE
|
||||
is something like `gnu-as' or `x' (for the X Window System). The
|
||||
`README' should mention any `--enable-' and `--with-' options that the
|
||||
package recognizes.
|
||||
|
||||
For packages that use the X Window System, `configure' can usually
|
||||
find the X include and library files automatically, but if it doesn't,
|
||||
you can use the `configure' options `--x-includes=DIR' and
|
||||
`--x-libraries=DIR' to specify their locations.
|
||||
|
||||
Specifying the System Type
|
||||
==========================
|
||||
|
||||
There may be some features `configure' cannot figure out automatically,
|
||||
but needs to determine by the type of machine the package will run on.
|
||||
Usually, assuming the package is built to be run on the _same_
|
||||
architectures, `configure' can figure that out, but if it prints a
|
||||
message saying it cannot guess the machine type, give it the
|
||||
`--build=TYPE' option. TYPE can either be a short name for the system
|
||||
type, such as `sun4', or a canonical name which has the form:
|
||||
|
||||
CPU-COMPANY-SYSTEM
|
||||
|
||||
where SYSTEM can have one of these forms:
|
||||
|
||||
OS KERNEL-OS
|
||||
|
||||
See the file `config.sub' for the possible values of each field. If
|
||||
`config.sub' isn't included in this package, then this package doesn't
|
||||
need to know the machine type.
|
||||
|
||||
If you are _building_ compiler tools for cross-compiling, you should
|
||||
use the option `--target=TYPE' to select the type of system they will
|
||||
produce code for.
|
||||
|
||||
If you want to _use_ a cross compiler, that generates code for a
|
||||
platform different from the build platform, you should specify the
|
||||
"host" platform (i.e., that on which the generated programs will
|
||||
eventually be run) with `--host=TYPE'.
|
||||
|
||||
Sharing Defaults
|
||||
================
|
||||
|
||||
If you want to set default values for `configure' scripts to share, you
|
||||
can create a site shell script called `config.site' that gives default
|
||||
values for variables like `CC', `cache_file', and `prefix'.
|
||||
`configure' looks for `PREFIX/share/config.site' if it exists, then
|
||||
`PREFIX/etc/config.site' if it exists. Or, you can set the
|
||||
`CONFIG_SITE' environment variable to the location of the site script.
|
||||
A warning: not all `configure' scripts look for a site script.
|
||||
|
||||
Defining Variables
|
||||
==================
|
||||
|
||||
Variables not defined in a site shell script can be set in the
|
||||
environment passed to `configure'. However, some packages may run
|
||||
configure again during the build, and the customized values of these
|
||||
variables may be lost. In order to avoid this problem, you should set
|
||||
them in the `configure' command line, using `VAR=value'. For example:
|
||||
|
||||
./configure CC=/usr/local2/bin/gcc
|
||||
|
||||
causes the specified `gcc' to be used as the C compiler (unless it is
|
||||
overridden in the site shell script).
|
||||
|
||||
Unfortunately, this technique does not work for `CONFIG_SHELL' due to
|
||||
an Autoconf bug. Until the bug is fixed you can use this workaround:
|
||||
|
||||
CONFIG_SHELL=/bin/bash /bin/bash ./configure CONFIG_SHELL=/bin/bash
|
||||
|
||||
`configure' Invocation
|
||||
======================
|
||||
|
||||
`configure' recognizes the following options to control how it operates.
|
||||
|
||||
`--help'
|
||||
`-h'
|
||||
Print a summary of the options to `configure', and exit.
|
||||
|
||||
`--version'
|
||||
`-V'
|
||||
Print the version of Autoconf used to generate the `configure'
|
||||
script, and exit.
|
||||
|
||||
`--cache-file=FILE'
|
||||
Enable the cache: use and save the results of the tests in FILE,
|
||||
traditionally `config.cache'. FILE defaults to `/dev/null' to
|
||||
disable caching.
|
||||
|
||||
`--config-cache'
|
||||
`-C'
|
||||
Alias for `--cache-file=config.cache'.
|
||||
|
||||
`--quiet'
|
||||
`--silent'
|
||||
`-q'
|
||||
Do not print messages saying which checks are being made. To
|
||||
suppress all normal output, redirect it to `/dev/null' (any error
|
||||
messages will still be shown).
|
||||
|
||||
`--srcdir=DIR'
|
||||
Look for the package's source code in directory DIR. Usually
|
||||
`configure' can determine that directory automatically.
|
||||
|
||||
`configure' also accepts some other, not widely useful, options. Run
|
||||
`configure --help' for more details.
|
||||
$ make
|
||||
# make install
|
||||
|
||||
|
|
|
@ -0,0 +1,135 @@
|
|||
Snapshot 0.1.6 (2005-07-28 Carl Worth <cworth@cworth.org>)
|
||||
==========================================================
|
||||
Behavioral changes
|
||||
------------------
|
||||
Clips are changed to only affect destination operands, not
|
||||
sources. This gives the desired behavior for cairo. If the X server's
|
||||
Render implementation wants to use pixman it will have to select
|
||||
source clipping, (presumably through a new API call that we can add at
|
||||
that point).
|
||||
|
||||
Bug fixes
|
||||
---------
|
||||
Fix leak of the clip region associated with an image in
|
||||
pixman_image_destroy.
|
||||
|
||||
Fix units for stride return to be FbStip-sized, (this bug was causing
|
||||
non antialiased text in cairo to appear as garbage).
|
||||
|
||||
Other changes
|
||||
-------------
|
||||
The implementation has been merged considerably with xserver/fb. Most
|
||||
of the merge was just name changes, but there were likely some bug
|
||||
fixes or performance improvements in there as well.
|
||||
|
||||
Snapshot 0.1.5 (2005-05-18 Carl Worth <cworth@cworth.org>)
|
||||
==========================================================
|
||||
Bug fixes
|
||||
---------
|
||||
Fix confusion of depth and bpp which was causing cairo to crash on
|
||||
some X servers.
|
||||
|
||||
Properly declare pixman_fixed16_16_t as int32_t which fixes
|
||||
compilation failures on some platforms.
|
||||
|
||||
Fix to find inttypes.h on AIX.
|
||||
|
||||
Fix bug in compositing when the source image has no alpha channel.
|
||||
|
||||
Some fixes to the clipping code.
|
||||
|
||||
Fix memory leak when asked to draw a degenerate trapezoid list.
|
||||
|
||||
Snapshot 0.1.4 (2005-03-07 Carl Worth <cworth@cworth.org>)
|
||||
==========================================================
|
||||
API Addition
|
||||
------------
|
||||
Add new function:
|
||||
|
||||
void
|
||||
pixman_add_trapezoids (pixman_image_t *dst,
|
||||
int x_off,
|
||||
int y_off,
|
||||
const pixman_trapezoid_t *traps,
|
||||
int ntraps);
|
||||
|
||||
Performance improvement
|
||||
-----------------------
|
||||
Restrict size of intermediate surface used while compositing
|
||||
trapezoids based on the bounds of the desination surface.
|
||||
|
||||
Bug fixes
|
||||
---------
|
||||
Fix rendering on 64-bit platforms.
|
||||
|
||||
Snapshot 0.1.3 (2005-01-21 Carl Worth <cworth@cworth.org>)
|
||||
==========================================================
|
||||
Performance improvements
|
||||
------------------------
|
||||
Solid fills are now much faster, (thanks to Alexander Larsson).
|
||||
|
||||
Bug fixes
|
||||
---------
|
||||
Fixed to quiet warnings in newer versions of gcc.
|
||||
|
||||
Don't divide-by-zero if given an image of size 0x0.
|
||||
|
||||
Fixed several corner cases where values outside a trapezoid would be
|
||||
drawn with alpha 1/255 (in the 8-bit case).
|
||||
|
||||
Internal changes
|
||||
----------------
|
||||
Imported the newer point-sampling trapezoid rasterization code that
|
||||
Keith Packard wrote for the X server. This provide pixel-perfect
|
||||
matching with the Render extension as well as code that is simpler,
|
||||
more robust, and easier to maintain.
|
||||
|
||||
Snapshot 0.1.2 (2004-10-27 Carl Worth <cworth@cworth.org>)
|
||||
==========================================================
|
||||
New functionality
|
||||
-----------------
|
||||
Added three new functions:
|
||||
|
||||
pixman_image_set_component_alpha
|
||||
pixman_format_get_masks
|
||||
pixman_image_get_format
|
||||
|
||||
The first enables component-alpha compositing which can be used for
|
||||
optimizing sub-pixel rendering of text and other geometry. This is
|
||||
useful when the geometrical relationship of the sub-pixel components
|
||||
of the display device are known, (eg. with flat-panel monitors rather
|
||||
than CRTs).
|
||||
|
||||
The other two functions are simple query functions that were missing.
|
||||
|
||||
Bug fixes
|
||||
---------
|
||||
Enabling both transform and repeat simultaneously now works.
|
||||
Some byte-order fixes.
|
||||
Clipping fixes: pixman now takes a copy of the client clipping region
|
||||
client clipping is now actually used, it wasn't earlier.
|
||||
|
||||
Snapshot 0.1.1 (2004-04-16 Carl Worth <cworth@east.isi.edu>)
|
||||
============================================================
|
||||
Build fixes for cygwin
|
||||
----------------------
|
||||
This snapshot adds the -no-undefined flag during compilation which is
|
||||
necessart for building a shared library under cygwin.
|
||||
|
||||
Cleanup of the public API
|
||||
-------------------------
|
||||
We recently noticed that there were a coupld of bugs in the script
|
||||
that renamed libic to libpixman. Fixing this requires the following
|
||||
changes in the public API:
|
||||
|
||||
PIXMAN_FORMAT_AR_GB32 -> PIXMAN_FORMAT_ARGB32
|
||||
PIXMAN_FORMAT_RG_B24 -> PIXMAN_FORMAT_RGB24
|
||||
|
||||
While we're changing that, we also normalized the names of structure
|
||||
tags, for example:
|
||||
|
||||
struct _pixman_region16_t -> struct pixman_region16
|
||||
etc.
|
||||
|
||||
but users are expected to use typedefs such as pixman_region16_t
|
||||
anyway.
|
|
@ -0,0 +1,47 @@
|
|||
libpixman - Pixel manipulation library
|
||||
|
||||
libpixman is a merge of libpixregion and libic.
|
||||
It also includes the slim headers.
|
||||
|
||||
----------------------------------------------------------------------
|
||||
libpixregion - Pixel region Library
|
||||
|
||||
libpixregion is a generic library for manipulating pixel regions. A
|
||||
PixRegion is a set of Y-X banded rectangles that cover the desired
|
||||
region.
|
||||
|
||||
The original code for libxregion was part of the reference X server
|
||||
implementation of the X Window System. A modified copy of the code
|
||||
also exists in the Xlib client library. libpixregion was formed so
|
||||
that both the X server and client libraries could share common code
|
||||
for region manipulation.
|
||||
|
||||
libpixregion is also intended to be applicable outside of the X Window
|
||||
System. The public interface of libpixregion does not depend on any
|
||||
part of the X Window System.
|
||||
|
||||
----------------------------------------------------------------------
|
||||
libic - Image compositing library
|
||||
|
||||
libic is a generic image compositing library. libic provides
|
||||
Porter/Duff compositing of images and implicit mask generation for
|
||||
geometric primitives including trapezoids, triangles, and rectangles.
|
||||
|
||||
The semantics of libic are designed to precisely match the
|
||||
specification of the X Render extension. In fact, the initial
|
||||
implementation of libic was lifted from the reference implementation
|
||||
of RENDER from the X server.
|
||||
|
||||
However, libic is intended to be useful independent of the X Window
|
||||
System. The public interface exported by libic does not contain any
|
||||
X-specific data structures.
|
||||
|
||||
Carl Worth
|
||||
cworth@isi.edu
|
||||
|
||||
Keith Packard (keithp@keithp.com) originally wrote all the original
|
||||
RENDER code that was yanked out to become libic. Keith also provided
|
||||
impetus and guidance in the development of libic.
|
||||
|
||||
----------------------------------------------------------------------
|
||||
slim - Shared Library Interface Macros
|
|
@ -1,139 +1,10 @@
|
|||
- Go through things marked FIXME
|
||||
Need to finish up libpixman to the point where there X server can use
|
||||
it in place of its original copy of all this code (eg. in fb). This
|
||||
means merging features that have happened in either tree since the
|
||||
birth of libpixman. Off-hand I can think of the following things that
|
||||
have happened:
|
||||
|
||||
- Add calls to prepare and finish access where necessary. grep for
|
||||
ACCESS_MEM, and make sure they are correctly wrapped in prepare
|
||||
and finish.
|
||||
|
||||
- restore READ/WRITE in the fbcompose combiners since they sometimes
|
||||
store directly to destination drawables.
|
||||
|
||||
- It probably makes sense to move the more strange X region API
|
||||
into pixman as well, but guarded with PIXMAN_XORG_COMPATIBILITY
|
||||
|
||||
- Reinstate the FbBits typedef? At the moment we don't
|
||||
even have the FbBits type; we just use uint32_t everywhere.
|
||||
|
||||
Keith says in bug 2335:
|
||||
|
||||
The 64-bit code in fb (pixman) is probably broken; it hasn't been
|
||||
used in quite some time as PCI (and AGP) is 32-bits wide, so
|
||||
doing things 64-bits at a time is a net loss. To quickly fix
|
||||
this, I suggest just using 32-bit datatypes by setting
|
||||
IC_SHIFT to 5 for all machines.
|
||||
|
||||
- Consider whether calling regions region16 is really such a great
|
||||
idea Vlad wants 32 bit regions for Cairo. This will break X server
|
||||
ABI, but should otherwise be mostly harmless, though a
|
||||
pixman_region_get_boxes16() may be useful.
|
||||
|
||||
- Make source clipping optional.
|
||||
- done: source clipping happens through an indirection.
|
||||
still needs to make the indirection settable. (And call it
|
||||
from X)
|
||||
|
||||
- Consider optimizing the 8/16 bit solid fills in pixman-util.c by
|
||||
storing more than one value at a time.
|
||||
|
||||
- Add an image cache to prevent excessive malloc/free. Note that pixman
|
||||
needs to be thread safe when used from cairo.
|
||||
|
||||
- Review the pixman_format_code_t enum to make sure it will support
|
||||
future formats. Some formats we will probably need:
|
||||
|
||||
ARGB/ABGR with 16/32/64 bit integer/floating channels
|
||||
YUV2,
|
||||
YV12
|
||||
|
||||
Also we may need the ability to distinguish between PICT_c8 and
|
||||
PICT_x4c4. (This could be done by interpreting the A channel as
|
||||
the depth for TYPE_COLOR and TYPE_GRAY formats).
|
||||
|
||||
A possibility may be to reserve the two top bits and make them
|
||||
encode "number of places to shift the channel widths given" Since
|
||||
these bits are 00 at the moment everything will continue to work,
|
||||
but these additional widths will be allowed:
|
||||
|
||||
All even widths between 18-32
|
||||
All multiples of four widths between 33 and 64
|
||||
All multiples of eight between 64 and 128
|
||||
|
||||
This means things like r21g22b21 won't work - is that worth
|
||||
worrying about? I don't think so. And of course the bpp field
|
||||
can't handle a depth of over 256, so > 64 bit channels arent'
|
||||
really all that useful.
|
||||
|
||||
We could reserve one extra bit to indicate floating point, but
|
||||
we may also just add
|
||||
|
||||
PIXMAN_TYPE_ARGB_FLOAT
|
||||
PIXMAN_TYPE_BGRA_FLOAT
|
||||
PIXMAN_TYPE_A_FLOAT
|
||||
|
||||
image types. With five bits we can support up to 32 different
|
||||
format types, which should be enough for everybody, even if we
|
||||
decide to support all the various video formats here:
|
||||
|
||||
http://www.fourcc.org/yuv.php
|
||||
|
||||
It may make sense to have a PIXMAN_TYPE_YUV, and then use the
|
||||
channel bits to specify the exact subtype.
|
||||
|
||||
What about color spaces such a linear vs. srGB etc.?
|
||||
|
||||
|
||||
done:
|
||||
|
||||
- Run cairo test suite; fix bugs
|
||||
- one bug in source-scale-clip
|
||||
|
||||
- Remove the warning suppression in the ACCESS_MEM macro and fix the
|
||||
warnings that are real
|
||||
- irrelevant now.
|
||||
|
||||
- make the wrapper functions global instead of image specific
|
||||
- this won't work since pixman is linked to both fb and wfb
|
||||
|
||||
- Add non-mmx solid fill
|
||||
|
||||
- Make sure the endian-ness macros are defined correctly.
|
||||
|
||||
- The rectangles in a region probably shouldn't be returned const as
|
||||
the X server will be changing them.
|
||||
|
||||
- Right now we _always_ have a clip region, which is empty by default.
|
||||
Why does this work at all? It probably doesn't. The server
|
||||
distinguishes two cases, one where nothing is clipped (CT_NONE), and
|
||||
one where there is a clip region (CT_REGION).
|
||||
|
||||
- Default clip region should be the full image
|
||||
|
||||
- Test if pseudo color still works. It does, but it also shows that
|
||||
copying a pixman_indexed_t on every composite operation is not
|
||||
going to fly. So, for now set_indexed() does not copy the
|
||||
indexed table.
|
||||
|
||||
Also just the malloc() to allocate a pixman image shows up pretty
|
||||
high.
|
||||
|
||||
Options include
|
||||
|
||||
- Make all the setters not copy their arguments
|
||||
|
||||
- Possibly combined with going back to the stack allocated
|
||||
approach that we already use for regions.
|
||||
|
||||
- Keep a cached pixman_image_t around for every picture. It would
|
||||
have to be kept uptodate every time something changes about the
|
||||
picture.
|
||||
|
||||
- Break the X server ABI and simply have the relevant parameter
|
||||
stored in the pixman image. This would have the additional benefits
|
||||
that:
|
||||
|
||||
- We can get rid of the annoying repeat field which is duplicated
|
||||
elsewhere.
|
||||
|
||||
- We can use pixman_color_t and pixman_gradient_stop_t
|
||||
etc. instead of the types that are defined in
|
||||
renderproto.h
|
||||
* libpixman has fix for transform + repeat
|
||||
* X server has some (MMX? SSE?) optimized compositing code
|
||||
|
||||
But see the logs for more details.
|
||||
|
|
|
@ -21,7 +21,6 @@
|
|||
# Contributor(s):
|
||||
# Brian Ryner <bryner@brianryner.com>
|
||||
# Stuart Parmenter <pavlov@pavlov.net>
|
||||
# Vladimir Vukicevic <vladimir@pobox.com>
|
||||
#
|
||||
# Alternatively, the contents of this file may be used under the terms of
|
||||
# either of the GNU General Public License Version 2 or later (the "GPL"),
|
||||
|
@ -64,25 +63,33 @@ endif
|
|||
endif
|
||||
|
||||
CSRCS = \
|
||||
pixman-compose-accessors.c \
|
||||
pixman-compose-noaccessors.c \
|
||||
pixman-compute-region.c \
|
||||
pixman-edge-accessors.c \
|
||||
pixman-edge-noaccessors.c \
|
||||
pixman-image.c \
|
||||
pixman-pict.c \
|
||||
pixman-region.c \
|
||||
pixman-trap.c \
|
||||
pixman-utils.c \
|
||||
fbcompose.c \
|
||||
fbedge.c \
|
||||
fbpict.c \
|
||||
fbtrap.c \
|
||||
icblt.c \
|
||||
icbltone.c \
|
||||
iccolor.c \
|
||||
icformat.c \
|
||||
icimage.c \
|
||||
icpixels.c \
|
||||
icrect.c \
|
||||
icstipple.c \
|
||||
ictransform.c \
|
||||
ictrap.c \
|
||||
ictri.c \
|
||||
icutil.c \
|
||||
pixregion.c \
|
||||
renderedge.c \
|
||||
$(NULL)
|
||||
|
||||
ifdef MOZ_X11
|
||||
#CSRCS += pixman-mmx.c
|
||||
#CSRCS += fbmmx.c
|
||||
#DEFINES += -DUSE_MMX
|
||||
endif
|
||||
|
||||
ifdef _MSC_VER
|
||||
CSRCS += pixman-mmx.c
|
||||
CSRCS += fbmmx.c
|
||||
DEFINES += -DUSE_MMX
|
||||
endif
|
||||
|
||||
|
@ -96,8 +103,6 @@ FORCE_USE_PIC = 1
|
|||
|
||||
include $(topsrcdir)/config/rules.mk
|
||||
|
||||
CFLAGS += -DPACKAGE="mozpixman" -D_USE_MATH_DEFINES
|
||||
|
||||
ifdef MOZ_X11
|
||||
#CFLAGS += -mmmx -msse -Winline --param inline-unit-growth=10000 --param large-function-growth=10000
|
||||
endif
|
||||
|
|
|
@ -0,0 +1,236 @@
|
|||
/*
|
||||
* $Id: fbtrap.c,v 1.21 2007-07-24 19:24:27 vladimir%pobox.com Exp $
|
||||
*
|
||||
* Copyright © 2004 Keith Packard
|
||||
*
|
||||
* 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 Keith Packard not be used in
|
||||
* advertising or publicity pertaining to distribution of the software without
|
||||
* specific, written prior permission. Keith Packard makes no
|
||||
* representations about the suitability of this software for any purpose. It
|
||||
* is provided "as is" without express or implied warranty.
|
||||
*
|
||||
* KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
|
||||
* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
|
||||
* EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR
|
||||
* CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
|
||||
* DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
|
||||
* TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
||||
* PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "pixman-xserver-compat.h"
|
||||
|
||||
#ifdef RENDER
|
||||
|
||||
/* XXX: Haven't added addTraps to libpixman yet. */
|
||||
#if 0
|
||||
void
|
||||
fbAddTraps (PicturePtr pPicture,
|
||||
INT16 x_off,
|
||||
INT16 y_off,
|
||||
int ntrap,
|
||||
xTrap *traps)
|
||||
{
|
||||
FbBits *buf;
|
||||
int bpp;
|
||||
int width;
|
||||
int stride;
|
||||
int height;
|
||||
int pxoff, pyoff;
|
||||
|
||||
xFixed x_off_fixed;
|
||||
xFixed y_off_fixed;
|
||||
RenderEdge l, r;
|
||||
xFixed t, b;
|
||||
|
||||
fbGetDrawable (pPicture->pDrawable, buf, stride, bpp, pxoff, pyoff);
|
||||
|
||||
width = pPicture->pDrawable->width;
|
||||
height = pPicture->pDrawable->height;
|
||||
x_off += pxoff;
|
||||
y_off += pyoff;
|
||||
|
||||
x_off_fixed = IntToxFixed(y_off);
|
||||
y_off_fixed = IntToxFixed(y_off);
|
||||
|
||||
while (ntrap--)
|
||||
{
|
||||
t = traps->top.y + y_off_fixed;
|
||||
if (t < 0)
|
||||
t = 0;
|
||||
t = RenderSampleCeilY (t, bpp);
|
||||
|
||||
b = traps->bot.y + y_off_fixed;
|
||||
if (xFixedToInt (b) >= height)
|
||||
b = IntToxFixed (height) - 1;
|
||||
b = RenderSampleFloorY (b, bpp);
|
||||
|
||||
if (b >= t)
|
||||
{
|
||||
/* initialize edge walkers */
|
||||
RenderEdgeInit (&l, bpp, t,
|
||||
traps->top.l + x_off_fixed,
|
||||
traps->top.y + y_off_fixed,
|
||||
traps->bot.l + x_off_fixed,
|
||||
traps->bot.y + y_off_fixed);
|
||||
|
||||
RenderEdgeInit (&r, bpp, t,
|
||||
traps->top.r + x_off_fixed,
|
||||
traps->top.y + y_off_fixed,
|
||||
traps->bot.r + x_off_fixed,
|
||||
traps->bot.y + y_off_fixed);
|
||||
|
||||
fbRasterizeEdges (buf, bpp, width, stride, &l, &r, t, b);
|
||||
}
|
||||
traps++;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
void
|
||||
fbRasterizeTrapezoid (PicturePtr pPicture,
|
||||
const xTrapezoid *trap,
|
||||
int x_off,
|
||||
int y_off)
|
||||
{
|
||||
FbBits *buf;
|
||||
int bpp;
|
||||
int width;
|
||||
int stride;
|
||||
int height;
|
||||
int pxoff, pyoff;
|
||||
|
||||
xFixed x_off_fixed;
|
||||
xFixed y_off_fixed;
|
||||
RenderEdge l, r;
|
||||
xFixed t, b;
|
||||
|
||||
fbGetDrawable (pPicture->pDrawable, buf, stride, bpp, pxoff, pyoff);
|
||||
|
||||
width = pPicture->pDrawable->width;
|
||||
height = pPicture->pDrawable->height;
|
||||
x_off += pxoff;
|
||||
y_off += pyoff;
|
||||
|
||||
x_off_fixed = IntToxFixed(x_off);
|
||||
y_off_fixed = IntToxFixed(y_off);
|
||||
t = trap->top + y_off_fixed;
|
||||
if (t < 0)
|
||||
t = 0;
|
||||
t = RenderSampleCeilY (t, bpp);
|
||||
|
||||
b = trap->bottom + y_off_fixed;
|
||||
if (xFixedToInt (b) >= height)
|
||||
b = IntToxFixed (height) - 1;
|
||||
b = RenderSampleFloorY (b, bpp);
|
||||
|
||||
if (b >= t)
|
||||
{
|
||||
/* initialize edge walkers */
|
||||
RenderLineFixedEdgeInit (&l, bpp, t, &trap->left, x_off, y_off);
|
||||
RenderLineFixedEdgeInit (&r, bpp, t, &trap->right, x_off, y_off);
|
||||
|
||||
fbRasterizeEdges (buf, bpp, width, stride, &l, &r, t, b);
|
||||
}
|
||||
}
|
||||
|
||||
/* XXX: Haven't add addTriangles to libpixman yet. */
|
||||
#if 0
|
||||
static int
|
||||
_GreaterY (xPointFixed *a, xPointFixed *b)
|
||||
{
|
||||
if (a->y == b->y)
|
||||
return a->x > b->x;
|
||||
return a->y > b->y;
|
||||
}
|
||||
|
||||
/*
|
||||
* Note that the definition of this function is a bit odd because
|
||||
* of the X coordinate space (y increasing downwards).
|
||||
*/
|
||||
static int
|
||||
_Clockwise (xPointFixed *ref, xPointFixed *a, xPointFixed *b)
|
||||
{
|
||||
xPointFixed ad, bd;
|
||||
|
||||
ad.x = a->x - ref->x;
|
||||
ad.y = a->y - ref->y;
|
||||
bd.x = b->x - ref->x;
|
||||
bd.y = b->y - ref->y;
|
||||
|
||||
return ((xFixed_32_32) bd.y * ad.x - (xFixed_32_32) ad.y * bd.x) < 0;
|
||||
}
|
||||
|
||||
/* FIXME -- this could be made more efficient */
|
||||
void
|
||||
fbAddTriangles (PicturePtr pPicture,
|
||||
INT16 x_off,
|
||||
INT16 y_off,
|
||||
int ntri,
|
||||
xTriangle *tris)
|
||||
{
|
||||
xPointFixed *top, *left, *right, *tmp;
|
||||
xTrapezoid trap;
|
||||
|
||||
for (; ntri; ntri--, tris++)
|
||||
{
|
||||
top = &tris->p1;
|
||||
left = &tris->p2;
|
||||
right = &tris->p3;
|
||||
if (_GreaterY (top, left)) {
|
||||
tmp = left; left = top; top = tmp;
|
||||
}
|
||||
if (_GreaterY (top, right)) {
|
||||
tmp = right; right = top; top = tmp;
|
||||
}
|
||||
if (_Clockwise (top, right, left)) {
|
||||
tmp = right; right = left; left = tmp;
|
||||
}
|
||||
|
||||
/*
|
||||
* Two cases:
|
||||
*
|
||||
* + +
|
||||
* / \ / \
|
||||
* / \ / \
|
||||
* / + + \
|
||||
* / -- -- \
|
||||
* / -- -- \
|
||||
* / --- --- \
|
||||
* +-- --+
|
||||
*/
|
||||
|
||||
trap.top = top->y;
|
||||
trap.left.p1 = *top;
|
||||
trap.left.p2 = *left;
|
||||
trap.right.p1 = *top;
|
||||
trap.right.p2 = *right;
|
||||
if (right->y < left->y)
|
||||
trap.bottom = right->y;
|
||||
else
|
||||
trap.bottom = left->y;
|
||||
fbRasterizeTrapezoid (pPicture, &trap, x_off, y_off);
|
||||
if (right->y < left->y)
|
||||
{
|
||||
trap.top = right->y;
|
||||
trap.bottom = left->y;
|
||||
trap.right.p1 = *right;
|
||||
trap.right.p2 = *left;
|
||||
}
|
||||
else
|
||||
{
|
||||
trap.top = left->y;
|
||||
trap.bottom = right->y;
|
||||
trap.left.p1 = *left;
|
||||
trap.left.p2 = *right;
|
||||
}
|
||||
fbRasterizeTrapezoid (pPicture, &trap, x_off, y_off);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* RENDER */
|
Некоторые файлы не были показаны из-за слишком большого количества измененных файлов Показать больше
Загрузка…
Ссылка в новой задаче