[poppler] poppler/poppler: CairoOutputDev.cc, 1.33, 1.34 CairoOutputDev.h, 1.13, 1.14

Jeff Muizelaar jrmuizel at kemper.freedesktop.org
Tue Apr 11 23:52:09 PDT 2006


Update of /cvs/poppler/poppler/poppler
In directory kemper:/tmp/cvs-serv22406/poppler

Modified Files:
	CairoOutputDev.cc CairoOutputDev.h 
Log Message:
2006-04-12  Jeff Muizelaar  <jeff at infidigm.net>

	* poppler/CairoOutputDev.cc:
	* poppler/CairoOutputDev.h: Add support for masked images to the cairo
	backend. CairoOutputDevice really should have been refactored before
	committing this, but the results were so pretty I couldn't resist.
	Fixes #6174.


Index: CairoOutputDev.cc
===================================================================
RCS file: /cvs/poppler/poppler/poppler/CairoOutputDev.cc,v
retrieving revision 1.33
retrieving revision 1.34
diff -u -d -r1.33 -r1.34
--- CairoOutputDev.cc	12 Apr 2006 05:46:44 -0000	1.33
+++ CairoOutputDev.cc	12 Apr 2006 06:52:07 -0000	1.34
@@ -549,6 +549,124 @@
   delete imgStr;
 }
 
+void CairoOutputDev::drawMaskedImage(GfxState *state, Object *ref,
+				Stream *str, int width, int height,
+				GfxImageColorMap *colorMap,
+				Stream *maskStr, int maskWidth,
+				int maskHeight, GBool maskInvert)
+{
+  ImageStream *maskImgStr;
+  maskImgStr = new ImageStream(maskStr, maskWidth, 1, 1);
+  maskImgStr->reset();
+
+  int row_stride = (maskWidth + 3) & ~3;
+  unsigned char *maskBuffer;
+  maskBuffer = (unsigned char *)gmalloc (row_stride * maskHeight);
+  unsigned char *maskDest;
+  cairo_surface_t *maskImage;
+  cairo_pattern_t *maskPattern;
+  Guchar *pix;
+  int x, y;
+
+  int invert_bit;
+  
+  invert_bit = maskInvert ? 1 : 0;
+
+  for (y = 0; y < height; y++) {
+    pix = maskImgStr->getLine();
+    maskDest = maskBuffer + y * row_stride;
+    for (x = 0; x < width; x++) {
+      if (pix[x] ^ invert_bit)
+	*maskDest++ = 0;
+      else
+	*maskDest++ = 255;
+    }
+  }
+
+  maskImage = cairo_image_surface_create_for_data (maskBuffer, CAIRO_FORMAT_A8,
+						 maskWidth, maskHeight, row_stride);
+
+  delete maskImgStr;
+  maskStr->close();
+
+  unsigned char *buffer;
+  unsigned int *dest;
+  cairo_surface_t *image;
+  cairo_pattern_t *pattern;
+  ImageStream *imgStr;
+  GfxRGB rgb;
+  int alpha, i;
+  double *ctm;
+  cairo_matrix_t matrix;
+  cairo_matrix_t maskMatrix;
+  int is_identity_transform;
+
+  buffer = (unsigned char *)gmalloc (width * height * 4);
+
+  /* TODO: Do we want to cache these? */
+  imgStr = new ImageStream(str, width,
+			   colorMap->getNumPixelComps(),
+			   colorMap->getBits());
+  imgStr->reset();
+  
+  /* ICCBased color space doesn't do any color correction
+   * so check its underlying color space as well */
+  is_identity_transform = colorMap->getColorSpace()->getMode() == csDeviceRGB ||
+		  colorMap->getColorSpace()->getMode() == csICCBased && 
+		  ((GfxICCBasedColorSpace*)colorMap->getColorSpace())->getAlt()->getMode() == csDeviceRGB;
+
+  for (y = 0; y < height; y++) {
+    dest = (unsigned int *) (buffer + y * 4 * width);
+    pix = imgStr->getLine();
+    colorMap->getRGBLine (pix, dest, width);
+  }
+
+  image = cairo_image_surface_create_for_data (buffer, CAIRO_FORMAT_RGB24,
+						 width, height, width * 4);
+
+  if (image == NULL)
+    return;
+  pattern = cairo_pattern_create_for_surface (image);
+  maskPattern = cairo_pattern_create_for_surface (maskImage);
+  if (pattern == NULL)
+    return;
+
+  ctm = state->getCTM();
+  LOG (printf ("drawImageMask %dx%d, matrix: %f, %f, %f, %f, %f, %f\n",
+	       width, height, ctm[0], ctm[1], ctm[2], ctm[3], ctm[4], ctm[5]));
+  matrix.xx = ctm[0] / width;
+  matrix.xy = -ctm[2] / height;
+  matrix.yx = ctm[1] / width;
+  matrix.yy = -ctm[3] / height;
+  matrix.x0 = ctm[2] + ctm[4];
+  matrix.y0 = ctm[3] + ctm[5];
+
+  maskMatrix.xx = ctm[0] / maskWidth;
+  maskMatrix.xy = -ctm[2] / maskHeight;
+  maskMatrix.yx = ctm[1] / maskWidth;
+  maskMatrix.yy = -ctm[3] / maskHeight;
+  maskMatrix.x0 = ctm[2] + ctm[4];
+  maskMatrix.y0 = ctm[3] + ctm[5];
+
+  cairo_matrix_invert (&matrix);
+  cairo_matrix_invert (&maskMatrix);
+
+  cairo_pattern_set_matrix (pattern, &matrix);
+  cairo_pattern_set_matrix (maskPattern, &maskMatrix);
+
+  cairo_pattern_set_filter (pattern, CAIRO_FILTER_BILINEAR);
+  cairo_set_source (cairo, pattern);
+  cairo_mask (cairo, maskPattern);
+
+  cairo_pattern_destroy (maskPattern);
+  cairo_surface_destroy (maskImage);
+  cairo_pattern_destroy (pattern);
+  cairo_surface_destroy (image);
+  free (buffer);
+  free (maskBuffer);
+  delete imgStr;
+}
+
 void CairoOutputDev::drawSoftMaskedImage(GfxState *state, Object *ref, Stream *str,
 				int width, int height,
 				GfxImageColorMap *colorMap,

Index: CairoOutputDev.h
===================================================================
RCS file: /cvs/poppler/poppler/poppler/CairoOutputDev.h,v
retrieving revision 1.13
retrieving revision 1.14
diff -u -d -r1.13 -r1.14
--- CairoOutputDev.h	12 Apr 2006 02:07:07 -0000	1.13
+++ CairoOutputDev.h	12 Apr 2006 06:52:07 -0000	1.14
@@ -124,6 +124,14 @@
 				int maskWidth, int maskHeight,
 				GfxImageColorMap *maskColorMap);
 
+  virtual void drawMaskedImage(GfxState *state, Object *ref, Stream *str,
+				int width, int height,
+				GfxImageColorMap *colorMap,
+				Stream *maskStr,
+				int maskWidth, int maskHeight,
+				GBool maskInvert);
+
+
   //----- Type 3 font operators
   virtual void type3D0(GfxState *state, double wx, double wy);
   virtual void type3D1(GfxState *state, double wx, double wy,



More information about the poppler mailing list