From 30dbcc1a232448214ab5bc3da7b974d97a7345da Mon Sep 17 00:00:00 2001 From: Adrian Johnson Date: Wed, 3 Jun 2009 22:08:57 +0930 Subject: [PATCH] Implement text in pattern colorspace for the cairo backend --- poppler/CairoOutputDev.cc | 47 +++++++++++++++++++++++++++++++++++++++++++++ poppler/CairoOutputDev.h | 19 ++++++++++++++++++ 2 files changed, 66 insertions(+), 0 deletions(-) diff --git a/poppler/CairoOutputDev.cc b/poppler/CairoOutputDev.cc index 5d4cb82..199e5ea 100644 --- a/poppler/CairoOutputDev.cc +++ b/poppler/CairoOutputDev.cc @@ -124,6 +124,7 @@ CairoOutputDev::CairoOutputDev() { stroke_opacity = 1.0; fill_opacity = 1.0; textClipPath = NULL; + haveCSPattern = gFalse; cairo = NULL; currentFont = NULL; prescaleImages = gTrue; @@ -507,6 +508,15 @@ void CairoOutputDev::updateFont(GfxState *state) { cairo_set_font_matrix (cairo, &matrix); } +void CairoOutputDev::updateRender(GfxState *state) { + int rm; + rm = state->getRender(); + if (rm == 7 && haveCSPattern) { + haveCSPattern = gFalse; + restoreState(state); + } +} + void CairoOutputDev::doPath(cairo_t *cairo, GfxState *state, GfxPath *path) { GfxSubpath *subpath; int i, j; @@ -758,7 +768,40 @@ void CairoOutputDev::type3D1(GfxState *state, double wx, double wy, t3_glyph_has_bbox = gTrue; } +void CairoOutputDev::beginTextObject(GfxState *state) { + if (state->getFillColorSpace()->getMode() == csPattern) { + haveCSPattern = gTrue; + saveState(state); + savedRender = state->getRender(); + state->setRender(7); // Set clip to text path + } +} + void CairoOutputDev::endTextObject(GfxState *state) { + if (haveCSPattern) { + state->setRender(savedRender); + haveCSPattern = gFalse; + if (state->getFillColorSpace()->getMode() != csPattern) { + if (textClipPath) { + cairo_new_path (cairo); + cairo_append_path (cairo, textClipPath); + cairo_set_fill_rule (cairo, CAIRO_FILL_RULE_WINDING); + cairo_set_source (cairo, fill_pattern); + cairo_fill (cairo); + if (cairo_shape) { + cairo_new_path (cairo_shape); + cairo_append_path (cairo_shape, textClipPath); + cairo_set_fill_rule (cairo_shape, CAIRO_FILL_RULE_WINDING); + cairo_fill (cairo_shape); + } + cairo_path_destroy (textClipPath); + textClipPath = NULL; + } + restoreState(state); + updateFillColor(state); + } + } + if (textClipPath) { // clip the accumulated text path cairo_append_path (cairo, textClipPath); @@ -1057,6 +1100,10 @@ void CairoOutputDev::clearSoftMask(GfxState * /*state*/) { mask = NULL; } +void CairoOutputDev::endMaskClip(GfxState *state) { + clearSoftMask(state); +} + void CairoOutputDev::drawImageMask(GfxState *state, Object *ref, Stream *str, int width, int height, GBool invert, GBool inlineImg) { diff --git a/poppler/CairoOutputDev.h b/poppler/CairoOutputDev.h index 5ec2bf0..7a9283f 100644 --- a/poppler/CairoOutputDev.h +++ b/poppler/CairoOutputDev.h @@ -135,6 +135,7 @@ public: //----- update text state virtual void updateFont(GfxState *state); + virtual void updateRender(GfxState *state); //----- path painting virtual void stroke(GfxState *state); @@ -157,8 +158,22 @@ public: double dx, double dy, CharCode code, Unicode *u, int uLen); virtual void endType3Char(GfxState *state); + virtual void beginTextObject(GfxState *state); + virtual GBool deviceHasTextClip(GfxState *state) { return textClipPath && haveCSPattern; } virtual void endTextObject(GfxState *state); + // If current colorspace is pattern, + // does this device support text in pattern colorspace? + virtual GBool supportTextCSPattern(GfxState *state) { + return state->getFillColorSpace()->getMode() == csPattern; } + + // If current colorspace is pattern, + // need this device special handling for masks in pattern colorspace? + virtual GBool fillMaskCSPattern(GfxState * state) { + return state->getFillColorSpace()->getMode() == csPattern; } + + virtual void endMaskClip(GfxState *state); + //----- grouping operators virtual void beginMarkedContent(char *name, Dict *properties); virtual void endMarkedContent(GfxState *state); @@ -276,6 +291,10 @@ protected: cairo_pattern_t *mask; struct MaskStack *next; } *maskStack; + + GBool haveCSPattern; // set if text has been drawn with a + // clipping render mode because of pattern colorspace + int savedRender; // use if pattern colorspace }; //------------------------------------------------------------------------ -- 1.6.0.4