summaryrefslogtreecommitdiff
path: root/Build/source/libs/xpdf/xpdf-src/xpdf/PSOutputDev.cc
diff options
context:
space:
mode:
Diffstat (limited to 'Build/source/libs/xpdf/xpdf-src/xpdf/PSOutputDev.cc')
-rw-r--r--Build/source/libs/xpdf/xpdf-src/xpdf/PSOutputDev.cc320
1 files changed, 220 insertions, 100 deletions
diff --git a/Build/source/libs/xpdf/xpdf-src/xpdf/PSOutputDev.cc b/Build/source/libs/xpdf/xpdf-src/xpdf/PSOutputDev.cc
index b9fff4ffaed..4cb4304e172 100644
--- a/Build/source/libs/xpdf/xpdf-src/xpdf/PSOutputDev.cc
+++ b/Build/source/libs/xpdf/xpdf-src/xpdf/PSOutputDev.cc
@@ -8,10 +8,6 @@
#include <aconf.h>
-#ifdef USE_GCC_PRAGMAS
-#pragma implementation
-#endif
-
#include <stdio.h>
#include <stddef.h>
#include <stdarg.h>
@@ -108,7 +104,8 @@ static const char *prolog[] = {
"/pdfOpNames [",
" /pdfFill /pdfStroke /pdfLastFill /pdfLastStroke",
" /pdfTextMat /pdfFontSize /pdfCharSpacing /pdfTextRender",
- " /pdfTextRise /pdfWordSpacing /pdfHorizScaling /pdfTextClipPath",
+ " /pdfTextRise /pdfWordSpacing /pdfHorizScaling /pdfTextPath",
+ " /pdfTextClipPath",
"] def",
"~123ngs",
"/pdfStartPage {",
@@ -145,6 +142,7 @@ static const char *prolog[] = {
" /pdfTextRise 0 def",
" /pdfWordSpacing 0 def",
" /pdfHorizScaling 1 def",
+ " /pdfTextPath [] def",
" /pdfTextClipPath [] def",
"} def",
"/pdfEndPage { end } def",
@@ -475,32 +473,34 @@ static const char *prolog[] = {
"/Tj {",
" fCol", // because stringwidth has to draw Type 3 chars
" 0 pdfTextRise pdfTextMat dtransform rmoveto",
- " currentpoint 4 2 roll",
- " pdfTextRender 1 and 0 eq {",
- " 2 copy xyshow2",
- " } if",
- " pdfTextRender 3 and dup 1 eq exch 2 eq or {",
- " 3 index 3 index moveto",
- " 2 copy",
- " currentfont /FontType get 3 eq { fCol } { sCol } ifelse",
- " xycp currentpoint stroke moveto",
- " } if",
- " pdfTextRender 4 and 0 ne {",
- " 4 2 roll moveto xycp",
- " /pdfTextClipPath [ pdfTextClipPath aload pop",
- " {/moveto cvx}",
- " {/lineto cvx}",
- " {/curveto cvx}",
- " {/closepath cvx}",
- " pathforall ] def",
- " currentpoint newpath moveto",
- " } {",
- " pop pop pop pop",
- " } ifelse",
+ " xyshow2",
+ " 0 pdfTextRise neg pdfTextMat dtransform rmoveto",
+ "} def",
+ "/TjS {",
+ " fCol", // because stringwidth has to draw Type 3 chars
+ " 0 pdfTextRise pdfTextMat dtransform rmoveto",
+ " currentfont /FontType get 3 eq { fCol } { sCol } ifelse",
+ " xycp currentpoint stroke moveto",
+ " 0 pdfTextRise neg pdfTextMat dtransform rmoveto",
+ "} def",
+ "/TjFS {",
+ " 2 copy currentpoint 4 2 roll Tj moveto TjS",
+ "} def",
+ "/TjSave {",
+ " fCol", // because stringwidth has to draw Type 3 chars
+ " 0 pdfTextRise pdfTextMat dtransform rmoveto",
+ " xycp",
+ " /pdfTextPath [ pdfTextPath aload pop",
+ " {/moveto cvx}",
+ " {/lineto cvx}",
+ " {/curveto cvx}",
+ " {/closepath cvx}",
+ " pathforall ] def",
+ " currentpoint newpath moveto",
" 0 pdfTextRise neg pdfTextMat dtransform rmoveto",
"} def",
"/Tj3 {",
- " pdfTextRender 3 and 3 ne {"
+ " pdfTextRender 3 and 3 ne {",
" fCol", // because stringwidth has to draw Type 3 chars
" 0 pdfTextRise pdfTextMat dtransform rmoveto",
" xyshow2",
@@ -513,8 +513,18 @@ static const char *prolog[] = {
" pdfTextMat dtransform rmoveto } def",
"/TJmV { 0.001 mul pdfFontSize mul neg 0 exch",
" pdfTextMat dtransform rmoveto } def",
- "/Tclip { pdfTextClipPath cvx exec clip newpath",
- " /pdfTextClipPath [] def } def",
+ "/Tfill { fCol pdfTextPath cvx exec fill } def",
+ "/Tstroke { sCol pdfTextPath cvx exec stroke } def",
+ "/Tclip { pdfTextPath cvx exec clip newpath } def",
+ "/Tstrokeclip { pdfTextPath cvx exec strokepath clip newpath } def",
+ "/Tclear { /pdfTextPath [] def } def",
+ "/Tsave {",
+ " /pdfTextClipPath [ pdfTextClipPath aload pop pdfTextPath aload pop ] def",
+ "} def",
+ "/Tclip2 {",
+ " pdfTextClipPath cvx exec clip newpath",
+ " /pdfTextClipPath [] def",
+ "} def",
"~1ns",
"% Level 1 image operators",
"~1n",
@@ -1309,7 +1319,8 @@ PSOutputDev::PSOutputDev(char *fileName, PDFDoc *docA,
paperSizes = NULL;
embFontList = NULL;
customColors = NULL;
- haveTextClip = gFalse;
+ haveSavedTextPath = gFalse;
+ haveSavedClipPath = gFalse;
t3String = NULL;
// open file or pipe
@@ -1376,7 +1387,8 @@ PSOutputDev::PSOutputDev(PSOutputFunc outputFuncA, void *outputStreamA,
paperSizes = NULL;
embFontList = NULL;
customColors = NULL;
- haveTextClip = gFalse;
+ haveSavedTextPath = gFalse;
+ haveSavedClipPath = gFalse;
t3String = NULL;
init(outputFuncA, outputStreamA, psGeneric,
@@ -1748,7 +1760,6 @@ void PSOutputDev::writeXpdfProcset() {
void PSOutputDev::writeDocSetup(Catalog *catalog) {
Page *page;
Dict *resDict;
- Annots *annots;
AcroForm *form;
Object obj1, obj2, obj3;
GString *s;
@@ -1774,6 +1785,7 @@ void PSOutputDev::writeDocSetup(Catalog *catalog) {
} else {
writePS("xpdf begin\n");
}
+ Annots *annots = doc->getAnnots();
needDefaultFont = gFalse;
for (pg = firstPage; pg <= lastPage; ++pg) {
if (rasterizePage[pg - firstPage]) {
@@ -1783,13 +1795,12 @@ void PSOutputDev::writeDocSetup(Catalog *catalog) {
if ((resDict = page->getResourceDict())) {
setupResources(resDict);
}
- annots = new Annots(doc, page->getAnnots(&obj1));
- obj1.free();
- if (annots->getNumAnnots()) {
+ int nAnnots = annots->getNumAnnots(pg);
+ if (nAnnots > 0) {
needDefaultFont = gTrue;
}
- for (i = 0; i < annots->getNumAnnots(); ++i) {
- if (annots->getAnnot(i)->getAppearance(&obj1)->isStream()) {
+ for (i = 0; i < nAnnots; ++i) {
+ if (annots->getAnnot(pg, i)->getAppearance(&obj1)->isStream()) {
obj1.streamGetDict()->lookup("Resources", &obj2);
if (obj2.isDict()) {
setupResources(obj2.getDict());
@@ -1798,7 +1809,6 @@ void PSOutputDev::writeDocSetup(Catalog *catalog) {
}
obj1.free();
}
- delete annots;
}
if ((form = catalog->getForm())) {
if (form->getNumFields() > 0) {
@@ -2150,6 +2160,9 @@ void PSOutputDev::setupFont(GfxFont *font, Dict *parentResDict) {
case fontType1:
fi->ff = setupExternalType1Font(font, fontLoc->path);
break;
+ case fontType1COT:
+ fi->ff = setupExternalOpenTypeT1CFont(font, fontLoc->path);
+ break;
case fontTrueType:
case fontTrueTypeOT:
fi->ff = setupExternalTrueTypeFont(font, fontLoc->path,
@@ -2573,6 +2586,48 @@ PSFontFileInfo *PSOutputDev::setupEmbeddedOpenTypeT1CFont(GfxFont *font,
return ff;
}
+PSFontFileInfo *PSOutputDev::setupExternalOpenTypeT1CFont(GfxFont *font,
+ GString *fileName) {
+ GString *psName;
+ PSFontFileInfo *ff;
+ FoFiTrueType *ffTT;
+
+ if (font->getName()) {
+ // check if font is already embedded
+ if ((ff = (PSFontFileInfo *)fontFileInfo->lookup(font->getName()))) {
+ return ff;
+ }
+ // this assumes that the PS font name matches the PDF font name
+ psName = font->getName()->copy();
+ } else {
+ // generate name
+ psName = makePSFontName(font, font->getID());
+ }
+
+ // beginning comment
+ writePSFmt("%%BeginResource: font {0:t}\n", psName);
+ embFontList->append("%%+ font ");
+ embFontList->append(psName->getCString());
+ embFontList->append("\n");
+
+ // convert it to a Type 1 font
+ if ((ffTT = FoFiTrueType::load(fileName->getCString(), 0, gTrue))) {
+ if (ffTT->isOpenTypeCFF()) {
+ ffTT->convertToType1(psName->getCString(), NULL, gTrue,
+ outputFunc, outputStream);
+ }
+ delete ffTT;
+ }
+
+ // ending comment
+ writePS("%%EndResource\n");
+
+ ff = new PSFontFileInfo(psName, font->getType(), psFontFileExternal);
+ ff->extFileName = fileName->copy();
+ fontFileInfo->add(ff->psName, ff);
+ return ff;
+}
+
PSFontFileInfo *PSOutputDev::setupEmbeddedTrueTypeFont(GfxFont *font, Ref *id) {
GString *psName;
PSFontFileInfo *ff;
@@ -3867,8 +3922,14 @@ void PSOutputDev::setupImage(Ref id, Stream *str, GBool mask,
} else {
s = str->getPSFilter(level < psLevel3 ? 2 : 3, "", gTrue);
if (s) {
- useLZW = useRLE = gFalse;
- useCompressed = gTrue;
+ if (globalParams->getPSLZW() && !str->hasStrongCompression()) {
+ useRLE = gFalse;
+ useLZW = gTrue;
+ useCompressed = gFalse;
+ } else {
+ useLZW = useRLE = gFalse;
+ useCompressed = gTrue;
+ }
delete s;
} else {
if (globalParams->getPSLZW()) {
@@ -4541,10 +4602,21 @@ void PSOutputDev::startPage(int pageNum, GfxState *state) {
tx -= xScale * x1;
ty -= yScale * y1;
}
- // center
+ // offset or center
if (tx0 >= 0 && ty0 >= 0) {
- tx += (rotate == 0 || rotate == 180) ? tx0 : ty0;
- ty += (rotate == 0 || rotate == 180) ? ty0 : -tx0;
+ if (rotate == 0) {
+ tx += tx0;
+ ty += ty0;
+ } else if (rotate == 90) {
+ tx += ty0;
+ ty += (imgWidth - yScale * height) - tx0;
+ } else if (rotate == 180) {
+ tx += (imgWidth - xScale * width) - tx0;
+ ty += (imgHeight - yScale * height) - ty0;
+ } else { // rotate == 270
+ tx += (imgHeight - xScale * width) - ty0;
+ ty += tx0;
+ }
} else if (globalParams->getPSCenter()) {
if (clipLLX0 < clipURX0 && clipLLY0 < clipURY0) {
tx += (imgWidth2 - xScale * (clipURX0 - clipLLX0)) / 2;
@@ -5103,16 +5175,6 @@ void PSOutputDev::updateTextShift(GfxState *state, double shift) {
noStateChanges = gFalse;
}
-void PSOutputDev::saveTextPos(GfxState *state) {
- writePS("currentpoint\n");
- noStateChanges = gFalse;
-}
-
-void PSOutputDev::restoreTextPos(GfxState *state) {
- writePS("m\n");
- noStateChanges = gFalse;
-}
-
void PSOutputDev::stroke(GfxState *state) {
doPath(state->getPath());
if (inType3Char && t3FillColorOnly) {
@@ -5766,23 +5828,10 @@ void PSOutputDev::doPath(GfxPath *path) {
}
}
-void PSOutputDev::drawString(GfxState *state, GString *s) {
- GfxFont *font;
- int wMode;
- int *codeToGID;
- GString *s2;
- double dx, dy, originX, originY, originX0, originY0, tOriginX0, tOriginY0;
- char *p;
- PSFontInfo *fi;
- UnicodeMap *uMap;
- CharCode code;
- Unicode u[8];
- char buf[8];
- double *dxdy;
- int dxdySize, len, nChars, uLen, n, m, i, j;
-
+void PSOutputDev::drawString(GfxState *state, GString *s,
+ GBool fill, GBool stroke, GBool makePath) {
// check for invisible text -- this is used by Acrobat Capture
- if (state->getRender() == 3) {
+ if (!fill && !stroke && !makePath) {
return;
}
@@ -5792,13 +5841,14 @@ void PSOutputDev::drawString(GfxState *state, GString *s) {
}
// get the font
- if (!(font = state->getFont())) {
+ GfxFont *font = state->getFont();
+ if (!font) {
return;
}
- wMode = font->getWMode();
+ int wMode = font->getWMode();
- fi = NULL;
- for (i = 0; i < fontInfo->getLength(); ++i) {
+ PSFontInfo *fi = NULL;
+ for (int i = 0; i < fontInfo->getLength(); ++i) {
fi = (PSFontInfo *)fontInfo->get(i);
if (fi->fontID.num == font->getID()->num &&
fi->fontID.gen == font->getID()->gen) {
@@ -5808,8 +5858,8 @@ void PSOutputDev::drawString(GfxState *state, GString *s) {
}
// check for a subtitute 16-bit font
- uMap = NULL;
- codeToGID = NULL;
+ UnicodeMap *uMap = NULL;
+ int *codeToGID = NULL;
if (font->isCIDFont()) {
if (!(fi && fi->ff)) {
// font substitution failed, so don't output any text
@@ -5827,17 +5877,21 @@ void PSOutputDev::drawString(GfxState *state, GString *s) {
}
// compute the positioning (dx, dy) for each char in the string
- nChars = 0;
- p = s->getCString();
- len = s->getLength();
- s2 = new GString();
- dxdySize = font->isCIDFont() ? 8 : s->getLength();
- dxdy = (double *)gmallocn(2 * dxdySize, sizeof(double));
- originX0 = originY0 = 0; // make gcc happy
+ int nChars = 0;
+ char *p = s->getCString();
+ int len = s->getLength();
+ GString *s2 = new GString();
+ int dxdySize = font->isCIDFont() ? 8 : s->getLength();
+ double *dxdy = (double *)gmallocn(2 * dxdySize, sizeof(double));
+ double originX0 = 0, originY0 = 0;
while (len > 0) {
- n = font->getNextChar(p, len, &code,
- u, (int)(sizeof(u) / sizeof(Unicode)), &uLen,
- &dx, &dy, &originX, &originY);
+ CharCode code;
+ Unicode u[8];
+ int uLen;
+ double dx, dy, originX, originY;
+ int n = font->getNextChar(p, len, &code,
+ u, (int)(sizeof(u) / sizeof(Unicode)), &uLen,
+ &dx, &dy, &originX, &originY);
//~ this doesn't handle the case where the origin offset changes
//~ within a string of characters -- which could be fixed by
//~ modifying dx,dy as needed for each character
@@ -5867,9 +5921,10 @@ void PSOutputDev::drawString(GfxState *state, GString *s) {
} while (nChars + uLen > dxdySize);
dxdy = (double *)greallocn(dxdy, 2 * dxdySize, sizeof(double));
}
- for (i = 0; i < uLen; ++i) {
- m = uMap->mapUnicode(u[i], buf, (int)sizeof(buf));
- for (j = 0; j < m; ++j) {
+ char buf[8];
+ for (int i = 0; i < uLen; ++i) {
+ int m = uMap->mapUnicode(u[i], buf, (int)sizeof(buf));
+ for (int j = 0; j < m; ++j) {
s2->append(buf[j]);
}
//~ this really needs to get the number of chars in the target
@@ -5906,25 +5961,45 @@ void PSOutputDev::drawString(GfxState *state, GString *s) {
}
originX0 *= state->getFontSize();
originY0 *= state->getFontSize();
+ double tOriginX0, tOriginY0;
state->textTransformDelta(originX0, originY0, &tOriginX0, &tOriginY0);
if (nChars > 0) {
if (wMode) {
writePSFmt("{0:.6g} {1:.6g} rmoveto\n", -tOriginX0, -tOriginY0);
}
+
writePSString(s2);
writePS("\n[");
- for (i = 0; i < 2 * nChars; ++i) {
+ for (int i = 0; i < 2 * nChars; ++i) {
if (i > 0) {
writePS("\n");
}
writePSFmt("{0:.6g}", dxdy[i]);
}
+ writePS("] ");
+
+ // the possible operations are:
+ // - fill
+ // - stroke
+ // - fill + stroke
+ // - makePath
+
if (font->getType() == fontType3) {
- writePS("] Tj3\n");
+ writePS("Tj3\n");
} else {
- writePS("] Tj\n");
+ if (fill && stroke) {
+ writePS("TjFS\n");
+ } else if (fill) {
+ writePS("Tj\n");
+ } else if (stroke) {
+ writePS("TjS\n");
+ } else if (makePath) {
+ writePS("TjSave\n");
+ haveSavedTextPath = gTrue;
+ }
}
+
if (wMode) {
writePSFmt("{0:.6g} {1:.6g} rmoveto\n", tOriginX0, tOriginY0);
}
@@ -5932,19 +6007,49 @@ void PSOutputDev::drawString(GfxState *state, GString *s) {
gfree(dxdy);
delete s2;
- if ((state->getRender() & 4) && font->getType() != fontType3) {
- haveTextClip = gTrue;
+ noStateChanges = gFalse;
+}
+
+void PSOutputDev::fillTextPath(GfxState *state) {
+ writePS("Tfill\n");
+}
+
+void PSOutputDev::strokeTextPath(GfxState *state) {
+ writePS("Tstroke\n");
+}
+
+void PSOutputDev::clipToTextPath(GfxState *state) {
+ writePS("Tclip\n");
+}
+
+void PSOutputDev::clipToTextStrokePath(GfxState *state) {
+ writePS("Tstrokeclip\n");
+}
+
+void PSOutputDev::clearTextPath(GfxState *state) {
+ if (haveSavedTextPath) {
+ writePS("Tclear\n");
+ haveSavedTextPath = gFalse;
}
+}
- noStateChanges = gFalse;
+void PSOutputDev::addTextPathToSavedClipPath(GfxState *state) {
+ if (haveSavedTextPath) {
+ writePS("Tsave\n");
+ haveSavedTextPath = gFalse;
+ haveSavedClipPath = gTrue;
+ }
}
-void PSOutputDev::endTextObject(GfxState *state) {
- if (haveTextClip) {
- writePS("Tclip\n");
- haveTextClip = gFalse;
- noStateChanges = gFalse;
+void PSOutputDev::clipToSavedClipPath(GfxState *state) {
+ if (!haveSavedClipPath) {
+ return;
}
+ writePS("Tclip2\n");
+ haveSavedClipPath = gFalse;
+}
+
+void PSOutputDev::endTextObject(GfxState *state) {
}
void PSOutputDev::drawImageMask(GfxState *state, Object *ref, Stream *str,
@@ -6396,6 +6501,11 @@ void PSOutputDev::doImageL2(Object *ref, GfxState *state,
}
useASCII = !(mode == psModeForm || inType3Char || preload);
useCompressed = gFalse;
+ } else if (globalParams->getPSLZW() && !str->hasStrongCompression()) {
+ useRLE = gFalse;
+ useLZW = gTrue;
+ useASCII = !(mode == psModeForm || inType3Char || preload);
+ useCompressed = gFalse;
} else {
useLZW = useRLE = gFalse;
useASCII = str->isBinary() &&
@@ -6869,6 +6979,11 @@ void PSOutputDev::doImageL3(Object *ref, GfxState *state,
}
maskUseASCII = !(mode == psModeForm || inType3Char || preload);
maskUseCompressed = gFalse;
+ } else if (globalParams->getPSLZW() && !maskStr->hasStrongCompression()) {
+ maskUseRLE = gFalse;
+ maskUseLZW = gTrue;
+ maskUseASCII = !(mode == psModeForm || inType3Char || preload);
+ maskUseCompressed = gFalse;
} else {
maskUseLZW = maskUseRLE = gFalse;
maskUseASCII = maskStr->isBinary() &&
@@ -7097,6 +7212,11 @@ void PSOutputDev::doImageL3(Object *ref, GfxState *state,
}
useASCII = !(mode == psModeForm || inType3Char || preload);
useCompressed = gFalse;
+ } else if (globalParams->getPSLZW() && !str->hasStrongCompression()) {
+ useRLE = gFalse;
+ useLZW = gTrue;
+ useASCII = !(mode == psModeForm || inType3Char || preload);
+ useCompressed = gFalse;
} else {
useLZW = useRLE = gFalse;
useASCII = str->isBinary() &&