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