[poppler] 3 commits - poppler/CairoOutputDev.cc poppler/CairoOutputDev.h

Adrian Johnson ajohnson at kemper.freedesktop.org
Tue Oct 7 13:16:08 PDT 2014


 poppler/CairoOutputDev.cc |   66 ++++++++++++++++++++++++++++++++++++----------
 poppler/CairoOutputDev.h  |    4 ++
 2 files changed, 56 insertions(+), 14 deletions(-)

New commits:
commit 96a04336c7a6331727724125686a0d6f42f19f46
Author: Adrian Johnson <ajohnson at redneon.com>
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 <ajohnson at redneon.com>
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 <ajohnson at redneon.com>
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;


More information about the poppler mailing list