summaryrefslogtreecommitdiffstats
path: root/src/extension/internal/pdfinput/pdf-parser.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/extension/internal/pdfinput/pdf-parser.cpp')
-rw-r--r--src/extension/internal/pdfinput/pdf-parser.cpp197
1 files changed, 63 insertions, 134 deletions
diff --git a/src/extension/internal/pdfinput/pdf-parser.cpp b/src/extension/internal/pdfinput/pdf-parser.cpp
index b8804ac00..c64f5de06 100644
--- a/src/extension/internal/pdfinput/pdf-parser.cpp
+++ b/src/extension/internal/pdfinput/pdf-parser.cpp
@@ -93,7 +93,7 @@ extern "C" {
#define patchColorDelta (dblToCol(1 / 256.0))
// Max number of operators kept in the history list.
-#define maxOperatorHistoryDepth 5
+#define maxOperatorHistoryDepth 16
//------------------------------------------------------------------------
// Operator table
@@ -283,9 +283,8 @@ PdfOperator PdfParser::opTab[] = {
//------------------------------------------------------------------------
PdfParser::PdfParser(XRef *xrefA, Inkscape::Extension::Internal::SvgBuilder *builderA,
- int pageNum, Dict *resDict, PDFRectangle *cropBox,
- GBool (*abortCheckCbkA)(void *data),
- void *abortCheckCbkDataA) {
+ int pageNum, int rotate, Dict *resDict, PDFRectangle *cropBox) {
+
int i;
xref = xrefA;
@@ -296,7 +295,7 @@ PdfParser::PdfParser(XRef *xrefA, Inkscape::Extension::Internal::SvgBuilder *bui
res = new GfxResources(xref, resDict, NULL);
// initialize
- state = new GfxState(72.0, 72.0, cropBox, 0, gFalse);
+ state = new GfxState(72.0, 72.0, cropBox, rotate, gTrue);
fontChanged = gFalse;
clip = clipNone;
ignoreUndef = 0;
@@ -304,16 +303,15 @@ PdfParser::PdfParser(XRef *xrefA, Inkscape::Extension::Internal::SvgBuilder *bui
builder = builderA;
builder->setDocumentSize(state->getPageWidth()*PX_PER_PT,
state->getPageHeight()*PX_PER_PT);
-
+
+ double *ctm = state->getCTM();
+ double scaledCTM[6];
for (i = 0; i < 6; ++i) {
- baseMatrix[i] = state->getCTM()[i];
+ baseMatrix[i] = ctm[i];
+ scaledCTM[i] = PX_PER_PT * ctm[i];
}
- // scale by PX_PER_PT and flip by the y axis
- builder->setTransform(PX_PER_PT, 0.0, 0.0, -PX_PER_PT, 0.0,
- state->getPageHeight()*PX_PER_PT);
+ builder->setTransform((double*)&scaledCTM);
formDepth = 0;
- abortCheckCbk = abortCheckCbkA;
- abortCheckCbkData = abortCheckCbkDataA;
// set crop box
if (cropBox) {
@@ -382,7 +380,6 @@ void PdfParser::go(GBool topLevel) {
int lastAbortCheck;
// scan a sequence of objects
- updateLevel = lastAbortCheck = 0;
numArgs = 0;
parser->getObj(&obj);
while (!obj.isEOF()) {
@@ -407,16 +404,6 @@ void PdfParser::go(GBool topLevel) {
args[i].free();
numArgs = 0;
- // check for an abort
- if (abortCheckCbk) {
- if (updateLevel - lastAbortCheck > 10) {
- if ((*abortCheckCbk)(abortCheckCbkData)) {
- break;
- }
- lastAbortCheck = updateLevel;
- }
- }
-
// got an argument - save it
} else if (numArgs < maxArgs) {
args[numArgs++] = obj;
@@ -481,10 +468,13 @@ void PdfParser::pushOperator(const char *name) {
}
}
-const char *PdfParser::getPreviousOperator() {
+const char *PdfParser::getPreviousOperator(unsigned int look_back) {
OpHistoryEntry *prev = NULL;
- if (operatorHistory != NULL) {
+ if (operatorHistory != NULL && look_back > 0) {
prev = operatorHistory->next;
+ while (--look_back > 0 && prev != NULL) {
+ prev = prev->next;
+ }
}
if (prev != NULL) {
return prev->name;
@@ -608,14 +598,20 @@ void PdfParser::opConcat(Object args[], int numArgs) {
double a5 = args[5].getNum();
if (!strcmp(prevOp, "q")) {
builder->setTransform(a0, a1, a2, a3, a4, a5);
- } else if (!strcmp(prevOp, "startPage")) {
- // multiply it with the current baseMatrix
- double c0 = baseMatrix[0]*a0 + baseMatrix[1]*a2;
- double c1 = baseMatrix[0]*a1 + baseMatrix[1]*a3;
- double c2 = baseMatrix[2]*a0 + baseMatrix[3]*a2;
- double c3 = baseMatrix[2]*a1 + baseMatrix[3]*a3;
- double c4 = baseMatrix[4]*a0 + baseMatrix[5]*a2 + a4;
- double c5 = baseMatrix[4]*a1 + baseMatrix[5]*a3 + a5;
+ } else if (!strcmp(prevOp, "cm")) {
+ // multiply it with the previous transform
+ double otherMatrix[6];
+ if (!builder->getTransform((double*)&otherMatrix)) { // invalid transform
+ // construct identity matrix
+ otherMatrix[0] = otherMatrix[3] = 1.0;
+ otherMatrix[1] = otherMatrix[2] = otherMatrix[4] = otherMatrix[5] = 0.0;
+ }
+ double c0 = otherMatrix[0]*a0 + otherMatrix[1]*a2;
+ double c1 = otherMatrix[0]*a1 + otherMatrix[1]*a3;
+ double c2 = otherMatrix[2]*a0 + otherMatrix[3]*a2;
+ double c3 = otherMatrix[2]*a1 + otherMatrix[3]*a3;
+ double c4 = otherMatrix[4]*a0 + otherMatrix[5]*a2 + a4;
+ double c5 = otherMatrix[4]*a1 + otherMatrix[5]*a3 + a5;
builder->setTransform(c0, c1, c2, c3, c4, c5);
} else {
builder->pushGroup();
@@ -643,6 +639,7 @@ void PdfParser::opSetDash(Object args[], int numArgs) {
}
}
state->setLineDash(dash, length, args[1].getNum());
+ builder->updateStyle(state);
}
void PdfParser::opSetFlat(Object args[], int numArgs) {
@@ -651,18 +648,22 @@ void PdfParser::opSetFlat(Object args[], int numArgs) {
void PdfParser::opSetLineJoin(Object args[], int numArgs) {
state->setLineJoin(args[0].getInt());
+ builder->updateStyle(state);
}
void PdfParser::opSetLineCap(Object args[], int numArgs) {
state->setLineCap(args[0].getInt());
+ builder->updateStyle(state);
}
void PdfParser::opSetMiterLimit(Object args[], int numArgs) {
state->setMiterLimit(args[0].getNum());
+ builder->updateStyle(state);
}
void PdfParser::opSetLineWidth(Object args[], int numArgs) {
state->setLineWidth(args[0].getNum());
+ builder->updateStyle(state);
}
void PdfParser::opSetExtGState(Object args[], int numArgs) {
@@ -926,6 +927,7 @@ void PdfParser::opSetFillGray(Object args[], int numArgs) {
state->setFillColorSpace(new GfxDeviceGrayColorSpace());
color.c[0] = dblToCol(args[0].getNum());
state->setFillColor(&color);
+ builder->updateStyle(state);
}
void PdfParser::opSetStrokeGray(Object args[], int numArgs) {
@@ -935,6 +937,7 @@ void PdfParser::opSetStrokeGray(Object args[], int numArgs) {
state->setStrokeColorSpace(new GfxDeviceGrayColorSpace());
color.c[0] = dblToCol(args[0].getNum());
state->setStrokeColor(&color);
+ builder->updateStyle(state);
}
void PdfParser::opSetFillCMYKColor(Object args[], int numArgs) {
@@ -947,6 +950,7 @@ void PdfParser::opSetFillCMYKColor(Object args[], int numArgs) {
color.c[i] = dblToCol(args[i].getNum());
}
state->setFillColor(&color);
+ builder->updateStyle(state);
}
void PdfParser::opSetStrokeCMYKColor(Object args[], int numArgs) {
@@ -959,6 +963,7 @@ void PdfParser::opSetStrokeCMYKColor(Object args[], int numArgs) {
color.c[i] = dblToCol(args[i].getNum());
}
state->setStrokeColor(&color);
+ builder->updateStyle(state);
}
void PdfParser::opSetFillRGBColor(Object args[], int numArgs) {
@@ -971,6 +976,7 @@ void PdfParser::opSetFillRGBColor(Object args[], int numArgs) {
color.c[i] = dblToCol(args[i].getNum());
}
state->setFillColor(&color);
+ builder->updateStyle(state);
}
void PdfParser::opSetStrokeRGBColor(Object args[], int numArgs) {
@@ -983,6 +989,7 @@ void PdfParser::opSetStrokeRGBColor(Object args[], int numArgs) {
color.c[i] = dblToCol(args[i].getNum());
}
state->setStrokeColor(&color);
+ builder->updateStyle(state);
}
void PdfParser::opSetFillColorSpace(Object args[], int numArgs) {
@@ -1002,6 +1009,7 @@ void PdfParser::opSetFillColorSpace(Object args[], int numArgs) {
state->setFillColorSpace(colorSpace);
colorSpace->getDefaultColor(&color);
state->setFillColor(&color);
+ builder->updateStyle(state);
} else {
error(getPos(), "Bad color space (fill)");
}
@@ -1024,6 +1032,7 @@ void PdfParser::opSetStrokeColorSpace(Object args[], int numArgs) {
state->setStrokeColorSpace(colorSpace);
colorSpace->getDefaultColor(&color);
state->setStrokeColor(&color);
+ builder->updateStyle(state);
} else {
error(getPos(), "Bad color space (stroke)");
}
@@ -1042,6 +1051,7 @@ void PdfParser::opSetFillColor(Object args[], int numArgs) {
color.c[i] = dblToCol(args[i].getNum());
}
state->setFillColor(&color);
+ builder->updateStyle(state);
}
void PdfParser::opSetStrokeColor(Object args[], int numArgs) {
@@ -1057,6 +1067,7 @@ void PdfParser::opSetStrokeColor(Object args[], int numArgs) {
color.c[i] = dblToCol(args[i].getNum());
}
state->setStrokeColor(&color);
+ builder->updateStyle(state);
}
void PdfParser::opSetFillColorN(Object args[], int numArgs) {
@@ -1078,6 +1089,7 @@ void PdfParser::opSetFillColorN(Object args[], int numArgs) {
}
}
state->setFillColor(&color);
+ builder->updateStyle(state);
}
if (args[numArgs-1].isName() &&
(pattern = res->lookupPattern(args[numArgs-1].getName()))) {
@@ -1096,6 +1108,7 @@ void PdfParser::opSetFillColorN(Object args[], int numArgs) {
}
}
state->setFillColor(&color);
+ builder->updateStyle(state);
}
}
@@ -1119,6 +1132,7 @@ void PdfParser::opSetStrokeColorN(Object args[], int numArgs) {
}
}
state->setStrokeColor(&color);
+ builder->updateStyle(state);
}
if (args[numArgs-1].isName() &&
(pattern = res->lookupPattern(args[numArgs-1].getName()))) {
@@ -1137,6 +1151,7 @@ void PdfParser::opSetStrokeColorN(Object args[], int numArgs) {
}
}
state->setStrokeColor(&color);
+ builder->updateStyle(state);
}
}
@@ -1922,10 +1937,11 @@ void PdfParser::opBeginText(Object args[], int numArgs) {
state->setTextMat(1, 0, 0, 1, 0, 0);
state->textMoveTo(0, 0);
fontChanged = gTrue;
+ builder->beginTextObject(state);
}
void PdfParser::opEndText(Object args[], int numArgs) {
- //NEEDED out->endTextObject(state);
+ builder->endTextObject(state);
}
//------------------------------------------------------------------------
@@ -1961,6 +1977,7 @@ void PdfParser::opSetTextLeading(Object args[], int numArgs) {
void PdfParser::opSetTextRender(Object args[], int numArgs) {
state->setRender(args[0].getInt());
+ builder->updateStyle(state);
}
void PdfParser::opSetTextRise(Object args[], int numArgs) {
@@ -1969,12 +1986,10 @@ void PdfParser::opSetTextRise(Object args[], int numArgs) {
void PdfParser::opSetWordSpacing(Object args[], int numArgs) {
state->setWordSpace(args[0].getNum());
- //out->updateWordSpace(state);
}
void PdfParser::opSetHorizScaling(Object args[], int numArgs) {
state->setHorizScaling(args[0].getNum());
- //out->updateHorizScaling(state);
fontChanged = gTrue;
}
@@ -2026,12 +2041,10 @@ void PdfParser::opShowText(Object args[], int numArgs) {
return;
}
if (fontChanged) {
- //NEEDED out->updateFont(state);
+ builder->updateFont(state);
fontChanged = gFalse;
}
- //out->beginStringOp(state);
doShowText(args[0].getString());
- //out->endStringOp(state);
}
void PdfParser::opMoveShowText(Object args[], int numArgs) {
@@ -2042,15 +2055,13 @@ void PdfParser::opMoveShowText(Object args[], int numArgs) {
return;
}
if (fontChanged) {
- //out->updateFont(state);
+ builder->updateFont(state);
fontChanged = gFalse;
}
tx = state->getLineX();
ty = state->getLineY() - state->getLeading();
state->textMoveTo(tx, ty);
- //out->beginStringOp(state);
doShowText(args[0].getString());
- //out->endStringOp(state);
}
void PdfParser::opMoveSetShowText(Object args[], int numArgs) {
@@ -2061,7 +2072,7 @@ void PdfParser::opMoveSetShowText(Object args[], int numArgs) {
return;
}
if (fontChanged) {
- //out->updateFont(state);
+ builder->updateFont(state);
fontChanged = gFalse;
}
state->setWordSpace(args[0].getNum());
@@ -2069,9 +2080,7 @@ void PdfParser::opMoveSetShowText(Object args[], int numArgs) {
tx = state->getLineX();
ty = state->getLineY() - state->getLeading();
state->textMoveTo(tx, ty);
- //out->beginStringOp(state);
doShowText(args[2].getString());
- //out->endStringOp(state);
}
void PdfParser::opShowSpaceText(Object args[], int numArgs) {
@@ -2085,10 +2094,9 @@ void PdfParser::opShowSpaceText(Object args[], int numArgs) {
return;
}
if (fontChanged) {
- //out->updateFont(state);
+ builder->updateFont(state);
fontChanged = gFalse;
}
- //out->beginStringOp(state);
wMode = state->getFont()->getWMode();
a = args[0].getArray();
for (i = 0; i < a->getLength(); ++i) {
@@ -2110,37 +2118,8 @@ void PdfParser::opShowSpaceText(Object args[], int numArgs) {
}
obj.free();
}
- //out->endStringOp(state);
-}
-
-#include <glib-object.h>
-#include <UnicodeMap.h>
-
-static gchar *
-unicode_to_char (Unicode *unicode,
- int len)
-{
- static UnicodeMap *uMap = NULL;
- if (uMap == NULL) {
- GooString *enc = new GooString("UTF-8");
- uMap = globalParams->getUnicodeMap(enc);
- uMap->incRefCnt ();
- delete enc;
- }
-
- GooString gstr;
- gchar buf[8]; /* 8 is enough for mapping an unicode char to a string */
- int i, n;
-
- for (i = 0; i < len; ++i) {
- n = uMap->mapUnicode(unicode[i], buf, sizeof(buf));
- gstr.append(buf, n);
- }
-
- return g_strdup (gstr.getCString ());
}
-
void PdfParser::doShowText(GooString *s) {
GfxFont *font;
int wMode;
@@ -2159,10 +2138,8 @@ void PdfParser::doShowText(GooString *s) {
font = state->getFont();
wMode = font->getWMode();
-printf("doShowText() called\n");
-// if (out->useDrawChar()) {
-// out->beginString(state, s);
-// }
+
+ builder->beginString(state, s);
// handle a Type 3 char
if (font->getType() == fontType3 && 0) {//out->interpretType3Chars()) {
@@ -2239,7 +2216,7 @@ printf("doShowText() called\n");
}
parser = oldParser;
- } else if (1){//out->useDrawChar()) {
+ } else {
state->textTransformDelta(0, state->getRise(), &riseX, &riseY);
p = s->getCString();
len = s->getLength();
@@ -2248,11 +2225,6 @@ printf("doShowText() called\n");
u, (int)(sizeof(u) / sizeof(Unicode)), &uLen,
&dx, &dy, &originX, &originY);
- if (uLen > 0) {
- gchar *sc = unicode_to_char((Unicode*)&u, uLen);
- printf("%s", sc);
- g_free(sc);
- }
if (wMode) {
dx *= state->getFontSize();
dy = dy * state->getFontSize() + state->getCharSpace();
@@ -2271,53 +2243,15 @@ printf("doShowText() called\n");
originX *= state->getFontSize();
originY *= state->getFontSize();
state->textTransformDelta(originX, originY, &tOriginX, &tOriginY);
-// out->drawChar(state, state->getCurX() + riseX, state->getCurY() + riseY,
-// tdx, tdy, tOriginX, tOriginY, code, n, u, uLen);
+ builder->addChar(state, state->getCurX() + riseX, state->getCurY() + riseY,
+ tdx, tdy, tOriginX, tOriginY, code, n, u, uLen);
state->shift(tdx, tdy);
p += n;
len -= n;
}
-
- } else {
- dx = dy = 0;
- p = s->getCString();
- len = s->getLength();
- nChars = nSpaces = 0;
- while (len > 0) {
- n = font->getNextChar(p, len, &code,
- u, (int)(sizeof(u) / sizeof(Unicode)), &uLen,
- &dx2, &dy2, &originX, &originY);
- dx += dx2;
- dy += dy2;
- if (n == 1 && *p == ' ') {
- ++nSpaces;
- }
- ++nChars;
- p += n;
- len -= n;
- }
- if (wMode) {
- dx *= state->getFontSize();
- dy = dy * state->getFontSize()
- + nChars * state->getCharSpace()
- + nSpaces * state->getWordSpace();
- } else {
- dx = dx * state->getFontSize()
- + nChars * state->getCharSpace()
- + nSpaces * state->getWordSpace();
- dx *= state->getHorizScaling();
- dy *= state->getFontSize();
- }
- state->textTransformDelta(dx, dy, &tdx, &tdy);
-// out->drawString(state, s);
- state->shift(tdx, tdy);
}
-// if (out->useDrawChar()) {
-// out->endString(state);
-// }
-
- updateLevel += 10 * s->getLength();
+ builder->endString(state);
}
//------------------------------------------------------------------------
@@ -2659,8 +2593,8 @@ void PdfParser::doImage(Object *ref, Stream *str, GBool inlineImg) {
/* out->drawMaskedImage(state, ref, str, width, height, colorMap,
maskStr, maskWidth, maskHeight, maskInvert);*/
} else {
-/* out->drawImage(state, ref, str, width, height, colorMap,
- haveColorKeyMask ? maskColors : (int *)NULL, inlineImg);*/
+ builder->addImage(state, str, width, height, colorMap,
+ haveColorKeyMask ? maskColors : (int *)NULL);
}
delete colorMap;
@@ -2668,11 +2602,6 @@ void PdfParser::doImage(Object *ref, Stream *str, GBool inlineImg) {
smaskObj.free();
}
- if ((i = width * height) > 1000) {
- i = 1000;
- }
- updateLevel += i;
-
return;
err2: