Hi,

this patch just saves some operations by taking them outside of the tiling 
loop in patterns. It's no big deal actually, but in big loops can save a lot 
of calls. 

I haven't taken any timing measure (any ideas for this...?), but i think the 
benefits are pretty straightforward.

It has to have a lots of mistakes, so please review it. Feedback is really 
appreciated here.

On another topic, I'm quite discouraged because I don't know how to go on. The 
idea of caching a rendered cell and then tiling that all around is *nice*, 
but I don't know how to cache a rendered cell... Albert told me about 
SplashBitmap but I only see getters there...

And the last thing is about getting patches. Even if i "make distclean" my 
branch and svn branch, I still get Makefiles and that kind of stuff in the 
middle. Any ideas to get rid of them automagically?

Thx,
-- 
Rafael Rodríguez

http://unrincon.blogspot.com
http://cornerofcode.blogspot.com
diff -urN poppler/poppler/Gfx.cc poppler-mine-old/poppler/Gfx.cc
--- poppler/poppler/Gfx.cc	2006-07-18 22:32:11.000000000 +0100
+++ poppler-mine-old/poppler/Gfx.cc	2006-08-31 18:16:02.000000000 +0100
@@ -563,7 +563,7 @@
 
     // got a command - execute it
     if (obj.isCmd()) {
-      if (printCommands) {
+//      if (printCommands) {
 	obj.print(stdout);
 	for (i = 0; i < numArgs; ++i) {
 	  printf(" ");
@@ -571,7 +571,7 @@
 	}
 	printf("\n");
 	fflush(stdout);
-      }
+//      }
 #ifdef HAVE_GETTIMEOFDAY
       if (profileCommands) 
 	timer = new GooTimer ();
@@ -666,6 +666,7 @@
   }
 }
 
+
 void Gfx::execOp(Object *cmd, Object args[], int numArgs) {
   Operator *op;
   char *name;
@@ -1349,7 +1350,7 @@
   double xMin, yMin, xMax, yMax, x, y, x1, y1;
   double cxMin, cyMin, cxMax, cyMax;
   int xi0, yi0, xi1, yi1, xi, yi;
-  double *ctm, *btm, *ptm;
+  double *ctm, *btm, *ptm, *bbox;
   double m[6], ictm[6], m1[6], imb[6];
   double det;
   double xstep, ystep;
@@ -1480,31 +1481,24 @@
   //~ edge instead of left/bottom (?)
   xstep = fabs(tPat->getXStep());
   ystep = fabs(tPat->getYStep());
-  xi0 = (int)floor((xMin - tPat->getBBox()[0]) / xstep);
-  xi1 = (int)ceil((xMax - tPat->getBBox()[0]) / xstep);
-  yi0 = (int)floor((yMin - tPat->getBBox()[1]) / ystep);
-  yi1 = (int)ceil((yMax - tPat->getBBox()[1]) / ystep);
-  for (i = 0; i < 4; ++i) {
-    m1[i] = m[i];
-  }
+  bbox = tPat->getBBox();
+  xi0 = (int)floor((xMin - bbox[0]) / xstep);
+  xi1 = (int)ceil((xMax - bbox[0]) / xstep);
+  yi0 = (int)floor((yMin - bbox[1]) / ystep);
+  yi1 = (int)ceil((yMax - bbox[1]) / ystep);
+
+  printf("xMin = %f, xMax = %f, yMin = %f, yMax = %f, bbox[0] = %f, bbox[1] = %f\n", xMin, xMax, yMin, yMax, bbox[0], bbox[1]);
+  printf("xstep = %f, ystep = %f, xi0 = %d, xi1 = %d, yi0 = %d, yi1 = %d\n", xstep, ystep, xi0, xi1, yi0, yi1);
+
+  //FIXME: tiling type attribute???
   if (out->useTilingPatternFill()) {
-    m1[4] = m[4];
-    m1[5] = m[5];
     out->tilingPatternFill(state, tPat->getContentStream(),
 			   tPat->getPaintType(), tPat->getResDict(),
-			   m1, tPat->getBBox(),
+			   m, bbox,
 			   xi0, yi0, xi1, yi1, xstep, ystep);
   } else {
-  for (yi = yi0; yi < yi1; ++yi) {
-    for (xi = xi0; xi < xi1; ++xi) {
-      x = xi * xstep;
-      y = yi * ystep;
-      m1[4] = x * m[0] + y * m[2] + m[4];
-      m1[5] = x * m[1] + y * m[3] + m[5];
-      doForm1(tPat->getContentStream(), tPat->getResDict(),
-	      m1, tPat->getBBox());
-    }
-  }
+    doForm1Pattern(tPat->getContentStream(), tPat->getResDict(), m, bbox,
+	xi0, xi1, yi0, yi1, xstep, ystep);
   }
 
   // restore graphics state
@@ -3481,6 +3475,78 @@
   return;
 }
 
