From e454411a7e80bd8e35424b720277d791b722a591 Mon Sep 17 00:00:00 2001 From: Adrian Johnson Date: Sun, 8 Apr 2012 23:11:30 +0930 Subject: [PATCH] cairo: only align stroke coords for horizontal and vertical lines Bug 48318 --- poppler/CairoOutputDev.cc | 67 ++++++++++++++++++++++++++++++++------------- poppler/CairoOutputDev.h | 2 +- 2 files changed, 49 insertions(+), 20 deletions(-) diff --git a/poppler/CairoOutputDev.cc b/poppler/CairoOutputDev.cc index 22fdaca..88d2f7f 100644 --- a/poppler/CairoOutputDev.cc +++ b/poppler/CairoOutputDev.cc @@ -640,48 +640,77 @@ void CairoOutputDev::updateFont(GfxState *state) { cairo_set_font_matrix (cairo, &matrix); } -void CairoOutputDev::alignStrokeCoords(double *x, double *y) +/* Align stroke coordinate i if the point is the start or end of a + * horizontal or vertical line */ +void CairoOutputDev::alignStrokeCoords(GfxSubpath *subpath, int i, double *x, double *y) { - /* see http://www.cairographics.org/FAQ/#sharp_lines */ - cairo_user_to_device (cairo, x, y); - *x = floor(*x) + 0.5; - *y = floor(*y) + 0.5; - cairo_device_to_user (cairo, x, y); + double x1, y1; + GBool align = gFalse; + + *x = subpath->getX(i); + *y = subpath->getY(i); + + if (i > 0 && !subpath->getCurve(i - 1)) { + x1 = subpath->getX(i - 1); + y1 = subpath->getY(i - 1); + if (*x == x1 || *y == y1) + align = gTrue; + } + + if (i < subpath->getNumPoints() - 1 && !subpath->getCurve(i + 1)) { + x1 = subpath->getX(i + 1); + y1 = subpath->getY(i + 1); + if (*x == x1 || *y == y1) + align = gTrue; + } + + if (align) { + /* see http://www.cairographics.org/FAQ/#sharp_lines */ + cairo_user_to_device (cairo, x, y); + *x = floor(*x) + 0.5; + *y = floor(*y) + 0.5; + cairo_device_to_user (cairo, x, y); + } } void CairoOutputDev::doPath(cairo_t *cairo, GfxState *state, GfxPath *path) { GfxSubpath *subpath; int i, j; + double x, y; cairo_new_path (cairo); for (i = 0; i < path->getNumSubpaths(); ++i) { subpath = path->getSubpath(i); if (subpath->getNumPoints() > 0) { if (align_stroke_coords) { - double x = subpath->getX(0); - double y = subpath->getY(0); - alignStrokeCoords(&x, &y); - cairo_move_to (cairo, x, y); + alignStrokeCoords(subpath, 0, &x, &y); } else { - cairo_move_to (cairo, subpath->getX(0), subpath->getY(0)); + x = subpath->getX(0); + y = subpath->getY(0); } + cairo_move_to (cairo, x, y); j = 1; while (j < subpath->getNumPoints()) { if (subpath->getCurve(j)) { + if (align_stroke_coords) { + alignStrokeCoords(subpath, j + 2, &x, &y); + } else { + x = subpath->getX(j+2); + y = subpath->getY(j+2); + } cairo_curve_to( cairo, subpath->getX(j), subpath->getY(j), subpath->getX(j+1), subpath->getY(j+1), - subpath->getX(j+2), subpath->getY(j+2)); + x, y); j += 3; } else { if (align_stroke_coords) { - double x = subpath->getX(j); - double y = subpath->getY(j); - alignStrokeCoords(&x, &y); - cairo_line_to (cairo, x, y); - } else { - cairo_line_to (cairo, subpath->getX(j), subpath->getY(j)); - } + alignStrokeCoords(subpath, j, &x, &y); + } else { + x = subpath->getX(j); + y = subpath->getY(j); + } + cairo_line_to (cairo, x, y); ++j; } } diff --git a/poppler/CairoOutputDev.h b/poppler/CairoOutputDev.h index 873dd43..f0c1666 100644 --- a/poppler/CairoOutputDev.h +++ b/poppler/CairoOutputDev.h @@ -274,7 +274,7 @@ protected: GBool getStreamData (Stream *str, char **buffer, int *length); void setMimeData(Stream *str, Object *ref, cairo_surface_t *image); void fillToStrokePathClip(); - void alignStrokeCoords(double *x, double *y); + void alignStrokeCoords(GfxSubpath *subpath, int i, double *x, double *y); GfxRGB fill_color, stroke_color; cairo_pattern_t *fill_pattern, *stroke_pattern; -- 1.7.5.4