From 223e7458d7ccb95ef9bad3884b9841cbc260d295 Mon Sep 17 00:00:00 2001 From: Adrian Johnson Date: Tue, 23 Aug 2011 20:46:24 +0930 Subject: [PATCH 1/2] cairo: fix stroking of very thin lines Lines with a width less than 1.0 are almost invisible in cairo output due to antialising. The PDF standard states that when the Stroke Adjust graphics parameter is true, all lines must be at least one pixel wide. Add a stroke_adjust flag to the CairoOuputDev. Like splash, use the globalParam strokeAdjust setting (which defaults to true) to initialize the flag and ignore the Stroke Adjust settng in PDF files. This emulates Acrobat behavior. When stroke_adjust is true, find the line width in device pixels and if less than 0.5 set the line width to 0.5 device pixels. The value 0.5 pixels seems to make horizontal and vertical lines look better because integer aligned 1.0 wide lines in cairo are rendered two pixels wide which looks too fat. --- poppler/CairoOutputDev.cc | 20 +++++++++++++++++++- poppler/CairoOutputDev.h | 1 + 2 files changed, 20 insertions(+), 1 deletions(-) diff --git a/poppler/CairoOutputDev.cc b/poppler/CairoOutputDev.cc index 968788e..272ae55 100644 --- a/poppler/CairoOutputDev.cc +++ b/poppler/CairoOutputDev.cc @@ -153,6 +153,10 @@ CairoOutputDev::CairoOutputDev() { text = NULL; actualText = NULL; + + // the SA parameter supposedly defaults to false, but Acrobat + // apparently hardwires it to true + stroke_adjust = globalParams->getStrokeAdjust(); } CairoOutputDev::~CairoOutputDev() { @@ -420,7 +424,21 @@ void CairoOutputDev::updateLineWidth(GfxState *state) { cairo_device_to_user_distance(cairo, &x, &y); cairo_set_line_width (cairo, MIN(fabs(x),fabs(y))); } else { - cairo_set_line_width (cairo, state->getLineWidth()); + double width = state->getLineWidth(); + if (stroke_adjust && !printing) { + double x, y; + x = y = width; + + /* find out line width in device units */ + cairo_user_to_device_distance(cairo, &x, &y); + if (x < 0.5 && y < 0.5) { + /* adjust width to at least one device pixel */ + x = y = 0.5; + cairo_device_to_user_distance(cairo, &x, &y); + width = MIN(fabs(x),fabs(y)); + } + } + cairo_set_line_width (cairo, width); } if (cairo_shape) cairo_set_line_width (cairo_shape, cairo_get_line_width (cairo)); diff --git a/poppler/CairoOutputDev.h b/poppler/CairoOutputDev.h index ca64ad5..7cf4157 100644 --- a/poppler/CairoOutputDev.h +++ b/poppler/CairoOutputDev.h @@ -287,6 +287,7 @@ protected: cairo_pattern_t *fill_pattern, *stroke_pattern; double fill_opacity; double stroke_opacity; + GBool stroke_adjust; CairoFont *currentFont; struct StrokePathClip { -- 1.7.4.1