[poppler] about patterns

Jeff Muizelaar jeff at infidigm.net
Wed Aug 23 09:56:39 PDT 2006


On Sat, Aug 19, 2006 at 10:54:39AM +0100, Rafael Rodríguez wrote:
> Hi,
> 
> for those who don't know, i'm the one with the SoK kpdf/okular project:
> 
> http://developer.kde.org/seasonofkde/project.php?kpdf_pattern.xml
> 

Here is some uncompiled untested code for the cairo backend that has the
basic idea of rendering to a temporary surface and then tiling that. It
might be of some help.

-Jeff


Index: poppler/CairoOutputDev.cc
===================================================================
RCS file: /cvs/poppler/poppler/poppler/CairoOutputDev.cc,v
retrieving revision 1.40
diff -u -r1.40 CairoOutputDev.cc
--- poppler/CairoOutputDev.cc	28 Jul 2006 18:17:45 -0000	1.40
+++ poppler/CairoOutputDev.cc	23 Aug 2006 01:15:13 -0000
@@ -349,6 +349,55 @@
   cairo_fill (cairo);
 }
 
+void CairoOutputDev::tilingPatternFill(GfxState *state, Object *str,
+				    int paintType, Dict *resDict,
+				    double *mat, double *bbox,
+				    int x0, int y0, int x1, int y1,
+				    double xStep, double yStep) {
+  PDFRectangle box;
+  Gfx *gfx;
+  cairo_surface_t *s;
+  cairo_surface_t *tile;
+  cairo_content_t content;
+  cairo_t *temp;
+  cairo_t *tile_cr;
+  cairo_t *surface_cr;
+
+  if (paintType == 2)
+	  content = CAIRO_CONTENT_COLOR_ALPHA;
+  else
+	  content = CAIRO_CONTENT_ALPHA;
+
+  // should be bounding box
+  tile = cairo_create_surface_similiar(cairo_get_target(cairo), content, x1-x0, y1-y0);
+  tile_cr = cairo_create (tile);
+  temp = cairo;
+  cairo = tile_cr;
+  box.x1 = bbox[0];
+  box.y1 = bbox[1];
+  box.x2 = bbox[2];
+  box.y2 = bbox[3];
+
+  gfx = new Gfx(xref, this, resDict, &box, NULL);
+  gfx->display(str);
+
+  cairo = temp;
+  //XXX: need to concat mat[]
+  for (int i = x0; i<x1; i++) {
+	  for (int j = y0; j<y1; j++) {
+		  if (paintType == 2) {
+			  cairo_set_source_surface(tile,i*xStep,j*yStep);
+			  cairo_paint(cairo);
+		  } else {
+			  cairo_mask_surface(tile, i*xStep, j*yStep);
+		  }
+	  }
+  }
+  cairo_destroy (tile_cr);
+  cairo_surface_destroy(tile);
+}
+
+
 void CairoOutputDev::clip(GfxState *state) {
   doPath (state, state->getPath());
   cairo_set_fill_rule (cairo, CAIRO_FILL_RULE_WINDING);


More information about the poppler mailing list