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

Carlos Garcia Campos carlosgc at kemper.freedesktop.org
Mon Feb 22 04:02:17 PST 2010


 configure.ac              |   24 -------
 poppler/CairoOutputDev.cc |  144 +++++++++++++++++++++++++++++++++++-----------
 poppler/CairoOutputDev.h  |    1 
 3 files changed, 112 insertions(+), 57 deletions(-)

New commits:
commit 80f47bbf45faf751c661c1d0931e8e1da622b8ca
Author: Carlos Garcia Campos <carlosgc at gnome.org>
Date:   Mon Feb 22 12:43:06 2010 +0100

    [cairo] Use cairo_surface_set_mime_data() when printing
    
    When rendering a jpeg image for printing, using
    cairo_surface_set_mime_data() to attach the jpeg stream to the
    surface reduces drastically the size of the output file.

diff --git a/poppler/CairoOutputDev.cc b/poppler/CairoOutputDev.cc
index af04086..d421431 100644
--- a/poppler/CairoOutputDev.cc
+++ b/poppler/CairoOutputDev.cc
@@ -2157,6 +2157,29 @@ cleanup:
   delete imgStr;
 }
 
+GBool CairoOutputDev::getStreamData (Stream *str, char **buffer, int *length)
+{
+  int len, i;
+  char *strBuffer;
+
+  len = 0;
+  str->reset();
+  while (str->getChar() != EOF) len++;
+  if (len == 0)
+    return gFalse;
+
+  strBuffer = (char *)gmalloc (len);
+
+  str->reset();
+  for (i = 0; i < len; ++i)
+    strBuffer[i] = str->getChar();
+
+  *buffer = strBuffer;
+  *length = len;
+
+  return gTrue;
+}
+
 void CairoOutputDev::drawImage(GfxState *state, Object *ref, Stream *str,
 			       int width, int height,
 			       GfxImageColorMap *colorMap,
@@ -2266,6 +2289,25 @@ void CairoOutputDev::drawImage(GfxState *state, Object *ref, Stream *str,
   }
 
   cairo_surface_mark_dirty (image);
+
+#if CAIRO_VERSION >= CAIRO_VERSION_ENCODE(1, 9, 6)
+  if (printing && (str->getKind() == strDCT || str->getKind() == strJPX)) {
+    char *strBuffer;
+    int len;
+
+    if (getStreamData (str->getNextStream(), &strBuffer, &len)) {
+      cairo_status_t st;
+      st = cairo_surface_set_mime_data (image,
+					str->getKind() == strDCT ?
+					CAIRO_MIME_TYPE_JPEG : CAIRO_MIME_TYPE_JP2,
+					(const unsigned char *)strBuffer, len,
+					gfree, strBuffer);
+      if (st)
+        gfree (strBuffer);
+    }
+  }
+#endif /* CAIRO_VERSION >= CAIRO_VERSION_ENCODE(1, 9, 6) */
+
   pattern = cairo_pattern_create_for_surface (image);
   cairo_surface_destroy (image);
   if (cairo_pattern_status (pattern))
diff --git a/poppler/CairoOutputDev.h b/poppler/CairoOutputDev.h
index 30043b5..e47825e 100644
--- a/poppler/CairoOutputDev.h
+++ b/poppler/CairoOutputDev.h
@@ -270,6 +270,7 @@ public:
 protected:
   void doPath(cairo_t *cairo, GfxState *state, GfxPath *path);
   cairo_surface_t *downscaleSurface(cairo_surface_t *orig_surface);
+  GBool getStreamData (Stream *str, char **buffer, int *length);
   
   GfxRGB fill_color, stroke_color;
   cairo_pattern_t *fill_pattern, *stroke_pattern;
commit d63293af6dbff65f160be0118b1580c03a1aab56
Author: Carlos Garcia Campos <carlosgc at gnome.org>
Date:   Fri Nov 27 09:52:23 2009 +0100

    [cairo] Turn EXTEND_PAD off when printing

diff --git a/poppler/CairoOutputDev.cc b/poppler/CairoOutputDev.cc
index 5dc1eb0..af04086 100644
--- a/poppler/CairoOutputDev.cc
+++ b/poppler/CairoOutputDev.cc
@@ -1557,7 +1557,8 @@ void CairoOutputDev::drawImageMaskRegular(GfxState *state, Object *ref, Stream *
    * images with CAIRO_FILTER_NEAREST to look really bad */
   cairo_pattern_set_filter (pattern,
 			    interpolate ? CAIRO_FILTER_BEST : CAIRO_FILTER_FAST);
-  cairo_pattern_set_extend (pattern, CAIRO_EXTEND_PAD);
+  if (!printing)
+    cairo_pattern_set_extend (pattern, CAIRO_EXTEND_PAD);
 
   cairo_matrix_init_translate (&matrix, 0, height);
   cairo_matrix_scale (&matrix, width, -height);
@@ -1565,19 +1566,25 @@ void CairoOutputDev::drawImageMaskRegular(GfxState *state, Object *ref, Stream *
 
   if (state->getFillColorSpace()->getMode() == csPattern) {
     mask = cairo_pattern_reference (pattern);
-  } else {
+  } else if (!printing) {
     cairo_save (cairo);
     cairo_rectangle (cairo, 0., 0., 1., 1.);
     cairo_clip (cairo);
     cairo_mask (cairo, pattern);
     cairo_restore (cairo);
+  } else {
+    cairo_mask (cairo, pattern);
   }
 
   if (cairo_shape) {
     cairo_save (cairo_shape);
     cairo_set_source (cairo_shape, pattern);
-    cairo_rectangle (cairo_shape, 0., 0., 1., 1.);
-    cairo_fill (cairo_shape);
+    if (!printing) {
+      cairo_rectangle (cairo_shape, 0., 0., 1., 1.);
+      cairo_fill (cairo_shape);
+    } else {
+      cairo_mask (cairo_shape, pattern);
+    }
     cairo_restore (cairo_shape);
   }
 
@@ -1963,10 +1970,12 @@ void CairoOutputDev::drawMaskedImage(GfxState *state, Object *ref,
 
   cairo_pattern_set_filter (pattern,
 			    interpolate ? CAIRO_FILTER_BILINEAR : CAIRO_FILTER_FAST);
-  cairo_pattern_set_extend (pattern, CAIRO_EXTEND_PAD);
   cairo_pattern_set_filter (maskPattern,
 			    maskInterpolate ? CAIRO_FILTER_BILINEAR : CAIRO_FILTER_FAST);
-  cairo_pattern_set_extend (maskPattern, CAIRO_EXTEND_PAD);
+  if (!printing) {
+    cairo_pattern_set_extend (pattern, CAIRO_EXTEND_PAD);
+    cairo_pattern_set_extend (maskPattern, CAIRO_EXTEND_PAD);
+  }
 
   cairo_matrix_init_translate (&matrix, 0, height);
   cairo_matrix_scale (&matrix, width, -height);
@@ -1976,18 +1985,27 @@ void CairoOutputDev::drawMaskedImage(GfxState *state, Object *ref,
   cairo_matrix_scale (&maskMatrix, maskWidth, -maskHeight);
   cairo_pattern_set_matrix (maskPattern, &maskMatrix);
 
-  cairo_save (cairo);
-  cairo_set_source (cairo, pattern);
-  cairo_rectangle (cairo, 0., 0., 1., 1.);
-  cairo_clip (cairo);
-  cairo_mask (cairo, maskPattern);
-  cairo_restore (cairo);
+  if (!printing) {
+    cairo_save (cairo);
+    cairo_set_source (cairo, pattern);
+    cairo_rectangle (cairo, 0., 0., 1., 1.);
+    cairo_clip (cairo);
+    cairo_mask (cairo, maskPattern);
+    cairo_restore (cairo);
+  } else {
+    cairo_set_source (cairo, pattern);
+    cairo_mask (cairo, maskPattern);
+  }
 
   if (cairo_shape) {
     cairo_save (cairo_shape);
     cairo_set_source (cairo_shape, pattern);
-    cairo_rectangle (cairo_shape, 0., 0., 1., 1.);
-    cairo_fill (cairo_shape);
+    if (!printing) {
+      cairo_rectangle (cairo_shape, 0., 0., 1., 1.);
+      cairo_fill (cairo_shape);
+    } else {
+      cairo_mask (cairo_shape, pattern);
+    }
     cairo_restore (cairo_shape);
   }
 
@@ -2088,10 +2106,12 @@ void CairoOutputDev::drawSoftMaskedImage(GfxState *state, Object *ref, Stream *s
   //XXX: should set mask filter
   cairo_pattern_set_filter (pattern,
 			    interpolate ? CAIRO_FILTER_BILINEAR : CAIRO_FILTER_FAST);
-  cairo_pattern_set_extend (pattern, CAIRO_EXTEND_PAD);
   cairo_pattern_set_filter (maskPattern,
 			    maskInterpolate ? CAIRO_FILTER_BILINEAR : CAIRO_FILTER_FAST);
-  cairo_pattern_set_extend (maskPattern, CAIRO_EXTEND_PAD);
+  if (!printing) {
+    cairo_pattern_set_extend (pattern, CAIRO_EXTEND_PAD);
+    cairo_pattern_set_extend (maskPattern, CAIRO_EXTEND_PAD);
+  }
 
   cairo_matrix_init_translate (&matrix, 0, height);
   cairo_matrix_scale (&matrix, width, -height);
@@ -2101,22 +2121,31 @@ void CairoOutputDev::drawSoftMaskedImage(GfxState *state, Object *ref, Stream *s
   cairo_matrix_scale (&maskMatrix, maskWidth, -maskHeight);
   cairo_pattern_set_matrix (maskPattern, &maskMatrix);
 
-  cairo_save (cairo);
-  cairo_set_source (cairo, pattern);
-  cairo_rectangle (cairo, 0., 0.,
-		   MIN (width, maskWidth) / (double)width,
-		   MIN (height, maskHeight) / (double)height);
-  cairo_clip (cairo);
-  cairo_mask (cairo, maskPattern);
-  cairo_restore (cairo);
+  if (!printing) {
+    cairo_save (cairo);
+    cairo_set_source (cairo, pattern);
+    cairo_rectangle (cairo, 0., 0.,
+		     MIN (width, maskWidth) / (double)width,
+		     MIN (height, maskHeight) / (double)height);
+    cairo_clip (cairo);
+    cairo_mask (cairo, maskPattern);
+    cairo_restore (cairo);
+  } else {
+    cairo_set_source (cairo, pattern);
+    cairo_mask (cairo, maskPattern);
+  }
 
   if (cairo_shape) {
     cairo_save (cairo_shape);
     cairo_set_source (cairo_shape, pattern);
-    cairo_rectangle (cairo_shape, 0., 0.,
-		     MIN (width, maskWidth) / (double)width,
-		     MIN (height, maskHeight) / (double)height);
-    cairo_fill (cairo_shape);
+    if (!printing) {
+      cairo_rectangle (cairo_shape, 0., 0.,
+		       MIN (width, maskWidth) / (double)width,
+		       MIN (height, maskHeight) / (double)height);
+      cairo_fill (cairo_shape);
+    } else {
+      cairo_mask (cairo_shape, pattern);
+    }
     cairo_restore (cairo_shape);
   }
 
@@ -2245,7 +2274,8 @@ void CairoOutputDev::drawImage(GfxState *state, Object *ref, Stream *str,
   cairo_pattern_set_filter (pattern,
 			    interpolate ?
 			    CAIRO_FILTER_BILINEAR : CAIRO_FILTER_FAST);
-  cairo_pattern_set_extend (pattern, CAIRO_EXTEND_PAD);
+  if (!printing)
+    cairo_pattern_set_extend (pattern, CAIRO_EXTEND_PAD);
 
   cairo_matrix_init_translate (&matrix, 0, height);
   cairo_matrix_scale (&matrix, width, -height);
@@ -2261,7 +2291,10 @@ void CairoOutputDev::drawImage(GfxState *state, Object *ref, Stream *str,
 
   cairo_save (cairo);
   cairo_set_source (cairo, pattern);
-  cairo_rectangle (cairo, 0., 0., 1., 1.);
+  if (printing)
+    cairo_rectangle (cairo, 0., 0., width, height);
+  else
+    cairo_rectangle (cairo, 0., 0., 1., 1.);
   if (maskPattern) {
     cairo_clip (cairo);
     cairo_mask (cairo, maskPattern);
@@ -2275,7 +2308,10 @@ void CairoOutputDev::drawImage(GfxState *state, Object *ref, Stream *str,
   if (cairo_shape) {
     cairo_save (cairo_shape);
     cairo_set_source (cairo_shape, pattern);
-    cairo_rectangle (cairo_shape, 0., 0., 1., 1.);
+    if (printing)
+      cairo_rectangle (cairo_shape, 0., 0., width, height);
+    else
+      cairo_rectangle (cairo_shape, 0., 0., 1., 1.);
     cairo_fill (cairo_shape);
     cairo_restore (cairo_shape);
   }
commit 880890c14e99a954b365a3a6b59deeffa5304d30
Author: Carlos Garcia Campos <carlosgc at gnome.org>
Date:   Mon Feb 22 11:01:05 2010 +0100

    [cairo] Use CAIRO_VERSION macros to check whether blend modes are available

diff --git a/configure.ac b/configure.ac
index 5d497c3..1f67c71 100644
--- a/configure.ac
+++ b/configure.ac
@@ -342,30 +342,6 @@ if test x$enable_cairo_output = xyes; then
   CAIRO_FEATURE="#define POPPLER_HAS_CAIRO 1"
   CAIRO_REQ="cairo"
   AC_CHECK_HEADERS(fcntl.h sys/mman.h sys/stat.h)
-  AC_LANG_PUSH([C])
-  _SAVE_CFLAGS=$CFLAGS
-  _SAVE_LIBS=$LIBS
-  CFLAGS="$CFLAGS $CAIRO_CFLAGS"
-  LIBS="$LIBS $CAIRO_LIBS"
-  AC_CACHE_CHECK([for cairo blend modes support],
-                 ac_cv_cairo_has_blend_modes,
-		 [AC_COMPILE_IFELSE(
-		   [AC_LANG_SOURCE([[
-#include <cairo.h>
-int main() {
-  cairo_t *cr;
-  cairo_set_operator(cr, CAIRO_OPERATOR_MULTIPLY);
-  return 0;
-}
-                   ]])],
-		   [ac_cv_cairo_has_blend_modes="yes"],
-                   [ac_cv_cairo_has_blend_modes="no"])])
-  CFLAGS=$_SAVE_CFLAGS
-  LIBS=$_SAVE_LIBS
-  AC_LANG_POP([C])
-  if test "$ac_cv_cairo_has_blend_modes" = "yes"; then
-    AC_DEFINE(CAIRO_HAS_BLEND_MODES, [1], [Whether cairo has blend modes support])
-  fi
 else
   CAIRO_FEATURE="#undef POPPLER_HAS_CAIRO"
   CAIRO_REQ=""
diff --git a/poppler/CairoOutputDev.cc b/poppler/CairoOutputDev.cc
index 160e2f3..5dc1eb0 100644
--- a/poppler/CairoOutputDev.cc
+++ b/poppler/CairoOutputDev.cc
@@ -500,7 +500,7 @@ void CairoOutputDev::updateFillColorStop(GfxState *state, double offset) {
 }
 
 void CairoOutputDev::updateBlendMode(GfxState *state) {
-#ifdef CAIRO_HAS_BLEND_MODES
+#if CAIRO_VERSION >= CAIRO_VERSION_ENCODE(1, 9, 4)
   switch (state->getBlendMode()) {
   default:
   case gfxBlendNormal:
@@ -553,7 +553,7 @@ void CairoOutputDev::updateBlendMode(GfxState *state) {
     break;
   }
   LOG(printf ("blend mode: %d\n", (int)state->getBlendMode()));
-#endif /* CAIRO_HAS_BLEND_MODES */
+#endif /* CAIRO_VERSION >= CAIRO_VERSION_ENCODE(1, 9, 4) */
 }
 
 void CairoOutputDev::updateFont(GfxState *state) {


More information about the poppler mailing list