[poppler] poppler/CairoOutputDev.cc poppler/CairoOutputDev.h utils/pdftocairo.1 utils/pdftocairo.cc
Adrian Johnson
ajohnson at kemper.freedesktop.org
Fri May 20 09:55:13 UTC 2016
poppler/CairoOutputDev.cc | 24 ++++++++++++++++
poppler/CairoOutputDev.h | 4 ++
utils/pdftocairo.1 | 26 ++++++++++++++++++
utils/pdftocairo.cc | 66 +++++++++++++++++++++++++++++++++++++++++-----
4 files changed, 112 insertions(+), 8 deletions(-)
New commits:
commit 853e94995255591b35d9bdbeb0174476838097c0
Author: Adrian Johnson <ajohnson at redneon.com>
Date: Sun Apr 17 16:02:57 2016 +0930
pdftocairo: add -antialias option
Bug 94977
diff --git a/poppler/CairoOutputDev.cc b/poppler/CairoOutputDev.cc
index b0987b3..9f892b2 100644
--- a/poppler/CairoOutputDev.cc
+++ b/poppler/CairoOutputDev.cc
@@ -206,6 +206,7 @@ void CairoOutputDev::setCairo(cairo_t *cairo)
/* save the initial matrix so that we can use it for type3 fonts. */
//XXX: is this sufficient? could we miss changes to the matrix somehow?
cairo_get_matrix(cairo, &orig_matrix);
+ setAntialias(cairo, antialias);
} else {
this->cairo = NULL;
this->cairo_shape = NULL;
@@ -228,6 +229,26 @@ void CairoOutputDev::setTextPage(TextPage *text)
}
}
+void CairoOutputDev::setAntialias(cairo_antialias_t antialias)
+{
+ this->antialias = antialias;
+ if (cairo)
+ setAntialias (cairo, antialias);
+ if (cairo_shape)
+ setAntialias (cairo_shape, antialias);
+}
+
+void CairoOutputDev::setAntialias(cairo_t *cr, cairo_antialias_t antialias)
+{
+ cairo_font_options_t *font_options;
+ cairo_set_antialias (cairo, antialias);
+ font_options = cairo_font_options_create ();
+ cairo_get_font_options (cr, font_options);
+ cairo_font_options_set_antialias (font_options, antialias);
+ cairo_set_font_options (cr, font_options);
+ cairo_font_options_destroy (font_options);
+}
+
void CairoOutputDev::startDoc(PDFDoc *docA,
CairoFontEngine *parentFontEngine) {
doc = docA;
@@ -913,6 +934,7 @@ GBool CairoOutputDev::tilingPatternFill(GfxState *state, Gfx *gfxA, Catalog *cat
old_cairo = cairo;
cairo = cairo_create (surface);
cairo_surface_destroy (surface);
+ setAntialias(cairo, antialias);
cairo_scale (cairo, surface_width / width, surface_height / height);
box.x1 = bbox[0]; box.y1 = bbox[1];
@@ -1611,6 +1633,7 @@ void CairoOutputDev::beginTransparencyGroup(GfxState * /*state*/, double * /*bbo
cairo_surface_t *cairo_shape_surface = cairo_surface_create_similar_clip (cairo, CAIRO_CONTENT_ALPHA);
cairo_shape = cairo_create (cairo_shape_surface);
cairo_surface_destroy (cairo_shape_surface);
+ setAntialias(cairo_shape, antialias);
/* the color doesn't matter as long as it is opaque */
cairo_set_source_rgb (cairo_shape, 0, 0, 0);
@@ -1765,6 +1788,7 @@ void CairoOutputDev::setSoftMask(GfxState * state, double * bbox, GBool alpha,
cairo_surface_t *source = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, width, height);
cairo_t *maskCtx = cairo_create(source);
+ setAntialias(maskCtx, antialias);
//XXX: hopefully this uses the correct color space */
if (!alpha && groupColorSpaceStack->cs) {
diff --git a/poppler/CairoOutputDev.h b/poppler/CairoOutputDev.h
index 103a326..3a6dbfa 100644
--- a/poppler/CairoOutputDev.h
+++ b/poppler/CairoOutputDev.h
@@ -266,6 +266,7 @@ public:
void setCairo (cairo_t *cr);
void setTextPage (TextPage *text);
void setPrinting (GBool printing) { this->printing = printing; needFontUpdate = gTrue; }
+ void setAntialias(cairo_antialias_t antialias);
void setInType3Char(GBool inType3Char) { this->inType3Char = inType3Char; }
void getType3GlyphWidth (double *wx, double *wy) { *wx = t3_glyph_wx; *wy = t3_glyph_wy; }
@@ -288,6 +289,7 @@ protected:
#if CAIRO_VERSION >= CAIRO_VERSION_ENCODE(1, 14, 0)
GBool setMimeDataForJBIG2Globals (Stream *str, cairo_surface_t *image);
#endif
+ void setAntialias(cairo_t *cr, cairo_antialias_t antialias);
GfxRGB fill_color, stroke_color;
cairo_pattern_t *fill_pattern, *stroke_pattern;
@@ -340,7 +342,7 @@ protected:
double t3_glyph_wx, t3_glyph_wy;
GBool t3_glyph_has_bbox;
double t3_glyph_bbox[4];
-
+ cairo_antialias_t antialias;
GBool prescaleImages;
TextPage *text; // text for the current page
diff --git a/utils/pdftocairo.1 b/utils/pdftocairo.1
index 2211da7..5e30adf 100644
--- a/utils/pdftocairo.1
+++ b/utils/pdftocairo.1
@@ -167,6 +167,32 @@ Generate a monochrome file (PNG and TIFF only).
.B \-gray
Generate a grayscale file (PNG, JPEG, and TIFF only).
.TP
+.B \-antialias
+Set the cairo antialias option used for text and drawing in image files (or rasterized regions in vector output). The options are:
+.RS
+.TP
+.B default
+Use the default antialiasing for the target device. This is the default setting if \-antialias is not used.
+.TP
+.B none
+Antialiasing is disabled.
+.TP
+.B gray
+Perform single-color antialiasing using shades of gray.
+.TP
+.B subpixel
+Perform antialiasing by taking advantage of the order of subpixel elements on devices such as LCD.
+.TP
+.B fast
+Hint that the backend should perform some antialiasing but prefer speed over quality.
+.TP
+.B good
+The backend should balance quality against performance.
+.TP
+.B best
+Hint that the backend should render at the highest quality, sacrificing speed if necessary.
+.RE
+.TP
.B \-transp
Use a transparent page color instead of white (PNG and TIFF only).
.TP
diff --git a/utils/pdftocairo.cc b/utils/pdftocairo.cc
index 71c60ef..906a5a1 100644
--- a/utils/pdftocairo.cc
+++ b/utils/pdftocairo.cc
@@ -106,6 +106,7 @@ static GBool useCropBox = gFalse;
static GBool mono = gFalse;
static GBool gray = gFalse;
static GBool transp = gFalse;
+static GooString antialias;
static GooString icc;
static GBool level2 = gFalse;
@@ -218,6 +219,8 @@ static const ArgDesc argDesc[] = {
"generate a grayscale image file (PNG, JPEG)"},
{"-transp", argFlag, &transp, 0,
"use a transparent background instead of white (PNG)"},
+ {"-antialias", argGooString, &antialias, 0,
+ "set cairo antialias option"},
#if USE_CMS
{"-icc", argGooString, &icc, 0,
"ICC color profile to use"},
@@ -271,6 +274,7 @@ static cairo_surface_t *surface;
static GBool printing;
static FILE *output_file;
static GBool usePDFPageSize;
+static cairo_antialias_t antialiasEnum = CAIRO_ANTIALIAS_DEFAULT;
#if USE_CMS
static unsigned char *icc_data;
@@ -278,7 +282,46 @@ static int icc_data_size;
static cmsHPROFILE profile;
#endif
-void writePageImage(GooString *filename)
+struct AntiliasOption
+{
+ const char *name;
+ cairo_antialias_t value;
+};
+
+static const AntiliasOption antialiasOptions[] =
+{
+ { "default", CAIRO_ANTIALIAS_DEFAULT },
+ { "none", CAIRO_ANTIALIAS_NONE },
+ { "gray", CAIRO_ANTIALIAS_GRAY },
+ { "subpixel", CAIRO_ANTIALIAS_SUBPIXEL },
+ { "fast", CAIRO_ANTIALIAS_FAST },
+ { "good", CAIRO_ANTIALIAS_GOOD },
+ { "best", CAIRO_ANTIALIAS_BEST },
+ { NULL, CAIRO_ANTIALIAS_DEFAULT },
+};
+
+static GBool parseAntialiasOption(GooString *antialias, cairo_antialias_t *antialiasEnum)
+{
+ const AntiliasOption *option = antialiasOptions;
+ while (option->name) {
+ if (antialias->cmp(option->name) == 0) {
+ *antialiasEnum = option->value;
+ return gTrue;
+ }
+ option++;
+ }
+
+ fprintf(stderr, "Error: Invalid antialias option \"%s\"\n", antialias->getCString());
+ fprintf(stderr, "Valid options are:\n");
+ option = antialiasOptions;
+ while (option->name) {
+ fprintf(stderr, " %s\n", option->name);
+ option++;
+ }
+ return gFalse;
+}
+
+static void writePageImage(GooString *filename)
{
ImgWriter *writer = 0;
FILE *file;
@@ -597,8 +640,16 @@ static void renderPage(PDFDoc *doc, CairoOutputDev *cairoOut, int pg,
cairo_matrix_t m;
cr = cairo_create(surface);
+
+ if (!printing && !transp) {
+ cairo_set_source_rgb (cr, 1,1,1);
+ cairo_paint (cr);
+ cairo_push_group_with_content (cr, CAIRO_CONTENT_COLOR_ALPHA);
+ }
+
cairoOut->setCairo(cr);
cairoOut->setPrinting(printing);
+ cairoOut->setAntialias(antialiasEnum);
cairo_save(cr);
if (ps && output_w > output_h) {
@@ -629,13 +680,9 @@ static void renderPage(PDFDoc *doc, CairoOutputDev *cairoOut, int pg,
cairo_restore(cr);
cairoOut->setCairo(NULL);
- // Blend onto white page
if (!printing && !transp) {
- cairo_save(cr);
- cairo_set_operator(cr, CAIRO_OPERATOR_DEST_OVER);
- cairo_set_source_rgb(cr, 1, 1, 1);
- cairo_paint(cr);
- cairo_restore(cr);
+ cairo_pop_group_to_source (cr);
+ cairo_paint (cr);
}
status = cairo_status(cr);
@@ -914,6 +961,11 @@ int main(int argc, char *argv[]) {
exit(99);
}
+ if (antialias.getLength() > 0) {
+ if (!parseAntialiasOption(&antialias, &antialiasEnum))
+ exit(99);
+ }
+
if (transp && !(png || tiff)) {
fprintf(stderr, "Error: -transp may only be used with png or tiff output.\n");
exit(99);
More information about the poppler
mailing list