mirror of
https://gitlab.freedesktop.org/cairo/cairo.git
synced 2025-12-25 09:30:18 +01:00
Made all changes necessary to abandon the Xc library, (sucking the functionality up into cairo_surface_t instead). Eliminated most of the remaining X datatypes (XFixed, XPointFixed, XLineFixed, XTrapezoid). Fixed some numerical problems relating to pen initialization and intersection calculation.
This commit is contained in:
parent
2026b1c44a
commit
e97cfd5eae
33 changed files with 1930 additions and 968 deletions
71
ChangeLog
71
ChangeLog
|
|
@ -1,3 +1,74 @@
|
|||
2003-07-30 Carl Worth <cworth@isi.edu>
|
||||
|
||||
* src/cairo_traps.c (_line_segs_intersect_ceil): Add one more
|
||||
conditional intersect to push past some fill bugs.
|
||||
|
||||
* src/cairo_surface.c (cairo_surface_create_for_drawable):
|
||||
(cairo_surface_create_for_image):
|
||||
(cairo_surface_put_image):
|
||||
(_cairo_surface_pull_image):
|
||||
(_cairo_surface_push_image):
|
||||
(cairo_surface_set_matrix):
|
||||
(cairo_surface_get_matrix):
|
||||
(cairo_surface_set_repeat):
|
||||
(_cairo_surface_composite):
|
||||
(_cairo_surface_fill_rectangle):
|
||||
(_cairo_surface_fill_rectangles):
|
||||
(_cairo_surface_composite_trapezoids): Absorb all functionality
|
||||
previously in the Xc library.
|
||||
|
||||
* src/cairo_pen.c (_cairo_pen_init): Don't store floating point
|
||||
theta in the pen. Instead, sort vertices by fixed point slope
|
||||
comparisons.
|
||||
(_cairo_pen_add_points): Fixed to remove duplicate pen vertices
|
||||
appearing at beginning and end of vertex array.
|
||||
(_pen_vertex_compare): New fixed-point "angle" comparison for pen
|
||||
vertices. A bit trickier than before, but much more accurate.
|
||||
|
||||
* src/cairo_path_stroke.c (_cairo_stroker_face_clockwise): Share
|
||||
clockwise calculation with other modules.
|
||||
|
||||
* src/cairo_path_bounds.c:
|
||||
* src/cairo_path_fill.c:
|
||||
* src/cairo_path_stroke.c:
|
||||
* src/cairo_pen.c:
|
||||
* src/cairo_polygon.c:
|
||||
* src/cairo_spline.c:
|
||||
* src/cairo_traps.c:
|
||||
* src/cairo_path.c: Replaced all references to
|
||||
XFixed, XPointFixed, XLineFixed, and XTrapezoid with new
|
||||
cairo_fixed_t, cairo_point_t, cairo_line_t, and cairo_trapezoid_t.
|
||||
|
||||
* src/cairo_path.c: (_cairo_path_interpret): Made the path
|
||||
interpreter callback names consistent, (eg. add_edge rather than
|
||||
AddEdge).
|
||||
|
||||
* src/cairo_gstate.c (_cairo_gstate_text_extents): Now silently
|
||||
exits for a non X surface, (avoids a crash until we can implement
|
||||
the libic text backend).
|
||||
|
||||
* src/cairo_gstate.c (_cairo_gstate_end_group):
|
||||
(_cairo_gstate_clip_and_composite_trapezoids):
|
||||
(_cairo_gstate_show_surface): Replaced all XcCalls with
|
||||
corresponding cairo_surface_calls.
|
||||
|
||||
* src/cairo_gstate.c (_cairo_gstate_transform_point):
|
||||
(_cairo_gstate_transform_font):
|
||||
(_cairo_gstate_text_extents): Renamed from the garbled names
|
||||
(eg. cairo_gstateransform_point) leftover from the great renaming.
|
||||
|
||||
* src/cairo_color.c (_cairo_color_set_rgb): Reworked cairo_color_t
|
||||
to eliminate reference to an XcColor object.
|
||||
|
||||
* src/cairo.h: Dropped include of <Xc.h>, added
|
||||
<X11/extensions/Xrender.h>, <fontconfig/fontconfig.h>, and <ic.h>
|
||||
|
||||
* src/cairo.c (cairo_get_fill_rule): Added missing cairo_get_fill_rule.
|
||||
|
||||
* configure.in (PKG_CHECK_MODULES): Drops xc, add libic
|
||||
|
||||
* cairo.pc.in (Requires): Drop xc, add libic.
|
||||
|
||||
2003-07-25 Carl Worth <cworth@isi.edu>
|
||||
|
||||
* src/cairo_traps.c (_line_segs_intersect_ceil): We don't need a
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ Name: cairo
|
|||
Description: Multi-platform 2D graphics library
|
||||
Version: @VERSION@
|
||||
|
||||
Requires: xc xft
|
||||
Requires: libic xft
|
||||
Libs: -L${libdir} -lcairo -lm
|
||||
Cflags: -I${includedir}
|
||||
|
||||
|
|
|
|||
|
|
@ -24,7 +24,7 @@ AC_SUBST(VERSION_INFO)
|
|||
|
||||
dnl ===========================================================================
|
||||
|
||||
XC_REQUIRED=0.1.0
|
||||
LIBIC_REQUIRES=0.1.0
|
||||
XFT_REQUIRED=2.1.1
|
||||
|
||||
dnl ===========================================================================
|
||||
|
|
@ -45,7 +45,7 @@ AC_PATH_XTRA
|
|||
|
||||
dnl ===========================================================================
|
||||
|
||||
PKG_CHECK_MODULES(CAIRO, xc >= $XC_REQUIRED xft >= $XFT_REQUIRED)
|
||||
PKG_CHECK_MODULES(CAIRO, xft >= $XFT_REQUIRED, libic >= $LIBIC_REQUIRED)
|
||||
AC_SUBST(CAIRO_CFLAGS)
|
||||
AC_SUBST(CAIRO_LIBS)
|
||||
|
||||
|
|
|
|||
|
|
@ -2,23 +2,23 @@ lib_LTLIBRARIES = libcairo.la
|
|||
include_HEADERS = cairo.h
|
||||
|
||||
libcairo_la_SOURCES = \
|
||||
cairo.h \
|
||||
cairo.c \
|
||||
cairoint.h \
|
||||
cairo.h \
|
||||
cairo_color.c \
|
||||
cairo_font.c \
|
||||
cairo_gstate.c \
|
||||
cairo_matrix.c \
|
||||
cairo_misc.c \
|
||||
cairo_path.c \
|
||||
cairo_path_bounds.c \
|
||||
cairo_path_fill.c \
|
||||
cairo_path_stroke.c \
|
||||
cairo_pen.c \
|
||||
cairo_polygon.c \
|
||||
cairo_slope.c \
|
||||
cairo_spline.c \
|
||||
cairo_surface.c \
|
||||
cairo_traps.c
|
||||
cairo_traps.c \
|
||||
cairoint.h
|
||||
|
||||
libcairo_la_LDFLAGS = -version-info @VERSION_INFO@
|
||||
|
||||
|
|
|
|||
|
|
@ -27,10 +27,13 @@
|
|||
|
||||
#include "cairoint.h"
|
||||
|
||||
static cairo_color_t CAIRO_COLOR_DEFAULT = { 1.0, 1.0, 1.0, 1.0, {0xffff, 0xffff, 0xffff, 0xffff}};
|
||||
static cairo_color_t CAIRO_COLOR_DEFAULT = {
|
||||
1.0, 1.0, 1.0, 1.0,
|
||||
0xffff, 0xffff, 0xffff, 0xffff
|
||||
};
|
||||
|
||||
static void
|
||||
_cairo_color_compute_xc_color (cairo_color_t *color);
|
||||
_cairo_color_compute_shorts (cairo_color_t *color);
|
||||
|
||||
void
|
||||
_cairo_color_init (cairo_color_t *color)
|
||||
|
|
@ -44,31 +47,22 @@ _cairo_color_fini (cairo_color_t *color)
|
|||
/* Nothing to do here */
|
||||
}
|
||||
|
||||
static void
|
||||
_cairo_color_compute_xc_color (cairo_color_t *color)
|
||||
{
|
||||
color->xc_color.red = color->red * color->alpha * 0xffff;
|
||||
color->xc_color.green = color->green * color->alpha * 0xffff;
|
||||
color->xc_color.blue = color->blue * color->alpha * 0xffff;
|
||||
color->xc_color.alpha = color->alpha * 0xffff;
|
||||
}
|
||||
|
||||
void
|
||||
_cairo_color_set_rgb (cairo_color_t *color, double red, double green, double blue)
|
||||
{
|
||||
color->red = red;
|
||||
color->red = red;
|
||||
color->green = green;
|
||||
color->blue = blue;
|
||||
color->blue = blue;
|
||||
|
||||
_cairo_color_compute_xc_color (color);
|
||||
_cairo_color_compute_shorts (color);
|
||||
}
|
||||
|
||||
void
|
||||
_cairo_color_get_rgb (cairo_color_t *color, double *red, double *green, double *blue)
|
||||
{
|
||||
*red = color->red;
|
||||
*red = color->red;
|
||||
*green = color->green;
|
||||
*blue = color->blue;
|
||||
*blue = color->blue;
|
||||
}
|
||||
|
||||
void
|
||||
|
|
@ -76,5 +70,15 @@ _cairo_color_set_alpha (cairo_color_t *color, double alpha)
|
|||
{
|
||||
color->alpha = alpha;
|
||||
|
||||
_cairo_color_compute_xc_color (color);
|
||||
_cairo_color_compute_shorts (color);
|
||||
}
|
||||
|
||||
static void
|
||||
_cairo_color_compute_shorts (cairo_color_t *color)
|
||||
{
|
||||
color->red_short = (color->red * color->alpha) * 0xffff;
|
||||
color->green_short = (color->green * color->alpha) * 0xffff;
|
||||
color->blue_short = (color->blue * color->alpha) * 0xffff;
|
||||
color->alpha_short = color->alpha * 0xffff;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -154,7 +154,7 @@ _cairo_font_resolve_xft_font (cairo_font_t *font, cairo_gstate_t *gstate, XftFon
|
|||
|
||||
FcPatternAddMatrix (pattern, "matrix", &fc_matrix);
|
||||
|
||||
/* XXX: Need to abandon Xft and use Xc instead */
|
||||
/* XXX: Need to make a generic (non-Xft) backend for text. */
|
||||
/* When I do that I can throw away these Display pointers */
|
||||
font->dpy = gstate->surface->dpy;
|
||||
match = XftFontMatch (font->dpy, DefaultScreen (font->dpy), pattern, &result);
|
||||
|
|
|
|||
|
|
@ -227,12 +227,12 @@ _cairo_gstate_begin_group (cairo_gstate_t *gstate)
|
|||
_cairo_color_init (&clear);
|
||||
_cairo_color_set_alpha (&clear, 0);
|
||||
|
||||
XcFillRectangle (CAIRO_OPERATOR_SRC,
|
||||
_cairo_surface_get_xc_surface (gstate->surface),
|
||||
&clear.xc_color,
|
||||
0, 0,
|
||||
_cairo_surface_get_width (gstate->surface),
|
||||
_cairo_surface_get_height (gstate->surface));
|
||||
_cairo_surface_fill_rectangle (gstate->surface,
|
||||
CAIRO_OPERATOR_SRC,
|
||||
&clear,
|
||||
0, 0,
|
||||
_cairo_surface_get_width (gstate->surface),
|
||||
_cairo_surface_get_height (gstate->surface));
|
||||
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
}
|
||||
|
|
@ -259,15 +259,15 @@ _cairo_gstate_end_group (cairo_gstate_t *gstate)
|
|||
* XXX: This could be made much more efficient by using
|
||||
_cairo_surface_get_damaged_width/Height if cairo_surface_t actually kept
|
||||
track of such informaton. *
|
||||
XcComposite (gstate->operator,
|
||||
_cairo_surface_get_xc_surface (gstate->surface),
|
||||
_cairo_surface_get_xc_surface (&mask),
|
||||
_cairo_surface_get_xc_surface (gstate->parent_surface),
|
||||
0, 0,
|
||||
0, 0,
|
||||
0, 0,
|
||||
_cairo_surface_get_width (gstate->surface),
|
||||
_cairo_surface_get_height (gstate->surface));
|
||||
_cairo_surface_composite (gstate->operator,
|
||||
gstate->surface,
|
||||
mask,
|
||||
gstate->parent_surface,
|
||||
0, 0,
|
||||
0, 0,
|
||||
0, 0,
|
||||
_cairo_surface_get_width (gstate->surface),
|
||||
_cairo_surface_get_height (gstate->surface));
|
||||
|
||||
_cairo_surface_fini (&mask);
|
||||
|
||||
|
|
@ -415,6 +415,12 @@ _cairo_gstate_set_fill_rule (cairo_gstate_t *gstate, cairo_fill_rule_t fill_rule
|
|||
return CAIRO_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
cairo_status_t
|
||||
_cairo_gstate_get_fill_rule (cairo_gstate_t *gstate)
|
||||
{
|
||||
return gstate->fill_rule;
|
||||
}
|
||||
|
||||
cairo_status_t
|
||||
_cairo_gstate_set_line_width (cairo_gstate_t *gstate, double width)
|
||||
{
|
||||
|
|
@ -495,7 +501,7 @@ _cairo_gstate_get_miter_limit (cairo_gstate_t *gstate)
|
|||
}
|
||||
|
||||
cairo_status_t
|
||||
cairo_gstate_translate (cairo_gstate_t *gstate, double tx, double ty)
|
||||
_cairo_gstate_translate (cairo_gstate_t *gstate, double tx, double ty)
|
||||
{
|
||||
cairo_matrix_t tmp;
|
||||
|
||||
|
|
@ -597,7 +603,7 @@ _cairo_gstate_identity_matrix (cairo_gstate_t *gstate)
|
|||
}
|
||||
|
||||
cairo_status_t
|
||||
cairo_gstateransform_point (cairo_gstate_t *gstate, double *x, double *y)
|
||||
_cairo_gstate_transform_point (cairo_gstate_t *gstate, double *x, double *y)
|
||||
{
|
||||
cairo_matrix_transform_point (&gstate->ctm, x, y);
|
||||
|
||||
|
|
@ -605,7 +611,7 @@ cairo_gstateransform_point (cairo_gstate_t *gstate, double *x, double *y)
|
|||
}
|
||||
|
||||
cairo_status_t
|
||||
cairo_gstateransform_distance (cairo_gstate_t *gstate, double *dx, double *dy)
|
||||
_cairo_gstate_transform_distance (cairo_gstate_t *gstate, double *dx, double *dy)
|
||||
{
|
||||
cairo_matrix_transform_distance (&gstate->ctm, dx, dy);
|
||||
|
||||
|
|
@ -760,6 +766,17 @@ _cairo_gstate_rel_curve_to (cairo_gstate_t *gstate,
|
|||
return status;
|
||||
}
|
||||
|
||||
/* XXX: NYI
|
||||
cairo_status_t
|
||||
_cairo_gstate_stroke_path (cairo_gstate_t *gstate)
|
||||
{
|
||||
cairo_status_t status;
|
||||
|
||||
_cairo_pen_init (&gstate
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
}
|
||||
*/
|
||||
|
||||
cairo_status_t
|
||||
_cairo_gstate_close_path (cairo_gstate_t *gstate)
|
||||
{
|
||||
|
|
@ -823,12 +840,12 @@ _cairo_gstate_clip_and_composite_trapezoids (cairo_gstate_t *gstate,
|
|||
cairo_surface_t *dst,
|
||||
cairo_traps_t *traps)
|
||||
{
|
||||
if (traps->num_xtraps == 0)
|
||||
if (traps->num_traps == 0)
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
|
||||
if (gstate->clip.surface) {
|
||||
XFixed xoff, yoff;
|
||||
XTrapezoid *t;
|
||||
cairo_fixed_t xoff, yoff;
|
||||
cairo_trapezoid_t *t;
|
||||
int i;
|
||||
|
||||
cairo_surface_t *intermediate, *white;
|
||||
|
|
@ -844,12 +861,13 @@ _cairo_gstate_clip_and_composite_trapezoids (cairo_gstate_t *gstate,
|
|||
gstate->clip.height,
|
||||
0.0, 0.0, 0.0, 0.0);
|
||||
|
||||
/* Ugh. The Xc/ (Render) interface doesn't allow an offset for
|
||||
the trapezoids. Need to manually shift all the coordinates
|
||||
to align with the offset origin of the clip surface. */
|
||||
/* Ugh. The cairo_composite/(Render) interface doesn't allow
|
||||
an offset for the trapezoids. Need to manually shift all
|
||||
the coordinates to align with the offset origin of the clip
|
||||
surface. */
|
||||
xoff = XDoubleToFixed (gstate->clip.x);
|
||||
yoff = XDoubleToFixed (gstate->clip.y);
|
||||
for (i=0, t=traps->xtraps; i < traps->num_xtraps; i++, t++) {
|
||||
for (i=0, t=traps->traps; i < traps->num_traps; i++, t++) {
|
||||
t->top -= yoff;
|
||||
t->bottom -= yoff;
|
||||
t->left.p1.x -= xoff;
|
||||
|
|
@ -862,49 +880,45 @@ _cairo_gstate_clip_and_composite_trapezoids (cairo_gstate_t *gstate,
|
|||
t->right.p2.y -= yoff;
|
||||
}
|
||||
|
||||
XcCompositeTrapezoids (CAIRO_OPERATOR_ADD,
|
||||
white->xc_surface,
|
||||
intermediate->xc_surface,
|
||||
0, 0,
|
||||
traps->xtraps,
|
||||
traps->num_xtraps);
|
||||
XcComposite (CAIRO_OPERATOR_IN,
|
||||
gstate->clip.surface->xc_surface,
|
||||
NULL,
|
||||
intermediate->xc_surface,
|
||||
0, 0, 0, 0, 0, 0,
|
||||
gstate->clip.width, gstate->clip.height);
|
||||
XcComposite (operator,
|
||||
src->xc_surface,
|
||||
intermediate->xc_surface,
|
||||
dst->xc_surface,
|
||||
0, 0,
|
||||
0, 0,
|
||||
gstate->clip.x,
|
||||
gstate->clip.y,
|
||||
gstate->clip.width,
|
||||
gstate->clip.height);
|
||||
_cairo_surface_composite_trapezoids (CAIRO_OPERATOR_ADD,
|
||||
white, intermediate,
|
||||
0, 0,
|
||||
traps->traps,
|
||||
traps->num_traps);
|
||||
_cairo_surface_composite (CAIRO_OPERATOR_IN,
|
||||
gstate->clip.surface,
|
||||
NULL,
|
||||
intermediate,
|
||||
0, 0, 0, 0, 0, 0,
|
||||
gstate->clip.width, gstate->clip.height);
|
||||
_cairo_surface_composite (operator,
|
||||
src, intermediate, dst,
|
||||
0, 0,
|
||||
0, 0,
|
||||
gstate->clip.x,
|
||||
gstate->clip.y,
|
||||
gstate->clip.width,
|
||||
gstate->clip.height);
|
||||
cairo_surface_destroy (intermediate);
|
||||
cairo_surface_destroy (white);
|
||||
|
||||
} else {
|
||||
double xoff, yoff;
|
||||
|
||||
if (traps->xtraps[0].left.p1.y < traps->xtraps[0].left.p2.y) {
|
||||
xoff = traps->xtraps[0].left.p1.x;
|
||||
yoff = traps->xtraps[0].left.p1.y;
|
||||
if (traps->traps[0].left.p1.y < traps->traps[0].left.p2.y) {
|
||||
xoff = traps->traps[0].left.p1.x;
|
||||
yoff = traps->traps[0].left.p1.y;
|
||||
} else {
|
||||
xoff = traps->xtraps[0].left.p2.x;
|
||||
yoff = traps->xtraps[0].left.p2.y;
|
||||
xoff = traps->traps[0].left.p2.x;
|
||||
yoff = traps->traps[0].left.p2.y;
|
||||
}
|
||||
|
||||
XcCompositeTrapezoids (gstate->operator,
|
||||
src->xc_surface,
|
||||
dst->xc_surface,
|
||||
XFixedToDouble (xoff) - gstate->pattern_offset.x,
|
||||
XFixedToDouble (yoff) - gstate->pattern_offset.y,
|
||||
traps->xtraps,
|
||||
traps->num_xtraps);
|
||||
_cairo_surface_composite_trapezoids (gstate->operator,
|
||||
src, dst,
|
||||
XFixedToDouble (xoff) - gstate->pattern_offset.x,
|
||||
XFixedToDouble (yoff) - gstate->pattern_offset.y,
|
||||
traps->traps,
|
||||
traps->num_traps);
|
||||
}
|
||||
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
|
|
@ -996,28 +1010,30 @@ _cairo_gstate_scale_font (cairo_gstate_t *gstate, double scale)
|
|||
}
|
||||
|
||||
cairo_status_t
|
||||
cairo_gstateransform_font (cairo_gstate_t *gstate,
|
||||
double a, double b,
|
||||
double c, double d)
|
||||
_cairo_gstate_transform_font (cairo_gstate_t *gstate,
|
||||
double a, double b,
|
||||
double c, double d)
|
||||
{
|
||||
return cairo_font_transform (&gstate->font,
|
||||
a, b, c, d);
|
||||
}
|
||||
|
||||
cairo_status_t
|
||||
cairo_gstateext_extents (cairo_gstate_t *gstate,
|
||||
const unsigned char *utf8,
|
||||
double *x, double *y,
|
||||
double *width, double *height,
|
||||
double *dx, double *dy)
|
||||
_cairo_gstate_text_extents (cairo_gstate_t *gstate,
|
||||
const unsigned char *utf8,
|
||||
double *x, double *y,
|
||||
double *width, double *height,
|
||||
double *dx, double *dy)
|
||||
{
|
||||
XftFont *xft_font;
|
||||
XGlyphInfo extents;
|
||||
|
||||
if (gstate->surface->dpy == 0)
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
|
||||
_cairo_font_resolve_xft_font (&gstate->font, gstate, &xft_font);
|
||||
|
||||
/* XXX: Need to abandon Xft and use Xc instead */
|
||||
/* (until I do, this call will croak on IcImage cairo_surface_ts */
|
||||
/* XXX: Need to make a generic (non-Xft) backend for text. */
|
||||
XftTextExtentsUtf8 (gstate->surface->dpy,
|
||||
xft_font,
|
||||
utf8,
|
||||
|
|
@ -1050,14 +1066,12 @@ _cairo_gstate_show_text (cairo_gstate_t *gstate, const unsigned char *utf8)
|
|||
|
||||
_cairo_font_resolve_xft_font (&gstate->font, gstate, &xft_font);
|
||||
|
||||
/* XXX: Need to abandon Xft and use Xc instead */
|
||||
/* (until I do, this call will croak on IcImage cairo_surface_ts */
|
||||
/* (also, this means text clipping isn't working. Basically text is broken.) */
|
||||
/* XXX: Need to make a generic (non-Xft) backend for text. */
|
||||
XftTextRenderUtf8 (gstate->surface->dpy,
|
||||
gstate->operator,
|
||||
_cairo_surface_get_picture (gstate->solid),
|
||||
gstate->solid->picture,
|
||||
xft_font,
|
||||
_cairo_surface_get_picture (gstate->surface),
|
||||
gstate->surface->picture,
|
||||
0, 0,
|
||||
gstate->current_pt.x,
|
||||
gstate->current_pt.y,
|
||||
|
|
@ -1107,15 +1121,13 @@ _cairo_gstate_show_surface (cairo_gstate_t *gstate,
|
|||
|
||||
/* XXX: The rendered size is sometimes 1 or 2 pixels short from
|
||||
what I expect. Need to fix this. */
|
||||
XcComposite (gstate->operator,
|
||||
surface->xc_surface,
|
||||
mask->xc_surface,
|
||||
gstate->surface->xc_surface,
|
||||
device_x, device_y,
|
||||
0, 0,
|
||||
device_x, device_y,
|
||||
device_width,
|
||||
device_height);
|
||||
_cairo_surface_composite (gstate->operator,
|
||||
surface, mask, gstate->surface,
|
||||
device_x, device_y,
|
||||
0, 0,
|
||||
device_x, device_y,
|
||||
device_width,
|
||||
device_height);
|
||||
|
||||
cairo_surface_destroy (mask);
|
||||
|
||||
|
|
|
|||
|
|
@ -30,10 +30,10 @@
|
|||
typedef struct cairo_path_bounder {
|
||||
int has_pt;
|
||||
|
||||
XFixed min_x;
|
||||
XFixed min_y;
|
||||
XFixed max_x;
|
||||
XFixed max_y;
|
||||
cairo_fixed_t min_x;
|
||||
cairo_fixed_t min_y;
|
||||
cairo_fixed_t max_x;
|
||||
cairo_fixed_t max_y;
|
||||
} cairo_path_bounder_t;
|
||||
|
||||
static void
|
||||
|
|
@ -43,14 +43,15 @@ static void
|
|||
_cairo_path_bounder_fini (cairo_path_bounder_t *bounder);
|
||||
|
||||
static cairo_status_t
|
||||
_cairo_path_bounder_add_point (cairo_path_bounder_t *bounder, XPointFixed *pt);
|
||||
_cairo_path_bounder_add_point (cairo_path_bounder_t *bounder, cairo_point_t *pt);
|
||||
|
||||
static cairo_status_t
|
||||
_cairo_path_bounder_add_edge (void *closure, XPointFixed *p1, XPointFixed *p2);
|
||||
_cairo_path_bounder_add_edge (void *closure, cairo_point_t *p1, cairo_point_t *p2);
|
||||
|
||||
static cairo_status_t
|
||||
_cairo_path_bounder_add_spline (void *closure,
|
||||
XPointFixed *a, XPointFixed *b, XPointFixed *c, XPointFixed *d);
|
||||
cairo_point_t *a, cairo_point_t *b,
|
||||
cairo_point_t *c, cairo_point_t *d);
|
||||
|
||||
static cairo_status_t
|
||||
_cairo_path_bounder_done_sub_path (void *closure, cairo_sub_path_done_t done);
|
||||
|
|
@ -71,7 +72,7 @@ _cairo_path_bounder_fini (cairo_path_bounder_t *bounder)
|
|||
}
|
||||
|
||||
static cairo_status_t
|
||||
_cairo_path_bounder_add_point (cairo_path_bounder_t *bounder, XPointFixed *pt)
|
||||
_cairo_path_bounder_add_point (cairo_path_bounder_t *bounder, cairo_point_t *pt)
|
||||
{
|
||||
if (bounder->has_pt) {
|
||||
if (pt->x < bounder->min_x)
|
||||
|
|
@ -98,7 +99,7 @@ _cairo_path_bounder_add_point (cairo_path_bounder_t *bounder, XPointFixed *pt)
|
|||
}
|
||||
|
||||
static cairo_status_t
|
||||
_cairo_path_bounder_add_edge (void *closure, XPointFixed *p1, XPointFixed *p2)
|
||||
_cairo_path_bounder_add_edge (void *closure, cairo_point_t *p1, cairo_point_t *p2)
|
||||
{
|
||||
cairo_path_bounder_t *bounder = closure;
|
||||
|
||||
|
|
@ -110,7 +111,8 @@ _cairo_path_bounder_add_edge (void *closure, XPointFixed *p1, XPointFixed *p2)
|
|||
|
||||
static cairo_status_t
|
||||
_cairo_path_bounder_add_spline (void *closure,
|
||||
XPointFixed *a, XPointFixed *b, XPointFixed *c, XPointFixed *d)
|
||||
cairo_point_t *a, cairo_point_t *b,
|
||||
cairo_point_t *c, cairo_point_t *d)
|
||||
{
|
||||
cairo_path_bounder_t *bounder = closure;
|
||||
|
||||
|
|
|
|||
|
|
@ -41,10 +41,12 @@ static void
|
|||
_cairo_filler_fini (cairo_filler_t *filler);
|
||||
|
||||
static cairo_status_t
|
||||
_cairo_filler_add_edge (void *closure, XPointFixed *p1, XPointFixed *p2);
|
||||
_cairo_filler_add_edge (void *closure, cairo_point_t *p1, cairo_point_t *p2);
|
||||
|
||||
static cairo_status_t
|
||||
_cairo_filler_add_spline (void *closure, XPointFixed *a, XPointFixed *b, XPointFixed *c, XPointFixed *d);
|
||||
_cairo_filler_add_spline (void *closure,
|
||||
cairo_point_t *a, cairo_point_t *b,
|
||||
cairo_point_t *c, cairo_point_t *d);
|
||||
|
||||
static cairo_status_t
|
||||
_cairo_filler_done_sub_path (void *closure, cairo_sub_path_done_t done);
|
||||
|
|
@ -68,7 +70,7 @@ _cairo_filler_fini (cairo_filler_t *filler)
|
|||
}
|
||||
|
||||
static cairo_status_t
|
||||
_cairo_filler_add_edge (void *closure, XPointFixed *p1, XPointFixed *p2)
|
||||
_cairo_filler_add_edge (void *closure, cairo_point_t *p1, cairo_point_t *p2)
|
||||
{
|
||||
cairo_filler_t *filler = closure;
|
||||
cairo_polygon_t *polygon = &filler->polygon;
|
||||
|
|
@ -77,7 +79,9 @@ _cairo_filler_add_edge (void *closure, XPointFixed *p1, XPointFixed *p2)
|
|||
}
|
||||
|
||||
static cairo_status_t
|
||||
_cairo_filler_add_spline (void *closure, XPointFixed *a, XPointFixed *b, XPointFixed *c, XPointFixed *d)
|
||||
_cairo_filler_add_spline (void *closure,
|
||||
cairo_point_t *a, cairo_point_t *b,
|
||||
cairo_point_t *c, cairo_point_t *d)
|
||||
{
|
||||
int i;
|
||||
cairo_status_t status = CAIRO_STATUS_SUCCESS;
|
||||
|
|
|
|||
|
|
@ -49,13 +49,15 @@ static void
|
|||
_cairo_stroker_fini (cairo_stroker_t *stroker);
|
||||
|
||||
static cairo_status_t
|
||||
_cairo_stroker_add_edge (void *closure, XPointFixed *p1, XPointFixed *p2);
|
||||
_cairo_stroker_add_edge (void *closure, cairo_point_t *p1, cairo_point_t *p2);
|
||||
|
||||
static cairo_status_t
|
||||
_cairo_stroker_add_edge_dashed (void *closure, XPointFixed *p1, XPointFixed *p2);
|
||||
_cairo_stroker_add_edge_dashed (void *closure, cairo_point_t *p1, cairo_point_t *p2);
|
||||
|
||||
static cairo_status_t
|
||||
_cairo_stroker_add_spline (void *closure, XPointFixed *a, XPointFixed *b, XPointFixed *c, XPointFixed *d);
|
||||
_cairo_stroker_add_spline (void *closure,
|
||||
cairo_point_t *a, cairo_point_t *b,
|
||||
cairo_point_t *c, cairo_point_t *d);
|
||||
|
||||
static cairo_status_t
|
||||
_cairo_stroker_done_sub_path (void *closure, cairo_sub_path_done_t done);
|
||||
|
|
@ -64,7 +66,7 @@ static cairo_status_t
|
|||
_cairo_stroker_done_path (void *closure);
|
||||
|
||||
static void
|
||||
_translate_point (XPointFixed *pt, XPointFixed *offset);
|
||||
_translate_point (cairo_point_t *pt, cairo_point_t *offset);
|
||||
|
||||
static int
|
||||
_cairo_stroker_face_clockwise (cairo_stroke_face_t *in, cairo_stroke_face_t *out);
|
||||
|
|
@ -125,7 +127,7 @@ _cairo_stroker_fini (cairo_stroker_t *stroker)
|
|||
}
|
||||
|
||||
static void
|
||||
_translate_point (XPointFixed *pt, XPointFixed *offset)
|
||||
_translate_point (cairo_point_t *pt, cairo_point_t *offset)
|
||||
{
|
||||
pt->x += offset->x;
|
||||
pt->y += offset->y;
|
||||
|
|
@ -134,14 +136,12 @@ _translate_point (XPointFixed *pt, XPointFixed *offset)
|
|||
static int
|
||||
_cairo_stroker_face_clockwise (cairo_stroke_face_t *in, cairo_stroke_face_t *out)
|
||||
{
|
||||
XPointDouble d_in, d_out;
|
||||
cairo_slope_t in_slope, out_slope;
|
||||
|
||||
d_in.x = XFixedToDouble (in->cw.x - in->pt.x);
|
||||
d_in.y = XFixedToDouble (in->cw.y - in->pt.y);
|
||||
d_out.x = XFixedToDouble (out->cw.x - out->pt.x);
|
||||
d_out.y = XFixedToDouble (out->cw.y - out->pt.y);
|
||||
_cairo_slope_init (&in_slope, &in->pt, &in->cw);
|
||||
_cairo_slope_init (&out_slope, &out->pt, &out->cw);
|
||||
|
||||
return d_out.y * d_in.x > d_in.y * d_out.x;
|
||||
return _cairo_slope_clockwise (&in_slope, &out_slope);
|
||||
}
|
||||
|
||||
static cairo_status_t
|
||||
|
|
@ -150,7 +150,7 @@ _cairo_stroker_join (cairo_stroker_t *stroker, cairo_stroke_face_t *in, cairo_st
|
|||
cairo_status_t status;
|
||||
cairo_gstate_t *gstate = stroker->gstate;
|
||||
int clockwise = _cairo_stroker_face_clockwise (out, in);
|
||||
XPointFixed *inpt, *outpt;
|
||||
cairo_point_t *inpt, *outpt;
|
||||
|
||||
if (in->cw.x == out->cw.x
|
||||
&& in->cw.y == out->cw.y
|
||||
|
|
@ -171,7 +171,7 @@ _cairo_stroker_join (cairo_stroker_t *stroker, cairo_stroke_face_t *in, cairo_st
|
|||
case CAIRO_LINE_JOIN_ROUND: {
|
||||
int i;
|
||||
int start, step, stop;
|
||||
XPointFixed tri[3], initial, final;
|
||||
cairo_point_t tri[3], initial, final;
|
||||
cairo_pen_t *pen = &gstate->pen_regular;
|
||||
|
||||
tri[0] = in->pt;
|
||||
|
|
@ -219,7 +219,7 @@ _cairo_stroker_join (cairo_stroker_t *stroker, cairo_stroke_face_t *in, cairo_st
|
|||
XDouble x1, y1, x2, y2;
|
||||
XDouble mx, my;
|
||||
XDouble dx1, dx2, dy1, dy2;
|
||||
XPointFixed outer;
|
||||
cairo_point_t outer;
|
||||
|
||||
x1 = XFixedToDouble (inpt->x);
|
||||
y1 = XFixedToDouble (inpt->y);
|
||||
|
|
@ -256,7 +256,7 @@ _cairo_stroker_join (cairo_stroker_t *stroker, cairo_stroke_face_t *in, cairo_st
|
|||
/* fall through ... */
|
||||
}
|
||||
case CAIRO_LINE_JOIN_BEVEL: {
|
||||
XPointFixed tri[3];
|
||||
cairo_point_t tri[3];
|
||||
tri[0] = in->pt;
|
||||
tri[1] = *inpt;
|
||||
tri[2] = *outpt;
|
||||
|
|
@ -279,8 +279,8 @@ _cairo_stroker_cap (cairo_stroker_t *stroker, cairo_stroke_face_t *f)
|
|||
case CAIRO_LINE_CAP_ROUND: {
|
||||
int i;
|
||||
int start, stop;
|
||||
cairo_slope_fixed_t slope;
|
||||
XPointFixed tri[3];
|
||||
cairo_slope_t slope;
|
||||
cairo_point_t tri[3];
|
||||
cairo_pen_t *pen = &gstate->pen_regular;
|
||||
|
||||
slope = f->dev_vector;
|
||||
|
|
@ -303,8 +303,8 @@ _cairo_stroker_cap (cairo_stroker_t *stroker, cairo_stroke_face_t *f)
|
|||
}
|
||||
case CAIRO_LINE_CAP_SQUARE: {
|
||||
double dx, dy;
|
||||
cairo_slope_fixed_t fvector;
|
||||
XPointFixed occw, ocw;
|
||||
cairo_slope_t fvector;
|
||||
cairo_point_t occw, ocw;
|
||||
cairo_polygon_t polygon;
|
||||
|
||||
_cairo_polygon_init (&polygon);
|
||||
|
|
@ -338,12 +338,12 @@ _cairo_stroker_cap (cairo_stroker_t *stroker, cairo_stroke_face_t *f)
|
|||
}
|
||||
|
||||
static void
|
||||
_compute_face (XPointFixed *pt, cairo_slope_fixed_t *slope, cairo_gstate_t *gstate, cairo_stroke_face_t *face)
|
||||
_compute_face (cairo_point_t *pt, cairo_slope_t *slope, cairo_gstate_t *gstate, cairo_stroke_face_t *face)
|
||||
{
|
||||
double mag, tmp;
|
||||
double dx, dy;
|
||||
XPointDouble usr_vector;
|
||||
XPointFixed offset_ccw, offset_cw;
|
||||
cairo_point_t offset_ccw, offset_cw;
|
||||
|
||||
dx = XFixedToDouble (slope->dx);
|
||||
dy = XFixedToDouble (slope->dy);
|
||||
|
|
@ -388,12 +388,12 @@ _compute_face (XPointFixed *pt, cairo_slope_fixed_t *slope, cairo_gstate_t *gsta
|
|||
}
|
||||
|
||||
static cairo_status_t
|
||||
_cairo_stroker_add_sub_edge (cairo_stroker_t *stroker, XPointFixed *p1, XPointFixed *p2,
|
||||
_cairo_stroker_add_sub_edge (cairo_stroker_t *stroker, cairo_point_t *p1, cairo_point_t *p2,
|
||||
cairo_stroke_face_t *start, cairo_stroke_face_t *end)
|
||||
{
|
||||
cairo_gstate_t *gstate = stroker->gstate;
|
||||
XPointFixed quad[4];
|
||||
cairo_slope_fixed_t slope;
|
||||
cairo_point_t quad[4];
|
||||
cairo_slope_t slope;
|
||||
|
||||
if (p1->x == p2->x && p1->y == p2->y) {
|
||||
/* XXX: Need to rethink how this case should be handled, (both
|
||||
|
|
@ -402,7 +402,7 @@ _cairo_stroker_add_sub_edge (cairo_stroker_t *stroker, XPointFixed *p1, XPointFi
|
|||
return CAIRO_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
_compute_slope (p1, p2, &slope);
|
||||
_cairo_slope_init (&slope, p1, p2);
|
||||
_compute_face (p1, &slope, gstate, start);
|
||||
|
||||
/* XXX: This could be optimized slightly by not calling
|
||||
|
|
@ -419,7 +419,7 @@ _cairo_stroker_add_sub_edge (cairo_stroker_t *stroker, XPointFixed *p1, XPointFi
|
|||
}
|
||||
|
||||
static cairo_status_t
|
||||
_cairo_stroker_add_edge (void *closure, XPointFixed *p1, XPointFixed *p2)
|
||||
_cairo_stroker_add_edge (void *closure, cairo_point_t *p1, cairo_point_t *p2)
|
||||
{
|
||||
cairo_status_t status;
|
||||
cairo_stroker_t *stroker = closure;
|
||||
|
|
@ -458,7 +458,7 @@ _cairo_stroker_add_edge (void *closure, XPointFixed *p1, XPointFixed *p2)
|
|||
* Dashed lines. Cap each dash end, join around turns when on
|
||||
*/
|
||||
static cairo_status_t
|
||||
_cairo_stroker_add_edge_dashed (void *closure, XPointFixed *p1, XPointFixed *p2)
|
||||
_cairo_stroker_add_edge_dashed (void *closure, cairo_point_t *p1, cairo_point_t *p2)
|
||||
{
|
||||
cairo_status_t status = CAIRO_STATUS_SUCCESS;
|
||||
cairo_stroker_t *stroker = closure;
|
||||
|
|
@ -466,7 +466,7 @@ _cairo_stroker_add_edge_dashed (void *closure, XPointFixed *p1, XPointFixed *p2)
|
|||
double mag, remain, tmp;
|
||||
double dx, dy;
|
||||
double dx2, dy2;
|
||||
XPointFixed fd1, fd2;
|
||||
cairo_point_t fd1, fd2;
|
||||
int first = 1;
|
||||
cairo_stroke_face_t sub_start, sub_end;
|
||||
|
||||
|
|
@ -564,7 +564,9 @@ _cairo_stroker_add_edge_dashed (void *closure, XPointFixed *p1, XPointFixed *p2)
|
|||
}
|
||||
|
||||
static cairo_status_t
|
||||
_cairo_stroker_add_spline (void *closure, XPointFixed *a, XPointFixed *b, XPointFixed *c, XPointFixed *d)
|
||||
_cairo_stroker_add_spline (void *closure,
|
||||
cairo_point_t *a, cairo_point_t *b,
|
||||
cairo_point_t *c, cairo_point_t *d)
|
||||
{
|
||||
cairo_status_t status = CAIRO_STATUS_SUCCESS;
|
||||
cairo_stroker_t *stroker = closure;
|
||||
|
|
@ -572,7 +574,7 @@ _cairo_stroker_add_spline (void *closure, XPointFixed *a, XPointFixed *b, XPoint
|
|||
cairo_spline_t spline;
|
||||
cairo_pen_t pen;
|
||||
cairo_stroke_face_t start, end;
|
||||
XPointFixed extra_points[4];
|
||||
cairo_point_t extra_points[4];
|
||||
|
||||
status = _cairo_spline_init (&spline, a, b, c, d);
|
||||
if (status == cairo_int_status_degenerate)
|
||||
|
|
@ -645,7 +647,7 @@ _cairo_stroker_done_sub_path (void *closure, cairo_sub_path_done_t done)
|
|||
/* fall through... */
|
||||
case cairo_sub_path_done_cap:
|
||||
if (stroker->have_first) {
|
||||
XPointFixed t;
|
||||
cairo_point_t t;
|
||||
/* The initial cap needs an outward facing vector. Reverse everything */
|
||||
stroker->first.usr_vector.x = -stroker->first.usr_vector.x;
|
||||
stroker->first.usr_vector.y = -stroker->first.usr_vector.y;
|
||||
|
|
@ -702,8 +704,8 @@ _cairo_path_stroke_to_traps (cairo_path_t *path, cairo_gstate_t *gstate, cairo_t
|
|||
_cairo_stroker_init (&stroker, gstate, traps);
|
||||
|
||||
status = _cairo_path_interpret (path,
|
||||
cairo_path_direction_forward,
|
||||
callbacks, &stroker);
|
||||
cairo_path_direction_forward,
|
||||
callbacks, &stroker);
|
||||
if (status) {
|
||||
_cairo_stroker_fini (&stroker);
|
||||
return status;
|
||||
|
|
|
|||
|
|
@ -30,7 +30,7 @@
|
|||
|
||||
/* private functions */
|
||||
static cairo_status_t
|
||||
_cairo_path_add (cairo_path_t *path, cairo_path_op_t op, XPointFixed *pts, int num_pts);
|
||||
_cairo_path_add (cairo_path_t *path, cairo_path_op_t op, cairo_point_t *pts, int num_pts);
|
||||
|
||||
static void
|
||||
_cairo_path_add_op_buf (cairo_path_t *path, cairo_path_op_buf_t *op);
|
||||
|
|
@ -60,7 +60,7 @@ static void
|
|||
_cairo_path_arg_buf_destroy (cairo_path_arg_buf_t *buf);
|
||||
|
||||
static void
|
||||
_cairo_path_arg_buf_add (cairo_path_arg_buf_t *arg, XPointFixed *pts, int num_pts);
|
||||
_cairo_path_arg_buf_add (cairo_path_arg_buf_t *arg, cairo_point_t *pts, int num_pts);
|
||||
|
||||
void
|
||||
_cairo_path_init (cairo_path_t *path)
|
||||
|
|
@ -125,7 +125,7 @@ _cairo_path_fini (cairo_path_t *path)
|
|||
cairo_status_t
|
||||
_cairo_path_move_to (cairo_path_t *path, double x, double y)
|
||||
{
|
||||
XPointFixed pt;
|
||||
cairo_point_t pt;
|
||||
|
||||
pt.x = XDoubleToFixed (x);
|
||||
pt.y = XDoubleToFixed (y);
|
||||
|
|
@ -136,7 +136,7 @@ _cairo_path_move_to (cairo_path_t *path, double x, double y)
|
|||
cairo_status_t
|
||||
_cairo_path_line_to (cairo_path_t *path, double x, double y)
|
||||
{
|
||||
XPointFixed pt;
|
||||
cairo_point_t pt;
|
||||
|
||||
pt.x = XDoubleToFixed (x);
|
||||
pt.y = XDoubleToFixed (y);
|
||||
|
|
@ -150,7 +150,7 @@ _cairo_path_curve_to (cairo_path_t *path,
|
|||
double x2, double y2,
|
||||
double x3, double y3)
|
||||
{
|
||||
XPointFixed pt[3];
|
||||
cairo_point_t pt[3];
|
||||
|
||||
pt[0].x = XDoubleToFixed (x1);
|
||||
pt[0].y = XDoubleToFixed (y1);
|
||||
|
|
@ -171,7 +171,7 @@ _cairo_path_close_path (cairo_path_t *path)
|
|||
}
|
||||
|
||||
static cairo_status_t
|
||||
_cairo_path_add (cairo_path_t *path, cairo_path_op_t op, XPointFixed *pts, int num_pts)
|
||||
_cairo_path_add (cairo_path_t *path, cairo_path_op_t op, cairo_point_t *pts, int num_pts)
|
||||
{
|
||||
cairo_status_t status;
|
||||
|
||||
|
|
@ -300,7 +300,7 @@ _cairo_path_arg_buf_destroy (cairo_path_arg_buf_t *arg)
|
|||
}
|
||||
|
||||
static void
|
||||
_cairo_path_arg_buf_add (cairo_path_arg_buf_t *arg, XPointFixed *pts, int num_pts)
|
||||
_cairo_path_arg_buf_add (cairo_path_arg_buf_t *arg, cairo_point_t *pts, int num_pts)
|
||||
{
|
||||
int i;
|
||||
|
||||
|
|
@ -328,9 +328,9 @@ _cairo_path_interpret (cairo_path_t *path, cairo_path_direction_t dir, const cai
|
|||
cairo_path_op_t op;
|
||||
cairo_path_arg_buf_t *arg_buf = path->arg_head;
|
||||
int buf_i = 0;
|
||||
XPointFixed pt[CAIRO_PATH_OP_MAX_ARGS];
|
||||
XPointFixed current = {0, 0};
|
||||
XPointFixed first = {0, 0};
|
||||
cairo_point_t pt[CAIRO_PATH_OP_MAX_ARGS];
|
||||
cairo_point_t current = {0, 0};
|
||||
cairo_point_t first = {0, 0};
|
||||
int has_current = 0;
|
||||
int has_edge = 0;
|
||||
int step = (dir == cairo_path_direction_forward) ? 1 : -1;
|
||||
|
|
@ -375,7 +375,7 @@ _cairo_path_interpret (cairo_path_t *path, cairo_path_direction_t dir, const cai
|
|||
switch (op) {
|
||||
case cairo_path_op_move_to:
|
||||
if (has_edge) {
|
||||
status = (*cb->DoneSubPath) (closure, cairo_sub_path_done_cap);
|
||||
status = (*cb->done_sub_path) (closure, cairo_sub_path_done_cap);
|
||||
if (status)
|
||||
return status;
|
||||
}
|
||||
|
|
@ -386,7 +386,7 @@ _cairo_path_interpret (cairo_path_t *path, cairo_path_direction_t dir, const cai
|
|||
break;
|
||||
case cairo_path_op_line_to:
|
||||
if (has_current) {
|
||||
status = (*cb->AddEdge) (closure, ¤t, &pt[0]);
|
||||
status = (*cb->add_edge) (closure, ¤t, &pt[0]);
|
||||
if (status)
|
||||
return status;
|
||||
current = pt[0];
|
||||
|
|
@ -400,7 +400,7 @@ _cairo_path_interpret (cairo_path_t *path, cairo_path_direction_t dir, const cai
|
|||
break;
|
||||
case cairo_path_op_curve_to:
|
||||
if (has_current) {
|
||||
status = (*cb->AddSpline) (closure, ¤t, &pt[0], &pt[1], &pt[2]);
|
||||
status = (*cb->add_spline) (closure, ¤t, &pt[0], &pt[1], &pt[2]);
|
||||
if (status)
|
||||
return status;
|
||||
current = pt[2];
|
||||
|
|
@ -414,8 +414,8 @@ _cairo_path_interpret (cairo_path_t *path, cairo_path_direction_t dir, const cai
|
|||
break;
|
||||
case cairo_path_op_close_path:
|
||||
if (has_edge) {
|
||||
(*cb->AddEdge) (closure, ¤t, &first);
|
||||
(*cb->DoneSubPath) (closure, cairo_sub_path_done_join);
|
||||
(*cb->add_edge) (closure, ¤t, &first);
|
||||
(*cb->done_sub_path) (closure, cairo_sub_path_done_join);
|
||||
}
|
||||
current.x = 0;
|
||||
current.y = 0;
|
||||
|
|
@ -428,9 +428,9 @@ _cairo_path_interpret (cairo_path_t *path, cairo_path_direction_t dir, const cai
|
|||
}
|
||||
}
|
||||
if (has_edge)
|
||||
(*cb->DoneSubPath) (closure, cairo_sub_path_done_cap);
|
||||
(*cb->done_sub_path) (closure, cairo_sub_path_done_cap);
|
||||
|
||||
return (*cb->DonePath) (closure);
|
||||
return (*cb->done_path) (closure);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
134
src/cairo-pen.c
134
src/cairo-pen.c
|
|
@ -34,13 +34,7 @@ static void
|
|||
_cairo_pen_compute_slopes (cairo_pen_t *pen);
|
||||
|
||||
static int
|
||||
_slope_clockwise (cairo_slope_fixed_t *a, cairo_slope_fixed_t *b);
|
||||
|
||||
static int
|
||||
_slope_counter_clockwise (cairo_slope_fixed_t *a, cairo_slope_fixed_t *b);
|
||||
|
||||
static int
|
||||
_cairo_pen_vertex_compare_by_theta (const void *a, const void *b);
|
||||
_pen_vertex_compare (const void *av, const void *bv);
|
||||
|
||||
static cairo_status_t
|
||||
_cairo_pen_stroke_spline_half (cairo_pen_t *pen, cairo_spline_t *spline, cairo_pen_stroke_direction_t dir, cairo_polygon_t *polygon);
|
||||
|
|
@ -60,8 +54,6 @@ cairo_status_t
|
|||
_cairo_pen_init (cairo_pen_t *pen, double radius, cairo_gstate_t *gstate)
|
||||
{
|
||||
int i;
|
||||
cairo_pen_vertex_t *v;
|
||||
double dx, dy;
|
||||
|
||||
if (pen->num_vertices) {
|
||||
/* XXX: It would be nice to notice that the pen is already properly constructed.
|
||||
|
|
@ -87,17 +79,13 @@ _cairo_pen_init (cairo_pen_t *pen, double radius, cairo_gstate_t *gstate)
|
|||
}
|
||||
|
||||
for (i=0; i < pen->num_vertices; i++) {
|
||||
v = &pen->vertex[i];
|
||||
v->theta = 2 * M_PI * i / (double) pen->num_vertices;
|
||||
dx = radius * cos (v->theta);
|
||||
dy = radius * sin (v->theta);
|
||||
double theta = 2 * M_PI * i / (double) pen->num_vertices;
|
||||
double dx = radius * cos (theta);
|
||||
double dy = radius * sin (theta);
|
||||
cairo_pen_vertex_t *v = &pen->vertex[i];
|
||||
cairo_matrix_transform_distance (&gstate->ctm, &dx, &dy);
|
||||
v->pt.x = XDoubleToFixed (dx);
|
||||
v->pt.y = XDoubleToFixed (dy);
|
||||
/* Recompute theta in device space */
|
||||
v->theta = atan2 (v->pt.y, v->pt.x);
|
||||
if (v->theta < 0)
|
||||
v->theta += 2 * M_PI;
|
||||
}
|
||||
|
||||
_cairo_pen_compute_slopes (pen);
|
||||
|
|
@ -128,26 +116,10 @@ _cairo_pen_init_copy (cairo_pen_t *pen, cairo_pen_t *other)
|
|||
return CAIRO_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
static int
|
||||
_cairo_pen_vertex_compare_by_theta (const void *a, const void *b)
|
||||
{
|
||||
double diff;
|
||||
const cairo_pen_vertex_t *va = a;
|
||||
const cairo_pen_vertex_t *vb = b;
|
||||
|
||||
diff = va->theta - vb->theta;
|
||||
if (diff < 0)
|
||||
return -1;
|
||||
else if (diff > 0)
|
||||
return 1;
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
cairo_status_t
|
||||
_cairo_pen_add_points (cairo_pen_t *pen, XPointFixed *pt, int num_pts)
|
||||
_cairo_pen_add_points (cairo_pen_t *pen, cairo_point_t *pt, int num_pts)
|
||||
{
|
||||
int i, j;
|
||||
int i;
|
||||
cairo_pen_vertex_t *v, *v_next, *new_vertex;
|
||||
|
||||
pen->num_vertices += num_pts;
|
||||
|
|
@ -162,21 +134,18 @@ _cairo_pen_add_points (cairo_pen_t *pen, XPointFixed *pt, int num_pts)
|
|||
for (i=0; i < num_pts; i++) {
|
||||
v = &pen->vertex[pen->num_vertices-(i+1)];
|
||||
v->pt = pt[i];
|
||||
v->theta = atan2 (v->pt.y, v->pt.x);
|
||||
if (v->theta < 0)
|
||||
v->theta += 2 * M_PI;
|
||||
}
|
||||
|
||||
qsort (pen->vertex, pen->num_vertices, sizeof (cairo_pen_vertex_t), _cairo_pen_vertex_compare_by_theta);
|
||||
qsort (pen->vertex, pen->num_vertices, sizeof (cairo_pen_vertex_t), _pen_vertex_compare);
|
||||
|
||||
/* eliminate any duplicate vertices */
|
||||
for (i=0; i < pen->num_vertices - 1; i++ ) {
|
||||
for (i=0; i < pen->num_vertices; i++ ) {
|
||||
v = &pen->vertex[i];
|
||||
v_next = &pen->vertex[i+1];
|
||||
if (v->pt.x == v_next->pt.x && v->pt.y == v_next->pt.y) {
|
||||
for (j=i+1; j < pen->num_vertices - 1; j++)
|
||||
pen->vertex[j] = pen->vertex[j+1];
|
||||
v_next = (i < pen->num_vertices - 1) ? &pen->vertex[i+1] : &pen->vertex[0];
|
||||
if (_pen_vertex_compare (v, v_next) == 0) {
|
||||
pen->num_vertices--;
|
||||
memmove (&pen->vertex[i], &pen->vertex[i+1],
|
||||
(pen->num_vertices - i) * sizeof (cairo_pen_vertex_t));
|
||||
/* There may be more of the same duplicate, check again */
|
||||
i--;
|
||||
}
|
||||
|
|
@ -219,34 +188,53 @@ _cairo_pen_compute_slopes (cairo_pen_t *pen)
|
|||
v = &pen->vertex[i];
|
||||
next = &pen->vertex[(i + 1) % pen->num_vertices];
|
||||
|
||||
_compute_slope (&prev->pt, &v->pt, &v->slope_cw);
|
||||
_compute_slope (&v->pt, &next->pt, &v->slope_ccw);
|
||||
_cairo_slope_init (&v->slope_cw, &prev->pt, &v->pt);
|
||||
_cairo_slope_init (&v->slope_ccw, &v->pt, &next->pt);
|
||||
}
|
||||
}
|
||||
|
||||
/* Is a clockwise of b?
|
||||
/* Is a further clockwise from (1,0) than b?
|
||||
*
|
||||
* NOTE: The strict equality here is not significant in and of itself,
|
||||
* but there are functions up above that are sensitive to it,
|
||||
* (cf. _cairo_pen_find_active_cw_vertex_index).
|
||||
* There are a two special cases to consider:
|
||||
* 1) a and b are not in the same half plane.
|
||||
* 2) both a and b are on the X axis
|
||||
* After that, the computation is a simple slope comparison.
|
||||
*/
|
||||
static int
|
||||
_slope_clockwise (cairo_slope_fixed_t *a, cairo_slope_fixed_t *b)
|
||||
_pen_vertex_compare (const void *av, const void *bv)
|
||||
{
|
||||
return ((cairo_fixed_48_16_t) b->dy * (cairo_fixed_48_16_t) a->dx
|
||||
> (cairo_fixed_48_16_t) a->dy * (cairo_fixed_48_16_t) b->dx);
|
||||
}
|
||||
const cairo_pen_vertex_t *a = av;
|
||||
const cairo_pen_vertex_t *b = bv;
|
||||
cairo_fixed_48_16_t diff;
|
||||
|
||||
static int
|
||||
_slope_counter_clockwise (cairo_slope_fixed_t *a, cairo_slope_fixed_t *b)
|
||||
{
|
||||
return ! _slope_clockwise (a, b);
|
||||
int a_above = a->pt.y >= 0;
|
||||
int b_above = b->pt.y >= 0;
|
||||
|
||||
if (a_above != b_above)
|
||||
return b_above - a_above;
|
||||
|
||||
if (a->pt.y == 0 && b->pt.y == 0) {
|
||||
int a_right = a->pt.x >= 0;
|
||||
int b_right = b->pt.x >= 0;
|
||||
|
||||
if (a_right != b_right)
|
||||
return b_right - a_right;
|
||||
}
|
||||
|
||||
diff = ((cairo_fixed_48_16_t) a->pt.y * (cairo_fixed_48_16_t) b->pt.x
|
||||
- (cairo_fixed_48_16_t) b->pt.y * (cairo_fixed_48_16_t) a->pt.x);
|
||||
|
||||
if (diff > 0)
|
||||
return 1;
|
||||
if (diff < 0)
|
||||
return -1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Find active pen vertex for clockwise edge of stroke at the given slope.
|
||||
*
|
||||
* NOTE: The behavior of this function is sensitive to the sense of
|
||||
* the inequality within _slope_clockwise/_slope_counter_clockwise.
|
||||
* the inequality within _cairo_slope_clockwise/_cairo_slope_counter_clockwise.
|
||||
*
|
||||
* The issue is that the slope_ccw member of one pen vertex will be
|
||||
* equivalent to the slope_cw member of the next pen vertex in a
|
||||
|
|
@ -255,14 +243,14 @@ _slope_counter_clockwise (cairo_slope_fixed_t *a, cairo_slope_fixed_t *b)
|
|||
*/
|
||||
cairo_status_t
|
||||
_cairo_pen_find_active_cw_vertex_index (cairo_pen_t *pen,
|
||||
cairo_slope_fixed_t *slope,
|
||||
cairo_slope_t *slope,
|
||||
int *active)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i=0; i < pen->num_vertices; i++) {
|
||||
if (_slope_clockwise (slope, &pen->vertex[i].slope_ccw)
|
||||
&& _slope_counter_clockwise (slope, &pen->vertex[i].slope_cw))
|
||||
if (_cairo_slope_clockwise (slope, &pen->vertex[i].slope_ccw)
|
||||
&& _cairo_slope_counter_clockwise (slope, &pen->vertex[i].slope_cw))
|
||||
break;
|
||||
}
|
||||
|
||||
|
|
@ -274,23 +262,23 @@ _cairo_pen_find_active_cw_vertex_index (cairo_pen_t *pen,
|
|||
/* Find active pen vertex for counterclockwise edge of stroke at the given slope.
|
||||
*
|
||||
* NOTE: The behavior of this function is sensitive to the sense of
|
||||
* the inequality within _slope_clockwise/_slope_counter_clockwise.
|
||||
* the inequality within _cairo_slope_clockwise/_cairo_slope_counter_clockwise.
|
||||
*/
|
||||
cairo_status_t
|
||||
_cairo_pen_find_active_ccw_vertex_index (cairo_pen_t *pen,
|
||||
cairo_slope_fixed_t *slope,
|
||||
cairo_slope_t *slope,
|
||||
int *active)
|
||||
{
|
||||
int i;
|
||||
cairo_slope_fixed_t slope_reverse;
|
||||
cairo_slope_t slope_reverse;
|
||||
|
||||
slope_reverse = *slope;
|
||||
slope_reverse.dx = -slope_reverse.dx;
|
||||
slope_reverse.dy = -slope_reverse.dy;
|
||||
|
||||
for (i=pen->num_vertices-1; i >= 0; i--) {
|
||||
if (_slope_counter_clockwise (&pen->vertex[i].slope_ccw, &slope_reverse)
|
||||
&& _slope_clockwise (&pen->vertex[i].slope_cw, &slope_reverse))
|
||||
if (_cairo_slope_counter_clockwise (&pen->vertex[i].slope_ccw, &slope_reverse)
|
||||
&& _cairo_slope_clockwise (&pen->vertex[i].slope_cw, &slope_reverse))
|
||||
break;
|
||||
}
|
||||
|
||||
|
|
@ -309,9 +297,9 @@ _cairo_pen_stroke_spline_half (cairo_pen_t *pen,
|
|||
cairo_status_t status;
|
||||
int start, stop, step;
|
||||
int active = 0;
|
||||
XPointFixed hull_pt;
|
||||
cairo_slope_fixed_t slope, initial_slope, final_slope;
|
||||
XPointFixed *pt = spline->pts;
|
||||
cairo_point_t hull_pt;
|
||||
cairo_slope_t slope, initial_slope, final_slope;
|
||||
cairo_point_t *pt = spline->pts;
|
||||
int num_pts = spline->num_pts;
|
||||
|
||||
if (dir == cairo_pen_stroke_direction_forward) {
|
||||
|
|
@ -345,11 +333,11 @@ _cairo_pen_stroke_spline_half (cairo_pen_t *pen,
|
|||
if (i + step == stop)
|
||||
slope = final_slope;
|
||||
else
|
||||
_compute_slope (&pt[i], &pt[i+step], &slope);
|
||||
if (_slope_counter_clockwise (&slope, &pen->vertex[active].slope_ccw)) {
|
||||
_cairo_slope_init (&slope, &pt[i], &pt[i+step]);
|
||||
if (_cairo_slope_counter_clockwise (&slope, &pen->vertex[active].slope_ccw)) {
|
||||
if (++active == pen->num_vertices)
|
||||
active = 0;
|
||||
} else if (_slope_clockwise (&slope, &pen->vertex[active].slope_cw)) {
|
||||
} else if (_cairo_slope_clockwise (&slope, &pen->vertex[active].slope_cw)) {
|
||||
if (--active == -1)
|
||||
active = pen->num_vertices - 1;
|
||||
} else {
|
||||
|
|
|
|||
|
|
@ -36,8 +36,7 @@ static cairo_status_t
|
|||
_cairo_polygon_grow_by (cairo_polygon_t *polygon, int additional);
|
||||
|
||||
static void
|
||||
_cairo_polygon_set_last_point (cairo_polygon_t *polygon, XPointFixed *pt);
|
||||
|
||||
_cairo_polygon_set_last_point (cairo_polygon_t *polygon, cairo_point_t *pt);
|
||||
|
||||
void
|
||||
_cairo_polygon_init (cairo_polygon_t *polygon)
|
||||
|
|
@ -94,14 +93,14 @@ _cairo_polygon_grow_by (cairo_polygon_t *polygon, int additional)
|
|||
}
|
||||
|
||||
static void
|
||||
_cairo_polygon_set_last_point (cairo_polygon_t *polygon, XPointFixed *pt)
|
||||
_cairo_polygon_set_last_point (cairo_polygon_t *polygon, cairo_point_t *pt)
|
||||
{
|
||||
polygon->last_pt = *pt;
|
||||
polygon->last_pt_defined = 1;
|
||||
}
|
||||
|
||||
cairo_status_t
|
||||
_cairo_polygon_add_edge (cairo_polygon_t *polygon, XPointFixed *p1, XPointFixed *p2)
|
||||
_cairo_polygon_add_edge (cairo_polygon_t *polygon, cairo_point_t *p1, cairo_point_t *p2)
|
||||
{
|
||||
cairo_status_t status;
|
||||
cairo_edge_t *edge;
|
||||
|
|
@ -144,7 +143,7 @@ _cairo_polygon_add_edge (cairo_polygon_t *polygon, XPointFixed *p1, XPointFixed
|
|||
}
|
||||
|
||||
cairo_status_t
|
||||
_cairo_polygon_add_point (cairo_polygon_t *polygon, XPointFixed *pt)
|
||||
_cairo_polygon_add_point (cairo_polygon_t *polygon, cairo_point_t *pt)
|
||||
{
|
||||
cairo_status_t status = CAIRO_STATUS_SUCCESS;
|
||||
|
||||
|
|
|
|||
|
|
@ -28,9 +28,31 @@
|
|||
#include "cairoint.h"
|
||||
|
||||
void
|
||||
_compute_slope (XPointFixed *a, XPointFixed *b, cairo_slope_fixed_t *slope)
|
||||
_cairo_slope_init (cairo_slope_t *slope, cairo_point_t *a, cairo_point_t *b)
|
||||
{
|
||||
slope->dx = b->x - a->x;
|
||||
slope->dy = b->y - a->y;
|
||||
}
|
||||
|
||||
/* Is a clockwise of b?
|
||||
*
|
||||
* NOTE: The strict equality here is not significant in and of itself,
|
||||
* but there are functions up above that are sensitive to it,
|
||||
* (cf. _cairo_pen_find_active_cw_vertex_index).
|
||||
*/
|
||||
int
|
||||
_cairo_slope_clockwise (cairo_slope_t *a, cairo_slope_t *b)
|
||||
{
|
||||
return ((cairo_fixed_48_16_t) b->dy * (cairo_fixed_48_16_t) a->dx
|
||||
> (cairo_fixed_48_16_t) a->dy * (cairo_fixed_48_16_t) b->dx);
|
||||
}
|
||||
|
||||
int
|
||||
_cairo_slope_counter_clockwise (cairo_slope_t *a, cairo_slope_t *b)
|
||||
{
|
||||
return ! _cairo_slope_clockwise (a, b);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
@ -31,10 +31,10 @@ static cairo_status_t
|
|||
_cairo_spline_grow_by (cairo_spline_t *spline, int additional);
|
||||
|
||||
static cairo_status_t
|
||||
_cairo_spline_add_point (cairo_spline_t *spline, XPointFixed *pt);
|
||||
_cairo_spline_add_point (cairo_spline_t *spline, cairo_point_t *pt);
|
||||
|
||||
static void
|
||||
_lerp_half (XPointFixed *a, XPointFixed *b, XPointFixed *result);
|
||||
_lerp_half (cairo_point_t *a, cairo_point_t *b, cairo_point_t *result);
|
||||
|
||||
static void
|
||||
_de_casteljau (cairo_spline_t *spline, cairo_spline_t *s1, cairo_spline_t *s2);
|
||||
|
|
@ -48,7 +48,9 @@ _cairo_spline_decompose_into (cairo_spline_t *spline, double tolerance_squared,
|
|||
#define CAIRO_SPLINE_GROWTH_INC 100
|
||||
|
||||
cairo_int_status_t
|
||||
_cairo_spline_init (cairo_spline_t *spline, XPointFixed *a, XPointFixed *b, XPointFixed *c, XPointFixed *d)
|
||||
_cairo_spline_init (cairo_spline_t *spline,
|
||||
cairo_point_t *a, cairo_point_t *b,
|
||||
cairo_point_t *c, cairo_point_t *d)
|
||||
{
|
||||
spline->a = *a;
|
||||
spline->b = *b;
|
||||
|
|
@ -56,21 +58,21 @@ _cairo_spline_init (cairo_spline_t *spline, XPointFixed *a, XPointFixed *b, XP
|
|||
spline->d = *d;
|
||||
|
||||
if (a->x != b->x || a->y != b->y) {
|
||||
_compute_slope (&spline->a, &spline->b, &spline->initial_slope);
|
||||
_cairo_slope_init (&spline->initial_slope, &spline->a, &spline->b);
|
||||
} else if (a->x != c->x || a->y != c->y) {
|
||||
_compute_slope (&spline->a, &spline->c, &spline->initial_slope);
|
||||
_cairo_slope_init (&spline->initial_slope, &spline->a, &spline->c);
|
||||
} else if (a->x != d->x || a->y != d->y) {
|
||||
_compute_slope (&spline->a, &spline->d, &spline->initial_slope);
|
||||
_cairo_slope_init (&spline->initial_slope, &spline->a, &spline->d);
|
||||
} else {
|
||||
return cairo_int_status_degenerate;
|
||||
}
|
||||
|
||||
if (c->x != d->x || c->y != d->y) {
|
||||
_compute_slope (&spline->c, &spline->d, &spline->final_slope);
|
||||
_cairo_slope_init (&spline->final_slope, &spline->c, &spline->d);
|
||||
} else if (b->x != d->x || b->y != d->y) {
|
||||
_compute_slope (&spline->b, &spline->d, &spline->final_slope);
|
||||
_cairo_slope_init (&spline->final_slope, &spline->b, &spline->d);
|
||||
} else {
|
||||
_compute_slope (&spline->a, &spline->d, &spline->final_slope);
|
||||
_cairo_slope_init (&spline->final_slope, &spline->a, &spline->d);
|
||||
}
|
||||
|
||||
spline->num_pts = 0;
|
||||
|
|
@ -92,7 +94,7 @@ _cairo_spline_fini (cairo_spline_t *spline)
|
|||
static cairo_status_t
|
||||
_cairo_spline_grow_by (cairo_spline_t *spline, int additional)
|
||||
{
|
||||
XPointFixed *new_pts;
|
||||
cairo_point_t *new_pts;
|
||||
int old_size = spline->pts_size;
|
||||
int new_size = spline->num_pts + additional;
|
||||
|
||||
|
|
@ -100,7 +102,7 @@ _cairo_spline_grow_by (cairo_spline_t *spline, int additional)
|
|||
return CAIRO_STATUS_SUCCESS;
|
||||
|
||||
spline->pts_size = new_size;
|
||||
new_pts = realloc (spline->pts, spline->pts_size * sizeof (XPointFixed));
|
||||
new_pts = realloc (spline->pts, spline->pts_size * sizeof (cairo_point_t));
|
||||
|
||||
if (new_pts == NULL) {
|
||||
spline->pts_size = old_size;
|
||||
|
|
@ -113,7 +115,7 @@ _cairo_spline_grow_by (cairo_spline_t *spline, int additional)
|
|||
}
|
||||
|
||||
static cairo_status_t
|
||||
_cairo_spline_add_point (cairo_spline_t *spline, XPointFixed *pt)
|
||||
_cairo_spline_add_point (cairo_spline_t *spline, cairo_point_t *pt)
|
||||
{
|
||||
cairo_status_t status;
|
||||
|
||||
|
|
@ -130,7 +132,7 @@ _cairo_spline_add_point (cairo_spline_t *spline, XPointFixed *pt)
|
|||
}
|
||||
|
||||
static void
|
||||
_lerp_half (XPointFixed *a, XPointFixed *b, XPointFixed *result)
|
||||
_lerp_half (cairo_point_t *a, cairo_point_t *b, cairo_point_t *result)
|
||||
{
|
||||
result->x = a->x + ((b->x - a->x) >> 1);
|
||||
result->y = a->y + ((b->y - a->y) >> 1);
|
||||
|
|
@ -139,9 +141,9 @@ _lerp_half (XPointFixed *a, XPointFixed *b, XPointFixed *result)
|
|||
static void
|
||||
_de_casteljau (cairo_spline_t *spline, cairo_spline_t *s1, cairo_spline_t *s2)
|
||||
{
|
||||
XPointFixed ab, bc, cd;
|
||||
XPointFixed abbc, bccd;
|
||||
XPointFixed final;
|
||||
cairo_point_t ab, bc, cd;
|
||||
cairo_point_t abbc, bccd;
|
||||
cairo_point_t final;
|
||||
|
||||
_lerp_half (&spline->a, &spline->b, &ab);
|
||||
_lerp_half (&spline->b, &spline->c, &bc);
|
||||
|
|
@ -162,7 +164,7 @@ _de_casteljau (cairo_spline_t *spline, cairo_spline_t *s1, cairo_spline_t *s2)
|
|||
}
|
||||
|
||||
static double
|
||||
_PointDistanceSquaredToPoint (XPointFixed *a, XPointFixed *b)
|
||||
_PointDistanceSquaredToPoint (cairo_point_t *a, cairo_point_t *b)
|
||||
{
|
||||
double dx = XFixedToDouble (b->x - a->x);
|
||||
double dy = XFixedToDouble (b->y - a->y);
|
||||
|
|
@ -171,12 +173,12 @@ _PointDistanceSquaredToPoint (XPointFixed *a, XPointFixed *b)
|
|||
}
|
||||
|
||||
static double
|
||||
_PointDistanceSquaredToSegment (XPointFixed *p, XPointFixed *p1, XPointFixed *p2)
|
||||
_PointDistanceSquaredToSegment (cairo_point_t *p, cairo_point_t *p1, cairo_point_t *p2)
|
||||
{
|
||||
double u;
|
||||
double dx, dy;
|
||||
double pdx, pdy;
|
||||
XPointFixed px;
|
||||
cairo_point_t px;
|
||||
|
||||
/* intersection point (px):
|
||||
|
||||
|
|
|
|||
|
|
@ -29,6 +29,34 @@
|
|||
|
||||
#include "cairoint.h"
|
||||
|
||||
static const XTransform CAIRO_XTRANSFORM_IDENTITY = {
|
||||
{
|
||||
{65536, 0, 0},
|
||||
{ 0, 65536, 0},
|
||||
{ 0, 0, 65536}
|
||||
}
|
||||
};
|
||||
|
||||
#define CAIRO_SURFACE_RENDER_AT_LEAST(surface, major, minor) \
|
||||
(((surface)->render_major > major) ? 1 \
|
||||
: ((surface)->render_major == major) ? ((surface)->render_minor >= minor) : 0)
|
||||
|
||||
#define CAIRO_SURFACE_RENDER_HAS_CREATE_PICTURE(surface) CAIRO_SURFACE_RENDER_AT_LEAST((surface), 0, 0)
|
||||
#define CAIRO_SURFACE_RENDER_HAS_COMPOSITE(surface) CAIRO_SURFACE_RENDER_AT_LEAST((surface), 0, 0)
|
||||
|
||||
#define CAIRO_SURFACE_RENDER_HAS_FILL_RECTANGLE(surface) CAIRO_SURFACE_RENDER_AT_LEAST((surface), 0, 1)
|
||||
#define CAIRO_SURFACE_RENDER_HAS_FILL_RECTANGLES(surface) CAIRO_SURFACE_RENDER_AT_LEAST((surface), 0, 1)
|
||||
|
||||
#define CAIRO_SURFACE_RENDER_HAS_DISJOINT(surface) CAIRO_SURFACE_RENDER_AT_LEAST((surface), 0, 2)
|
||||
#define CAIRO_SURFACE_RENDER_HAS_CONJOINT(surface) CAIRO_SURFACE_RENDER_AT_LEAST((surface), 0, 2)
|
||||
|
||||
#define CAIRO_SURFACE_RENDER_HAS_TRAPEZOIDS(surface) CAIRO_SURFACE_RENDER_AT_LEAST((surface), 0, 4)
|
||||
#define CAIRO_SURFACE_RENDER_HAS_TRIANGLES(surface) CAIRO_SURFACE_RENDER_AT_LEAST((surface), 0, 4)
|
||||
#define CAIRO_SURFACE_RENDER_HAS_TRISTRIP(surface) CAIRO_SURFACE_RENDER_AT_LEAST((surface), 0, 4)
|
||||
#define CAIRO_SURFACE_RENDER_HAS_TRIFAN(surface) CAIRO_SURFACE_RENDER_AT_LEAST((surface), 0, 4)
|
||||
|
||||
#define CAIRO_SURFACE_RENDER_HAS_PICTURE_TRANSFORM(surface) CAIRO_SURFACE_RENDER_AT_LEAST((surface), 0, 6)
|
||||
|
||||
cairo_surface_t *
|
||||
cairo_surface_create_for_drawable (Display *dpy,
|
||||
Drawable drawable,
|
||||
|
|
@ -42,20 +70,35 @@ cairo_surface_create_for_drawable (Display *dpy,
|
|||
if (surface == NULL)
|
||||
return NULL;
|
||||
|
||||
surface->dpy = dpy;
|
||||
surface->image_data = NULL;
|
||||
|
||||
surface->xc_surface = XcSurfaceCreateForDrawable (dpy, drawable, visual, format, colormap);
|
||||
if (surface->xc_surface == NULL) {
|
||||
free (surface);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* XXX: We should really get this value from somewhere like Xft.dpy */
|
||||
surface->ppm = 3780;
|
||||
|
||||
surface->ref_count = 1;
|
||||
|
||||
surface->dpy = dpy;
|
||||
surface->image_data = NULL;
|
||||
surface->icimage = NULL;
|
||||
|
||||
surface->type = CAIRO_SURFACE_TYPE_DRAWABLE;
|
||||
surface->xtransform = CAIRO_XTRANSFORM_IDENTITY;
|
||||
|
||||
surface->gc = 0;
|
||||
surface->drawable = drawable;
|
||||
surface->visual = visual;
|
||||
|
||||
if (! XRenderQueryVersion (dpy, &surface->render_major, &surface->render_minor)) {
|
||||
surface->render_major = -1;
|
||||
surface->render_minor = -1;
|
||||
}
|
||||
|
||||
/* XXX: I'm currently ignoring the colormap. Is that bad? */
|
||||
if (CAIRO_SURFACE_RENDER_HAS_CREATE_PICTURE (surface))
|
||||
surface->picture = XRenderCreatePicture (dpy, drawable,
|
||||
visual
|
||||
? XRenderFindVisualFormat (dpy, visual)
|
||||
: XRenderFindStandardFormat (dpy, format),
|
||||
0, NULL);
|
||||
|
||||
return surface;
|
||||
}
|
||||
|
||||
|
|
@ -144,25 +187,31 @@ cairo_surface_create_for_image (char *data,
|
|||
if (surface == NULL)
|
||||
return NULL;
|
||||
|
||||
/* Assume a default until the user lets us know otherwise */
|
||||
surface->ppm = 3780;
|
||||
surface->ref_count = 1;
|
||||
|
||||
surface->dpy = NULL;
|
||||
surface->image_data = NULL;
|
||||
|
||||
image = IcImageCreateForData ((IcBits *) data, &icformat, width, height, cairo_format_bpp (format), stride);
|
||||
if (image == NULL) {
|
||||
free (surface);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
surface->xc_surface = XcSurfaceCreateForIcImage (image);
|
||||
if (surface->xc_surface == NULL) {
|
||||
IcImageDestroy (image);
|
||||
free (surface);
|
||||
return NULL;
|
||||
}
|
||||
surface->type = CAIRO_SURFACE_TYPE_ICIMAGE;
|
||||
surface->xtransform = CAIRO_XTRANSFORM_IDENTITY;
|
||||
|
||||
/* Assume a default until the user lets us know otherwise */
|
||||
surface->ppm = 3780;
|
||||
surface->gc = 0;
|
||||
surface->drawable = 0;
|
||||
surface->visual = NULL;
|
||||
surface->render_major = -1;
|
||||
surface->render_minor = -1;
|
||||
|
||||
surface->ref_count = 1;
|
||||
surface->picture = 0;
|
||||
|
||||
surface->icimage = image;
|
||||
|
||||
return surface;
|
||||
}
|
||||
|
|
@ -205,8 +254,6 @@ cairo_surface_create_similar_solid (cairo_surface_t *other,
|
|||
cairo_surface_t *surface = NULL;
|
||||
cairo_color_t color;
|
||||
|
||||
/* XXX: create_similar should perhaps move down to Xc, (then we
|
||||
could drop xrsurface->dpy as well) */
|
||||
if (other->dpy) {
|
||||
Display *dpy = other->dpy;
|
||||
int scr = DefaultScreen (dpy);
|
||||
|
|
@ -270,32 +317,130 @@ cairo_surface_destroy (cairo_surface_t *surface)
|
|||
if (surface->ref_count)
|
||||
return;
|
||||
|
||||
surface->dpy = 0;
|
||||
|
||||
XcSurfaceDestroy (surface->xc_surface);
|
||||
surface->xc_surface = NULL;
|
||||
if (surface->picture)
|
||||
XRenderFreePicture (surface->dpy, surface->picture);
|
||||
|
||||
if (surface->icimage)
|
||||
IcImageDestroy (surface->icimage);
|
||||
|
||||
if (surface->image_data)
|
||||
free (surface->image_data);
|
||||
surface->image_data = NULL;
|
||||
|
||||
surface->dpy = 0;
|
||||
|
||||
free (surface);
|
||||
}
|
||||
|
||||
static void
|
||||
_cairo_surface_ensure_gc (cairo_surface_t *surface)
|
||||
{
|
||||
if (surface->gc)
|
||||
return;
|
||||
|
||||
surface->gc = XCreateGC (surface->dpy, surface->drawable, 0, NULL);
|
||||
}
|
||||
|
||||
cairo_status_t
|
||||
cairo_surface_put_image (cairo_surface_t *surface,
|
||||
char *data,
|
||||
int width,
|
||||
int height,
|
||||
int stride)
|
||||
char *data,
|
||||
int width,
|
||||
int height,
|
||||
int stride)
|
||||
{
|
||||
XcSurfacePutImage (surface->xc_surface, data,
|
||||
width, height, stride);
|
||||
if (surface->picture) {
|
||||
XImage *image;
|
||||
unsigned bitmap_pad;
|
||||
|
||||
/* XXX: This is obviously bogus. depth needs to be figured out for real */
|
||||
int depth = 32;
|
||||
|
||||
if (depth > 16)
|
||||
bitmap_pad = 32;
|
||||
else if (depth > 8)
|
||||
bitmap_pad = 16;
|
||||
else
|
||||
bitmap_pad = 8;
|
||||
|
||||
image = XCreateImage(surface->dpy,
|
||||
DefaultVisual(surface->dpy, DefaultScreen(surface->dpy)),
|
||||
depth, ZPixmap, 0,
|
||||
data, width, height,
|
||||
bitmap_pad,
|
||||
stride);
|
||||
if (image == NULL)
|
||||
return CAIRO_STATUS_NO_MEMORY;
|
||||
|
||||
_cairo_surface_ensure_gc (surface);
|
||||
XPutImage(surface->dpy, surface->drawable, surface->gc,
|
||||
image, 0, 0, 0, 0, width, height);
|
||||
|
||||
/* Foolish XDestroyImage thinks it can free my data, but I won't
|
||||
stand for it. */
|
||||
image->data = NULL;
|
||||
XDestroyImage(image);
|
||||
} else {
|
||||
/* XXX: Need to implement the IcImage method of setting a picture. memcpy? */
|
||||
}
|
||||
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
/* XXX: Symmetry demands an cairo_surface_get_image as well */
|
||||
/* XXX: Symmetry demands an cairo_surface_get_image as well. */
|
||||
|
||||
void
|
||||
_cairo_surface_pull_image (cairo_surface_t *surface)
|
||||
{
|
||||
/* XXX: NYI (Also needs support for pictures with external alpha.)
|
||||
if (surface->type == CAIRO_SURFACE_TYPE_ICIMAGE)
|
||||
return;
|
||||
|
||||
if (surface->icimage) {
|
||||
IcImageDestroy (surface->icimage);
|
||||
surface->icimage = NULL;
|
||||
}
|
||||
|
||||
_cairo_surface_ensure_GC (surface);
|
||||
surface->ximage = XGetImage (surface->dpy,
|
||||
surface->drawable,
|
||||
surface->gc,
|
||||
0, 0,
|
||||
width, height,
|
||||
AllPlanes, ZPixmap);
|
||||
|
||||
surface->icimage = IcImageCreateForData (image->data,
|
||||
IcFormat *format,
|
||||
int width, int height,
|
||||
int bpp, int stride);
|
||||
*/
|
||||
}
|
||||
|
||||
void
|
||||
_cairo_surface_push_image (cairo_surface_t *surface)
|
||||
{
|
||||
/* XXX: NYI
|
||||
if (surface->type == CAIRO_SURFACE_TYPE_ICIMAGE)
|
||||
return;
|
||||
|
||||
if (surface->ximage == NULL)
|
||||
return;
|
||||
|
||||
_cairo_surface_ensure_GC (surface);
|
||||
XPutImage (surface->dpy,
|
||||
surface->drawable,
|
||||
surface->gc,
|
||||
surface->ximage,
|
||||
0, 0,
|
||||
0, 0,
|
||||
width, height);
|
||||
|
||||
* Foolish XDestroyImage thinks it can free my data, but I won't
|
||||
stand for it. *
|
||||
surface->ximage->data = NULL;
|
||||
XDestroyImage(surface->ximage);
|
||||
surface->ximage = NULL;
|
||||
*/
|
||||
}
|
||||
|
||||
/* XXX: We may want to move to projective matrices at some point. If
|
||||
nothing else, that would eliminate the two different transform data
|
||||
|
|
@ -303,22 +448,31 @@ cairo_surface_put_image (cairo_surface_t *surface,
|
|||
cairo_status_t
|
||||
cairo_surface_set_matrix (cairo_surface_t *surface, cairo_matrix_t *matrix)
|
||||
{
|
||||
XTransform xtransform;
|
||||
XTransform *xtransform = &surface->xtransform;
|
||||
|
||||
xtransform.matrix[0][0] = XDoubleToFixed (matrix->m[0][0]);
|
||||
xtransform.matrix[0][1] = XDoubleToFixed (matrix->m[1][0]);
|
||||
xtransform.matrix[0][2] = XDoubleToFixed (matrix->m[2][0]);
|
||||
xtransform->matrix[0][0] = XDoubleToFixed (matrix->m[0][0]);
|
||||
xtransform->matrix[0][1] = XDoubleToFixed (matrix->m[1][0]);
|
||||
xtransform->matrix[0][2] = XDoubleToFixed (matrix->m[2][0]);
|
||||
|
||||
xtransform.matrix[1][0] = XDoubleToFixed (matrix->m[0][1]);
|
||||
xtransform.matrix[1][1] = XDoubleToFixed (matrix->m[1][1]);
|
||||
xtransform.matrix[1][2] = XDoubleToFixed (matrix->m[2][1]);
|
||||
xtransform->matrix[1][0] = XDoubleToFixed (matrix->m[0][1]);
|
||||
xtransform->matrix[1][1] = XDoubleToFixed (matrix->m[1][1]);
|
||||
xtransform->matrix[1][2] = XDoubleToFixed (matrix->m[2][1]);
|
||||
|
||||
xtransform.matrix[2][0] = 0;
|
||||
xtransform.matrix[2][1] = 0;
|
||||
xtransform.matrix[2][2] = XDoubleToFixed (1);
|
||||
xtransform->matrix[2][0] = 0;
|
||||
xtransform->matrix[2][1] = 0;
|
||||
xtransform->matrix[2][2] = XDoubleToFixed (1);
|
||||
|
||||
XcSurfaceSetTransform (surface->xc_surface,
|
||||
&xtransform);
|
||||
if (surface->picture) {
|
||||
if (CAIRO_SURFACE_RENDER_HAS_PICTURE_TRANSFORM (surface))
|
||||
XRenderSetPictureTransform (surface->dpy, surface->picture, xtransform);
|
||||
/* XXX: Need support here if using an old RENDER without support
|
||||
for SetPictureTransform */
|
||||
}
|
||||
|
||||
/* XXX: This cast should only occur with a #define hint from libic that it is OK */
|
||||
if (surface->icimage) {
|
||||
IcImageSetTransform (surface->icimage, (IcTransform *) xtransform);
|
||||
}
|
||||
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
}
|
||||
|
|
@ -326,51 +480,134 @@ cairo_surface_set_matrix (cairo_surface_t *surface, cairo_matrix_t *matrix)
|
|||
cairo_status_t
|
||||
cairo_surface_get_matrix (cairo_surface_t *surface, cairo_matrix_t *matrix)
|
||||
{
|
||||
XTransform xtransform;
|
||||
XTransform *xtransform = &surface->xtransform;
|
||||
|
||||
XcSurfaceGetTransform (surface->xc_surface, &xtransform);
|
||||
matrix->m[0][0] = XFixedToDouble (xtransform->matrix[0][0]);
|
||||
matrix->m[1][0] = XFixedToDouble (xtransform->matrix[0][1]);
|
||||
matrix->m[2][0] = XFixedToDouble (xtransform->matrix[0][2]);
|
||||
|
||||
matrix->m[0][0] = XFixedToDouble (xtransform.matrix[0][0]);
|
||||
matrix->m[1][0] = XFixedToDouble (xtransform.matrix[0][1]);
|
||||
matrix->m[2][0] = XFixedToDouble (xtransform.matrix[0][2]);
|
||||
|
||||
matrix->m[0][1] = XFixedToDouble (xtransform.matrix[1][0]);
|
||||
matrix->m[1][1] = XFixedToDouble (xtransform.matrix[1][1]);
|
||||
matrix->m[2][1] = XFixedToDouble (xtransform.matrix[1][2]);
|
||||
matrix->m[0][1] = XFixedToDouble (xtransform->matrix[1][0]);
|
||||
matrix->m[1][1] = XFixedToDouble (xtransform->matrix[1][1]);
|
||||
matrix->m[2][1] = XFixedToDouble (xtransform->matrix[1][2]);
|
||||
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
/* XXX: The Render specification has capitalized versions of these
|
||||
strings. However, the current implementation is case-sensitive and
|
||||
expects lowercase versions. */
|
||||
static char *
|
||||
_render_filter_name (cairo_filter_t filter)
|
||||
{
|
||||
switch (filter) {
|
||||
case CAIRO_FILTER_FAST:
|
||||
return "fast";
|
||||
case CAIRO_FILTER_GOOD:
|
||||
return "good";
|
||||
case CAIRO_FILTER_BEST:
|
||||
return "best";
|
||||
case CAIRO_FILTER_NEAREST:
|
||||
return "nearest";
|
||||
case CAIRO_FILTER_BILINEAR:
|
||||
return "bilinear";
|
||||
default:
|
||||
return "best";
|
||||
}
|
||||
}
|
||||
|
||||
cairo_status_t
|
||||
cairo_surface_set_filter (cairo_surface_t *surface, cairo_filter_t filter)
|
||||
{
|
||||
XcSurfaceSetFilter (surface->xc_surface, filter);
|
||||
if (surface->picture) {
|
||||
XRenderSetPictureFilter (surface->dpy, surface->picture,
|
||||
_render_filter_name (filter), NULL, 0);
|
||||
}
|
||||
|
||||
if (surface->icimage) {
|
||||
IcImageSetFilter (surface->icimage, filter);
|
||||
}
|
||||
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
/* XXX: The Xc version of this function isn't quite working yet
|
||||
/* XXX: NYI
|
||||
cairo_status_t
|
||||
cairo_surface_set_clip_region (cairo_surface_t *surface, Region region)
|
||||
cairo_surface_clip_rectangle (cairo_surface_t *surface,
|
||||
int x, int y,
|
||||
int width, int height)
|
||||
{
|
||||
XcSurfaceSetClipRegion (surface->xc_surface, region);
|
||||
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
}
|
||||
*/
|
||||
|
||||
/* XXX: NYI
|
||||
cairo_status_t
|
||||
cairo_surface_clip_restore (cairo_surface_t *surface);
|
||||
*/
|
||||
|
||||
cairo_status_t
|
||||
cairo_surface_set_repeat (cairo_surface_t *surface, int repeat)
|
||||
{
|
||||
XcSurfaceSetRepeat (surface->xc_surface, repeat);
|
||||
if (surface->picture) {
|
||||
unsigned long mask;
|
||||
XRenderPictureAttributes pa;
|
||||
|
||||
mask = CPRepeat;
|
||||
pa.repeat = repeat;
|
||||
|
||||
XRenderChangePicture (surface->dpy, surface->picture, mask, &pa);
|
||||
}
|
||||
|
||||
if (surface->icimage) {
|
||||
IcImageSetRepeat (surface->icimage, repeat);
|
||||
}
|
||||
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
/* XXX: This function is going away, right? */
|
||||
Picture
|
||||
_cairo_surface_get_picture (cairo_surface_t *surface)
|
||||
void
|
||||
_cairo_surface_composite (cairo_operator_t operator,
|
||||
cairo_surface_t *src,
|
||||
cairo_surface_t *mask,
|
||||
cairo_surface_t *dst,
|
||||
int src_x,
|
||||
int src_y,
|
||||
int mask_x,
|
||||
int mask_y,
|
||||
int dst_x,
|
||||
int dst_y,
|
||||
unsigned int width,
|
||||
unsigned int height)
|
||||
{
|
||||
return XcSurfaceGetPicture (surface->xc_surface);
|
||||
if (dst->type == CAIRO_SURFACE_TYPE_DRAWABLE
|
||||
&& CAIRO_SURFACE_RENDER_HAS_COMPOSITE (dst)
|
||||
&& src->dpy == dst->dpy
|
||||
&& (mask == NULL || mask->dpy == dst->dpy)) {
|
||||
|
||||
XRenderComposite (dst->dpy, operator,
|
||||
src->picture,
|
||||
mask ? mask->picture : 0,
|
||||
dst->picture,
|
||||
src_x, src_y,
|
||||
mask_x, mask_y,
|
||||
dst_x, dst_y,
|
||||
width, height);
|
||||
} else {
|
||||
_cairo_surface_pull_image (src);
|
||||
_cairo_surface_pull_image (mask);
|
||||
_cairo_surface_pull_image (dst);
|
||||
|
||||
IcComposite (operator,
|
||||
src->icimage,
|
||||
mask ? mask->icimage : NULL,
|
||||
dst->icimage,
|
||||
src_x, src_y,
|
||||
mask_x, mask_y,
|
||||
dst_x, dst_y,
|
||||
width, height);
|
||||
|
||||
_cairo_surface_push_image (dst);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
|
|
@ -382,10 +619,80 @@ _cairo_surface_fill_rectangle (cairo_surface_t *surface,
|
|||
int width,
|
||||
int height)
|
||||
{
|
||||
XcFillRectangle (operator,
|
||||
surface->xc_surface,
|
||||
&color->xc_color,
|
||||
x, y,
|
||||
width, height);
|
||||
cairo_rectangle_t rect;
|
||||
|
||||
rect.x = x;
|
||||
rect.y = y;
|
||||
rect.width = width;
|
||||
rect.height = height;
|
||||
|
||||
_cairo_surface_fill_rectangles (surface, operator, color, &rect, 1);
|
||||
}
|
||||
|
||||
void
|
||||
_cairo_surface_fill_rectangles (cairo_surface_t *surface,
|
||||
cairo_operator_t operator,
|
||||
const cairo_color_t *color,
|
||||
cairo_rectangle_t *rects,
|
||||
int num_rects)
|
||||
{
|
||||
if (surface->type == CAIRO_SURFACE_TYPE_DRAWABLE
|
||||
&& CAIRO_SURFACE_RENDER_HAS_FILL_RECTANGLE (surface)) {
|
||||
|
||||
XRenderColor render_color;
|
||||
render_color.red = color->red_short;
|
||||
render_color.green = color->green_short;
|
||||
render_color.blue = color->blue_short;
|
||||
render_color.alpha = color->alpha_short;
|
||||
|
||||
/* XXX: This XRectangle cast is evil... it needs to go away somehow. */
|
||||
XRenderFillRectangles (surface->dpy, operator, surface->picture,
|
||||
&render_color, (XRectangle *) rects, num_rects);
|
||||
|
||||
} else {
|
||||
IcColor ic_color;
|
||||
|
||||
ic_color.red = color->red_short;
|
||||
ic_color.green = color->green_short;
|
||||
ic_color.blue = color->blue_short;
|
||||
ic_color.alpha = color->alpha_short;
|
||||
|
||||
_cairo_surface_pull_image (surface);
|
||||
|
||||
/* XXX: The IcRectangle cast is evil... it needs to go away somehow. */
|
||||
IcFillRectangles (operator, surface->icimage,
|
||||
&ic_color, (IcRectangle *) rects, num_rects);
|
||||
|
||||
_cairo_surface_push_image (surface);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
_cairo_surface_composite_trapezoids (cairo_operator_t operator,
|
||||
cairo_surface_t *src,
|
||||
cairo_surface_t *dst,
|
||||
int xSrc,
|
||||
int ySrc,
|
||||
const cairo_trapezoid_t *traps,
|
||||
int num_traps)
|
||||
{
|
||||
if (dst->type == CAIRO_SURFACE_TYPE_DRAWABLE
|
||||
&& CAIRO_SURFACE_RENDER_HAS_TRAPEZOIDS (dst)
|
||||
&& src->dpy == dst->dpy) {
|
||||
|
||||
/* XXX: The XTrapezoid cast is evil and needs to go away somehow. */
|
||||
XRenderCompositeTrapezoids (dst->dpy, operator, src->picture, dst->picture,
|
||||
XRenderFindStandardFormat (dst->dpy, PictStandardA8),
|
||||
xSrc, ySrc, (XTrapezoid *) traps, num_traps);
|
||||
} else {
|
||||
_cairo_surface_pull_image (src);
|
||||
_cairo_surface_pull_image (dst);
|
||||
|
||||
/* XXX: The IcTrapezoid cast is evil and needs to go away somehow. */
|
||||
IcCompositeTrapezoids (operator, src->icimage, dst->icimage,
|
||||
xSrc, ySrc, (IcTrapezoid *) traps, num_traps);
|
||||
|
||||
_cairo_surface_push_image (dst);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -32,13 +32,13 @@ static cairo_status_t
|
|||
cairo_traps_grow_by (cairo_traps_t *traps, int additional);
|
||||
|
||||
cairo_status_t
|
||||
cairo_traps_add_trap (cairo_traps_t *traps, XFixed top, XFixed bottom,
|
||||
XLineFixed *left, XLineFixed *right);
|
||||
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_status_t
|
||||
cairo_traps_add_trap_from_points (cairo_traps_t *traps, XFixed top, XFixed bottom,
|
||||
XPointFixed left_p1, XPointFixed left_p2,
|
||||
XPointFixed right_p1, XPointFixed right_p2);
|
||||
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);
|
||||
|
||||
static int
|
||||
_compare_point_fixed_by_y (const void *av, const void *bv);
|
||||
|
|
@ -50,72 +50,72 @@ static int
|
|||
_compare_cairo_edge_by_slope (const void *av, const void *bv);
|
||||
|
||||
static cairo_fixed_16_16_t
|
||||
_compute_x (XLineFixed *line, XFixed y);
|
||||
_compute_x (cairo_line_t *line, cairo_fixed_t y);
|
||||
|
||||
static double
|
||||
_compute_inverse_slope (XLineFixed *l);
|
||||
_compute_inverse_slope (cairo_line_t *l);
|
||||
|
||||
static double
|
||||
_compute_x_intercept (XLineFixed *l, double inverse_slope);
|
||||
_compute_x_intercept (cairo_line_t *l, double inverse_slope);
|
||||
|
||||
static XFixed
|
||||
_line_segs_intersect_ceil (XLineFixed *left, XLineFixed *right, XFixed *y_ret);
|
||||
static cairo_fixed_t
|
||||
_line_segs_intersect_ceil (cairo_line_t *left, cairo_line_t *right, cairo_fixed_t *y_ret);
|
||||
|
||||
void
|
||||
cairo_traps_init (cairo_traps_t *traps)
|
||||
{
|
||||
traps->num_xtraps = 0;
|
||||
traps->num_traps = 0;
|
||||
|
||||
traps->xtraps_size = 0;
|
||||
traps->xtraps = NULL;
|
||||
traps->traps_size = 0;
|
||||
traps->traps = NULL;
|
||||
}
|
||||
|
||||
void
|
||||
cairo_traps_fini (cairo_traps_t *traps)
|
||||
{
|
||||
if (traps->xtraps_size) {
|
||||
free (traps->xtraps);
|
||||
traps->xtraps = NULL;
|
||||
traps->xtraps_size = 0;
|
||||
traps->num_xtraps = 0;
|
||||
if (traps->traps_size) {
|
||||
free (traps->traps);
|
||||
traps->traps = NULL;
|
||||
traps->traps_size = 0;
|
||||
traps->num_traps = 0;
|
||||
}
|
||||
}
|
||||
|
||||
cairo_status_t
|
||||
cairo_traps_add_trap (cairo_traps_t *traps, XFixed top, XFixed bottom,
|
||||
XLineFixed *left, XLineFixed *right)
|
||||
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_status_t status;
|
||||
XTrapezoid *trap;
|
||||
cairo_trapezoid_t *trap;
|
||||
|
||||
if (top == bottom) {
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
if (traps->num_xtraps >= traps->xtraps_size) {
|
||||
if (traps->num_traps >= traps->traps_size) {
|
||||
status = cairo_traps_grow_by (traps, CAIRO_TRAPS_GROWTH_INC);
|
||||
if (status)
|
||||
return status;
|
||||
}
|
||||
|
||||
trap = &traps->xtraps[traps->num_xtraps];
|
||||
trap = &traps->traps[traps->num_traps];
|
||||
trap->top = top;
|
||||
trap->bottom = bottom;
|
||||
trap->left = *left;
|
||||
trap->right = *right;
|
||||
|
||||
traps->num_xtraps++;
|
||||
traps->num_traps++;
|
||||
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
cairo_status_t
|
||||
cairo_traps_add_trap_from_points (cairo_traps_t *traps, XFixed top, XFixed bottom,
|
||||
XPointFixed left_p1, XPointFixed left_p2,
|
||||
XPointFixed right_p1, XPointFixed right_p2)
|
||||
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)
|
||||
{
|
||||
XLineFixed left;
|
||||
XLineFixed right;
|
||||
cairo_line_t left;
|
||||
cairo_line_t right;
|
||||
|
||||
left.p1 = left_p1;
|
||||
left.p2 = left_p2;
|
||||
|
|
@ -129,23 +129,23 @@ cairo_traps_add_trap_from_points (cairo_traps_t *traps, XFixed top, XFixed botto
|
|||
static cairo_status_t
|
||||
cairo_traps_grow_by (cairo_traps_t *traps, int additional)
|
||||
{
|
||||
XTrapezoid *new_xtraps;
|
||||
int old_size = traps->xtraps_size;
|
||||
int new_size = traps->num_xtraps + additional;
|
||||
cairo_trapezoid_t *new_traps;
|
||||
int old_size = traps->traps_size;
|
||||
int new_size = traps->num_traps + additional;
|
||||
|
||||
if (new_size <= traps->xtraps_size) {
|
||||
if (new_size <= traps->traps_size) {
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
traps->xtraps_size = new_size;
|
||||
new_xtraps = realloc (traps->xtraps, traps->xtraps_size * sizeof (XTrapezoid));
|
||||
traps->traps_size = new_size;
|
||||
new_traps = realloc (traps->traps, traps->traps_size * sizeof (cairo_trapezoid_t));
|
||||
|
||||
if (new_xtraps == NULL) {
|
||||
traps->xtraps_size = old_size;
|
||||
if (new_traps == NULL) {
|
||||
traps->traps_size = old_size;
|
||||
return CAIRO_STATUS_NO_MEMORY;
|
||||
}
|
||||
|
||||
traps->xtraps = new_xtraps;
|
||||
traps->traps = new_traps;
|
||||
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
}
|
||||
|
|
@ -153,7 +153,7 @@ cairo_traps_grow_by (cairo_traps_t *traps, int additional)
|
|||
static int
|
||||
_compare_point_fixed_by_y (const void *av, const void *bv)
|
||||
{
|
||||
const XPointFixed *a = av, *b = bv;
|
||||
const cairo_point_t *a = av, *b = bv;
|
||||
|
||||
int ret = a->y - b->y;
|
||||
if (ret == 0) {
|
||||
|
|
@ -163,15 +163,15 @@ _compare_point_fixed_by_y (const void *av, const void *bv)
|
|||
}
|
||||
|
||||
cairo_status_t
|
||||
cairo_traps_tessellate_triangle (cairo_traps_t *traps, XPointFixed t[3])
|
||||
cairo_traps_tessellate_triangle (cairo_traps_t *traps, cairo_point_t t[3])
|
||||
{
|
||||
cairo_status_t status;
|
||||
XLineFixed line;
|
||||
cairo_line_t line;
|
||||
cairo_fixed_16_16_t intersect;
|
||||
XPointFixed tsort[3];
|
||||
cairo_point_t tsort[3];
|
||||
|
||||
memcpy (tsort, t, 3 * sizeof (XPointFixed));
|
||||
qsort (tsort, 3, sizeof (XPointFixed), _compare_point_fixed_by_y);
|
||||
memcpy (tsort, t, 3 * sizeof (cairo_point_t));
|
||||
qsort (tsort, 3, sizeof (cairo_point_t), _compare_point_fixed_by_y);
|
||||
|
||||
/* horizontal top edge requires special handling */
|
||||
if (tsort[0].y == tsort[1].y) {
|
||||
|
|
@ -226,11 +226,11 @@ cairo_traps_tessellate_triangle (cairo_traps_t *traps, XPointFixed t[3])
|
|||
|
||||
/* Warning: This function reorders the elements of the array provided. */
|
||||
cairo_status_t
|
||||
cairo_traps_tessellate_rectangle (cairo_traps_t *traps, XPointFixed q[4])
|
||||
cairo_traps_tessellate_rectangle (cairo_traps_t *traps, cairo_point_t q[4])
|
||||
{
|
||||
cairo_status_t status;
|
||||
|
||||
qsort (q, 4, sizeof (XPointFixed), _compare_point_fixed_by_y);
|
||||
qsort (q, 4, sizeof (cairo_point_t), _compare_point_fixed_by_y);
|
||||
|
||||
if (q[1].x > q[2].x) {
|
||||
status = cairo_traps_add_trap_from_points (traps,
|
||||
|
|
@ -335,7 +335,7 @@ _det (double a, double b, double c, double d)
|
|||
}
|
||||
|
||||
static int
|
||||
_lines_intersect (XLineFixed *l1, XLineFixed *l2, XFixed *y_intersection)
|
||||
_lines_intersect (cairo_line_t *l1, cairo_line_t *l2, cairo_fixed_t *y_intersection)
|
||||
{
|
||||
double dx1 = XFixedToDouble (l1->p1.x - l1->p2.x);
|
||||
double dy1 = XFixedToDouble (l1->p1.y - l1->p2.y);
|
||||
|
|
@ -362,7 +362,7 @@ _lines_intersect (XLineFixed *l1, XLineFixed *l2, XFixed *y_intersection)
|
|||
}
|
||||
*/
|
||||
static cairo_fixed_16_16_t
|
||||
_compute_x (XLineFixed *line, XFixed y)
|
||||
_compute_x (cairo_line_t *line, cairo_fixed_t y)
|
||||
{
|
||||
cairo_fixed_16_16_t dx = line->p2.x - line->p1.x;
|
||||
cairo_fixed_32_32_t ex = (cairo_fixed_48_16_t) (y - line->p1.y) * (cairo_fixed_48_16_t) dx;
|
||||
|
|
@ -372,20 +372,20 @@ _compute_x (XLineFixed *line, XFixed y)
|
|||
}
|
||||
|
||||
static double
|
||||
_compute_inverse_slope (XLineFixed *l)
|
||||
_compute_inverse_slope (cairo_line_t *l)
|
||||
{
|
||||
return (XFixedToDouble (l->p2.x - l->p1.x) /
|
||||
XFixedToDouble (l->p2.y - l->p1.y));
|
||||
}
|
||||
|
||||
static double
|
||||
_compute_x_intercept (XLineFixed *l, double inverse_slope)
|
||||
_compute_x_intercept (cairo_line_t *l, double inverse_slope)
|
||||
{
|
||||
return XFixedToDouble (l->p1.x) - inverse_slope * XFixedToDouble (l->p1.y);
|
||||
}
|
||||
|
||||
static int
|
||||
_line_segs_intersect_ceil (XLineFixed *l1, XLineFixed *l2, XFixed *y_ret)
|
||||
_line_segs_intersect_ceil (cairo_line_t *l1, cairo_line_t *l2, cairo_fixed_t *y_ret)
|
||||
{
|
||||
/*
|
||||
* x = m1y + b1
|
||||
|
|
@ -406,7 +406,7 @@ _line_segs_intersect_ceil (XLineFixed *l1, XLineFixed *l2, XFixed *y_ret)
|
|||
y_intersect = XDoubleToFixed ((b2 - b1) / (m1 - m2));
|
||||
|
||||
if (m1 < m2) {
|
||||
XLineFixed *t;
|
||||
cairo_line_t *t;
|
||||
t = l1;
|
||||
l1 = l2;
|
||||
l2 = t;
|
||||
|
|
@ -418,6 +418,22 @@ _line_segs_intersect_ceil (XLineFixed *l1, XLineFixed *l2, XFixed *y_ret)
|
|||
most, we must increment once. */
|
||||
if (_compute_x (l2, y_intersect) > _compute_x (l1, y_intersect))
|
||||
y_intersect++;
|
||||
/* XXX: Hmm... Keith's error calculations said we'd at most be off
|
||||
by one sub-pixel. But, I found that the paint-fill-BE-01.svg
|
||||
test from the W3C SVG conformance suite definitely requires two
|
||||
increments.
|
||||
|
||||
It could be that we need one to overcome the error, and another
|
||||
to round up.
|
||||
|
||||
It would be nice to be sure this code is correct, (but we can't
|
||||
do the while loop as it will work for way to long on
|
||||
exceedingly distant intersections with large errors that we
|
||||
really don't care about anyway as they will be ignored by the
|
||||
calling function.
|
||||
*/
|
||||
if (_compute_x (l2, y_intersect) > _compute_x (l1, y_intersect))
|
||||
y_intersect++;
|
||||
|
||||
*y_ret = y_intersect;
|
||||
|
||||
|
|
@ -458,7 +474,7 @@ cairo_traps_tessellate_polygon (cairo_traps_t *traps,
|
|||
{
|
||||
cairo_status_t status;
|
||||
int i, active, inactive;
|
||||
XFixed y, y_next, intersect;
|
||||
cairo_fixed_t y, y_next, intersect;
|
||||
int in_out, num_edges = poly->num_edges;
|
||||
cairo_edge_t *edges = poly->edges;
|
||||
|
||||
|
|
|
|||
170
src/cairo.c
170
src/cairo.c
|
|
@ -160,12 +160,6 @@ cairo_set_target_surface (cairo_t *cr, cairo_surface_t *surface)
|
|||
cr->status = _cairo_gstate_set_target_surface (cr->gstate, surface);
|
||||
}
|
||||
|
||||
cairo_surface_t *
|
||||
cairo_get_target_surface (cairo_t *cr)
|
||||
{
|
||||
return _cairo_gstate_get_target_surface (cr->gstate);
|
||||
}
|
||||
|
||||
void
|
||||
cairo_set_target_drawable (cairo_t *cr,
|
||||
Display *dpy,
|
||||
|
|
@ -225,12 +219,6 @@ cairo_set_operator (cairo_t *cr, cairo_operator_t op)
|
|||
cr->status = _cairo_gstate_set_operator (cr->gstate, op);
|
||||
}
|
||||
|
||||
cairo_operator_t
|
||||
cairo_get_operator (cairo_t *cr)
|
||||
{
|
||||
return _cairo_gstate_get_operator (cr->gstate);
|
||||
}
|
||||
|
||||
void
|
||||
cairo_set_rgb_color (cairo_t *cr, double red, double green, double blue)
|
||||
{
|
||||
|
|
@ -244,16 +232,6 @@ cairo_set_rgb_color (cairo_t *cr, double red, double green, double blue)
|
|||
cr->status = _cairo_gstate_set_rgb_color (cr->gstate, red, green, blue);
|
||||
}
|
||||
|
||||
void
|
||||
cairo_get_rgb_color (cairo_t *cr, double *red, double *green, double *blue)
|
||||
{
|
||||
/* XXX: Should we do anything with the return values in the error case? */
|
||||
if (cr->status)
|
||||
return;
|
||||
|
||||
cr->status = _cairo_gstate_get_rgb_color (cr->gstate, red, green, blue);
|
||||
}
|
||||
|
||||
void
|
||||
cairo_set_pattern (cairo_t *cr, cairo_surface_t *pattern)
|
||||
{
|
||||
|
|
@ -274,12 +252,6 @@ cairo_set_tolerance (cairo_t *cr, double tolerance)
|
|||
cr->status = _cairo_gstate_set_tolerance (cr->gstate, tolerance);
|
||||
}
|
||||
|
||||
double
|
||||
cairo_get_tolerance (cairo_t *cr)
|
||||
{
|
||||
return _cairo_gstate_get_tolerance (cr->gstate);
|
||||
}
|
||||
|
||||
void
|
||||
cairo_set_alpha (cairo_t *cr, double alpha)
|
||||
{
|
||||
|
|
@ -291,12 +263,6 @@ cairo_set_alpha (cairo_t *cr, double alpha)
|
|||
cr->status = _cairo_gstate_set_alpha (cr->gstate, alpha);
|
||||
}
|
||||
|
||||
double
|
||||
cairo_get_alpha (cairo_t *cr)
|
||||
{
|
||||
return _cairo_gstate_get_alpha (cr->gstate);
|
||||
}
|
||||
|
||||
void
|
||||
cairo_set_fill_rule (cairo_t *cr, cairo_fill_rule_t fill_rule)
|
||||
{
|
||||
|
|
@ -315,12 +281,6 @@ cairo_set_line_width (cairo_t *cr, double width)
|
|||
cr->status = _cairo_gstate_set_line_width (cr->gstate, width);
|
||||
}
|
||||
|
||||
double
|
||||
cairo_get_line_width (cairo_t *cr)
|
||||
{
|
||||
return _cairo_gstate_get_line_width (cr->gstate);
|
||||
}
|
||||
|
||||
void
|
||||
cairo_set_line_cap (cairo_t *cr, cairo_line_cap_t line_cap)
|
||||
{
|
||||
|
|
@ -330,12 +290,6 @@ cairo_set_line_cap (cairo_t *cr, cairo_line_cap_t line_cap)
|
|||
cr->status = _cairo_gstate_set_line_cap (cr->gstate, line_cap);
|
||||
}
|
||||
|
||||
cairo_line_cap_t
|
||||
cairo_get_line_cap (cairo_t *cr)
|
||||
{
|
||||
return _cairo_gstate_get_line_cap (cr->gstate);
|
||||
}
|
||||
|
||||
void
|
||||
cairo_set_line_join (cairo_t *cr, cairo_line_join_t line_join)
|
||||
{
|
||||
|
|
@ -345,12 +299,6 @@ cairo_set_line_join (cairo_t *cr, cairo_line_join_t line_join)
|
|||
cr->status = _cairo_gstate_set_line_join (cr->gstate, line_join);
|
||||
}
|
||||
|
||||
cairo_line_join_t
|
||||
cairo_get_line_join (cairo_t *cr)
|
||||
{
|
||||
return _cairo_gstate_get_line_join (cr->gstate);
|
||||
}
|
||||
|
||||
void
|
||||
cairo_set_dash (cairo_t *cr, double *dashes, int ndash, double offset)
|
||||
{
|
||||
|
|
@ -369,12 +317,6 @@ cairo_set_miter_limit (cairo_t *cr, double limit)
|
|||
cr->status = _cairo_gstate_set_miter_limit (cr->gstate, limit);
|
||||
}
|
||||
|
||||
double
|
||||
cairo_get_miter_limit (cairo_t *cr)
|
||||
{
|
||||
return _cairo_gstate_get_miter_limit (cr->gstate);
|
||||
}
|
||||
|
||||
void
|
||||
cairo_translate (cairo_t *cr, double tx, double ty)
|
||||
{
|
||||
|
|
@ -446,7 +388,7 @@ cairo_transform_point (cairo_t *cr, double *x, double *y)
|
|||
if (cr->status)
|
||||
return;
|
||||
|
||||
cr->status = cairo_gstateransform_point (cr->gstate, x, y);
|
||||
cr->status = cairo_gstate_transform_point (cr->gstate, x, y);
|
||||
}
|
||||
|
||||
void
|
||||
|
|
@ -455,7 +397,7 @@ cairo_transform_distance (cairo_t *cr, double *dx, double *dy)
|
|||
if (cr->status)
|
||||
return;
|
||||
|
||||
cr->status = cairo_gstateransform_distance (cr->gstate, dx, dy);
|
||||
cr->status = cairo_gstate_transform_distance (cr->gstate, dx, dy);
|
||||
}
|
||||
|
||||
void
|
||||
|
|
@ -513,9 +455,9 @@ cairo_curve_to (cairo_t *cr,
|
|||
return;
|
||||
|
||||
cr->status = _cairo_gstate_curve_to (cr->gstate,
|
||||
x1, y1,
|
||||
x2, y2,
|
||||
x3, y3);
|
||||
x1, y1,
|
||||
x2, y2,
|
||||
x3, y3);
|
||||
}
|
||||
|
||||
void
|
||||
|
|
@ -546,9 +488,9 @@ cairo_rel_curve_to (cairo_t *cr,
|
|||
return;
|
||||
|
||||
cr->status = _cairo_gstate_rel_curve_to (cr->gstate,
|
||||
dx1, dy1,
|
||||
dx2, dy2,
|
||||
dx3, dy3);
|
||||
dx1, dy1,
|
||||
dx2, dy2,
|
||||
dx3, dy3);
|
||||
}
|
||||
|
||||
void
|
||||
|
|
@ -566,6 +508,17 @@ cairo_rectangle (cairo_t *cr,
|
|||
cairo_close_path (cr);
|
||||
}
|
||||
|
||||
/* XXX: NYI
|
||||
void
|
||||
cairo_stroke_path (cairo_t *cr)
|
||||
{
|
||||
if (cr->status)
|
||||
return;
|
||||
|
||||
cr->status = _cairo_gstate_stroke_path (cr->gstate);
|
||||
}
|
||||
*/
|
||||
|
||||
void
|
||||
cairo_close_path (cairo_t *cr)
|
||||
{
|
||||
|
|
@ -575,16 +528,6 @@ cairo_close_path (cairo_t *cr)
|
|||
cr->status = _cairo_gstate_close_path (cr->gstate);
|
||||
}
|
||||
|
||||
void
|
||||
cairo_get_current_point (cairo_t *cr, double *x, double *y)
|
||||
{
|
||||
/* XXX: Should we do anything with the return values in the error case? */
|
||||
if (cr->status)
|
||||
return;
|
||||
|
||||
cr->status = _cairo_gstate_get_current_point (cr->gstate, x, y);
|
||||
}
|
||||
|
||||
void
|
||||
cairo_stroke (cairo_t *cr)
|
||||
{
|
||||
|
|
@ -638,8 +581,8 @@ cairo_transform_font (cairo_t *cr,
|
|||
if (cr->status)
|
||||
return;
|
||||
|
||||
cr->status = cairo_gstateransform_font (cr->gstate,
|
||||
a, b, c, d);
|
||||
cr->status = cairo_gstate_transform_font (cr->gstate,
|
||||
a, b, c, d);
|
||||
}
|
||||
|
||||
void
|
||||
|
|
@ -652,8 +595,8 @@ cairo_text_extents (cairo_t *cr,
|
|||
if (cr->status)
|
||||
return;
|
||||
|
||||
cr->status = cairo_gstateext_extents (cr->gstate, utf8,
|
||||
x, y, width, height, dx, dy);
|
||||
cr->status = cairo_gstate_text_extents (cr->gstate, utf8,
|
||||
x, y, width, height, dx, dy);
|
||||
}
|
||||
|
||||
void
|
||||
|
|
@ -678,6 +621,73 @@ cairo_show_surface (cairo_t *cr,
|
|||
surface, width, height);
|
||||
}
|
||||
|
||||
cairo_operator_t
|
||||
cairo_get_operator (cairo_t *cr)
|
||||
{
|
||||
return _cairo_gstate_get_operator (cr->gstate);
|
||||
}
|
||||
|
||||
void
|
||||
cairo_get_rgb_color (cairo_t *cr, double *red, double *green, double *blue)
|
||||
{
|
||||
_cairo_gstate_get_rgb_color (cr->gstate, red, green, blue);
|
||||
}
|
||||
|
||||
double
|
||||
cairo_get_alpha (cairo_t *cr)
|
||||
{
|
||||
return _cairo_gstate_get_alpha (cr->gstate);
|
||||
}
|
||||
|
||||
|
||||
double
|
||||
cairo_get_tolerance (cairo_t *cr)
|
||||
{
|
||||
return _cairo_gstate_get_tolerance (cr->gstate);
|
||||
}
|
||||
|
||||
void
|
||||
cairo_get_current_point (cairo_t *cr, double *x, double *y)
|
||||
{
|
||||
_cairo_gstate_get_current_point (cr->gstate, x, y);
|
||||
}
|
||||
|
||||
cairo_fill_rule_t
|
||||
cairo_get_fill_rule (cairo_t *cr)
|
||||
{
|
||||
return _cairo_gstate_get_fill_rule (cr->gstate);
|
||||
}
|
||||
|
||||
double
|
||||
cairo_get_line_width (cairo_t *cr)
|
||||
{
|
||||
return _cairo_gstate_get_line_width (cr->gstate);
|
||||
}
|
||||
|
||||
cairo_line_cap_t
|
||||
cairo_get_line_cap (cairo_t *cr)
|
||||
{
|
||||
return _cairo_gstate_get_line_cap (cr->gstate);
|
||||
}
|
||||
|
||||
cairo_line_join_t
|
||||
cairo_get_line_join (cairo_t *cr)
|
||||
{
|
||||
return _cairo_gstate_get_line_join (cr->gstate);
|
||||
}
|
||||
|
||||
double
|
||||
cairo_get_miter_limit (cairo_t *cr)
|
||||
{
|
||||
return _cairo_gstate_get_miter_limit (cr->gstate);
|
||||
}
|
||||
|
||||
cairo_surface_t *
|
||||
cairo_get_target_surface (cairo_t *cr)
|
||||
{
|
||||
return _cairo_gstate_get_target_surface (cr->gstate);
|
||||
}
|
||||
|
||||
cairo_status_t
|
||||
cairo_get_status (cairo_t *cr)
|
||||
{
|
||||
|
|
|
|||
116
src/cairo.h
116
src/cairo.h
|
|
@ -28,7 +28,9 @@
|
|||
#ifndef _CAIRO_H_
|
||||
#define _CAIRO_H_
|
||||
|
||||
#include <Xc.h>
|
||||
#include <X11/extensions/Xrender.h>
|
||||
#include <fontconfig/fontconfig.h>
|
||||
#include <ic.h>
|
||||
|
||||
typedef struct cairo cairo_t;
|
||||
typedef struct cairo_surface cairo_surface_t;
|
||||
|
|
@ -131,18 +133,33 @@ cairo_set_operator (cairo_t *cr, cairo_operator_t op);
|
|||
|
||||
/* XXX: Probably want to bite the bullet and expose a cairo_color_t object */
|
||||
|
||||
/* XXX: I've been trying to come up with a sane way to specify:
|
||||
|
||||
cairo_set_color (cairo_t *cr, cairo_color_t *color);
|
||||
|
||||
Keith wants to be able to support super-luminescent colors,
|
||||
(premultiplied colors with R/G/B greater than alpha). The current
|
||||
API does not allow that. Adding a premulitplied RGBA cairo_color_t
|
||||
would do the trick.
|
||||
|
||||
One problem though is that alpha is currently orthogonal to
|
||||
color. For example, show_surface uses gstate->alpha but ignores the
|
||||
color. So, it doesn't seem be right to have cairo_set_color modify
|
||||
the behavior of cairo_show_surface.
|
||||
*/
|
||||
|
||||
void
|
||||
cairo_set_rgb_color (cairo_t *cr, double red, double green, double blue);
|
||||
|
||||
void
|
||||
cairo_set_alpha (cairo_t *cr, double alpha);
|
||||
|
||||
void
|
||||
cairo_set_pattern (cairo_t *cr, cairo_surface_t *pattern);
|
||||
|
||||
void
|
||||
cairo_set_tolerance (cairo_t *cr, double tolerance);
|
||||
|
||||
void
|
||||
cairo_set_alpha (cairo_t *cr, double alpha);
|
||||
|
||||
typedef enum cairo_fill_rule {
|
||||
CAIRO_FILL_RULE_WINDING,
|
||||
CAIRO_FILL_RULE_EVEN_ODD
|
||||
|
|
@ -239,14 +256,26 @@ cairo_rel_line_to (cairo_t *cr, double dx, double dy);
|
|||
|
||||
void
|
||||
cairo_rel_curve_to (cairo_t *cr,
|
||||
double dx1, double dy1,
|
||||
double dx2, double dy2,
|
||||
double dx3, double dy3);
|
||||
double dx1, double dy1,
|
||||
double dx2, double dy2,
|
||||
double dx3, double dy3);
|
||||
|
||||
void
|
||||
cairo_rectangle (cairo_t *cr,
|
||||
double x, double y,
|
||||
double width, double height);
|
||||
double x, double y,
|
||||
double width, double height);
|
||||
|
||||
/* XXX: This is the same name that PostScript uses, but to me the name
|
||||
suggests an actual drawing operation ala cairo_stroke --- especially
|
||||
since I want to add a cairo_path_t and with that it would be
|
||||
natural to have "cairo_stroke_path (cairo_t *, cairo_path_t *)"
|
||||
|
||||
Maybe we could use something like "cairo_outline_path (cairo_t *)"?
|
||||
*/
|
||||
/* XXX: NYI
|
||||
void
|
||||
cairo_stroke_path (cairo_t *cr);
|
||||
*/
|
||||
|
||||
void
|
||||
cairo_close_path (cairo_t *cr);
|
||||
|
|
@ -306,14 +335,14 @@ cairo_get_operator (cairo_t *cr);
|
|||
void
|
||||
cairo_get_rgb_color (cairo_t *cr, double *red, double *green, double *blue);
|
||||
|
||||
double
|
||||
cairo_get_alpha (cairo_t *cr);
|
||||
|
||||
/* XXX: Do we want cairo_get_pattern as well? */
|
||||
|
||||
double
|
||||
cairo_get_tolerance (cairo_t *cr);
|
||||
|
||||
double
|
||||
cairo_get_alpha (cairo_t *cr);
|
||||
|
||||
void
|
||||
cairo_get_current_point (cairo_t *cr, double *x, double *y);
|
||||
|
||||
|
|
@ -369,23 +398,23 @@ cairo_get_status_string (cairo_t *cr);
|
|||
*/
|
||||
cairo_surface_t *
|
||||
cairo_surface_create_for_drawable (Display *dpy,
|
||||
Drawable drawable,
|
||||
Visual *visual,
|
||||
cairo_format_t format,
|
||||
Colormap colormap);
|
||||
Drawable drawable,
|
||||
Visual *visual,
|
||||
cairo_format_t format,
|
||||
Colormap colormap);
|
||||
|
||||
cairo_surface_t *
|
||||
cairo_surface_create_for_image (char *data,
|
||||
cairo_format_t format,
|
||||
int width,
|
||||
int height,
|
||||
int stride);
|
||||
cairo_format_t format,
|
||||
int width,
|
||||
int height,
|
||||
int stride);
|
||||
|
||||
cairo_surface_t *
|
||||
cairo_surface_create_similar (cairo_surface_t *other,
|
||||
cairo_format_t format,
|
||||
int width,
|
||||
int height);
|
||||
cairo_format_t format,
|
||||
int width,
|
||||
int height);
|
||||
|
||||
/* XXX: One problem with having RGB and A here in one function is that
|
||||
it introduces the question of pre-multiplied vs. non-pre-multiplied
|
||||
|
|
@ -393,28 +422,31 @@ cairo_surface_create_similar (cairo_surface_t *other,
|
|||
other public functions need it. */
|
||||
cairo_surface_t *
|
||||
cairo_surface_create_similar_solid (cairo_surface_t *other,
|
||||
cairo_format_t format,
|
||||
int width,
|
||||
int height,
|
||||
double red,
|
||||
double green,
|
||||
double blue,
|
||||
double alpha);
|
||||
cairo_format_t format,
|
||||
int width,
|
||||
int height,
|
||||
double red,
|
||||
double green,
|
||||
double blue,
|
||||
double alpha);
|
||||
|
||||
void
|
||||
cairo_surface_destroy (cairo_surface_t *surface);
|
||||
|
||||
/* XXX: Should this take an X/Y offset as well? (Probably) */
|
||||
cairo_status_t
|
||||
cairo_surface_put_image (cairo_surface_t *surface,
|
||||
char *data,
|
||||
int width,
|
||||
int height,
|
||||
int stride);
|
||||
char *data,
|
||||
int width,
|
||||
int height,
|
||||
int stride);
|
||||
|
||||
/* XXX: The Xc version of this function isn't quite working yet
|
||||
/* XXX: NYI
|
||||
cairo_status_t
|
||||
cairo_surface_set_clip_region (cairo_surface_t *surface, Region region);
|
||||
cairo_surface_clip_restore (cairo_surface_t *surface);
|
||||
cairo_status_t
|
||||
cairo_surface_clip_rectangle (cairo_surface_t *surface,
|
||||
int x, int y,
|
||||
int width, int height);
|
||||
*/
|
||||
|
||||
/* XXX: Note: The current Render/Ic implementations don't do the right
|
||||
|
|
@ -429,11 +461,11 @@ cairo_status_t
|
|||
cairo_surface_get_matrix (cairo_surface_t *surface, cairo_matrix_t *matrix);
|
||||
|
||||
typedef enum cairo_filter {
|
||||
CAIRO_FILTER_FAST = XcFilterFast,
|
||||
CAIRO_FILTER_GOOD = XcFilterGood,
|
||||
CAIRO_FILTER_BEST = XcFilterBest,
|
||||
CAIRO_FILTER_NEAREST = XcFilterNearest,
|
||||
CAIRO_FILTER_BILINEAR = XcFilterBilinear
|
||||
CAIRO_FILTER_FAST = IcFilterFast,
|
||||
CAIRO_FILTER_GOOD = IcFilterGood,
|
||||
CAIRO_FILTER_BEST = IcFilterBest,
|
||||
CAIRO_FILTER_NEAREST = IcFilterNearest,
|
||||
CAIRO_FILTER_BILINEAR = IcFilterBilinear
|
||||
} cairo_filter_t;
|
||||
|
||||
cairo_status_t
|
||||
|
|
|
|||
|
|
@ -27,10 +27,13 @@
|
|||
|
||||
#include "cairoint.h"
|
||||
|
||||
static cairo_color_t CAIRO_COLOR_DEFAULT = { 1.0, 1.0, 1.0, 1.0, {0xffff, 0xffff, 0xffff, 0xffff}};
|
||||
static cairo_color_t CAIRO_COLOR_DEFAULT = {
|
||||
1.0, 1.0, 1.0, 1.0,
|
||||
0xffff, 0xffff, 0xffff, 0xffff
|
||||
};
|
||||
|
||||
static void
|
||||
_cairo_color_compute_xc_color (cairo_color_t *color);
|
||||
_cairo_color_compute_shorts (cairo_color_t *color);
|
||||
|
||||
void
|
||||
_cairo_color_init (cairo_color_t *color)
|
||||
|
|
@ -44,31 +47,22 @@ _cairo_color_fini (cairo_color_t *color)
|
|||
/* Nothing to do here */
|
||||
}
|
||||
|
||||
static void
|
||||
_cairo_color_compute_xc_color (cairo_color_t *color)
|
||||
{
|
||||
color->xc_color.red = color->red * color->alpha * 0xffff;
|
||||
color->xc_color.green = color->green * color->alpha * 0xffff;
|
||||
color->xc_color.blue = color->blue * color->alpha * 0xffff;
|
||||
color->xc_color.alpha = color->alpha * 0xffff;
|
||||
}
|
||||
|
||||
void
|
||||
_cairo_color_set_rgb (cairo_color_t *color, double red, double green, double blue)
|
||||
{
|
||||
color->red = red;
|
||||
color->red = red;
|
||||
color->green = green;
|
||||
color->blue = blue;
|
||||
color->blue = blue;
|
||||
|
||||
_cairo_color_compute_xc_color (color);
|
||||
_cairo_color_compute_shorts (color);
|
||||
}
|
||||
|
||||
void
|
||||
_cairo_color_get_rgb (cairo_color_t *color, double *red, double *green, double *blue)
|
||||
{
|
||||
*red = color->red;
|
||||
*red = color->red;
|
||||
*green = color->green;
|
||||
*blue = color->blue;
|
||||
*blue = color->blue;
|
||||
}
|
||||
|
||||
void
|
||||
|
|
@ -76,5 +70,15 @@ _cairo_color_set_alpha (cairo_color_t *color, double alpha)
|
|||
{
|
||||
color->alpha = alpha;
|
||||
|
||||
_cairo_color_compute_xc_color (color);
|
||||
_cairo_color_compute_shorts (color);
|
||||
}
|
||||
|
||||
static void
|
||||
_cairo_color_compute_shorts (cairo_color_t *color)
|
||||
{
|
||||
color->red_short = (color->red * color->alpha) * 0xffff;
|
||||
color->green_short = (color->green * color->alpha) * 0xffff;
|
||||
color->blue_short = (color->blue * color->alpha) * 0xffff;
|
||||
color->alpha_short = color->alpha * 0xffff;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -154,7 +154,7 @@ _cairo_font_resolve_xft_font (cairo_font_t *font, cairo_gstate_t *gstate, XftFon
|
|||
|
||||
FcPatternAddMatrix (pattern, "matrix", &fc_matrix);
|
||||
|
||||
/* XXX: Need to abandon Xft and use Xc instead */
|
||||
/* XXX: Need to make a generic (non-Xft) backend for text. */
|
||||
/* When I do that I can throw away these Display pointers */
|
||||
font->dpy = gstate->surface->dpy;
|
||||
match = XftFontMatch (font->dpy, DefaultScreen (font->dpy), pattern, &result);
|
||||
|
|
|
|||
|
|
@ -227,12 +227,12 @@ _cairo_gstate_begin_group (cairo_gstate_t *gstate)
|
|||
_cairo_color_init (&clear);
|
||||
_cairo_color_set_alpha (&clear, 0);
|
||||
|
||||
XcFillRectangle (CAIRO_OPERATOR_SRC,
|
||||
_cairo_surface_get_xc_surface (gstate->surface),
|
||||
&clear.xc_color,
|
||||
0, 0,
|
||||
_cairo_surface_get_width (gstate->surface),
|
||||
_cairo_surface_get_height (gstate->surface));
|
||||
_cairo_surface_fill_rectangle (gstate->surface,
|
||||
CAIRO_OPERATOR_SRC,
|
||||
&clear,
|
||||
0, 0,
|
||||
_cairo_surface_get_width (gstate->surface),
|
||||
_cairo_surface_get_height (gstate->surface));
|
||||
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
}
|
||||
|
|
@ -259,15 +259,15 @@ _cairo_gstate_end_group (cairo_gstate_t *gstate)
|
|||
* XXX: This could be made much more efficient by using
|
||||
_cairo_surface_get_damaged_width/Height if cairo_surface_t actually kept
|
||||
track of such informaton. *
|
||||
XcComposite (gstate->operator,
|
||||
_cairo_surface_get_xc_surface (gstate->surface),
|
||||
_cairo_surface_get_xc_surface (&mask),
|
||||
_cairo_surface_get_xc_surface (gstate->parent_surface),
|
||||
0, 0,
|
||||
0, 0,
|
||||
0, 0,
|
||||
_cairo_surface_get_width (gstate->surface),
|
||||
_cairo_surface_get_height (gstate->surface));
|
||||
_cairo_surface_composite (gstate->operator,
|
||||
gstate->surface,
|
||||
mask,
|
||||
gstate->parent_surface,
|
||||
0, 0,
|
||||
0, 0,
|
||||
0, 0,
|
||||
_cairo_surface_get_width (gstate->surface),
|
||||
_cairo_surface_get_height (gstate->surface));
|
||||
|
||||
_cairo_surface_fini (&mask);
|
||||
|
||||
|
|
@ -415,6 +415,12 @@ _cairo_gstate_set_fill_rule (cairo_gstate_t *gstate, cairo_fill_rule_t fill_rule
|
|||
return CAIRO_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
cairo_status_t
|
||||
_cairo_gstate_get_fill_rule (cairo_gstate_t *gstate)
|
||||
{
|
||||
return gstate->fill_rule;
|
||||
}
|
||||
|
||||
cairo_status_t
|
||||
_cairo_gstate_set_line_width (cairo_gstate_t *gstate, double width)
|
||||
{
|
||||
|
|
@ -495,7 +501,7 @@ _cairo_gstate_get_miter_limit (cairo_gstate_t *gstate)
|
|||
}
|
||||
|
||||
cairo_status_t
|
||||
cairo_gstate_translate (cairo_gstate_t *gstate, double tx, double ty)
|
||||
_cairo_gstate_translate (cairo_gstate_t *gstate, double tx, double ty)
|
||||
{
|
||||
cairo_matrix_t tmp;
|
||||
|
||||
|
|
@ -597,7 +603,7 @@ _cairo_gstate_identity_matrix (cairo_gstate_t *gstate)
|
|||
}
|
||||
|
||||
cairo_status_t
|
||||
cairo_gstateransform_point (cairo_gstate_t *gstate, double *x, double *y)
|
||||
_cairo_gstate_transform_point (cairo_gstate_t *gstate, double *x, double *y)
|
||||
{
|
||||
cairo_matrix_transform_point (&gstate->ctm, x, y);
|
||||
|
||||
|
|
@ -605,7 +611,7 @@ cairo_gstateransform_point (cairo_gstate_t *gstate, double *x, double *y)
|
|||
}
|
||||
|
||||
cairo_status_t
|
||||
cairo_gstateransform_distance (cairo_gstate_t *gstate, double *dx, double *dy)
|
||||
_cairo_gstate_transform_distance (cairo_gstate_t *gstate, double *dx, double *dy)
|
||||
{
|
||||
cairo_matrix_transform_distance (&gstate->ctm, dx, dy);
|
||||
|
||||
|
|
@ -760,6 +766,17 @@ _cairo_gstate_rel_curve_to (cairo_gstate_t *gstate,
|
|||
return status;
|
||||
}
|
||||
|
||||
/* XXX: NYI
|
||||
cairo_status_t
|
||||
_cairo_gstate_stroke_path (cairo_gstate_t *gstate)
|
||||
{
|
||||
cairo_status_t status;
|
||||
|
||||
_cairo_pen_init (&gstate
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
}
|
||||
*/
|
||||
|
||||
cairo_status_t
|
||||
_cairo_gstate_close_path (cairo_gstate_t *gstate)
|
||||
{
|
||||
|
|
@ -823,12 +840,12 @@ _cairo_gstate_clip_and_composite_trapezoids (cairo_gstate_t *gstate,
|
|||
cairo_surface_t *dst,
|
||||
cairo_traps_t *traps)
|
||||
{
|
||||
if (traps->num_xtraps == 0)
|
||||
if (traps->num_traps == 0)
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
|
||||
if (gstate->clip.surface) {
|
||||
XFixed xoff, yoff;
|
||||
XTrapezoid *t;
|
||||
cairo_fixed_t xoff, yoff;
|
||||
cairo_trapezoid_t *t;
|
||||
int i;
|
||||
|
||||
cairo_surface_t *intermediate, *white;
|
||||
|
|
@ -844,12 +861,13 @@ _cairo_gstate_clip_and_composite_trapezoids (cairo_gstate_t *gstate,
|
|||
gstate->clip.height,
|
||||
0.0, 0.0, 0.0, 0.0);
|
||||
|
||||
/* Ugh. The Xc/ (Render) interface doesn't allow an offset for
|
||||
the trapezoids. Need to manually shift all the coordinates
|
||||
to align with the offset origin of the clip surface. */
|
||||
/* Ugh. The cairo_composite/(Render) interface doesn't allow
|
||||
an offset for the trapezoids. Need to manually shift all
|
||||
the coordinates to align with the offset origin of the clip
|
||||
surface. */
|
||||
xoff = XDoubleToFixed (gstate->clip.x);
|
||||
yoff = XDoubleToFixed (gstate->clip.y);
|
||||
for (i=0, t=traps->xtraps; i < traps->num_xtraps; i++, t++) {
|
||||
for (i=0, t=traps->traps; i < traps->num_traps; i++, t++) {
|
||||
t->top -= yoff;
|
||||
t->bottom -= yoff;
|
||||
t->left.p1.x -= xoff;
|
||||
|
|
@ -862,49 +880,45 @@ _cairo_gstate_clip_and_composite_trapezoids (cairo_gstate_t *gstate,
|
|||
t->right.p2.y -= yoff;
|
||||
}
|
||||
|
||||
XcCompositeTrapezoids (CAIRO_OPERATOR_ADD,
|
||||
white->xc_surface,
|
||||
intermediate->xc_surface,
|
||||
0, 0,
|
||||
traps->xtraps,
|
||||
traps->num_xtraps);
|
||||
XcComposite (CAIRO_OPERATOR_IN,
|
||||
gstate->clip.surface->xc_surface,
|
||||
NULL,
|
||||
intermediate->xc_surface,
|
||||
0, 0, 0, 0, 0, 0,
|
||||
gstate->clip.width, gstate->clip.height);
|
||||
XcComposite (operator,
|
||||
src->xc_surface,
|
||||
intermediate->xc_surface,
|
||||
dst->xc_surface,
|
||||
0, 0,
|
||||
0, 0,
|
||||
gstate->clip.x,
|
||||
gstate->clip.y,
|
||||
gstate->clip.width,
|
||||
gstate->clip.height);
|
||||
_cairo_surface_composite_trapezoids (CAIRO_OPERATOR_ADD,
|
||||
white, intermediate,
|
||||
0, 0,
|
||||
traps->traps,
|
||||
traps->num_traps);
|
||||
_cairo_surface_composite (CAIRO_OPERATOR_IN,
|
||||
gstate->clip.surface,
|
||||
NULL,
|
||||
intermediate,
|
||||
0, 0, 0, 0, 0, 0,
|
||||
gstate->clip.width, gstate->clip.height);
|
||||
_cairo_surface_composite (operator,
|
||||
src, intermediate, dst,
|
||||
0, 0,
|
||||
0, 0,
|
||||
gstate->clip.x,
|
||||
gstate->clip.y,
|
||||
gstate->clip.width,
|
||||
gstate->clip.height);
|
||||
cairo_surface_destroy (intermediate);
|
||||
cairo_surface_destroy (white);
|
||||
|
||||
} else {
|
||||
double xoff, yoff;
|
||||
|
||||
if (traps->xtraps[0].left.p1.y < traps->xtraps[0].left.p2.y) {
|
||||
xoff = traps->xtraps[0].left.p1.x;
|
||||
yoff = traps->xtraps[0].left.p1.y;
|
||||
if (traps->traps[0].left.p1.y < traps->traps[0].left.p2.y) {
|
||||
xoff = traps->traps[0].left.p1.x;
|
||||
yoff = traps->traps[0].left.p1.y;
|
||||
} else {
|
||||
xoff = traps->xtraps[0].left.p2.x;
|
||||
yoff = traps->xtraps[0].left.p2.y;
|
||||
xoff = traps->traps[0].left.p2.x;
|
||||
yoff = traps->traps[0].left.p2.y;
|
||||
}
|
||||
|
||||
XcCompositeTrapezoids (gstate->operator,
|
||||
src->xc_surface,
|
||||
dst->xc_surface,
|
||||
XFixedToDouble (xoff) - gstate->pattern_offset.x,
|
||||
XFixedToDouble (yoff) - gstate->pattern_offset.y,
|
||||
traps->xtraps,
|
||||
traps->num_xtraps);
|
||||
_cairo_surface_composite_trapezoids (gstate->operator,
|
||||
src, dst,
|
||||
XFixedToDouble (xoff) - gstate->pattern_offset.x,
|
||||
XFixedToDouble (yoff) - gstate->pattern_offset.y,
|
||||
traps->traps,
|
||||
traps->num_traps);
|
||||
}
|
||||
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
|
|
@ -996,28 +1010,30 @@ _cairo_gstate_scale_font (cairo_gstate_t *gstate, double scale)
|
|||
}
|
||||
|
||||
cairo_status_t
|
||||
cairo_gstateransform_font (cairo_gstate_t *gstate,
|
||||
double a, double b,
|
||||
double c, double d)
|
||||
_cairo_gstate_transform_font (cairo_gstate_t *gstate,
|
||||
double a, double b,
|
||||
double c, double d)
|
||||
{
|
||||
return cairo_font_transform (&gstate->font,
|
||||
a, b, c, d);
|
||||
}
|
||||
|
||||
cairo_status_t
|
||||
cairo_gstateext_extents (cairo_gstate_t *gstate,
|
||||
const unsigned char *utf8,
|
||||
double *x, double *y,
|
||||
double *width, double *height,
|
||||
double *dx, double *dy)
|
||||
_cairo_gstate_text_extents (cairo_gstate_t *gstate,
|
||||
const unsigned char *utf8,
|
||||
double *x, double *y,
|
||||
double *width, double *height,
|
||||
double *dx, double *dy)
|
||||
{
|
||||
XftFont *xft_font;
|
||||
XGlyphInfo extents;
|
||||
|
||||
if (gstate->surface->dpy == 0)
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
|
||||
_cairo_font_resolve_xft_font (&gstate->font, gstate, &xft_font);
|
||||
|
||||
/* XXX: Need to abandon Xft and use Xc instead */
|
||||
/* (until I do, this call will croak on IcImage cairo_surface_ts */
|
||||
/* XXX: Need to make a generic (non-Xft) backend for text. */
|
||||
XftTextExtentsUtf8 (gstate->surface->dpy,
|
||||
xft_font,
|
||||
utf8,
|
||||
|
|
@ -1050,14 +1066,12 @@ _cairo_gstate_show_text (cairo_gstate_t *gstate, const unsigned char *utf8)
|
|||
|
||||
_cairo_font_resolve_xft_font (&gstate->font, gstate, &xft_font);
|
||||
|
||||
/* XXX: Need to abandon Xft and use Xc instead */
|
||||
/* (until I do, this call will croak on IcImage cairo_surface_ts */
|
||||
/* (also, this means text clipping isn't working. Basically text is broken.) */
|
||||
/* XXX: Need to make a generic (non-Xft) backend for text. */
|
||||
XftTextRenderUtf8 (gstate->surface->dpy,
|
||||
gstate->operator,
|
||||
_cairo_surface_get_picture (gstate->solid),
|
||||
gstate->solid->picture,
|
||||
xft_font,
|
||||
_cairo_surface_get_picture (gstate->surface),
|
||||
gstate->surface->picture,
|
||||
0, 0,
|
||||
gstate->current_pt.x,
|
||||
gstate->current_pt.y,
|
||||
|
|
@ -1107,15 +1121,13 @@ _cairo_gstate_show_surface (cairo_gstate_t *gstate,
|
|||
|
||||
/* XXX: The rendered size is sometimes 1 or 2 pixels short from
|
||||
what I expect. Need to fix this. */
|
||||
XcComposite (gstate->operator,
|
||||
surface->xc_surface,
|
||||
mask->xc_surface,
|
||||
gstate->surface->xc_surface,
|
||||
device_x, device_y,
|
||||
0, 0,
|
||||
device_x, device_y,
|
||||
device_width,
|
||||
device_height);
|
||||
_cairo_surface_composite (gstate->operator,
|
||||
surface, mask, gstate->surface,
|
||||
device_x, device_y,
|
||||
0, 0,
|
||||
device_x, device_y,
|
||||
device_width,
|
||||
device_height);
|
||||
|
||||
cairo_surface_destroy (mask);
|
||||
|
||||
|
|
|
|||
|
|
@ -30,7 +30,7 @@
|
|||
|
||||
/* private functions */
|
||||
static cairo_status_t
|
||||
_cairo_path_add (cairo_path_t *path, cairo_path_op_t op, XPointFixed *pts, int num_pts);
|
||||
_cairo_path_add (cairo_path_t *path, cairo_path_op_t op, cairo_point_t *pts, int num_pts);
|
||||
|
||||
static void
|
||||
_cairo_path_add_op_buf (cairo_path_t *path, cairo_path_op_buf_t *op);
|
||||
|
|
@ -60,7 +60,7 @@ static void
|
|||
_cairo_path_arg_buf_destroy (cairo_path_arg_buf_t *buf);
|
||||
|
||||
static void
|
||||
_cairo_path_arg_buf_add (cairo_path_arg_buf_t *arg, XPointFixed *pts, int num_pts);
|
||||
_cairo_path_arg_buf_add (cairo_path_arg_buf_t *arg, cairo_point_t *pts, int num_pts);
|
||||
|
||||
void
|
||||
_cairo_path_init (cairo_path_t *path)
|
||||
|
|
@ -125,7 +125,7 @@ _cairo_path_fini (cairo_path_t *path)
|
|||
cairo_status_t
|
||||
_cairo_path_move_to (cairo_path_t *path, double x, double y)
|
||||
{
|
||||
XPointFixed pt;
|
||||
cairo_point_t pt;
|
||||
|
||||
pt.x = XDoubleToFixed (x);
|
||||
pt.y = XDoubleToFixed (y);
|
||||
|
|
@ -136,7 +136,7 @@ _cairo_path_move_to (cairo_path_t *path, double x, double y)
|
|||
cairo_status_t
|
||||
_cairo_path_line_to (cairo_path_t *path, double x, double y)
|
||||
{
|
||||
XPointFixed pt;
|
||||
cairo_point_t pt;
|
||||
|
||||
pt.x = XDoubleToFixed (x);
|
||||
pt.y = XDoubleToFixed (y);
|
||||
|
|
@ -150,7 +150,7 @@ _cairo_path_curve_to (cairo_path_t *path,
|
|||
double x2, double y2,
|
||||
double x3, double y3)
|
||||
{
|
||||
XPointFixed pt[3];
|
||||
cairo_point_t pt[3];
|
||||
|
||||
pt[0].x = XDoubleToFixed (x1);
|
||||
pt[0].y = XDoubleToFixed (y1);
|
||||
|
|
@ -171,7 +171,7 @@ _cairo_path_close_path (cairo_path_t *path)
|
|||
}
|
||||
|
||||
static cairo_status_t
|
||||
_cairo_path_add (cairo_path_t *path, cairo_path_op_t op, XPointFixed *pts, int num_pts)
|
||||
_cairo_path_add (cairo_path_t *path, cairo_path_op_t op, cairo_point_t *pts, int num_pts)
|
||||
{
|
||||
cairo_status_t status;
|
||||
|
||||
|
|
@ -300,7 +300,7 @@ _cairo_path_arg_buf_destroy (cairo_path_arg_buf_t *arg)
|
|||
}
|
||||
|
||||
static void
|
||||
_cairo_path_arg_buf_add (cairo_path_arg_buf_t *arg, XPointFixed *pts, int num_pts)
|
||||
_cairo_path_arg_buf_add (cairo_path_arg_buf_t *arg, cairo_point_t *pts, int num_pts)
|
||||
{
|
||||
int i;
|
||||
|
||||
|
|
@ -328,9 +328,9 @@ _cairo_path_interpret (cairo_path_t *path, cairo_path_direction_t dir, const cai
|
|||
cairo_path_op_t op;
|
||||
cairo_path_arg_buf_t *arg_buf = path->arg_head;
|
||||
int buf_i = 0;
|
||||
XPointFixed pt[CAIRO_PATH_OP_MAX_ARGS];
|
||||
XPointFixed current = {0, 0};
|
||||
XPointFixed first = {0, 0};
|
||||
cairo_point_t pt[CAIRO_PATH_OP_MAX_ARGS];
|
||||
cairo_point_t current = {0, 0};
|
||||
cairo_point_t first = {0, 0};
|
||||
int has_current = 0;
|
||||
int has_edge = 0;
|
||||
int step = (dir == cairo_path_direction_forward) ? 1 : -1;
|
||||
|
|
@ -375,7 +375,7 @@ _cairo_path_interpret (cairo_path_t *path, cairo_path_direction_t dir, const cai
|
|||
switch (op) {
|
||||
case cairo_path_op_move_to:
|
||||
if (has_edge) {
|
||||
status = (*cb->DoneSubPath) (closure, cairo_sub_path_done_cap);
|
||||
status = (*cb->done_sub_path) (closure, cairo_sub_path_done_cap);
|
||||
if (status)
|
||||
return status;
|
||||
}
|
||||
|
|
@ -386,7 +386,7 @@ _cairo_path_interpret (cairo_path_t *path, cairo_path_direction_t dir, const cai
|
|||
break;
|
||||
case cairo_path_op_line_to:
|
||||
if (has_current) {
|
||||
status = (*cb->AddEdge) (closure, ¤t, &pt[0]);
|
||||
status = (*cb->add_edge) (closure, ¤t, &pt[0]);
|
||||
if (status)
|
||||
return status;
|
||||
current = pt[0];
|
||||
|
|
@ -400,7 +400,7 @@ _cairo_path_interpret (cairo_path_t *path, cairo_path_direction_t dir, const cai
|
|||
break;
|
||||
case cairo_path_op_curve_to:
|
||||
if (has_current) {
|
||||
status = (*cb->AddSpline) (closure, ¤t, &pt[0], &pt[1], &pt[2]);
|
||||
status = (*cb->add_spline) (closure, ¤t, &pt[0], &pt[1], &pt[2]);
|
||||
if (status)
|
||||
return status;
|
||||
current = pt[2];
|
||||
|
|
@ -414,8 +414,8 @@ _cairo_path_interpret (cairo_path_t *path, cairo_path_direction_t dir, const cai
|
|||
break;
|
||||
case cairo_path_op_close_path:
|
||||
if (has_edge) {
|
||||
(*cb->AddEdge) (closure, ¤t, &first);
|
||||
(*cb->DoneSubPath) (closure, cairo_sub_path_done_join);
|
||||
(*cb->add_edge) (closure, ¤t, &first);
|
||||
(*cb->done_sub_path) (closure, cairo_sub_path_done_join);
|
||||
}
|
||||
current.x = 0;
|
||||
current.y = 0;
|
||||
|
|
@ -428,9 +428,9 @@ _cairo_path_interpret (cairo_path_t *path, cairo_path_direction_t dir, const cai
|
|||
}
|
||||
}
|
||||
if (has_edge)
|
||||
(*cb->DoneSubPath) (closure, cairo_sub_path_done_cap);
|
||||
(*cb->done_sub_path) (closure, cairo_sub_path_done_cap);
|
||||
|
||||
return (*cb->DonePath) (closure);
|
||||
return (*cb->done_path) (closure);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -30,10 +30,10 @@
|
|||
typedef struct cairo_path_bounder {
|
||||
int has_pt;
|
||||
|
||||
XFixed min_x;
|
||||
XFixed min_y;
|
||||
XFixed max_x;
|
||||
XFixed max_y;
|
||||
cairo_fixed_t min_x;
|
||||
cairo_fixed_t min_y;
|
||||
cairo_fixed_t max_x;
|
||||
cairo_fixed_t max_y;
|
||||
} cairo_path_bounder_t;
|
||||
|
||||
static void
|
||||
|
|
@ -43,14 +43,15 @@ static void
|
|||
_cairo_path_bounder_fini (cairo_path_bounder_t *bounder);
|
||||
|
||||
static cairo_status_t
|
||||
_cairo_path_bounder_add_point (cairo_path_bounder_t *bounder, XPointFixed *pt);
|
||||
_cairo_path_bounder_add_point (cairo_path_bounder_t *bounder, cairo_point_t *pt);
|
||||
|
||||
static cairo_status_t
|
||||
_cairo_path_bounder_add_edge (void *closure, XPointFixed *p1, XPointFixed *p2);
|
||||
_cairo_path_bounder_add_edge (void *closure, cairo_point_t *p1, cairo_point_t *p2);
|
||||
|
||||
static cairo_status_t
|
||||
_cairo_path_bounder_add_spline (void *closure,
|
||||
XPointFixed *a, XPointFixed *b, XPointFixed *c, XPointFixed *d);
|
||||
cairo_point_t *a, cairo_point_t *b,
|
||||
cairo_point_t *c, cairo_point_t *d);
|
||||
|
||||
static cairo_status_t
|
||||
_cairo_path_bounder_done_sub_path (void *closure, cairo_sub_path_done_t done);
|
||||
|
|
@ -71,7 +72,7 @@ _cairo_path_bounder_fini (cairo_path_bounder_t *bounder)
|
|||
}
|
||||
|
||||
static cairo_status_t
|
||||
_cairo_path_bounder_add_point (cairo_path_bounder_t *bounder, XPointFixed *pt)
|
||||
_cairo_path_bounder_add_point (cairo_path_bounder_t *bounder, cairo_point_t *pt)
|
||||
{
|
||||
if (bounder->has_pt) {
|
||||
if (pt->x < bounder->min_x)
|
||||
|
|
@ -98,7 +99,7 @@ _cairo_path_bounder_add_point (cairo_path_bounder_t *bounder, XPointFixed *pt)
|
|||
}
|
||||
|
||||
static cairo_status_t
|
||||
_cairo_path_bounder_add_edge (void *closure, XPointFixed *p1, XPointFixed *p2)
|
||||
_cairo_path_bounder_add_edge (void *closure, cairo_point_t *p1, cairo_point_t *p2)
|
||||
{
|
||||
cairo_path_bounder_t *bounder = closure;
|
||||
|
||||
|
|
@ -110,7 +111,8 @@ _cairo_path_bounder_add_edge (void *closure, XPointFixed *p1, XPointFixed *p2)
|
|||
|
||||
static cairo_status_t
|
||||
_cairo_path_bounder_add_spline (void *closure,
|
||||
XPointFixed *a, XPointFixed *b, XPointFixed *c, XPointFixed *d)
|
||||
cairo_point_t *a, cairo_point_t *b,
|
||||
cairo_point_t *c, cairo_point_t *d)
|
||||
{
|
||||
cairo_path_bounder_t *bounder = closure;
|
||||
|
||||
|
|
|
|||
|
|
@ -41,10 +41,12 @@ static void
|
|||
_cairo_filler_fini (cairo_filler_t *filler);
|
||||
|
||||
static cairo_status_t
|
||||
_cairo_filler_add_edge (void *closure, XPointFixed *p1, XPointFixed *p2);
|
||||
_cairo_filler_add_edge (void *closure, cairo_point_t *p1, cairo_point_t *p2);
|
||||
|
||||
static cairo_status_t
|
||||
_cairo_filler_add_spline (void *closure, XPointFixed *a, XPointFixed *b, XPointFixed *c, XPointFixed *d);
|
||||
_cairo_filler_add_spline (void *closure,
|
||||
cairo_point_t *a, cairo_point_t *b,
|
||||
cairo_point_t *c, cairo_point_t *d);
|
||||
|
||||
static cairo_status_t
|
||||
_cairo_filler_done_sub_path (void *closure, cairo_sub_path_done_t done);
|
||||
|
|
@ -68,7 +70,7 @@ _cairo_filler_fini (cairo_filler_t *filler)
|
|||
}
|
||||
|
||||
static cairo_status_t
|
||||
_cairo_filler_add_edge (void *closure, XPointFixed *p1, XPointFixed *p2)
|
||||
_cairo_filler_add_edge (void *closure, cairo_point_t *p1, cairo_point_t *p2)
|
||||
{
|
||||
cairo_filler_t *filler = closure;
|
||||
cairo_polygon_t *polygon = &filler->polygon;
|
||||
|
|
@ -77,7 +79,9 @@ _cairo_filler_add_edge (void *closure, XPointFixed *p1, XPointFixed *p2)
|
|||
}
|
||||
|
||||
static cairo_status_t
|
||||
_cairo_filler_add_spline (void *closure, XPointFixed *a, XPointFixed *b, XPointFixed *c, XPointFixed *d)
|
||||
_cairo_filler_add_spline (void *closure,
|
||||
cairo_point_t *a, cairo_point_t *b,
|
||||
cairo_point_t *c, cairo_point_t *d)
|
||||
{
|
||||
int i;
|
||||
cairo_status_t status = CAIRO_STATUS_SUCCESS;
|
||||
|
|
|
|||
|
|
@ -49,13 +49,15 @@ static void
|
|||
_cairo_stroker_fini (cairo_stroker_t *stroker);
|
||||
|
||||
static cairo_status_t
|
||||
_cairo_stroker_add_edge (void *closure, XPointFixed *p1, XPointFixed *p2);
|
||||
_cairo_stroker_add_edge (void *closure, cairo_point_t *p1, cairo_point_t *p2);
|
||||
|
||||
static cairo_status_t
|
||||
_cairo_stroker_add_edge_dashed (void *closure, XPointFixed *p1, XPointFixed *p2);
|
||||
_cairo_stroker_add_edge_dashed (void *closure, cairo_point_t *p1, cairo_point_t *p2);
|
||||
|
||||
static cairo_status_t
|
||||
_cairo_stroker_add_spline (void *closure, XPointFixed *a, XPointFixed *b, XPointFixed *c, XPointFixed *d);
|
||||
_cairo_stroker_add_spline (void *closure,
|
||||
cairo_point_t *a, cairo_point_t *b,
|
||||
cairo_point_t *c, cairo_point_t *d);
|
||||
|
||||
static cairo_status_t
|
||||
_cairo_stroker_done_sub_path (void *closure, cairo_sub_path_done_t done);
|
||||
|
|
@ -64,7 +66,7 @@ static cairo_status_t
|
|||
_cairo_stroker_done_path (void *closure);
|
||||
|
||||
static void
|
||||
_translate_point (XPointFixed *pt, XPointFixed *offset);
|
||||
_translate_point (cairo_point_t *pt, cairo_point_t *offset);
|
||||
|
||||
static int
|
||||
_cairo_stroker_face_clockwise (cairo_stroke_face_t *in, cairo_stroke_face_t *out);
|
||||
|
|
@ -125,7 +127,7 @@ _cairo_stroker_fini (cairo_stroker_t *stroker)
|
|||
}
|
||||
|
||||
static void
|
||||
_translate_point (XPointFixed *pt, XPointFixed *offset)
|
||||
_translate_point (cairo_point_t *pt, cairo_point_t *offset)
|
||||
{
|
||||
pt->x += offset->x;
|
||||
pt->y += offset->y;
|
||||
|
|
@ -134,14 +136,12 @@ _translate_point (XPointFixed *pt, XPointFixed *offset)
|
|||
static int
|
||||
_cairo_stroker_face_clockwise (cairo_stroke_face_t *in, cairo_stroke_face_t *out)
|
||||
{
|
||||
XPointDouble d_in, d_out;
|
||||
cairo_slope_t in_slope, out_slope;
|
||||
|
||||
d_in.x = XFixedToDouble (in->cw.x - in->pt.x);
|
||||
d_in.y = XFixedToDouble (in->cw.y - in->pt.y);
|
||||
d_out.x = XFixedToDouble (out->cw.x - out->pt.x);
|
||||
d_out.y = XFixedToDouble (out->cw.y - out->pt.y);
|
||||
_cairo_slope_init (&in_slope, &in->pt, &in->cw);
|
||||
_cairo_slope_init (&out_slope, &out->pt, &out->cw);
|
||||
|
||||
return d_out.y * d_in.x > d_in.y * d_out.x;
|
||||
return _cairo_slope_clockwise (&in_slope, &out_slope);
|
||||
}
|
||||
|
||||
static cairo_status_t
|
||||
|
|
@ -150,7 +150,7 @@ _cairo_stroker_join (cairo_stroker_t *stroker, cairo_stroke_face_t *in, cairo_st
|
|||
cairo_status_t status;
|
||||
cairo_gstate_t *gstate = stroker->gstate;
|
||||
int clockwise = _cairo_stroker_face_clockwise (out, in);
|
||||
XPointFixed *inpt, *outpt;
|
||||
cairo_point_t *inpt, *outpt;
|
||||
|
||||
if (in->cw.x == out->cw.x
|
||||
&& in->cw.y == out->cw.y
|
||||
|
|
@ -171,7 +171,7 @@ _cairo_stroker_join (cairo_stroker_t *stroker, cairo_stroke_face_t *in, cairo_st
|
|||
case CAIRO_LINE_JOIN_ROUND: {
|
||||
int i;
|
||||
int start, step, stop;
|
||||
XPointFixed tri[3], initial, final;
|
||||
cairo_point_t tri[3], initial, final;
|
||||
cairo_pen_t *pen = &gstate->pen_regular;
|
||||
|
||||
tri[0] = in->pt;
|
||||
|
|
@ -219,7 +219,7 @@ _cairo_stroker_join (cairo_stroker_t *stroker, cairo_stroke_face_t *in, cairo_st
|
|||
XDouble x1, y1, x2, y2;
|
||||
XDouble mx, my;
|
||||
XDouble dx1, dx2, dy1, dy2;
|
||||
XPointFixed outer;
|
||||
cairo_point_t outer;
|
||||
|
||||
x1 = XFixedToDouble (inpt->x);
|
||||
y1 = XFixedToDouble (inpt->y);
|
||||
|
|
@ -256,7 +256,7 @@ _cairo_stroker_join (cairo_stroker_t *stroker, cairo_stroke_face_t *in, cairo_st
|
|||
/* fall through ... */
|
||||
}
|
||||
case CAIRO_LINE_JOIN_BEVEL: {
|
||||
XPointFixed tri[3];
|
||||
cairo_point_t tri[3];
|
||||
tri[0] = in->pt;
|
||||
tri[1] = *inpt;
|
||||
tri[2] = *outpt;
|
||||
|
|
@ -279,8 +279,8 @@ _cairo_stroker_cap (cairo_stroker_t *stroker, cairo_stroke_face_t *f)
|
|||
case CAIRO_LINE_CAP_ROUND: {
|
||||
int i;
|
||||
int start, stop;
|
||||
cairo_slope_fixed_t slope;
|
||||
XPointFixed tri[3];
|
||||
cairo_slope_t slope;
|
||||
cairo_point_t tri[3];
|
||||
cairo_pen_t *pen = &gstate->pen_regular;
|
||||
|
||||
slope = f->dev_vector;
|
||||
|
|
@ -303,8 +303,8 @@ _cairo_stroker_cap (cairo_stroker_t *stroker, cairo_stroke_face_t *f)
|
|||
}
|
||||
case CAIRO_LINE_CAP_SQUARE: {
|
||||
double dx, dy;
|
||||
cairo_slope_fixed_t fvector;
|
||||
XPointFixed occw, ocw;
|
||||
cairo_slope_t fvector;
|
||||
cairo_point_t occw, ocw;
|
||||
cairo_polygon_t polygon;
|
||||
|
||||
_cairo_polygon_init (&polygon);
|
||||
|
|
@ -338,12 +338,12 @@ _cairo_stroker_cap (cairo_stroker_t *stroker, cairo_stroke_face_t *f)
|
|||
}
|
||||
|
||||
static void
|
||||
_compute_face (XPointFixed *pt, cairo_slope_fixed_t *slope, cairo_gstate_t *gstate, cairo_stroke_face_t *face)
|
||||
_compute_face (cairo_point_t *pt, cairo_slope_t *slope, cairo_gstate_t *gstate, cairo_stroke_face_t *face)
|
||||
{
|
||||
double mag, tmp;
|
||||
double dx, dy;
|
||||
XPointDouble usr_vector;
|
||||
XPointFixed offset_ccw, offset_cw;
|
||||
cairo_point_t offset_ccw, offset_cw;
|
||||
|
||||
dx = XFixedToDouble (slope->dx);
|
||||
dy = XFixedToDouble (slope->dy);
|
||||
|
|
@ -388,12 +388,12 @@ _compute_face (XPointFixed *pt, cairo_slope_fixed_t *slope, cairo_gstate_t *gsta
|
|||
}
|
||||
|
||||
static cairo_status_t
|
||||
_cairo_stroker_add_sub_edge (cairo_stroker_t *stroker, XPointFixed *p1, XPointFixed *p2,
|
||||
_cairo_stroker_add_sub_edge (cairo_stroker_t *stroker, cairo_point_t *p1, cairo_point_t *p2,
|
||||
cairo_stroke_face_t *start, cairo_stroke_face_t *end)
|
||||
{
|
||||
cairo_gstate_t *gstate = stroker->gstate;
|
||||
XPointFixed quad[4];
|
||||
cairo_slope_fixed_t slope;
|
||||
cairo_point_t quad[4];
|
||||
cairo_slope_t slope;
|
||||
|
||||
if (p1->x == p2->x && p1->y == p2->y) {
|
||||
/* XXX: Need to rethink how this case should be handled, (both
|
||||
|
|
@ -402,7 +402,7 @@ _cairo_stroker_add_sub_edge (cairo_stroker_t *stroker, XPointFixed *p1, XPointFi
|
|||
return CAIRO_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
_compute_slope (p1, p2, &slope);
|
||||
_cairo_slope_init (&slope, p1, p2);
|
||||
_compute_face (p1, &slope, gstate, start);
|
||||
|
||||
/* XXX: This could be optimized slightly by not calling
|
||||
|
|
@ -419,7 +419,7 @@ _cairo_stroker_add_sub_edge (cairo_stroker_t *stroker, XPointFixed *p1, XPointFi
|
|||
}
|
||||
|
||||
static cairo_status_t
|
||||
_cairo_stroker_add_edge (void *closure, XPointFixed *p1, XPointFixed *p2)
|
||||
_cairo_stroker_add_edge (void *closure, cairo_point_t *p1, cairo_point_t *p2)
|
||||
{
|
||||
cairo_status_t status;
|
||||
cairo_stroker_t *stroker = closure;
|
||||
|
|
@ -458,7 +458,7 @@ _cairo_stroker_add_edge (void *closure, XPointFixed *p1, XPointFixed *p2)
|
|||
* Dashed lines. Cap each dash end, join around turns when on
|
||||
*/
|
||||
static cairo_status_t
|
||||
_cairo_stroker_add_edge_dashed (void *closure, XPointFixed *p1, XPointFixed *p2)
|
||||
_cairo_stroker_add_edge_dashed (void *closure, cairo_point_t *p1, cairo_point_t *p2)
|
||||
{
|
||||
cairo_status_t status = CAIRO_STATUS_SUCCESS;
|
||||
cairo_stroker_t *stroker = closure;
|
||||
|
|
@ -466,7 +466,7 @@ _cairo_stroker_add_edge_dashed (void *closure, XPointFixed *p1, XPointFixed *p2)
|
|||
double mag, remain, tmp;
|
||||
double dx, dy;
|
||||
double dx2, dy2;
|
||||
XPointFixed fd1, fd2;
|
||||
cairo_point_t fd1, fd2;
|
||||
int first = 1;
|
||||
cairo_stroke_face_t sub_start, sub_end;
|
||||
|
||||
|
|
@ -564,7 +564,9 @@ _cairo_stroker_add_edge_dashed (void *closure, XPointFixed *p1, XPointFixed *p2)
|
|||
}
|
||||
|
||||
static cairo_status_t
|
||||
_cairo_stroker_add_spline (void *closure, XPointFixed *a, XPointFixed *b, XPointFixed *c, XPointFixed *d)
|
||||
_cairo_stroker_add_spline (void *closure,
|
||||
cairo_point_t *a, cairo_point_t *b,
|
||||
cairo_point_t *c, cairo_point_t *d)
|
||||
{
|
||||
cairo_status_t status = CAIRO_STATUS_SUCCESS;
|
||||
cairo_stroker_t *stroker = closure;
|
||||
|
|
@ -572,7 +574,7 @@ _cairo_stroker_add_spline (void *closure, XPointFixed *a, XPointFixed *b, XPoint
|
|||
cairo_spline_t spline;
|
||||
cairo_pen_t pen;
|
||||
cairo_stroke_face_t start, end;
|
||||
XPointFixed extra_points[4];
|
||||
cairo_point_t extra_points[4];
|
||||
|
||||
status = _cairo_spline_init (&spline, a, b, c, d);
|
||||
if (status == cairo_int_status_degenerate)
|
||||
|
|
@ -645,7 +647,7 @@ _cairo_stroker_done_sub_path (void *closure, cairo_sub_path_done_t done)
|
|||
/* fall through... */
|
||||
case cairo_sub_path_done_cap:
|
||||
if (stroker->have_first) {
|
||||
XPointFixed t;
|
||||
cairo_point_t t;
|
||||
/* The initial cap needs an outward facing vector. Reverse everything */
|
||||
stroker->first.usr_vector.x = -stroker->first.usr_vector.x;
|
||||
stroker->first.usr_vector.y = -stroker->first.usr_vector.y;
|
||||
|
|
@ -702,8 +704,8 @@ _cairo_path_stroke_to_traps (cairo_path_t *path, cairo_gstate_t *gstate, cairo_t
|
|||
_cairo_stroker_init (&stroker, gstate, traps);
|
||||
|
||||
status = _cairo_path_interpret (path,
|
||||
cairo_path_direction_forward,
|
||||
callbacks, &stroker);
|
||||
cairo_path_direction_forward,
|
||||
callbacks, &stroker);
|
||||
if (status) {
|
||||
_cairo_stroker_fini (&stroker);
|
||||
return status;
|
||||
|
|
|
|||
134
src/cairo_pen.c
134
src/cairo_pen.c
|
|
@ -34,13 +34,7 @@ static void
|
|||
_cairo_pen_compute_slopes (cairo_pen_t *pen);
|
||||
|
||||
static int
|
||||
_slope_clockwise (cairo_slope_fixed_t *a, cairo_slope_fixed_t *b);
|
||||
|
||||
static int
|
||||
_slope_counter_clockwise (cairo_slope_fixed_t *a, cairo_slope_fixed_t *b);
|
||||
|
||||
static int
|
||||
_cairo_pen_vertex_compare_by_theta (const void *a, const void *b);
|
||||
_pen_vertex_compare (const void *av, const void *bv);
|
||||
|
||||
static cairo_status_t
|
||||
_cairo_pen_stroke_spline_half (cairo_pen_t *pen, cairo_spline_t *spline, cairo_pen_stroke_direction_t dir, cairo_polygon_t *polygon);
|
||||
|
|
@ -60,8 +54,6 @@ cairo_status_t
|
|||
_cairo_pen_init (cairo_pen_t *pen, double radius, cairo_gstate_t *gstate)
|
||||
{
|
||||
int i;
|
||||
cairo_pen_vertex_t *v;
|
||||
double dx, dy;
|
||||
|
||||
if (pen->num_vertices) {
|
||||
/* XXX: It would be nice to notice that the pen is already properly constructed.
|
||||
|
|
@ -87,17 +79,13 @@ _cairo_pen_init (cairo_pen_t *pen, double radius, cairo_gstate_t *gstate)
|
|||
}
|
||||
|
||||
for (i=0; i < pen->num_vertices; i++) {
|
||||
v = &pen->vertex[i];
|
||||
v->theta = 2 * M_PI * i / (double) pen->num_vertices;
|
||||
dx = radius * cos (v->theta);
|
||||
dy = radius * sin (v->theta);
|
||||
double theta = 2 * M_PI * i / (double) pen->num_vertices;
|
||||
double dx = radius * cos (theta);
|
||||
double dy = radius * sin (theta);
|
||||
cairo_pen_vertex_t *v = &pen->vertex[i];
|
||||
cairo_matrix_transform_distance (&gstate->ctm, &dx, &dy);
|
||||
v->pt.x = XDoubleToFixed (dx);
|
||||
v->pt.y = XDoubleToFixed (dy);
|
||||
/* Recompute theta in device space */
|
||||
v->theta = atan2 (v->pt.y, v->pt.x);
|
||||
if (v->theta < 0)
|
||||
v->theta += 2 * M_PI;
|
||||
}
|
||||
|
||||
_cairo_pen_compute_slopes (pen);
|
||||
|
|
@ -128,26 +116,10 @@ _cairo_pen_init_copy (cairo_pen_t *pen, cairo_pen_t *other)
|
|||
return CAIRO_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
static int
|
||||
_cairo_pen_vertex_compare_by_theta (const void *a, const void *b)
|
||||
{
|
||||
double diff;
|
||||
const cairo_pen_vertex_t *va = a;
|
||||
const cairo_pen_vertex_t *vb = b;
|
||||
|
||||
diff = va->theta - vb->theta;
|
||||
if (diff < 0)
|
||||
return -1;
|
||||
else if (diff > 0)
|
||||
return 1;
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
cairo_status_t
|
||||
_cairo_pen_add_points (cairo_pen_t *pen, XPointFixed *pt, int num_pts)
|
||||
_cairo_pen_add_points (cairo_pen_t *pen, cairo_point_t *pt, int num_pts)
|
||||
{
|
||||
int i, j;
|
||||
int i;
|
||||
cairo_pen_vertex_t *v, *v_next, *new_vertex;
|
||||
|
||||
pen->num_vertices += num_pts;
|
||||
|
|
@ -162,21 +134,18 @@ _cairo_pen_add_points (cairo_pen_t *pen, XPointFixed *pt, int num_pts)
|
|||
for (i=0; i < num_pts; i++) {
|
||||
v = &pen->vertex[pen->num_vertices-(i+1)];
|
||||
v->pt = pt[i];
|
||||
v->theta = atan2 (v->pt.y, v->pt.x);
|
||||
if (v->theta < 0)
|
||||
v->theta += 2 * M_PI;
|
||||
}
|
||||
|
||||
qsort (pen->vertex, pen->num_vertices, sizeof (cairo_pen_vertex_t), _cairo_pen_vertex_compare_by_theta);
|
||||
qsort (pen->vertex, pen->num_vertices, sizeof (cairo_pen_vertex_t), _pen_vertex_compare);
|
||||
|
||||
/* eliminate any duplicate vertices */
|
||||
for (i=0; i < pen->num_vertices - 1; i++ ) {
|
||||
for (i=0; i < pen->num_vertices; i++ ) {
|
||||
v = &pen->vertex[i];
|
||||
v_next = &pen->vertex[i+1];
|
||||
if (v->pt.x == v_next->pt.x && v->pt.y == v_next->pt.y) {
|
||||
for (j=i+1; j < pen->num_vertices - 1; j++)
|
||||
pen->vertex[j] = pen->vertex[j+1];
|
||||
v_next = (i < pen->num_vertices - 1) ? &pen->vertex[i+1] : &pen->vertex[0];
|
||||
if (_pen_vertex_compare (v, v_next) == 0) {
|
||||
pen->num_vertices--;
|
||||
memmove (&pen->vertex[i], &pen->vertex[i+1],
|
||||
(pen->num_vertices - i) * sizeof (cairo_pen_vertex_t));
|
||||
/* There may be more of the same duplicate, check again */
|
||||
i--;
|
||||
}
|
||||
|
|
@ -219,34 +188,53 @@ _cairo_pen_compute_slopes (cairo_pen_t *pen)
|
|||
v = &pen->vertex[i];
|
||||
next = &pen->vertex[(i + 1) % pen->num_vertices];
|
||||
|
||||
_compute_slope (&prev->pt, &v->pt, &v->slope_cw);
|
||||
_compute_slope (&v->pt, &next->pt, &v->slope_ccw);
|
||||
_cairo_slope_init (&v->slope_cw, &prev->pt, &v->pt);
|
||||
_cairo_slope_init (&v->slope_ccw, &v->pt, &next->pt);
|
||||
}
|
||||
}
|
||||
|
||||
/* Is a clockwise of b?
|
||||
/* Is a further clockwise from (1,0) than b?
|
||||
*
|
||||
* NOTE: The strict equality here is not significant in and of itself,
|
||||
* but there are functions up above that are sensitive to it,
|
||||
* (cf. _cairo_pen_find_active_cw_vertex_index).
|
||||
* There are a two special cases to consider:
|
||||
* 1) a and b are not in the same half plane.
|
||||
* 2) both a and b are on the X axis
|
||||
* After that, the computation is a simple slope comparison.
|
||||
*/
|
||||
static int
|
||||
_slope_clockwise (cairo_slope_fixed_t *a, cairo_slope_fixed_t *b)
|
||||
_pen_vertex_compare (const void *av, const void *bv)
|
||||
{
|
||||
return ((cairo_fixed_48_16_t) b->dy * (cairo_fixed_48_16_t) a->dx
|
||||
> (cairo_fixed_48_16_t) a->dy * (cairo_fixed_48_16_t) b->dx);
|
||||
}
|
||||
const cairo_pen_vertex_t *a = av;
|
||||
const cairo_pen_vertex_t *b = bv;
|
||||
cairo_fixed_48_16_t diff;
|
||||
|
||||
static int
|
||||
_slope_counter_clockwise (cairo_slope_fixed_t *a, cairo_slope_fixed_t *b)
|
||||
{
|
||||
return ! _slope_clockwise (a, b);
|
||||
int a_above = a->pt.y >= 0;
|
||||
int b_above = b->pt.y >= 0;
|
||||
|
||||
if (a_above != b_above)
|
||||
return b_above - a_above;
|
||||
|
||||
if (a->pt.y == 0 && b->pt.y == 0) {
|
||||
int a_right = a->pt.x >= 0;
|
||||
int b_right = b->pt.x >= 0;
|
||||
|
||||
if (a_right != b_right)
|
||||
return b_right - a_right;
|
||||
}
|
||||
|
||||
diff = ((cairo_fixed_48_16_t) a->pt.y * (cairo_fixed_48_16_t) b->pt.x
|
||||
- (cairo_fixed_48_16_t) b->pt.y * (cairo_fixed_48_16_t) a->pt.x);
|
||||
|
||||
if (diff > 0)
|
||||
return 1;
|
||||
if (diff < 0)
|
||||
return -1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Find active pen vertex for clockwise edge of stroke at the given slope.
|
||||
*
|
||||
* NOTE: The behavior of this function is sensitive to the sense of
|
||||
* the inequality within _slope_clockwise/_slope_counter_clockwise.
|
||||
* the inequality within _cairo_slope_clockwise/_cairo_slope_counter_clockwise.
|
||||
*
|
||||
* The issue is that the slope_ccw member of one pen vertex will be
|
||||
* equivalent to the slope_cw member of the next pen vertex in a
|
||||
|
|
@ -255,14 +243,14 @@ _slope_counter_clockwise (cairo_slope_fixed_t *a, cairo_slope_fixed_t *b)
|
|||
*/
|
||||
cairo_status_t
|
||||
_cairo_pen_find_active_cw_vertex_index (cairo_pen_t *pen,
|
||||
cairo_slope_fixed_t *slope,
|
||||
cairo_slope_t *slope,
|
||||
int *active)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i=0; i < pen->num_vertices; i++) {
|
||||
if (_slope_clockwise (slope, &pen->vertex[i].slope_ccw)
|
||||
&& _slope_counter_clockwise (slope, &pen->vertex[i].slope_cw))
|
||||
if (_cairo_slope_clockwise (slope, &pen->vertex[i].slope_ccw)
|
||||
&& _cairo_slope_counter_clockwise (slope, &pen->vertex[i].slope_cw))
|
||||
break;
|
||||
}
|
||||
|
||||
|
|
@ -274,23 +262,23 @@ _cairo_pen_find_active_cw_vertex_index (cairo_pen_t *pen,
|
|||
/* Find active pen vertex for counterclockwise edge of stroke at the given slope.
|
||||
*
|
||||
* NOTE: The behavior of this function is sensitive to the sense of
|
||||
* the inequality within _slope_clockwise/_slope_counter_clockwise.
|
||||
* the inequality within _cairo_slope_clockwise/_cairo_slope_counter_clockwise.
|
||||
*/
|
||||
cairo_status_t
|
||||
_cairo_pen_find_active_ccw_vertex_index (cairo_pen_t *pen,
|
||||
cairo_slope_fixed_t *slope,
|
||||
cairo_slope_t *slope,
|
||||
int *active)
|
||||
{
|
||||
int i;
|
||||
cairo_slope_fixed_t slope_reverse;
|
||||
cairo_slope_t slope_reverse;
|
||||
|
||||
slope_reverse = *slope;
|
||||
slope_reverse.dx = -slope_reverse.dx;
|
||||
slope_reverse.dy = -slope_reverse.dy;
|
||||
|
||||
for (i=pen->num_vertices-1; i >= 0; i--) {
|
||||
if (_slope_counter_clockwise (&pen->vertex[i].slope_ccw, &slope_reverse)
|
||||
&& _slope_clockwise (&pen->vertex[i].slope_cw, &slope_reverse))
|
||||
if (_cairo_slope_counter_clockwise (&pen->vertex[i].slope_ccw, &slope_reverse)
|
||||
&& _cairo_slope_clockwise (&pen->vertex[i].slope_cw, &slope_reverse))
|
||||
break;
|
||||
}
|
||||
|
||||
|
|
@ -309,9 +297,9 @@ _cairo_pen_stroke_spline_half (cairo_pen_t *pen,
|
|||
cairo_status_t status;
|
||||
int start, stop, step;
|
||||
int active = 0;
|
||||
XPointFixed hull_pt;
|
||||
cairo_slope_fixed_t slope, initial_slope, final_slope;
|
||||
XPointFixed *pt = spline->pts;
|
||||
cairo_point_t hull_pt;
|
||||
cairo_slope_t slope, initial_slope, final_slope;
|
||||
cairo_point_t *pt = spline->pts;
|
||||
int num_pts = spline->num_pts;
|
||||
|
||||
if (dir == cairo_pen_stroke_direction_forward) {
|
||||
|
|
@ -345,11 +333,11 @@ _cairo_pen_stroke_spline_half (cairo_pen_t *pen,
|
|||
if (i + step == stop)
|
||||
slope = final_slope;
|
||||
else
|
||||
_compute_slope (&pt[i], &pt[i+step], &slope);
|
||||
if (_slope_counter_clockwise (&slope, &pen->vertex[active].slope_ccw)) {
|
||||
_cairo_slope_init (&slope, &pt[i], &pt[i+step]);
|
||||
if (_cairo_slope_counter_clockwise (&slope, &pen->vertex[active].slope_ccw)) {
|
||||
if (++active == pen->num_vertices)
|
||||
active = 0;
|
||||
} else if (_slope_clockwise (&slope, &pen->vertex[active].slope_cw)) {
|
||||
} else if (_cairo_slope_clockwise (&slope, &pen->vertex[active].slope_cw)) {
|
||||
if (--active == -1)
|
||||
active = pen->num_vertices - 1;
|
||||
} else {
|
||||
|
|
|
|||
|
|
@ -36,8 +36,7 @@ static cairo_status_t
|
|||
_cairo_polygon_grow_by (cairo_polygon_t *polygon, int additional);
|
||||
|
||||
static void
|
||||
_cairo_polygon_set_last_point (cairo_polygon_t *polygon, XPointFixed *pt);
|
||||
|
||||
_cairo_polygon_set_last_point (cairo_polygon_t *polygon, cairo_point_t *pt);
|
||||
|
||||
void
|
||||
_cairo_polygon_init (cairo_polygon_t *polygon)
|
||||
|
|
@ -94,14 +93,14 @@ _cairo_polygon_grow_by (cairo_polygon_t *polygon, int additional)
|
|||
}
|
||||
|
||||
static void
|
||||
_cairo_polygon_set_last_point (cairo_polygon_t *polygon, XPointFixed *pt)
|
||||
_cairo_polygon_set_last_point (cairo_polygon_t *polygon, cairo_point_t *pt)
|
||||
{
|
||||
polygon->last_pt = *pt;
|
||||
polygon->last_pt_defined = 1;
|
||||
}
|
||||
|
||||
cairo_status_t
|
||||
_cairo_polygon_add_edge (cairo_polygon_t *polygon, XPointFixed *p1, XPointFixed *p2)
|
||||
_cairo_polygon_add_edge (cairo_polygon_t *polygon, cairo_point_t *p1, cairo_point_t *p2)
|
||||
{
|
||||
cairo_status_t status;
|
||||
cairo_edge_t *edge;
|
||||
|
|
@ -144,7 +143,7 @@ _cairo_polygon_add_edge (cairo_polygon_t *polygon, XPointFixed *p1, XPointFixed
|
|||
}
|
||||
|
||||
cairo_status_t
|
||||
_cairo_polygon_add_point (cairo_polygon_t *polygon, XPointFixed *pt)
|
||||
_cairo_polygon_add_point (cairo_polygon_t *polygon, cairo_point_t *pt)
|
||||
{
|
||||
cairo_status_t status = CAIRO_STATUS_SUCCESS;
|
||||
|
||||
|
|
|
|||
58
src/cairo_slope.c
Normal file
58
src/cairo_slope.c
Normal file
|
|
@ -0,0 +1,58 @@
|
|||
/*
|
||||
* Copyright © 2002 USC, Information Sciences Institute
|
||||
*
|
||||
* 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 the
|
||||
* University of Southern California not be used in advertising or
|
||||
* publicity pertaining to distribution of the software without
|
||||
* specific, written prior permission. The University of Southern
|
||||
* California makes no representations about the suitability of this
|
||||
* software for any purpose. It is provided "as is" without express
|
||||
* or implied warranty.
|
||||
*
|
||||
* THE UNIVERSITY OF SOUTHERN CALIFORNIA DISCLAIMS ALL WARRANTIES WITH
|
||||
* REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL THE UNIVERSITY OF
|
||||
* SOUTHERN CALIFORNIA 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.
|
||||
*
|
||||
* Author: Carl D. Worth <cworth@isi.edu>
|
||||
*/
|
||||
|
||||
#include "cairoint.h"
|
||||
|
||||
void
|
||||
_cairo_slope_init (cairo_slope_t *slope, cairo_point_t *a, cairo_point_t *b)
|
||||
{
|
||||
slope->dx = b->x - a->x;
|
||||
slope->dy = b->y - a->y;
|
||||
}
|
||||
|
||||
/* Is a clockwise of b?
|
||||
*
|
||||
* NOTE: The strict equality here is not significant in and of itself,
|
||||
* but there are functions up above that are sensitive to it,
|
||||
* (cf. _cairo_pen_find_active_cw_vertex_index).
|
||||
*/
|
||||
int
|
||||
_cairo_slope_clockwise (cairo_slope_t *a, cairo_slope_t *b)
|
||||
{
|
||||
return ((cairo_fixed_48_16_t) b->dy * (cairo_fixed_48_16_t) a->dx
|
||||
> (cairo_fixed_48_16_t) a->dy * (cairo_fixed_48_16_t) b->dx);
|
||||
}
|
||||
|
||||
int
|
||||
_cairo_slope_counter_clockwise (cairo_slope_t *a, cairo_slope_t *b)
|
||||
{
|
||||
return ! _cairo_slope_clockwise (a, b);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
@ -31,10 +31,10 @@ static cairo_status_t
|
|||
_cairo_spline_grow_by (cairo_spline_t *spline, int additional);
|
||||
|
||||
static cairo_status_t
|
||||
_cairo_spline_add_point (cairo_spline_t *spline, XPointFixed *pt);
|
||||
_cairo_spline_add_point (cairo_spline_t *spline, cairo_point_t *pt);
|
||||
|
||||
static void
|
||||
_lerp_half (XPointFixed *a, XPointFixed *b, XPointFixed *result);
|
||||
_lerp_half (cairo_point_t *a, cairo_point_t *b, cairo_point_t *result);
|
||||
|
||||
static void
|
||||
_de_casteljau (cairo_spline_t *spline, cairo_spline_t *s1, cairo_spline_t *s2);
|
||||
|
|
@ -48,7 +48,9 @@ _cairo_spline_decompose_into (cairo_spline_t *spline, double tolerance_squared,
|
|||
#define CAIRO_SPLINE_GROWTH_INC 100
|
||||
|
||||
cairo_int_status_t
|
||||
_cairo_spline_init (cairo_spline_t *spline, XPointFixed *a, XPointFixed *b, XPointFixed *c, XPointFixed *d)
|
||||
_cairo_spline_init (cairo_spline_t *spline,
|
||||
cairo_point_t *a, cairo_point_t *b,
|
||||
cairo_point_t *c, cairo_point_t *d)
|
||||
{
|
||||
spline->a = *a;
|
||||
spline->b = *b;
|
||||
|
|
@ -56,21 +58,21 @@ _cairo_spline_init (cairo_spline_t *spline, XPointFixed *a, XPointFixed *b, XP
|
|||
spline->d = *d;
|
||||
|
||||
if (a->x != b->x || a->y != b->y) {
|
||||
_compute_slope (&spline->a, &spline->b, &spline->initial_slope);
|
||||
_cairo_slope_init (&spline->initial_slope, &spline->a, &spline->b);
|
||||
} else if (a->x != c->x || a->y != c->y) {
|
||||
_compute_slope (&spline->a, &spline->c, &spline->initial_slope);
|
||||
_cairo_slope_init (&spline->initial_slope, &spline->a, &spline->c);
|
||||
} else if (a->x != d->x || a->y != d->y) {
|
||||
_compute_slope (&spline->a, &spline->d, &spline->initial_slope);
|
||||
_cairo_slope_init (&spline->initial_slope, &spline->a, &spline->d);
|
||||
} else {
|
||||
return cairo_int_status_degenerate;
|
||||
}
|
||||
|
||||
if (c->x != d->x || c->y != d->y) {
|
||||
_compute_slope (&spline->c, &spline->d, &spline->final_slope);
|
||||
_cairo_slope_init (&spline->final_slope, &spline->c, &spline->d);
|
||||
} else if (b->x != d->x || b->y != d->y) {
|
||||
_compute_slope (&spline->b, &spline->d, &spline->final_slope);
|
||||
_cairo_slope_init (&spline->final_slope, &spline->b, &spline->d);
|
||||
} else {
|
||||
_compute_slope (&spline->a, &spline->d, &spline->final_slope);
|
||||
_cairo_slope_init (&spline->final_slope, &spline->a, &spline->d);
|
||||
}
|
||||
|
||||
spline->num_pts = 0;
|
||||
|
|
@ -92,7 +94,7 @@ _cairo_spline_fini (cairo_spline_t *spline)
|
|||
static cairo_status_t
|
||||
_cairo_spline_grow_by (cairo_spline_t *spline, int additional)
|
||||
{
|
||||
XPointFixed *new_pts;
|
||||
cairo_point_t *new_pts;
|
||||
int old_size = spline->pts_size;
|
||||
int new_size = spline->num_pts + additional;
|
||||
|
||||
|
|
@ -100,7 +102,7 @@ _cairo_spline_grow_by (cairo_spline_t *spline, int additional)
|
|||
return CAIRO_STATUS_SUCCESS;
|
||||
|
||||
spline->pts_size = new_size;
|
||||
new_pts = realloc (spline->pts, spline->pts_size * sizeof (XPointFixed));
|
||||
new_pts = realloc (spline->pts, spline->pts_size * sizeof (cairo_point_t));
|
||||
|
||||
if (new_pts == NULL) {
|
||||
spline->pts_size = old_size;
|
||||
|
|
@ -113,7 +115,7 @@ _cairo_spline_grow_by (cairo_spline_t *spline, int additional)
|
|||
}
|
||||
|
||||
static cairo_status_t
|
||||
_cairo_spline_add_point (cairo_spline_t *spline, XPointFixed *pt)
|
||||
_cairo_spline_add_point (cairo_spline_t *spline, cairo_point_t *pt)
|
||||
{
|
||||
cairo_status_t status;
|
||||
|
||||
|
|
@ -130,7 +132,7 @@ _cairo_spline_add_point (cairo_spline_t *spline, XPointFixed *pt)
|
|||
}
|
||||
|
||||
static void
|
||||
_lerp_half (XPointFixed *a, XPointFixed *b, XPointFixed *result)
|
||||
_lerp_half (cairo_point_t *a, cairo_point_t *b, cairo_point_t *result)
|
||||
{
|
||||
result->x = a->x + ((b->x - a->x) >> 1);
|
||||
result->y = a->y + ((b->y - a->y) >> 1);
|
||||
|
|
@ -139,9 +141,9 @@ _lerp_half (XPointFixed *a, XPointFixed *b, XPointFixed *result)
|
|||
static void
|
||||
_de_casteljau (cairo_spline_t *spline, cairo_spline_t *s1, cairo_spline_t *s2)
|
||||
{
|
||||
XPointFixed ab, bc, cd;
|
||||
XPointFixed abbc, bccd;
|
||||
XPointFixed final;
|
||||
cairo_point_t ab, bc, cd;
|
||||
cairo_point_t abbc, bccd;
|
||||
cairo_point_t final;
|
||||
|
||||
_lerp_half (&spline->a, &spline->b, &ab);
|
||||
_lerp_half (&spline->b, &spline->c, &bc);
|
||||
|
|
@ -162,7 +164,7 @@ _de_casteljau (cairo_spline_t *spline, cairo_spline_t *s1, cairo_spline_t *s2)
|
|||
}
|
||||
|
||||
static double
|
||||
_PointDistanceSquaredToPoint (XPointFixed *a, XPointFixed *b)
|
||||
_PointDistanceSquaredToPoint (cairo_point_t *a, cairo_point_t *b)
|
||||
{
|
||||
double dx = XFixedToDouble (b->x - a->x);
|
||||
double dy = XFixedToDouble (b->y - a->y);
|
||||
|
|
@ -171,12 +173,12 @@ _PointDistanceSquaredToPoint (XPointFixed *a, XPointFixed *b)
|
|||
}
|
||||
|
||||
static double
|
||||
_PointDistanceSquaredToSegment (XPointFixed *p, XPointFixed *p1, XPointFixed *p2)
|
||||
_PointDistanceSquaredToSegment (cairo_point_t *p, cairo_point_t *p1, cairo_point_t *p2)
|
||||
{
|
||||
double u;
|
||||
double dx, dy;
|
||||
double pdx, pdy;
|
||||
XPointFixed px;
|
||||
cairo_point_t px;
|
||||
|
||||
/* intersection point (px):
|
||||
|
||||
|
|
|
|||
|
|
@ -29,6 +29,34 @@
|
|||
|
||||
#include "cairoint.h"
|
||||
|
||||
static const XTransform CAIRO_XTRANSFORM_IDENTITY = {
|
||||
{
|
||||
{65536, 0, 0},
|
||||
{ 0, 65536, 0},
|
||||
{ 0, 0, 65536}
|
||||
}
|
||||
};
|
||||
|
||||
#define CAIRO_SURFACE_RENDER_AT_LEAST(surface, major, minor) \
|
||||
(((surface)->render_major > major) ? 1 \
|
||||
: ((surface)->render_major == major) ? ((surface)->render_minor >= minor) : 0)
|
||||
|
||||
#define CAIRO_SURFACE_RENDER_HAS_CREATE_PICTURE(surface) CAIRO_SURFACE_RENDER_AT_LEAST((surface), 0, 0)
|
||||
#define CAIRO_SURFACE_RENDER_HAS_COMPOSITE(surface) CAIRO_SURFACE_RENDER_AT_LEAST((surface), 0, 0)
|
||||
|
||||
#define CAIRO_SURFACE_RENDER_HAS_FILL_RECTANGLE(surface) CAIRO_SURFACE_RENDER_AT_LEAST((surface), 0, 1)
|
||||
#define CAIRO_SURFACE_RENDER_HAS_FILL_RECTANGLES(surface) CAIRO_SURFACE_RENDER_AT_LEAST((surface), 0, 1)
|
||||
|
||||
#define CAIRO_SURFACE_RENDER_HAS_DISJOINT(surface) CAIRO_SURFACE_RENDER_AT_LEAST((surface), 0, 2)
|
||||
#define CAIRO_SURFACE_RENDER_HAS_CONJOINT(surface) CAIRO_SURFACE_RENDER_AT_LEAST((surface), 0, 2)
|
||||
|
||||
#define CAIRO_SURFACE_RENDER_HAS_TRAPEZOIDS(surface) CAIRO_SURFACE_RENDER_AT_LEAST((surface), 0, 4)
|
||||
#define CAIRO_SURFACE_RENDER_HAS_TRIANGLES(surface) CAIRO_SURFACE_RENDER_AT_LEAST((surface), 0, 4)
|
||||
#define CAIRO_SURFACE_RENDER_HAS_TRISTRIP(surface) CAIRO_SURFACE_RENDER_AT_LEAST((surface), 0, 4)
|
||||
#define CAIRO_SURFACE_RENDER_HAS_TRIFAN(surface) CAIRO_SURFACE_RENDER_AT_LEAST((surface), 0, 4)
|
||||
|
||||
#define CAIRO_SURFACE_RENDER_HAS_PICTURE_TRANSFORM(surface) CAIRO_SURFACE_RENDER_AT_LEAST((surface), 0, 6)
|
||||
|
||||
cairo_surface_t *
|
||||
cairo_surface_create_for_drawable (Display *dpy,
|
||||
Drawable drawable,
|
||||
|
|
@ -42,20 +70,35 @@ cairo_surface_create_for_drawable (Display *dpy,
|
|||
if (surface == NULL)
|
||||
return NULL;
|
||||
|
||||
surface->dpy = dpy;
|
||||
surface->image_data = NULL;
|
||||
|
||||
surface->xc_surface = XcSurfaceCreateForDrawable (dpy, drawable, visual, format, colormap);
|
||||
if (surface->xc_surface == NULL) {
|
||||
free (surface);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* XXX: We should really get this value from somewhere like Xft.dpy */
|
||||
surface->ppm = 3780;
|
||||
|
||||
surface->ref_count = 1;
|
||||
|
||||
surface->dpy = dpy;
|
||||
surface->image_data = NULL;
|
||||
surface->icimage = NULL;
|
||||
|
||||
surface->type = CAIRO_SURFACE_TYPE_DRAWABLE;
|
||||
surface->xtransform = CAIRO_XTRANSFORM_IDENTITY;
|
||||
|
||||
surface->gc = 0;
|
||||
surface->drawable = drawable;
|
||||
surface->visual = visual;
|
||||
|
||||
if (! XRenderQueryVersion (dpy, &surface->render_major, &surface->render_minor)) {
|
||||
surface->render_major = -1;
|
||||
surface->render_minor = -1;
|
||||
}
|
||||
|
||||
/* XXX: I'm currently ignoring the colormap. Is that bad? */
|
||||
if (CAIRO_SURFACE_RENDER_HAS_CREATE_PICTURE (surface))
|
||||
surface->picture = XRenderCreatePicture (dpy, drawable,
|
||||
visual
|
||||
? XRenderFindVisualFormat (dpy, visual)
|
||||
: XRenderFindStandardFormat (dpy, format),
|
||||
0, NULL);
|
||||
|
||||
return surface;
|
||||
}
|
||||
|
||||
|
|
@ -144,25 +187,31 @@ cairo_surface_create_for_image (char *data,
|
|||
if (surface == NULL)
|
||||
return NULL;
|
||||
|
||||
/* Assume a default until the user lets us know otherwise */
|
||||
surface->ppm = 3780;
|
||||
surface->ref_count = 1;
|
||||
|
||||
surface->dpy = NULL;
|
||||
surface->image_data = NULL;
|
||||
|
||||
image = IcImageCreateForData ((IcBits *) data, &icformat, width, height, cairo_format_bpp (format), stride);
|
||||
if (image == NULL) {
|
||||
free (surface);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
surface->xc_surface = XcSurfaceCreateForIcImage (image);
|
||||
if (surface->xc_surface == NULL) {
|
||||
IcImageDestroy (image);
|
||||
free (surface);
|
||||
return NULL;
|
||||
}
|
||||
surface->type = CAIRO_SURFACE_TYPE_ICIMAGE;
|
||||
surface->xtransform = CAIRO_XTRANSFORM_IDENTITY;
|
||||
|
||||
/* Assume a default until the user lets us know otherwise */
|
||||
surface->ppm = 3780;
|
||||
surface->gc = 0;
|
||||
surface->drawable = 0;
|
||||
surface->visual = NULL;
|
||||
surface->render_major = -1;
|
||||
surface->render_minor = -1;
|
||||
|
||||
surface->ref_count = 1;
|
||||
surface->picture = 0;
|
||||
|
||||
surface->icimage = image;
|
||||
|
||||
return surface;
|
||||
}
|
||||
|
|
@ -205,8 +254,6 @@ cairo_surface_create_similar_solid (cairo_surface_t *other,
|
|||
cairo_surface_t *surface = NULL;
|
||||
cairo_color_t color;
|
||||
|
||||
/* XXX: create_similar should perhaps move down to Xc, (then we
|
||||
could drop xrsurface->dpy as well) */
|
||||
if (other->dpy) {
|
||||
Display *dpy = other->dpy;
|
||||
int scr = DefaultScreen (dpy);
|
||||
|
|
@ -270,32 +317,130 @@ cairo_surface_destroy (cairo_surface_t *surface)
|
|||
if (surface->ref_count)
|
||||
return;
|
||||
|
||||
surface->dpy = 0;
|
||||
|
||||
XcSurfaceDestroy (surface->xc_surface);
|
||||
surface->xc_surface = NULL;
|
||||
if (surface->picture)
|
||||
XRenderFreePicture (surface->dpy, surface->picture);
|
||||
|
||||
if (surface->icimage)
|
||||
IcImageDestroy (surface->icimage);
|
||||
|
||||
if (surface->image_data)
|
||||
free (surface->image_data);
|
||||
surface->image_data = NULL;
|
||||
|
||||
surface->dpy = 0;
|
||||
|
||||
free (surface);
|
||||
}
|
||||
|
||||
static void
|
||||
_cairo_surface_ensure_gc (cairo_surface_t *surface)
|
||||
{
|
||||
if (surface->gc)
|
||||
return;
|
||||
|
||||
surface->gc = XCreateGC (surface->dpy, surface->drawable, 0, NULL);
|
||||
}
|
||||
|
||||
cairo_status_t
|
||||
cairo_surface_put_image (cairo_surface_t *surface,
|
||||
char *data,
|
||||
int width,
|
||||
int height,
|
||||
int stride)
|
||||
char *data,
|
||||
int width,
|
||||
int height,
|
||||
int stride)
|
||||
{
|
||||
XcSurfacePutImage (surface->xc_surface, data,
|
||||
width, height, stride);
|
||||
if (surface->picture) {
|
||||
XImage *image;
|
||||
unsigned bitmap_pad;
|
||||
|
||||
/* XXX: This is obviously bogus. depth needs to be figured out for real */
|
||||
int depth = 32;
|
||||
|
||||
if (depth > 16)
|
||||
bitmap_pad = 32;
|
||||
else if (depth > 8)
|
||||
bitmap_pad = 16;
|
||||
else
|
||||
bitmap_pad = 8;
|
||||
|
||||
image = XCreateImage(surface->dpy,
|
||||
DefaultVisual(surface->dpy, DefaultScreen(surface->dpy)),
|
||||
depth, ZPixmap, 0,
|
||||
data, width, height,
|
||||
bitmap_pad,
|
||||
stride);
|
||||
if (image == NULL)
|
||||
return CAIRO_STATUS_NO_MEMORY;
|
||||
|
||||
_cairo_surface_ensure_gc (surface);
|
||||
XPutImage(surface->dpy, surface->drawable, surface->gc,
|
||||
image, 0, 0, 0, 0, width, height);
|
||||
|
||||
/* Foolish XDestroyImage thinks it can free my data, but I won't
|
||||
stand for it. */
|
||||
image->data = NULL;
|
||||
XDestroyImage(image);
|
||||
} else {
|
||||
/* XXX: Need to implement the IcImage method of setting a picture. memcpy? */
|
||||
}
|
||||
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
/* XXX: Symmetry demands an cairo_surface_get_image as well */
|
||||
/* XXX: Symmetry demands an cairo_surface_get_image as well. */
|
||||
|
||||
void
|
||||
_cairo_surface_pull_image (cairo_surface_t *surface)
|
||||
{
|
||||
/* XXX: NYI (Also needs support for pictures with external alpha.)
|
||||
if (surface->type == CAIRO_SURFACE_TYPE_ICIMAGE)
|
||||
return;
|
||||
|
||||
if (surface->icimage) {
|
||||
IcImageDestroy (surface->icimage);
|
||||
surface->icimage = NULL;
|
||||
}
|
||||
|
||||
_cairo_surface_ensure_GC (surface);
|
||||
surface->ximage = XGetImage (surface->dpy,
|
||||
surface->drawable,
|
||||
surface->gc,
|
||||
0, 0,
|
||||
width, height,
|
||||
AllPlanes, ZPixmap);
|
||||
|
||||
surface->icimage = IcImageCreateForData (image->data,
|
||||
IcFormat *format,
|
||||
int width, int height,
|
||||
int bpp, int stride);
|
||||
*/
|
||||
}
|
||||
|
||||
void
|
||||
_cairo_surface_push_image (cairo_surface_t *surface)
|
||||
{
|
||||
/* XXX: NYI
|
||||
if (surface->type == CAIRO_SURFACE_TYPE_ICIMAGE)
|
||||
return;
|
||||
|
||||
if (surface->ximage == NULL)
|
||||
return;
|
||||
|
||||
_cairo_surface_ensure_GC (surface);
|
||||
XPutImage (surface->dpy,
|
||||
surface->drawable,
|
||||
surface->gc,
|
||||
surface->ximage,
|
||||
0, 0,
|
||||
0, 0,
|
||||
width, height);
|
||||
|
||||
* Foolish XDestroyImage thinks it can free my data, but I won't
|
||||
stand for it. *
|
||||
surface->ximage->data = NULL;
|
||||
XDestroyImage(surface->ximage);
|
||||
surface->ximage = NULL;
|
||||
*/
|
||||
}
|
||||
|
||||
/* XXX: We may want to move to projective matrices at some point. If
|
||||
nothing else, that would eliminate the two different transform data
|
||||
|
|
@ -303,22 +448,31 @@ cairo_surface_put_image (cairo_surface_t *surface,
|
|||
cairo_status_t
|
||||
cairo_surface_set_matrix (cairo_surface_t *surface, cairo_matrix_t *matrix)
|
||||
{
|
||||
XTransform xtransform;
|
||||
XTransform *xtransform = &surface->xtransform;
|
||||
|
||||
xtransform.matrix[0][0] = XDoubleToFixed (matrix->m[0][0]);
|
||||
xtransform.matrix[0][1] = XDoubleToFixed (matrix->m[1][0]);
|
||||
xtransform.matrix[0][2] = XDoubleToFixed (matrix->m[2][0]);
|
||||
xtransform->matrix[0][0] = XDoubleToFixed (matrix->m[0][0]);
|
||||
xtransform->matrix[0][1] = XDoubleToFixed (matrix->m[1][0]);
|
||||
xtransform->matrix[0][2] = XDoubleToFixed (matrix->m[2][0]);
|
||||
|
||||
xtransform.matrix[1][0] = XDoubleToFixed (matrix->m[0][1]);
|
||||
xtransform.matrix[1][1] = XDoubleToFixed (matrix->m[1][1]);
|
||||
xtransform.matrix[1][2] = XDoubleToFixed (matrix->m[2][1]);
|
||||
xtransform->matrix[1][0] = XDoubleToFixed (matrix->m[0][1]);
|
||||
xtransform->matrix[1][1] = XDoubleToFixed (matrix->m[1][1]);
|
||||
xtransform->matrix[1][2] = XDoubleToFixed (matrix->m[2][1]);
|
||||
|
||||
xtransform.matrix[2][0] = 0;
|
||||
xtransform.matrix[2][1] = 0;
|
||||
xtransform.matrix[2][2] = XDoubleToFixed (1);
|
||||
xtransform->matrix[2][0] = 0;
|
||||
xtransform->matrix[2][1] = 0;
|
||||
xtransform->matrix[2][2] = XDoubleToFixed (1);
|
||||
|
||||
XcSurfaceSetTransform (surface->xc_surface,
|
||||
&xtransform);
|
||||
if (surface->picture) {
|
||||
if (CAIRO_SURFACE_RENDER_HAS_PICTURE_TRANSFORM (surface))
|
||||
XRenderSetPictureTransform (surface->dpy, surface->picture, xtransform);
|
||||
/* XXX: Need support here if using an old RENDER without support
|
||||
for SetPictureTransform */
|
||||
}
|
||||
|
||||
/* XXX: This cast should only occur with a #define hint from libic that it is OK */
|
||||
if (surface->icimage) {
|
||||
IcImageSetTransform (surface->icimage, (IcTransform *) xtransform);
|
||||
}
|
||||
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
}
|
||||
|
|
@ -326,51 +480,134 @@ cairo_surface_set_matrix (cairo_surface_t *surface, cairo_matrix_t *matrix)
|
|||
cairo_status_t
|
||||
cairo_surface_get_matrix (cairo_surface_t *surface, cairo_matrix_t *matrix)
|
||||
{
|
||||
XTransform xtransform;
|
||||
XTransform *xtransform = &surface->xtransform;
|
||||
|
||||
XcSurfaceGetTransform (surface->xc_surface, &xtransform);
|
||||
matrix->m[0][0] = XFixedToDouble (xtransform->matrix[0][0]);
|
||||
matrix->m[1][0] = XFixedToDouble (xtransform->matrix[0][1]);
|
||||
matrix->m[2][0] = XFixedToDouble (xtransform->matrix[0][2]);
|
||||
|
||||
matrix->m[0][0] = XFixedToDouble (xtransform.matrix[0][0]);
|
||||
matrix->m[1][0] = XFixedToDouble (xtransform.matrix[0][1]);
|
||||
matrix->m[2][0] = XFixedToDouble (xtransform.matrix[0][2]);
|
||||
|
||||
matrix->m[0][1] = XFixedToDouble (xtransform.matrix[1][0]);
|
||||
matrix->m[1][1] = XFixedToDouble (xtransform.matrix[1][1]);
|
||||
matrix->m[2][1] = XFixedToDouble (xtransform.matrix[1][2]);
|
||||
matrix->m[0][1] = XFixedToDouble (xtransform->matrix[1][0]);
|
||||
matrix->m[1][1] = XFixedToDouble (xtransform->matrix[1][1]);
|
||||
matrix->m[2][1] = XFixedToDouble (xtransform->matrix[1][2]);
|
||||
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
/* XXX: The Render specification has capitalized versions of these
|
||||
strings. However, the current implementation is case-sensitive and
|
||||
expects lowercase versions. */
|
||||
static char *
|
||||
_render_filter_name (cairo_filter_t filter)
|
||||
{
|
||||
switch (filter) {
|
||||
case CAIRO_FILTER_FAST:
|
||||
return "fast";
|
||||
case CAIRO_FILTER_GOOD:
|
||||
return "good";
|
||||
case CAIRO_FILTER_BEST:
|
||||
return "best";
|
||||
case CAIRO_FILTER_NEAREST:
|
||||
return "nearest";
|
||||
case CAIRO_FILTER_BILINEAR:
|
||||
return "bilinear";
|
||||
default:
|
||||
return "best";
|
||||
}
|
||||
}
|
||||
|
||||
cairo_status_t
|
||||
cairo_surface_set_filter (cairo_surface_t *surface, cairo_filter_t filter)
|
||||
{
|
||||
XcSurfaceSetFilter (surface->xc_surface, filter);
|
||||
if (surface->picture) {
|
||||
XRenderSetPictureFilter (surface->dpy, surface->picture,
|
||||
_render_filter_name (filter), NULL, 0);
|
||||
}
|
||||
|
||||
if (surface->icimage) {
|
||||
IcImageSetFilter (surface->icimage, filter);
|
||||
}
|
||||
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
/* XXX: The Xc version of this function isn't quite working yet
|
||||
/* XXX: NYI
|
||||
cairo_status_t
|
||||
cairo_surface_set_clip_region (cairo_surface_t *surface, Region region)
|
||||
cairo_surface_clip_rectangle (cairo_surface_t *surface,
|
||||
int x, int y,
|
||||
int width, int height)
|
||||
{
|
||||
XcSurfaceSetClipRegion (surface->xc_surface, region);
|
||||
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
}
|
||||
*/
|
||||
|
||||
/* XXX: NYI
|
||||
cairo_status_t
|
||||
cairo_surface_clip_restore (cairo_surface_t *surface);
|
||||
*/
|
||||
|
||||
cairo_status_t
|
||||
cairo_surface_set_repeat (cairo_surface_t *surface, int repeat)
|
||||
{
|
||||
XcSurfaceSetRepeat (surface->xc_surface, repeat);
|
||||
if (surface->picture) {
|
||||
unsigned long mask;
|
||||
XRenderPictureAttributes pa;
|
||||
|
||||
mask = CPRepeat;
|
||||
pa.repeat = repeat;
|
||||
|
||||
XRenderChangePicture (surface->dpy, surface->picture, mask, &pa);
|
||||
}
|
||||
|
||||
if (surface->icimage) {
|
||||
IcImageSetRepeat (surface->icimage, repeat);
|
||||
}
|
||||
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
/* XXX: This function is going away, right? */
|
||||
Picture
|
||||
_cairo_surface_get_picture (cairo_surface_t *surface)
|
||||
void
|
||||
_cairo_surface_composite (cairo_operator_t operator,
|
||||
cairo_surface_t *src,
|
||||
cairo_surface_t *mask,
|
||||
cairo_surface_t *dst,
|
||||
int src_x,
|
||||
int src_y,
|
||||
int mask_x,
|
||||
int mask_y,
|
||||
int dst_x,
|
||||
int dst_y,
|
||||
unsigned int width,
|
||||
unsigned int height)
|
||||
{
|
||||
return XcSurfaceGetPicture (surface->xc_surface);
|
||||
if (dst->type == CAIRO_SURFACE_TYPE_DRAWABLE
|
||||
&& CAIRO_SURFACE_RENDER_HAS_COMPOSITE (dst)
|
||||
&& src->dpy == dst->dpy
|
||||
&& (mask == NULL || mask->dpy == dst->dpy)) {
|
||||
|
||||
XRenderComposite (dst->dpy, operator,
|
||||
src->picture,
|
||||
mask ? mask->picture : 0,
|
||||
dst->picture,
|
||||
src_x, src_y,
|
||||
mask_x, mask_y,
|
||||
dst_x, dst_y,
|
||||
width, height);
|
||||
} else {
|
||||
_cairo_surface_pull_image (src);
|
||||
_cairo_surface_pull_image (mask);
|
||||
_cairo_surface_pull_image (dst);
|
||||
|
||||
IcComposite (operator,
|
||||
src->icimage,
|
||||
mask ? mask->icimage : NULL,
|
||||
dst->icimage,
|
||||
src_x, src_y,
|
||||
mask_x, mask_y,
|
||||
dst_x, dst_y,
|
||||
width, height);
|
||||
|
||||
_cairo_surface_push_image (dst);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
|
|
@ -382,10 +619,80 @@ _cairo_surface_fill_rectangle (cairo_surface_t *surface,
|
|||
int width,
|
||||
int height)
|
||||
{
|
||||
XcFillRectangle (operator,
|
||||
surface->xc_surface,
|
||||
&color->xc_color,
|
||||
x, y,
|
||||
width, height);
|
||||
cairo_rectangle_t rect;
|
||||
|
||||
rect.x = x;
|
||||
rect.y = y;
|
||||
rect.width = width;
|
||||
rect.height = height;
|
||||
|
||||
_cairo_surface_fill_rectangles (surface, operator, color, &rect, 1);
|
||||
}
|
||||
|
||||
void
|
||||
_cairo_surface_fill_rectangles (cairo_surface_t *surface,
|
||||
cairo_operator_t operator,
|
||||
const cairo_color_t *color,
|
||||
cairo_rectangle_t *rects,
|
||||
int num_rects)
|
||||
{
|
||||
if (surface->type == CAIRO_SURFACE_TYPE_DRAWABLE
|
||||
&& CAIRO_SURFACE_RENDER_HAS_FILL_RECTANGLE (surface)) {
|
||||
|
||||
XRenderColor render_color;
|
||||
render_color.red = color->red_short;
|
||||
render_color.green = color->green_short;
|
||||
render_color.blue = color->blue_short;
|
||||
render_color.alpha = color->alpha_short;
|
||||
|
||||
/* XXX: This XRectangle cast is evil... it needs to go away somehow. */
|
||||
XRenderFillRectangles (surface->dpy, operator, surface->picture,
|
||||
&render_color, (XRectangle *) rects, num_rects);
|
||||
|
||||
} else {
|
||||
IcColor ic_color;
|
||||
|
||||
ic_color.red = color->red_short;
|
||||
ic_color.green = color->green_short;
|
||||
ic_color.blue = color->blue_short;
|
||||
ic_color.alpha = color->alpha_short;
|
||||
|
||||
_cairo_surface_pull_image (surface);
|
||||
|
||||
/* XXX: The IcRectangle cast is evil... it needs to go away somehow. */
|
||||
IcFillRectangles (operator, surface->icimage,
|
||||
&ic_color, (IcRectangle *) rects, num_rects);
|
||||
|
||||
_cairo_surface_push_image (surface);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
_cairo_surface_composite_trapezoids (cairo_operator_t operator,
|
||||
cairo_surface_t *src,
|
||||
cairo_surface_t *dst,
|
||||
int xSrc,
|
||||
int ySrc,
|
||||
const cairo_trapezoid_t *traps,
|
||||
int num_traps)
|
||||
{
|
||||
if (dst->type == CAIRO_SURFACE_TYPE_DRAWABLE
|
||||
&& CAIRO_SURFACE_RENDER_HAS_TRAPEZOIDS (dst)
|
||||
&& src->dpy == dst->dpy) {
|
||||
|
||||
/* XXX: The XTrapezoid cast is evil and needs to go away somehow. */
|
||||
XRenderCompositeTrapezoids (dst->dpy, operator, src->picture, dst->picture,
|
||||
XRenderFindStandardFormat (dst->dpy, PictStandardA8),
|
||||
xSrc, ySrc, (XTrapezoid *) traps, num_traps);
|
||||
} else {
|
||||
_cairo_surface_pull_image (src);
|
||||
_cairo_surface_pull_image (dst);
|
||||
|
||||
/* XXX: The IcTrapezoid cast is evil and needs to go away somehow. */
|
||||
IcCompositeTrapezoids (operator, src->icimage, dst->icimage,
|
||||
xSrc, ySrc, (IcTrapezoid *) traps, num_traps);
|
||||
|
||||
_cairo_surface_push_image (dst);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -32,13 +32,13 @@ static cairo_status_t
|
|||
cairo_traps_grow_by (cairo_traps_t *traps, int additional);
|
||||
|
||||
cairo_status_t
|
||||
cairo_traps_add_trap (cairo_traps_t *traps, XFixed top, XFixed bottom,
|
||||
XLineFixed *left, XLineFixed *right);
|
||||
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_status_t
|
||||
cairo_traps_add_trap_from_points (cairo_traps_t *traps, XFixed top, XFixed bottom,
|
||||
XPointFixed left_p1, XPointFixed left_p2,
|
||||
XPointFixed right_p1, XPointFixed right_p2);
|
||||
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);
|
||||
|
||||
static int
|
||||
_compare_point_fixed_by_y (const void *av, const void *bv);
|
||||
|
|
@ -50,72 +50,72 @@ static int
|
|||
_compare_cairo_edge_by_slope (const void *av, const void *bv);
|
||||
|
||||
static cairo_fixed_16_16_t
|
||||
_compute_x (XLineFixed *line, XFixed y);
|
||||
_compute_x (cairo_line_t *line, cairo_fixed_t y);
|
||||
|
||||
static double
|
||||
_compute_inverse_slope (XLineFixed *l);
|
||||
_compute_inverse_slope (cairo_line_t *l);
|
||||
|
||||
static double
|
||||
_compute_x_intercept (XLineFixed *l, double inverse_slope);
|
||||
_compute_x_intercept (cairo_line_t *l, double inverse_slope);
|
||||
|
||||
static XFixed
|
||||
_line_segs_intersect_ceil (XLineFixed *left, XLineFixed *right, XFixed *y_ret);
|
||||
static cairo_fixed_t
|
||||
_line_segs_intersect_ceil (cairo_line_t *left, cairo_line_t *right, cairo_fixed_t *y_ret);
|
||||
|
||||
void
|
||||
cairo_traps_init (cairo_traps_t *traps)
|
||||
{
|
||||
traps->num_xtraps = 0;
|
||||
traps->num_traps = 0;
|
||||
|
||||
traps->xtraps_size = 0;
|
||||
traps->xtraps = NULL;
|
||||
traps->traps_size = 0;
|
||||
traps->traps = NULL;
|
||||
}
|
||||
|
||||
void
|
||||
cairo_traps_fini (cairo_traps_t *traps)
|
||||
{
|
||||
if (traps->xtraps_size) {
|
||||
free (traps->xtraps);
|
||||
traps->xtraps = NULL;
|
||||
traps->xtraps_size = 0;
|
||||
traps->num_xtraps = 0;
|
||||
if (traps->traps_size) {
|
||||
free (traps->traps);
|
||||
traps->traps = NULL;
|
||||
traps->traps_size = 0;
|
||||
traps->num_traps = 0;
|
||||
}
|
||||
}
|
||||
|
||||
cairo_status_t
|
||||
cairo_traps_add_trap (cairo_traps_t *traps, XFixed top, XFixed bottom,
|
||||
XLineFixed *left, XLineFixed *right)
|
||||
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_status_t status;
|
||||
XTrapezoid *trap;
|
||||
cairo_trapezoid_t *trap;
|
||||
|
||||
if (top == bottom) {
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
if (traps->num_xtraps >= traps->xtraps_size) {
|
||||
if (traps->num_traps >= traps->traps_size) {
|
||||
status = cairo_traps_grow_by (traps, CAIRO_TRAPS_GROWTH_INC);
|
||||
if (status)
|
||||
return status;
|
||||
}
|
||||
|
||||
trap = &traps->xtraps[traps->num_xtraps];
|
||||
trap = &traps->traps[traps->num_traps];
|
||||
trap->top = top;
|
||||
trap->bottom = bottom;
|
||||
trap->left = *left;
|
||||
trap->right = *right;
|
||||
|
||||
traps->num_xtraps++;
|
||||
traps->num_traps++;
|
||||
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
cairo_status_t
|
||||
cairo_traps_add_trap_from_points (cairo_traps_t *traps, XFixed top, XFixed bottom,
|
||||
XPointFixed left_p1, XPointFixed left_p2,
|
||||
XPointFixed right_p1, XPointFixed right_p2)
|
||||
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)
|
||||
{
|
||||
XLineFixed left;
|
||||
XLineFixed right;
|
||||
cairo_line_t left;
|
||||
cairo_line_t right;
|
||||
|
||||
left.p1 = left_p1;
|
||||
left.p2 = left_p2;
|
||||
|
|
@ -129,23 +129,23 @@ cairo_traps_add_trap_from_points (cairo_traps_t *traps, XFixed top, XFixed botto
|
|||
static cairo_status_t
|
||||
cairo_traps_grow_by (cairo_traps_t *traps, int additional)
|
||||
{
|
||||
XTrapezoid *new_xtraps;
|
||||
int old_size = traps->xtraps_size;
|
||||
int new_size = traps->num_xtraps + additional;
|
||||
cairo_trapezoid_t *new_traps;
|
||||
int old_size = traps->traps_size;
|
||||
int new_size = traps->num_traps + additional;
|
||||
|
||||
if (new_size <= traps->xtraps_size) {
|
||||
if (new_size <= traps->traps_size) {
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
traps->xtraps_size = new_size;
|
||||
new_xtraps = realloc (traps->xtraps, traps->xtraps_size * sizeof (XTrapezoid));
|
||||
traps->traps_size = new_size;
|
||||
new_traps = realloc (traps->traps, traps->traps_size * sizeof (cairo_trapezoid_t));
|
||||
|
||||
if (new_xtraps == NULL) {
|
||||
traps->xtraps_size = old_size;
|
||||
if (new_traps == NULL) {
|
||||
traps->traps_size = old_size;
|
||||
return CAIRO_STATUS_NO_MEMORY;
|
||||
}
|
||||
|
||||
traps->xtraps = new_xtraps;
|
||||
traps->traps = new_traps;
|
||||
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
}
|
||||
|
|
@ -153,7 +153,7 @@ cairo_traps_grow_by (cairo_traps_t *traps, int additional)
|
|||
static int
|
||||
_compare_point_fixed_by_y (const void *av, const void *bv)
|
||||
{
|
||||
const XPointFixed *a = av, *b = bv;
|
||||
const cairo_point_t *a = av, *b = bv;
|
||||
|
||||
int ret = a->y - b->y;
|
||||
if (ret == 0) {
|
||||
|
|
@ -163,15 +163,15 @@ _compare_point_fixed_by_y (const void *av, const void *bv)
|
|||
}
|
||||
|
||||
cairo_status_t
|
||||
cairo_traps_tessellate_triangle (cairo_traps_t *traps, XPointFixed t[3])
|
||||
cairo_traps_tessellate_triangle (cairo_traps_t *traps, cairo_point_t t[3])
|
||||
{
|
||||
cairo_status_t status;
|
||||
XLineFixed line;
|
||||
cairo_line_t line;
|
||||
cairo_fixed_16_16_t intersect;
|
||||
XPointFixed tsort[3];
|
||||
cairo_point_t tsort[3];
|
||||
|
||||
memcpy (tsort, t, 3 * sizeof (XPointFixed));
|
||||
qsort (tsort, 3, sizeof (XPointFixed), _compare_point_fixed_by_y);
|
||||
memcpy (tsort, t, 3 * sizeof (cairo_point_t));
|
||||
qsort (tsort, 3, sizeof (cairo_point_t), _compare_point_fixed_by_y);
|
||||
|
||||
/* horizontal top edge requires special handling */
|
||||
if (tsort[0].y == tsort[1].y) {
|
||||
|
|
@ -226,11 +226,11 @@ cairo_traps_tessellate_triangle (cairo_traps_t *traps, XPointFixed t[3])
|
|||
|
||||
/* Warning: This function reorders the elements of the array provided. */
|
||||
cairo_status_t
|
||||
cairo_traps_tessellate_rectangle (cairo_traps_t *traps, XPointFixed q[4])
|
||||
cairo_traps_tessellate_rectangle (cairo_traps_t *traps, cairo_point_t q[4])
|
||||
{
|
||||
cairo_status_t status;
|
||||
|
||||
qsort (q, 4, sizeof (XPointFixed), _compare_point_fixed_by_y);
|
||||
qsort (q, 4, sizeof (cairo_point_t), _compare_point_fixed_by_y);
|
||||
|
||||
if (q[1].x > q[2].x) {
|
||||
status = cairo_traps_add_trap_from_points (traps,
|
||||
|
|
@ -335,7 +335,7 @@ _det (double a, double b, double c, double d)
|
|||
}
|
||||
|
||||
static int
|
||||
_lines_intersect (XLineFixed *l1, XLineFixed *l2, XFixed *y_intersection)
|
||||
_lines_intersect (cairo_line_t *l1, cairo_line_t *l2, cairo_fixed_t *y_intersection)
|
||||
{
|
||||
double dx1 = XFixedToDouble (l1->p1.x - l1->p2.x);
|
||||
double dy1 = XFixedToDouble (l1->p1.y - l1->p2.y);
|
||||
|
|
@ -362,7 +362,7 @@ _lines_intersect (XLineFixed *l1, XLineFixed *l2, XFixed *y_intersection)
|
|||
}
|
||||
*/
|
||||
static cairo_fixed_16_16_t
|
||||
_compute_x (XLineFixed *line, XFixed y)
|
||||
_compute_x (cairo_line_t *line, cairo_fixed_t y)
|
||||
{
|
||||
cairo_fixed_16_16_t dx = line->p2.x - line->p1.x;
|
||||
cairo_fixed_32_32_t ex = (cairo_fixed_48_16_t) (y - line->p1.y) * (cairo_fixed_48_16_t) dx;
|
||||
|
|
@ -372,20 +372,20 @@ _compute_x (XLineFixed *line, XFixed y)
|
|||
}
|
||||
|
||||
static double
|
||||
_compute_inverse_slope (XLineFixed *l)
|
||||
_compute_inverse_slope (cairo_line_t *l)
|
||||
{
|
||||
return (XFixedToDouble (l->p2.x - l->p1.x) /
|
||||
XFixedToDouble (l->p2.y - l->p1.y));
|
||||
}
|
||||
|
||||
static double
|
||||
_compute_x_intercept (XLineFixed *l, double inverse_slope)
|
||||
_compute_x_intercept (cairo_line_t *l, double inverse_slope)
|
||||
{
|
||||
return XFixedToDouble (l->p1.x) - inverse_slope * XFixedToDouble (l->p1.y);
|
||||
}
|
||||
|
||||
static int
|
||||
_line_segs_intersect_ceil (XLineFixed *l1, XLineFixed *l2, XFixed *y_ret)
|
||||
_line_segs_intersect_ceil (cairo_line_t *l1, cairo_line_t *l2, cairo_fixed_t *y_ret)
|
||||
{
|
||||
/*
|
||||
* x = m1y + b1
|
||||
|
|
@ -406,7 +406,7 @@ _line_segs_intersect_ceil (XLineFixed *l1, XLineFixed *l2, XFixed *y_ret)
|
|||
y_intersect = XDoubleToFixed ((b2 - b1) / (m1 - m2));
|
||||
|
||||
if (m1 < m2) {
|
||||
XLineFixed *t;
|
||||
cairo_line_t *t;
|
||||
t = l1;
|
||||
l1 = l2;
|
||||
l2 = t;
|
||||
|
|
@ -418,6 +418,22 @@ _line_segs_intersect_ceil (XLineFixed *l1, XLineFixed *l2, XFixed *y_ret)
|
|||
most, we must increment once. */
|
||||
if (_compute_x (l2, y_intersect) > _compute_x (l1, y_intersect))
|
||||
y_intersect++;
|
||||
/* XXX: Hmm... Keith's error calculations said we'd at most be off
|
||||
by one sub-pixel. But, I found that the paint-fill-BE-01.svg
|
||||
test from the W3C SVG conformance suite definitely requires two
|
||||
increments.
|
||||
|
||||
It could be that we need one to overcome the error, and another
|
||||
to round up.
|
||||
|
||||
It would be nice to be sure this code is correct, (but we can't
|
||||
do the while loop as it will work for way to long on
|
||||
exceedingly distant intersections with large errors that we
|
||||
really don't care about anyway as they will be ignored by the
|
||||
calling function.
|
||||
*/
|
||||
if (_compute_x (l2, y_intersect) > _compute_x (l1, y_intersect))
|
||||
y_intersect++;
|
||||
|
||||
*y_ret = y_intersect;
|
||||
|
||||
|
|
@ -458,7 +474,7 @@ cairo_traps_tessellate_polygon (cairo_traps_t *traps,
|
|||
{
|
||||
cairo_status_t status;
|
||||
int i, active, inactive;
|
||||
XFixed y, y_next, intersect;
|
||||
cairo_fixed_t y, y_next, intersect;
|
||||
int in_out, num_edges = poly->num_edges;
|
||||
cairo_edge_t *edges = poly->edges;
|
||||
|
||||
|
|
|
|||
245
src/cairoint.h
245
src/cairoint.h
|
|
@ -70,6 +70,40 @@ typedef long long int cairo_fixed_32_32_t;
|
|||
typedef cairo_fixed_32_32_t cairo_fixed_48_16_t;
|
||||
typedef int32_t cairo_fixed_16_16_t;
|
||||
|
||||
/* The common 16.16 format gets a shorter name */
|
||||
typedef cairo_fixed_16_16_t cairo_fixed_t;
|
||||
|
||||
typedef struct cairo_point {
|
||||
cairo_fixed_t x;
|
||||
cairo_fixed_t y;
|
||||
} cairo_point_t;
|
||||
|
||||
typedef struct cairo_slope
|
||||
{
|
||||
cairo_fixed_t dx;
|
||||
cairo_fixed_t dy;
|
||||
} cairo_slope_t;
|
||||
|
||||
typedef struct cairo_point_double {
|
||||
double x;
|
||||
double y;
|
||||
} cairo_point_double_t;
|
||||
|
||||
typedef struct cairo_line {
|
||||
cairo_point_t p1;
|
||||
cairo_point_t p2;
|
||||
} cairo_line_t;
|
||||
|
||||
typedef struct cairo_trapezoid {
|
||||
cairo_fixed_t top, bottom;
|
||||
cairo_line_t left, right;
|
||||
} cairo_trapezoid_t;
|
||||
|
||||
typedef struct cairo_rectangle_int {
|
||||
short x, y;
|
||||
unsigned short width, height;
|
||||
} cairo_rectangle_t;
|
||||
|
||||
/* Sure wish C had a real enum type so that this would be distinct
|
||||
from cairo_status_t. Oh well, without that, I'll use this bogus 1000
|
||||
offset */
|
||||
|
|
@ -95,10 +129,10 @@ typedef enum cairo_sub_path_done {
|
|||
} cairo_sub_path_done_t;
|
||||
|
||||
typedef struct cairo_path_callbacks {
|
||||
cairo_status_t (*AddEdge) (void *closure, XPointFixed *p1, XPointFixed *p2);
|
||||
cairo_status_t (*AddSpline) (void *closure, XPointFixed *a, XPointFixed *b, XPointFixed *c, XPointFixed *d);
|
||||
cairo_status_t (*DoneSubPath) (void *closure, cairo_sub_path_done_t done);
|
||||
cairo_status_t (*DonePath) (void *closure);
|
||||
cairo_status_t (*add_edge) (void *closure, cairo_point_t *p1, cairo_point_t *p2);
|
||||
cairo_status_t (*add_spline) (void *closure, cairo_point_t *a, cairo_point_t *b, cairo_point_t *c, cairo_point_t *d);
|
||||
cairo_status_t (*done_sub_path) (void *closure, cairo_sub_path_done_t done);
|
||||
cairo_status_t (*done_path) (void *closure);
|
||||
} cairo_path_callbacks_t;
|
||||
|
||||
#define CAIRO_PATH_BUF_SZ 64
|
||||
|
|
@ -112,7 +146,7 @@ typedef struct cairo_path_op_buf {
|
|||
|
||||
typedef struct cairo_path_arg_buf {
|
||||
int num_pts;
|
||||
XPointFixed pt[CAIRO_PATH_BUF_SZ];
|
||||
cairo_point_t pt[CAIRO_PATH_BUF_SZ];
|
||||
|
||||
struct cairo_path_arg_buf *next, *prev;
|
||||
} cairo_path_arg_buf_t;
|
||||
|
|
@ -126,10 +160,10 @@ typedef struct cairo_path {
|
|||
} cairo_path_t;
|
||||
|
||||
typedef struct cairo_edge {
|
||||
XLineFixed edge;
|
||||
Bool clockWise;
|
||||
cairo_line_t edge;
|
||||
int clockWise;
|
||||
|
||||
XFixed current_x;
|
||||
cairo_fixed_16_16_t current_x;
|
||||
} cairo_edge_t;
|
||||
|
||||
typedef struct cairo_polygon {
|
||||
|
|
@ -137,29 +171,23 @@ typedef struct cairo_polygon {
|
|||
int edges_size;
|
||||
cairo_edge_t *edges;
|
||||
|
||||
XPointFixed first_pt;
|
||||
cairo_point_t first_pt;
|
||||
int first_pt_defined;
|
||||
XPointFixed last_pt;
|
||||
cairo_point_t last_pt;
|
||||
int last_pt_defined;
|
||||
|
||||
int closed;
|
||||
} cairo_polygon_t;
|
||||
|
||||
typedef struct cairo_slope_fixed
|
||||
{
|
||||
XFixed dx;
|
||||
XFixed dy;
|
||||
} cairo_slope_fixed_t;
|
||||
|
||||
typedef struct cairo_spline {
|
||||
XPointFixed a, b, c, d;
|
||||
cairo_point_t a, b, c, d;
|
||||
|
||||
cairo_slope_fixed_t initial_slope;
|
||||
cairo_slope_fixed_t final_slope;
|
||||
cairo_slope_t initial_slope;
|
||||
cairo_slope_t final_slope;
|
||||
|
||||
int num_pts;
|
||||
int pts_size;
|
||||
XPointFixed *pts;
|
||||
cairo_point_t *pts;
|
||||
} cairo_spline_t;
|
||||
|
||||
/* XXX: This can go away once incremental spline tessellation is working */
|
||||
|
|
@ -169,11 +197,10 @@ typedef enum cairo_pen_stroke_direction {
|
|||
} cairo_pen_stroke_direction_t;
|
||||
|
||||
typedef struct _cairo_pen_vertex {
|
||||
XPointFixed pt;
|
||||
cairo_point_t pt;
|
||||
|
||||
double theta;
|
||||
cairo_slope_fixed_t slope_ccw;
|
||||
cairo_slope_fixed_t slope_cw;
|
||||
cairo_slope_t slope_ccw;
|
||||
cairo_slope_t slope_cw;
|
||||
} cairo_pen_vertex_t;
|
||||
|
||||
typedef struct cairo_pen {
|
||||
|
|
@ -184,24 +211,51 @@ typedef struct cairo_pen {
|
|||
cairo_pen_vertex_t *vertex;
|
||||
} cairo_pen_t;
|
||||
|
||||
typedef enum cairo_surface_type {
|
||||
CAIRO_SURFACE_TYPE_DRAWABLE,
|
||||
CAIRO_SURFACE_TYPE_ICIMAGE
|
||||
} cairo_surface_type_t;
|
||||
|
||||
struct cairo_surface {
|
||||
Display *dpy;
|
||||
char *image_data;
|
||||
|
||||
XcSurface *xc_surface;
|
||||
|
||||
double ppm;
|
||||
|
||||
unsigned int ref_count;
|
||||
|
||||
cairo_surface_type_t type;
|
||||
XTransform xtransform;
|
||||
|
||||
/* For TYPE_DRAWABLE */
|
||||
Display *dpy;
|
||||
GC gc;
|
||||
Drawable drawable;
|
||||
Visual *visual;
|
||||
|
||||
int render_major;
|
||||
int render_minor;
|
||||
|
||||
Picture picture;
|
||||
|
||||
/* For TYPE_ICIMAGE */
|
||||
IcImage *icimage;
|
||||
};
|
||||
|
||||
/* XXX: Right now, the cairo_color structure puts unpremultiplied
|
||||
color in the doubles and premultiplied color in the shorts. Yes,
|
||||
this is crazy insane, (but at least we don't export this
|
||||
madness). I'm still working on a cleaner API, but in the meantime,
|
||||
at least this does prevent precision loss in color when changing
|
||||
alpha. */
|
||||
typedef struct cairo_color {
|
||||
double red;
|
||||
double green;
|
||||
double blue;
|
||||
double alpha;
|
||||
|
||||
XcColor xc_color;
|
||||
unsigned short red_short;
|
||||
unsigned short green_short;
|
||||
unsigned short blue_short;
|
||||
unsigned short alpha_short;
|
||||
} cairo_color_t;
|
||||
|
||||
struct cairo_matrix {
|
||||
|
|
@ -209,9 +263,9 @@ struct cairo_matrix {
|
|||
};
|
||||
|
||||
typedef struct cairo_traps {
|
||||
int num_xtraps;
|
||||
int xtraps_size;
|
||||
XTrapezoid *xtraps;
|
||||
cairo_trapezoid_t *traps;
|
||||
int num_traps;
|
||||
int traps_size;
|
||||
} cairo_traps_t;
|
||||
|
||||
#define CAIRO_FONT_KEY_DEFAULT "serif"
|
||||
|
|
@ -265,7 +319,7 @@ typedef struct cairo_gstate {
|
|||
cairo_surface_t *surface;
|
||||
cairo_surface_t *solid;
|
||||
cairo_surface_t *pattern;
|
||||
XPointDouble pattern_offset;
|
||||
cairo_point_double_t pattern_offset;
|
||||
|
||||
cairo_clip_rec_t clip;
|
||||
|
||||
|
|
@ -278,8 +332,8 @@ typedef struct cairo_gstate {
|
|||
|
||||
cairo_path_t path;
|
||||
|
||||
XPointDouble last_move_pt;
|
||||
XPointDouble current_pt;
|
||||
cairo_point_double_t last_move_pt;
|
||||
cairo_point_double_t current_pt;
|
||||
int has_current_pt;
|
||||
|
||||
cairo_pen_t pen_regular;
|
||||
|
|
@ -293,11 +347,11 @@ struct cairo {
|
|||
};
|
||||
|
||||
typedef struct cairo_stroke_face {
|
||||
XPointFixed ccw;
|
||||
XPointFixed pt;
|
||||
XPointFixed cw;
|
||||
cairo_slope_fixed_t dev_vector;
|
||||
XPointDouble usr_vector;
|
||||
cairo_point_t ccw;
|
||||
cairo_point_t pt;
|
||||
cairo_point_t cw;
|
||||
cairo_slope_t dev_vector;
|
||||
cairo_point_double_t usr_vector;
|
||||
} cairo_stroke_face_t;
|
||||
|
||||
/* cairo_gstate_t.c */
|
||||
|
|
@ -370,6 +424,9 @@ _cairo_gstate_get_alpha (cairo_gstate_t *gstate);
|
|||
cairo_status_t
|
||||
_cairo_gstate_set_fill_rule (cairo_gstate_t *gstate, cairo_fill_rule_t fill_rule);
|
||||
|
||||
cairo_fill_rule_t
|
||||
_cairo_gstate_get_fill_rule (cairo_gstate_t *gstate);
|
||||
|
||||
cairo_status_t
|
||||
_cairo_gstate_set_line_width (cairo_gstate_t *gstate, double width);
|
||||
|
||||
|
|
@ -421,10 +478,10 @@ cairo_status_t
|
|||
_cairo_gstate_identity_matrix (cairo_gstate_t *gstate);
|
||||
|
||||
cairo_status_t
|
||||
cairo_gstateransform_point (cairo_gstate_t *gstate, double *x, double *y);
|
||||
cairo_gstate_transform_point (cairo_gstate_t *gstate, double *x, double *y);
|
||||
|
||||
cairo_status_t
|
||||
cairo_gstateransform_distance (cairo_gstate_t *gstate, double *dx, double *dy);
|
||||
cairo_gstate_transform_distance (cairo_gstate_t *gstate, double *dx, double *dy);
|
||||
|
||||
cairo_status_t
|
||||
_cairo_gstate_inverse_transform_point (cairo_gstate_t *gstate, double *x, double *y);
|
||||
|
|
@ -459,6 +516,11 @@ _cairo_gstate_rel_curve_to (cairo_gstate_t *gstate,
|
|||
double dx2, double dy2,
|
||||
double dx3, double dy3);
|
||||
|
||||
/* XXX: NYI
|
||||
cairo_status_t
|
||||
_cairo_gstate_stroke_path (cairo_gstate_t *gstate);
|
||||
*/
|
||||
|
||||
cairo_status_t
|
||||
_cairo_gstate_close_path (cairo_gstate_t *gstate);
|
||||
|
||||
|
|
@ -481,16 +543,16 @@ cairo_status_t
|
|||
_cairo_gstate_scale_font (cairo_gstate_t *gstate, double scale);
|
||||
|
||||
cairo_status_t
|
||||
cairo_gstateransform_font (cairo_gstate_t *gstate,
|
||||
double a, double b,
|
||||
double c, double d);
|
||||
cairo_gstate_transform_font (cairo_gstate_t *gstate,
|
||||
double a, double b,
|
||||
double c, double d);
|
||||
|
||||
cairo_status_t
|
||||
cairo_gstateext_extents (cairo_gstate_t *gstate,
|
||||
const unsigned char *utf8,
|
||||
double *x, double *y,
|
||||
double *width, double *height,
|
||||
double *dx, double *dy);
|
||||
cairo_gstate_text_extents (cairo_gstate_t *gstate,
|
||||
const unsigned char *utf8,
|
||||
double *x, double *y,
|
||||
double *width, double *height,
|
||||
double *dx, double *dy);
|
||||
|
||||
cairo_status_t
|
||||
_cairo_gstate_show_text (cairo_gstate_t *gstate, const unsigned char *utf8);
|
||||
|
|
@ -591,13 +653,6 @@ _cairo_path_stroke_to_traps (cairo_path_t *path, cairo_gstate_t *gstate, cairo_t
|
|||
void
|
||||
_cairo_surface_reference (cairo_surface_t *surface);
|
||||
|
||||
XcSurface *
|
||||
_cairo_surface_get_xc_surface (cairo_surface_t *surface);
|
||||
|
||||
/* XXX: This function is going away, right? */
|
||||
Picture
|
||||
_cairo_surface_get_picture (cairo_surface_t *surface);
|
||||
|
||||
void
|
||||
_cairo_surface_fill_rectangle (cairo_surface_t *surface,
|
||||
cairo_operator_t operator,
|
||||
|
|
@ -607,6 +662,42 @@ _cairo_surface_fill_rectangle (cairo_surface_t *surface,
|
|||
int width,
|
||||
int height);
|
||||
|
||||
void
|
||||
_cairo_surface_composite (cairo_operator_t operator,
|
||||
cairo_surface_t *src,
|
||||
cairo_surface_t *mask,
|
||||
cairo_surface_t *dst,
|
||||
int src_x,
|
||||
int src_y,
|
||||
int mask_x,
|
||||
int mask_y,
|
||||
int dst_x,
|
||||
int dst_y,
|
||||
unsigned int width,
|
||||
unsigned int height);
|
||||
|
||||
void
|
||||
_cairo_surface_fill_rectangles (cairo_surface_t *surface,
|
||||
cairo_operator_t operator,
|
||||
const cairo_color_t *color,
|
||||
cairo_rectangle_t *rects,
|
||||
int num_rects);
|
||||
|
||||
void
|
||||
_cairo_surface_composite_trapezoids (cairo_operator_t operator,
|
||||
cairo_surface_t *src,
|
||||
cairo_surface_t *dst,
|
||||
int xSrc,
|
||||
int ySrc,
|
||||
const cairo_trapezoid_t *traps,
|
||||
int ntraps);
|
||||
|
||||
void
|
||||
_cairo_surface_pull_image (cairo_surface_t *surface);
|
||||
|
||||
void
|
||||
_cairo_surface_push_image (cairo_surface_t *surface);
|
||||
|
||||
/* cairo_pen_t.c */
|
||||
cairo_status_t
|
||||
_cairo_pen_init (cairo_pen_t *pen, double radius, cairo_gstate_t *gstate);
|
||||
|
|
@ -621,23 +712,23 @@ void
|
|||
_cairo_pen_fini (cairo_pen_t *pen);
|
||||
|
||||
cairo_status_t
|
||||
_cairo_pen_add_points (cairo_pen_t *pen, XPointFixed *pt, int num_pts);
|
||||
_cairo_pen_add_points (cairo_pen_t *pen, cairo_point_t *pt, int num_pts);
|
||||
|
||||
cairo_status_t
|
||||
_cairo_pen_add_points_for_slopes (cairo_pen_t *pen,
|
||||
XPointFixed *a,
|
||||
XPointFixed *b,
|
||||
XPointFixed *c,
|
||||
XPointFixed *d);
|
||||
cairo_point_t *a,
|
||||
cairo_point_t *b,
|
||||
cairo_point_t *c,
|
||||
cairo_point_t *d);
|
||||
|
||||
cairo_status_t
|
||||
_cairo_pen_find_active_cw_vertex_index (cairo_pen_t *pen,
|
||||
cairo_slope_fixed_t *slope,
|
||||
cairo_slope_t *slope,
|
||||
int *active);
|
||||
|
||||
cairo_status_t
|
||||
_cairo_pen_find_active_ccw_vertex_index (cairo_pen_t *pen,
|
||||
cairo_slope_fixed_t *slope,
|
||||
cairo_slope_t *slope,
|
||||
int *active);
|
||||
|
||||
cairo_status_t
|
||||
|
|
@ -654,10 +745,10 @@ void
|
|||
_cairo_polygon_fini (cairo_polygon_t *polygon);
|
||||
|
||||
cairo_status_t
|
||||
_cairo_polygon_add_edge (cairo_polygon_t *polygon, XPointFixed *p1, XPointFixed *p2);
|
||||
_cairo_polygon_add_edge (cairo_polygon_t *polygon, cairo_point_t *p1, cairo_point_t *p2);
|
||||
|
||||
cairo_status_t
|
||||
_cairo_polygon_add_point (cairo_polygon_t *polygon, XPointFixed *pt);
|
||||
_cairo_polygon_add_point (cairo_polygon_t *polygon, cairo_point_t *pt);
|
||||
|
||||
cairo_status_t
|
||||
_cairo_polygon_close (cairo_polygon_t *polygon);
|
||||
|
|
@ -665,10 +756,10 @@ _cairo_polygon_close (cairo_polygon_t *polygon);
|
|||
/* cairo_spline_t.c */
|
||||
cairo_int_status_t
|
||||
_cairo_spline_init (cairo_spline_t *spline,
|
||||
XPointFixed *a,
|
||||
XPointFixed *b,
|
||||
XPointFixed *c,
|
||||
XPointFixed *d);
|
||||
cairo_point_t *a,
|
||||
cairo_point_t *b,
|
||||
cairo_point_t *c,
|
||||
cairo_point_t *d);
|
||||
|
||||
cairo_status_t
|
||||
_cairo_spline_decompose (cairo_spline_t *spline, double tolerance);
|
||||
|
|
@ -714,19 +805,25 @@ void
|
|||
cairo_traps_fini (cairo_traps_t *traps);
|
||||
|
||||
cairo_status_t
|
||||
cairo_traps_tessellate_triangle (cairo_traps_t *traps, XPointFixed t[3]);
|
||||
cairo_traps_tessellate_triangle (cairo_traps_t *traps, cairo_point_t t[3]);
|
||||
|
||||
cairo_status_t
|
||||
cairo_traps_tessellate_rectangle (cairo_traps_t *traps, XPointFixed q[4]);
|
||||
cairo_traps_tessellate_rectangle (cairo_traps_t *traps, cairo_point_t q[4]);
|
||||
|
||||
cairo_status_t
|
||||
cairo_traps_tessellate_polygon (cairo_traps_t *traps,
|
||||
cairo_polygon_t *poly,
|
||||
cairo_fill_rule_t fill_rule);
|
||||
|
||||
/* cairo_misc.c */
|
||||
/* cairo_slope.c */
|
||||
|
||||
void
|
||||
_compute_slope (XPointFixed *a, XPointFixed *b, cairo_slope_fixed_t *slope);
|
||||
_cairo_slope_init (cairo_slope_t *slope, cairo_point_t *a, cairo_point_t *b);
|
||||
|
||||
int
|
||||
_cairo_slope_clockwise (cairo_slope_t *a, cairo_slope_t *b);
|
||||
|
||||
int
|
||||
_cairo_slope_counter_clockwise (cairo_slope_t *a, cairo_slope_t *b);
|
||||
|
||||
#endif
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue