346 lines
9.4 KiB
Diff
346 lines
9.4 KiB
Diff
Index: cairo_gstate.c
|
|
===================================================================
|
|
RCS file: /cvsroot/mozilla/gfx/cairo/cairo/src/cairo_gstate.c,v
|
|
retrieving revision 1.3
|
|
diff -u -8 -p -r1.3 cairo_gstate.c
|
|
--- cairo_gstate.c 30 Mar 2005 17:32:16 -0000 1.3
|
|
+++ cairo_gstate.c 31 Mar 2005 19:53:08 -0000
|
|
@@ -84,16 +84,18 @@ _cairo_gstate_init (cairo_gstate_t *gsta
|
|
gstate->line_join = CAIRO_GSTATE_LINE_JOIN_DEFAULT;
|
|
gstate->miter_limit = CAIRO_GSTATE_MITER_LIMIT_DEFAULT;
|
|
|
|
gstate->fill_rule = CAIRO_GSTATE_FILL_RULE_DEFAULT;
|
|
|
|
gstate->dash = NULL;
|
|
gstate->num_dashes = 0;
|
|
gstate->dash_offset = 0.0;
|
|
+ gstate->max_dash_length = 0.0;
|
|
+ gstate->fraction_dash_lit = 0.0;
|
|
|
|
gstate->font_family = NULL;
|
|
gstate->font_slant = CAIRO_FONT_SLANT_DEFAULT;
|
|
gstate->font_weight = CAIRO_FONT_WEIGHT_DEFAULT;
|
|
|
|
gstate->font = NULL;
|
|
|
|
gstate->surface = NULL;
|
|
@@ -538,28 +540,41 @@ cairo_line_join_t
|
|
_cairo_gstate_current_line_join (cairo_gstate_t *gstate)
|
|
{
|
|
return gstate->line_join;
|
|
}
|
|
|
|
cairo_status_t
|
|
_cairo_gstate_set_dash (cairo_gstate_t *gstate, double *dash, int num_dashes, double offset)
|
|
{
|
|
+ double length = 0.0, lit = 0.0;
|
|
+ int i;
|
|
+
|
|
if (gstate->dash) {
|
|
free (gstate->dash);
|
|
gstate->dash = NULL;
|
|
}
|
|
|
|
gstate->num_dashes = num_dashes;
|
|
if (gstate->num_dashes) {
|
|
gstate->dash = malloc (gstate->num_dashes * sizeof (double));
|
|
if (gstate->dash == NULL) {
|
|
gstate->num_dashes = 0;
|
|
return CAIRO_STATUS_NO_MEMORY;
|
|
}
|
|
+
|
|
+ gstate->max_dash_length = 0.0;
|
|
+ for (i = 0; i < num_dashes; i++) {
|
|
+ gstate->max_dash_length = MAX(dash[i], gstate->max_dash_length);
|
|
+
|
|
+ if (!(i & 1))
|
|
+ lit += dash[i];
|
|
+ length += dash[i];
|
|
+ }
|
|
+ gstate->fraction_dash_lit = lit/length;
|
|
}
|
|
|
|
memcpy (gstate->dash, dash, gstate->num_dashes * sizeof (double));
|
|
gstate->dash_offset = offset;
|
|
|
|
return CAIRO_STATUS_SUCCESS;
|
|
}
|
|
|
|
@@ -1317,46 +1332,77 @@ _cairo_gstate_pattern_init_copy (cairo_g
|
|
cairo_pattern_union_t *pattern,
|
|
cairo_pattern_t *src)
|
|
{
|
|
_cairo_pattern_init_copy (&pattern->base, src);
|
|
_cairo_pattern_transform (&pattern->base, &gstate->ctm_inverse);
|
|
_cairo_pattern_set_alpha (&pattern->base, gstate->alpha);
|
|
}
|
|
|
|
+static cairo_bool_t
|
|
+_dashes_invisible (cairo_gstate_t *gstate)
|
|
+{
|
|
+ if (gstate->dash) {
|
|
+ double min, max;
|
|
+
|
|
+ _cairo_matrix_compute_expansion_factors (&gstate->ctm, &min, &max);
|
|
+
|
|
+ /* Quick and dirty applicaton of Nyquist sampling limit */
|
|
+
|
|
+ if (min * gstate->max_dash_length < 0.5f)
|
|
+ return TRUE;
|
|
+ }
|
|
+
|
|
+ return FALSE;
|
|
+}
|
|
+
|
|
cairo_status_t
|
|
_cairo_gstate_stroke (cairo_gstate_t *gstate)
|
|
{
|
|
cairo_status_t status;
|
|
cairo_traps_t traps;
|
|
+ double *dash = NULL;
|
|
+ double alpha = 0.0;
|
|
|
|
if (gstate->line_width <= 0.0)
|
|
return CAIRO_STATUS_SUCCESS;
|
|
|
|
+ if (_dashes_invisible(gstate)) {
|
|
+ dash = gstate->dash;
|
|
+ gstate->dash = NULL;
|
|
+
|
|
+ alpha = gstate->alpha;
|
|
+ gstate->alpha *= gstate->fraction_dash_lit;
|
|
+ }
|
|
+
|
|
_cairo_pen_init (&gstate->pen_regular, gstate->line_width / 2.0, gstate);
|
|
|
|
_cairo_traps_init (&traps);
|
|
|
|
status = _cairo_path_stroke_to_traps (&gstate->path, gstate, &traps);
|
|
- if (status) {
|
|
- _cairo_traps_fini (&traps);
|
|
- return status;
|
|
- }
|
|
+ if (status)
|
|
+ goto BAIL;
|
|
|
|
_cairo_gstate_clip_and_composite_trapezoids (gstate,
|
|
gstate->pattern,
|
|
gstate->operator,
|
|
gstate->surface,
|
|
&traps);
|
|
|
|
+ BAIL:
|
|
_cairo_traps_fini (&traps);
|
|
|
|
_cairo_gstate_new_path (gstate);
|
|
|
|
- return CAIRO_STATUS_SUCCESS;
|
|
+ if (dash) {
|
|
+ gstate->dash = dash;
|
|
+ gstate->alpha = alpha;
|
|
+ }
|
|
+
|
|
+ return status;
|
|
}
|
|
|
|
cairo_status_t
|
|
_cairo_gstate_in_stroke (cairo_gstate_t *gstate,
|
|
double x,
|
|
double y,
|
|
cairo_bool_t *inside_ret)
|
|
{
|
|
@@ -1695,19 +1741,25 @@ _cairo_gstate_show_page (cairo_gstate_t
|
|
cairo_status_t
|
|
_cairo_gstate_stroke_extents (cairo_gstate_t *gstate,
|
|
double *x1, double *y1,
|
|
double *x2, double *y2)
|
|
{
|
|
cairo_status_t status;
|
|
cairo_traps_t traps;
|
|
cairo_box_t extents;
|
|
+ double *dash = NULL;
|
|
+
|
|
+ if (_dashes_invisible(gstate)) {
|
|
+ dash = gstate->dash;
|
|
+ gstate->dash = NULL;
|
|
+ }
|
|
|
|
_cairo_pen_init (&gstate->pen_regular, gstate->line_width / 2.0, gstate);
|
|
-
|
|
+
|
|
_cairo_traps_init (&traps);
|
|
|
|
status = _cairo_path_stroke_to_traps (&gstate->path, gstate, &traps);
|
|
if (status)
|
|
goto BAIL;
|
|
|
|
_cairo_traps_extents (&traps, &extents);
|
|
|
|
@@ -1716,16 +1768,19 @@ _cairo_gstate_stroke_extents (cairo_gsta
|
|
*x2 = _cairo_fixed_to_double (extents.p2.x);
|
|
*y2 = _cairo_fixed_to_double (extents.p2.y);
|
|
|
|
cairo_matrix_transform_point (&gstate->ctm_inverse, x1, y1);
|
|
cairo_matrix_transform_point (&gstate->ctm_inverse, x2, y2);
|
|
|
|
BAIL:
|
|
_cairo_traps_fini (&traps);
|
|
+
|
|
+ if (dash)
|
|
+ gstate->dash = dash;
|
|
|
|
return status;
|
|
}
|
|
|
|
cairo_status_t
|
|
_cairo_gstate_fill_extents (cairo_gstate_t *gstate,
|
|
double *x1, double *y1,
|
|
double *x2, double *y2)
|
|
Index: cairo_matrix.c
|
|
===================================================================
|
|
RCS file: /cvsroot/mozilla/gfx/cairo/cairo/src/cairo_matrix.c,v
|
|
retrieving revision 1.2
|
|
diff -u -8 -p -r1.2 cairo_matrix.c
|
|
--- cairo_matrix.c 23 Mar 2005 19:53:39 -0000 1.2
|
|
+++ cairo_matrix.c 31 Mar 2005 19:53:08 -0000
|
|
@@ -615,16 +615,39 @@ _cairo_matrix_compute_scale_factors (cai
|
|
*sx = minor;
|
|
*sy = major;
|
|
}
|
|
}
|
|
|
|
return CAIRO_STATUS_SUCCESS;
|
|
}
|
|
|
|
+/* Compute the min/max expansion factors. See the comment in
|
|
+ * cairo-pen.c for the derivation */
|
|
+cairo_status_t
|
|
+_cairo_matrix_compute_expansion_factors (cairo_matrix_t *matrix,
|
|
+ double *min, double *max)
|
|
+{
|
|
+ double a = matrix->m[0][0], c = matrix->m[0][1];
|
|
+ double b = matrix->m[1][0], d = matrix->m[1][1];
|
|
+
|
|
+ double i = a*a + c*c;
|
|
+ double j = b*b + d*d;
|
|
+
|
|
+ double f = 0.5 * (i + j);
|
|
+ double g = 0.5 * (i - j);
|
|
+ double h = a*b + c*d;
|
|
+
|
|
+ *max = sqrt (f + sqrt (g*g+h*h));
|
|
+
|
|
+ *min = sqrt (f - sqrt (g*g+h*h));
|
|
+
|
|
+ return CAIRO_STATUS_SUCCESS;
|
|
+}
|
|
+
|
|
cairo_bool_t
|
|
_cairo_matrix_is_integer_translation(cairo_matrix_t *mat,
|
|
int *itx, int *ity)
|
|
{
|
|
double a, b, c, d, tx, ty;
|
|
int ttx, tty;
|
|
int ok = 0;
|
|
cairo_matrix_get_affine (mat, &a, &b, &c, &d, &tx, &ty);
|
|
Index: cairo_pen.c
|
|
===================================================================
|
|
RCS file: /cvsroot/mozilla/gfx/cairo/cairo/src/cairo_pen.c,v
|
|
retrieving revision 1.2
|
|
diff -u -8 -p -r1.2 cairo_pen.c
|
|
--- cairo_pen.c 23 Mar 2005 19:53:39 -0000 1.2
|
|
+++ cairo_pen.c 31 Mar 2005 19:53:08 -0000
|
|
@@ -367,42 +367,24 @@ doesn't matter where on the circle the e
|
|
|
|
*/
|
|
|
|
static int
|
|
_cairo_pen_vertices_needed (double tolerance,
|
|
double radius,
|
|
cairo_matrix_t *matrix)
|
|
{
|
|
- double a = matrix->m[0][0], c = matrix->m[0][1];
|
|
- double b = matrix->m[1][0], d = matrix->m[1][1];
|
|
+ double min, max, major_axis;
|
|
+ int num_vertices;
|
|
|
|
- double i = a*a + c*c;
|
|
- double j = b*b + d*d;
|
|
-
|
|
- double f = 0.5 * (i + j);
|
|
- double g = 0.5 * (i - j);
|
|
- double h = a*b + c*d;
|
|
-
|
|
- /*
|
|
- * compute major and minor axes lengths for
|
|
- * a pen with the specified radius
|
|
- */
|
|
-
|
|
- double major_axis = radius * sqrt (f + sqrt (g*g+h*h));
|
|
-
|
|
- /*
|
|
- * we don't need the minor axis length, which is
|
|
- * double min = radius * sqrt (f - sqrt (g*g+h*h));
|
|
- */
|
|
-
|
|
+ _cairo_matrix_compute_expansion_factors (matrix, &min, &max);
|
|
+ major_axis = radius * max;
|
|
/*
|
|
* compute number of vertices needed
|
|
*/
|
|
- int num_vertices;
|
|
|
|
/* Where tolerance / M is > 1, we use 4 points */
|
|
if (tolerance >= major_axis) {
|
|
num_vertices = 4;
|
|
} else {
|
|
double delta = acos (1 - tolerance / major_axis);
|
|
num_vertices = ceil (M_PI / delta);
|
|
|
|
Index: cairoint.h
|
|
===================================================================
|
|
RCS file: /cvsroot/mozilla/gfx/cairo/cairo/src/cairoint.h,v
|
|
retrieving revision 1.4
|
|
diff -u -8 -p -r1.4 cairoint.h
|
|
--- cairoint.h 29 Mar 2005 20:53:07 -0000 1.4
|
|
+++ cairoint.h 31 Mar 2005 19:53:08 -0000
|
|
@@ -853,16 +853,18 @@ typedef struct _cairo_gstate {
|
|
cairo_line_join_t line_join;
|
|
double miter_limit;
|
|
|
|
cairo_fill_rule_t fill_rule;
|
|
|
|
double *dash;
|
|
int num_dashes;
|
|
double dash_offset;
|
|
+ double max_dash_length;
|
|
+ double fraction_dash_lit;
|
|
|
|
char *font_family; /* NULL means CAIRO_FONT_FAMILY_DEFAULT; */
|
|
cairo_font_slant_t font_slant;
|
|
cairo_font_weight_t font_weight;
|
|
|
|
cairo_font_t *font; /* Specific to the current CTM */
|
|
|
|
cairo_surface_t *surface;
|
|
@@ -1640,16 +1642,19 @@ cairo_private cairo_status_t
|
|
_cairo_matrix_compute_determinant (cairo_matrix_t *matrix, double *det);
|
|
|
|
cairo_private cairo_status_t
|
|
_cairo_matrix_compute_eigen_values (cairo_matrix_t *matrix, double *lambda1, double *lambda2);
|
|
|
|
cairo_private cairo_status_t
|
|
_cairo_matrix_compute_scale_factors (cairo_matrix_t *matrix, double *sx, double *sy, int x_major);
|
|
|
|
+cairo_private cairo_status_t
|
|
+_cairo_matrix_compute_expansion_factors (cairo_matrix_t *matrix, double *min, double *max);
|
|
+
|
|
cairo_private cairo_bool_t
|
|
_cairo_matrix_is_integer_translation(cairo_matrix_t *matrix, int *itx, int *ity);
|
|
|
|
/* cairo_traps.c */
|
|
cairo_private void
|
|
_cairo_traps_init (cairo_traps_t *traps);
|
|
|
|
cairo_private void
|