+void Gfx::doForm1Pattern(Object *str, Dict *resDict, double *matrix, double *bbox, 
+	int xi0, int xi1, int yi0, int yi1, double xstep, double ystep) {
+  Parser *oldParser;
+  double oldBaseMatrix[6], m1[6];
+  int i, yi, xi;
+  double x, y;
+
+  // push new resources on stack
+  pushResources(resDict);
+
+   for (i = 0; i < 4; ++i)
+     m1[i] = matrix[i];
+
+  // set new base matrix
+  for (i = 0; i < 6; ++i) {
+    oldBaseMatrix[i] = baseMatrix[i];
+  }
+
+  for (yi = yi0, y = yi0 * ystep; yi < yi1; ++yi, y += ystep) {
+    for (xi = xi0, x = xi0 * xstep; xi < xi1; ++xi, x += xstep) {
+      m1[4] = x * matrix[0] + y * matrix[2] + matrix[4];
+      m1[5] = x * matrix[1] + y * matrix[3] + matrix[5];
+
+      // save current graphics state
+      saveState();
+	
+      // kill any pre-existing path
+      state->clearPath();
+	
+      // save current parser
+      oldParser = parser;
+	
+      // set form transformation matrix
+      state->concatCTM(m1[0], m1[1], m1[2], m1[3], m1[4], m1[5]);
+      out->updateCTM(state, m1[0], m1[1], m1[2], m1[3], m1[4], m1[5]);
+	
+      // set new base matrix
+      for (i = 0; i < 6; ++i) {
+        baseMatrix[i] = state->getCTM()[i];
+      }
+      
+      // set form bounding box
+      state->moveTo(bbox[0], bbox[1]);
+      state->lineTo(bbox[2], bbox[1]);
+      state->lineTo(bbox[2], bbox[3]);
+      state->lineTo(bbox[0], bbox[3]);
+      state->closePath();
+      state->clip();
+      out->clip(state);
+      state->clearPath();
+      
+      // draw the form
+      display(str);
+      
+      // restore parser
+      parser = oldParser;
+      
+      // restore graphics state
+      restoreState();
+    }
+  }
+  
+  for (i = 0; i < 6; ++i) {
+    baseMatrix[i] = oldBaseMatrix[i];
+  }
+	
+  // pop resource stack
+  popResources();
+
+  return;
+}
+
 //------------------------------------------------------------------------
 // in-line image operators
 //------------------------------------------------------------------------
diff -urN poppler/poppler/Gfx.h poppler-mine-old/poppler/Gfx.h
--- poppler/poppler/Gfx.h	2005-10-30 20:29:05.000000000 +0000
+++ poppler-mine-old/poppler/Gfx.h	2006-08-16 03:31:12.000000000 +0100
@@ -119,6 +119,10 @@
   // Interpret a stream or array of streams.
   void display(Object *obj, GBool topLevel = gTrue);
 
+  // Same for tiling patterns
+  void displayPattern(Object *obj, double *matrix, double *bbox, int xi0, int xi1,
+	int yi0, int yi1, double xstep, double ystep);
+
   // Display an annotation, given its appearance (a Form XObject) and
   // bounding box (in default user space).
   void doAnnot(Object *str, double xMin, double yMin,
@@ -159,8 +163,16 @@
 
   static Operator opTab[];	// table of operators
 
+  void updateTilingState(double *matrix, double *bbox);
   void go(GBool topLevel);
+  void goPattern(double *matrix, double *bbox, int xi0, int xi1, int yi0, int yi1, 
+	double xstep, double ystep);
   void execOp(Object *cmd, Object args[], int numArgs);
+  void execOpPattern(Object *cmd, Object args[], int numArgs, double *matrix, 
+	double *bbox, int xi0, int xi1, int yi0, int yi1, double xstep, double ystep);
+  bool isPaintingOperator(char *name);
+
+  int findOpNum(char *name);
   Operator *findOp(char *name);
   GBool checkArg(Object *arg, TchkType type);
   int getPos();
@@ -266,6 +278,8 @@
   void doImage(Object *ref, Stream *str, GBool inlineImg);
   void doForm(Object *str);
   void doForm1(Object *str, Dict *resDict, double *matrix, double *bbox);
+  void doForm1Pattern(Object *str, Dict *resDict, double *matrix, double *bbox, 
+  	int xi0, int xi1, int yi0, int yi1, double xstep, double ystep);
 
   // in-line image operators
   void opBeginImage(Object args[], int numArgs);
_______________________________________________
poppler mailing list
[email protected]
http://lists.freedesktop.org/mailman/listinfo/poppler

Reply via email to