poppler/CairoOutputDev.cc | 66 ++++++++++++++++++++++++++++++++++++---------- poppler/CairoOutputDev.h | 4 ++ 2 files changed, 56 insertions(+), 14 deletions(-)
New commits: commit 96a04336c7a6331727724125686a0d6f42f19f46 Author: Adrian Johnson <[email protected]> Date: Mon Oct 6 10:21:51 2014 +1030 cairo: only embed mime data if image decode map is identity https://bugs.launchpad.net/ubuntu/+source/cairo/+bug/1317517 diff --git a/poppler/CairoOutputDev.cc b/poppler/CairoOutputDev.cc index bbfc552..3babb63 100644 --- a/poppler/CairoOutputDev.cc +++ b/poppler/CairoOutputDev.cc @@ -2575,7 +2575,7 @@ void CairoOutputDev::drawSoftMaskedImage(GfxState *state, Object *ref, Stream *s cairo_surface_mark_dirty (image); - setMimeData(state, str, ref, image); + setMimeData(state, str, ref, colorMap, image); pattern = cairo_pattern_create_for_surface (image); cairo_surface_destroy (image); @@ -2678,7 +2678,17 @@ GBool CairoOutputDev::getStreamData (Stream *str, char **buffer, int *length) return gTrue; } -void CairoOutputDev::setMimeData(GfxState *state, Stream *str, Object *ref, cairo_surface_t *image) +static GBool colorMapHasIdentityDecodeMap(GfxImageColorMap *colorMap) +{ + for (int i = 0; i < colorMap->getNumPixelComps(); i++) { + if (colorMap->getDecodeLow(i) != 0.0 || colorMap->getDecodeHigh(i) != 1.0) + return gFalse; + } + return gTrue; +} + +void CairoOutputDev::setMimeData(GfxState *state, Stream *str, Object *ref, + GfxImageColorMap *colorMap, cairo_surface_t *image) { char *strBuffer; int len; @@ -2719,6 +2729,9 @@ void CairoOutputDev::setMimeData(GfxState *state, Stream *str, Object *ref, cair } } + if (!colorMapHasIdentityDecodeMap(colorMap)) + return; + if (getStreamData (str->getNextStream(), &strBuffer, &len)) { cairo_status_t st; @@ -2936,7 +2949,7 @@ void CairoOutputDev::drawImage(GfxState *state, Object *ref, Stream *str, filter = getFilterForSurface (image, interpolate); if (!inlineImg) /* don't read stream twice if it is an inline image */ - setMimeData(state, str, ref, image); + setMimeData(state, str, ref, colorMap, image); pattern = cairo_pattern_create_for_surface (image); cairo_surface_destroy (image); diff --git a/poppler/CairoOutputDev.h b/poppler/CairoOutputDev.h index 4fbf045..8de391a 100644 --- a/poppler/CairoOutputDev.h +++ b/poppler/CairoOutputDev.h @@ -276,7 +276,8 @@ protected: cairo_filter_t getFilterForSurface(cairo_surface_t *image, GBool interpolate); GBool getStreamData (Stream *str, char **buffer, int *length); - void setMimeData(GfxState *state, Stream *str, Object *ref, cairo_surface_t *image); + void setMimeData(GfxState *state, Stream *str, Object *ref, + GfxImageColorMap *colorMap, cairo_surface_t *image); void fillToStrokePathClip(GfxState *state); void alignStrokeCoords(GfxSubpath *subpath, int i, double *x, double *y); commit 18541054bebce3f9d4729629785bf140d67d2da0 Author: Adrian Johnson <[email protected]> Date: Wed Sep 24 21:20:42 2014 +0930 cairo: Only embed mime data for gray/rgb/cmyk colorspaces Bug 80719 diff --git a/poppler/CairoOutputDev.cc b/poppler/CairoOutputDev.cc index e4ae9d7..bbfc552 100644 --- a/poppler/CairoOutputDev.cc +++ b/poppler/CairoOutputDev.cc @@ -2575,7 +2575,7 @@ void CairoOutputDev::drawSoftMaskedImage(GfxState *state, Object *ref, Stream *s cairo_surface_mark_dirty (image); - setMimeData(str, ref, image); + setMimeData(state, str, ref, image); pattern = cairo_pattern_create_for_surface (image); cairo_surface_destroy (image); @@ -2678,22 +2678,45 @@ GBool CairoOutputDev::getStreamData (Stream *str, char **buffer, int *length) return gTrue; } -void CairoOutputDev::setMimeData(Stream *str, Object *ref, cairo_surface_t *image) +void CairoOutputDev::setMimeData(GfxState *state, Stream *str, Object *ref, cairo_surface_t *image) { char *strBuffer; int len; Object obj; + GfxColorSpace *colorSpace; if (!printing || !(str->getKind() == strDCT || str->getKind() == strJPX)) return; + str->getDict()->lookup("ColorSpace", &obj); + colorSpace = GfxColorSpace::parse(&obj, this, state); + obj.free(); + // colorspace in stream dict may be different from colorspace in jpx // data - if (str->getKind() == strJPX) { - GBool hasColorSpace = !str->getDict()->lookup("ColorSpace", &obj)->isNull(); - obj.free(); - if (hasColorSpace) - return; + if (str->getKind() == strJPX && colorSpace) + return; + + // only embed mime data for gray, rgb, and cmyk colorspaces. + if (colorSpace) { + GfxColorSpaceMode mode = colorSpace->getMode(); + delete colorSpace; + switch (mode) { + case csDeviceGray: + case csCalGray: + case csDeviceRGB: + case csCalRGB: + case csDeviceCMYK: + case csICCBased: + break; + + case csLab: + case csIndexed: + case csSeparation: + case csDeviceN: + case csPattern: + return; + } } if (getStreamData (str->getNextStream(), &strBuffer, &len)) { @@ -2913,7 +2936,7 @@ void CairoOutputDev::drawImage(GfxState *state, Object *ref, Stream *str, filter = getFilterForSurface (image, interpolate); if (!inlineImg) /* don't read stream twice if it is an inline image */ - setMimeData(str, ref, image); + setMimeData(state, str, ref, image); pattern = cairo_pattern_create_for_surface (image); cairo_surface_destroy (image); diff --git a/poppler/CairoOutputDev.h b/poppler/CairoOutputDev.h index 26e6c44..4fbf045 100644 --- a/poppler/CairoOutputDev.h +++ b/poppler/CairoOutputDev.h @@ -276,7 +276,7 @@ protected: cairo_filter_t getFilterForSurface(cairo_surface_t *image, GBool interpolate); GBool getStreamData (Stream *str, char **buffer, int *length); - void setMimeData(Stream *str, Object *ref, cairo_surface_t *image); + void setMimeData(GfxState *state, Stream *str, Object *ref, cairo_surface_t *image); void fillToStrokePathClip(GfxState *state); void alignStrokeCoords(GfxSubpath *subpath, int i, double *x, double *y); commit cbf2652c483d7010fc36191c8b209a57eeec93d8 Author: Adrian Johnson <[email protected]> Date: Thu Jan 26 00:37:17 2012 +1030 cairo: don't render text when text matrix is not invertable Emulates acroread behavior. Bug 78042 diff --git a/poppler/CairoOutputDev.cc b/poppler/CairoOutputDev.cc index 1c67b5c..e4ae9d7 100644 --- a/poppler/CairoOutputDev.cc +++ b/poppler/CairoOutputDev.cc @@ -147,6 +147,7 @@ CairoOutputDev::CairoOutputDev() { inUncoloredPattern = gFalse; inType3Char = gFalse; t3_glyph_has_bbox = gFalse; + text_matrix_valid = gTrue; groupColorSpaceStack = NULL; maskStack = NULL; @@ -283,6 +284,8 @@ void CairoOutputDev::restoreState(GfxState *state) { if (cairo_shape) cairo_restore (cairo_shape); + text_matrix_valid = gTrue; + /* These aren't restored by cairo_restore() since we keep them in * the output device. */ updateFillColor(state); @@ -657,11 +660,13 @@ void CairoOutputDev::updateFont(GfxState *state) { */ invert_matrix = matrix; if (cairo_matrix_invert(&invert_matrix)) { - error(errSyntaxWarning, -1, "font matrix not invertible\n"); + error(errSyntaxWarning, -1, "font matrix not invertible"); + text_matrix_valid = gFalse; return; } cairo_set_font_matrix (cairo, &matrix); + text_matrix_valid = gTrue; } /* Tolerance in pixels for checking if strokes are horizontal or vertical @@ -1250,10 +1255,8 @@ void CairoOutputDev::endString(GfxState *state) // ignore empty strings and invisible text -- this is used by // Acrobat Capture render = state->getRender(); - if (render == 3 || glyphCount == 0) { - gfree(glyphs); - glyphs = NULL; - return; + if (render == 3 || glyphCount == 0 || !text_matrix_valid) { + goto finish; } if (!(render & 1)) { @@ -1305,6 +1308,7 @@ void CairoOutputDev::endString(GfxState *state) } } +finish: gfree (glyphs); glyphs = NULL; if (use_show_text_glyphs) { diff --git a/poppler/CairoOutputDev.h b/poppler/CairoOutputDev.h index 28f97fd..26e6c44 100644 --- a/poppler/CairoOutputDev.h +++ b/poppler/CairoOutputDev.h @@ -315,6 +315,7 @@ protected: GBool needFontUpdate; // set when the font needs to be updated GBool printing; GBool use_show_text_glyphs; + GBool text_matrix_valid; cairo_surface_t *surface; cairo_glyph_t *glyphs; int glyphCount; _______________________________________________ poppler mailing list [email protected] http://lists.freedesktop.org/mailman/listinfo/poppler
