diff -Nur cairo-1.2.4/src/cairo.c cairo-1.2.4-patched/src/cairo.c --- cairo-1.2.4/src/cairo.c 2006-08-18 17:20:16.000000000 +0300 +++ cairo-1.2.4-patched/src/cairo.c 2006-12-19 09:09:01.000000000 +0200 @@ -41,6 +41,8 @@ #include "cairo-arc-private.h" #include "cairo-path-data-private.h" +#include "cairo-log-private.h" + #define CAIRO_TOLERANCE_MINIMUM 0.0002 /* We're limited by 16 bits of sub-pixel precision */ static const cairo_t cairo_nil = { @@ -1180,7 +1182,9 @@ { if (cr->status) return; - + _cairo_log_start ("cairo_new_path()"); + _cairo_log_pointer ("gstate", cr->gstate); + _cairo_log_end (); _cairo_path_fixed_fini (&cr->path); } slim_hidden_def(cairo_new_path); @@ -1202,13 +1206,31 @@ if (cr->status) return; + _cairo_log_start ("cairo_move_to()"); + _cairo_log_pointer ("gstate", cr->gstate); + _cairo_log_start ("user space"); + _cairo_log_double ("x", x); + _cairo_log_double ("y", y); + _cairo_log_end (); + _cairo_gstate_user_to_backend (cr->gstate, &x, &y); + _cairo_log_start ("device space"); + _cairo_log_double ("x", x); + _cairo_log_double ("y", y); + _cairo_log_end (); + x_fixed = _cairo_fixed_from_double (x); y_fixed = _cairo_fixed_from_double (y); + _cairo_log_start ("device spaced (fixed)"); + _cairo_log_fixed ("x_fixed", x_fixed); + _cairo_log_fixed ("y_fixed", y_fixed); + _cairo_log_end (); cr->status = _cairo_path_fixed_move_to (&cr->path, x_fixed, y_fixed); if (cr->status) _cairo_set_error (cr, cr->status); + _cairo_log_status ("status", cr->status); + _cairo_log_end (); } slim_hidden_def(cairo_move_to); @@ -1235,7 +1257,9 @@ { if (cr->status) return; - + _cairo_log_start ("cairo_new_sub_path()"); + _cairo_log_pointer ("gstate", cr->gstate); + _cairo_log_end (); _cairo_path_fixed_new_sub_path (&cr->path); } @@ -1260,13 +1284,31 @@ if (cr->status) return; + _cairo_log_start ("cairo_line_to()"); + _cairo_log_pointer ("gstate", cr->gstate); + _cairo_log_start ("user space"); + _cairo_log_double ("x", x); + _cairo_log_double ("y", y); + _cairo_log_end (); + _cairo_gstate_user_to_backend (cr->gstate, &x, &y); + _cairo_log_start ("device space"); + _cairo_log_double ("x", x); + _cairo_log_double ("y", y); + _cairo_log_end (); + x_fixed = _cairo_fixed_from_double (x); y_fixed = _cairo_fixed_from_double (y); + _cairo_log_start ("device spaced (fixed)"); + _cairo_log_fixed ("x_fixed", x_fixed); + _cairo_log_fixed ("y_fixed", y_fixed); + _cairo_log_end (); cr->status = _cairo_path_fixed_line_to (&cr->path, x_fixed, y_fixed); if (cr->status) _cairo_set_error (cr, cr->status); + _cairo_log_status ("status", cr->status); + _cairo_log_end (); } /** @@ -1301,10 +1343,30 @@ if (cr->status) return; + _cairo_log_start ("cairo_curve_to()"); + _cairo_log_pointer ("gstate", cr->gstate); + _cairo_log_start ("user space"); + _cairo_log_double ("x1", x1); + _cairo_log_double ("y1", y1); + _cairo_log_double ("x2", x2); + _cairo_log_double ("y2", y2); + _cairo_log_double ("x3", x3); + _cairo_log_double ("y3", y3); + _cairo_log_end (); + _cairo_gstate_user_to_backend (cr->gstate, &x1, &y1); _cairo_gstate_user_to_backend (cr->gstate, &x2, &y2); _cairo_gstate_user_to_backend (cr->gstate, &x3, &y3); + _cairo_log_start ("device space"); + _cairo_log_double ("x1", x1); + _cairo_log_double ("y1", y1); + _cairo_log_double ("x2", x2); + _cairo_log_double ("y2", y2); + _cairo_log_double ("x3", x3); + _cairo_log_double ("y3", y3); + _cairo_log_end (); + x1_fixed = _cairo_fixed_from_double (x1); y1_fixed = _cairo_fixed_from_double (y1); @@ -1314,12 +1376,23 @@ x3_fixed = _cairo_fixed_from_double (x3); y3_fixed = _cairo_fixed_from_double (y3); + _cairo_log_start ("device space (fixed)"); + _cairo_log_double ("x1_fixed", x1_fixed); + _cairo_log_double ("y1_fixed", y1_fixed); + _cairo_log_double ("x2_fixed", x2_fixed); + _cairo_log_double ("y2_fixed", y2_fixed); + _cairo_log_double ("x3_fixed", x3_fixed); + _cairo_log_double ("y3_fixed", y3_fixed); + _cairo_log_end (); + cr->status = _cairo_path_fixed_curve_to (&cr->path, x1_fixed, y1_fixed, x2_fixed, y2_fixed, x3_fixed, y3_fixed); if (cr->status) _cairo_set_error (cr, cr->status); + _cairo_log_status ("status", cr->status); + _cairo_log_end (); } /** @@ -1474,14 +1547,32 @@ if (cr->status) return; + _cairo_log_start ("cairo_rel_move_to()"); + _cairo_log_pointer ("gstate", cr->gstate); + _cairo_log_start ("user space"); + _cairo_log_double ("dx", dx); + _cairo_log_double ("dy", dy); + _cairo_log_end (); _cairo_gstate_user_to_device_distance (cr->gstate, &dx, &dy); + _cairo_log_start ("device space"); + _cairo_log_double ("dx", dx); + _cairo_log_double ("dy", dy); + _cairo_log_end (); + dx_fixed = _cairo_fixed_from_double (dx); dy_fixed = _cairo_fixed_from_double (dy); + _cairo_log_start ("device spaced (fixed)"); + _cairo_log_fixed ("dx_fixed", dx_fixed); + _cairo_log_fixed ("dy_fixed", dy_fixed); + _cairo_log_end (); cr->status = _cairo_path_fixed_rel_move_to (&cr->path, dx_fixed, dy_fixed); if (cr->status) _cairo_set_error (cr, cr->status); + + _cairo_log_status ("status", cr->status); + _cairo_log_end (); } /** @@ -1509,14 +1600,32 @@ if (cr->status) return; + _cairo_log_start ("cairo_rel_line_to()"); + _cairo_log_pointer ("gstate", cr->gstate); + _cairo_log_start ("user space"); + _cairo_log_double ("dx", dx); + _cairo_log_double ("dy", dy); + _cairo_log_end (); _cairo_gstate_user_to_device_distance (cr->gstate, &dx, &dy); + _cairo_log_start ("device space"); + _cairo_log_double ("dx", dx); + _cairo_log_double ("dy", dy); + _cairo_log_end (); + dx_fixed = _cairo_fixed_from_double (dx); dy_fixed = _cairo_fixed_from_double (dy); + _cairo_log_start ("device spaced (fixed)"); + _cairo_log_fixed ("dx_fixed", dx_fixed); + _cairo_log_fixed ("dy_fixed", dy_fixed); + _cairo_log_end (); cr->status = _cairo_path_fixed_rel_line_to (&cr->path, dx_fixed, dy_fixed); if (cr->status) _cairo_set_error (cr, cr->status); + + _cairo_log_status ("status", cr->status); + _cairo_log_end (); } slim_hidden_def(cairo_rel_line_to); @@ -1559,10 +1668,30 @@ if (cr->status) return; + _cairo_log_start ("cairo_rel_curve_to()"); + _cairo_log_pointer ("gstate", cr->gstate); + _cairo_log_start ("user space"); + _cairo_log_double ("dx1", dx1); + _cairo_log_double ("dy1", dy1); + _cairo_log_double ("dx2", dx2); + _cairo_log_double ("dy2", dy2); + _cairo_log_double ("dx3", dx3); + _cairo_log_double ("dy3", dy3); + _cairo_log_end (); + _cairo_gstate_user_to_device_distance (cr->gstate, &dx1, &dy1); _cairo_gstate_user_to_device_distance (cr->gstate, &dx2, &dy2); _cairo_gstate_user_to_device_distance (cr->gstate, &dx3, &dy3); + _cairo_log_start ("device space"); + _cairo_log_double ("dx1", dx1); + _cairo_log_double ("dy1", dy1); + _cairo_log_double ("dx2", dx2); + _cairo_log_double ("dy2", dy2); + _cairo_log_double ("dx3", dx3); + _cairo_log_double ("dy3", dy3); + _cairo_log_end (); + dx1_fixed = _cairo_fixed_from_double (dx1); dy1_fixed = _cairo_fixed_from_double (dy1); @@ -1572,12 +1701,23 @@ dx3_fixed = _cairo_fixed_from_double (dx3); dy3_fixed = _cairo_fixed_from_double (dy3); + _cairo_log_start ("device space (fixed)"); + _cairo_log_double ("dx1_fixed", dx1_fixed); + _cairo_log_double ("dy1_fixed", dy1_fixed); + _cairo_log_double ("dx2_fixed", dx2_fixed); + _cairo_log_double ("dy2_fixed", dy2_fixed); + _cairo_log_double ("dx3_fixed", dx3_fixed); + _cairo_log_double ("dy3_fixed", dy3_fixed); + _cairo_log_end (); + cr->status = _cairo_path_fixed_rel_curve_to (&cr->path, dx1_fixed, dy1_fixed, dx2_fixed, dy2_fixed, dx3_fixed, dy3_fixed); if (cr->status) _cairo_set_error (cr, cr->status); + _cairo_log_status ("status", cr->status); + _cairo_log_end (); } /** @@ -1607,12 +1747,13 @@ { if (cr->status) return; - + _cairo_log_start ("cairo_rectangle()"); cairo_move_to (cr, x, y); cairo_rel_line_to (cr, width, 0); cairo_rel_line_to (cr, 0, height); cairo_rel_line_to (cr, -width, 0); cairo_close_path (cr); + _cairo_log_end (); } /* XXX: NYI @@ -1659,10 +1800,13 @@ { if (cr->status) return; - + _cairo_log_start ("cairo_close_path()"); + _cairo_log_pointer ("gstate ptr", cr->gstate); cr->status = _cairo_path_fixed_close_path (&cr->path); if (cr->status) _cairo_set_error (cr, cr->status); + _cairo_log_status ("status", cr->status); + _cairo_log_end (); } slim_hidden_def(cairo_close_path); @@ -1847,10 +1991,13 @@ { if (cr->status) return; - + _cairo_log_start ("cairo_stroke_preserve()"); + _cairo_log_pointer ("gstate ptr", cr->gstate); cr->status = _cairo_gstate_stroke (cr->gstate, &cr->path); if (cr->status) _cairo_set_error (cr, cr->status); + _cairo_log_status ("cairo_stroke_preserve status", cr->status); + _cairo_log_end (); } slim_hidden_def(cairo_stroke_preserve); diff -Nur cairo-1.2.4/src/cairo-gstate.c cairo-1.2.4-patched/src/cairo-gstate.c --- cairo-1.2.4/src/cairo-gstate.c 2006-08-18 17:20:16.000000000 +0300 +++ cairo-1.2.4-patched/src/cairo-gstate.c 2006-12-19 09:09:01.000000000 +0200 @@ -41,6 +41,7 @@ #include "cairo-clip-private.h" #include "cairo-gstate-private.h" +#include "cairo-log-private.h" static cairo_status_t _cairo_gstate_init (cairo_gstate_t *gstate, @@ -131,6 +132,10 @@ gstate->next = NULL; + _cairo_log_start ("gstate_init()"); + _cairo_log_pointer ("gstate ptr", gstate); + _cairo_log_end (); + return CAIRO_STATUS_SUCCESS; } @@ -180,6 +185,13 @@ gstate->next = NULL; + _cairo_log_start ("gstate_init_copy()"); + _cairo_log_pointer ("gstate ptr", gstate); + _cairo_log_pointer ("other gstate ptr", other); + _cairo_log_matrix ("ctm", &gstate->ctm); + _cairo_log_matrix ("ctm_inverse", &gstate->ctm_inverse); + _cairo_log_end (); + return CAIRO_STATUS_SUCCESS; } @@ -565,15 +577,23 @@ _cairo_gstate_translate (cairo_gstate_t *gstate, double tx, double ty) { cairo_matrix_t tmp; + _cairo_log_start ("gstate_translate()"); + _cairo_log_pointer ("gstate ptr", gstate); + _cairo_log_double ("tx", tx); + _cairo_log_double ("ty", ty); _cairo_gstate_unset_scaled_font (gstate); cairo_matrix_init_translate (&tmp, tx, ty); + _cairo_log_matrix ("ctm before", &gstate->ctm); cairo_matrix_multiply (&gstate->ctm, &tmp, &gstate->ctm); + _cairo_log_matrix ("ctm after", &gstate->ctm); cairo_matrix_init_translate (&tmp, -tx, -ty); cairo_matrix_multiply (&gstate->ctm_inverse, &gstate->ctm_inverse, &tmp); + _cairo_log_matrix ("ctm_inverse", &gstate->ctm_inverse); + _cairo_log_end (); return CAIRO_STATUS_SUCCESS; } @@ -581,18 +601,29 @@ _cairo_gstate_scale (cairo_gstate_t *gstate, double sx, double sy) { cairo_matrix_t tmp; - - if (sx == 0 || sy == 0) + _cairo_log_start ("gstate_scale()"); + _cairo_log_pointer ("gstate ptr", gstate); + _cairo_log_double ("sx", sx); + _cairo_log_double ("sy", sy); + + if (sx == 0 || sy == 0) { + _cairo_log_status ("failed", CAIRO_STATUS_INVALID_MATRIX); + _cairo_log_end (); return CAIRO_STATUS_INVALID_MATRIX; + } _cairo_gstate_unset_scaled_font (gstate); cairo_matrix_init_scale (&tmp, sx, sy); + _cairo_log_matrix ("ctm before", &gstate->ctm); cairo_matrix_multiply (&gstate->ctm, &tmp, &gstate->ctm); + _cairo_log_matrix ("ctm after", &gstate->ctm); cairo_matrix_init_scale (&tmp, 1/sx, 1/sy); cairo_matrix_multiply (&gstate->ctm_inverse, &gstate->ctm_inverse, &tmp); + _cairo_log_matrix ("ctm_inverse", &gstate->ctm_inverse); + _cairo_log_end (); return CAIRO_STATUS_SUCCESS; } @@ -600,15 +631,22 @@ _cairo_gstate_rotate (cairo_gstate_t *gstate, double angle) { cairo_matrix_t tmp; + _cairo_log_start ("gstate_rotate()"); + _cairo_log_pointer ("gstate ptr", gstate); + _cairo_log_double ("angle", angle); _cairo_gstate_unset_scaled_font (gstate); cairo_matrix_init_rotate (&tmp, angle); + _cairo_log_matrix ("ctm before", &gstate->ctm); cairo_matrix_multiply (&gstate->ctm, &tmp, &gstate->ctm); + _cairo_log_matrix ("ctm after", &gstate->ctm); cairo_matrix_init_rotate (&tmp, -angle); cairo_matrix_multiply (&gstate->ctm_inverse, &gstate->ctm_inverse, &tmp); + _cairo_log_matrix ("ctm_inverse", &gstate->ctm_inverse); + _cairo_log_end (); return CAIRO_STATUS_SUCCESS; } @@ -617,15 +655,24 @@ const cairo_matrix_t *matrix) { cairo_matrix_t tmp; + cairo_status_t status; + _cairo_log_start ("gstate_transform()"); + _cairo_log_pointer ("gstate ptr", gstate); + _cairo_log_matrix ("input matrix", matrix); _cairo_gstate_unset_scaled_font (gstate); tmp = *matrix; + _cairo_log_matrix ("ctm before", &gstate->ctm); cairo_matrix_multiply (&gstate->ctm, &tmp, &gstate->ctm); + _cairo_log_matrix ("ctm after", &gstate->ctm); - cairo_matrix_invert (&tmp); + status = cairo_matrix_invert (&tmp); + _cairo_log_status ("inversion of input matrix", status); cairo_matrix_multiply (&gstate->ctm_inverse, &gstate->ctm_inverse, &tmp); + _cairo_log_matrix ("ctm_inverse", &gstate->ctm_inverse); + _cairo_log_end (); return CAIRO_STATUS_SUCCESS; } @@ -634,6 +681,9 @@ const cairo_matrix_t *matrix) { cairo_status_t status; + _cairo_log_start ("gstate_set_matrix()"); + _cairo_log_pointer ("gstate ptr", gstate); + _cairo_log_matrix ("input matrix", matrix); _cairo_gstate_unset_scaled_font (gstate); @@ -641,6 +691,10 @@ gstate->ctm_inverse = *matrix; status = cairo_matrix_invert (&gstate->ctm_inverse); + _cairo_log_matrix ("ctm_inverse", &gstate->ctm_inverse); + _cairo_log_status ("inversion of input matrix", status); + _cairo_log_end (); + if (status) return status; @@ -651,10 +705,13 @@ _cairo_gstate_identity_matrix (cairo_gstate_t *gstate) { _cairo_gstate_unset_scaled_font (gstate); + _cairo_log_start ("gstate_identity_matrix()"); + _cairo_log_pointer ("gstate ptr", gstate); cairo_matrix_init_identity (&gstate->ctm); cairo_matrix_init_identity (&gstate->ctm_inverse); + _cairo_log_end (); return CAIRO_STATUS_SUCCESS; } diff -Nur cairo-1.2.4/src/cairo-log.c cairo-1.2.4-patched/src/cairo-log.c --- cairo-1.2.4/src/cairo-log.c 1970-01-01 02:00:00.000000000 +0200 +++ cairo-1.2.4-patched/src/cairo-log.c 2006-12-19 09:09:01.000000000 +0200 @@ -0,0 +1,684 @@ +#include "cairoint.h" +#include "cairo-log-private.h" +#include "cairo-path-fixed-private.h" +#include +#include + +static int _dump_debug_level = 0; +static int _dump_debug_done_indent = 0; + +static cairo_status_t _cairo_log_move_to (void *unused_closure, cairo_point_t *p); +static cairo_status_t _cairo_log_line_to (void *unused_closure, cairo_point_t *p); +static cairo_status_t _cairo_log_close_path (void *unused_closure); +static cairo_status_t _cairo_log_curve_to ( + void *unused_closure, + cairo_point_t *ctrl1, + cairo_point_t *ctrl2, + cairo_point_t *stop); + + +void /*__attribute__((format (printf, 1, 2)))*/ +_cairo_log_vprintf (char const *fmt, va_list ap) +{ + static FILE *log_fp = NULL; + if (!log_fp) { + char filename[100]; + pid_t stamp = getpid(); + sprintf (filename, "/tmp/debug-cairo.%llu.log", (uint64_t)stamp); + log_fp = fopen (filename, "wb"); + assert (log_fp || "can't open debugging log file in stroker"); + } + vfprintf (log_fp, fmt, ap); + fflush (log_fp); +} + +void +_cairo_log_printf (char const *fmt, ...) +{ + va_list ap; + va_start (ap, fmt); + _cairo_log_vprintf (fmt, ap); + va_end (ap); +} + +void +_cairo_log_start (char const *name) +{ + int i; + if (_dump_debug_done_indent) { + _cairo_log_printf("\n"); + } + /*_cairo_log_printf ("%-3d ", _dump_debug_level);*/ + for (i=0; i < _dump_debug_level; i++) { + _cairo_log_printf ("\t"); + } + if (name) _cairo_log_printf ("%s=", name); + _dump_debug_level++; + _dump_debug_done_indent = 1; +} + +void +_cairo_log_end (void) +{ + --_dump_debug_level; + if (_dump_debug_done_indent) + _cairo_log_printf ("\n"); + _dump_debug_done_indent = 0; +} + +void +_cairo_log_start_array(char const *name, int size) +{ + _cairo_log_start (name); + _cairo_log_printf ("[%d]", size); +} + +void +_cairo_log_end_array(void) +{ + _cairo_log_end (); +} + +void /*__attribute__((format (printf, 2, 3)))*/ +_cairo_log_stringf (char const *name, char const *fmt, ...) +{ + va_list ap; + va_start (ap, fmt); + _cairo_log_start (name); + _cairo_log_vprintf (fmt, ap); + _cairo_log_end (); + va_end (ap); +} + +void +_cairo_log_bytes (void const *buf, size_t size) +{ + size_t i; + uint8_t const *bytes= buf; + for (i=0; buf && iline_width); + _cairo_log_line_cap ("line_cap", style->line_cap); + _cairo_log_line_join ("line_join", style->line_join); + _cairo_log_double ("miter_limit", style->miter_limit); + _cairo_log_double_array ("dash", style->dash, style->num_dashes, _cairo_log_content); + _cairo_log_double ("dash_offset", style->dash_offset); + _cairo_log_end (); +} + +static cairo_status_t +_cairo_log_move_to (void *unused_closure, cairo_point_t *p) +{ + (void)unused_closure; + _cairo_log_point ("moveto", *p); + return CAIRO_STATUS_SUCCESS; +} + +static cairo_status_t +_cairo_log_line_to (void *unused_closure, cairo_point_t *p) +{ + (void)unused_closure; + _cairo_log_point ("lineto", *p); + return CAIRO_STATUS_SUCCESS; +} + +static cairo_status_t +_cairo_log_curve_to (void *unused_closure, + cairo_point_t *ctrl1, + cairo_point_t *ctrl2, + cairo_point_t *stop) +{ + (void)unused_closure; + _cairo_log_point ("curveto_ctrl1", *ctrl1); + _cairo_log_point ("curveto_ctrl2", *ctrl2); + _cairo_log_point ("curveto_stop", *stop); + return CAIRO_STATUS_SUCCESS; +} + +static cairo_status_t +_cairo_log_close_path (void *unused_closure) +{ + (void)unused_closure; + _cairo_log_start ("closepath"); + _cairo_log_end (); + return CAIRO_STATUS_SUCCESS; +} + +void +_cairo_log_path_fixed (char const *name, cairo_path_fixed_t *path) +{ + _cairo_log_start (name); + _cairo_log_bool ("has_current_point", path->has_current_point); + _cairo_log_point ("last_move_point", path->last_move_point); + _cairo_log_point ("current_point", path->current_point); + + _cairo_log_start ("ops"); + _cairo_path_fixed_interpret (path, CAIRO_DIRECTION_FORWARD, + _cairo_log_move_to, + _cairo_log_line_to, + _cairo_log_curve_to, + _cairo_log_close_path, + NULL); + _cairo_log_end (); + _cairo_log_end (); +} + +void +_cairo_log_matrix (char const *name, cairo_matrix_t const *m) +{ + _cairo_log_start (name); + _cairo_log_double ("xx", m->xx); + _cairo_log_double ("yx", m->yx); + _cairo_log_double ("xy", m->xy); + _cairo_log_double ("yy", m->yy); + _cairo_log_double ("x0", m->x0); + _cairo_log_double ("y0", m->y0); + _cairo_log_end (); +} + +void +_cairo_log_pattern (char const *name, cairo_pattern_t const *pat) +{ + _cairo_log_start (name); + if (pat) { + _cairo_log_pattern_type ("type", pat->type); + _cairo_log_int ("ref_count", pat->ref_count); + _cairo_log_status ("status", pat->status); + _cairo_log_filter ("filter", pat->filter); + _cairo_log_extend ("extend", pat->extend); + _cairo_log_matrix ("matrix", &pat->matrix); + } + _cairo_log_end (); +} + +void +_cairo_log_slope (char const *name, cairo_slope_t s) +{ + cairo_point_t p; + p.x = s.dx; + p.y = s.dy; + _cairo_log_point (name, p); +} + +void +_cairo_log_stroke_face (char const *name, cairo_stroke_face_t const *face) +{ + _cairo_log_start (name); + if (face) { + _cairo_log_point ("ccw", face->ccw); + _cairo_log_point ("point", face->point); + _cairo_log_point ("cw", face->cw); + _cairo_log_slope ("dev_vector", face->dev_vector); + _cairo_log_point_double ("usr_vector", face->usr_vector); + } + _cairo_log_end (); +} + +static void +_cairo_log_pen_vertex (cairo_pen_vertex_t const *vertex) +{ + if (vertex) { + _cairo_log_point ("point", vertex->point); + _cairo_log_slope ("slope_ccw", vertex->slope_ccw); + _cairo_log_slope ("slope_cw", vertex->slope_cw); + } +} + +void +_cairo_log_pen (char const *name, cairo_pen_t const *pen, cairo_bool_t _cairo_log_contents) +{ + int i; + _cairo_log_start (name); + if (pen) { + _cairo_log_double ("radius", pen->radius); + _cairo_log_double ("tolerance", pen->tolerance); + + _cairo_log_start_array ("vertices", pen->num_vertices); + for (i=0; _cairo_log_contents && inum_vertices; i++) { + _cairo_log_pen_vertex(pen->vertices + i); + } + _cairo_log_end_array (); + } + _cairo_log_end (); +} + +void +_cairo_log_line(char const *name, cairo_line_t const *line) +{ + _cairo_log_start (name); + if (line) { + _cairo_log_point ("p1", line->p1); + _cairo_log_point ("p2", line->p2); + } + _cairo_log_end (); +} + +void +_cairo_log_box(char const *name, cairo_box_t const *box) +{ + _cairo_log_line (name, box); +} + +void +_cairo_log_trapezoid(char const *name, cairo_trapezoid_t const *trap) +{ + _cairo_log_start (name); + if (trap) { + _cairo_log_fixed ("top", trap->top); + _cairo_log_fixed ("bottom", trap->bottom); + _cairo_log_line ("left", &trap->left); + _cairo_log_line ("right", &trap->right); + if (trap->top > trap->bottom) { + _cairo_log_bool ("warning: top>bottom", TRUE); + } + } + _cairo_log_end (); +} + +void +_cairo_log_traps(char const *name, cairo_traps_t const *traps, cairo_bool_t log_content) +{ + _cairo_log_start (name); + if (traps) { + int i; + _cairo_log_int ("num_traps", traps->num_traps); + _cairo_log_int ("traps_size", traps->traps_size); + _cairo_log_box ("extents", &traps->extents); + _cairo_log_start_array ("traps", traps->num_traps); + for (i=0; log_content && traps->traps && inum_traps; i++) { + char buf[40]; + sprintf(buf, "traps[%d]", i); + _cairo_log_trapezoid(buf, traps->traps + i); + } + _cairo_log_end_array (); + } + _cairo_log_end (); +} diff -Nur cairo-1.2.4/src/cairo-log-private.h cairo-1.2.4-patched/src/cairo-log-private.h --- cairo-1.2.4/src/cairo-log-private.h 1970-01-01 02:00:00.000000000 +0200 +++ cairo-1.2.4-patched/src/cairo-log-private.h 2006-12-19 09:09:01.000000000 +0200 @@ -0,0 +1,202 @@ +#ifndef _CAIRO_LOG_H +#define _CAIRO_LOG_H + +#include "cairoint.h" + +cairo_private void /*__attribute__((format (printf, 1, 2)))*/ +_cairo_log_vprintf ( + char const *fmt, + va_list ap); + +cairo_private void /*__attribute__((format (printf, 1, 2)))*/ +_cairo_log_printf ( + char const *fmt, + ...); + +cairo_private void +_cairo_log_start ( + char const *name); + +cairo_private void +_cairo_log_end (void); + +cairo_private void +_cairo_log_start_array ( + char const *name, + int size); + +cairo_private void +_cairo_log_end_array (void); + +cairo_private void /*__attribute__((format (printf, 2, 3)))*/ +_cairo_log_stringf ( + char const *name, + char const *fmt, + ...) ; + +cairo_private void +_cairo_log_bytes ( + void const *buf, + size_t size); + +cairo_private void +_cairo_log_double_bytes ( + char const *name, + double const *ptr); + +cairo_private void +_cairo_log_double ( + char const *name, + double value); + +cairo_private void +_cairo_log_double_array ( + char const *name, + double const *ary, + unsigned n, + cairo_bool_t log_content); + +cairo_private void +_cairo_log_bool( + char const *name, + cairo_bool_t value); + +cairo_private void +_cairo_log_int ( + char const *name, + int x); + +cairo_private void +_cairo_log_fixed ( + char const *name, + cairo_fixed_t x); + +cairo_private void +_cairo_log_point ( + char const *name, + cairo_point_t point); + +cairo_private void +_cairo_log_point_double ( + char const *name, + cairo_point_double_t p); + +cairo_private void +_cairo_log_pointer ( + char const *name, + void const *ptr); + +cairo_private void +_cairo_log_status ( + char const *name, + cairo_status_t status); + +cairo_private void +_cairo_log_int_status ( + char const *name, + cairo_int_status_t status); + +cairo_private void +_cairo_log_content ( + char const *name, + cairo_content_t content); + +cairo_private void +_cairo_log_operator ( + char const *name, + cairo_operator_t op); + +cairo_private void +_cairo_log_antialias ( + char const *name, + cairo_antialias_t antialias); + +cairo_private void +_cairo_log_fill_rule ( + char const *name, + cairo_fill_rule_t fill_rule); + +cairo_private void +_cairo_log_line_cap ( + char const *name, + cairo_line_cap_t cap); + +cairo_private void +_cairo_log_line_join ( + char const *name, + cairo_line_join_t line_join); + +cairo_private void +_cairo_log_pattern_type ( + char const *name, + cairo_pattern_type_t pattern); + +cairo_private void +_cairo_log_extend ( + char const *name, + cairo_extend_t extend); + +cairo_private void +_cairo_log_filter ( + char const *name, + cairo_filter_t filter); + +cairo_private void +_cairo_log_path_fixed ( + char const *name, + cairo_path_fixed_t *path); + +cairo_private void +_cairo_log_matrix ( + char const *name, + cairo_matrix_t const *m); + +cairo_private void +_cairo_log_pattern ( + char const *name, + cairo_pattern_t const *pat); + +cairo_private void +_cairo_log_slope ( + char const *name, + cairo_slope_t s); + +cairo_private void +_cairo_log_stroke_style ( + char const *name, + cairo_stroke_style_t const *style, + cairo_bool_t log_content); + +cairo_private void +_cairo_log_stroke_face ( + char const *name, + cairo_stroke_face_t const *face); + +cairo_private void +_cairo_log_pen ( + char const *name, + cairo_pen_t const *pen, + cairo_bool_t log_content); + +cairo_private void +_cairo_log_line ( + char const *name, + cairo_line_t const *line); + +cairo_private void +_cairo_log_box ( + char const *name, + cairo_box_t const *box); + +cairo_private void +_cairo_log_trapezoid ( + char const *name, + cairo_trapezoid_t const *trap); + +cairo_private void +_cairo_log_traps ( + char const *name, + cairo_traps_t const *traps, + cairo_bool_t log_content); + +#endif /* _CAIRO_LOG_H */ diff -Nur cairo-1.2.4/src/cairo-path-stroke.c cairo-1.2.4-patched/src/cairo-path-stroke.c --- cairo-1.2.4/src/cairo-path-stroke.c 2006-08-18 17:53:02.000000000 +0300 +++ cairo-1.2.4-patched/src/cairo-path-stroke.c 2006-12-19 09:09:01.000000000 +0200 @@ -35,6 +35,7 @@ */ #include "cairoint.h" +#include "cairo-log-private.h" typedef struct cairo_stroker { cairo_stroke_style_t *style; @@ -108,6 +109,29 @@ static cairo_status_t _cairo_stroker_join (cairo_stroker_t *stroker, cairo_stroke_face_t *in, cairo_stroke_face_t *out); +static void +_cairo_log_stroker(char const *name, cairo_stroker_t const *stroker) +{ + _cairo_log_start(name); + _cairo_log_double("tolerance", stroker->tolerance); + _cairo_log_point("current point", stroker->current_point); + _cairo_log_point("first_point", stroker->first_point); + _cairo_log_bool("has_sub_path", stroker->has_sub_path); + _cairo_log_bool("has_current_face", stroker->has_current_face); + _cairo_log_bool("has_first_face", stroker->has_first_face); + _cairo_log_bool("dashed", stroker->dashed); + _cairo_log_int("dash_index", stroker->dash_index); + _cairo_log_bool("dash_on", stroker->dash_on); + _cairo_log_double("dash_remain", stroker->dash_remain); + _cairo_log_stroke_face("current_face", &stroker->current_face); + _cairo_log_stroke_face("first_face", &stroker->first_face); + _cairo_log_matrix("ctm", stroker->ctm); + _cairo_log_matrix("ctm_inverse", stroker->ctm_inverse); + _cairo_log_stroke_style("style", stroker->style, TRUE); + _cairo_log_pen("pen", &stroker->pen, FALSE); + _cairo_log_traps("traps", stroker->traps, FALSE); + _cairo_log_end(); +} static void _cairo_stroker_start_dash (cairo_stroker_t *stroker) @@ -115,6 +139,7 @@ double offset; int on = 1; unsigned int i = 0; + _cairo_log_start ("stroker_start_dash()"); offset = stroker->style->dash_offset; @@ -122,6 +147,9 @@ offset reaches zero. Otherwise when an initial dash segment shrinks to zero it will be skipped over. */ while (offset > 0.0 && offset >= stroker->style->dash[i]) { + _cairo_log_int ("i", i); + _cairo_log_double ("dash[i]", stroker->style->dash[i]); + _cairo_log_double ("offset", offset); offset -= stroker->style->dash[i]; on = 1-on; if (++i == stroker->style->num_dashes) @@ -131,19 +159,39 @@ stroker->dash_index = i; stroker->dash_on = on; stroker->dash_remain = stroker->style->dash[i] - offset; + + _cairo_log_bool ("dashed", stroker->dashed); + _cairo_log_bool ("dash_on", stroker->dash_on); + _cairo_log_double ("dash_remain", stroker->dash_remain); + _cairo_log_int ("dash_index", stroker->dash_index); + _cairo_log_end (); } static void _cairo_stroker_step_dash (cairo_stroker_t *stroker, double step) { + _cairo_log_start ("stroker_step_dash()"); + _cairo_log_double ("step", step); + _cairo_log_int ("dash_index", stroker->dash_index); + _cairo_log_double ("dash_remain", stroker->dash_remain); + stroker->dash_remain -= step; + + _cairo_log_double ("new dash_remain", stroker->dash_remain); + if (stroker->dash_remain <= 0) { stroker->dash_index++; if (stroker->dash_index == stroker->style->num_dashes) stroker->dash_index = 0; stroker->dash_on = 1-stroker->dash_on; stroker->dash_remain = stroker->style->dash[stroker->dash_index]; + + _cairo_log_bool ("advanced", TRUE); + _cairo_log_int ("dash_index", stroker->dash_index); + _cairo_log_bool ("dash_on", stroker->dash_on); + _cairo_log_double ("dash_remain", stroker->dash_remain); } + _cairo_log_end (); } static void @@ -154,24 +202,34 @@ double tolerance, cairo_traps_t *traps) { + memset (stroker, 0xAB, sizeof(cairo_stroker_t)); + _cairo_log_start ("stroker_init()"); + _cairo_log_stroke_style ("style", stroke_style, TRUE); + _cairo_log_matrix ("ctm", ctm); + _cairo_log_matrix ("ctm_inverse", ctm_inverse); + _cairo_log_double ("tolerance", tolerance); + _cairo_log_traps ("traps", traps, FALSE); + stroker->style = stroke_style; stroker->ctm = ctm; stroker->ctm_inverse = ctm_inverse; stroker->tolerance = tolerance; stroker->traps = traps; - _cairo_pen_init (&stroker->pen, - stroke_style->line_width / 2.0, - tolerance, ctm); - stroker->has_current_face = FALSE; stroker->has_first_face = FALSE; stroker->has_sub_path = FALSE; + _cairo_pen_init (&stroker->pen, + stroke_style->line_width / 2.0, + tolerance, ctm); + _cairo_log_pen ("pen", &stroker->pen, FALSE); + if (stroker->style->dash) _cairo_stroker_start_dash (stroker); else stroker->dashed = FALSE; + _cairo_log_end (); } static void @@ -191,25 +249,39 @@ _cairo_stroker_face_clockwise (cairo_stroke_face_t *in, cairo_stroke_face_t *out) { cairo_slope_t in_slope, out_slope; - + int cw; + _cairo_log_start ("stroker_face_clockwise()"); + _cairo_log_stroke_face ("in", in); + _cairo_log_stroke_face ("out", out); _cairo_slope_init (&in_slope, &in->point, &in->cw); _cairo_slope_init (&out_slope, &out->point, &out->cw); - return _cairo_slope_clockwise (&in_slope, &out_slope); + cw = _cairo_slope_clockwise (&in_slope, &out_slope); + _cairo_log_int("result cw", cw); + _cairo_log_end (); + return cw; } 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; - int clockwise = _cairo_stroker_face_clockwise (out, in); + int clockwise; cairo_point_t *inpt, *outpt; + _cairo_log_start ("stroker_join()"); + _cairo_log_stroke_face ("in", in); + _cairo_log_stroke_face ("out", out); + + clockwise = _cairo_stroker_face_clockwise (out, in); + _cairo_log_int ("clockwise", clockwise); if (in->cw.x == out->cw.x && in->cw.y == out->cw.y && in->ccw.x == out->ccw.x && in->ccw.y == out->ccw.y) { + _cairo_log_int_status ("status", CAIRO_INT_STATUS_NOTHING_TO_DO); + _cairo_log_end (); return CAIRO_STATUS_SUCCESS; } @@ -220,6 +292,9 @@ inpt = &in->cw; outpt = &out->cw; } + _cairo_log_point("inpt", *inpt); + _cairo_log_point("outpt", *outpt); + _cairo_log_line_join ("line_join", stroker->style->line_join); switch (stroker->style->line_join) { case CAIRO_LINE_JOIN_ROUND: { @@ -228,6 +303,8 @@ cairo_point_t tri[3]; cairo_pen_t *pen = &stroker->pen; + _cairo_log_start("case CAIRO_LINE_JOIN_ROUND:"); + tri[0] = in->point; if (clockwise) { _cairo_pen_find_active_ccw_vertex_index (pen, &in->dev_vector, &start); @@ -238,11 +315,22 @@ step = +1; _cairo_pen_find_active_cw_vertex_index (pen, &out->dev_vector, &stop); } + _cairo_log_int ("start", start); + _cairo_log_int ("stop", stop); + _cairo_log_int ("step", step); + assert(0 <= start && start < pen->num_vertices); + assert(0 <= stop && stop < pen->num_vertices); i = start; tri[1] = *inpt; + _cairo_log_start_array ("trifan", abs(start-stop)); while (i != stop) { tri[2] = in->point; + _cairo_log_int ("i", i); + _cairo_log_point ("[0]", tri[0]); + _cairo_log_point ("[1]", tri[1]); + _cairo_log_point ("[2]", tri[2]); + _translate_point (&tri[2], &pen->vertices[i].point); _cairo_traps_tessellate_triangle (stroker->traps, tri); tri[1] = tri[2]; @@ -254,8 +342,15 @@ } tri[2] = *outpt; - - return _cairo_traps_tessellate_triangle (stroker->traps, tri); + _cairo_log_int ("i", i); + _cairo_log_point ("[0]", tri[0]); + _cairo_log_point ("[1]", tri[1]); + _cairo_log_point ("[2]", tri[2]); + + status = _cairo_traps_tessellate_triangle (stroker->traps, tri); + _cairo_log_end_array (); + _cairo_log_end (); + goto out; } case CAIRO_LINE_JOIN_MITER: default: { @@ -264,7 +359,9 @@ (-in->usr_vector.y * out->usr_vector.y)); double ml = stroker->style->miter_limit; - /* + _cairo_log_start("case CAIRO_LINE_JOIN_MITER:"); + + /* (FIXME: comments -- sec = 1/cos) * Check the miter limit -- lines meeting at an acute angle * can generate long miters, the limit converts them to bevel * @@ -292,6 +389,11 @@ * 2 <= ml² (1 - in · out) * */ + _cairo_log_double ("-in.out", in_dot_out); + _cairo_log_double ("test qty (must be >= 2)", ml*ml*(1-in_dot_out)); + _cairo_log_double ("miter limit", ml); + _cairo_log_bool ("accept miter limit test", 2 <= ml*ml*(1-in_dot_out)); + if (2 <= ml * ml * (1 - in_dot_out)) { double x1, y1, x2, y2; double mx, my; @@ -310,14 +412,34 @@ y1 = _cairo_fixed_to_double (inpt->y); dx1 = in->usr_vector.x; dy1 = in->usr_vector.y; + _cairo_log_start ("user space"); + _cairo_log_double ("x1", x1); + _cairo_log_double ("y1", y1); + _cairo_log_double ("dx1", dx1); + _cairo_log_double ("dy1", dy1); + _cairo_log_end (); cairo_matrix_transform_distance (stroker->ctm, &dx1, &dy1); + _cairo_log_start ("device space"); + _cairo_log_double ("dx1", dx1); + _cairo_log_double ("dy1", dy1); + _cairo_log_end (); /* 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_log_start ("user space"); + _cairo_log_double ("x2", x2); + _cairo_log_double ("y2", y2); + _cairo_log_double ("dx2", dx2); + _cairo_log_double ("dy2", dy2); + _cairo_log_end (); cairo_matrix_transform_distance (stroker->ctm, &dx2, &dy2); + _cairo_log_start ("device space"); + _cairo_log_double ("dx2", dx2); + _cairo_log_double ("dy2", dy2); + _cairo_log_end (); /* * Compute the location of the outer corner of the miter. @@ -329,10 +451,12 @@ */ my = (((x2 - x1) * dy1 * dy2 - y2 * dx2 * dy1 + y1 * dx1 * dy2) / (dx1 * dy2 - dx2 * dy1)); + _cairo_log_double ("my", my); if (fabs (dy1) >= fabs (dy2)) mx = (my - y1) * dx1 / dy1 + x1; else mx = (my - y2) * dx2 / dy2 + x2; + _cairo_log_double ("mx", mx); /* * Draw the quadrilateral @@ -345,33 +469,55 @@ _cairo_polygon_line_to (&polygon, &outer); _cairo_polygon_line_to (&polygon, outpt); _cairo_polygon_close (&polygon); + + _cairo_log_start ("quad"); + _cairo_log_point("[0]", in->point); + _cairo_log_point("[1]", *inpt); + _cairo_log_point("[2]", outer); + _cairo_log_point("[3]", *outpt); + _cairo_log_end (); status = _cairo_traps_tessellate_polygon (stroker->traps, &polygon, CAIRO_FILL_RULE_WINDING); _cairo_polygon_fini (&polygon); - return status; + _cairo_log_end (); /* end "case ... JOIN_MITER:" */ + goto out; } /* fall through ... */ + _cairo_log_end (); /* end "case ... JOIN_MITER:" */ } case CAIRO_LINE_JOIN_BEVEL: { cairo_point_t tri[3]; tri[0] = in->point; tri[1] = *inpt; tri[2] = *outpt; - - return _cairo_traps_tessellate_triangle (stroker->traps, tri); + _cairo_log_start ("case CAIRO_LINE_JOIN_BEVEL:"); + _cairo_log_point ("[0]", tri[0]); + _cairo_log_point ("[1]", tri[1]); + _cairo_log_point ("[2]", tri[2]); + status = _cairo_traps_tessellate_triangle (stroker->traps, tri); + _cairo_log_end (); } } + + out: + _cairo_log_status ("join status", status); + _cairo_log_end (); + return status; } static cairo_status_t _cairo_stroker_add_cap (cairo_stroker_t *stroker, cairo_stroke_face_t *f) { cairo_status_t status; - - if (stroker->style->line_cap == CAIRO_LINE_CAP_BUTT) + _cairo_log_start ("stroker_add_cap"); + _cairo_log_line_cap ("cap", stroker->style->line_cap); + if (stroker->style->line_cap == CAIRO_LINE_CAP_BUTT) { + _cairo_log_int_status ("bailing on butt cap", CAIRO_INT_STATUS_NOTHING_TO_DO); + _cairo_log_end (); return CAIRO_STATUS_SUCCESS; + } switch (stroker->style->line_cap) { case CAIRO_LINE_CAP_ROUND: { @@ -381,23 +527,45 @@ cairo_point_t tri[3]; cairo_pen_t *pen = &stroker->pen; + _cairo_log_start ("case CAIRO_LINE_CAP_ROUND:"); + _cairo_log_stroke_face("face", f); + slope = f->dev_vector; _cairo_pen_find_active_cw_vertex_index (pen, &slope, &start); + + _cairo_log_int ("start", start); + assert(0 <= start && start < pen->num_vertices); + slope.dx = -slope.dx; slope.dy = -slope.dy; _cairo_pen_find_active_cw_vertex_index (pen, &slope, &stop); + _cairo_log_int ("stop", stop); + assert(0 <= stop && stop < pen->num_vertices); + tri[0] = f->point; tri[1] = f->cw; + _cairo_log_start_array ("trifan", abs(start-stop)); for (i=start; i != stop; i = (i+1) % pen->num_vertices) { tri[2] = f->point; _translate_point (&tri[2], &pen->vertices[i].point); + _cairo_log_int ("i", i); + _cairo_log_point ("[0]", tri[0]); + _cairo_log_point ("[1]", tri[1]); + _cairo_log_point ("[2]", tri[2]); _cairo_traps_tessellate_triangle (stroker->traps, tri); tri[1] = tri[2]; } tri[2] = f->ccw; - - return _cairo_traps_tessellate_triangle (stroker->traps, tri); + _cairo_log_int ("i", i); + _cairo_log_point ("[0]", tri[0]); + _cairo_log_point ("[1]", tri[1]); + _cairo_log_point ("[2]", tri[2]); + _cairo_log_end_array (); + + status = _cairo_traps_tessellate_triangle (stroker->traps, tri); + _cairo_log_end (); + goto out; } case CAIRO_LINE_CAP_SQUARE: { double dx, dy; @@ -405,18 +573,40 @@ cairo_point_t occw, ocw; cairo_polygon_t polygon; + _cairo_log_start ("case CAIRO_LINE_CAP_ROUND:"); + _cairo_log_stroke_face ("face", f); + _cairo_log_double ("line_width", stroker->style->line_width ); + dx = f->usr_vector.x; dy = f->usr_vector.y; + _cairo_log_start ("line width scaled usr_vector"); dx *= stroker->style->line_width / 2.0; dy *= stroker->style->line_width / 2.0; + _cairo_log_double ("dx", dx); + _cairo_log_double ("dy", dy); + _cairo_log_end (); + cairo_matrix_transform_distance (stroker->ctm, &dx, &dy); + _cairo_log_start ("device space"); + _cairo_log_double ("dx", dx); + _cairo_log_double ("dy", dy); fvector.dx = _cairo_fixed_from_double (dx); fvector.dy = _cairo_fixed_from_double (dy); + _cairo_log_slope ("fvector", fvector); + _cairo_log_end (); + occw.x = f->ccw.x + fvector.dx; occw.y = f->ccw.y + fvector.dy; ocw.x = f->cw.x + fvector.dx; ocw.y = f->cw.y + fvector.dy; + _cairo_log_start ("quad"); + _cairo_log_point("[0]", f->cw); + _cairo_log_point("[1]", ocw); + _cairo_log_point("[2]", occw); + _cairo_log_point("[3]", f->ccw); + _cairo_log_end (); + _cairo_polygon_init (&polygon); _cairo_polygon_move_to (&polygon, &f->cw); _cairo_polygon_line_to (&polygon, &ocw); @@ -426,13 +616,19 @@ status = _cairo_traps_tessellate_polygon (stroker->traps, &polygon, CAIRO_FILL_RULE_WINDING); _cairo_polygon_fini (&polygon); - - return status; + _cairo_log_end (); + goto out; } case CAIRO_LINE_CAP_BUTT: default: - return CAIRO_STATUS_SUCCESS; + _cairo_log_int_status ("unexpected bailing on default case", + CAIRO_INT_STATUS_NOTHING_TO_DO); } + + out: + _cairo_log_status ("cap status", status); + _cairo_log_end (); + return status; } static cairo_status_t @@ -441,6 +637,9 @@ { cairo_stroke_face_t reversed; cairo_point_t t; + cairo_status_t status; + + _cairo_log_start ("stroker_add_leading_cap()"); reversed = *face; @@ -453,14 +652,23 @@ reversed.cw = reversed.ccw; reversed.ccw = t; - return _cairo_stroker_add_cap (stroker, &reversed); + status = _cairo_stroker_add_cap (stroker, &reversed); + + _cairo_log_status ("leading cap status", status); + _cairo_log_end (); + return status; } static cairo_status_t _cairo_stroker_add_trailing_cap (cairo_stroker_t *stroker, cairo_stroke_face_t *face) { - return _cairo_stroker_add_cap (stroker, face); + cairo_status_t status; + _cairo_log_start ("stroker_add_trailing_cap()"); + status = _cairo_stroker_add_cap (stroker, face); + _cairo_log_status ("trailing cap status", status); + _cairo_log_end (); + return status; } static void @@ -469,7 +677,13 @@ static cairo_status_t _cairo_stroker_add_caps (cairo_stroker_t *stroker) { - cairo_status_t status; + cairo_status_t status = CAIRO_STATUS_SUCCESS; + + _cairo_log_start ("stroker_add_caps()"); + _cairo_log_bool ("has_sub_path", stroker->has_sub_path); + _cairo_log_bool ("has_first_face", stroker->has_first_face); + _cairo_log_bool ("has_current_face", stroker->has_current_face); + /* check for a degenerative sub_path */ if (stroker->has_sub_path && !stroker->has_first_face @@ -478,6 +692,7 @@ { /* pick an arbitrary slope to use */ cairo_slope_t slope = {1, 0}; + _cairo_log_bool("degenerate sub path", TRUE); _compute_face (&stroker->first_point, &slope, stroker, &stroker->first_face); stroker->has_first_face = stroker->has_current_face = TRUE; @@ -487,16 +702,19 @@ if (stroker->has_first_face) { status = _cairo_stroker_add_leading_cap (stroker, &stroker->first_face); if (status) - return status; + goto out; } if (stroker->has_current_face) { status = _cairo_stroker_add_trailing_cap (stroker, &stroker->current_face); if (status) - return status; + goto out; } - return CAIRO_STATUS_SUCCESS; + out: + _cairo_log_status ("add caps status", status); + _cairo_log_end (); + return status; } static void @@ -508,14 +726,28 @@ cairo_point_double_t usr_vector; cairo_point_t offset_ccw, offset_cw; + _cairo_log_start ("_compute_face()"); + _cairo_log_slope ("slope", *slope); + line_dx = _cairo_fixed_to_double (slope->dx); line_dy = _cairo_fixed_to_double (slope->dy); + _cairo_log_start ("device space"); + _cairo_log_double ("line_dx", line_dx); + _cairo_log_double ("line_dy", line_dy); + _cairo_log_end (); /* faces are normal in user space, not device space */ cairo_matrix_transform_distance (stroker->ctm_inverse, &line_dx, &line_dy); + _cairo_log_start ("user space"); + _cairo_log_double ("line_dx", line_dx); + _cairo_log_double ("line_dy", line_dy); + _cairo_log_end (); mag = sqrt (line_dx * line_dx + line_dy * line_dy); + _cairo_log_double("mag", mag); if (mag == 0) { + _cairo_log_stringf("WARNING", "_compute_face() bailed: magnitudeless direction vector?"); + _cairo_log_end (); /* XXX: Can't compute other face points. Do we want a tag in the face for this case? */ return; } @@ -523,6 +755,10 @@ /* normalize to unit length */ line_dx /= mag; line_dy /= mag; + _cairo_log_start ("normalised in user space"); + _cairo_log_double ("line_dx", line_dx); + _cairo_log_double ("line_dy", line_dy); + _cairo_log_end (); usr_vector.x = line_dx; usr_vector.y = line_dy; @@ -535,6 +771,8 @@ * by looking at the determinant of the matrix. */ _cairo_matrix_compute_determinant (stroker->ctm, &det); + _cairo_log_double ("CTM det", det); + _cairo_log_double ("line_width", stroker->style->line_width); if (det >= 0) { face_dx = - line_dy * (stroker->style->line_width / 2.0); @@ -545,9 +783,17 @@ face_dx = line_dy * (stroker->style->line_width / 2.0); face_dy = - line_dx * (stroker->style->line_width / 2.0); } + _cairo_log_start ("user space"); + _cairo_log_double ("face_dx", face_dx); + _cairo_log_double ("face_dy", face_dy); + _cairo_log_end (); /* back to device space */ cairo_matrix_transform_distance (stroker->ctm, &face_dx, &face_dy); + _cairo_log_start ("device space"); + _cairo_log_double ("face_dx", face_dx); + _cairo_log_double ("face_dy", face_dy); + _cairo_log_end (); offset_ccw.x = _cairo_fixed_from_double (face_dx); offset_ccw.y = _cairo_fixed_from_double (face_dy); @@ -556,7 +802,6 @@ face->ccw = *point; _translate_point (&face->ccw, &offset_ccw); - face->point = *point; face->cw = *point; @@ -566,6 +811,8 @@ face->usr_vector.y = usr_vector.y; face->dev_vector = *slope; + _cairo_log_stroke_face ("_compute_face() result", face); + _cairo_log_end(); } static cairo_status_t @@ -576,6 +823,11 @@ cairo_status_t status; cairo_polygon_t polygon; + _cairo_log_start ("stroker_add_sub_edge()"); + _cairo_log_point ("p1", *p1); + _cairo_log_point ("p2", *p2); + _cairo_log_slope("slope", *slope); + _compute_face (p1, slope, stroker, start); /* XXX: This could be optimized slightly by not calling @@ -583,8 +835,12 @@ fields from start. */ _compute_face (p2, slope, stroker, end); - if (p1->x == p2->x && p1->y == p2->y) - return CAIRO_STATUS_SUCCESS; + + if (p1->x == p2->x && p1->y == p2->y) { + _cairo_log_int_status ("aborted: p1,p2 are equal", CAIRO_INT_STATUS_NOTHING_TO_DO); + status = CAIRO_STATUS_SUCCESS; + goto out; + } /* XXX: I should really check the return value of the move_to/line_to functions here to catch out of memory @@ -592,6 +848,13 @@ status flag to the polygon object that I could check only once at then end of this sequence, (like we do with cairo_t already). */ + _cairo_log_start ("quad"); + _cairo_log_point("[0]", start->cw); + _cairo_log_point("[1]", start->ccw); + _cairo_log_point("[2]", end->ccw); + _cairo_log_point("[3]", end->cw); + _cairo_log_end (); + _cairo_polygon_init (&polygon); _cairo_polygon_move_to (&polygon, &start->cw); _cairo_polygon_line_to (&polygon, &start->ccw); @@ -608,19 +871,25 @@ &polygon, CAIRO_FILL_RULE_WINDING); _cairo_polygon_fini (&polygon); - + out: + _cairo_log_status ("add sub edge status", status); + _cairo_log_end (); return status; } static cairo_status_t _cairo_stroker_move_to (void *closure, cairo_point_t *point) { - cairo_status_t status; + cairo_status_t status = CAIRO_STATUS_SUCCESS; cairo_stroker_t *stroker = closure; + _cairo_log_start ("stroker_move_to()"); + _cairo_log_point ("point", *point); + _cairo_log_stroker("stroker", stroker); status = _cairo_stroker_add_caps (stroker); - if (status) - return status; + if (status) { + goto out; + } stroker->first_point = *point; stroker->current_point = *point; @@ -628,57 +897,84 @@ stroker->has_first_face = FALSE; stroker->has_current_face = FALSE; stroker->has_sub_path = FALSE; - - return CAIRO_STATUS_SUCCESS; + out: + _cairo_log_status("stroker_move_to status", status); + _cairo_log_end (); + return status; } static cairo_status_t _cairo_stroker_move_to_dashed (void *closure, cairo_point_t *point) { /* reset the dash pattern for new sub paths */ + cairo_status_t status; cairo_stroker_t *stroker = closure; + _cairo_log_start ("stroker_move_to_dashed()"); + _cairo_log_point ("point", *point); _cairo_stroker_start_dash (stroker); - - return _cairo_stroker_move_to (closure, point); + status = _cairo_stroker_move_to (closure, point); + _cairo_log_status ("stroker_move_to_dashed status", status); + _cairo_log_end (); + return status; } static cairo_status_t _cairo_stroker_line_to (void *closure, cairo_point_t *point) { - cairo_status_t status; + cairo_status_t status = CAIRO_STATUS_SUCCESS; cairo_stroker_t *stroker = closure; cairo_stroke_face_t start, end; cairo_point_t *p1 = &stroker->current_point; cairo_point_t *p2 = point; cairo_slope_t slope; + _cairo_log_start ("stroker_line_to()"); + _cairo_log_point ("point", *point); + _cairo_log_stroker("stroker", stroker); + stroker->has_sub_path = TRUE; - if (p1->x == p2->x && p1->y == p2->y) - return CAIRO_STATUS_SUCCESS; + if (p1->x == p2->x && p1->y == p2->y) { + _cairo_log_int_status ("bailed on account of no movement", + CAIRO_INT_STATUS_NOTHING_TO_DO); + goto out; + } _cairo_slope_init (&slope, p1, p2); + _cairo_log_slope("slope", slope); status = _cairo_stroker_add_sub_edge (stroker, p1, p2, &slope, &start, &end); if (status) - return status; + goto out; + _cairo_log_stroke_face("end face", &end); if (stroker->has_current_face) { + _cairo_log_start ("have current face -- need join"); status = _cairo_stroker_join (stroker, &stroker->current_face, &start); + _cairo_log_end (); if (status) - return status; + goto out; + _cairo_log_stroke_face("start face", &start); } else { + _cairo_log_start ("no current face"); if (!stroker->has_first_face) { + _cairo_log_start ("no first face"); stroker->first_face = start; + _cairo_log_stroke_face("new first face", &start); stroker->has_first_face = TRUE; + _cairo_log_end (); } + _cairo_log_end (); } stroker->current_face = end; stroker->has_current_face = TRUE; stroker->current_point = *point; - - return CAIRO_STATUS_SUCCESS; + _cairo_log_point ("new current point", *point); + out: + _cairo_log_status ("stroker_line_to status", status); + _cairo_log_end (); + return status; } /* @@ -701,45 +997,88 @@ stroker->has_sub_path = stroker->dash_on; - if (p1->x == p2->x && p1->y == p2->y) - return CAIRO_STATUS_SUCCESS; + _cairo_log_start ("stroker_line_to_dashed()"); + _cairo_log_point ("point", *point); + _cairo_log_stroker ("stroker", stroker); + + if (p1->x == p2->x && p1->y == p2->y) { + _cairo_log_int_status ("bailed on account of no movement", + CAIRO_INT_STATUS_NOTHING_TO_DO); + goto out0; + } _cairo_slope_init (&slope, p1, p2); + _cairo_log_slope ("slope", slope); dx = _cairo_fixed_to_double (p2->x - p1->x); dy = _cairo_fixed_to_double (p2->y - p1->y); + _cairo_log_start ("device space"); + _cairo_log_double ("dx", dx); + _cairo_log_double ("dy", dy); + _cairo_log_end (); cairo_matrix_transform_distance (stroker->ctm_inverse, &dx, &dy); + _cairo_log_start ("user space"); + _cairo_log_double ("dx", dx); + _cairo_log_double ("dy", dy); + _cairo_log_end (); mag = sqrt (dx *dx + dy * dy); + _cairo_log_double ("mag", mag); remain = mag; fd1 = *p1; while (remain) { + _cairo_log_start ("dash iteration"); + _cairo_log_double ("remain", remain); + _cairo_log_bool ("dash_on", stroker->dash_on); + _cairo_log_bool ("has_sub_path", stroker->has_sub_path); + _cairo_log_bool ("has_current_face", stroker->has_current_face); + _cairo_log_bool ("has_first_face", stroker->has_first_face); + _cairo_log_bool ("first iteration", first); + _cairo_log_point("fd1", fd1); + tmp = stroker->dash_remain; if (tmp > remain) tmp = remain; remain -= tmp; + _cairo_log_double("step (tmp)", tmp); + _cairo_log_double("remain after tmp", remain); + dx2 = dx * (mag - remain)/mag; dy2 = dy * (mag - remain)/mag; + _cairo_log_start ("user space"); + _cairo_log_double ("dx2", dx2); + _cairo_log_double ("dy2", dy2); + _cairo_log_end (); + cairo_matrix_transform_distance (stroker->ctm, &dx2, &dy2); + _cairo_log_start ("device space"); + _cairo_log_double ("dx2", dx2); + _cairo_log_double ("dy2", dy2); + _cairo_log_end (); + fd2.x = _cairo_fixed_from_double (dx2); fd2.y = _cairo_fixed_from_double (dy2); + _cairo_log_point ("fd2 before offset", fd2); fd2.x += p1->x; fd2.y += p1->y; + _cairo_log_point ("fd2", fd2); + /* * XXX simplify this case analysis */ if (stroker->dash_on) { status = _cairo_stroker_add_sub_edge (stroker, &fd1, &fd2, &slope, &sub_start, &sub_end); if (status) - return status; + goto out; + if (!first) { /* * Not first dash in this segment, cap start */ status = _cairo_stroker_add_leading_cap (stroker, &sub_start); if (status) - return status; + goto out; } else { /* * First in this segment, join to any current_face, else @@ -749,7 +1088,7 @@ if (stroker->has_current_face) { status = _cairo_stroker_join (stroker, &stroker->current_face, &sub_start); if (status) - return status; + goto out; } else { if (!stroker->has_first_face) { stroker->first_face = sub_start; @@ -757,7 +1096,7 @@ } else { status = _cairo_stroker_add_leading_cap (stroker, &sub_start); if (status) - return status; + goto out; } } stroker->has_sub_path = TRUE; @@ -768,7 +1107,7 @@ */ status = _cairo_stroker_add_trailing_cap (stroker, &sub_end); if (status) - return status; + goto out; } else { /* * Mark previous line face and fix up next time @@ -786,7 +1125,7 @@ if (stroker->has_current_face) { status = _cairo_stroker_add_trailing_cap (stroker, &stroker->current_face); if (status) - return status; + goto out; } } if (!remain) @@ -795,11 +1134,18 @@ _cairo_stroker_step_dash (stroker, tmp); fd1 = fd2; first = FALSE; + _cairo_log_end (); } - stroker->current_point = *point; + _cairo_log_point("new current point", *point); + out0: + _cairo_log_status ("stroker_line_to_dashed status", status); + _cairo_log_end (); return status; + out: + _cairo_log_end (); + goto out0; } static cairo_status_t @@ -816,21 +1162,38 @@ cairo_point_t extra_points[4]; cairo_point_t *a = &stroker->current_point; + _cairo_log_start ("stroker_curve_to()"); + _cairo_log_point("a", *a); + _cairo_log_point("b", *b); + _cairo_log_point("c", *c); + _cairo_log_point("d", *d); + _cairo_log_stroker("stroker", stroker); + status = _cairo_spline_init (&spline, a, b, c, d); - if (status == CAIRO_INT_STATUS_DEGENERATE) - return CAIRO_STATUS_SUCCESS; + if (status == CAIRO_INT_STATUS_DEGENERATE) { + _cairo_log_int_status("spline_init", status); + goto out; + } status = _cairo_pen_init_copy (&pen, &stroker->pen); - if (status) + if (status) { + _cairo_log_status ("pen_init_copy", status); goto CLEANUP_SPLINE; + } + _cairo_log_start ("computing start face"); _compute_face (a, &spline.initial_slope, stroker, &start); + _cairo_log_end (); + _cairo_log_start ("computing end face"); _compute_face (d, &spline.final_slope, stroker, &end); + _cairo_log_end (); if (stroker->has_current_face) { status = _cairo_stroker_join (stroker, &stroker->current_face, &start); - if (status) - return status; + if (status) { + _cairo_log_status ("join failed", status); + goto CLEANUP_PEN; + } } else { if (!stroker->has_first_face) { stroker->first_face = start; @@ -853,13 +1216,27 @@ extra_points[3].x -= end.point.x; extra_points[3].y -= end.point.y; + _cairo_log_start ("extra pen points"); + _cairo_log_point("[0]", extra_points[0]); + _cairo_log_point("[1]", extra_points[1]); + _cairo_log_point("[2]", extra_points[2]); + _cairo_log_point("[3]", extra_points[3]); + _cairo_log_end (); + status = _cairo_pen_add_points (&pen, extra_points, 4); - if (status) + if (status) { + _cairo_log_status ("pen_add_points", status); goto CLEANUP_PEN; + } + _cairo_log_pen ("spline pen", &pen, FALSE); + _cairo_log_traps ("traps before spline stroke", stroker->traps, FALSE); status = _cairo_pen_stroke_spline (&pen, &spline, stroker->tolerance, stroker->traps); - if (status) + if (status) { + _cairo_log_status ("pen_stroke_spline", status); goto CLEANUP_PEN; + } + _cairo_log_traps ("traps after spline stroke", stroker->traps, FALSE); CLEANUP_PEN: _cairo_pen_fini (&pen); @@ -867,7 +1244,9 @@ _cairo_spline_fini (&spline); stroker->current_point = *d; - + out: + _cairo_log_status("stroker_curve_to status", status); + _cairo_log_end (); return status; } @@ -902,23 +1281,40 @@ cairo_line_join_t line_join_save; int i; + _cairo_log_start ("stroker_curve_to_dashed()"); + _cairo_log_point("a", *a); + _cairo_log_point("b", *b); + _cairo_log_point("c", *c); + _cairo_log_point("d", *d); + _cairo_log_stroker("stroker", stroker); + status = _cairo_spline_init (&spline, a, b, c, d); - if (status == CAIRO_INT_STATUS_DEGENERATE) - return CAIRO_STATUS_SUCCESS; + if (status == CAIRO_INT_STATUS_DEGENERATE) { + _cairo_log_int_status("spline_init", status); + goto out; + } /* If the line width is so small that the pen is reduced to a single point, then we have nothing to do. */ - if (stroker->pen.num_vertices <= 1) + _cairo_log_double ("line_width", stroker->style->line_width); + if (stroker->pen.num_vertices <= 1) { + _cairo_log_int ("pen.num_vertices", stroker->pen.num_vertices); + _cairo_log_stringf ("warning", "line width too small?"); goto CLEANUP_SPLINE; + } /* Temporarily modify the stroker to use round joins to guarantee * smooth stroked curves. */ line_join_save = stroker->style->line_join; stroker->style->line_join = CAIRO_LINE_JOIN_ROUND; + _cairo_log_stringf("info", "temporarily switching to ROUND joins"); status = _cairo_spline_decompose (&spline, stroker->tolerance); - if (status) + if (status) { + _cairo_log_status ("spline_decompose", status); goto CLEANUP_GSTATE; + } + _cairo_log_int ("spline.num_points", spline.num_points); for (i = 1; i < spline.num_points; i++) { if (stroker->dashed) @@ -934,7 +1330,9 @@ CLEANUP_SPLINE: _cairo_spline_fini (&spline); - + out: + _cairo_log_status ("stroker_curve_to_dashed status", status); + _cairo_log_end (); return status; } @@ -944,28 +1342,33 @@ cairo_status_t status; cairo_stroker_t *stroker = closure; + _cairo_log_start ("stroker_close_path()"); + if (stroker->dashed) status = _cairo_stroker_line_to_dashed (stroker, &stroker->first_point); else status = _cairo_stroker_line_to (stroker, &stroker->first_point); if (status) - return status; + goto out; if (stroker->has_first_face && stroker->has_current_face) { status = _cairo_stroker_join (stroker, &stroker->current_face, &stroker->first_face); if (status) - return status; + goto out; } else { status = _cairo_stroker_add_caps (stroker); if (status) - return status; + goto out; } stroker->has_sub_path = FALSE; stroker->has_first_face = FALSE; stroker->has_current_face = FALSE; - return CAIRO_STATUS_SUCCESS; + out: + _cairo_log_status("close_path status", status); + _cairo_log_end (); + return status; } cairo_status_t @@ -978,6 +1381,10 @@ { cairo_status_t status = CAIRO_STATUS_SUCCESS; cairo_stroker_t stroker; + static int stroke_count = 0; + int stroke_id = ++stroke_count; + _cairo_log_start("START path_stroke_to_traps()"); + _cairo_log_int ("stroke_id", stroke_id); _cairo_stroker_init (&stroker, stroke_style, ctm, ctm_inverse, tolerance, @@ -1006,6 +1413,8 @@ BAIL: _cairo_stroker_fini (&stroker); - + _cairo_log_int ("stroke_id", stroke_id); + _cairo_log_status ("END path_fixed_stroke_to_traps() status", status); + _cairo_log_end (); return status; } diff -Nur cairo-1.2.4/src/cairo-surface-fallback.c cairo-1.2.4-patched/src/cairo-surface-fallback.c --- cairo-1.2.4/src/cairo-surface-fallback.c 2006-08-10 23:14:46.000000000 +0300 +++ cairo-1.2.4-patched/src/cairo-surface-fallback.c 2006-12-19 09:09:01.000000000 +0200 @@ -37,6 +37,7 @@ #include "cairo-surface-fallback-private.h" #include "cairo-clip-private.h" +#include "cairo-log-private.h" typedef struct { cairo_surface_t *dst; @@ -784,6 +785,20 @@ _cairo_traps_init (&traps); + if (1) { + _cairo_log_start ("surface_fallback_stroke"); + _cairo_log_operator ("op", op); + _cairo_log_pointer("surface", surface); + _cairo_log_pattern ("source", source); + _cairo_log_stroke_style ("stroke_style", stroke_style, TRUE); + _cairo_log_matrix ("ctm", ctm); + _cairo_log_matrix ("ctm_inverse", ctm_inverse); + _cairo_log_double ("tolerance", tolerance); + _cairo_log_antialias ("antialias", antialias); + _cairo_log_path_fixed ("path", path); + _cairo_log_end (); + } + status = _cairo_path_fixed_stroke_to_traps (path, stroke_style, ctm, ctm_inverse, diff -Nur cairo-1.2.4/src/Makefile.am cairo-1.2.4-patched/src/Makefile.am --- cairo-1.2.4/src/Makefile.am 2006-08-18 17:20:16.000000000 +0300 +++ cairo-1.2.4-patched/src/Makefile.am 2006-12-19 09:09:01.000000000 +0200 @@ -217,6 +217,8 @@ $(libcairo_glitz_sources) \ $(libcairo_win32_sources) \ $(libcairo_directfb_sources) \ + cairo-log.c \ + cairo-log-private.h \ cairoint.h libcairo_la_LDFLAGS = -version-info @VERSION_INFO@ -no-undefined $(export_symbols) diff -Nur cairo-1.2.4/src/Makefile.in cairo-1.2.4-patched/src/Makefile.in --- cairo-1.2.4/src/Makefile.in 2006-08-19 03:41:57.000000000 +0300 +++ cairo-1.2.4-patched/src/Makefile.in 2006-12-19 09:08:49.000000000 +0200 @@ -114,7 +114,8 @@ cairo-quartz-private.h cairo-xcb-surface.c \ cairo-glitz-surface.c cairo-win32-surface.c \ cairo-win32-private.h cairo-win32-font.c \ - cairo-directfb-surface.c cairoint.h + cairo-directfb-surface.c cairo-log.c cairo-log-private.h \ + cairoint.h @CAIRO_HAS_ATSUI_FONT_TRUE@am__objects_1 = cairo-atsui-font.lo @CAIRO_HAS_FT_FONT_TRUE@am__objects_2 = cairo-ft-font.lo @CAIRO_HAS_PS_SURFACE_TRUE@am__objects_3 = cairo-ps-surface.lo @@ -160,7 +161,7 @@ $(am__objects_4) $(am__objects_5) $(am__objects_6) \ $(am__objects_7) $(am__objects_10) $(am__objects_11) \ $(am__objects_12) $(am__objects_13) $(am__objects_14) \ - $(am__objects_17) $(am__objects_18) + $(am__objects_17) $(am__objects_18) cairo-log.lo libcairo_la_OBJECTS = $(am_libcairo_la_OBJECTS) libcairo_beos_la_LIBADD = am__libcairo_beos_la_SOURCES_DIST = cairo-beos-surface.cpp @@ -562,6 +563,8 @@ $(libcairo_glitz_sources) \ $(libcairo_win32_sources) \ $(libcairo_directfb_sources) \ + cairo-log.c \ + cairo-log-private.h \ cairoint.h libcairo_la_LDFLAGS = -version-info @VERSION_INFO@ -no-undefined $(export_symbols) @@ -675,6 +678,7 @@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cairo-hash.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cairo-hull.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cairo-image-surface.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cairo-log.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cairo-lzw.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cairo-matrix.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cairo-meta-surface.Plo@am__quote@