mirror of
https://gitlab.freedesktop.org/cairo/cairo.git
synced 2026-05-05 19:18:12 +02:00
Originally 2005-10-28 Keith Packard <keithp@keithp.com>:
Remove pen_regular field from the gstate. Move stroke fallback from gstate to surface where it belongs. Eliminate dependence on cairo_gstate_t object. Fix to include just cairo-clip-private.h rather than cairo-gstate.private.h.
This commit is contained in:
parent
3cae05c4c5
commit
a7228cc37a
8 changed files with 333 additions and 151 deletions
28
ChangeLog
28
ChangeLog
|
|
@ -1,3 +1,31 @@
|
|||
2005-10-31 Carl Worth <cworth@cworth.org>
|
||||
|
||||
Originally 2005-10-28 Keith Packard <keithp@keithp.com>:
|
||||
|
||||
* src/cairo-gstate-private.h: Remove pen_regular field from the
|
||||
gstate.
|
||||
|
||||
* src/cairoint.h:
|
||||
* src/cairo-gstate.c: (_cairo_gstate_init),
|
||||
(_cairo_gstate_init_copy), (_cairo_gstate_fini),
|
||||
(_cairo_gstate_stroke), (_cairo_gstate_in_stroke),
|
||||
(_cairo_gstate_stroke_extents):
|
||||
* src/cairo-path-stroke.c: (_cairo_stroker_start_dash),
|
||||
(_cairo_stroker_step_dash), (_cairo_stroker_init),
|
||||
(_cairo_stroker_fini), (_cairo_stroker_join),
|
||||
(_cairo_stroker_add_cap), (_compute_face),
|
||||
(_cairo_stroker_add_sub_edge), (_cairo_stroker_line_to_dashed),
|
||||
(_cairo_stroker_curve_to), (_cairo_stroker_curve_to_dashed),
|
||||
(_cairo_path_fixed_stroke_to_traps):
|
||||
* src/cairo-surface.c: (_fallback_stroke), (_cairo_surface_stroke):
|
||||
Move stroke fallback from gstate to surface where it belongs.
|
||||
|
||||
* src/cairo-pen.c: (_cairo_pen_init): Eliminate dependence
|
||||
on cairo_gstate_t object.
|
||||
|
||||
* src/cairo-meta-surface.c: Fix to include just
|
||||
cairo-clip-private.h rather than cairo-gstate.private.h.
|
||||
|
||||
2005-10-31 T Rowley <tim.rowley@gmail.com>
|
||||
|
||||
* src/cairo-win32-font.c (_cairo_win32_scaled_font_init_glyph_path):
|
||||
|
|
|
|||
|
|
@ -69,8 +69,6 @@ struct _cairo_gstate {
|
|||
cairo_matrix_t ctm_inverse;
|
||||
cairo_matrix_t source_ctm_inverse; /* At the time ->source was set */
|
||||
|
||||
cairo_pen_t pen_regular;
|
||||
|
||||
cairo_pattern_t *source;
|
||||
|
||||
struct _cairo_gstate *next;
|
||||
|
|
|
|||
|
|
@ -52,10 +52,6 @@ _cairo_gstate_init_copy (cairo_gstate_t *gstate, cairo_gstate_t *other);
|
|||
static void
|
||||
_cairo_gstate_fini (cairo_gstate_t *gstate);
|
||||
|
||||
static cairo_status_t
|
||||
_cairo_gstate_clip_and_composite_trapezoids (cairo_gstate_t *gstate,
|
||||
cairo_traps_t *traps);
|
||||
|
||||
static cairo_status_t
|
||||
_cairo_gstate_ensure_font_face (cairo_gstate_t *gstate);
|
||||
|
||||
|
|
@ -121,8 +117,6 @@ _cairo_gstate_init (cairo_gstate_t *gstate,
|
|||
_cairo_gstate_identity_matrix (gstate);
|
||||
gstate->source_ctm_inverse = gstate->ctm_inverse;
|
||||
|
||||
_cairo_pen_init_empty (&gstate->pen_regular);
|
||||
|
||||
gstate->source = _cairo_pattern_create_solid (CAIRO_COLOR_BLACK);
|
||||
if (gstate->source->status)
|
||||
return CAIRO_STATUS_NO_MEMORY;
|
||||
|
|
@ -135,7 +129,6 @@ _cairo_gstate_init (cairo_gstate_t *gstate,
|
|||
static cairo_status_t
|
||||
_cairo_gstate_init_copy (cairo_gstate_t *gstate, cairo_gstate_t *other)
|
||||
{
|
||||
cairo_status_t status;
|
||||
cairo_gstate_t *next;
|
||||
|
||||
/* Copy all members, but don't smash the next pointer */
|
||||
|
|
@ -163,20 +156,7 @@ _cairo_gstate_init_copy (cairo_gstate_t *gstate, cairo_gstate_t *other)
|
|||
|
||||
cairo_pattern_reference (gstate->source);
|
||||
|
||||
status = _cairo_pen_init_copy (&gstate->pen_regular, &other->pen_regular);
|
||||
if (status)
|
||||
goto CLEANUP_FONT;
|
||||
|
||||
return status;
|
||||
|
||||
CLEANUP_FONT:
|
||||
cairo_scaled_font_destroy (gstate->scaled_font);
|
||||
gstate->scaled_font = NULL;
|
||||
|
||||
free (gstate->dash);
|
||||
gstate->dash = NULL;
|
||||
|
||||
return CAIRO_STATUS_NO_MEMORY;
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
@ -197,8 +177,6 @@ _cairo_gstate_fini (cairo_gstate_t *gstate)
|
|||
|
||||
cairo_pattern_destroy (gstate->source);
|
||||
|
||||
_cairo_pen_fini (&gstate->pen_regular);
|
||||
|
||||
if (gstate->dash) {
|
||||
free (gstate->dash);
|
||||
gstate->dash = NULL;
|
||||
|
|
@ -1157,7 +1135,7 @@ cairo_status_t
|
|||
_cairo_gstate_stroke (cairo_gstate_t *gstate, cairo_path_fixed_t *path)
|
||||
{
|
||||
cairo_status_t status;
|
||||
cairo_traps_t traps;
|
||||
cairo_pattern_union_t source_pattern;
|
||||
|
||||
if (gstate->source->status)
|
||||
return gstate->source->status;
|
||||
|
|
@ -1169,21 +1147,28 @@ _cairo_gstate_stroke (cairo_gstate_t *gstate, cairo_path_fixed_t *path)
|
|||
if (status)
|
||||
return status;
|
||||
|
||||
_cairo_pen_init (&gstate->pen_regular, gstate->line_width / 2.0, gstate);
|
||||
_cairo_gstate_copy_transformed_source (gstate, &source_pattern.base);
|
||||
|
||||
_cairo_traps_init (&traps);
|
||||
status = _cairo_surface_stroke (gstate->operator,
|
||||
&source_pattern.base,
|
||||
gstate->target,
|
||||
path,
|
||||
gstate->tolerance,
|
||||
&gstate->ctm,
|
||||
&gstate->ctm_inverse,
|
||||
gstate->antialias,
|
||||
|
||||
status = _cairo_path_fixed_stroke_to_traps (path, gstate, &traps);
|
||||
if (status) {
|
||||
_cairo_traps_fini (&traps);
|
||||
return status;
|
||||
}
|
||||
gstate->line_width,
|
||||
gstate->line_cap,
|
||||
gstate->line_join,
|
||||
gstate->miter_limit,
|
||||
|
||||
_cairo_gstate_clip_and_composite_trapezoids (gstate, &traps);
|
||||
gstate->dash,
|
||||
gstate->num_dashes,
|
||||
gstate->dash_offset);
|
||||
|
||||
return status;
|
||||
|
||||
_cairo_traps_fini (&traps);
|
||||
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
cairo_status_t
|
||||
|
|
@ -1198,11 +1183,21 @@ _cairo_gstate_in_stroke (cairo_gstate_t *gstate,
|
|||
|
||||
_cairo_gstate_user_to_backend (gstate, &x, &y);
|
||||
|
||||
_cairo_pen_init (&gstate->pen_regular, gstate->line_width / 2.0, gstate);
|
||||
|
||||
_cairo_traps_init (&traps);
|
||||
|
||||
status = _cairo_path_fixed_stroke_to_traps (path, gstate, &traps);
|
||||
status = _cairo_path_fixed_stroke_to_traps (path, &traps,
|
||||
gstate->tolerance,
|
||||
&gstate->ctm,
|
||||
&gstate->ctm_inverse,
|
||||
|
||||
gstate->line_width,
|
||||
gstate->line_cap,
|
||||
gstate->line_join,
|
||||
gstate->miter_limit,
|
||||
|
||||
gstate->dash,
|
||||
gstate->num_dashes,
|
||||
gstate->dash_offset);
|
||||
if (status)
|
||||
goto BAIL;
|
||||
|
||||
|
|
@ -1498,28 +1493,6 @@ _cairo_surface_clip_and_composite_trapezoids (cairo_pattern_t *src,
|
|||
return status;
|
||||
}
|
||||
|
||||
/* Warning: This call modifies the coordinates of traps */
|
||||
static cairo_status_t
|
||||
_cairo_gstate_clip_and_composite_trapezoids (cairo_gstate_t *gstate,
|
||||
cairo_traps_t *traps)
|
||||
{
|
||||
cairo_pattern_union_t pattern;
|
||||
cairo_status_t status;
|
||||
|
||||
_cairo_gstate_copy_transformed_source (gstate, &pattern.base);
|
||||
|
||||
status = _cairo_surface_clip_and_composite_trapezoids (&pattern.base,
|
||||
gstate->operator,
|
||||
gstate->target,
|
||||
traps,
|
||||
&gstate->clip,
|
||||
gstate->antialias);
|
||||
|
||||
_cairo_pattern_fini (&pattern.base);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
cairo_status_t
|
||||
_cairo_gstate_fill (cairo_gstate_t *gstate, cairo_path_fixed_t *path)
|
||||
{
|
||||
|
|
@ -1598,11 +1571,21 @@ _cairo_gstate_stroke_extents (cairo_gstate_t *gstate,
|
|||
cairo_traps_t traps;
|
||||
cairo_box_t extents;
|
||||
|
||||
_cairo_pen_init (&gstate->pen_regular, gstate->line_width / 2.0, gstate);
|
||||
|
||||
_cairo_traps_init (&traps);
|
||||
|
||||
status = _cairo_path_fixed_stroke_to_traps (path, gstate, &traps);
|
||||
status = _cairo_path_fixed_stroke_to_traps (path, &traps,
|
||||
gstate->tolerance,
|
||||
&gstate->ctm,
|
||||
&gstate->ctm_inverse,
|
||||
|
||||
gstate->line_width,
|
||||
gstate->line_cap,
|
||||
gstate->line_join,
|
||||
gstate->miter_limit,
|
||||
|
||||
gstate->dash,
|
||||
gstate->num_dashes,
|
||||
gstate->dash_offset);
|
||||
if (status)
|
||||
goto BAIL;
|
||||
|
||||
|
|
|
|||
|
|
@ -35,7 +35,7 @@
|
|||
|
||||
#include "cairoint.h"
|
||||
#include "cairo-meta-surface-private.h"
|
||||
#include "cairo-gstate-private.h"
|
||||
#include "cairo-clip-private.h"
|
||||
|
||||
static const cairo_surface_backend_t cairo_meta_surface_backend;
|
||||
|
||||
|
|
|
|||
|
|
@ -36,12 +36,26 @@
|
|||
|
||||
#include "cairoint.h"
|
||||
|
||||
#include "cairo-gstate-private.h"
|
||||
|
||||
typedef struct cairo_stroker {
|
||||
cairo_gstate_t *gstate;
|
||||
cairo_traps_t *traps;
|
||||
|
||||
cairo_pen_t pen;
|
||||
|
||||
cairo_matrix_t *ctm;
|
||||
cairo_matrix_t *ctm_inverse;
|
||||
double tolerance;
|
||||
|
||||
/* stroke style */
|
||||
double line_width;
|
||||
cairo_line_cap_t line_cap;
|
||||
cairo_line_join_t line_join;
|
||||
double miter_limit;
|
||||
|
||||
/* dash style */
|
||||
double *dash;
|
||||
int num_dashes;
|
||||
double dash_offset;
|
||||
|
||||
cairo_bool_t has_current_point;
|
||||
cairo_point_t current_point;
|
||||
cairo_point_t first_point;
|
||||
|
|
@ -60,7 +74,21 @@ typedef struct cairo_stroker {
|
|||
|
||||
/* private functions */
|
||||
static void
|
||||
_cairo_stroker_init (cairo_stroker_t *stroker, cairo_gstate_t *gstate, cairo_traps_t *traps);
|
||||
_cairo_stroker_init (cairo_stroker_t *stroker,
|
||||
cairo_traps_t *traps,
|
||||
|
||||
double tolerance,
|
||||
cairo_matrix_t *ctm,
|
||||
cairo_matrix_t *ctm_inverse,
|
||||
|
||||
double line_width,
|
||||
cairo_line_cap_t line_cap,
|
||||
cairo_line_join_t line_join,
|
||||
double miter_limit,
|
||||
|
||||
double *dash,
|
||||
int num_dashes,
|
||||
double dash_offset);
|
||||
|
||||
static void
|
||||
_cairo_stroker_fini (cairo_stroker_t *stroker);
|
||||
|
|
@ -101,49 +129,75 @@ _cairo_stroker_join (cairo_stroker_t *stroker, cairo_stroke_face_t *in, cairo_st
|
|||
static void
|
||||
_cairo_stroker_start_dash (cairo_stroker_t *stroker)
|
||||
{
|
||||
cairo_gstate_t *gstate = stroker->gstate;
|
||||
double offset;
|
||||
int on = 1;
|
||||
int i = 0;
|
||||
|
||||
offset = gstate->dash_offset;
|
||||
while (offset >= gstate->dash[i]) {
|
||||
offset -= gstate->dash[i];
|
||||
offset = stroker->dash_offset;
|
||||
while (offset >= stroker->dash[i]) {
|
||||
offset -= stroker->dash[i];
|
||||
on = 1-on;
|
||||
if (++i == gstate->num_dashes)
|
||||
if (++i == stroker->num_dashes)
|
||||
i = 0;
|
||||
}
|
||||
stroker->dashed = TRUE;
|
||||
stroker->dash_index = i;
|
||||
stroker->dash_on = on;
|
||||
stroker->dash_remain = gstate->dash[i] - offset;
|
||||
stroker->dash_remain = stroker->dash[i] - offset;
|
||||
}
|
||||
|
||||
static void
|
||||
_cairo_stroker_step_dash (cairo_stroker_t *stroker, double step)
|
||||
{
|
||||
cairo_gstate_t *gstate = stroker->gstate;
|
||||
stroker->dash_remain -= step;
|
||||
if (stroker->dash_remain <= 0) {
|
||||
stroker->dash_index++;
|
||||
if (stroker->dash_index == gstate->num_dashes)
|
||||
if (stroker->dash_index == stroker->num_dashes)
|
||||
stroker->dash_index = 0;
|
||||
stroker->dash_on = 1-stroker->dash_on;
|
||||
stroker->dash_remain = gstate->dash[stroker->dash_index];
|
||||
stroker->dash_remain = stroker->dash[stroker->dash_index];
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
_cairo_stroker_init (cairo_stroker_t *stroker, cairo_gstate_t *gstate, cairo_traps_t *traps)
|
||||
_cairo_stroker_init (cairo_stroker_t *stroker,
|
||||
cairo_traps_t *traps,
|
||||
|
||||
double tolerance,
|
||||
cairo_matrix_t *ctm,
|
||||
cairo_matrix_t *ctm_inverse,
|
||||
|
||||
double line_width,
|
||||
cairo_line_cap_t line_cap,
|
||||
cairo_line_join_t line_join,
|
||||
double miter_limit,
|
||||
|
||||
double *dash,
|
||||
int num_dashes,
|
||||
double dash_offset)
|
||||
{
|
||||
stroker->gstate = gstate;
|
||||
stroker->traps = traps;
|
||||
|
||||
_cairo_pen_init (&stroker->pen, line_width / 2.0, tolerance, ctm);
|
||||
|
||||
stroker->tolerance = tolerance;
|
||||
stroker->ctm = ctm;
|
||||
stroker->ctm_inverse = ctm_inverse;
|
||||
|
||||
stroker->line_width = line_width;
|
||||
stroker->line_cap = line_cap;
|
||||
stroker->line_join = line_join;
|
||||
stroker->miter_limit = miter_limit;
|
||||
|
||||
stroker->dash = dash;
|
||||
stroker->num_dashes = num_dashes;
|
||||
stroker->dash_offset = dash_offset;
|
||||
|
||||
stroker->has_current_point = FALSE;
|
||||
stroker->has_current_face = FALSE;
|
||||
stroker->has_first_face = FALSE;
|
||||
|
||||
if (gstate->dash)
|
||||
if (stroker->dash)
|
||||
_cairo_stroker_start_dash (stroker);
|
||||
else
|
||||
stroker->dashed = FALSE;
|
||||
|
|
@ -152,7 +206,7 @@ _cairo_stroker_init (cairo_stroker_t *stroker, cairo_gstate_t *gstate, cairo_tra
|
|||
static void
|
||||
_cairo_stroker_fini (cairo_stroker_t *stroker)
|
||||
{
|
||||
/* nothing to do here */
|
||||
_cairo_pen_fini (&stroker->pen);
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
@ -177,8 +231,7 @@ static cairo_status_t
|
|||
_cairo_stroker_join (cairo_stroker_t *stroker, cairo_stroke_face_t *in, cairo_stroke_face_t *out)
|
||||
{
|
||||
cairo_status_t status;
|
||||
cairo_gstate_t *gstate = stroker->gstate;
|
||||
int clockwise = _cairo_stroker_face_clockwise (out, in);
|
||||
int clockwise = _cairo_stroker_face_clockwise (out, in);
|
||||
cairo_point_t *inpt, *outpt;
|
||||
|
||||
if (in->cw.x == out->cw.x
|
||||
|
|
@ -196,12 +249,12 @@ _cairo_stroker_join (cairo_stroker_t *stroker, cairo_stroke_face_t *in, cairo_st
|
|||
outpt = &out->cw;
|
||||
}
|
||||
|
||||
switch (gstate->line_join) {
|
||||
switch (stroker->line_join) {
|
||||
case CAIRO_LINE_JOIN_ROUND: {
|
||||
int i;
|
||||
int start, step, stop;
|
||||
cairo_point_t tri[3];
|
||||
cairo_pen_t *pen = &gstate->pen_regular;
|
||||
cairo_pen_t *pen = &stroker->pen;
|
||||
|
||||
tri[0] = in->point;
|
||||
if (clockwise) {
|
||||
|
|
@ -237,7 +290,7 @@ _cairo_stroker_join (cairo_stroker_t *stroker, cairo_stroke_face_t *in, cairo_st
|
|||
/* dot product of incoming slope vector with outgoing slope vector */
|
||||
double in_dot_out = ((-in->usr_vector.x * out->usr_vector.x)+
|
||||
(-in->usr_vector.y * out->usr_vector.y));
|
||||
double ml = gstate->miter_limit;
|
||||
double ml = stroker->miter_limit;
|
||||
|
||||
/*
|
||||
* Check the miter limit -- lines meeting at an acute angle
|
||||
|
|
@ -285,14 +338,14 @@ _cairo_stroker_join (cairo_stroker_t *stroker, cairo_stroke_face_t *in, cairo_st
|
|||
y1 = _cairo_fixed_to_double (inpt->y);
|
||||
dx1 = in->usr_vector.x;
|
||||
dy1 = in->usr_vector.y;
|
||||
cairo_matrix_transform_distance (&gstate->ctm, &dx1, &dy1);
|
||||
cairo_matrix_transform_distance (stroker->ctm, &dx1, &dy1);
|
||||
|
||||
/* outer point of outgoing line face */
|
||||
x2 = _cairo_fixed_to_double (outpt->x);
|
||||
y2 = _cairo_fixed_to_double (outpt->y);
|
||||
dx2 = out->usr_vector.x;
|
||||
dy2 = out->usr_vector.y;
|
||||
cairo_matrix_transform_distance (&gstate->ctm, &dx2, &dy2);
|
||||
cairo_matrix_transform_distance (stroker->ctm, &dx2, &dy2);
|
||||
|
||||
/*
|
||||
* Compute the location of the outer corner of the miter.
|
||||
|
|
@ -344,18 +397,17 @@ static cairo_status_t
|
|||
_cairo_stroker_add_cap (cairo_stroker_t *stroker, cairo_stroke_face_t *f)
|
||||
{
|
||||
cairo_status_t status;
|
||||
cairo_gstate_t *gstate = stroker->gstate;
|
||||
|
||||
if (gstate->line_cap == CAIRO_LINE_CAP_BUTT)
|
||||
if (stroker->line_cap == CAIRO_LINE_CAP_BUTT)
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
|
||||
switch (gstate->line_cap) {
|
||||
switch (stroker->line_cap) {
|
||||
case CAIRO_LINE_CAP_ROUND: {
|
||||
int i;
|
||||
int start, stop;
|
||||
cairo_slope_t slope;
|
||||
cairo_point_t tri[3];
|
||||
cairo_pen_t *pen = &gstate->pen_regular;
|
||||
cairo_pen_t *pen = &stroker->pen;
|
||||
|
||||
slope = f->dev_vector;
|
||||
_cairo_pen_find_active_cw_vertex_index (pen, &slope, &start);
|
||||
|
|
@ -383,9 +435,9 @@ _cairo_stroker_add_cap (cairo_stroker_t *stroker, cairo_stroke_face_t *f)
|
|||
|
||||
dx = f->usr_vector.x;
|
||||
dy = f->usr_vector.y;
|
||||
dx *= gstate->line_width / 2.0;
|
||||
dy *= gstate->line_width / 2.0;
|
||||
cairo_matrix_transform_distance (&gstate->ctm, &dx, &dy);
|
||||
dx *= stroker->line_width / 2.0;
|
||||
dy *= stroker->line_width / 2.0;
|
||||
cairo_matrix_transform_distance (stroker->ctm, &dx, &dy);
|
||||
fvector.dx = _cairo_fixed_from_double (dx);
|
||||
fvector.dy = _cairo_fixed_from_double (dy);
|
||||
occw.x = f->ccw.x + fvector.dx;
|
||||
|
|
@ -460,7 +512,7 @@ _cairo_stroker_add_caps (cairo_stroker_t *stroker)
|
|||
}
|
||||
|
||||
static void
|
||||
_compute_face (cairo_point_t *point, cairo_slope_t *slope, cairo_gstate_t *gstate, cairo_stroke_face_t *face)
|
||||
_compute_face (cairo_point_t *point, cairo_slope_t *slope, cairo_stroker_t *stroker, cairo_stroke_face_t *face)
|
||||
{
|
||||
double mag, det;
|
||||
double line_dx, line_dy;
|
||||
|
|
@ -472,7 +524,7 @@ _compute_face (cairo_point_t *point, cairo_slope_t *slope, cairo_gstate_t *gstat
|
|||
line_dy = _cairo_fixed_to_double (slope->dy);
|
||||
|
||||
/* faces are normal in user space, not device space */
|
||||
cairo_matrix_transform_distance (&gstate->ctm_inverse, &line_dx, &line_dy);
|
||||
cairo_matrix_transform_distance (stroker->ctm_inverse, &line_dx, &line_dy);
|
||||
|
||||
mag = sqrt (line_dx * line_dx + line_dy * line_dy);
|
||||
if (mag == 0) {
|
||||
|
|
@ -494,20 +546,20 @@ _compute_face (cairo_point_t *point, cairo_slope_t *slope, cairo_gstate_t *gstat
|
|||
* whether the ctm reflects or not, and that can be determined
|
||||
* by looking at the determinant of the matrix.
|
||||
*/
|
||||
_cairo_matrix_compute_determinant (&gstate->ctm, &det);
|
||||
_cairo_matrix_compute_determinant (stroker->ctm, &det);
|
||||
if (det >= 0)
|
||||
{
|
||||
face_dx = - line_dy * (gstate->line_width / 2.0);
|
||||
face_dy = line_dx * (gstate->line_width / 2.0);
|
||||
face_dx = - line_dy * (stroker->line_width / 2.0);
|
||||
face_dy = line_dx * (stroker->line_width / 2.0);
|
||||
}
|
||||
else
|
||||
{
|
||||
face_dx = line_dy * (gstate->line_width / 2.0);
|
||||
face_dy = - line_dx * (gstate->line_width / 2.0);
|
||||
face_dx = line_dy * (stroker->line_width / 2.0);
|
||||
face_dy = - line_dx * (stroker->line_width / 2.0);
|
||||
}
|
||||
|
||||
/* back to device space */
|
||||
cairo_matrix_transform_distance (&gstate->ctm, &face_dx, &face_dy);
|
||||
cairo_matrix_transform_distance (stroker->ctm, &face_dx, &face_dy);
|
||||
|
||||
offset_ccw.x = _cairo_fixed_from_double (face_dx);
|
||||
offset_ccw.y = _cairo_fixed_from_double (face_dy);
|
||||
|
|
@ -533,7 +585,6 @@ _cairo_stroker_add_sub_edge (cairo_stroker_t *stroker, cairo_point_t *p1, cairo_
|
|||
cairo_stroke_face_t *start, cairo_stroke_face_t *end)
|
||||
{
|
||||
cairo_status_t status;
|
||||
cairo_gstate_t *gstate = stroker->gstate;
|
||||
cairo_polygon_t polygon;
|
||||
cairo_slope_t slope;
|
||||
|
||||
|
|
@ -545,12 +596,12 @@ _cairo_stroker_add_sub_edge (cairo_stroker_t *stroker, cairo_point_t *p1, cairo_
|
|||
}
|
||||
|
||||
_cairo_slope_init (&slope, p1, p2);
|
||||
_compute_face (p1, &slope, gstate, start);
|
||||
_compute_face (p1, &slope, stroker, start);
|
||||
|
||||
/* XXX: This could be optimized slightly by not calling
|
||||
_compute_face again but rather translating the relevant
|
||||
fields from start. */
|
||||
_compute_face (p2, &slope, gstate, end);
|
||||
_compute_face (p2, &slope, stroker, end);
|
||||
|
||||
/* XXX: I should really check the return value of the
|
||||
move_to/line_to functions here to catch out of memory
|
||||
|
|
@ -648,7 +699,6 @@ _cairo_stroker_line_to_dashed (void *closure, cairo_point_t *point)
|
|||
{
|
||||
cairo_status_t status = CAIRO_STATUS_SUCCESS;
|
||||
cairo_stroker_t *stroker = closure;
|
||||
cairo_gstate_t *gstate = stroker->gstate;
|
||||
double mag, remain, tmp;
|
||||
double dx, dy;
|
||||
double dx2, dy2;
|
||||
|
|
@ -664,7 +714,7 @@ _cairo_stroker_line_to_dashed (void *closure, cairo_point_t *point)
|
|||
dx = _cairo_fixed_to_double (p2->x - p1->x);
|
||||
dy = _cairo_fixed_to_double (p2->y - p1->y);
|
||||
|
||||
cairo_matrix_transform_distance (&gstate->ctm_inverse, &dx, &dy);
|
||||
cairo_matrix_transform_distance (stroker->ctm_inverse, &dx, &dy);
|
||||
|
||||
mag = sqrt (dx *dx + dy * dy);
|
||||
remain = mag;
|
||||
|
|
@ -676,7 +726,7 @@ _cairo_stroker_line_to_dashed (void *closure, cairo_point_t *point)
|
|||
remain -= tmp;
|
||||
dx2 = dx * (mag - remain)/mag;
|
||||
dy2 = dy * (mag - remain)/mag;
|
||||
cairo_matrix_transform_distance (&gstate->ctm, &dx2, &dy2);
|
||||
cairo_matrix_transform_distance (stroker->ctm, &dx2, &dy2);
|
||||
fd2.x = _cairo_fixed_from_double (dx2);
|
||||
fd2.y = _cairo_fixed_from_double (dy2);
|
||||
fd2.x += p1->x;
|
||||
|
|
@ -764,7 +814,6 @@ _cairo_stroker_curve_to (void *closure,
|
|||
{
|
||||
cairo_status_t status = CAIRO_STATUS_SUCCESS;
|
||||
cairo_stroker_t *stroker = closure;
|
||||
cairo_gstate_t *gstate = stroker->gstate;
|
||||
cairo_spline_t spline;
|
||||
cairo_pen_t pen;
|
||||
cairo_stroke_face_t start, end;
|
||||
|
|
@ -775,12 +824,12 @@ _cairo_stroker_curve_to (void *closure,
|
|||
if (status == CAIRO_INT_STATUS_DEGENERATE)
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
|
||||
status = _cairo_pen_init_copy (&pen, &gstate->pen_regular);
|
||||
status = _cairo_pen_init_copy (&pen, &stroker->pen);
|
||||
if (status)
|
||||
goto CLEANUP_SPLINE;
|
||||
|
||||
_compute_face (a, &spline.initial_slope, gstate, &start);
|
||||
_compute_face (d, &spline.final_slope, gstate, &end);
|
||||
_compute_face (a, &spline.initial_slope, stroker, &start);
|
||||
_compute_face (d, &spline.final_slope, stroker, &end);
|
||||
|
||||
if (stroker->has_current_face) {
|
||||
status = _cairo_stroker_join (stroker, &stroker->current_face, &start);
|
||||
|
|
@ -812,7 +861,7 @@ _cairo_stroker_curve_to (void *closure,
|
|||
if (status)
|
||||
goto CLEANUP_PEN;
|
||||
|
||||
status = _cairo_pen_stroke_spline (&pen, &spline, gstate->tolerance, stroker->traps);
|
||||
status = _cairo_pen_stroke_spline (&pen, &spline, stroker->tolerance, stroker->traps);
|
||||
if (status)
|
||||
goto CLEANUP_PEN;
|
||||
|
||||
|
|
@ -852,7 +901,6 @@ _cairo_stroker_curve_to_dashed (void *closure,
|
|||
{
|
||||
cairo_status_t status = CAIRO_STATUS_SUCCESS;
|
||||
cairo_stroker_t *stroker = closure;
|
||||
cairo_gstate_t *gstate = stroker->gstate;
|
||||
cairo_spline_t spline;
|
||||
cairo_point_t *a = &stroker->current_point;
|
||||
cairo_line_join_t line_join_save;
|
||||
|
|
@ -864,15 +912,15 @@ _cairo_stroker_curve_to_dashed (void *closure,
|
|||
|
||||
/* If the line width is so small that the pen is reduced to a
|
||||
single point, then we have nothing to do. */
|
||||
if (gstate->pen_regular.num_vertices <= 1)
|
||||
if (stroker->pen.num_vertices <= 1)
|
||||
goto CLEANUP_SPLINE;
|
||||
|
||||
/* Temporarily modify the gstate to use round joins to guarantee
|
||||
/* Temporarily modify the stroker to use round joins to guarantee
|
||||
* smooth stroked curves. */
|
||||
line_join_save = gstate->line_join;
|
||||
gstate->line_join = CAIRO_LINE_JOIN_ROUND;
|
||||
line_join_save = stroker->line_join;
|
||||
stroker->line_join = CAIRO_LINE_JOIN_ROUND;
|
||||
|
||||
status = _cairo_spline_decompose (&spline, gstate->tolerance);
|
||||
status = _cairo_spline_decompose (&spline, stroker->tolerance);
|
||||
if (status)
|
||||
goto CLEANUP_GSTATE;
|
||||
|
||||
|
|
@ -886,7 +934,7 @@ _cairo_stroker_curve_to_dashed (void *closure,
|
|||
}
|
||||
|
||||
CLEANUP_GSTATE:
|
||||
gstate->line_join = line_join_save;
|
||||
stroker->line_join = line_join_save;
|
||||
|
||||
CLEANUP_SPLINE:
|
||||
_cairo_spline_fini (&spline);
|
||||
|
|
@ -923,16 +971,29 @@ _cairo_stroker_close_path (void *closure)
|
|||
}
|
||||
|
||||
cairo_status_t
|
||||
_cairo_path_fixed_stroke_to_traps (cairo_path_fixed_t *path,
|
||||
cairo_gstate_t *gstate,
|
||||
cairo_traps_t *traps)
|
||||
_cairo_path_fixed_stroke_to_traps (cairo_path_fixed_t *path,
|
||||
cairo_traps_t *traps,
|
||||
double tolerance,
|
||||
cairo_matrix_t *ctm,
|
||||
cairo_matrix_t *ctm_inverse,
|
||||
|
||||
double line_width,
|
||||
cairo_line_cap_t line_cap,
|
||||
cairo_line_join_t line_join,
|
||||
double miter_limit,
|
||||
|
||||
double *dash,
|
||||
int num_dashes,
|
||||
double dash_offset)
|
||||
{
|
||||
cairo_status_t status = CAIRO_STATUS_SUCCESS;
|
||||
cairo_stroker_t stroker;
|
||||
|
||||
_cairo_stroker_init (&stroker, gstate, traps);
|
||||
_cairo_stroker_init (&stroker, traps, tolerance, ctm, ctm_inverse,
|
||||
line_width, line_cap, line_join, miter_limit,
|
||||
dash, num_dashes, dash_offset);
|
||||
|
||||
if (gstate->dash)
|
||||
if (stroker.dash)
|
||||
status = _cairo_path_fixed_interpret (path,
|
||||
CAIRO_DIRECTION_FORWARD,
|
||||
_cairo_stroker_move_to,
|
||||
|
|
|
|||
|
|
@ -36,8 +36,6 @@
|
|||
|
||||
#include "cairoint.h"
|
||||
|
||||
#include "cairo-gstate-private.h"
|
||||
|
||||
static int
|
||||
_cairo_pen_vertices_needed (double tolerance, double radius, cairo_matrix_t *matrix);
|
||||
|
||||
|
|
@ -59,35 +57,28 @@ _cairo_pen_init_empty (cairo_pen_t *pen)
|
|||
}
|
||||
|
||||
cairo_status_t
|
||||
_cairo_pen_init (cairo_pen_t *pen, double radius, cairo_gstate_t *gstate)
|
||||
_cairo_pen_init (cairo_pen_t *pen,
|
||||
double radius,
|
||||
double tolerance,
|
||||
cairo_matrix_t *ctm)
|
||||
{
|
||||
int i;
|
||||
int reflect;
|
||||
double det;
|
||||
|
||||
if (pen->num_vertices) {
|
||||
/* XXX: It would be nice to notice that the pen is already properly constructed.
|
||||
However, this test would also have to account for possible changes in the transformation
|
||||
matrix.
|
||||
if (pen->radius == radius && pen->tolerance == tolerance)
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
*/
|
||||
_cairo_pen_fini (pen);
|
||||
}
|
||||
|
||||
pen->radius = radius;
|
||||
pen->tolerance = gstate->tolerance;
|
||||
pen->tolerance = tolerance;
|
||||
|
||||
_cairo_matrix_compute_determinant (&gstate->ctm, &det);
|
||||
_cairo_matrix_compute_determinant (ctm, &det);
|
||||
if (det >= 0) {
|
||||
reflect = 0;
|
||||
} else {
|
||||
reflect = 1;
|
||||
}
|
||||
|
||||
pen->num_vertices = _cairo_pen_vertices_needed (gstate->tolerance,
|
||||
pen->num_vertices = _cairo_pen_vertices_needed (tolerance,
|
||||
radius,
|
||||
&gstate->ctm);
|
||||
ctm);
|
||||
|
||||
pen->vertices = malloc (pen->num_vertices * sizeof (cairo_pen_vertex_t));
|
||||
if (pen->vertices == NULL) {
|
||||
|
|
@ -105,7 +96,7 @@ _cairo_pen_init (cairo_pen_t *pen, double radius, cairo_gstate_t *gstate)
|
|||
double dx = radius * cos (reflect ? -theta : theta);
|
||||
double dy = radius * sin (reflect ? -theta : theta);
|
||||
cairo_pen_vertex_t *v = &pen->vertices[i];
|
||||
cairo_matrix_transform_distance (&gstate->ctm, &dx, &dy);
|
||||
cairo_matrix_transform_distance (ctm, &dx, &dy);
|
||||
v->point.x = _cairo_fixed_from_double (dx);
|
||||
v->point.y = _cairo_fixed_from_double (dy);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -38,7 +38,7 @@
|
|||
#include <stdlib.h>
|
||||
|
||||
#include "cairoint.h"
|
||||
#include "cairo-gstate-private.h"
|
||||
#include "cairo-clip-private.h"
|
||||
|
||||
const cairo_surface_t _cairo_surface_nil = {
|
||||
&cairo_image_surface_backend, /* backend */
|
||||
|
|
@ -1302,6 +1302,94 @@ _cairo_surface_mask (cairo_operator_t operator,
|
|||
return _fallback_mask (operator, source_pattern, mask_pattern, dst);
|
||||
}
|
||||
|
||||
static cairo_status_t
|
||||
_fallback_stroke (cairo_operator_t operator,
|
||||
cairo_pattern_t *source_pattern,
|
||||
cairo_surface_t *dst,
|
||||
cairo_path_fixed_t *path,
|
||||
cairo_matrix_t *ctm,
|
||||
cairo_matrix_t *ctm_inverse,
|
||||
double tolerance,
|
||||
cairo_antialias_t antialias,
|
||||
|
||||
double line_width,
|
||||
cairo_line_cap_t line_cap,
|
||||
cairo_line_join_t line_join,
|
||||
double miter_limit,
|
||||
|
||||
double *dash,
|
||||
int num_dashes,
|
||||
double dash_offset)
|
||||
{
|
||||
cairo_status_t status;
|
||||
cairo_traps_t traps;
|
||||
|
||||
_cairo_traps_init (&traps);
|
||||
|
||||
status = _cairo_path_fixed_stroke_to_traps (path, &traps, tolerance,
|
||||
ctm, ctm_inverse,
|
||||
line_width, line_cap,
|
||||
line_join, miter_limit,
|
||||
dash, num_dashes,
|
||||
dash_offset);
|
||||
|
||||
if (status) {
|
||||
_cairo_traps_fini (&traps);
|
||||
return status;
|
||||
}
|
||||
|
||||
_cairo_surface_clip_and_composite_trapezoids (source_pattern,
|
||||
operator,
|
||||
dst,
|
||||
&traps,
|
||||
dst->clip,
|
||||
antialias);
|
||||
|
||||
_cairo_traps_fini (&traps);
|
||||
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
cairo_status_t
|
||||
_cairo_surface_stroke (cairo_operator_t operator,
|
||||
cairo_pattern_t *source_pattern,
|
||||
cairo_surface_t *dst,
|
||||
cairo_path_fixed_t *path,
|
||||
double tolerance,
|
||||
cairo_matrix_t *ctm,
|
||||
cairo_matrix_t *ctm_inverse,
|
||||
cairo_antialias_t antialias,
|
||||
|
||||
double line_width,
|
||||
cairo_line_cap_t line_cap,
|
||||
cairo_line_join_t line_join,
|
||||
double miter_limit,
|
||||
|
||||
double *dash,
|
||||
int num_dashes,
|
||||
double dash_offset)
|
||||
{
|
||||
assert (! dst->is_snapshot);
|
||||
|
||||
/* XXX: Need to add this to the backend.
|
||||
if (dst->backend->stroke) {
|
||||
cairo_status_t status;
|
||||
status = dst->backend->stroke (operator, source_pattern, dst, path,
|
||||
ctm, ctm_inverse, tolerance, antialias,
|
||||
line_width, line_cap,
|
||||
line_join, miter_limit,
|
||||
dash, num_dashes, dash_offset);
|
||||
if (status != CAIRO_INT_STATUS_UNSUPPORTED)
|
||||
return status;
|
||||
}
|
||||
*/
|
||||
|
||||
return _fallback_stroke (operator, source_pattern, dst, path,
|
||||
ctm, ctm_inverse, tolerance, antialias,
|
||||
line_width, line_cap, line_join, miter_limit,
|
||||
dash, num_dashes, dash_offset);
|
||||
}
|
||||
|
||||
static cairo_status_t
|
||||
_fallback_fill_path (cairo_operator_t operator,
|
||||
cairo_pattern_t *pattern,
|
||||
|
|
|
|||
|
|
@ -1419,9 +1419,20 @@ _cairo_path_fixed_fill_to_traps (cairo_path_fixed_t *path,
|
|||
|
||||
/* cairo_path_stroke.c */
|
||||
cairo_private cairo_status_t
|
||||
_cairo_path_fixed_stroke_to_traps (cairo_path_fixed_t *path,
|
||||
cairo_gstate_t *gstate,
|
||||
cairo_traps_t *traps);
|
||||
_cairo_path_fixed_stroke_to_traps (cairo_path_fixed_t *path,
|
||||
cairo_traps_t *traps,
|
||||
double tolerance,
|
||||
cairo_matrix_t *ctm,
|
||||
cairo_matrix_t *ctm_inverse,
|
||||
|
||||
double line_width,
|
||||
cairo_line_cap_t line_cap,
|
||||
cairo_line_join_t line_join,
|
||||
double miter_limit,
|
||||
|
||||
double *dash,
|
||||
int num_dashes,
|
||||
double dash_offset);
|
||||
|
||||
/* cairo-scaled-font.c */
|
||||
|
||||
|
|
@ -1581,6 +1592,25 @@ _cairo_surface_mask (cairo_operator_t operator,
|
|||
cairo_pattern_t *mask_pattern,
|
||||
cairo_surface_t *dst);
|
||||
|
||||
cairo_private cairo_status_t
|
||||
_cairo_surface_stroke (cairo_operator_t operator,
|
||||
cairo_pattern_t *source_pattern,
|
||||
cairo_surface_t *dst,
|
||||
cairo_path_fixed_t *path,
|
||||
double tolerance,
|
||||
cairo_matrix_t *ctm,
|
||||
cairo_matrix_t *ctm_inverse,
|
||||
cairo_antialias_t antialias,
|
||||
|
||||
double line_width,
|
||||
cairo_line_cap_t line_cap,
|
||||
cairo_line_join_t line_join,
|
||||
double miter_limit,
|
||||
|
||||
double *dash,
|
||||
int num_dashes,
|
||||
double dash_offset);
|
||||
|
||||
cairo_private cairo_status_t
|
||||
_cairo_surface_fill_path (cairo_operator_t operator,
|
||||
cairo_pattern_t *pattern,
|
||||
|
|
@ -1762,7 +1792,10 @@ _cairo_surface_is_image (const cairo_surface_t *surface);
|
|||
|
||||
/* cairo_pen.c */
|
||||
cairo_private cairo_status_t
|
||||
_cairo_pen_init (cairo_pen_t *pen, double radius, cairo_gstate_t *gstate);
|
||||
_cairo_pen_init (cairo_pen_t *pen,
|
||||
double radius,
|
||||
double tolerance,
|
||||
cairo_matrix_t *ctm);
|
||||
|
||||
cairo_private cairo_status_t
|
||||
_cairo_pen_init_empty (cairo_pen_t *pen);
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue