summaryrefslogtreecommitdiff
path: root/Build/source/libs/xpdf/xpdf-src/xpdf
diff options
context:
space:
mode:
authorAkira Kakuto <kakuto@fuk.kindai.ac.jp>2024-02-10 06:55:23 +0000
committerAkira Kakuto <kakuto@fuk.kindai.ac.jp>2024-02-10 06:55:23 +0000
commit0357cc55904fda095727bb30f07b68dbf3439f8e (patch)
tree4dfe670d69c9d538606e6d49fe29b506c05e5975 /Build/source/libs/xpdf/xpdf-src/xpdf
parent28c5129fe7864e1005edc90cf737372ba1bc78c7 (diff)
xpdf 4.05
git-svn-id: svn://tug.org/texlive/trunk@69765 c570f23f-e606-0410-a88d-b1316a301751
Diffstat (limited to 'Build/source/libs/xpdf/xpdf-src/xpdf')
-rw-r--r--Build/source/libs/xpdf/xpdf-src/xpdf/AcroForm.cc40
-rw-r--r--Build/source/libs/xpdf/xpdf-src/xpdf/AcroForm.h6
-rw-r--r--Build/source/libs/xpdf/xpdf-src/xpdf/Annot.cc396
-rw-r--r--Build/source/libs/xpdf/xpdf-src/xpdf/Annot.h52
-rw-r--r--Build/source/libs/xpdf/xpdf-src/xpdf/Array.cc8
-rw-r--r--Build/source/libs/xpdf/xpdf-src/xpdf/Array.h4
-rw-r--r--Build/source/libs/xpdf/xpdf-src/xpdf/BuiltinFont.cc4
-rw-r--r--Build/source/libs/xpdf/xpdf-src/xpdf/BuiltinFont.h4
-rw-r--r--Build/source/libs/xpdf/xpdf-src/xpdf/CMap.cc4
-rw-r--r--Build/source/libs/xpdf/xpdf-src/xpdf/CMap.h4
-rw-r--r--Build/source/libs/xpdf/xpdf-src/xpdf/Catalog.cc282
-rw-r--r--Build/source/libs/xpdf/xpdf-src/xpdf/Catalog.h15
-rw-r--r--Build/source/libs/xpdf/xpdf-src/xpdf/CharCodeToUnicode.cc18
-rw-r--r--Build/source/libs/xpdf/xpdf-src/xpdf/CharCodeToUnicode.h4
-rw-r--r--Build/source/libs/xpdf/xpdf-src/xpdf/Decrypt.cc36
-rw-r--r--Build/source/libs/xpdf/xpdf-src/xpdf/Decrypt.h4
-rw-r--r--Build/source/libs/xpdf/xpdf-src/xpdf/Dict.cc4
-rw-r--r--Build/source/libs/xpdf/xpdf-src/xpdf/Dict.h4
-rw-r--r--Build/source/libs/xpdf/xpdf-src/xpdf/DisplayState.cc4
-rw-r--r--Build/source/libs/xpdf/xpdf-src/xpdf/DisplayState.h4
-rw-r--r--Build/source/libs/xpdf/xpdf-src/xpdf/Error.cc4
-rw-r--r--Build/source/libs/xpdf/xpdf-src/xpdf/Error.h4
-rw-r--r--Build/source/libs/xpdf/xpdf-src/xpdf/Function.cc4
-rw-r--r--Build/source/libs/xpdf/xpdf-src/xpdf/Function.h4
-rw-r--r--Build/source/libs/xpdf/xpdf-src/xpdf/Gfx.cc514
-rw-r--r--Build/source/libs/xpdf/xpdf-src/xpdf/Gfx.h9
-rw-r--r--Build/source/libs/xpdf/xpdf-src/xpdf/GfxFont.cc269
-rw-r--r--Build/source/libs/xpdf/xpdf-src/xpdf/GfxFont.h18
-rw-r--r--Build/source/libs/xpdf/xpdf-src/xpdf/GfxState.cc456
-rw-r--r--Build/source/libs/xpdf/xpdf-src/xpdf/GfxState.h19
-rw-r--r--Build/source/libs/xpdf/xpdf-src/xpdf/GlobalParams.cc243
-rw-r--r--Build/source/libs/xpdf/xpdf-src/xpdf/GlobalParams.h30
-rw-r--r--Build/source/libs/xpdf/xpdf-src/xpdf/HTMLGen.cc72
-rw-r--r--Build/source/libs/xpdf/xpdf-src/xpdf/HTMLGen.h24
-rw-r--r--Build/source/libs/xpdf/xpdf-src/xpdf/ImageOutputDev.cc8
-rw-r--r--Build/source/libs/xpdf/xpdf-src/xpdf/ImageOutputDev.h4
-rw-r--r--Build/source/libs/xpdf/xpdf-src/xpdf/JArithmeticDecoder.cc4
-rw-r--r--Build/source/libs/xpdf/xpdf-src/xpdf/JArithmeticDecoder.h4
-rw-r--r--Build/source/libs/xpdf/xpdf-src/xpdf/JBIG2Stream.cc28
-rw-r--r--Build/source/libs/xpdf/xpdf-src/xpdf/JBIG2Stream.h5
-rw-r--r--Build/source/libs/xpdf/xpdf-src/xpdf/JPXStream.cc21
-rw-r--r--Build/source/libs/xpdf/xpdf-src/xpdf/JPXStream.h5
-rw-r--r--Build/source/libs/xpdf/xpdf-src/xpdf/Lexer.cc19
-rw-r--r--Build/source/libs/xpdf/xpdf-src/xpdf/Lexer.h4
-rw-r--r--Build/source/libs/xpdf/xpdf-src/xpdf/Link.cc4
-rw-r--r--Build/source/libs/xpdf/xpdf-src/xpdf/Link.h4
-rw-r--r--Build/source/libs/xpdf/xpdf-src/xpdf/NameToCharCode.cc4
-rw-r--r--Build/source/libs/xpdf/xpdf-src/xpdf/NameToCharCode.h4
-rw-r--r--Build/source/libs/xpdf/xpdf-src/xpdf/Object.cc14
-rw-r--r--Build/source/libs/xpdf/xpdf-src/xpdf/Object.h8
-rw-r--r--Build/source/libs/xpdf/xpdf-src/xpdf/OptionalContent.cc4
-rw-r--r--Build/source/libs/xpdf/xpdf-src/xpdf/OptionalContent.h4
-rw-r--r--Build/source/libs/xpdf/xpdf-src/xpdf/Outline.cc4
-rw-r--r--Build/source/libs/xpdf/xpdf-src/xpdf/Outline.h4
-rw-r--r--Build/source/libs/xpdf/xpdf-src/xpdf/OutputDev.cc13
-rw-r--r--Build/source/libs/xpdf/xpdf-src/xpdf/OutputDev.h28
-rw-r--r--Build/source/libs/xpdf/xpdf-src/xpdf/PDF417Barcode.cc4
-rw-r--r--Build/source/libs/xpdf/xpdf-src/xpdf/PDF417Barcode.h4
-rw-r--r--Build/source/libs/xpdf/xpdf-src/xpdf/PDFCore.cc129
-rw-r--r--Build/source/libs/xpdf/xpdf-src/xpdf/PDFCore.h53
-rw-r--r--Build/source/libs/xpdf/xpdf-src/xpdf/PDFDoc.cc16
-rw-r--r--Build/source/libs/xpdf/xpdf-src/xpdf/PDFDoc.h13
-rw-r--r--Build/source/libs/xpdf/xpdf-src/xpdf/PSOutputDev.cc320
-rw-r--r--Build/source/libs/xpdf/xpdf-src/xpdf/PSOutputDev.h25
-rw-r--r--Build/source/libs/xpdf/xpdf-src/xpdf/PSTokenizer.cc4
-rw-r--r--Build/source/libs/xpdf/xpdf-src/xpdf/PSTokenizer.h4
-rw-r--r--Build/source/libs/xpdf/xpdf-src/xpdf/Page.cc19
-rw-r--r--Build/source/libs/xpdf/xpdf-src/xpdf/Page.h5
-rw-r--r--Build/source/libs/xpdf/xpdf-src/xpdf/Parser.cc4
-rw-r--r--Build/source/libs/xpdf/xpdf-src/xpdf/Parser.h4
-rw-r--r--Build/source/libs/xpdf/xpdf-src/xpdf/PreScanOutputDev.cc4
-rw-r--r--Build/source/libs/xpdf/xpdf-src/xpdf/PreScanOutputDev.h4
-rw-r--r--Build/source/libs/xpdf/xpdf-src/xpdf/SecurityHandler.cc4
-rw-r--r--Build/source/libs/xpdf/xpdf-src/xpdf/SecurityHandler.h4
-rw-r--r--Build/source/libs/xpdf/xpdf-src/xpdf/ShadingImage.cc18
-rw-r--r--Build/source/libs/xpdf/xpdf-src/xpdf/ShadingImage.h4
-rw-r--r--Build/source/libs/xpdf/xpdf-src/xpdf/SplashOutputDev.cc188
-rw-r--r--Build/source/libs/xpdf/xpdf-src/xpdf/SplashOutputDev.h17
-rw-r--r--Build/source/libs/xpdf/xpdf-src/xpdf/Stream.cc24
-rw-r--r--Build/source/libs/xpdf/xpdf-src/xpdf/Stream.h12
-rw-r--r--Build/source/libs/xpdf/xpdf-src/xpdf/TextOutputDev.cc569
-rw-r--r--Build/source/libs/xpdf/xpdf-src/xpdf/TextOutputDev.h35
-rw-r--r--Build/source/libs/xpdf/xpdf-src/xpdf/TextString.cc4
-rw-r--r--Build/source/libs/xpdf/xpdf-src/xpdf/TextString.h4
-rw-r--r--Build/source/libs/xpdf/xpdf-src/xpdf/TileCache.cc6
-rw-r--r--Build/source/libs/xpdf/xpdf-src/xpdf/TileCache.h4
-rw-r--r--Build/source/libs/xpdf/xpdf-src/xpdf/TileCompositor.cc4
-rw-r--r--Build/source/libs/xpdf/xpdf-src/xpdf/TileCompositor.h4
-rw-r--r--Build/source/libs/xpdf/xpdf-src/xpdf/TileMap.cc14
-rw-r--r--Build/source/libs/xpdf/xpdf-src/xpdf/TileMap.h4
-rw-r--r--Build/source/libs/xpdf/xpdf-src/xpdf/UnicodeMap.cc4
-rw-r--r--Build/source/libs/xpdf/xpdf-src/xpdf/UnicodeMap.h4
-rw-r--r--Build/source/libs/xpdf/xpdf-src/xpdf/UnicodeRemapping.cc4
-rw-r--r--Build/source/libs/xpdf/xpdf-src/xpdf/UnicodeRemapping.h4
-rw-r--r--Build/source/libs/xpdf/xpdf-src/xpdf/UnicodeTypeTable.cc132
-rw-r--r--Build/source/libs/xpdf/xpdf-src/xpdf/UnicodeTypeTable.h2
-rw-r--r--Build/source/libs/xpdf/xpdf-src/xpdf/WebFont.cc4
-rw-r--r--Build/source/libs/xpdf/xpdf-src/xpdf/WebFont.h4
-rw-r--r--Build/source/libs/xpdf/xpdf-src/xpdf/XFAScanner.cc4
-rw-r--r--Build/source/libs/xpdf/xpdf-src/xpdf/XFAScanner.h4
-rw-r--r--Build/source/libs/xpdf/xpdf-src/xpdf/XRef.cc93
-rw-r--r--Build/source/libs/xpdf/xpdf-src/xpdf/XRef.h9
-rw-r--r--Build/source/libs/xpdf/xpdf-src/xpdf/Zoox.cc12
-rw-r--r--Build/source/libs/xpdf/xpdf-src/xpdf/Zoox.h5
-rw-r--r--Build/source/libs/xpdf/xpdf-src/xpdf/config.h16
-rw-r--r--Build/source/libs/xpdf/xpdf-src/xpdf/pdfdetach.cc11
-rw-r--r--Build/source/libs/xpdf/xpdf-src/xpdf/pdffonts.cc20
-rw-r--r--Build/source/libs/xpdf/xpdf-src/xpdf/pdfimages.cc11
-rw-r--r--Build/source/libs/xpdf/xpdf-src/xpdf/pdfinfo.cc61
-rw-r--r--Build/source/libs/xpdf/xpdf-src/xpdf/pdftohtml.cc38
-rw-r--r--Build/source/libs/xpdf/xpdf-src/xpdf/pdftopng.cc11
-rw-r--r--Build/source/libs/xpdf/xpdf-src/xpdf/pdftoppm.cc11
-rw-r--r--Build/source/libs/xpdf/xpdf-src/xpdf/pdftops.cc11
-rw-r--r--Build/source/libs/xpdf/xpdf-src/xpdf/pdftotext.cc11
114 files changed, 3229 insertions, 1552 deletions
diff --git a/Build/source/libs/xpdf/xpdf-src/xpdf/AcroForm.cc b/Build/source/libs/xpdf/xpdf-src/xpdf/AcroForm.cc
index 7b2b9855669..33534dafd60 100644
--- a/Build/source/libs/xpdf/xpdf-src/xpdf/AcroForm.cc
+++ b/Build/source/libs/xpdf/xpdf-src/xpdf/AcroForm.cc
@@ -8,10 +8,6 @@
#include <aconf.h>
-#ifdef USE_GCC_PRAGMAS
-#pragma implementation
-#endif
-
#include <stdlib.h>
#include <math.h>
#include "gmem.h"
@@ -343,8 +339,12 @@ AcroForm *AcroForm::load(PDFDoc *docA, Catalog *catalog, Object *acroFormObjA) {
AcroForm *acroForm;
AcroFormField *field;
Object xfaObj, fieldsObj, annotsObj, annotRef, annotObj, obj1, obj2;
+ char *touchedObjs;
int pageNum, i, j;
+ touchedObjs = (char *)gmalloc(docA->getXRef()->getNumObjects());
+ memset(touchedObjs, 0, docA->getXRef()->getNumObjects());
+
// this is the normal case: acroFormObj is a dictionary, as expected
if (acroFormObjA->isDict()) {
acroForm = new AcroForm(docA, acroFormObjA);
@@ -372,11 +372,12 @@ AcroForm *AcroForm::load(PDFDoc *docA, Catalog *catalog, Object *acroFormObjA) {
}
obj1.free();
delete acroForm;
+ gfree(touchedObjs);
return NULL;
}
for (i = 0; i < obj1.arrayGetLength(); ++i) {
obj1.arrayGetNF(i, &obj2);
- acroForm->scanField(&obj2);
+ acroForm->scanField(&obj2, touchedObjs);
obj2.free();
}
obj1.free();
@@ -400,7 +401,7 @@ AcroForm *AcroForm::load(PDFDoc *docA, Catalog *catalog, Object *acroFormObjA) {
annotRef.fetch(acroForm->doc->getXRef(), &annotObj);
if (annotObj.isDict()) {
if (annotObj.dictLookup("Subtype", &obj1)->isName("Widget")) {
- acroForm->scanField(&annotRef);
+ acroForm->scanField(&annotRef, touchedObjs);
}
obj1.free();
}
@@ -431,7 +432,7 @@ AcroForm *AcroForm::load(PDFDoc *docA, Catalog *catalog, Object *acroFormObjA) {
annotRef.fetch(acroForm->doc->getXRef(), &annotObj);
if (annotObj.isDict()) {
if (annotObj.dictLookup("Subtype", &obj1)->isName("Widget")) {
- acroForm->scanField(&annotRef);
+ acroForm->scanField(&annotRef, touchedObjs);
}
obj1.free();
}
@@ -449,6 +450,8 @@ AcroForm *AcroForm::load(PDFDoc *docA, Catalog *catalog, Object *acroFormObjA) {
}
}
+ gfree(touchedObjs);
+
return acroForm;
}
@@ -512,12 +515,22 @@ int AcroForm::lookupAnnotPage(Object *annotRef) {
return 0;
}
-void AcroForm::scanField(Object *fieldRef) {
+void AcroForm::scanField(Object *fieldRef, char *touchedObjs) {
AcroFormField *field;
Object fieldObj, kidsObj, kidRef, kidObj, subtypeObj;
GBool isTerminal;
int i;
+ // check for an object loop
+ if (fieldRef->isRef()) {
+ if (fieldRef->getRefNum() < 0 ||
+ fieldRef->getRefNum() >= doc->getXRef()->getNumObjects() ||
+ touchedObjs[fieldRef->getRefNum()]) {
+ return;
+ }
+ touchedObjs[fieldRef->getRefNum()] = 1;
+ }
+
fieldRef->fetch(doc->getXRef(), &fieldObj);
if (!fieldObj.isDict()) {
error(errSyntaxError, -1, "AcroForm field object is wrong type");
@@ -545,7 +558,7 @@ void AcroForm::scanField(Object *fieldRef) {
if (!isTerminal) {
for (i = 0; !isTerminal && i < kidsObj.arrayGetLength(); ++i) {
kidsObj.arrayGetNF(i, &kidRef);
- scanField(&kidRef);
+ scanField(&kidRef, touchedObjs);
kidRef.free();
}
}
@@ -2033,21 +2046,18 @@ void AcroFormField::drawText(GString *text, GString *da, GfxFontDict *fontDict,
wMax = dx - 2 * border - 4;
-#if 1 //~tmp
// this is a kludge that appears to match Adobe's behavior
if (height > 15) {
topBorder = 5;
} else {
topBorder = 2;
}
-#else
- topBorder = 5;
-#endif
// compute font autosize
if (fontSize == 0) {
for (fontSize = 10; fontSize > 1; --fontSize) {
yy = dy - topBorder;
+ w = 0;
i = 0;
while (i < text2->getLength()) {
getNextLine(text2, i, font, fontSize, wMax, &j, &w, &k);
@@ -3183,7 +3193,7 @@ GBool AcroFormField::unicodeStringEqual(Unicode *u, int unicodeLength,
return gFalse;
}
for (int i = 0; i < unicodeLength; ++i) {
- if ((s->getChar(i) & 0xff) != u[i]) {
+ if ((Unicode)(s->getChar(i) & 0xff) != u[i]) {
return gFalse;
}
}
@@ -3193,7 +3203,7 @@ GBool AcroFormField::unicodeStringEqual(Unicode *u, int unicodeLength,
GBool AcroFormField::unicodeStringEqual(Unicode *u, int unicodeLength,
const char *s) {
for (int i = 0; i < unicodeLength; ++i) {
- if (!s[i] || (s[i] & 0xff) != u[i]) {
+ if (!s[i] || (Unicode)(s[i] & 0xff) != u[i]) {
return gFalse;
}
}
diff --git a/Build/source/libs/xpdf/xpdf-src/xpdf/AcroForm.h b/Build/source/libs/xpdf/xpdf-src/xpdf/AcroForm.h
index 7678d46dbc8..0e922d17afc 100644
--- a/Build/source/libs/xpdf/xpdf-src/xpdf/AcroForm.h
+++ b/Build/source/libs/xpdf/xpdf-src/xpdf/AcroForm.h
@@ -11,10 +11,6 @@
#include <aconf.h>
-#ifdef USE_GCC_PRAGMAS
-#pragma interface
-#endif
-
class TextString;
class Gfx;
class GfxFont;
@@ -47,7 +43,7 @@ private:
AcroForm(PDFDoc *docA, Object *acroFormObjA);
void buildAnnotPageList(Catalog *catalog);
int lookupAnnotPage(Object *annotRef);
- void scanField(Object *fieldRef);
+ void scanField(Object *fieldRef, char *touchedObjs);
PDFDoc *doc;
Object acroFormObj;
diff --git a/Build/source/libs/xpdf/xpdf-src/xpdf/Annot.cc b/Build/source/libs/xpdf/xpdf-src/xpdf/Annot.cc
index 82ef600be73..465bda6194a 100644
--- a/Build/source/libs/xpdf/xpdf-src/xpdf/Annot.cc
+++ b/Build/source/libs/xpdf/xpdf-src/xpdf/Annot.cc
@@ -2,18 +2,15 @@
//
// Annot.cc
//
-// Copyright 2000-2003 Glyph & Cog, LLC
+// Copyright 2000-2022 Glyph & Cog, LLC
//
//========================================================================
#include <aconf.h>
-#ifdef USE_GCC_PRAGMAS
-#pragma implementation
-#endif
-
#include <stdlib.h>
#include <math.h>
+#include <limits.h>
#include "gmem.h"
#include "gmempp.h"
#include "GList.h"
@@ -278,6 +275,8 @@ Annot::Annot(PDFDoc *docA, Dict *dict, Ref *refA) {
obj3.free();
} else if (obj2.isRef()) {
obj2.copy(&appearance);
+ } else if (obj2.isStream()) {
+ obj2.copy(&appearance);
}
obj1.free();
obj2.free();
@@ -306,29 +305,48 @@ Annot::~Annot() {
ocObj.free();
}
-void Annot::generateAnnotAppearance() {
+void Annot::generateAnnotAppearance(Object *annotObj) {
Object obj;
-
appearance.fetch(doc->getXRef(), &obj);
- if (!obj.isStream()) {
- if (type) {
- if (!type->cmp("Line")) {
- generateLineAppearance();
- } else if (!type->cmp("PolyLine")) {
- generatePolyLineAppearance();
- } else if (!type->cmp("Polygon")) {
- generatePolygonAppearance();
- } else if (!type->cmp("FreeText")) {
- generateFreeTextAppearance();
- }
- }
- }
+ GBool alreadyHaveAppearance = obj.isStream();
obj.free();
+ if (alreadyHaveAppearance) {
+ return;
+ }
+
+ if (!type || (type->cmp("Line") &&
+ type->cmp("PolyLine") &&
+ type->cmp("Polygon") &&
+ type->cmp("FreeText"))) {
+ return;
+ }
+
+ Object annotObj2;
+ if (!annotObj) {
+ getObject(&annotObj2);
+ annotObj = &annotObj2;
+ }
+ if (!annotObj->isDict()) {
+ annotObj2.free();
+ return;
+ }
+
+ if (!type->cmp("Line")) {
+ generateLineAppearance(annotObj);
+ } else if (!type->cmp("PolyLine")) {
+ generatePolyLineAppearance(annotObj);
+ } else if (!type->cmp("Polygon")) {
+ generatePolygonAppearance(annotObj);
+ } else if (!type->cmp("FreeText")) {
+ generateFreeTextAppearance(annotObj);
+ }
+
+ annotObj2.free();
}
//~ this doesn't draw the caption
-void Annot::generateLineAppearance() {
- Object annotObj, gfxStateDict, appearDict, obj1, obj2;
+void Annot::generateLineAppearance(Object *annotObj) {
+ Object gfxStateDict, appearDict, obj1, obj2;
MemStream *appearStream;
double x1, y1, x2, y2, dx, dy, len, w;
double lx1, ly1, lx2, ly2;
@@ -339,15 +357,10 @@ void Annot::generateLineAppearance() {
AnnotLineEndType lineEnd1, lineEnd2;
GBool fill;
- if (!getObject(&annotObj)->isDict()) {
- annotObj.free();
- return;
- }
-
appearBuf = new GString();
//----- check for transparency
- if (annotObj.dictLookup("CA", &obj1)->isNum()) {
+ if (annotObj->dictLookup("CA", &obj1)->isNum()) {
gfxStateDict.initDict(doc->getXRef());
gfxStateDict.dictAdd(copyString("ca"), obj1.copy(&obj2));
appearBuf->append("/GS1 gs\n");
@@ -358,7 +371,7 @@ void Annot::generateLineAppearance() {
setLineStyle(borderStyle, &w);
setStrokeColor(borderStyle->getColor(), borderStyle->getNumColorComps());
fill = gFalse;
- if (annotObj.dictLookup("IC", &obj1)->isArray()) {
+ if (annotObj->dictLookup("IC", &obj1)->isArray()) {
if (setFillColor(&obj1)) {
fill = gTrue;
}
@@ -366,14 +379,14 @@ void Annot::generateLineAppearance() {
obj1.free();
//----- get line properties
- if (annotObj.dictLookup("L", &obj1)->isArray() &&
+ if (annotObj->dictLookup("L", &obj1)->isArray() &&
obj1.arrayGetLength() == 4) {
if (obj1.arrayGet(0, &obj2)->isNum()) {
x1 = obj2.getNum();
} else {
obj2.free();
obj1.free();
- goto err1;
+ return;
}
obj2.free();
if (obj1.arrayGet(1, &obj2)->isNum()) {
@@ -381,7 +394,7 @@ void Annot::generateLineAppearance() {
} else {
obj2.free();
obj1.free();
- goto err1;
+ return;
}
obj2.free();
if (obj1.arrayGet(2, &obj2)->isNum()) {
@@ -389,7 +402,7 @@ void Annot::generateLineAppearance() {
} else {
obj2.free();
obj1.free();
- goto err1;
+ return;
}
obj2.free();
if (obj1.arrayGet(3, &obj2)->isNum()) {
@@ -397,16 +410,16 @@ void Annot::generateLineAppearance() {
} else {
obj2.free();
obj1.free();
- goto err1;
+ return;
}
obj2.free();
} else {
obj1.free();
- goto err1;
+ return;
}
obj1.free();
lineEnd1 = lineEnd2 = annotLineEndNone;
- if (annotObj.dictLookup("LE", &obj1)->isArray() &&
+ if (annotObj->dictLookup("LE", &obj1)->isArray() &&
obj1.arrayGetLength() == 2) {
lineEnd1 = parseLineEndType(obj1.arrayGet(0, &obj2));
obj2.free();
@@ -414,19 +427,19 @@ void Annot::generateLineAppearance() {
obj2.free();
}
obj1.free();
- if (annotObj.dictLookup("LL", &obj1)->isNum()) {
+ if (annotObj->dictLookup("LL", &obj1)->isNum()) {
leaderLen = obj1.getNum();
} else {
leaderLen = 0;
}
obj1.free();
- if (annotObj.dictLookup("LLE", &obj1)->isNum()) {
+ if (annotObj->dictLookup("LLE", &obj1)->isNum()) {
leaderExtLen = obj1.getNum();
} else {
leaderExtLen = 0;
}
obj1.free();
- if (annotObj.dictLookup("LLO", &obj1)->isNum()) {
+ if (annotObj->dictLookup("LLO", &obj1)->isNum()) {
leaderOffLen = obj1.getNum();
} else {
leaderOffLen = 0;
@@ -513,27 +526,19 @@ void Annot::generateLineAppearance() {
appearBuf->getLength(), &appearDict);
appearance.free();
appearance.initStream(appearStream);
-
- err1:
- annotObj.free();
}
//~ this doesn't handle line ends (arrows)
-void Annot::generatePolyLineAppearance() {
- Object annotObj, gfxStateDict, appearDict, obj1, obj2;
+void Annot::generatePolyLineAppearance(Object *annotObj) {
+ Object gfxStateDict, appearDict, obj1, obj2;
MemStream *appearStream;
double x1, y1, w;
int i;
- if (!getObject(&annotObj)->isDict()) {
- annotObj.free();
- return;
- }
-
appearBuf = new GString();
//----- check for transparency
- if (annotObj.dictLookup("CA", &obj1)->isNum()) {
+ if (annotObj->dictLookup("CA", &obj1)->isNum()) {
gfxStateDict.initDict(doc->getXRef());
gfxStateDict.dictAdd(copyString("ca"), obj1.copy(&obj2));
appearBuf->append("/GS1 gs\n");
@@ -544,7 +549,7 @@ void Annot::generatePolyLineAppearance() {
setLineStyle(borderStyle, &w);
setStrokeColor(borderStyle->getColor(), borderStyle->getNumColorComps());
// fill = gFalse;
- // if (annotObj.dictLookup("IC", &obj1)->isArray()) {
+ // if (annotObj->dictLookup("IC", &obj1)->isArray()) {
// if (setFillColor(&obj1)) {
// fill = gTrue;
// }
@@ -552,22 +557,22 @@ void Annot::generatePolyLineAppearance() {
// obj1.free();
//----- draw line
- if (!annotObj.dictLookup("Vertices", &obj1)->isArray()) {
+ if (!annotObj->dictLookup("Vertices", &obj1)->isArray()) {
obj1.free();
- goto err1;
+ return;
}
for (i = 0; i+1 < obj1.arrayGetLength(); i += 2) {
if (!obj1.arrayGet(i, &obj2)->isNum()) {
obj2.free();
obj1.free();
- goto err1;
+ return;
}
x1 = obj2.getNum();
obj2.free();
if (!obj1.arrayGet(i+1, &obj2)->isNum()) {
obj2.free();
obj1.free();
- goto err1;
+ return;
}
y1 = obj2.getNum();
obj2.free();
@@ -606,26 +611,18 @@ void Annot::generatePolyLineAppearance() {
appearBuf->getLength(), &appearDict);
appearance.free();
appearance.initStream(appearStream);
-
- err1:
- annotObj.free();
}
-void Annot::generatePolygonAppearance() {
- Object annotObj, gfxStateDict, appearDict, obj1, obj2;
+void Annot::generatePolygonAppearance(Object *annotObj) {
+ Object gfxStateDict, appearDict, obj1, obj2;
MemStream *appearStream;
double x1, y1;
int i;
- if (!getObject(&annotObj)->isDict()) {
- annotObj.free();
- return;
- }
-
appearBuf = new GString();
//----- check for transparency
- if (annotObj.dictLookup("CA", &obj1)->isNum()) {
+ if (annotObj->dictLookup("CA", &obj1)->isNum()) {
gfxStateDict.initDict(doc->getXRef());
gfxStateDict.dictAdd(copyString("ca"), obj1.copy(&obj2));
appearBuf->append("/GS1 gs\n");
@@ -633,30 +630,30 @@ void Annot::generatePolygonAppearance() {
obj1.free();
//----- set fill color
- if (!annotObj.dictLookup("IC", &obj1)->isArray() ||
+ if (!annotObj->dictLookup("IC", &obj1)->isArray() ||
!setFillColor(&obj1)) {
obj1.free();
- goto err1;
+ return;
}
obj1.free();
//----- fill polygon
- if (!annotObj.dictLookup("Vertices", &obj1)->isArray()) {
+ if (!annotObj->dictLookup("Vertices", &obj1)->isArray()) {
obj1.free();
- goto err1;
+ return;
}
for (i = 0; i+1 < obj1.arrayGetLength(); i += 2) {
if (!obj1.arrayGet(i, &obj2)->isNum()) {
obj2.free();
obj1.free();
- goto err1;
+ return;
}
x1 = obj2.getNum();
obj2.free();
if (!obj1.arrayGet(i+1, &obj2)->isNum()) {
obj2.free();
obj1.free();
- goto err1;
+ return;
}
y1 = obj2.getNum();
obj2.free();
@@ -695,31 +692,23 @@ void Annot::generatePolygonAppearance() {
appearBuf->getLength(), &appearDict);
appearance.free();
appearance.initStream(appearStream);
-
- err1:
- annotObj.free();
}
//~ this doesn't handle rich text
//~ this doesn't handle the callout
//~ this doesn't handle the RD field
-void Annot::generateFreeTextAppearance() {
- Object annotObj, gfxStateDict, appearDict, obj1, obj2;
+void Annot::generateFreeTextAppearance(Object *annotObj) {
+ Object gfxStateDict, appearDict, obj1, obj2;
Object resources, gsResources, fontResources, defaultFont;
GString *text, *da;
double lineWidth;
int quadding, rot;
MemStream *appearStream;
- if (!getObject(&annotObj)->isDict()) {
- annotObj.free();
- return;
- }
-
appearBuf = new GString();
//----- check for transparency
- if (annotObj.dictLookup("CA", &obj1)->isNum()) {
+ if (annotObj->dictLookup("CA", &obj1)->isNum()) {
gfxStateDict.initDict(doc->getXRef());
gfxStateDict.dictAdd(copyString("ca"), obj1.copy(&obj2));
appearBuf->append("/GS1 gs\n");
@@ -727,19 +716,19 @@ void Annot::generateFreeTextAppearance() {
obj1.free();
//----- draw the text
- if (annotObj.dictLookup("Contents", &obj1)->isString()) {
+ if (annotObj->dictLookup("Contents", &obj1)->isString()) {
text = obj1.getString()->copy();
} else {
text = new GString();
}
obj1.free();
- if (annotObj.dictLookup("Q", &obj1)->isInt()) {
+ if (annotObj->dictLookup("Q", &obj1)->isInt()) {
quadding = obj1.getInt();
} else {
quadding = 0;
}
obj1.free();
- if (annotObj.dictLookup("DA", &obj1)->isString()) {
+ if (annotObj->dictLookup("DA", &obj1)->isString()) {
da = obj1.getString()->copy();
} else {
da = new GString();
@@ -747,7 +736,7 @@ void Annot::generateFreeTextAppearance() {
obj1.free();
// the "Rotate" field is not defined in the PDF spec, but Acrobat
// looks at it
- if (annotObj.dictLookup("Rotate", &obj1)->isInt()) {
+ if (annotObj->dictLookup("Rotate", &obj1)->isInt()) {
rot = obj1.getInt();
} else {
rot = 0;
@@ -797,8 +786,6 @@ void Annot::generateFreeTextAppearance() {
appearBuf->getLength(), &appearDict);
appearance.free();
appearance.initStream(appearStream);
-
- annotObj.free();
}
void Annot::setLineStyle(AnnotBorderStyle *bs, double *lineWidth) {
@@ -1344,105 +1331,192 @@ Object *Annot::getObject(Object *obj) {
}
//------------------------------------------------------------------------
-// Annots
+// PageAnnots
//------------------------------------------------------------------------
-Annots::Annots(PDFDoc *docA, Object *annotsObj) {
- Annot *annot;
- Object obj1, obj2;
- Ref ref;
- GBool drawWidgetAnnots;
- int size;
- int i;
+class PageAnnots {
+public:
+
+ PageAnnots();
+ ~PageAnnots();
+
+ GList *annots; // list of annots on the page [Annot]
+ GBool appearancesGenerated; // set after appearances have been generated
+};
+
+PageAnnots::PageAnnots() {
+ annots = new GList();
+ appearancesGenerated = gFalse;
+}
+
+PageAnnots::~PageAnnots() {
+ deleteGList(annots, Annot);
+}
+//------------------------------------------------------------------------
+// Annots
+//------------------------------------------------------------------------
+
+Annots::Annots(PDFDoc *docA) {
doc = docA;
- annots = NULL;
- size = 0;
- nAnnots = 0;
-
- if (annotsObj->isArray()) {
- // Kludge: some PDF files define an empty AcroForm, but still
- // include Widget-type annotations -- in that case, we want to
- // draw the widgets (since the form code won't). This really
- // ought to look for Widget-type annotations that are not included
- // in any form field.
- drawWidgetAnnots = !doc->getCatalog()->getForm() ||
- doc->getCatalog()->getForm()->getNumFields() == 0;
- for (i = 0; i < annotsObj->arrayGetLength(); ++i) {
- if (annotsObj->arrayGetNF(i, &obj1)->isRef()) {
- ref = obj1.getRef();
- obj1.free();
- annotsObj->arrayGet(i, &obj1);
- } else {
- ref.num = ref.gen = -1;
- }
- if (obj1.isDict()) {
- if (drawWidgetAnnots ||
- !obj1.dictLookup("Subtype", &obj2)->isName("Widget")) {
- annot = new Annot(doc, obj1.getDict(), &ref);
- if (annot->isOk()) {
- if (nAnnots >= size) {
- size += 16;
- annots = (Annot **)greallocn(annots, size, sizeof(Annot *));
- }
- annots[nAnnots++] = annot;
- } else {
- delete annot;
- }
- }
- obj2.free();
- }
- obj1.free();
- }
+ pageAnnots = (PageAnnots **)gmallocn(doc->getNumPages(), sizeof(PageAnnots*));
+ for (int page = 1; page <= doc->getNumPages(); ++page) {
+ pageAnnots[page - 1] = NULL;
}
+ formFieldRefsSize = 0;
+ formFieldRefs = NULL;
}
Annots::~Annots() {
- int i;
+ for (int page = 1; page <= doc->getNumPages(); ++page) {
+ delete pageAnnots[page - 1];
+ }
+ gfree(pageAnnots);
+ gfree(formFieldRefs);
+}
+
+void Annots::loadAnnots(int page) {
+ if (pageAnnots[page - 1]) {
+ return;
+ }
+
+ pageAnnots[page - 1] = new PageAnnots();
+
+ Object annotsObj;
+ doc->getCatalog()->getPage(page)->getAnnots(&annotsObj);
+ if (!annotsObj.isArray()) {
+ annotsObj.free();
+ return;
+ }
+
+ loadFormFieldRefs();
+
+ for (int i = 0; i < annotsObj.arrayGetLength(); ++i) {
+ Object annotObj;
+ Ref annotRef;
+ if (annotsObj.arrayGetNF(i, &annotObj)->isRef()) {
+ annotRef = annotObj.getRef();
+ annotObj.free();
+ annotsObj.arrayGet(i, &annotObj);
+ } else {
+ annotRef.num = annotRef.gen = -1;
+ }
+ if (!annotObj.isDict()) {
+ annotObj.free();
+ continue;
+ }
+
+ // skip any annotations which are used as AcroForm fields --
+ // they'll be rendered by the AcroForm module
+ if (annotRef.num >= 0 && annotRef.num < formFieldRefsSize &&
+ formFieldRefs[annotRef.num]) {
+ annotObj.free();
+ continue;
+ }
+
+ Annot *annot = new Annot(doc, annotObj.getDict(), &annotRef);
+ annotObj.free();
+ if (annot->isOk()) {
+ pageAnnots[page - 1]->annots->append(annot);
+ } else {
+ delete annot;
+ }
+ }
+
+ annotsObj.free();
+}
+
+// Build a set of object refs for AcroForm fields.
+void Annots::loadFormFieldRefs() {
+ if (formFieldRefs) {
+ return;
+ }
- for (i = 0; i < nAnnots; ++i) {
- delete annots[i];
+ AcroForm *form = doc->getCatalog()->getForm();
+ if (!form) {
+ return;
+ }
+
+ int newFormFieldRefsSize = 256;
+ for (int i = 0; i < form->getNumFields(); ++i) {
+ AcroFormField *field = form->getField(i);
+ Object fieldRef;
+ field->getFieldRef(&fieldRef);
+ if (fieldRef.getRefNum() >= formFieldRefsSize) {
+ while (fieldRef.getRefNum() >= newFormFieldRefsSize &&
+ newFormFieldRefsSize <= INT_MAX / 2) {
+ newFormFieldRefsSize *= 2;
+ }
+ if (fieldRef.getRefNum() >= newFormFieldRefsSize) {
+ continue;
+ }
+ formFieldRefs = (char *)grealloc(formFieldRefs, newFormFieldRefsSize);
+ for (int j = formFieldRefsSize; j < newFormFieldRefsSize; ++j) {
+ formFieldRefs[j] = (char)0;
+ }
+ formFieldRefsSize = newFormFieldRefsSize;
+ }
+ formFieldRefs[fieldRef.getRefNum()] = (char)1;
+ fieldRef.free();
}
- gfree(annots);
}
-Annot *Annots::find(double x, double y) {
- int i;
+int Annots::getNumAnnots(int page) {
+ loadAnnots(page);
+ return pageAnnots[page - 1]->annots->getLength();
+}
+
+Annot *Annots::getAnnot(int page, int idx) {
+ loadAnnots(page);
+ return (Annot *)pageAnnots[page - 1]->annots->get(idx);
+}
- for (i = nAnnots - 1; i >= 0; --i) {
- if (annots[i]->inRect(x, y)) {
- return annots[i];
+Annot *Annots::find(int page, double x, double y) {
+ loadAnnots(page);
+ PageAnnots *pa = pageAnnots[page - 1];
+ for (int i = pa->annots->getLength() - 1; i >= 0; --i) {
+ Annot *annot = (Annot *)pa->annots->get(i);
+ if (annot->inRect(x, y)) {
+ return annot;
}
}
return NULL;
}
-int Annots::findIdx(double x, double y) {
- int i;
-
- for (i = nAnnots - 1; i >= 0; --i) {
- if (annots[i]->inRect(x, y)) {
+int Annots::findIdx(int page, double x, double y) {
+ loadAnnots(page);
+ PageAnnots *pa = pageAnnots[page - 1];
+ for (int i = pa->annots->getLength() - 1; i >= 0; --i) {
+ Annot *annot = (Annot *)pa->annots->get(i);
+ if (annot->inRect(x, y)) {
return i;
}
}
return -1;
}
-void Annots::generateAnnotAppearances() {
- int i;
-
- for (i = 0; i < nAnnots; ++i) {
- annots[i]->generateAnnotAppearance();
+void Annots::add(int page, Object *annotObj) {
+ if (!annotObj->isDict()) {
+ return;
+ }
+ Ref annotRef = {-1, -1};
+ Annot *annot = new Annot(doc, annotObj->getDict(), &annotRef);
+ if (annot->isOk()) {
+ annot->generateAnnotAppearance(annotObj);
+ pageAnnots[page - 1]->annots->append(annot);
+ } else {
+ delete annot;
}
}
-Annot *Annots::findAnnot(Ref *ref) {
- int i;
-
- for (i = 0; i < nAnnots; ++i) {
- if (annots[i]->match(ref)) {
- return annots[i];
+void Annots::generateAnnotAppearances(int page) {
+ loadAnnots(page);
+ PageAnnots *pa = pageAnnots[page - 1];
+ if (!pa->appearancesGenerated) {
+ for (int i = 0; i < pa->annots->getLength(); ++i) {
+ Annot *annot = (Annot *)pa->annots->get(i);
+ annot->generateAnnotAppearance(NULL);
}
+ pa->appearancesGenerated = gTrue;
}
- return NULL;
}
diff --git a/Build/source/libs/xpdf/xpdf-src/xpdf/Annot.h b/Build/source/libs/xpdf/xpdf-src/xpdf/Annot.h
index 6ba5ff490da..168061fc262 100644
--- a/Build/source/libs/xpdf/xpdf-src/xpdf/Annot.h
+++ b/Build/source/libs/xpdf/xpdf-src/xpdf/Annot.h
@@ -2,7 +2,7 @@
//
// Annot.h
//
-// Copyright 2000-2003 Glyph & Cog, LLC
+// Copyright 2000-2022 Glyph & Cog, LLC
//
//========================================================================
@@ -11,15 +11,12 @@
#include <aconf.h>
-#ifdef USE_GCC_PRAGMAS
-#pragma interface
-#endif
-
class XRef;
class Catalog;
class Gfx;
class GfxFontDict;
class PDFDoc;
+class PageAnnots;
//------------------------------------------------------------------------
// AnnotBorderStyle
@@ -105,14 +102,14 @@ public:
GBool match(Ref *refA)
{ return ref.num == refA->num && ref.gen == refA->gen; }
- void generateAnnotAppearance();
+ void generateAnnotAppearance(Object *annotObj);
private:
- void generateLineAppearance();
- void generatePolyLineAppearance();
- void generatePolygonAppearance();
- void generateFreeTextAppearance();
+ void generateLineAppearance(Object *annotObj);
+ void generatePolyLineAppearance(Object *annotObj);
+ void generatePolygonAppearance(Object *annotObj);
+ void generateFreeTextAppearance(Object *annotObj);
void setLineStyle(AnnotBorderStyle *bs, double *lineWidth);
void setStrokeColor(double *color, int nComps);
GBool setFillColor(Object *colorObj);
@@ -152,34 +149,35 @@ private:
class Annots {
public:
- // Build a list of Annot objects.
- Annots(PDFDoc *docA, Object *annotsObj);
+ Annots(PDFDoc *docA);
~Annots();
- // Iterate through list of annotations.
- int getNumAnnots() { return nAnnots; }
- Annot *getAnnot(int i) { return annots[i]; }
+ // Iterate over annotations on a specific page.
+ int getNumAnnots(int page);
+ Annot *getAnnot(int page, int idx);
- // If point <x>,<y> is in an annotation, return the associated
- // annotation; else return NULL.
- Annot *find(double x, double y);
- int findIdx(double x, double y);
+ // If point (<x>,<y>) is in an annotation, return the associated
+ // annotation (or annotation index); else return NULL (or -1).
+ Annot *find(int page, double x, double y);
+ int findIdx(int page, double x, double y);
+
+ // Add an annotation [annotObj] on page [page].
+ void add(int page, Object *annotObj);
// Generate an appearance stream for any non-form-field annotation
- // that is missing it.
- void generateAnnotAppearances();
+ // on the specified page that is missing an appearance.
+ void generateAnnotAppearances(int page);
private:
- void scanFieldAppearances(Dict *node, Ref *ref, Dict *parent,
- Dict *acroForm);
-
- Annot *findAnnot(Ref *ref);
+ void loadAnnots(int page);
+ void loadFormFieldRefs();
PDFDoc *doc;
- Annot **annots;
- int nAnnots;
+ PageAnnots **pageAnnots; // list of annots for each page
+ int formFieldRefsSize; // number of entries in formFieldRefs[]
+ char *formFieldRefs; // set of AcroForm field refs
};
#endif
diff --git a/Build/source/libs/xpdf/xpdf-src/xpdf/Array.cc b/Build/source/libs/xpdf/xpdf-src/xpdf/Array.cc
index 2bf948ec65c..2771186152a 100644
--- a/Build/source/libs/xpdf/xpdf-src/xpdf/Array.cc
+++ b/Build/source/libs/xpdf/xpdf-src/xpdf/Array.cc
@@ -8,10 +8,6 @@
#include <aconf.h>
-#ifdef USE_GCC_PRAGMAS
-#pragma implementation
-#endif
-
#include <stdlib.h>
#include <stddef.h>
#include "gmem.h"
@@ -53,7 +49,7 @@ void Array::add(Object *elem) {
Object *Array::get(int i, Object *obj, int recursion) {
if (i < 0 || i >= length) {
-#ifdef DEBUG_MEM
+#ifdef DEBUG_OBJECT_MEM
abort();
#else
return obj->initNull();
@@ -64,7 +60,7 @@ Object *Array::get(int i, Object *obj, int recursion) {
Object *Array::getNF(int i, Object *obj) {
if (i < 0 || i >= length) {
-#ifdef DEBUG_MEM
+#ifdef DEBUG_OBJECT_MEM
abort();
#else
return obj->initNull();
diff --git a/Build/source/libs/xpdf/xpdf-src/xpdf/Array.h b/Build/source/libs/xpdf/xpdf-src/xpdf/Array.h
index 8d10eadc8dd..9a887f41e46 100644
--- a/Build/source/libs/xpdf/xpdf-src/xpdf/Array.h
+++ b/Build/source/libs/xpdf/xpdf-src/xpdf/Array.h
@@ -11,10 +11,6 @@
#include <aconf.h>
-#ifdef USE_GCC_PRAGMAS
-#pragma interface
-#endif
-
#if MULTITHREADED
#include "GMutex.h"
#endif
diff --git a/Build/source/libs/xpdf/xpdf-src/xpdf/BuiltinFont.cc b/Build/source/libs/xpdf/xpdf-src/xpdf/BuiltinFont.cc
index d2f875e45fd..51c2d33b3f9 100644
--- a/Build/source/libs/xpdf/xpdf-src/xpdf/BuiltinFont.cc
+++ b/Build/source/libs/xpdf/xpdf-src/xpdf/BuiltinFont.cc
@@ -8,10 +8,6 @@
#include <aconf.h>
-#ifdef USE_GCC_PRAGMAS
-#pragma implementation
-#endif
-
#include <stdlib.h>
#include <string.h>
#include "gmem.h"
diff --git a/Build/source/libs/xpdf/xpdf-src/xpdf/BuiltinFont.h b/Build/source/libs/xpdf/xpdf-src/xpdf/BuiltinFont.h
index f24cbf98f9f..042e4e0d634 100644
--- a/Build/source/libs/xpdf/xpdf-src/xpdf/BuiltinFont.h
+++ b/Build/source/libs/xpdf/xpdf-src/xpdf/BuiltinFont.h
@@ -11,10 +11,6 @@
#include <aconf.h>
-#ifdef USE_GCC_PRAGMAS
-#pragma interface
-#endif
-
#include "gtypes.h"
struct BuiltinFont;
diff --git a/Build/source/libs/xpdf/xpdf-src/xpdf/CMap.cc b/Build/source/libs/xpdf/xpdf-src/xpdf/CMap.cc
index 12632c5992c..c898ac5737d 100644
--- a/Build/source/libs/xpdf/xpdf-src/xpdf/CMap.cc
+++ b/Build/source/libs/xpdf/xpdf-src/xpdf/CMap.cc
@@ -8,10 +8,6 @@
#include <aconf.h>
-#ifdef USE_GCC_PRAGMAS
-#pragma implementation
-#endif
-
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
diff --git a/Build/source/libs/xpdf/xpdf-src/xpdf/CMap.h b/Build/source/libs/xpdf/xpdf-src/xpdf/CMap.h
index 55692b4f337..5731ef09f01 100644
--- a/Build/source/libs/xpdf/xpdf-src/xpdf/CMap.h
+++ b/Build/source/libs/xpdf/xpdf-src/xpdf/CMap.h
@@ -11,10 +11,6 @@
#include <aconf.h>
-#ifdef USE_GCC_PRAGMAS
-#pragma interface
-#endif
-
#include "gtypes.h"
#include "CharTypes.h"
diff --git a/Build/source/libs/xpdf/xpdf-src/xpdf/Catalog.cc b/Build/source/libs/xpdf/xpdf-src/xpdf/Catalog.cc
index ddcbad55f07..7a9b0701ca3 100644
--- a/Build/source/libs/xpdf/xpdf-src/xpdf/Catalog.cc
+++ b/Build/source/libs/xpdf/xpdf-src/xpdf/Catalog.cc
@@ -8,10 +8,6 @@
#include <aconf.h>
-#ifdef USE_GCC_PRAGMAS
-#pragma implementation
-#endif
-
#include <string.h>
#include <stddef.h>
#include <limits.h>
@@ -526,7 +522,10 @@ GBool Catalog::readPageTree(Object *catDict) {
// because other code tries to fetch pages 1 through n.
// In both cases: ignore the given page count and scan the tree
// instead.
- numPages = countPageTree(&topPagesObj);
+ char *touchedObjs = (char *)gmalloc(xref->getNumObjects());
+ memset(touchedObjs, 0, xref->getNumObjects());
+ numPages = countPageTree(&topPagesRef, touchedObjs);
+ gfree(touchedObjs);
}
} else {
// assume we got a Page node instead of a Pages node
@@ -553,30 +552,53 @@ GBool Catalog::readPageTree(Object *catDict) {
return gTrue;
}
-int Catalog::countPageTree(Object *pagesObj) {
- Object kids, kid;
- int n, n2, i;
-
- if (!pagesObj->isDict()) {
+int Catalog::countPageTree(Object *pagesNodeRef, char *touchedObjs) {
+ // check for invalid reference
+ if (pagesNodeRef->isRef() &&
+ (pagesNodeRef->getRefNum() < 0 ||
+ pagesNodeRef->getRefNum() >= xref->getNumObjects())) {
return 0;
}
- if (pagesObj->dictLookup("Kids", &kids)->isArray()) {
- n = 0;
- for (i = 0; i < kids.arrayGetLength(); ++i) {
- kids.arrayGet(i, &kid);
- n2 = countPageTree(&kid);
- if (n2 < INT_MAX - n) {
- n += n2;
- } else {
- error(errSyntaxError, -1, "Page tree contains too many pages");
- n = INT_MAX;
- }
- kid.free();
+
+ // check for a page tree loop; fetch the node object
+ Object pagesNode;
+ if (pagesNodeRef->isRef()) {
+ if (touchedObjs[pagesNodeRef->getRefNum()]) {
+ error(errSyntaxError, -1, "Loop in Pages tree");
+ return 0;
}
+ touchedObjs[pagesNodeRef->getRefNum()] = 1;
+ xref->fetch(pagesNodeRef->getRefNum(), pagesNodeRef->getRefGen(),
+ &pagesNode);
} else {
- n = 1;
+ pagesNodeRef->copy(&pagesNode);
+ }
+
+ // count the subtree
+ int n = 0;
+ if (pagesNode.isDict()) {
+ Object kids;
+ if (pagesNode.dictLookup("Kids", &kids)->isArray()) {
+ for (int i = 0; i < kids.arrayGetLength(); ++i) {
+ Object kid;
+ kids.arrayGetNF(i, &kid);
+ int n2 = countPageTree(&kid, touchedObjs);
+ if (n2 < INT_MAX - n) {
+ n += n2;
+ } else {
+ error(errSyntaxError, -1, "Page tree contains too many pages");
+ n = INT_MAX;
+ }
+ kid.free();
+ }
+ } else {
+ n = 1;
+ }
+ kids.free();
}
- kids.free();
+
+ pagesNode.free();
+
return n;
}
@@ -738,37 +760,55 @@ void Catalog::readEmbeddedFileList(Dict *catDict) {
Object obj1, obj2;
char *touchedObjs;
+ touchedObjs = (char *)gmalloc(xref->getNumObjects());
+ memset(touchedObjs, 0, xref->getNumObjects());
+
// read the embedded file name tree
if (catDict->lookup("Names", &obj1)->isDict()) {
- if (obj1.dictLookup("EmbeddedFiles", &obj2)->isDict()) {
- readEmbeddedFileTree(&obj2);
- }
+ obj1.dictLookupNF("EmbeddedFiles", &obj2);
+ readEmbeddedFileTree(&obj2, touchedObjs);
obj2.free();
}
obj1.free();
// look for file attachment annotations
- touchedObjs = (char *)gmalloc(xref->getNumObjects());
- memset(touchedObjs, 0, xref->getNumObjects());
readFileAttachmentAnnots(catDict->lookupNF("Pages", &obj1), touchedObjs);
obj1.free();
+
gfree(touchedObjs);
}
-void Catalog::readEmbeddedFileTree(Object *node) {
- Object kidsObj, kidObj;
+void Catalog::readEmbeddedFileTree(Object *nodeRef, char *touchedObjs) {
+ Object node, kidsObj, kidObj;
Object namesObj, nameObj, fileSpecObj;
int i;
- if (node->dictLookup("Kids", &kidsObj)->isArray()) {
+ // check for an object loop
+ if (nodeRef->isRef()) {
+ if (nodeRef->getRefNum() < 0 ||
+ nodeRef->getRefNum() >= xref->getNumObjects() ||
+ touchedObjs[nodeRef->getRefNum()]) {
+ return;
+ }
+ touchedObjs[nodeRef->getRefNum()] = 1;
+ xref->fetch(nodeRef->getRefNum(), nodeRef->getRefGen(), &node);
+ } else {
+ nodeRef->copy(&node);
+ }
+
+ if (!node.isDict()) {
+ node.free();
+ return;
+ }
+
+ if (node.dictLookup("Kids", &kidsObj)->isArray()) {
for (i = 0; i < kidsObj.arrayGetLength(); ++i) {
- if (kidsObj.arrayGet(i, &kidObj)->isDict()) {
- readEmbeddedFileTree(&kidObj);
- }
+ kidsObj.arrayGetNF(i, &kidObj);
+ readEmbeddedFileTree(&kidObj, touchedObjs);
kidObj.free();
}
} else {
- if (node->dictLookup("Names", &namesObj)->isArray()) {
+ if (node.dictLookup("Names", &namesObj)->isArray()) {
for (i = 0; i+1 < namesObj.arrayGetLength(); ++i) {
namesObj.arrayGet(i, &nameObj);
namesObj.arrayGet(i+1, &fileSpecObj);
@@ -780,6 +820,8 @@ void Catalog::readEmbeddedFileTree(Object *node) {
namesObj.free();
}
kidsObj.free();
+
+ node.free();
}
void Catalog::readFileAttachmentAnnots(Object *pageNodeRef,
@@ -788,8 +830,9 @@ void Catalog::readFileAttachmentAnnots(Object *pageNodeRef,
int i;
// check for an invalid object reference (e.g., in a damaged PDF file)
- if (pageNodeRef->getRefNum() < 0 ||
- pageNodeRef->getRefNum() >= xref->getNumObjects()) {
+ if (pageNodeRef->isRef() &&
+ (pageNodeRef->getRefNum() < 0 ||
+ pageNodeRef->getRefNum() >= xref->getNumObjects())) {
return;
}
@@ -901,10 +944,14 @@ Object *Catalog::getEmbeddedFileStreamObj(int idx, Object *strObj) {
void Catalog::readPageLabelTree(Object *root) {
PageLabelNode *label0, *label1;
+ char *touchedObjs;
int i;
+ touchedObjs = (char *)gmalloc(xref->getNumObjects());
+ memset(touchedObjs, 0, xref->getNumObjects());
pageLabels = new GList();
- readPageLabelTree2(root);
+ readPageLabelTree2(root, touchedObjs);
+ gfree(touchedObjs);
if (pageLabels->getLength() == 0) {
deleteGList(pageLabels, PageLabelNode);
@@ -922,15 +969,29 @@ void Catalog::readPageLabelTree(Object *root) {
label0->lastPage = numPages;
}
-void Catalog::readPageLabelTree2(Object *node) {
- Object nums, num, labelObj, kids, kid;
+void Catalog::readPageLabelTree2(Object *nodeRef, char *touchedObjs) {
+ Object node, nums, num, labelObj, kids, kid;
int i;
- if (!node->isDict()) {
+ // check for an object loop
+ if (nodeRef->isRef()) {
+ if (nodeRef->getRefNum() < 0 ||
+ nodeRef->getRefNum() >= xref->getNumObjects() ||
+ touchedObjs[nodeRef->getRefNum()]) {
+ return;
+ }
+ touchedObjs[nodeRef->getRefNum()] = 1;
+ xref->fetch(nodeRef->getRefNum(), nodeRef->getRefGen(), &node);
+ } else {
+ nodeRef->copy(&node);
+ }
+
+ if (!node.isDict()) {
+ node.free();
return;
}
- if (node->dictLookup("Nums", &nums)->isArray()) {
+ if (node.dictLookup("Nums", &nums)->isArray()) {
for (i = 0; i < nums.arrayGetLength() - 1; i += 2) {
if (nums.arrayGet(i, &num)->isInt()) {
if (nums.arrayGet(i+1, &labelObj)->isDict()) {
@@ -944,14 +1005,16 @@ void Catalog::readPageLabelTree2(Object *node) {
}
nums.free();
- if (node->dictLookup("Kids", &kids)->isArray()) {
+ if (node.dictLookup("Kids", &kids)->isArray()) {
for (i = 0; i < kids.arrayGetLength(); ++i) {
- kids.arrayGet(i, &kid);
- readPageLabelTree2(&kid);
+ kids.arrayGetNF(i, &kid);
+ readPageLabelTree2(&kid, touchedObjs);
kid.free();
}
}
kids.free();
+
+ node.free();
}
TextString *Catalog::getPageLabel(int pageNum) {
@@ -1195,3 +1258,130 @@ GBool Catalog::convertPageLabelToInt(TextString *pageLabel, int prefixLength,
}
return gFalse;
}
+
+GBool Catalog::usesJavaScript() {
+ Object catDict;
+ if (!xref->getCatalog(&catDict)->isDict()) {
+ catDict.free();
+ return gFalse;
+ }
+
+ GBool usesJS = gFalse;
+
+ // check for Catalog.Names.JavaScript
+ Object namesObj;
+ if (catDict.dictLookup("Names", &namesObj)->isDict()) {
+ Object jsNamesObj;
+ namesObj.dictLookup("JavaScript", &jsNamesObj);
+ if (jsNamesObj.isDict()) {
+ usesJS = gTrue;
+ }
+ jsNamesObj.free();
+ }
+ namesObj.free();
+
+ // look for JavaScript actionas in Page.AA
+ if (!usesJS) {
+ char *touchedObjs = (char *)gmalloc(xref->getNumObjects());
+ memset(touchedObjs, 0, xref->getNumObjects());
+ Object pagesObj;
+ usesJS = scanPageTreeForJavaScript(catDict.dictLookupNF("Pages", &pagesObj),
+ touchedObjs);
+ pagesObj.free();
+ gfree(touchedObjs);
+ }
+
+ catDict.free();
+
+ return usesJS;
+}
+
+GBool Catalog::scanPageTreeForJavaScript(Object *pageNodeRef,
+ char *touchedObjs) {
+ // check for an invalid object reference (e.g., in a damaged PDF file)
+ if (pageNodeRef->isRef() &&
+ (pageNodeRef->getRefNum() < 0 ||
+ pageNodeRef->getRefNum() >= xref->getNumObjects())) {
+ return gFalse;
+ }
+
+ // check for a page tree loop
+ Object pageNode;
+ if (pageNodeRef->isRef()) {
+ if (touchedObjs[pageNodeRef->getRefNum()]) {
+ return gFalse;
+ }
+ touchedObjs[pageNodeRef->getRefNum()] = 1;
+ xref->fetch(pageNodeRef->getRefNum(), pageNodeRef->getRefGen(), &pageNode);
+ } else {
+ pageNodeRef->copy(&pageNode);
+ }
+
+ // scan the page tree node
+ GBool usesJS = gFalse;
+ if (pageNode.isDict()) {
+ Object kids;
+ if (pageNode.dictLookup("Kids", &kids)->isArray()) {
+ for (int i = 0; i < kids.arrayGetLength() && !usesJS; ++i) {
+ Object kid;
+ if (scanPageTreeForJavaScript(kids.arrayGetNF(i, &kid), touchedObjs)) {
+ usesJS = gTrue;
+ }
+ kid.free();
+ }
+ } else {
+
+ // scan Page.AA
+ Object pageAA;
+ if (pageNode.dictLookup("AA", &pageAA)->isDict()) {
+ if (scanAAForJavaScript(&pageAA)) {
+ usesJS = gTrue;
+ }
+ }
+ pageAA.free();
+
+ // scanPage.Annots
+ if (!usesJS) {
+ Object annots;
+ if (pageNode.dictLookup("Annots", &annots)->isArray()) {
+ for (int i = 0; i < annots.arrayGetLength() && !usesJS; ++i) {
+ Object annot;
+ if (annots.arrayGet(i, &annot)->isDict()) {
+ Object annotAA;
+ if (annot.dictLookup("AA", &annotAA)->isDict()) {
+ if (scanAAForJavaScript(&annotAA)) {
+ usesJS = gTrue;
+ }
+ }
+ annotAA.free();
+ }
+ annot.free();
+ }
+ }
+ annots.free();
+ }
+ }
+ kids.free();
+ }
+
+ pageNode.free();
+
+ return usesJS;
+}
+
+GBool Catalog::scanAAForJavaScript(Object *aaObj) {
+ GBool usesJS = gFalse;
+ for (int i = 0; i < aaObj->dictGetLength() && !usesJS; ++i) {
+ Object action;
+ if (aaObj->dictGetVal(i, &action)->isDict()) {
+ Object js;
+ if (!action.dictLookupNF("JS", &js)->isNull()) {
+ usesJS = gTrue;
+ }
+ js.free();
+ }
+ action.free();
+ }
+ return usesJS;
+}
+
diff --git a/Build/source/libs/xpdf/xpdf-src/xpdf/Catalog.h b/Build/source/libs/xpdf/xpdf-src/xpdf/Catalog.h
index 0acdd2d1574..91597e54137 100644
--- a/Build/source/libs/xpdf/xpdf-src/xpdf/Catalog.h
+++ b/Build/source/libs/xpdf/xpdf-src/xpdf/Catalog.h
@@ -11,10 +11,6 @@
#include <aconf.h>
-#ifdef USE_GCC_PRAGMAS
-#pragma interface
-#endif
-
#if MULTITHREADED
#include "GMutex.h"
#endif
@@ -118,6 +114,9 @@ public:
Object *getViewerPreferences() { return &viewerPrefs; }
+ // Return true if the document uses JavaScript.
+ GBool usesJavaScript();
+
private:
PDFDoc *doc;
@@ -146,21 +145,23 @@ private:
Object *findDestInTree(Object *tree, GString *name, Object *obj);
GBool readPageTree(Object *catDict);
- int countPageTree(Object *pagesObj);
+ int countPageTree(Object *pagesNodeRef, char *touchedObjs);
void loadPage(int pg);
void loadPage2(int pg, int relPg, PageTreeNode *node);
void readEmbeddedFileList(Dict *catDict);
- void readEmbeddedFileTree(Object *node);
+ void readEmbeddedFileTree(Object *nodeRef, char *touchedObjs);
void readFileAttachmentAnnots(Object *pageNodeRef,
char *touchedObjs);
void readEmbeddedFile(Object *fileSpec, Object *name1);
void readPageLabelTree(Object *root);
- void readPageLabelTree2(Object *node);
+ void readPageLabelTree2(Object *node, char *touchedObjs);
PageLabelNode *findPageLabel(int pageNum);
GString *makeRomanNumeral(int num, GBool uppercase);
GString *makeLetterLabel(int num, GBool uppercase);
GBool convertPageLabelToInt(TextString *pageLabel, int prefixLength,
char style, int *n);
+ GBool scanPageTreeForJavaScript(Object *pageNodeRef, char *touchedObjs);
+ GBool scanAAForJavaScript(Object *aaObj);
};
#endif
diff --git a/Build/source/libs/xpdf/xpdf-src/xpdf/CharCodeToUnicode.cc b/Build/source/libs/xpdf/xpdf-src/xpdf/CharCodeToUnicode.cc
index 0a2100fde9b..83720069e64 100644
--- a/Build/source/libs/xpdf/xpdf-src/xpdf/CharCodeToUnicode.cc
+++ b/Build/source/libs/xpdf/xpdf-src/xpdf/CharCodeToUnicode.cc
@@ -8,10 +8,6 @@
#include <aconf.h>
-#ifdef USE_GCC_PRAGMAS
-#pragma implementation
-#endif
-
#include <stdio.h>
#include <string.h>
#include "gmem.h"
@@ -274,7 +270,18 @@ GBool CharCodeToUnicode::parseCMap1(int (*getCharFunc)(void *), void *data,
pst = new PSTokenizer(getCharFunc, data);
pst->getToken(tok1, sizeof(tok1), &n1);
while (pst->getToken(tok2, sizeof(tok2), &n2)) {
- if (!strcmp(tok2, "usecmap")) {
+ if (!strcmp(tok1, "begincodespacerange")) {
+ if (globalParams->getIgnoreWrongSizeToUnicode() &&
+ tok2[0] == '<' && tok2[n2 - 1] == '>' &&
+ n2 - 2 != nBits / 4) {
+ error(errSyntaxWarning, -1,
+ "Incorrect character size in ToUnicode CMap");
+ ok = gFalse;
+ break;
+ }
+ while (pst->getToken(tok1, sizeof(tok1), &n1) &&
+ strcmp(tok1, "endcodespacerange")) ;
+ } else if (!strcmp(tok2, "usecmap")) {
if (tok1[0] == '/') {
name = new GString(tok1 + 1);
if ((f = globalParams->findToUnicodeFile(name))) {
@@ -465,6 +472,7 @@ GBool CharCodeToUnicode::parseCMap1(int (*getCharFunc)(void *), void *data,
pst->getToken(tok1, sizeof(tok1), &n1);
} else {
strcpy(tok1, tok2);
+ n1 = n2;
}
}
delete pst;
diff --git a/Build/source/libs/xpdf/xpdf-src/xpdf/CharCodeToUnicode.h b/Build/source/libs/xpdf/xpdf-src/xpdf/CharCodeToUnicode.h
index be9025107aa..7bbc97f834e 100644
--- a/Build/source/libs/xpdf/xpdf-src/xpdf/CharCodeToUnicode.h
+++ b/Build/source/libs/xpdf/xpdf-src/xpdf/CharCodeToUnicode.h
@@ -13,10 +13,6 @@
#include <aconf.h>
-#ifdef USE_GCC_PRAGMAS
-#pragma interface
-#endif
-
#include "CharTypes.h"
#if MULTITHREADED
diff --git a/Build/source/libs/xpdf/xpdf-src/xpdf/Decrypt.cc b/Build/source/libs/xpdf/xpdf-src/xpdf/Decrypt.cc
index d4f8d4ec336..d36626dc344 100644
--- a/Build/source/libs/xpdf/xpdf-src/xpdf/Decrypt.cc
+++ b/Build/source/libs/xpdf/xpdf-src/xpdf/Decrypt.cc
@@ -8,10 +8,6 @@
#include <aconf.h>
-#ifdef USE_GCC_PRAGMAS
-#pragma implementation
-#endif
-
#include <string.h>
#include "gmem.h"
#include "gmempp.h"
@@ -1492,14 +1488,14 @@ static void sha512(Guchar *msg, int msgLen, Guchar *hash) {
SHA512Uint64 H[8];
int blkLen, i;
- H[0] = 0x6a09e667f3bcc908LL;
- H[1] = 0xbb67ae8584caa73bLL;
- H[2] = 0x3c6ef372fe94f82bLL;
- H[3] = 0xa54ff53a5f1d36f1LL;
- H[4] = 0x510e527fade682d1LL;
- H[5] = 0x9b05688c2b3e6c1fLL;
- H[6] = 0x1f83d9abfb41bd6bLL;
- H[7] = 0x5be0cd19137e2179LL;
+ H[0] = 0x6a09e667f3bcc908ULL;
+ H[1] = 0xbb67ae8584caa73bULL;
+ H[2] = 0x3c6ef372fe94f82bULL;
+ H[3] = 0xa54ff53a5f1d36f1ULL;
+ H[4] = 0x510e527fade682d1ULL;
+ H[5] = 0x9b05688c2b3e6c1fULL;
+ H[6] = 0x1f83d9abfb41bd6bULL;
+ H[7] = 0x5be0cd19137e2179ULL;
blkLen = 0;
for (i = 0; i + 128 <= msgLen; i += 128) {
@@ -1558,14 +1554,14 @@ static void sha384(Guchar *msg, int msgLen, Guchar *hash) {
SHA512Uint64 H[8];
int blkLen, i;
- H[0] = 0xcbbb9d5dc1059ed8LL;
- H[1] = 0x629a292a367cd507LL;
- H[2] = 0x9159015a3070dd17LL;
- H[3] = 0x152fecd8f70e5939LL;
- H[4] = 0x67332667ffc00b31LL;
- H[5] = 0x8eb44a8768581511LL;
- H[6] = 0xdb0c2e0d64f98fa7LL;
- H[7] = 0x47b5481dbefa4fa4LL;
+ H[0] = 0xcbbb9d5dc1059ed8ULL;
+ H[1] = 0x629a292a367cd507ULL;
+ H[2] = 0x9159015a3070dd17ULL;
+ H[3] = 0x152fecd8f70e5939ULL;
+ H[4] = 0x67332667ffc00b31ULL;
+ H[5] = 0x8eb44a8768581511ULL;
+ H[6] = 0xdb0c2e0d64f98fa7ULL;
+ H[7] = 0x47b5481dbefa4fa4ULL;
blkLen = 0;
for (i = 0; i + 128 <= msgLen; i += 128) {
diff --git a/Build/source/libs/xpdf/xpdf-src/xpdf/Decrypt.h b/Build/source/libs/xpdf/xpdf-src/xpdf/Decrypt.h
index 2b10abd050b..d0f38409109 100644
--- a/Build/source/libs/xpdf/xpdf-src/xpdf/Decrypt.h
+++ b/Build/source/libs/xpdf/xpdf-src/xpdf/Decrypt.h
@@ -11,10 +11,6 @@
#include <aconf.h>
-#ifdef USE_GCC_PRAGMAS
-#pragma interface
-#endif
-
#include "gtypes.h"
#include "GString.h"
#include "Object.h"
diff --git a/Build/source/libs/xpdf/xpdf-src/xpdf/Dict.cc b/Build/source/libs/xpdf/xpdf-src/xpdf/Dict.cc
index c8c29736fe9..71ea377f8a7 100644
--- a/Build/source/libs/xpdf/xpdf-src/xpdf/Dict.cc
+++ b/Build/source/libs/xpdf/xpdf-src/xpdf/Dict.cc
@@ -8,10 +8,6 @@
#include <aconf.h>
-#ifdef USE_GCC_PRAGMAS
-#pragma implementation
-#endif
-
#include <stddef.h>
#include <string.h>
#include "gmem.h"
diff --git a/Build/source/libs/xpdf/xpdf-src/xpdf/Dict.h b/Build/source/libs/xpdf/xpdf-src/xpdf/Dict.h
index b05f729e0a8..804fcdf1312 100644
--- a/Build/source/libs/xpdf/xpdf-src/xpdf/Dict.h
+++ b/Build/source/libs/xpdf/xpdf-src/xpdf/Dict.h
@@ -11,10 +11,6 @@
#include <aconf.h>
-#ifdef USE_GCC_PRAGMAS
-#pragma interface
-#endif
-
#if MULTITHREADED
#include "GMutex.h"
#endif
diff --git a/Build/source/libs/xpdf/xpdf-src/xpdf/DisplayState.cc b/Build/source/libs/xpdf/xpdf-src/xpdf/DisplayState.cc
index e0d306857ca..f1e8dcffeac 100644
--- a/Build/source/libs/xpdf/xpdf-src/xpdf/DisplayState.cc
+++ b/Build/source/libs/xpdf/xpdf-src/xpdf/DisplayState.cc
@@ -8,10 +8,6 @@
#include <aconf.h>
-#ifdef USE_GCC_PRAGMAS
-#pragma implementation
-#endif
-
#include <stdlib.h>
#include "gmempp.h"
#include "GString.h"
diff --git a/Build/source/libs/xpdf/xpdf-src/xpdf/DisplayState.h b/Build/source/libs/xpdf/xpdf-src/xpdf/DisplayState.h
index 12c8170f0b3..a078c757d33 100644
--- a/Build/source/libs/xpdf/xpdf-src/xpdf/DisplayState.h
+++ b/Build/source/libs/xpdf/xpdf-src/xpdf/DisplayState.h
@@ -11,10 +11,6 @@
#include <aconf.h>
-#ifdef USE_GCC_PRAGMAS
-#pragma interface
-#endif
-
#include "gtypes.h"
#include "SplashTypes.h"
diff --git a/Build/source/libs/xpdf/xpdf-src/xpdf/Error.cc b/Build/source/libs/xpdf/xpdf-src/xpdf/Error.cc
index aec27dc5099..111f277d3c2 100644
--- a/Build/source/libs/xpdf/xpdf-src/xpdf/Error.cc
+++ b/Build/source/libs/xpdf/xpdf-src/xpdf/Error.cc
@@ -8,10 +8,6 @@
#include <aconf.h>
-#ifdef USE_GCC_PRAGMAS
-#pragma implementation
-#endif
-
#include <stdio.h>
#include <stddef.h>
#include <stdarg.h>
diff --git a/Build/source/libs/xpdf/xpdf-src/xpdf/Error.h b/Build/source/libs/xpdf/xpdf-src/xpdf/Error.h
index 39e7613e4e6..574330f6446 100644
--- a/Build/source/libs/xpdf/xpdf-src/xpdf/Error.h
+++ b/Build/source/libs/xpdf/xpdf-src/xpdf/Error.h
@@ -11,10 +11,6 @@
#include <aconf.h>
-#ifdef USE_GCC_PRAGMAS
-#pragma interface
-#endif
-
#include <stdio.h>
#include "config.h"
#include "gfile.h"
diff --git a/Build/source/libs/xpdf/xpdf-src/xpdf/Function.cc b/Build/source/libs/xpdf/xpdf-src/xpdf/Function.cc
index 82f32b9dd93..966a3155c50 100644
--- a/Build/source/libs/xpdf/xpdf-src/xpdf/Function.cc
+++ b/Build/source/libs/xpdf/xpdf-src/xpdf/Function.cc
@@ -8,10 +8,6 @@
#include <aconf.h>
-#ifdef USE_GCC_PRAGMAS
-#pragma implementation
-#endif
-
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
diff --git a/Build/source/libs/xpdf/xpdf-src/xpdf/Function.h b/Build/source/libs/xpdf/xpdf-src/xpdf/Function.h
index bf1f25e51cc..73c92abe30c 100644
--- a/Build/source/libs/xpdf/xpdf-src/xpdf/Function.h
+++ b/Build/source/libs/xpdf/xpdf-src/xpdf/Function.h
@@ -11,10 +11,6 @@
#include <aconf.h>
-#ifdef USE_GCC_PRAGMAS
-#pragma interface
-#endif
-
#include "gtypes.h"
#include "Object.h"
diff --git a/Build/source/libs/xpdf/xpdf-src/xpdf/Gfx.cc b/Build/source/libs/xpdf/xpdf-src/xpdf/Gfx.cc
index 1539b8404bc..ea7951a75fc 100644
--- a/Build/source/libs/xpdf/xpdf-src/xpdf/Gfx.cc
+++ b/Build/source/libs/xpdf/xpdf-src/xpdf/Gfx.cc
@@ -8,10 +8,6 @@
#include <aconf.h>
-#ifdef USE_GCC_PRAGMAS
-#pragma implementation
-#endif
-
#include <stdlib.h>
#include <stdio.h>
#include <stddef.h>
@@ -536,6 +532,7 @@ Gfx::Gfx(PDFDoc *docA, OutputDev *outA, int pageNum, Dict *resDict,
out = outA;
state = new GfxState(hDPI, vDPI, box, rotate, out->upsideDown());
fontChanged = gFalse;
+ haveSavedClipPath = gFalse;
clip = clipNone;
ignoreUndef = 0;
out->startPage(pageNum, state);
@@ -584,6 +581,7 @@ Gfx::Gfx(PDFDoc *docA, OutputDev *outA, Dict *resDict,
out = outA;
state = new GfxState(72, 72, box, 0, gFalse);
fontChanged = gFalse;
+ haveSavedClipPath = gFalse;
clip = clipNone;
ignoreUndef = 0;
for (i = 0; i < 6; ++i) {
@@ -1829,15 +1827,20 @@ void Gfx::opFillStroke(Object args[], int numArgs) {
}
if (state->isPath()) {
if (ocState) {
- if (state->getFillColorSpace()->getMode() == csPattern) {
- doPatternFill(gFalse);
- } else {
- out->fill(state);
- }
- if (state->getStrokeColorSpace()->getMode() == csPattern) {
- doPatternStroke();
+ if (state->getFillColorSpace()->getMode() == csPattern ||
+ state->getStrokeColorSpace()->getMode() == csPattern) {
+ if (state->getFillColorSpace()->getMode() == csPattern) {
+ doPatternFill(gFalse);
+ } else {
+ out->fill(state);
+ }
+ if (state->getStrokeColorSpace()->getMode() == csPattern) {
+ doPatternStroke();
+ } else {
+ out->stroke(state);
+ }
} else {
- out->stroke(state);
+ out->fillStroke(state, gFalse);
}
}
}
@@ -1852,15 +1855,20 @@ void Gfx::opCloseFillStroke(Object args[], int numArgs) {
if (state->isPath()) {
state->closePath();
if (ocState) {
- if (state->getFillColorSpace()->getMode() == csPattern) {
- doPatternFill(gFalse);
- } else {
- out->fill(state);
- }
- if (state->getStrokeColorSpace()->getMode() == csPattern) {
- doPatternStroke();
+ if (state->getFillColorSpace()->getMode() == csPattern ||
+ state->getStrokeColorSpace()->getMode() == csPattern) {
+ if (state->getFillColorSpace()->getMode() == csPattern) {
+ doPatternFill(gFalse);
+ } else {
+ out->fill(state);
+ }
+ if (state->getStrokeColorSpace()->getMode() == csPattern) {
+ doPatternStroke();
+ } else {
+ out->stroke(state);
+ }
} else {
- out->stroke(state);
+ out->fillStroke(state, gFalse);
}
}
}
@@ -1874,15 +1882,20 @@ void Gfx::opEOFillStroke(Object args[], int numArgs) {
}
if (state->isPath()) {
if (ocState) {
- if (state->getFillColorSpace()->getMode() == csPattern) {
- doPatternFill(gTrue);
- } else {
- out->eoFill(state);
- }
- if (state->getStrokeColorSpace()->getMode() == csPattern) {
- doPatternStroke();
+ if (state->getFillColorSpace()->getMode() == csPattern ||
+ state->getStrokeColorSpace()->getMode() == csPattern) {
+ if (state->getFillColorSpace()->getMode() == csPattern) {
+ doPatternFill(gTrue);
+ } else {
+ out->eoFill(state);
+ }
+ if (state->getStrokeColorSpace()->getMode() == csPattern) {
+ doPatternStroke();
+ } else {
+ out->stroke(state);
+ }
} else {
- out->stroke(state);
+ out->fillStroke(state, gTrue);
}
}
}
@@ -1897,15 +1910,20 @@ void Gfx::opCloseEOFillStroke(Object args[], int numArgs) {
if (state->isPath()) {
state->closePath();
if (ocState) {
- if (state->getFillColorSpace()->getMode() == csPattern) {
- doPatternFill(gTrue);
- } else {
- out->eoFill(state);
- }
- if (state->getStrokeColorSpace()->getMode() == csPattern) {
- doPatternStroke();
+ if (state->getFillColorSpace()->getMode() == csPattern ||
+ state->getStrokeColorSpace()->getMode() == csPattern) {
+ if (state->getFillColorSpace()->getMode() == csPattern) {
+ doPatternFill(gTrue);
+ } else {
+ out->eoFill(state);
+ }
+ if (state->getStrokeColorSpace()->getMode() == csPattern) {
+ doPatternStroke();
+ } else {
+ out->stroke(state);
+ }
} else {
- out->stroke(state);
+ out->fillStroke(state, gTrue);
}
}
}
@@ -1966,7 +1984,7 @@ void Gfx::doPatternStroke() {
}
}
-void Gfx::doPatternText() {
+void Gfx::doPatternText(GBool stroke) {
GfxPattern *pattern;
// this is a bit of a kludge -- patterns can be really slow, so we
@@ -1976,7 +1994,8 @@ void Gfx::doPatternText() {
return;
}
- if (!(pattern = state->getFillPattern())) {
+ pattern = stroke ? state->getStrokePattern() : state->getFillPattern();
+ if (!pattern) {
return;
}
switch (pattern->getType()) {
@@ -2193,16 +2212,30 @@ void Gfx::doTilingPatternFill(GfxTilingPattern *tPat,
if (bbox[1] > bbox[3]) {
t = bbox[1]; bbox[1] = bbox[3]; bbox[3] = t;
}
- xstep = fabs(tPat->getXStep());
- ystep = fabs(tPat->getYStep());
- xi0 = (int)ceil((xMin - bbox[2]) / xstep);
- xi1 = (int)floor((xMax - bbox[0]) / xstep) + 1;
- yi0 = (int)ceil((yMin - bbox[3]) / ystep);
- yi1 = (int)floor((yMax - bbox[1]) / ystep) + 1;
+ xstep = tPat->getXStep();
+ ystep = tPat->getYStep();
+ if (xstep == 0 || ystep == 0) {
+ error(errSyntaxError, getPos(), "Zero x or y step in tiling pattern fill");
+ goto err;
+ }
+ if (xstep > 0) {
+ xi0 = (int)ceil((xMin - bbox[2]) / xstep);
+ xi1 = (int)floor((xMax - bbox[0]) / xstep) + 1;
+ } else {
+ xi0 = (int)ceil((xMax - bbox[0]) / xstep);
+ xi1 = (int)floor((xMin - bbox[2]) / xstep) + 1;
+ }
+ if (ystep > 0) {
+ yi0 = (int)ceil((yMin - bbox[3]) / ystep);
+ yi1 = (int)floor((yMax - bbox[1]) / ystep) + 1;
+ } else {
+ yi0 = (int)ceil((yMax - bbox[1]) / ystep);
+ yi1 = (int)floor((yMin - bbox[3]) / ystep) + 1;
+ }
for (i = 0; i < 4; ++i) {
m1[i] = m[i];
}
- if (out->useTilingPatternFill()) {
+ if (out->useTilingPatternFill() && !tPat->usesBlendMode(xref)) {
m1[4] = m[4];
m1[5] = m[5];
out->tilingPatternFill(state, this, tPat->getContentStreamRef(),
@@ -3521,12 +3554,16 @@ void Gfx::fillPatch(GfxPatch *patch, GfxPatchMeshShading *shading, int depth) {
}
void Gfx::doEndPath() {
- if (state->isCurPt() && clip != clipNone) {
- state->clip();
- if (clip == clipNormal) {
- out->clip(state);
+ if (clip != clipNone) {
+ if (state->isCurPt()) {
+ state->clip();
+ if (clip == clipNormal) {
+ out->clip(state);
+ } else {
+ out->eoClip(state);
+ }
} else {
- out->eoClip(state);
+ error(errSyntaxError, getPos(), "Empty path in clip");
}
}
clip = clipNone;
@@ -3555,9 +3592,15 @@ void Gfx::opBeginText(Object args[], int numArgs) {
out->updateTextMat(state);
out->updateTextPos(state);
fontChanged = gTrue;
+ haveSavedClipPath = gFalse;
}
void Gfx::opEndText(Object args[], int numArgs) {
+ if (haveSavedClipPath) {
+ out->clipToSavedClipPath(state);
+ haveSavedClipPath = gFalse;
+ }
+
out->endTextObject(state);
}
@@ -3786,27 +3829,8 @@ void Gfx::opShowSpaceText(Object args[], int numArgs) {
}
void Gfx::doShowText(GString *s) {
- GfxFont *font;
- int wMode;
- double riseX, riseY;
- CharCode code;
- Unicode u[8];
- double x, y, dx, dy, dx2, dy2, curX, curY, tdx, tdy, ddx, ddy;
- double originX, originY, tOriginX, tOriginY;
- double x0, y0, x1, y1;
- double oldCTM[6], newCTM[6];
- double *mat;
- Object charProcRef, charProc;
- Dict *resDict;
- Parser *oldParser;
- GfxState *savedState;
- char *p;
- int render;
- GBool patternFill;
- int len, n, uLen, nChars, nSpaces, i;
-
- font = state->getFont();
- wMode = font->getWMode();
+ GfxFont *font = state->getFont();
+ int wMode = font->getWMode();
if (globalParams->isDroppedFont(font->getName()
? font->getName()->getCString() : "")) {
@@ -3818,35 +3842,63 @@ void Gfx::doShowText(GString *s) {
out->beginString(state, s);
}
- // if we're doing a pattern fill, set up clipping
- render = state->getRender();
- if (!(render & 1) &&
- state->getFillColorSpace()->getMode() == csPattern) {
- patternFill = gTrue;
- saveState();
- // disable fill, enable clipping, leave stroke unchanged
- if ((render ^ (render >> 1)) & 1) {
- render = 5;
+ // figure out the drawing mode
+ // note: clipping, pattern fill, and pattern stroke are all handled
+ // by saving the path and then performing the appropriate
+ // actions in opEndText()
+ GBool doFill = gFalse;
+ GBool doStroke = gFalse;
+ GBool doMakePath = gFalse;
+ int render = state->getRender() & 7;
+ switch (render & 7) {
+ case 0: // fill
+ if (state->getFillColorSpace()->getMode() == csPattern) {
+ doMakePath = gTrue;
} else {
- render = 7;
+ doFill = gTrue;
}
- state->setRender(render);
- out->updateRender(state);
- } else {
- patternFill = gFalse;
+ break;
+ case 1: // stroke
+ if (state->getStrokeColorSpace()->getMode() == csPattern) {
+ doMakePath = gTrue;
+ } else {
+ doStroke = gTrue;
+ }
+ break;
+ case 2: // fill + stroke
+ if (state->getFillColorSpace()->getMode() == csPattern ||
+ state->getStrokeColorSpace()->getMode() == csPattern) {
+ doMakePath = gTrue;
+ } else {
+ doFill = gTrue;
+ doStroke = gTrue;
+ }
+ break;
+ case 3: // invisible
+ // nothing
+ break;
+ case 4: // fill + clip
+ case 5: // stroke + clip
+ case 6: // fill + stroke + clip
+ case 7: // clip
+ doMakePath = gTrue;
+ break;
}
+ double riseX, riseY;
state->textTransformDelta(0, state->getRise(), &riseX, &riseY);
- x0 = state->getCurX() + riseX;
- y0 = state->getCurY() + riseY;
+ double xMin = state->getCurX() + riseX;
+ double yMin = state->getCurY() + riseY;
// handle a Type 3 char
if (font->getType() == fontType3 && out->interpretType3Chars()) {
- mat = state->getCTM();
- for (i = 0; i < 6; ++i) {
+ double *mat = state->getCTM();
+ double oldCTM[6];
+ for (int i = 0; i < 6; ++i) {
oldCTM[i] = mat[i];
}
mat = state->getTextMat();
+ double newCTM[6];
newCTM[0] = mat[0] * oldCTM[0] + mat[1] * oldCTM[2];
newCTM[1] = mat[0] * oldCTM[1] + mat[1] * oldCTM[3];
newCTM[2] = mat[2] * oldCTM[0] + mat[3] * oldCTM[2];
@@ -3862,24 +3914,29 @@ void Gfx::doShowText(GString *s) {
newCTM[3] *= state->getFontSize();
newCTM[0] *= state->getHorizScaling();
newCTM[1] *= state->getHorizScaling();
- curX = state->getCurX();
- curY = state->getCurY();
- oldParser = parser;
- p = s->getCString();
- len = s->getLength();
+ double curX = state->getCurX();
+ double curY = state->getCurY();
+ Parser *oldParser = parser;
+ char *p = s->getCString();
+ int len = s->getLength();
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);
dx = dx * state->getFontSize() + state->getCharSpace();
if (n == 1 && *p == ' ') {
dx += state->getWordSpace();
}
dx *= state->getHorizScaling();
dy *= state->getFontSize();
+ double tdx, tdy, ddx, ddy, x, y;
state->textTransformDelta(dx, dy, &tdx, &tdy);
state->transform(curX + riseX, curY + riseY, &x, &y);
- savedState = saveStateStack();
+ GfxState *savedState = saveStateStack();
state->setCTM(newCTM[0], newCTM[1], newCTM[2], newCTM[3], x, y);
//~ the CTM concat values here are wrong (but never used)
out->updateCTM(state, 1, 0, 0, 1, 0, 0);
@@ -3899,9 +3956,11 @@ void Gfx::doShowText(GString *s) {
#endif
if (!out->beginType3Char(state, curX + riseX, curY + riseY, ddx, ddy,
code, u, uLen)) {
+ Object charProcRef, charProc;
((Gfx8BitFont *)font)->getCharProcNF(code, &charProcRef);
charProcRef.fetch(xref, &charProc);
- if ((resDict = ((Gfx8BitFont *)font)->getResources())) {
+ Dict *resDict = ((Gfx8BitFont *)font)->getResources();
+ if (resDict) {
pushResources(resDict);
}
if (charProc.isStream()) {
@@ -3927,12 +3986,16 @@ void Gfx::doShowText(GString *s) {
parser = oldParser;
} else if (out->useDrawChar()) {
- p = s->getCString();
- len = s->getLength();
+ char *p = s->getCString();
+ int len = s->getLength();
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);
if (wMode) {
dx *= state->getFontSize();
dy = dy * state->getFontSize() + state->getCharSpace();
@@ -3947,26 +4010,32 @@ void Gfx::doShowText(GString *s) {
dx *= state->getHorizScaling();
dy *= state->getFontSize();
}
+ double tdx, tdy, tOriginX, tOriginY;
state->textTransformDelta(dx, dy, &tdx, &tdy);
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);
+ tdx, tdy, tOriginX, tOriginY, code, n, u, uLen,
+ doFill, doStroke, doMakePath);
state->shift(tdx, tdy);
p += n;
len -= n;
}
} else {
- dx = dy = 0;
- p = s->getCString();
- len = s->getLength();
- nChars = nSpaces = 0;
+ double dx = 0, dy = 0;
+ char *p = s->getCString();
+ int len = s->getLength();
+ int nChars = 0, nSpaces = 0;
while (len > 0) {
- n = font->getNextChar(p, len, &code,
- u, (int)(sizeof(u) / sizeof(Unicode)), &uLen,
- &dx2, &dy2, &originX, &originY);
+ CharCode code;
+ Unicode u[8];
+ int uLen;
+ double dx2, dy2, originX, originY;
+ int 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 == ' ') {
@@ -3988,8 +4057,9 @@ void Gfx::doShowText(GString *s) {
dx *= state->getHorizScaling();
dy *= state->getFontSize();
}
+ double tdx, tdy;
state->textTransformDelta(dx, dy, &tdx, &tdy);
- out->drawString(state, s);
+ out->drawString(state, s, doFill, doStroke, doMakePath);
state->shift(tdx, tdy);
}
@@ -3997,40 +4067,70 @@ void Gfx::doShowText(GString *s) {
out->endString(state);
}
- if (patternFill) {
- out->saveTextPos(state);
- // tell the OutputDev to do the clipping
- out->endTextObject(state);
- // set up a clipping bbox so doPatternText will work -- assume
+ if (doMakePath) {
+ // compute the clipping bbox for the saved text path -- assume
// that the text bounding box does not extend past the baseline in
// any direction by more than twice the font size
- x1 = state->getCurX() + riseX;
- y1 = state->getCurY() + riseY;
- if (x0 > x1) {
- x = x0; x0 = x1; x1 = x;
+ double xMax = state->getCurX() + riseX;
+ double yMax = state->getCurY() + riseY;
+ double t;
+ if (xMin > xMax) {
+ t = xMin; xMin = xMax; xMax = t;
}
- if (y0 > y1) {
- y = y0; y0 = y1; y1 = y;
+ if (yMin > yMax) {
+ t = yMin; yMin = yMax; yMax = t;
}
- state->textTransformDelta(0, state->getFontSize(), &dx, &dy);
+ double dx1, dy1, dx2, dy2;
+ state->textTransformDelta(0, state->getFontSize(), &dx1, &dy1);
state->textTransformDelta(state->getFontSize(), 0, &dx2, &dy2);
- dx = fabs(dx);
+ dx1 = fabs(dx1);
dx2 = fabs(dx2);
- if (dx2 > dx) {
- dx = dx2;
+ if (dx2 > dx1) {
+ dx1 = dx2;
}
- dy = fabs(dy);
+ dy1 = fabs(dy1);
dy2 = fabs(dy2);
- if (dy2 > dy) {
- dy = dy2;
- }
- state->clipToRect(x0 - 2 * dx, y0 - 2 * dy, x1 + 2 * dx, y1 + 2 * dy);
- // set render mode to fill-only
- state->setRender(0);
- out->updateRender(state);
- doPatternText();
- restoreState();
- out->restoreTextPos(state);
+ if (dy2 > dy1) {
+ dy1 = dy2;
+ }
+ xMin -= 2 * dx1;
+ yMin -= 2 * dy1;
+ xMax += 2 * dx1;
+ yMax += 2 * dy1;
+
+ //--- fill
+ if ((render & 3) == 0 || (render & 3) == 2) {
+ if (state->getFillColorSpace()->getMode() == csPattern) {
+ saveState();
+ state->clipToRect(xMin, yMin, xMax, yMax);
+ out->clipToTextPath(state);
+ doPatternText(gFalse);
+ restoreState();
+ } else {
+ out->fillTextPath(state);
+ }
+ }
+
+ //--- stroke
+ if ((render & 3) == 1 || (render & 3) == 2) {
+ if (state->getStrokeColorSpace()->getMode() == csPattern) {
+ saveState();
+ state->clipToRect(xMin, yMin, xMax, yMax);
+ out->clipToTextStrokePath(state);
+ doPatternText(gTrue);
+ restoreState();
+ } else {
+ out->strokeTextPath(state);
+ }
+ }
+
+ //--- clip
+ if (render & 4) {
+ out->addTextPathToSavedClipPath(state);
+ haveSavedClipPath = gTrue;
+ } else {
+ out->clearTextPath(state);
+ }
}
opCounter += 10 * s->getLength();
@@ -4116,6 +4216,7 @@ void Gfx::opXObject(Object args[], int numArgs) {
xObj.streamGetDict()->lookup("Level1", &obj3);
out->psXObject(xObj.getStream(),
obj3.isStream() ? obj3.getStream() : (Stream *)NULL);
+ obj3.free();
}
} else if (obj2.isName()) {
error(errSyntaxError, getPos(),
@@ -4191,10 +4292,14 @@ GBool Gfx::doImage(Object *ref, Stream *str, GBool inlineImg) {
obj1.free();
dict->lookup("W", &obj1);
}
- if (!obj1.isInt()) {
+ if (obj1.isInt()) {
+ width = obj1.getInt();
+ } else if (obj1.isReal()) {
+ error(errSyntaxWarning, getPos(), "Non-integer image width");
+ width = (int)obj1.getReal();
+ } else {
goto err2;
}
- width = obj1.getInt();
obj1.free();
if (width <= 0) {
goto err1;
@@ -4204,10 +4309,14 @@ GBool Gfx::doImage(Object *ref, Stream *str, GBool inlineImg) {
obj1.free();
dict->lookup("H", &obj1);
}
- if (!obj1.isInt()) {
+ if (obj1.isInt()) {
+ height = obj1.getInt();
+ } else if (obj1.isReal()) {
+ error(errSyntaxWarning, getPos(), "Non-integer image height");
+ height = (int)obj1.getReal();
+ } else {
goto err2;
}
- height = obj1.getInt();
obj1.free();
if (height <= 0) {
goto err1;
@@ -4233,8 +4342,14 @@ GBool Gfx::doImage(Object *ref, Stream *str, GBool inlineImg) {
obj1.free();
dict->lookup("BPC", &obj1);
}
- if (obj1.isInt()) {
- bits = obj1.getInt();
+ if (obj1.isNum()) {
+ if (obj1.isInt()) {
+ bits = obj1.getInt();
+ } else if (obj1.isReal()) {
+ error(errSyntaxWarning, getPos(),
+ "Non-integer image bits per component");
+ bits = (int)obj1.getReal();
+ }
if (bits < 1 || bits > 16) {
goto err2;
}
@@ -4377,26 +4492,34 @@ GBool Gfx::doImage(Object *ref, Stream *str, GBool inlineImg) {
obj1.free();
maskDict->lookup("W", &obj1);
}
- if (!obj1.isInt()) {
+ if (obj1.isInt()) {
+ maskWidth = obj1.getInt();
+ } else if (obj1.isReal()) {
+ error(errSyntaxWarning, getPos(), "Non-integer image mask width");
+ maskWidth = (int)obj1.getReal();
+ } else {
delete colorMap;
maskObj.free();
smaskObj.free();
goto err2;
}
- maskWidth = obj1.getInt();
obj1.free();
maskDict->lookup("Height", &obj1);
if (obj1.isNull()) {
obj1.free();
maskDict->lookup("H", &obj1);
}
- if (!obj1.isInt()) {
+ if (obj1.isInt()) {
+ maskHeight = obj1.getInt();
+ } else if (obj1.isReal()) {
+ error(errSyntaxWarning, getPos(), "Non-integer image mask height");
+ maskHeight = (int)obj1.getReal();
+ } else {
delete colorMap;
maskObj.free();
smaskObj.free();
goto err2;
}
- maskHeight = obj1.getInt();
obj1.free();
if (maskWidth <= 0 || maskHeight <= 0) {
delete colorMap;
@@ -4409,13 +4532,18 @@ GBool Gfx::doImage(Object *ref, Stream *str, GBool inlineImg) {
obj1.free();
maskDict->lookup("BPC", &obj1);
}
- if (!obj1.isInt()) {
+ if (obj1.isInt()) {
+ maskBits = obj1.getInt();
+ } else if (obj1.isReal()) {
+ error(errSyntaxWarning, getPos(),
+ "Non-integer image mask bits per component");
+ maskBits = (int)obj1.getReal();
+ } else {
delete colorMap;
maskObj.free();
smaskObj.free();
goto err2;
}
- maskBits = obj1.getInt();
obj1.free();
if (maskBits < 1 || maskBits > 16) {
delete colorMap;
@@ -4512,6 +4640,7 @@ GBool Gfx::doImage(Object *ref, Stream *str, GBool inlineImg) {
}
} else if (maskObj.isStream()) {
// explicit mask
+ haveExplicitMask = gTrue;
if (inlineImg) {
delete colorMap;
maskObj.free();
@@ -4526,32 +4655,31 @@ GBool Gfx::doImage(Object *ref, Stream *str, GBool inlineImg) {
obj1.free();
maskDict->lookup("W", &obj1);
}
- if (!obj1.isInt()) {
- delete colorMap;
- maskObj.free();
- smaskObj.free();
- goto err2;
+ if (obj1.isInt()) {
+ maskWidth = obj1.getInt();
+ } else if (obj1.isReal()) {
+ error(errSyntaxWarning, getPos(), "Non-integer image mask width");
+ maskWidth = (int)obj1.getReal();
+ } else {
+ haveExplicitMask = gFalse;
}
- maskWidth = obj1.getInt();
obj1.free();
maskDict->lookup("Height", &obj1);
if (obj1.isNull()) {
obj1.free();
maskDict->lookup("H", &obj1);
}
- if (!obj1.isInt()) {
- delete colorMap;
- maskObj.free();
- smaskObj.free();
- goto err2;
+ if (obj1.isInt()) {
+ maskHeight = obj1.getInt();
+ } else if (obj1.isReal()) {
+ error(errSyntaxWarning, getPos(), "Non-integer image mask height");
+ maskHeight = (int)obj1.getReal();
+ } else {
+ haveExplicitMask = gFalse;
}
- maskHeight = obj1.getInt();
obj1.free();
if (maskWidth <= 0 || maskHeight <= 0) {
- delete colorMap;
- maskObj.free();
- smaskObj.free();
- goto err2;
+ haveExplicitMask = gFalse;
}
maskDict->lookup("ImageMask", &obj1);
if (obj1.isNull()) {
@@ -4559,10 +4687,7 @@ GBool Gfx::doImage(Object *ref, Stream *str, GBool inlineImg) {
maskDict->lookup("IM", &obj1);
}
if (!obj1.isBool() || !obj1.getBool()) {
- delete colorMap;
- maskObj.free();
- smaskObj.free();
- goto err2;
+ haveExplicitMask = gFalse;
}
obj1.free();
maskInvert = gFalse;
@@ -4576,13 +4701,12 @@ GBool Gfx::doImage(Object *ref, Stream *str, GBool inlineImg) {
maskInvert = obj2.isNum() && obj2.getNum() == 1;
obj2.free();
} else if (!obj1.isNull()) {
- delete colorMap;
- maskObj.free();
- smaskObj.free();
- goto err2;
+ haveExplicitMask = gFalse;
}
obj1.free();
- haveExplicitMask = gTrue;
+ if (!haveExplicitMask) {
+ error(errSyntaxError, getPos(), "Bad image parameters");
+ }
}
// if drawing is disabled, skip over inline image data
@@ -4768,6 +4892,8 @@ void Gfx::drawForm(Object *strRef, Dict *resDict,
double oldBaseMatrix[6];
int i;
+ out->startStream(strRef->getRef(), state);
+
// push new resources on stack
pushResources(resDict);
@@ -4897,7 +5023,7 @@ void Gfx::drawForm(Object *strRef, Dict *resDict,
delete blendingColorSpace;
}
- return;
+ out->endStream(strRef->getRef());
}
void Gfx::takeContentStreamStack(Gfx *oldGfx) {
@@ -4936,7 +5062,9 @@ void Gfx::opBeginImage(Object args[], int numArgs) {
// if we have the stream length, skip to end-of-stream and then
// skip 'EI' in the original stream
} else if (haveLength) {
- while ((c1 = str->getChar()) != EOF) ;
+ // NB: getUndecodedStream() returns the EmbedStream created by
+ // buildImageStream()
+ while ((c1 = str->getUndecodedStream()->getChar()) != EOF) ;
delete str;
str = parser->getStream();
c1 = str->getChar();
@@ -5091,15 +5219,28 @@ void Gfx::opBeginMarkedContent(Object args[], int numArgs) {
}
obj.free();
mcKind = gfxMCOptionalContent;
- } else if (args[0].isName("Span") && numArgs == 2 && args[1].isDict()) {
- if (args[1].dictLookup("ActualText", &obj)->isString()) {
- s = new TextString(obj.getString());
- out->beginActualText(state, s->getUnicode(), s->getLength());
- delete s;
- mcKind = gfxMCActualText;
+ } else if (numArgs == 2 && args[1].isDict()) {
+ if (args[0].isName("Span")) {
+ if (args[1].dictLookup("ActualText", &obj)->isString()) {
+ s = new TextString(obj.getString());
+ out->beginActualText(state, s->getUnicode(), s->getLength());
+ delete s;
+ mcKind = gfxMCActualText;
+ }
+ obj.free();
+ }
+ if (args[1].dictLookup("MCID", &obj)->isInt()) {
+ out->beginStructureItem(args[0].getName(), obj.getInt(),
+ args[1].getDict());
+ if (mcKind == gfxMCActualText) {
+ mcKind = gfxMCStructureItemAndActualText;
+ } else {
+ mcKind = gfxMCStructureItem;
+ }
}
obj.free();
}
+
mc = new GfxMarkedContent(mcKind, ocState);
markedContentStack->append(mc);
}
@@ -5123,6 +5264,11 @@ void Gfx::opEndMarkedContent(Object args[], int numArgs) {
}
} else if (mcKind == gfxMCActualText) {
out->endActualText(state);
+ } else if (mcKind == gfxMCStructureItem) {
+ out->endStructureItem();
+ } else if (mcKind == gfxMCStructureItemAndActualText) {
+ out->endStructureItem();
+ out->endActualText(state);
}
} else {
error(errSyntaxWarning, getPos(), "Mismatched EMC operator");
diff --git a/Build/source/libs/xpdf/xpdf-src/xpdf/Gfx.h b/Build/source/libs/xpdf/xpdf-src/xpdf/Gfx.h
index 14d7a608438..0f288cf3b9d 100644
--- a/Build/source/libs/xpdf/xpdf-src/xpdf/Gfx.h
+++ b/Build/source/libs/xpdf/xpdf-src/xpdf/Gfx.h
@@ -11,10 +11,6 @@
#include <aconf.h>
-#ifdef USE_GCC_PRAGMAS
-#pragma interface
-#endif
-
#include "gtypes.h"
#include "gfile.h"
#include "GfxState.h"
@@ -106,6 +102,8 @@ private:
enum GfxMarkedContentKind {
gfxMCOptionalContent,
gfxMCActualText,
+ gfxMCStructureItem,
+ gfxMCStructureItemAndActualText,
gfxMCOther
};
@@ -194,6 +192,7 @@ private:
GfxState *state; // current graphics state
GBool fontChanged; // set if font or text matrix has changed
+ GBool haveSavedClipPath;
GfxClipType clip; // do a clip?
int ignoreUndef; // current BX/EX nesting level
double baseMatrix[6]; // default matrix for most recent
@@ -273,7 +272,7 @@ private:
void opCloseEOFillStroke(Object args[], int numArgs);
void doPatternFill(GBool eoFill);
void doPatternStroke();
- void doPatternText();
+ void doPatternText(GBool stroke);
void doPatternImageMask(Object *ref, Stream *str, int width, int height,
GBool invert, GBool inlineImg, GBool interpolate);
void doTilingPatternFill(GfxTilingPattern *tPat,
diff --git a/Build/source/libs/xpdf/xpdf-src/xpdf/GfxFont.cc b/Build/source/libs/xpdf/xpdf-src/xpdf/GfxFont.cc
index 30e8bd1c79c..c3db4e8651b 100644
--- a/Build/source/libs/xpdf/xpdf-src/xpdf/GfxFont.cc
+++ b/Build/source/libs/xpdf/xpdf-src/xpdf/GfxFont.cc
@@ -8,10 +8,6 @@
#include <aconf.h>
-#ifdef USE_GCC_PRAGMAS
-#pragma implementation
-#endif
-
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
@@ -307,26 +303,10 @@ GfxFontType GfxFont::getFontType(XRef *xref, Dict *fontDict, Ref *embID) {
obj2.initNull();
}
+ // NB: the PDF spec doesn't say anything about precedence, but Adobe
+ // uses FontFile3 over FontFile2 if both are present.
if (fontDict2->lookup("FontDescriptor", &fontDesc)->isDict()) {
- if (fontDesc.dictLookupNF("FontFile", &obj3)->isRef()) {
- *embID = obj3.getRef();
- if (expectedType != fontType1) {
- err = gTrue;
- }
- }
- obj3.free();
- if (embID->num == -1 &&
- fontDesc.dictLookupNF("FontFile2", &obj3)->isRef()) {
- *embID = obj3.getRef();
- if (isType0) {
- expectedType = fontCIDType2;
- } else if (expectedType != fontTrueType) {
- err = gTrue;
- }
- }
- obj3.free();
- if (embID->num == -1 &&
- fontDesc.dictLookupNF("FontFile3", &obj3)->isRef()) {
+ if (fontDesc.dictLookupNF("FontFile3", &obj3)->isRef()) {
*embID = obj3.getRef();
if (obj3.fetch(xref, &obj4)->isStream()) {
obj4.streamGetDict()->lookup("Subtype", &subtype);
@@ -375,6 +355,26 @@ GfxFontType GfxFont::getFontType(XRef *xref, Dict *fontDict, Ref *embID) {
obj4.free();
}
obj3.free();
+ if (embID->num == -1) {
+ if (fontDesc.dictLookupNF("FontFile2", &obj3)->isRef()) {
+ *embID = obj3.getRef();
+ if (isType0) {
+ expectedType = fontCIDType2;
+ } else if (expectedType != fontTrueType) {
+ err = gTrue;
+ }
+ }
+ obj3.free();
+ }
+ if (embID->num == -1) {
+ if (fontDesc.dictLookupNF("FontFile", &obj3)->isRef()) {
+ *embID = obj3.getRef();
+ if (expectedType != fontType1) {
+ err = gTrue;
+ }
+ }
+ obj3.free();
+ }
}
fontDesc.free();
@@ -533,6 +533,33 @@ void GfxFont::readFontDescriptor(XRef *xref, Dict *fontDict) {
}
obj1.free();
+
+ // scan font name for bold/italic tags and update the flags
+ if (name) {
+ i = name->getLength();
+ if (i > 2 && !strncmp(name->getCString() + i - 2, "MT", 2)) {
+ i -= 2;
+ }
+ if (i > 6 && !strncmp(name->getCString() + i - 6, "Italic", 6)) {
+ flags |= fontItalic;
+ i -= 6;
+ } else if (i > 2 && !strncmp(name->getCString() + i - 2, "It", 2)) {
+ flags |= fontItalic;
+ i -= 2;
+ } else if (i > 7 && !strncmp(name->getCString() + i - 7, "Oblique", 7)) {
+ flags |= fontItalic;
+ i -= 7;
+ }
+ char c = name->getChar(i-1);
+ if (!((c >= 'A' && c <= 'Z') ||
+ (c >= 'a' && c <= 'z') ||
+ (c >= '0' && c <= '9'))) {
+ --i;
+ }
+ if (i > 4 && !strncmp(name->getCString() + i - 4, "Bold", 4)) {
+ flags |= fontBold;
+ }
+ }
}
CharCodeToUnicode *GfxFont::readToUnicodeCMap(Dict *fontDict, int nBits,
@@ -1436,7 +1463,7 @@ CharCodeToUnicode *Gfx8BitFont::getToUnicode() {
int *Gfx8BitFont::getCodeToGIDMap(FoFiTrueType *ff) {
int *map;
int cmapPlatform, cmapEncoding;
- int unicodeCmap, macRomanCmap, msSymbolCmap, cmap;
+ int unicodeCmap, macRomanCmap, macUnicodeCmap, msSymbolCmap, cmap;
GBool nonsymbolic, useMacRoman, useUnicode;
char *charName;
Unicode u;
@@ -1450,15 +1477,16 @@ int *Gfx8BitFont::getCodeToGIDMap(FoFiTrueType *ff) {
// This is based on the cmap/encoding selection algorithm in the PDF
// 2.0 spec, but with some differences to match up with Adobe's
// behavior.
- unicodeCmap = macRomanCmap = msSymbolCmap = -1;
+ unicodeCmap = macRomanCmap = macUnicodeCmap = msSymbolCmap = -1;
for (i = 0; i < ff->getNumCmaps(); ++i) {
cmapPlatform = ff->getCmapPlatform(i);
cmapEncoding = ff->getCmapEncoding(i);
- if ((cmapPlatform == 3 && cmapEncoding == 1) ||
- (cmapPlatform == 0 && cmapEncoding <= 4)) {
+ if (cmapPlatform == 3 && cmapEncoding == 1) {
unicodeCmap = i;
} else if (cmapPlatform == 1 && cmapEncoding == 0) {
macRomanCmap = i;
+ } else if (cmapPlatform == 0 && cmapEncoding <= 4) {
+ macUnicodeCmap = i;
} else if (cmapPlatform == 3 && cmapEncoding == 0) {
msSymbolCmap = i;
}
@@ -1466,24 +1494,25 @@ int *Gfx8BitFont::getCodeToGIDMap(FoFiTrueType *ff) {
useMacRoman = gFalse;
useUnicode = gFalse;
nonsymbolic = !(flags & fontSymbolic);
- if (usesMacRomanEnc && macRomanCmap >= 0) {
- cmap = macRomanCmap;
- useMacRoman = gTrue;
- } else if (embFontID.num < 0 && hasEncoding && unicodeCmap >= 0) {
+ if (embFontID.num < 0 && hasEncoding && unicodeCmap >= 0) {
cmap = unicodeCmap;
useUnicode = gTrue;
- } else if (nonsymbolic && unicodeCmap >= 0) {
- cmap = unicodeCmap;
- useUnicode = gTrue;
- } else if (nonsymbolic && macRomanCmap >= 0) {
- cmap = macRomanCmap;
- useMacRoman = gTrue;
- } else if (msSymbolCmap >= 0) {
+ } else if (!nonsymbolic && msSymbolCmap >= 0) {
cmap = msSymbolCmap;
} else if (unicodeCmap >= 0) {
cmap = unicodeCmap;
+ useUnicode = nonsymbolic;
+ } else if (usesMacRomanEnc && macRomanCmap >= 0) {
+ // MacRoman cmap has higher precedence than Mac Unicode only if
+ // the font uses the MacRoman encoding
+ cmap = macRomanCmap;
+ useMacRoman = gTrue;
+ } else if (macUnicodeCmap >= 0) {
+ cmap = macUnicodeCmap;
+ useUnicode = nonsymbolic;
} else if (macRomanCmap >= 0) {
cmap = macRomanCmap;
+ useMacRoman = nonsymbolic;
} else {
cmap = 0;
}
@@ -2229,75 +2258,99 @@ GBool GfxCIDFont::problematicForUnicode() {
// GfxFontDict
//------------------------------------------------------------------------
-GfxFontDict::GfxFontDict(XRef *xref, Ref *fontDictRef, Dict *fontDict) {
- GfxFont *font;
- char *tag;
- Object obj1, obj2;
- Ref r;
- int i;
+class GfxFontDictEntry {
+public:
+
+ GfxFontDictEntry(Ref refA, Object *fontObjA);
+ ~GfxFontDictEntry();
+ void load(GfxFont *fontA);
+ GBool loaded;
+ Ref ref;
+ Object fontObj; // valid if unloaded
+ GfxFont *font; // valid if loaded
+};
+
+GfxFontDictEntry::GfxFontDictEntry(Ref refA, Object *fontObjA) {
+ loaded = gFalse;
+ ref = refA;
+ fontObjA->copy(&fontObj);
+ font = NULL;
+}
+
+GfxFontDictEntry::~GfxFontDictEntry() {
+ // NB: If the font has been loaded, font is non-NULL and is owned by
+ // GfxFontDict.uniqueFonts.
+ if (!loaded) {
+ fontObj.free();
+ }
+}
+
+void GfxFontDictEntry::load(GfxFont *fontA) {
+ loaded = gTrue;
+ font = fontA;
+ fontObj.free();
+}
+
+GfxFontDict::GfxFontDict(XRef *xrefA, Ref *fontDictRef, Dict *fontDict) {
+ xref = xrefA;
fonts = new GHash(gTrue);
uniqueFonts = new GList();
- for (i = 0; i < fontDict->getLength(); ++i) {
- tag = fontDict->getKey(i);
- fontDict->getValNF(i, &obj1);
- obj1.fetch(xref, &obj2);
- if (!obj2.isDict()) {
- error(errSyntaxError, -1, "font resource is not a dictionary");
- } else if (obj1.isRef() && (font = lookupByRef(obj1.getRef()))) {
- fonts->add(new GString(tag), font);
+
+ for (int i = 0; i < fontDict->getLength(); ++i) {
+ char *tag = fontDict->getKey(i);
+ Object fontObj;
+ fontDict->getValNF(i, &fontObj);
+ Ref r;
+ if (fontObj.isRef()) {
+ r = fontObj.getRef();
+ } else if (fontDictRef) {
+ // legal generation numbers are five digits, so we use a
+ // 6-digit number here
+ r.gen = 100000 + fontDictRef->num;
+ r.num = i;
} else {
- if (obj1.isRef()) {
- r = obj1.getRef();
- } else if (fontDictRef) {
- // legal generation numbers are five digits, so we use a
- // 6-digit number here
- r.gen = 100000 + fontDictRef->num;
- r.num = i;
- } else {
- // no indirect reference for this font, or for the containing
- // font dict, so hash the font and use that
- r.gen = 100000;
- r.num = hashFontObject(&obj2);
- }
- if ((font = GfxFont::makeFont(xref, tag, r, obj2.getDict()))) {
- if (!font->isOk()) {
- delete font;
- } else {
- uniqueFonts->append(font);
- fonts->add(new GString(tag), font);
- }
- }
+ // no indirect reference for this font, or for the containing
+ // font dict, so hash the font and use that
+ r.gen = 100000;
+ r.num = hashFontObject(&fontObj);
}
- obj1.free();
- obj2.free();
+ fonts->add(new GString(tag), new GfxFontDictEntry(r, &fontObj));
+ fontObj.free();
}
}
GfxFontDict::~GfxFontDict() {
deleteGList(uniqueFonts, GfxFont);
- delete fonts;
+ deleteGHash(fonts, GfxFontDictEntry);
}
GfxFont *GfxFontDict::lookup(char *tag) {
- return (GfxFont *)fonts->lookup(tag);
+ GfxFontDictEntry *entry = (GfxFontDictEntry *)fonts->lookup(tag);
+ if (!entry) {
+ return NULL;
+ }
+ load(tag, entry);
+ return entry->font;
}
GfxFont *GfxFontDict::lookupByRef(Ref ref) {
- GfxFont *font;
- int i;
-
- for (i = 0; i < uniqueFonts->getLength(); ++i) {
- font = (GfxFont *)uniqueFonts->get(i);
- if (font->getID()->num == ref.num &&
- font->getID()->gen == ref.gen) {
- return font;
+ GHashIter *iter;
+ GString *tag;
+ GfxFontDictEntry *entry;
+ fonts->startIter(&iter);
+ while (fonts->getNext(&iter, &tag, (void **)&entry)) {
+ if (entry->ref.num == ref.num && entry->ref.gen == ref.gen) {
+ fonts->killIter(&iter);
+ load(tag->getCString(), entry);
+ return entry->font;
}
}
return NULL;
}
int GfxFontDict::getNumFonts() {
+ loadAll();
return uniqueFonts->getLength();
}
@@ -2305,6 +2358,52 @@ GfxFont *GfxFontDict::getFont(int i) {
return (GfxFont *)uniqueFonts->get(i);
}
+void GfxFontDict::loadAll() {
+ GHashIter *iter;
+ GString *tag;
+ GfxFontDictEntry *entry;
+ fonts->startIter(&iter);
+ while (fonts->getNext(&iter, &tag, (void **)&entry)) {
+ load(tag->getCString(), entry);
+ }
+}
+
+void GfxFontDict::load(char *tag, GfxFontDictEntry *entry) {
+ if (entry->loaded) {
+ return;
+ }
+
+ // check for a duplicate that has already been loaded
+ // (don't do this for "synthetic" refs)
+ if (entry->fontObj.isRef()) {
+ for (int i = 0; i < uniqueFonts->getLength(); ++i) {
+ GfxFont *font = (GfxFont *)uniqueFonts->get(i);
+ if (font->getID()->num == entry->ref.num &&
+ font->getID()->gen == entry->ref.gen) {
+ entry->load(font);
+ return;
+ }
+ }
+ }
+
+ GfxFont *font = NULL;
+ Object obj;
+ entry->fontObj.fetch(xref, &obj);
+ if (obj.isDict()) {
+ font = GfxFont::makeFont(xref, tag, entry->ref, obj.getDict());
+ if (font->isOk()) {
+ uniqueFonts->append(font);
+ } else {
+ delete font;
+ font = NULL;
+ }
+ } else {
+ error(errSyntaxError, -1, "font resource is not a dictionary");
+ }
+ obj.free();
+ entry->load(font);
+}
+
// FNV-1a hash
class FNVHash {
public:
diff --git a/Build/source/libs/xpdf/xpdf-src/xpdf/GfxFont.h b/Build/source/libs/xpdf/xpdf-src/xpdf/GfxFont.h
index e752ded62f8..ec6d3c3d246 100644
--- a/Build/source/libs/xpdf/xpdf-src/xpdf/GfxFont.h
+++ b/Build/source/libs/xpdf/xpdf-src/xpdf/GfxFont.h
@@ -11,10 +11,6 @@
#include <aconf.h>
-#ifdef USE_GCC_PRAGMAS
-#pragma interface
-#endif
-
#include "gtypes.h"
#include "GString.h"
#include "Object.h"
@@ -29,6 +25,7 @@ class FoFiTrueType;
class FoFiType1C;
struct GfxFontCIDWidths;
struct Base14FontMapEntry;
+class GfxFontDictEntry;
class FNVHash;
//------------------------------------------------------------------------
@@ -388,7 +385,7 @@ class GfxFontDict {
public:
// Build the font dictionary, given the PDF font dictionary.
- GfxFontDict(XRef *xref, Ref *fontDictRef, Dict *fontDict);
+ GfxFontDict(XRef *xrefA, Ref *fontDictRef, Dict *fontDict);
// Destructor.
~GfxFontDict();
@@ -405,13 +402,18 @@ private:
friend class GfxFont;
+ void loadAll();
+ void load(char *tag, GfxFontDictEntry *entry);
static int hashFontObject(Object *obj);
static void hashFontObject1(Object *obj, FNVHash *h);
- GHash *fonts; // hash table of fonts -- this may
- // include duplicates, i.e., when
- // two tags map to the same font
+ XRef *xref;
+ GHash *fonts; // hash table of fonts, mapping from
+ // tag to GfxFontDictEntry; this may
+ // contain duplicates, i.e., two
+ // tags that map to the same font
GList *uniqueFonts; // list of all unique font objects (no dups)
+ // that have been loaded
};
#endif
diff --git a/Build/source/libs/xpdf/xpdf-src/xpdf/GfxState.cc b/Build/source/libs/xpdf/xpdf-src/xpdf/GfxState.cc
index 43503aaedb8..9aed7345ad2 100644
--- a/Build/source/libs/xpdf/xpdf-src/xpdf/GfxState.cc
+++ b/Build/source/libs/xpdf/xpdf-src/xpdf/GfxState.cc
@@ -8,10 +8,6 @@
#include <aconf.h>
-#ifdef USE_GCC_PRAGMAS
-#pragma implementation
-#endif
-
#include <stddef.h>
#include <math.h>
#include <string.h>
@@ -936,15 +932,15 @@ GfxColorSpace *GfxICCBasedColorSpace::parse(Array *arr,
}
nCompsA = obj2.getInt();
obj2.free();
- if (nCompsA > 4) {
- error(errSyntaxError, -1,
- "ICCBased color space with too many ({0:d} > 4) components",
- nCompsA);
- nCompsA = 4;
- }
- if (dict->lookup("Alternate", &obj2)->isNull() ||
- !(altA = GfxColorSpace::parse(&obj2,
- recursion + 1))) {
+ if (!dict->lookup("Alternate", &obj2)->isNull() &&
+ (altA = GfxColorSpace::parse(&obj2,
+ recursion + 1))) {
+ if (altA->getNComps() != nCompsA) {
+ error(errSyntaxError, -1,
+ "Number of components in ICCBased color space doesn't match alternate color space");
+ nCompsA = altA->getNComps();
+ }
+ } else {
switch (nCompsA) {
case 1:
altA = GfxColorSpace::create(csDeviceGray);
@@ -1784,6 +1780,258 @@ GfxPattern *GfxTilingPattern::copy() {
&resDict, matrix, &contentStreamRef);
}
+GBool GfxTilingPattern::usesBlendMode(XRef *xref) {
+ char *scannedObjs = (char *)gmalloc(xref->getNumObjects());
+ memset(scannedObjs, 0, xref->getNumObjects());
+ GBool ret = scanResourcesForBlendMode(&resDict, scannedObjs, xref);
+ gfree(scannedObjs);
+ return ret;
+}
+
+GBool GfxTilingPattern::scanResourcesForBlendMode(Object *resDict2,
+ char *scannedObjs,
+ XRef *xref) {
+ Object ref1, obj1, obj2;
+
+ if (!resDict2->isDict()) {
+ return gFalse;
+ }
+
+ //----- ExtGStates
+ resDict2->dictLookupNF("ExtGState", &ref1);
+ if (!ref1.isRef() || (ref1.getRefNum() < xref->getNumObjects() &&
+ !scannedObjs[ref1.getRefNum()])) {
+ if (ref1.isRef()) {
+ scannedObjs[ref1.getRefNum()] = 1;
+ ref1.fetch(xref, &obj1);
+ } else {
+ ref1.copy(&obj1);
+ }
+ if (obj1.isDict()) {
+ for (int i = 0; i < obj1.dictGetLength(); ++i) {
+ if (scanExtGStateForBlendMode(obj1.dictGetValNF(i, &obj2),
+ scannedObjs, xref)) {
+ obj2.free();
+ obj1.free();
+ ref1.free();
+ return gTrue;
+ }
+ obj2.free();
+ }
+ }
+ obj1.free();
+ }
+ ref1.free();
+
+ //----- patterns
+ resDict2->dictLookupNF("Pattern", &ref1);
+ if (!ref1.isRef() || (ref1.getRefNum() < xref->getNumObjects() &&
+ !scannedObjs[ref1.getRefNum()])) {
+ if (ref1.isRef()) {
+ scannedObjs[ref1.getRefNum()] = 1;
+ ref1.fetch(xref, &obj1);
+ } else {
+ ref1.copy(&obj1);
+ }
+ if (obj1.isDict()) {
+ for (int i = 0; i < obj1.dictGetLength(); ++i) {
+ if (scanPatternForBlendMode(obj1.dictGetValNF(i, &obj2),
+ scannedObjs, xref)) {
+ obj2.free();
+ obj1.free();
+ ref1.free();
+ return gTrue;
+ }
+ obj2.free();
+ }
+ }
+ obj1.free();
+ }
+ ref1.free();
+
+ //----- XObjects
+ resDict2->dictLookupNF("XObject", &ref1);
+ if (!ref1.isRef() || (ref1.getRefNum() < xref->getNumObjects() &&
+ !scannedObjs[ref1.getRefNum()])) {
+ if (ref1.isRef()) {
+ scannedObjs[ref1.getRefNum()] = 1;
+ ref1.fetch(xref, &obj1);
+ } else {
+ ref1.copy(&obj1);
+ }
+ if (obj1.isDict()) {
+ for (int i = 0; i < obj1.dictGetLength(); ++i) {
+ if (scanXObjectForBlendMode(obj1.dictGetValNF(i, &obj2),
+ scannedObjs, xref)) {
+ obj2.free();
+ obj1.free();
+ ref1.free();
+ return gTrue;
+ }
+ obj2.free();
+ }
+ }
+ obj1.free();
+ }
+ ref1.free();
+
+ return gFalse;
+}
+
+GBool GfxTilingPattern::scanExtGStateForBlendMode(Object *gsObj,
+ char *scannedObjs,
+ XRef *xref) {
+ Object gsDict, obj1;
+
+ if (gsObj->isRef()) {
+ if (gsObj->getRefNum() >= xref->getNumObjects() ||
+ scannedObjs[gsObj->getRefNum()]) {
+ return gFalse;
+ }
+ scannedObjs[gsObj->getRefNum()] = 1;
+ gsObj->fetch(xref, &gsDict);
+ } else {
+ gsObj->copy(&gsDict);
+ }
+ if (!gsDict.isDict()) {
+ gsDict.free();
+ return gFalse;
+ }
+
+ gsDict.dictLookup("BM", &obj1);
+ if (obj1.isName() && !obj1.isName("Normal")) {
+ obj1.free();
+ gsDict.free();
+ return gTrue;
+ }
+ obj1.free();
+
+ if (!gsDict.dictLookupNF("SMask", &obj1)->isNull()) {
+ if (scanSoftMaskForBlendMode(&obj1, scannedObjs, xref)) {
+ obj1.free();
+ gsDict.free();
+ return gTrue;
+ }
+ }
+ obj1.free();
+
+ gsDict.free();
+
+ return gFalse;
+}
+
+GBool GfxTilingPattern::scanSoftMaskForBlendMode(Object *softMaskObj,
+ char *scannedObjs,
+ XRef *xref) {
+ Object softMaskDict, obj1;
+
+ if (softMaskObj->isRef()) {
+ if (softMaskObj->getRefNum() >= xref->getNumObjects() ||
+ scannedObjs[softMaskObj->getRefNum()]) {
+ return gFalse;
+ }
+ scannedObjs[softMaskObj->getRefNum()] = 1;
+ softMaskObj->fetch(xref, &softMaskDict);
+ } else {
+ softMaskObj->copy(&softMaskDict);
+ }
+ if (!softMaskDict.isDict()) {
+ softMaskDict.free();
+ return gFalse;
+ }
+
+ if (!softMaskDict.dictLookupNF("G", &obj1)->isNull()) {
+ if (scanXObjectForBlendMode(&obj1, scannedObjs, xref)) {
+ obj1.free();
+ softMaskDict.free();
+ return gTrue;
+ }
+ }
+ obj1.free();
+
+ softMaskDict.free();
+
+ return gFalse;
+}
+
+GBool GfxTilingPattern::scanPatternForBlendMode(Object *patternObj,
+ char *scannedObjs,
+ XRef *xref) {
+ Object patternObj2, obj1;
+ Dict *patternDict;
+
+ if (patternObj->isRef()) {
+ if (patternObj->getRefNum() >= xref->getNumObjects() ||
+ scannedObjs[patternObj->getRefNum()]) {
+ return gFalse;
+ }
+ scannedObjs[patternObj->getRefNum()] = 1;
+ patternObj->fetch(xref, &patternObj2);
+ } else {
+ patternObj->copy(&patternObj2);
+ }
+ if (patternObj2.isDict()) {
+ patternDict = patternObj2.getDict();
+ } else if (patternObj2.isStream()) {
+ patternDict = patternObj2.streamGetDict();
+ } else {
+ patternObj2.free();
+ return gFalse;
+ }
+
+ if (!patternDict->lookupNF("Resources", &obj1)->isNull()) {
+ if (scanResourcesForBlendMode(&obj1, scannedObjs, xref)) {
+ obj1.free();
+ patternObj2.free();
+ return gTrue;
+ }
+ }
+ obj1.free();
+
+ patternObj2.free();
+
+ return gFalse;
+}
+
+GBool GfxTilingPattern::scanXObjectForBlendMode(Object *xObj,
+ char *scannedObjs,
+ XRef *xref) {
+ Object xObj2, obj1;
+ Dict *dict;
+
+ if (xObj->isRef()) {
+ if (xObj->getRefNum() >= xref->getNumObjects() ||
+ scannedObjs[xObj->getRefNum()]) {
+ return gFalse;
+ }
+ scannedObjs[xObj->getRefNum()] = 1;
+ xObj->fetch(xref, &xObj2);
+ } else {
+ xObj->copy(&xObj2);
+ }
+ if (xObj2.isDict()) {
+ dict = xObj2.getDict();
+ } else if (xObj2.isStream()) {
+ dict = xObj2.streamGetDict();
+ } else {
+ xObj2.free();
+ return gFalse;
+ }
+
+ if (!dict->lookupNF("Resources", &obj1)->isNull()) {
+ if (scanResourcesForBlendMode(&obj1, scannedObjs, xref)) {
+ obj1.free();
+ xObj2.free();
+ return gTrue;
+ }
+ }
+ obj1.free();
+
+ xObj2.free();
+
+ return gFalse;
+}
+
//------------------------------------------------------------------------
// GfxShadingPattern
//------------------------------------------------------------------------
@@ -2963,8 +3211,8 @@ void GfxGouraudTriangleShading::getTriangle(
}
}
-void GfxGouraudTriangleShading::getBBox(double *xMin, double *yMin,
- double *xMax, double *yMax) {
+void GfxGouraudTriangleShading::getBBox(double *xMinA, double *yMinA,
+ double *xMaxA, double *yMaxA) {
double xxMin = 0;
double yyMin = 0;
double xxMax = 0;
@@ -2985,10 +3233,10 @@ void GfxGouraudTriangleShading::getBBox(double *xMin, double *yMin,
yyMax = vertices[i].y;
}
}
- *xMin = xxMin;
- *yMin = yyMin;
- *xMax = xxMax;
- *yMax = yyMax;
+ *xMinA = xxMin;
+ *yMinA = yyMin;
+ *xMaxA = xxMax;
+ *yMaxA = yyMax;
}
void GfxGouraudTriangleShading::getColor(double *in, GfxColor *out) {
@@ -3621,8 +3869,8 @@ GfxShading *GfxPatchMeshShading::copy() {
return new GfxPatchMeshShading(this);
}
-void GfxPatchMeshShading::getBBox(double *xMin, double *yMin,
- double *xMax, double *yMax) {
+void GfxPatchMeshShading::getBBox(double *xMinA, double *yMinA,
+ double *xMaxA, double *yMaxA) {
double xxMin = 0;
double yyMin = 0;
double xxMax = 0;
@@ -3647,10 +3895,10 @@ void GfxPatchMeshShading::getBBox(double *xMin, double *yMin,
}
}
}
- *xMin = xxMin;
- *yMin = yyMin;
- *xMax = xxMax;
- *yMax = yyMax;
+ *xMinA = xxMin;
+ *yMinA = yyMin;
+ *xMaxA = xxMax;
+ *yMaxA = yyMax;
}
void GfxPatchMeshShading::getColor(double *in, GfxColor *out) {
@@ -4651,35 +4899,36 @@ void GfxState::clipToStrokePath() {
// There are two cases for each point on the path:
// (1) miter join, under miter limit => compute the miter point
// (2) all other joins and caps => use the path point +/- 0.5 * line width
- double xMin = 0, yMin = 0, xMax = 0, yMax = 0;
+ double uxMin = 0, uyMin = 0, uxMax = 0, uyMax = 0;
double w = 0.5 * lineWidth;
for (int i = 0; i < path->getNumSubpaths(); ++i) {
GfxSubpath *subpath = path->getSubpath(i);
- for (int j = 0; j < subpath->getNumPoints(); ++j) {
+ int nPoints;
+ if (subpath->isClosed()) {
+ nPoints = subpath->getNumPoints() - 1;
+ } else {
+ nPoints = subpath->getNumPoints();
+ }
+ for (int j = 0; j < nPoints; ++j) {
double x1 = subpath->getX(j);
double y1 = subpath->getY(j);
if (i == 0 && j == 0) {
- xMin = xMax = x1;
- yMin = yMax = y1;
+ uxMin = uxMax = x1;
+ uyMin = uyMax = y1;
}
GBool useMiter = gFalse;
if (lineJoin == 0 && // miter join
- ((j > 0 && j < subpath->getNumPoints() - 1) || subpath->isClosed())) {
+ (subpath->isClosed() || (j > 0 && j < subpath->getNumPoints() - 1))) {
double x0, y0, x2, y2;
- if (j > 0) {
+ if (j == 0) {
+ x0 = subpath->getX(nPoints - 1);
+ y0 = subpath->getY(nPoints - 1);
+ } else {
x0 = subpath->getX(j - 1);
y0 = subpath->getY(j - 1);
- } else {
- x0 = subpath->getLastX();
- y0 = subpath->getLastY();
- }
- if (j < subpath->getNumPoints() - 1) {
- x2 = subpath->getX(j + 1);
- y2 = subpath->getY(j + 1);
- } else {
- x2 = subpath->getX(0);
- y2 = subpath->getY(0);
}
+ x2 = subpath->getX(j + 1);
+ y2 = subpath->getY(j + 1);
if ((fabs(x1 - x0) > 0.0001 || fabs(y1 - y0) > 0.0001) &&
(fabs(x2 - x1) > 0.0001 || fabs(y2 - y1) > 0.0001)) {
double d01 = 1 / sqrt((x1 - x0) * (x1 - x0) + (y1 - y0) * (y1 - y0));
@@ -4704,15 +4953,15 @@ void GfxState::clipToStrokePath() {
}
double mx = ax + m * w * ux;
double my = ay + m * w * uy;
- if (mx < xMin) {
- xMin = mx;
- } else if (mx > xMax) {
- xMax = mx;
+ if (mx < uxMin) {
+ uxMin = mx;
+ } else if (mx > uxMax) {
+ uxMax = mx;
}
- if (my < yMin) {
- yMin = my;
- } else if (my > yMax) {
- yMax = my;
+ if (my < uyMin) {
+ uyMin = my;
+ } else if (my > uyMax) {
+ uyMax = my;
}
useMiter = gTrue;
}
@@ -4720,66 +4969,71 @@ void GfxState::clipToStrokePath() {
}
}
if (!useMiter) {
- if (x1 - w < xMin) {
- xMin = x1 - w;
+ if (x1 - w < uxMin) {
+ uxMin = x1 - w;
}
- if (x1 + w > xMax) {
- xMax = x1 + w;
+ if (x1 + w > uxMax) {
+ uxMax = x1 + w;
}
- if (y1 - w < yMin) {
- yMin = y1 - w;
+ if (y1 - w < uyMin) {
+ uyMin = y1 - w;
}
- if (y1 + w > yMax) {
- yMax = y1 + w;
+ if (y1 + w > uyMax) {
+ uyMax = y1 + w;
}
}
}
}
- double xx, yy;
- transform(xMin, yMin, &xx, &yy);
- if (xx < clipXMin) {
- clipXMin = xx;
- } else if (xx > clipXMax) {
- clipXMax = xx;
- }
- if (yy < clipYMin) {
- clipYMin = yy;
- } else if (yy > clipYMax) {
- clipYMax = yy;
- }
- transform(xMin, yMax, &xx, &yy);
- if (xx < clipXMin) {
- clipXMin = xx;
- } else if (xx > clipXMax) {
- clipXMax = xx;
- }
- if (yy < clipYMin) {
- clipYMin = yy;
- } else if (yy > clipYMax) {
- clipYMax = yy;
- }
- transform(xMax, yMin, &xx, &yy);
- if (xx < clipXMin) {
- clipXMin = xx;
- } else if (xx > clipXMax) {
- clipXMax = xx;
- }
- if (yy < clipYMin) {
- clipYMin = yy;
- } else if (yy > clipYMax) {
- clipYMax = yy;
- }
- transform(xMax, yMax, &xx, &yy);
- if (xx < clipXMin) {
- clipXMin = xx;
- } else if (xx > clipXMax) {
- clipXMax = xx;
- }
- if (yy < clipYMin) {
- clipYMin = yy;
- } else if (yy > clipYMax) {
- clipYMax = yy;
+ double dxMin, dyMin, dxMax, dyMax, xx, yy;
+ transform(uxMin, uyMin, &xx, &yy);
+ dxMin = dxMax = xx;
+ dyMin = dyMax = yy;
+ transform(uxMin, uyMax, &xx, &yy);
+ if (xx < dxMin) {
+ dxMin = xx;
+ } else if (xx > dxMax) {
+ dxMax = xx;
+ }
+ if (yy < dyMin) {
+ dyMin = yy;
+ } else if (yy > dyMax) {
+ dyMax = yy;
+ }
+ transform(uxMax, uyMin, &xx, &yy);
+ if (xx < dxMin) {
+ dxMin = xx;
+ } else if (xx > dxMax) {
+ dxMax = xx;
+ }
+ if (yy < dyMin) {
+ dyMin = yy;
+ } else if (yy > dyMax) {
+ dyMax = yy;
+ }
+ transform(uxMax, uyMax, &xx, &yy);
+ if (xx < dxMin) {
+ dxMin = xx;
+ } else if (xx > dxMax) {
+ dxMax = xx;
+ }
+ if (yy < dyMin) {
+ dyMin = yy;
+ } else if (yy > dyMax) {
+ dyMax = yy;
+ }
+
+ if (dxMin > clipXMin) {
+ clipXMin = dxMin;
+ }
+ if (dyMin > clipYMin) {
+ clipYMin = dyMin;
+ }
+ if (dxMax < clipXMax) {
+ clipXMax = dxMax;
+ }
+ if (dyMax < clipYMax) {
+ clipYMax = dyMax;
}
}
diff --git a/Build/source/libs/xpdf/xpdf-src/xpdf/GfxState.h b/Build/source/libs/xpdf/xpdf-src/xpdf/GfxState.h
index 60d48527c29..57b57e06a66 100644
--- a/Build/source/libs/xpdf/xpdf-src/xpdf/GfxState.h
+++ b/Build/source/libs/xpdf/xpdf-src/xpdf/GfxState.h
@@ -11,10 +11,6 @@
#include <aconf.h>
-#ifdef USE_GCC_PRAGMAS
-#pragma interface
-#endif
-
#include "gtypes.h"
#include "Object.h"
#include "Function.h"
@@ -663,6 +659,7 @@ public:
{ return resDict.isDict() ? resDict.getDict() : (Dict *)NULL; }
double *getMatrix() { return matrix; }
Object *getContentStreamRef() { return &contentStreamRef; }
+ GBool usesBlendMode(XRef *xref);
private:
@@ -670,6 +667,16 @@ private:
double *bboxA, double xStepA, double yStepA,
Object *resDictA, double *matrixA,
Object *contentStreamA);
+ GBool scanResourcesForBlendMode(Object *resDict2,
+ char *scannedObjs, XRef *xref);
+ GBool scanExtGStateForBlendMode(Object *gsObj,
+ char *scannedObjs, XRef *xref);
+ GBool scanSoftMaskForBlendMode(Object *softMaskObj,
+ char *scannedObjs, XRef *xref);
+ GBool scanPatternForBlendMode(Object *patternObj,
+ char *scannedObjs, XRef *xref);
+ GBool scanXObjectForBlendMode(Object *xObj,
+ char *scannedObjs, XRef *xref);
int paintType;
int tilingType;
@@ -883,7 +890,7 @@ public:
void getTriangle(int i, double *x0, double *y0, double *color0,
double *x1, double *y1, double *color1,
double *x2, double *y2, double *color2);
- void getBBox(double *xMin, double *yMin, double *xMax, double *yMax);
+ void getBBox(double *xMinA, double *yMinA, double *xMaxA, double *yMaxA);
void getColor(double *in, GfxColor *out);
private:
@@ -923,7 +930,7 @@ public:
int getNComps() { return nComps; }
int getNPatches() { return nPatches; }
GfxPatch *getPatch(int i) { return &patches[i]; }
- void getBBox(double *xMin, double *yMin, double *xMax, double *yMax);
+ void getBBox(double *xMinA, double *yMinA, double *xMaxA, double *yMaxA);
void getColor(double *in, GfxColor *out);
private:
diff --git a/Build/source/libs/xpdf/xpdf-src/xpdf/GlobalParams.cc b/Build/source/libs/xpdf/xpdf-src/xpdf/GlobalParams.cc
index e7cc594b12d..fcacd7f1e71 100644
--- a/Build/source/libs/xpdf/xpdf-src/xpdf/GlobalParams.cc
+++ b/Build/source/libs/xpdf/xpdf-src/xpdf/GlobalParams.cc
@@ -8,10 +8,6 @@
#include <aconf.h>
-#ifdef USE_GCC_PRAGMAS
-#pragma implementation
-#endif
-
#include <string.h>
#include <stdio.h>
#include <stdarg.h>
@@ -44,10 +40,12 @@
#include "GlobalParams.h"
#ifdef _WIN32
+#ifndef __GNUC__
# undef strcasecmp
# undef strncasecmp
# define strcasecmp _stricmp
# define strncasecmp _strnicmp
+#endif
#else
# include <strings.h>
#endif
@@ -105,14 +103,14 @@ static struct {
{NULL}
};
-#ifdef _WIN32
static const char *displayFontDirs[] = {
+#ifdef BASE14_FONT_DIR
+ BASE14_FONT_DIR,
+#endif
+#ifdef _WIN32
"c:/windows/fonts",
"c:/winnt/fonts",
- NULL
-};
-#else
-static const char *displayFontDirs[] = {
+#else // _WIN32
"/usr/share/ghostscript/fonts",
"/usr/local/share/ghostscript/fonts",
"/usr/share/fonts/default/Type1",
@@ -121,9 +119,9 @@ static const char *displayFontDirs[] = {
#if defined(__sun) && defined(__SVR4)
"/usr/sfw/share/ghostscript/fonts",
#endif
+#endif // _WIN32
NULL
};
-#endif
#ifdef __APPLE__
static const char *macSystemFontPath = "/System/Library/Fonts";
@@ -183,7 +181,7 @@ public:
~SysFontInfo();
GString *mungeName1(GString *in);
GString *mungeName2(GString *in);
- void mungeName3(GString *name, GBool *bold, GBool *italic);
+ void mungeName3(GString *nameA, GBool *bold, GBool *italic);
int match(GString *nameA);
};
@@ -260,24 +258,24 @@ GString *SysFontInfo::mungeName2(GString *in) {
// Remove trailing bold/italic/regular/roman tags from the name.
// (Note: the names have already been uppercased by mungeName1/2.)
-void SysFontInfo::mungeName3(GString *name, GBool *bold, GBool *italic) {
+void SysFontInfo::mungeName3(GString *nameA, GBool *bold, GBool *italic) {
*bold = gFalse;
*italic = gFalse;
- int n = name->getLength();
+ int n = nameA->getLength();
while (1) {
- if (n >= 4 && !strcmp(name->getCString() + n - 4, "BOLD")) {
- name->del(n - 4, 4);
+ if (n >= 4 && !strcmp(nameA->getCString() + n - 4, "BOLD")) {
+ nameA->del(n - 4, 4);
n -= 4;
*bold = gTrue;
- } else if (n >= 6 && !strcmp(name->getCString() + n - 6, "ITALIC")) {
- name->del(n - 6, 6);
+ } else if (n >= 6 && !strcmp(nameA->getCString() + n - 6, "ITALIC")) {
+ nameA->del(n - 6, 6);
n -= 6;
*italic = gTrue;
- } else if (n >= 7 && !strcmp(name->getCString() + n - 7, "REGULAR")) {
- name->del(n - 7, 7);
+ } else if (n >= 7 && !strcmp(nameA->getCString() + n - 7, "REGULAR")) {
+ nameA->del(n - 7, 7);
n -= 7;
- } else if (n >= 5 && !strcmp(name->getCString() + n - 5, "ROMAN")) {
- name->del(n - 5, 5);
+ } else if (n >= 5 && !strcmp(nameA->getCString() + n - 5, "ROMAN")) {
+ nameA->del(n - 5, 5);
n -= 5;
} else {
break;
@@ -659,7 +657,7 @@ GlobalParams::GlobalParams(const char *cfgFileName) {
base14SysFonts = new GHash(gTrue);
sysFonts = new SysFontList();
#if HAVE_PAPER_H
- char *paperName;
+ const char *paperName;
const struct paper *paperType;
paperinit();
if ((paperName = systempapername())) {
@@ -715,6 +713,21 @@ GlobalParams::GlobalParams(const char *cfgFileName) {
textKeepTinyChars = gTrue;
initialZoom = new GString("125");
defaultFitZoom = 0;
+ zoomScaleFactor = 1;
+ zoomValues = new GList();
+ zoomValues->append(new GString("25"));
+ zoomValues->append(new GString("50"));
+ zoomValues->append(new GString("75"));
+ zoomValues->append(new GString("100"));
+ zoomValues->append(new GString("110"));
+ zoomValues->append(new GString("125"));
+ zoomValues->append(new GString("150"));
+ zoomValues->append(new GString("175"));
+ zoomValues->append(new GString("200"));
+ zoomValues->append(new GString("300"));
+ zoomValues->append(new GString("400"));
+ zoomValues->append(new GString("600"));
+ zoomValues->append(new GString("800"));
initialDisplayMode = new GString("continuous");
initialToolbarState = gTrue;
initialSidebarState = gTrue;
@@ -748,6 +761,7 @@ GlobalParams::GlobalParams(const char *cfgFileName) {
fullScreenMatteColor = new GString("#000000");
selectionColor = new GString("#8080ff");
reverseVideoInvertImages = gFalse;
+ allowLinksToChangeZoom = gTrue;
launchCommand = NULL;
movieCommand = NULL;
defaultPrinter = NULL;
@@ -755,10 +769,15 @@ GlobalParams::GlobalParams(const char *cfgFileName) {
mapUnknownCharNames = gFalse;
mapExtTrueTypeFontsViaUnicode = gTrue;
useTrueTypeUnicodeMapping = gFalse;
+ ignoreWrongSizeToUnicode = gFalse;
droppedFonts = new GHash(gTrue);
+ separateRotatedText = gFalse;
createDefaultKeyBindings();
popupMenuCmds = new GList();
- tabStateFile = appendToPath(getHomeDir(), ".xpdf.tab-state");
+#ifndef PDF_PARSER_ONLY
+ initStateFilePaths();
+#endif
+ saveSessionOnQuit = gTrue;
savePageNumbers = gTrue;
printCommands = gFalse;
printStatusInfo = gFalse;
@@ -1017,6 +1036,27 @@ void GlobalParams::createDefaultKeyBindings() {
xpdfKeyContextAny, "zoomFitWidth"));
}
+#ifndef PDF_PARSER_ONLY
+void GlobalParams::initStateFilePaths() {
+#ifdef _WIN32
+ char path[MAX_PATH];
+ if (SHGetFolderPathA(NULL, CSIDL_APPDATA, NULL,
+ SHGFP_TYPE_CURRENT, path) != S_OK) {
+ return;
+ }
+ GString *dir = appendToPath(new GString(path), "xpdf");
+ CreateDirectoryA(dir->getCString(), NULL);
+ pagesFile = appendToPath(dir->copy(), "xpdf.pages");
+ tabStateFile = appendToPath(dir->copy(), "xpdf.tab-state");
+ sessionFile = appendToPath(dir, "xpdf.session");
+#else
+ pagesFile = appendToPath(getHomeDir(), ".xpdf.pages");
+ tabStateFile = appendToPath(getHomeDir(), ".xpdf.tab-state");
+ sessionFile = appendToPath(getHomeDir(), ".xpdf.session");
+#endif
+}
+#endif
+
void GlobalParams::parseFile(GString *fileName, FILE *f) {
int line;
char buf[512];
@@ -1157,6 +1197,10 @@ void GlobalParams::parseLine(char *buf, GString *fileName, int line) {
parseString("initialZoom", &initialZoom, tokens, fileName, line);
} else if (!cmd->cmp("defaultFitZoom")) {
parseInteger("defaultFitZoom", &defaultFitZoom, tokens, fileName, line);
+ } else if (!cmd->cmp("zoomScaleFactor")) {
+ parseZoomScaleFactor(tokens, fileName, line);
+ } else if (!cmd->cmp("zoomValues")) {
+ parseZoomValues(tokens, fileName, line);
} else if (!cmd->cmp("initialDisplayMode")) {
parseString("initialDisplayMode", &initialDisplayMode,
tokens, fileName, line);
@@ -1244,6 +1288,9 @@ void GlobalParams::parseLine(char *buf, GString *fileName, int line) {
} else if (!cmd->cmp("reverseVideoInvertImages")) {
parseYesNo("reverseVideoInvertImages", &reverseVideoInvertImages,
tokens, fileName, line);
+ } else if (!cmd->cmp("allowLinksToChangeZoom")) {
+ parseYesNo("allowLinksToChangeZoom", &allowLinksToChangeZoom,
+ tokens, fileName, line);
} else if (!cmd->cmp("launchCommand")) {
parseString("launchCommand", &launchCommand, tokens, fileName, line);
} else if (!cmd->cmp("movieCommand")) {
@@ -1261,11 +1308,16 @@ void GlobalParams::parseLine(char *buf, GString *fileName, int line) {
&mapExtTrueTypeFontsViaUnicode,
tokens, fileName, line);
} else if (!cmd->cmp("useTrueTypeUnicodeMapping")) {
- parseYesNo("useTrueTypeUnicodeMapping",
- &useTrueTypeUnicodeMapping,
+ parseYesNo("useTrueTypeUnicodeMapping", &useTrueTypeUnicodeMapping,
+ tokens, fileName, line);
+ } else if (!cmd->cmp("ignoreWrongSizeToUnicode")) {
+ parseYesNo("ignoreWrongSizeToUnicode", &ignoreWrongSizeToUnicode,
tokens, fileName, line);
} else if (!cmd->cmp("dropFont")) {
parseDropFont(tokens, fileName, line);
+ } else if (!cmd->cmp("separateRotatedText")) {
+ parseYesNo("separateRotatedText", &separateRotatedText,
+ tokens, fileName, line);
} else if (!cmd->cmp("bind")) {
parseBind(tokens, fileName, line);
} else if (!cmd->cmp("unbind")) {
@@ -1274,6 +1326,11 @@ void GlobalParams::parseLine(char *buf, GString *fileName, int line) {
parsePopupMenuCmd(tokens, fileName, line);
} else if (!cmd->cmp("tabStateFile")) {
parseString("tabStateFile", &tabStateFile, tokens, fileName, line);
+ } else if (!cmd->cmp("sessionFile")) {
+ parseString("sessionFile", &sessionFile, tokens, fileName, line);
+ } else if (!cmd->cmp("saveSessionOnQuit")) {
+ parseYesNo("saveSessionOnQuit", &saveSessionOnQuit,
+ tokens, fileName, line);
} else if (!cmd->cmp("savePageNumbers")) {
parseYesNo("savePageNumbers", &savePageNumbers, tokens, fileName, line);
} else if (!cmd->cmp("printCommands")) {
@@ -1973,6 +2030,59 @@ void GlobalParams::parsePopupMenuCmd(GList *tokens,
cmds));
}
+void GlobalParams::parseZoomScaleFactor(GList *tokens,
+ GString *fileName, int line) {
+ if (tokens->getLength() != 2) {
+ error(errConfig, -1, "Bad 'zoomScaleFactor' config file command ({0:t}:{1:d})",
+ fileName, line);
+ return;
+ }
+ GString *tok = (GString *)tokens->get(1);
+ if (tok->getLength() == 0) {
+ error(errConfig, -1, "Bad 'zoomScaleFactor' config file command ({0:t}:{1:d})",
+ fileName, line);
+ return;
+ }
+ if (tok->cmp("actual") == 0) {
+ zoomScaleFactor = -1;
+ } else {
+ for (int i = 0; i < tok->getLength(); ++i) {
+ if (!((tok->getChar(i) >= '0' && tok->getChar(i) <= '9') ||
+ tok->getChar(i) == '.')) {
+ error(errConfig, -1, "Bad 'zoomScaleFactor' config file command ({0:t}:{1:d})",
+ fileName, line);
+ return;
+ }
+ }
+ zoomScaleFactor = atof(tok->getCString());
+ }
+}
+
+void GlobalParams::parseZoomValues(GList *tokens,
+ GString *fileName, int line) {
+ if (tokens->getLength() < 2) {
+ error(errConfig, -1, "Bad 'zoomValues' config file command ({0:t}:{1:d})",
+ fileName, line);
+ return;
+ }
+ for (int i = 1; i < tokens->getLength(); ++i) {
+ GString *tok = (GString *)tokens->get(i);
+ for (int j = 0; j < tok->getLength(); ++j) {
+ if (tok->getChar(j) < '0' || tok->getChar(j) > '9') {
+ error(errConfig, -1, "Bad 'zoomValues' config file command ({0:t}:{1:d})",
+ fileName, line);
+ return;
+ }
+ }
+ }
+ deleteGList(zoomValues, GString);
+ zoomValues = new GList();
+ for (int i = 1; i < tokens->getLength(); ++i) {
+ GString *tok = (GString *)tokens->get(i);
+ zoomValues->append(tok->copy());
+ }
+}
+
void GlobalParams::parseYesNo(const char *cmdName, GBool *flag,
GList *tokens, GString *fileName, int line) {
GString *tok;
@@ -2104,6 +2214,7 @@ GlobalParams::~GlobalParams() {
deleteGList(psResidentFontsCC, PSFontParam16);
delete textEncoding;
delete initialZoom;
+ deleteGList(zoomValues, GString);
delete initialDisplayMode;
delete initialSelectMode;
if (paperColor) {
@@ -2130,7 +2241,9 @@ GlobalParams::~GlobalParams() {
delete droppedFonts;
deleteGList(keyBindings, KeyBinding);
deleteGList(popupMenuCmds, PopupMenuCmd);
+ delete pagesFile;
delete tabStateFile;
+ delete sessionFile;
delete debugLogFile;
cMapDirs->startIter(&iter);
@@ -2959,6 +3072,19 @@ int GlobalParams::getDefaultFitZoom() {
return z;
}
+double GlobalParams::getZoomScaleFactor() {
+ double z;
+
+ lockGlobalParams;
+ z = zoomScaleFactor;
+ unlockGlobalParams;
+ return z;
+}
+
+GList *GlobalParams::getZoomValues() {
+ return zoomValues;
+}
+
GString *GlobalParams::getInitialDisplayMode() {
GString *s;
@@ -3250,6 +3376,15 @@ GBool GlobalParams::getReverseVideoInvertImages() {
return invert;
}
+GBool GlobalParams::getAllowLinksToChangeZoom() {
+ GBool allow;
+
+ lockGlobalParams;
+ allow = allowLinksToChangeZoom;
+ unlockGlobalParams;
+ return allow;
+}
+
GString *GlobalParams::getDefaultPrinter() {
GString *s;
@@ -3295,6 +3430,15 @@ GBool GlobalParams::getUseTrueTypeUnicodeMapping() {
return use;
}
+GBool GlobalParams::getIgnoreWrongSizeToUnicode() {
+ GBool ignore;
+
+ lockGlobalParams;
+ ignore = ignoreWrongSizeToUnicode;
+ unlockGlobalParams;
+ return ignore;
+}
+
GBool GlobalParams::isDroppedFont(const char *fontName) {
GBool isDropped;
@@ -3304,6 +3448,15 @@ GBool GlobalParams::isDroppedFont(const char *fontName) {
return isDropped;
}
+GBool GlobalParams::getSeparateRotatedText() {
+ GBool sep;
+
+ lockGlobalParams;
+ sep = separateRotatedText;
+ unlockGlobalParams;
+ return sep;
+}
+
GList *GlobalParams::getKeyBinding(int code, int mods, int context) {
KeyBinding *binding;
GList *cmds;
@@ -3356,6 +3509,15 @@ PopupMenuCmd *GlobalParams::getPopupMenuCmd(int idx) {
return cmd;
}
+GString *GlobalParams::getPagesFile() {
+ GString *s;
+
+ lockGlobalParams;
+ s = pagesFile->copy();
+ unlockGlobalParams;
+ return s;
+}
+
GString *GlobalParams::getTabStateFile() {
GString *s;
@@ -3365,6 +3527,15 @@ GString *GlobalParams::getTabStateFile() {
return s;
}
+GString *GlobalParams::getSessionFile() {
+ GString *s;
+
+ lockGlobalParams;
+ s = sessionFile->copy();
+ unlockGlobalParams;
+ return s;
+}
+
GBool GlobalParams::getSavePageNumbers() {
GBool s;
@@ -3374,6 +3545,15 @@ GBool GlobalParams::getSavePageNumbers() {
return s;
}
+GBool GlobalParams::getSaveSessionOnQuit() {
+ GBool s;
+
+ lockGlobalParams;
+ s = saveSessionOnQuit;
+ unlockGlobalParams;
+ return s;
+}
+
GBool GlobalParams::getPrintCommands() {
GBool p;
@@ -3712,6 +3892,12 @@ void GlobalParams::setInitialZoom(char *s) {
unlockGlobalParams;
}
+void GlobalParams::setDefaultFitZoom(int z) {
+ lockGlobalParams;
+ defaultFitZoom = z;
+ unlockGlobalParams;
+}
+
GBool GlobalParams::setEnableFreeType(char *s) {
GBool ok;
@@ -3815,6 +4001,13 @@ void GlobalParams::setTabStateFile(char *tabStateFileA) {
unlockGlobalParams;
}
+void GlobalParams::setSessionFile(char *sessionFileA) {
+ lockGlobalParams;
+ delete sessionFile;
+ sessionFile = new GString(sessionFileA);
+ unlockGlobalParams;
+}
+
void GlobalParams::setPrintCommands(GBool printCommandsA) {
lockGlobalParams;
printCommands = printCommandsA;
diff --git a/Build/source/libs/xpdf/xpdf-src/xpdf/GlobalParams.h b/Build/source/libs/xpdf/xpdf-src/xpdf/GlobalParams.h
index d72473f2a46..c9b4c7bdc09 100644
--- a/Build/source/libs/xpdf/xpdf-src/xpdf/GlobalParams.h
+++ b/Build/source/libs/xpdf/xpdf-src/xpdf/GlobalParams.h
@@ -14,10 +14,6 @@
#include <aconf.h>
-#ifdef USE_GCC_PRAGMAS
-#pragma interface
-#endif
-
#include <stdio.h>
#ifdef _WIN32
# include <windows.h>
@@ -303,6 +299,8 @@ public:
GBool getTextKeepTinyChars();
GString *getInitialZoom();
int getDefaultFitZoom();
+ double getZoomScaleFactor();
+ GList *getZoomValues();
GString *getInitialDisplayMode();
GBool getInitialToolbarState();
GBool getInitialSidebarState();
@@ -336,6 +334,7 @@ public:
GString *getFullScreenMatteColor();
GString *getSelectionColor();
GBool getReverseVideoInvertImages();
+ GBool getAllowLinksToChangeZoom();
GString *getLaunchCommand() { return launchCommand; }
GString *getMovieCommand() { return movieCommand; }
GString *getDefaultPrinter();
@@ -343,12 +342,17 @@ public:
GBool getMapUnknownCharNames();
GBool getMapExtTrueTypeFontsViaUnicode();
GBool getUseTrueTypeUnicodeMapping();
+ GBool getIgnoreWrongSizeToUnicode();
GBool isDroppedFont(const char *fontName);
+ GBool getSeparateRotatedText();
GList *getKeyBinding(int code, int mods, int context);
GList *getAllKeyBindings();
int getNumPopupMenuCmds();
PopupMenuCmd *getPopupMenuCmd(int idx);
+ GString *getPagesFile();
GString *getTabStateFile();
+ GString *getSessionFile();
+ GBool getSaveSessionOnQuit();
GBool getSavePageNumbers();
GBool getPrintCommands();
GBool getPrintStatusInfo();
@@ -390,6 +394,7 @@ public:
void setTextPageBreaks(GBool pageBreaks);
void setTextKeepTinyChars(GBool keep);
void setInitialZoom(char *s);
+ void setDefaultFitZoom(int z);
GBool setEnableFreeType(char *s);
GBool setAntialias(char *s);
GBool setVectorAntialias(char *s);
@@ -405,6 +410,7 @@ public:
void setMapUnknownCharNames(GBool map);
void setMapExtTrueTypeFontsViaUnicode(GBool map);
void setTabStateFile(char *tabStateFileA);
+ void setSessionFile(char *sessionFileA);
void setPrintCommands(GBool printCommandsA);
void setPrintStatusInfo(GBool printStatusInfoA);
void setErrQuiet(GBool errQuietA);
@@ -420,6 +426,9 @@ private:
void setDataDirVar();
void createDefaultKeyBindings();
+#ifndef PDF_PARSER_ONLY
+ void initStateFilePaths();
+#endif
void parseFile(GString *fileName, FILE *f);
GList *parseLineTokens(char *buf, GString *fileName, int line);
void parseNameToUnicode(GList *tokens, GString *fileName, int line);
@@ -450,6 +459,8 @@ private:
const char *cmdName,
GList *tokens, GString *fileName, int line);
void parsePopupMenuCmd(GList *tokens, GString *fileName, int line);
+ void parseZoomScaleFactor(GList *tokens, GString *fileName, int line);
+ void parseZoomValues(GList *tokens, GString *fileName, int line);
void parseYesNo(const char *cmdName, GBool *flag,
GList *tokens, GString *fileName, int line);
GBool parseYesNo2(char *token, GBool *flag);
@@ -548,7 +559,9 @@ private:
GBool textKeepTinyChars; // keep all characters in text output
GString *initialZoom; // initial zoom level
int defaultFitZoom; // default zoom factor if initialZoom is
- // 'page' or 'width'.
+ // 'page' or 'width'
+ double zoomScaleFactor; // displayed zoom values are scaled by this
+ GList *zoomValues; // zoom values for the combo box
GString *initialDisplayMode; // initial display mode (single,
// continuous, etc.)
GBool initialToolbarState; // initial toolbar state - open (true)
@@ -586,6 +599,7 @@ private:
GString *fullScreenMatteColor; // matte color in full-screen mode
GString *selectionColor; // selection color
GBool reverseVideoInvertImages; // invert images in reverse video mode
+ GBool allowLinksToChangeZoom; // allow clicking on a link to change the zoom
GString *launchCommand; // command executed for 'launch' links
GString *movieCommand; // command executed for movie annotations
GString *defaultPrinter; // default printer (for interactive printing
@@ -597,10 +611,16 @@ private:
GBool useTrueTypeUnicodeMapping; // use the Unicode cmaps in TrueType
// fonts, rather than the PDF
// ToUnicode mapping
+ GBool ignoreWrongSizeToUnicode; // ignore ToUnicode CMaps if their size
+ // (8-bit vs 16-bit) doesn't match the font
GHash *droppedFonts; // dropped fonts [int]
+ GBool separateRotatedText; // separate text at each rotation
GList *keyBindings; // key & mouse button bindings [KeyBinding]
GList *popupMenuCmds; // popup menu commands [PopupMenuCmd]
+ GString *pagesFile; // path for the page number save file
GString *tabStateFile; // path for the tab state save file
+ GString *sessionFile; // path for the session save file
+ GBool saveSessionOnQuit; // save session info when xpdf is quit
GBool savePageNumbers; // save page number when file is closed
// and restore page number when opened
GBool printCommands; // print the drawing commands
diff --git a/Build/source/libs/xpdf/xpdf-src/xpdf/HTMLGen.cc b/Build/source/libs/xpdf/xpdf-src/xpdf/HTMLGen.cc
index a077655ef43..0183d3a14f4 100644
--- a/Build/source/libs/xpdf/xpdf-src/xpdf/HTMLGen.cc
+++ b/Build/source/libs/xpdf/xpdf-src/xpdf/HTMLGen.cc
@@ -21,10 +21,6 @@
#include <aconf.h>
-#ifdef USE_GCC_PRAGMAS
-#pragma implementation
-#endif
-
#include <stdlib.h>
#include <png.h>
#include "gmem.h"
@@ -35,6 +31,7 @@
#include "PDFDoc.h"
#include "GfxFont.h"
#include "AcroForm.h"
+#include "TextString.h"
#include "TextOutputDev.h"
#include "SplashOutputDev.h"
#include "ErrorCodes.h"
@@ -42,9 +39,11 @@
#include "HTMLGen.h"
#ifdef _WIN32
+#ifndef __GNUC__
# define strcasecmp stricmp
# define strncasecmp strnicmp
#endif
+#endif
//------------------------------------------------------------------------
@@ -297,6 +296,7 @@ HTMLGen::HTMLGen(double backgroundResolutionA, GBool tableMode) {
convertFormFields = gFalse;
embedBackgroundImage = gFalse;
embedFonts = gFalse;
+ includeMetadata = gFalse;
// set up the TextOutputDev
textOutControl.mode = tableMode ? textOutTableLayout : textOutReadingOrder;
@@ -312,6 +312,10 @@ HTMLGen::HTMLGen(double backgroundResolutionA, GBool tableMode) {
splashOut = new SplashOutputDev(splashModeRGB8, 1, gFalse, paperColor);
fontDefns = NULL;
+
+ nVisibleChars = 0;
+ nInvisibleChars = 0;
+ nRemovedDupChars = 0;
}
HTMLGen::~HTMLGen() {
@@ -462,11 +466,11 @@ int HTMLGen::convertPage(
llyI = bitmap->getHeight() - 1;
}
if (uryI <= llyI && llxI <= urxI) {
- SplashColorPtr p = bitmap->getDataPtr()
- + uryI * bitmap->getRowSize() + llxI * 3;
- for (int y = uryI; y <= llyI; ++y) {
- memset(p, 0xff, (urxI - llxI + 1) * 3);
- p += bitmap->getRowSize();
+ SplashColorPtr pix = bitmap->getDataPtr()
+ + uryI * bitmap->getRowSize() + llxI * 3;
+ for (y = uryI; y <= llyI; ++y) {
+ memset(pix, 0xff, (urxI - llxI + 1) * 3);
+ pix += bitmap->getRowSize();
}
}
@@ -483,6 +487,9 @@ int HTMLGen::convertPage(
pr(writeHTML, htmlStream, "<html>\n");
pr(writeHTML, htmlStream, "<head>\n");
pr(writeHTML, htmlStream, "<meta http-equiv=\"Content-Type\" content=\"text/html; charset=UTF-8\">\n");
+ if (includeMetadata) {
+ genDocMetadata(writeHTML, htmlStream);
+ }
pr(writeHTML, htmlStream, "<style type=\"text/css\">\n");
pr(writeHTML, htmlStream, ".txt { white-space:nowrap; }\n");
if (convertFormFields) {
@@ -571,6 +578,9 @@ int HTMLGen::convertPage(
// generate the HTML text
nextFieldID = 0;
cols = text->makeColumns();
+ nVisibleChars = text->getNumVisibleChars();
+ nInvisibleChars = text->getNumInvisibleChars();
+ nRemovedDupChars = text->getNumRemovedDupChars();
for (colIdx = 0; colIdx < cols->getLength(); ++colIdx) {
col = (TextColumn *)cols->get(colIdx);
pars = col->getParagraphs();
@@ -1118,3 +1128,47 @@ void HTMLGen::getFontDetails(TextFontInfo *font, const char **family,
*weight = bold ? "bold" : "normal";
*style = italic ? "italic" : "normal";
}
+
+void HTMLGen::genDocMetadata(int (*writeHTML)(void *stream,
+ const char *data, int size),
+ void *htmlStream) {
+ Object info;
+ doc->getDocInfo(&info);
+ if (info.isDict()) {
+ genDocMetadataItem(writeHTML, htmlStream, info.getDict(), "Title");
+ genDocMetadataItem(writeHTML, htmlStream, info.getDict(), "Subject");
+ genDocMetadataItem(writeHTML, htmlStream, info.getDict(), "Keywords");
+ genDocMetadataItem(writeHTML, htmlStream, info.getDict(), "Author");
+ genDocMetadataItem(writeHTML, htmlStream, info.getDict(), "Creator");
+ genDocMetadataItem(writeHTML, htmlStream, info.getDict(), "Producer");
+ genDocMetadataItem(writeHTML, htmlStream, info.getDict(), "CreationDate");
+ genDocMetadataItem(writeHTML, htmlStream, info.getDict(), "ModDate");
+ }
+ info.free();
+}
+
+void HTMLGen::genDocMetadataItem(int (*writeHTML)(void *stream,
+ const char *data, int size),
+ void *htmlStream,
+ Dict *infoDict, const char *key) {
+ Object val;
+ if (infoDict->lookup(key, &val)->isString()) {
+ GString *s = GString::format("<meta name=\"{0:s}\" content=\"", key);
+ TextString *ts = new TextString(val.getString());
+ Unicode *u = ts->getUnicode();
+ for (int i = 0; i < ts->getLength(); ++i) {
+ if (u[i] == '"') {
+ s->append("&quot;");
+ } else if (u[i] == '&') {
+ s->append("&amp;");
+ } else {
+ appendUTF8(u[i], s);
+ }
+ }
+ delete ts;
+ s->append("\">\n");
+ writeHTML(htmlStream, s->getCString(), s->getLength());
+ delete s;
+ }
+ val.free();
+}
diff --git a/Build/source/libs/xpdf/xpdf-src/xpdf/HTMLGen.h b/Build/source/libs/xpdf/xpdf-src/xpdf/HTMLGen.h
index 66ee2d27406..47e361f78fa 100644
--- a/Build/source/libs/xpdf/xpdf-src/xpdf/HTMLGen.h
+++ b/Build/source/libs/xpdf/xpdf-src/xpdf/HTMLGen.h
@@ -11,10 +11,6 @@
#include <aconf.h>
-#ifdef USE_GCC_PRAGMAS
-#pragma interface
-#endif
-
class GString;
class PDFDoc;
class TextOutputDev;
@@ -61,6 +57,9 @@ public:
void setEmbedFonts(GBool embedFontsA)
{ embedFonts = embedFontsA; }
+ void setIncludeMetadata(GBool includeMetadataA)
+ { includeMetadata = includeMetadataA; }
+
void startDoc(PDFDoc *docA);
int convertPage(int pg, const char *pngURL, const char *htmlDir,
int (*writeHTML)(void *stream, const char *data, int size),
@@ -68,6 +67,11 @@ public:
int (*writePNG)(void *stream, const char *data, int size),
void *pngStream);
+ // Get the counter values.
+ int getNumVisibleChars() { return nVisibleChars; }
+ int getNumInvisibleChars() { return nInvisibleChars; }
+ int getNumRemovedDupChars() { return nRemovedDupChars; }
+
private:
int findDirSpan(GList *words, int firstWordIdx, int primaryDir,
@@ -82,6 +86,13 @@ private:
void getFontDetails(TextFontInfo *font, const char **family,
const char **weight, const char **style,
double *scale);
+ void genDocMetadata(int (*writeHTML)(void *stream,
+ const char *data, int size),
+ void *htmlStream);
+ void genDocMetadataItem(int (*writeHTML)(void *stream,
+ const char *data, int size),
+ void *htmlStream,
+ Dict *infoDict, const char *key);
double backgroundResolution;
double zoom;
@@ -92,6 +103,7 @@ private:
GBool convertFormFields;
GBool embedBackgroundImage;
GBool embedFonts;
+ GBool includeMetadata;
PDFDoc *doc;
TextOutputDev *textOut;
@@ -107,6 +119,10 @@ private:
GList *formFieldInfo; // [HTMLGenFormFieldInfo]
int nextFieldID;
+ int nVisibleChars; // number of visible chars on the page
+ int nInvisibleChars; // number of invisible chars on the page
+ int nRemovedDupChars; // number of duplicate chars removed
+
GBool ok;
};
diff --git a/Build/source/libs/xpdf/xpdf-src/xpdf/ImageOutputDev.cc b/Build/source/libs/xpdf/xpdf-src/xpdf/ImageOutputDev.cc
index 5a694d7b665..2c2db13fa4d 100644
--- a/Build/source/libs/xpdf/xpdf-src/xpdf/ImageOutputDev.cc
+++ b/Build/source/libs/xpdf/xpdf-src/xpdf/ImageOutputDev.cc
@@ -8,10 +8,6 @@
#include <aconf.h>
-#ifdef USE_GCC_PRAGMAS
-#pragma implementation
-#endif
-
#include <stdio.h>
#include <stdlib.h>
#include <stddef.h>
@@ -22,6 +18,7 @@
#include "config.h"
#include "Error.h"
#include "GfxState.h"
+#include "Gfx.h"
#include "Object.h"
#include "Stream.h"
#include "ImageOutputDev.h"
@@ -52,7 +49,8 @@ void ImageOutputDev::tilingPatternFill(GfxState *state, Gfx *gfx,
double *mat, double *bbox,
int x0, int y0, int x1, int y1,
double xStep, double yStep) {
- // do nothing -- this avoids the potentially slow loop in Gfx.cc
+ // draw the tile once, just in case it contains image(s)
+ gfx->drawForm(strRef, resDict, mat, bbox);
}
void ImageOutputDev::drawImageMask(GfxState *state, Object *ref, Stream *str,
diff --git a/Build/source/libs/xpdf/xpdf-src/xpdf/ImageOutputDev.h b/Build/source/libs/xpdf/xpdf-src/xpdf/ImageOutputDev.h
index 5a72925aee9..0abe6f1bb55 100644
--- a/Build/source/libs/xpdf/xpdf-src/xpdf/ImageOutputDev.h
+++ b/Build/source/libs/xpdf/xpdf-src/xpdf/ImageOutputDev.h
@@ -11,10 +11,6 @@
#include <aconf.h>
-#ifdef USE_GCC_PRAGMAS
-#pragma interface
-#endif
-
#include <stdio.h>
#include "gtypes.h"
#include "OutputDev.h"
diff --git a/Build/source/libs/xpdf/xpdf-src/xpdf/JArithmeticDecoder.cc b/Build/source/libs/xpdf/xpdf-src/xpdf/JArithmeticDecoder.cc
index 3d10cb4acad..f00063e8ec2 100644
--- a/Build/source/libs/xpdf/xpdf-src/xpdf/JArithmeticDecoder.cc
+++ b/Build/source/libs/xpdf/xpdf-src/xpdf/JArithmeticDecoder.cc
@@ -8,10 +8,6 @@
#include <aconf.h>
-#ifdef USE_GCC_PRAGMAS
-#pragma implementation
-#endif
-
#include "gmempp.h"
#include "Object.h"
#include "Stream.h"
diff --git a/Build/source/libs/xpdf/xpdf-src/xpdf/JArithmeticDecoder.h b/Build/source/libs/xpdf/xpdf-src/xpdf/JArithmeticDecoder.h
index c0f773fb107..8714b46a9ef 100644
--- a/Build/source/libs/xpdf/xpdf-src/xpdf/JArithmeticDecoder.h
+++ b/Build/source/libs/xpdf/xpdf-src/xpdf/JArithmeticDecoder.h
@@ -13,10 +13,6 @@
#include <aconf.h>
-#ifdef USE_GCC_PRAGMAS
-#pragma interface
-#endif
-
#include "gtypes.h"
class Stream;
diff --git a/Build/source/libs/xpdf/xpdf-src/xpdf/JBIG2Stream.cc b/Build/source/libs/xpdf/xpdf-src/xpdf/JBIG2Stream.cc
index 02450b4f816..8d71e17f96c 100644
--- a/Build/source/libs/xpdf/xpdf-src/xpdf/JBIG2Stream.cc
+++ b/Build/source/libs/xpdf/xpdf-src/xpdf/JBIG2Stream.cc
@@ -8,10 +8,6 @@
#include <aconf.h>
-#ifdef USE_GCC_PRAGMAS
-#pragma implementation
-#endif
-
#include <stdlib.h>
#include <limits.h>
#include "gmempp.h"
@@ -1798,6 +1794,11 @@ GBool JBIG2Stream::readSymbolDictSeg(Guint segNum, Guint length,
break;
}
}
+ if (refAggNum <= 0 || refAggNum > 10000) {
+ error(errSyntaxError, getPos(),
+ "Invalid refinement/aggregation instance count in JBIG2 symbol dictionary");
+ goto syntaxError;
+ }
#if 0 //~ This special case was added about a year before the final draft
//~ of the JBIG2 spec was released. I have encountered some old
//~ JBIG2 images that predate it.
@@ -2440,6 +2441,18 @@ JBIG2Bitmap *JBIG2Stream::readTextRegion(GBool huff, GBool refine,
refDX = ((rdw >= 0) ? rdw : rdw - 1) / 2 + rdx;
refDY = ((rdh >= 0) ? rdh : rdh - 1) / 2 + rdy;
+ if (rdw > INT_MAX - syms[symID]->getWidth() ||
+ rdh > INT_MAX - syms[symID]->getHeight()) {
+ error(errSyntaxError, getPos(),
+ "Invalid refinement size in JBIG2 text region");
+ continue;
+ }
+ // sanity check
+ if (rdw > 1000 || rdh > 1000) {
+ error(errSyntaxError, getPos(),
+ "Invalid refinement size in JBIG2 text region");
+ continue;
+ }
symbolBitmap =
readGenericRefinementRegion(rdw + syms[symID]->getWidth(),
rdh + syms[symID]->getHeight(),
@@ -2527,7 +2540,8 @@ void JBIG2Stream::readPatternDictSeg(Guint segNum, Guint length) {
!readULong(&grayMax)) {
goto eofError;
}
- if (patternW == 0 || patternH == 0) {
+ if (patternW == 0 || patternH == 0 ||
+ grayMax > UINT_MAX / patternW - 1) {
error(errSyntaxError, getPos(),
"Bad size in JBIG2 pattern dictionary segment");
return;
@@ -3948,7 +3962,9 @@ void JBIG2Stream::readPageInfoSeg(Guint length) {
!readUByte(&flags) || !readUWord(&striping)) {
goto eofError;
}
- if (pageW == 0 || pageH == 0 || pageW > INT_MAX / pageW) {
+ if (pageW == 0 || pageH == 0 ||
+ pageW > INT_MAX || pageH > INT_MAX ||
+ pageH > INT_MAX / pageW) {
error(errSyntaxError, getPos(), "Bad page size in JBIG2 stream");
return;
}
diff --git a/Build/source/libs/xpdf/xpdf-src/xpdf/JBIG2Stream.h b/Build/source/libs/xpdf/xpdf-src/xpdf/JBIG2Stream.h
index bb44ba1ab01..4964255bbf7 100644
--- a/Build/source/libs/xpdf/xpdf-src/xpdf/JBIG2Stream.h
+++ b/Build/source/libs/xpdf/xpdf-src/xpdf/JBIG2Stream.h
@@ -11,10 +11,6 @@
#include <aconf.h>
-#ifdef USE_GCC_PRAGMAS
-#pragma interface
-#endif
-
#include "gtypes.h"
#include "Object.h"
#include "Stream.h"
@@ -45,6 +41,7 @@ public:
virtual GString *getPSFilter(int psLevel, const char *indent,
GBool okToReadStream);
virtual GBool isBinary(GBool last = gTrue);
+ virtual GBool hasStrongCompression() { return gTrue; }
private:
diff --git a/Build/source/libs/xpdf/xpdf-src/xpdf/JPXStream.cc b/Build/source/libs/xpdf/xpdf-src/xpdf/JPXStream.cc
index a1f7395dd57..5ed1890a1d3 100644
--- a/Build/source/libs/xpdf/xpdf-src/xpdf/JPXStream.cc
+++ b/Build/source/libs/xpdf/xpdf-src/xpdf/JPXStream.cc
@@ -8,10 +8,6 @@
#include <aconf.h>
-#ifdef USE_GCC_PRAGMAS
-#pragma implementation
-#endif
-
#include <limits.h>
#include "gmem.h"
#include "gmempp.h"
@@ -1117,6 +1113,7 @@ JPXDecodeResult JPXStream::readCodestream(Guint len) {
"JPX COC marker segment before COD segment");
return jpxDecodeFatalError;
}
+ comp = 0;
if ((img.nComps > 256 && !readUWord(&comp)) ||
(img.nComps <= 256 && !readUByte(&comp)) ||
comp >= img.nComps ||
@@ -1269,6 +1266,7 @@ JPXDecodeResult JPXStream::readCodestream(Guint len) {
"JPX QCC marker segment before QCD segment");
return jpxDecodeFatalError;
}
+ comp = 0;
if ((img.nComps > 256 && !readUWord(&comp)) ||
(img.nComps <= 256 && !readUByte(&comp)) ||
comp >= img.nComps ||
@@ -1641,6 +1639,7 @@ GBool JPXStream::readTilePart() {
error(errSyntaxError, getPos(), "Extraneous JPX COC marker segment");
return gFalse;
}
+ comp = 0;
if ((img.nComps > 256 && !readUWord(&comp)) ||
(img.nComps <= 256 && !readUByte(&comp)) ||
comp >= img.nComps ||
@@ -1774,6 +1773,7 @@ GBool JPXStream::readTilePart() {
error(errSyntaxError, getPos(), "Extraneous JPX QCC marker segment");
return gFalse;
}
+ comp = 0;
if ((img.nComps > 256 && !readUWord(&comp)) ||
(img.nComps <= 256 && !readUByte(&comp)) ||
comp >= img.nComps ||
@@ -2619,7 +2619,12 @@ GBool JPXStream::readCodeBlockData(JPXTileComp *tileComp,
if (cb->arithDecoder) {
cover(63);
- cb->arithDecoder->restart(cb->dataLen[0]);
+ if (tileComp->codeBlockStyle & 0x04) {
+ cb->arithDecoder->setStream(bufStr, cb->dataLen[0]);
+ cb->arithDecoder->start();
+ } else {
+ cb->arithDecoder->restart(cb->dataLen[0]);
+ }
} else {
cover(64);
cb->arithDecoder = new JArithmeticDecoder();
@@ -3319,7 +3324,7 @@ void JPXStream::inverseTransform1D(JPXTileComp *tileComp, int *data,
// converts fixed point samples back to integers.
GBool JPXStream::inverseMultiCompAndDC(JPXTile *tile) {
JPXTileComp *tileComp;
- int coeff, d0, d1, d2, t, minVal, maxVal, zeroVal;
+ int coeff, d0, d1, d2, t, minVal, maxVal, zeroVal, shift, rounding;
int *dataPtr;
Guint j, comp, x, y;
@@ -3404,12 +3409,14 @@ GBool JPXStream::inverseMultiCompAndDC(JPXTile *tile) {
maxVal = (1 << tileComp->prec) - 1;
zeroVal = 1 << (tileComp->prec - 1);
dataPtr = tileComp->data;
+ shift = fracBits - tileComp->prec;
+ rounding = 1 << (shift - 1);
for (y = 0; y < tileComp->h; ++y) {
for (x = 0; x < tileComp->w; ++x) {
coeff = *dataPtr;
if (tileComp->transform == 0) {
cover(112);
- coeff >>= fracBits - tileComp->prec;
+ coeff = (coeff + rounding) >> shift;
}
coeff += zeroVal;
if (coeff < 0) {
diff --git a/Build/source/libs/xpdf/xpdf-src/xpdf/JPXStream.h b/Build/source/libs/xpdf/xpdf-src/xpdf/JPXStream.h
index 4b8587b0fb2..ce12427ced9 100644
--- a/Build/source/libs/xpdf/xpdf-src/xpdf/JPXStream.h
+++ b/Build/source/libs/xpdf/xpdf-src/xpdf/JPXStream.h
@@ -11,10 +11,6 @@
#include <aconf.h>
-#ifdef USE_GCC_PRAGMAS
-#pragma interface
-#endif
-
#include "gtypes.h"
#include "Object.h"
#include "Stream.h"
@@ -291,6 +287,7 @@ public:
virtual GString *getPSFilter(int psLevel, const char *indent,
GBool okToReadStream);
virtual GBool isBinary(GBool last = gTrue);
+ virtual GBool hasStrongCompression() { return gTrue; }
virtual void getImageParams(int *bitsPerComponent,
StreamColorSpaceMode *csMode);
void reduceResolution(int reductionA) { reduction = reductionA; }
diff --git a/Build/source/libs/xpdf/xpdf-src/xpdf/Lexer.cc b/Build/source/libs/xpdf/xpdf-src/xpdf/Lexer.cc
index 0c74dbb04ea..d1066d33837 100644
--- a/Build/source/libs/xpdf/xpdf-src/xpdf/Lexer.cc
+++ b/Build/source/libs/xpdf/xpdf-src/xpdf/Lexer.cc
@@ -8,10 +8,6 @@
#include <aconf.h>
-#ifdef USE_GCC_PRAGMAS
-#pragma implementation
-#endif
-
#include <stdlib.h>
#include <stddef.h>
#include <string.h>
@@ -113,7 +109,7 @@ Object *Lexer::getObj(Object *obj) {
char *p;
int c, c2;
GBool comment, neg, doubleMinus, done, invalid;
- int numParen;
+ int numParen, nErrors;
int xi;
double xf, scale;
GString *s;
@@ -434,7 +430,8 @@ Object *Lexer::getObj(Object *obj) {
m = n = 0;
c2 = 0;
s = NULL;
- while (1) {
+ nErrors = 0;
+ while (nErrors < 100) {
c = getChar();
if (c == '>') {
break;
@@ -443,15 +440,17 @@ Object *Lexer::getObj(Object *obj) {
break;
} else if (specialChars[c] != 1) {
c2 = c2 << 4;
- if (c >= '0' && c <= '9')
+ if (c >= '0' && c <= '9') {
c2 += c - '0';
- else if (c >= 'A' && c <= 'F')
+ } else if (c >= 'A' && c <= 'F') {
c2 += c - 'A' + 10;
- else if (c >= 'a' && c <= 'f')
+ } else if (c >= 'a' && c <= 'f') {
c2 += c - 'a' + 10;
- else
+ } else {
error(errSyntaxError, getPos(),
"Illegal character <{0:02x}> in hex string", c);
+ ++nErrors;
+ }
if (++m == 2) {
if (n == tokBufSize) {
if (!s)
diff --git a/Build/source/libs/xpdf/xpdf-src/xpdf/Lexer.h b/Build/source/libs/xpdf/xpdf-src/xpdf/Lexer.h
index d481c2c5a2b..458a5851584 100644
--- a/Build/source/libs/xpdf/xpdf-src/xpdf/Lexer.h
+++ b/Build/source/libs/xpdf/xpdf-src/xpdf/Lexer.h
@@ -11,10 +11,6 @@
#include <aconf.h>
-#ifdef USE_GCC_PRAGMAS
-#pragma interface
-#endif
-
#include "Object.h"
#include "Stream.h"
diff --git a/Build/source/libs/xpdf/xpdf-src/xpdf/Link.cc b/Build/source/libs/xpdf/xpdf-src/xpdf/Link.cc
index 900f79ddf85..60f20867338 100644
--- a/Build/source/libs/xpdf/xpdf-src/xpdf/Link.cc
+++ b/Build/source/libs/xpdf/xpdf-src/xpdf/Link.cc
@@ -8,10 +8,6 @@
#include <aconf.h>
-#ifdef USE_GCC_PRAGMAS
-#pragma implementation
-#endif
-
#include <stddef.h>
#include <string.h>
#include "gmem.h"
diff --git a/Build/source/libs/xpdf/xpdf-src/xpdf/Link.h b/Build/source/libs/xpdf/xpdf-src/xpdf/Link.h
index 480496ad176..d6155447e92 100644
--- a/Build/source/libs/xpdf/xpdf-src/xpdf/Link.h
+++ b/Build/source/libs/xpdf/xpdf-src/xpdf/Link.h
@@ -11,10 +11,6 @@
#include <aconf.h>
-#ifdef USE_GCC_PRAGMAS
-#pragma interface
-#endif
-
#include "Object.h"
class GString;
diff --git a/Build/source/libs/xpdf/xpdf-src/xpdf/NameToCharCode.cc b/Build/source/libs/xpdf/xpdf-src/xpdf/NameToCharCode.cc
index f846d8e940d..0088986d2f0 100644
--- a/Build/source/libs/xpdf/xpdf-src/xpdf/NameToCharCode.cc
+++ b/Build/source/libs/xpdf/xpdf-src/xpdf/NameToCharCode.cc
@@ -8,10 +8,6 @@
#include <aconf.h>
-#ifdef USE_GCC_PRAGMAS
-#pragma implementation
-#endif
-
#include <string.h>
#include "gmem.h"
#include "gmempp.h"
diff --git a/Build/source/libs/xpdf/xpdf-src/xpdf/NameToCharCode.h b/Build/source/libs/xpdf/xpdf-src/xpdf/NameToCharCode.h
index 6548133cdcd..cf2170bfd46 100644
--- a/Build/source/libs/xpdf/xpdf-src/xpdf/NameToCharCode.h
+++ b/Build/source/libs/xpdf/xpdf-src/xpdf/NameToCharCode.h
@@ -11,10 +11,6 @@
#include <aconf.h>
-#ifdef USE_GCC_PRAGMAS
-#pragma interface
-#endif
-
#include "CharTypes.h"
struct NameToCharCodeEntry;
diff --git a/Build/source/libs/xpdf/xpdf-src/xpdf/Object.cc b/Build/source/libs/xpdf/xpdf-src/xpdf/Object.cc
index 898fbc99e2b..dbb785868c8 100644
--- a/Build/source/libs/xpdf/xpdf-src/xpdf/Object.cc
+++ b/Build/source/libs/xpdf/xpdf-src/xpdf/Object.cc
@@ -8,10 +8,6 @@
#include <aconf.h>
-#ifdef USE_GCC_PRAGMAS
-#pragma implementation
-#endif
-
#include <stddef.h>
#include "gmempp.h"
#include "Object.h"
@@ -42,7 +38,7 @@ const char *objTypeNames[numObjTypes] = {
"none"
};
-#ifdef DEBUG_MEM
+#ifdef DEBUG_OBJECT_MEM
#if MULTITHREADED
GAtomicCounter Object::numAlloc[numObjTypes] =
{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
@@ -50,7 +46,7 @@ GAtomicCounter Object::numAlloc[numObjTypes] =
long Object::numAlloc[numObjTypes] =
{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
#endif
-#endif // DEBUG_MEM
+#endif // DEBUG_OBJECT_MEM
Object *Object::initArray(XRef *xref) {
initObj(objArray);
@@ -101,7 +97,7 @@ Object *Object::copy(Object *obj) {
default:
break;
}
-#ifdef DEBUG_MEM
+#ifdef DEBUG_OBJECT_MEM
#if MULTITHREADED
gAtomicIncrement(&numAlloc[type]);
#else
@@ -143,7 +139,7 @@ void Object::free() {
default:
break;
}
-#ifdef DEBUG_MEM
+#ifdef DEBUG_OBJECT_MEM
#if MULTITHREADED
gAtomicDecrement(&numAlloc[type]);
#else
@@ -225,7 +221,7 @@ void Object::print(FILE *f) {
}
void Object::memCheck(FILE *f) {
-#ifdef DEBUG_MEM
+#ifdef DEBUG_OBJECT_MEM
int i;
long t;
diff --git a/Build/source/libs/xpdf/xpdf-src/xpdf/Object.h b/Build/source/libs/xpdf/xpdf-src/xpdf/Object.h
index cb636510149..17c082041b7 100644
--- a/Build/source/libs/xpdf/xpdf-src/xpdf/Object.h
+++ b/Build/source/libs/xpdf/xpdf-src/xpdf/Object.h
@@ -11,10 +11,6 @@
#include <aconf.h>
-#ifdef USE_GCC_PRAGMAS
-#pragma interface
-#endif
-
#include <stdio.h>
#include <string.h>
#include "gtypes.h"
@@ -71,7 +67,7 @@ enum ObjType {
// Object
//------------------------------------------------------------------------
-#ifdef DEBUG_MEM
+#ifdef DEBUG_OBJECT_MEM
# if MULTITHREADED
# define initObj(t) gAtomicIncrement(&numAlloc[type = t])
# else
@@ -216,7 +212,7 @@ private:
char *cmd; // command
};
-#ifdef DEBUG_MEM
+#ifdef DEBUG_OBJECT_MEM
#if MULTITHREADED
static GAtomicCounter // number of each type of object
numAlloc[numObjTypes]; // currently allocated
diff --git a/Build/source/libs/xpdf/xpdf-src/xpdf/OptionalContent.cc b/Build/source/libs/xpdf/xpdf-src/xpdf/OptionalContent.cc
index a0fbb1b06c2..501ad2d1220 100644
--- a/Build/source/libs/xpdf/xpdf-src/xpdf/OptionalContent.cc
+++ b/Build/source/libs/xpdf/xpdf-src/xpdf/OptionalContent.cc
@@ -8,10 +8,6 @@
#include <aconf.h>
-#ifdef USE_GCC_PRAGMAS
-#pragma implementation
-#endif
-
#include "gmempp.h"
#include "GString.h"
#include "GList.h"
diff --git a/Build/source/libs/xpdf/xpdf-src/xpdf/OptionalContent.h b/Build/source/libs/xpdf/xpdf-src/xpdf/OptionalContent.h
index f00ef296a0c..f4eb1e95cb7 100644
--- a/Build/source/libs/xpdf/xpdf-src/xpdf/OptionalContent.h
+++ b/Build/source/libs/xpdf/xpdf-src/xpdf/OptionalContent.h
@@ -11,10 +11,6 @@
#include <aconf.h>
-#ifdef USE_GCC_PRAGMAS
-#pragma interface
-#endif
-
#include "gtypes.h"
#include "Object.h"
#include "CharTypes.h"
diff --git a/Build/source/libs/xpdf/xpdf-src/xpdf/Outline.cc b/Build/source/libs/xpdf/xpdf-src/xpdf/Outline.cc
index 9593956f8d0..09e3b754bef 100644
--- a/Build/source/libs/xpdf/xpdf-src/xpdf/Outline.cc
+++ b/Build/source/libs/xpdf/xpdf-src/xpdf/Outline.cc
@@ -8,10 +8,6 @@
#include <aconf.h>
-#ifdef USE_GCC_PRAGMAS
-#pragma implementation
-#endif
-
#include "gmem.h"
#include "gmempp.h"
#include "GString.h"
diff --git a/Build/source/libs/xpdf/xpdf-src/xpdf/Outline.h b/Build/source/libs/xpdf/xpdf-src/xpdf/Outline.h
index e9bce83cdad..80943ab8be9 100644
--- a/Build/source/libs/xpdf/xpdf-src/xpdf/Outline.h
+++ b/Build/source/libs/xpdf/xpdf-src/xpdf/Outline.h
@@ -11,10 +11,6 @@
#include <aconf.h>
-#ifdef USE_GCC_PRAGMAS
-#pragma interface
-#endif
-
#include "Object.h"
#include "CharTypes.h"
diff --git a/Build/source/libs/xpdf/xpdf-src/xpdf/OutputDev.cc b/Build/source/libs/xpdf/xpdf-src/xpdf/OutputDev.cc
index f2be88edfdc..93dc1bc1273 100644
--- a/Build/source/libs/xpdf/xpdf-src/xpdf/OutputDev.cc
+++ b/Build/source/libs/xpdf/xpdf-src/xpdf/OutputDev.cc
@@ -8,10 +8,6 @@
#include <aconf.h>
-#ifdef USE_GCC_PRAGMAS
-#pragma implementation
-#endif
-
#include <stddef.h>
#include "gmempp.h"
#include "Object.h"
@@ -76,6 +72,15 @@ void OutputDev::updateAll(GfxState *state) {
updateFont(state);
}
+void OutputDev::fillStroke(GfxState *state, GBool eo) {
+ if (eo) {
+ eoFill(state);
+ } else {
+ fill(state);
+ }
+ stroke(state);
+}
+
GBool OutputDev::beginType3Char(GfxState *state, double x, double y,
double dx, double dy,
CharCode code, Unicode *u, int uLen) {
diff --git a/Build/source/libs/xpdf/xpdf-src/xpdf/OutputDev.h b/Build/source/libs/xpdf/xpdf-src/xpdf/OutputDev.h
index 54483cfcc43..0b31d14a50c 100644
--- a/Build/source/libs/xpdf/xpdf-src/xpdf/OutputDev.h
+++ b/Build/source/libs/xpdf/xpdf-src/xpdf/OutputDev.h
@@ -11,10 +11,6 @@
#include <aconf.h>
-#ifdef USE_GCC_PRAGMAS
-#pragma interface
-#endif
-
#include "gtypes.h"
#include "CharTypes.h"
@@ -99,6 +95,10 @@ public:
// End a page.
virtual void endPage() {}
+ // Start/end a sub-page stream (Form XObject, annotation).
+ virtual void startStream(Ref streamRef, GfxState *state) {}
+ virtual void endStream(Ref streamRef) {}
+
//----- coordinate conversion
// Convert between device and user coordinates.
@@ -147,13 +147,12 @@ public:
virtual void updateHorizScaling(GfxState *state) {}
virtual void updateTextPos(GfxState *state) {}
virtual void updateTextShift(GfxState *state, double shift) {}
- virtual void saveTextPos(GfxState *state) {}
- virtual void restoreTextPos(GfxState *state) {}
//----- path painting
virtual void stroke(GfxState *state) {}
virtual void fill(GfxState *state) {}
virtual void eoFill(GfxState *state) {}
+ virtual void fillStroke(GfxState *state, GBool eo);
virtual void tilingPatternFill(GfxState *state, Gfx *gfx, Object *strRef,
int paintType, int tilingType, Dict *resDict,
double *mat, double *bbox,
@@ -175,8 +174,17 @@ public:
virtual void drawChar(GfxState *state, double x, double y,
double dx, double dy,
double originX, double originY,
- CharCode code, int nBytes, Unicode *u, int uLen) {}
- virtual void drawString(GfxState *state, GString *s) {}
+ CharCode code, int nBytes, Unicode *u, int uLen,
+ GBool fill, GBool stroke, GBool makePath) {}
+ virtual void drawString(GfxState *state, GString *s,
+ GBool fill, GBool stroke, GBool makePath) {}
+ virtual void fillTextPath(GfxState *state) {}
+ virtual void strokeTextPath(GfxState *state) {}
+ virtual void clipToTextPath(GfxState *state) {}
+ virtual void clipToTextStrokePath(GfxState *state) {}
+ virtual void clearTextPath(GfxState *state) {}
+ virtual void addTextPathToSavedClipPath(GfxState *state) {}
+ virtual void clipToSavedClipPath(GfxState *state) {}
virtual GBool beginType3Char(GfxState *state, double x, double y,
double dx, double dy,
CharCode code, Unicode *u, int uLen);
@@ -242,6 +250,10 @@ public:
//----- links
virtual void processLink(Link *link) {}
+ //----- structure tree
+ virtual void beginStructureItem(const char *tag, int mcid, Dict *dict) {}
+ virtual void endStructureItem() {}
+
private:
double defCTM[6]; // default coordinate transform matrix
diff --git a/Build/source/libs/xpdf/xpdf-src/xpdf/PDF417Barcode.cc b/Build/source/libs/xpdf/xpdf-src/xpdf/PDF417Barcode.cc
index 0dd35ee4902..bb273b6161d 100644
--- a/Build/source/libs/xpdf/xpdf-src/xpdf/PDF417Barcode.cc
+++ b/Build/source/libs/xpdf/xpdf-src/xpdf/PDF417Barcode.cc
@@ -8,10 +8,6 @@
#include <aconf.h>
-#ifdef USE_GCC_PRAGMAS
-#pragma implementation
-#endif
-
#include <math.h>
#include "gtypes.h"
#include "GString.h"
diff --git a/Build/source/libs/xpdf/xpdf-src/xpdf/PDF417Barcode.h b/Build/source/libs/xpdf/xpdf-src/xpdf/PDF417Barcode.h
index 8166865280b..c86f1df4508 100644
--- a/Build/source/libs/xpdf/xpdf-src/xpdf/PDF417Barcode.h
+++ b/Build/source/libs/xpdf/xpdf-src/xpdf/PDF417Barcode.h
@@ -11,10 +11,6 @@
#include <aconf.h>
-#ifdef USE_GCC_PRAGMAS
-#pragma interface
-#endif
-
class GString;
// Draw a PDF417 barcode:
diff --git a/Build/source/libs/xpdf/xpdf-src/xpdf/PDFCore.cc b/Build/source/libs/xpdf/xpdf-src/xpdf/PDFCore.cc
index b833d5dabf0..baf2353de1c 100644
--- a/Build/source/libs/xpdf/xpdf-src/xpdf/PDFCore.cc
+++ b/Build/source/libs/xpdf/xpdf-src/xpdf/PDFCore.cc
@@ -8,10 +8,6 @@
#include <aconf.h>
-#ifdef USE_GCC_PRAGMAS
-#pragma implementation
-#endif
-
#include <math.h>
#include "gmempp.h"
#include "GString.h"
@@ -47,9 +43,6 @@ PDFCore::PDFCore(SplashColorMode colorMode, int bitmapRowPad,
linksPage = 0;
links = NULL;
- annotsPage = 0;
- annots = NULL;
-
textPage = 0;
textDPI = 0;
textRotate = 0;
@@ -116,6 +109,7 @@ PDFCore::~PDFCore() {
delete state;
clearPage();
if (doc) {
+ aboutToDeleteDoc();
delete doc;
}
for (i = 0; i < pdfHistorySize; ++i) {
@@ -201,6 +195,7 @@ int PDFCore::loadFile2(PDFDoc *newDoc) {
// NB: do not delete doc until after DisplayState::setDoc() returns
state->setDoc(newDoc);
if (doc) {
+ aboutToDeleteDoc();
delete doc;
}
doc = newDoc;
@@ -219,6 +214,7 @@ void PDFCore::clear() {
// no document
// NB: do not delete doc until after DisplayState::setDoc() returns
state->setDoc(NULL);
+ aboutToDeleteDoc();
delete doc;
doc = NULL;
clearPage();
@@ -300,6 +296,8 @@ void PDFCore::displayDest(LinkDest *dest) {
page = 1;
}
+ GBool changeZoom = globalParams->getAllowLinksToChangeZoom();
+
switch (dest->getKind()) {
case destXYZ:
cvtUserToDev(page, dest->getLeft(), dest->getTop(), &dx, &dy);
@@ -317,7 +315,9 @@ void PDFCore::displayDest(LinkDest *dest) {
break;
case destFit:
case destFitB:
- state->setZoom(zoomPage);
+ if (changeZoom) {
+ state->setZoom(zoomPage);
+ }
scrollX = tileMap->getPageLeftX(page);
scrollY = tileMap->getPageTopY(page);
startUpdate();
@@ -326,7 +326,9 @@ void PDFCore::displayDest(LinkDest *dest) {
break;
case destFitH:
case destFitBH:
- state->setZoom(zoomWidth);
+ if (changeZoom) {
+ state->setZoom(zoomWidth);
+ }
scrollX = tileMap->getPageLeftX(page);
scrollY = tileMap->getPageTopY(page);
if (dest->getChangeTop()) {
@@ -339,7 +341,9 @@ void PDFCore::displayDest(LinkDest *dest) {
break;
case destFitV:
case destFitBV:
- state->setZoom(zoomHeight);
+ if (changeZoom) {
+ state->setZoom(zoomHeight);
+ }
scrollX = tileMap->getPageLeftX(page);
scrollY = tileMap->getPageTopY(page);
if (dest->getChangeTop()) {
@@ -351,8 +355,13 @@ void PDFCore::displayDest(LinkDest *dest) {
finishUpdate(gTrue, gTrue);
break;
case destFitR:
- zoomToRect(page, dest->getLeft(), dest->getTop(),
- dest->getRight(), dest->getBottom());
+ if (changeZoom) {
+ zoomToRect(page, dest->getLeft(), dest->getTop(),
+ dest->getRight(), dest->getBottom());
+ } else {
+ scrollToCentered(page, 0.5 * (dest->getLeft() + dest->getRight()),
+ 0.5 * (dest->getTop(), dest->getBottom()));
+ }
break;
}
}
@@ -426,9 +435,16 @@ void PDFCore::finishUpdate(GBool addToHist, GBool checkForChangedFile) {
// tileDone or tick (incremental update) to avoid "flashing" the
// screen (drawing a blank background, followed by the actual
// content slightly later)
- getWindowBitmap(gTrue);
- if (bitmapFinished) {
+ // - this postponement actually causes flickering in certain cases
+ // (the Qt QML backend) -- don't do it if alwaysInvalidateOnUpdate()
+ // returns true
+ if (alwaysInvalidateOnUpdate()) {
invalidateWholeWindow();
+ } else {
+ getWindowBitmap(gTrue);
+ if (bitmapFinished) {
+ invalidateWholeWindow();
+ }
}
updateScrollbars();
@@ -1637,6 +1653,50 @@ GList *PDFCore::findAll(Unicode *u, int len, GBool caseSensitive,
return results;
}
+GList *AsyncFindAll::run(PDFDoc *doc, Unicode *u, int len, GBool caseSensitive,
+ GBool wholeWord, int firstPage, int lastPage) {
+ GList *results = new GList();
+
+ TextOutputDev *textOut = new TextOutputDev(NULL, &core->textOutCtrl, gFalse);
+ if (!textOut->isOk()) {
+ delete textOut;
+ return results;
+ }
+
+ for (int pg = firstPage; pg <= lastPage && !canceled; ++pg) {
+ doc->displayPage(textOut, pg, 72, 72, 0, gFalse, gTrue, gFalse);
+ GBool first = gTrue;
+ while (!canceled) {
+ double xMin, yMin, xMax, yMax;
+ if (!textOut->findText(u, len, first, gTrue, !first, gFalse,
+ caseSensitive, gFalse, wholeWord,
+ &xMin, &yMin, &xMax, &yMax)) {
+ break;
+ }
+ double uxMin, uyMin, uxMax, uyMax, t;
+ textOut->cvtDevToUser(xMin, yMin, &uxMin, &uyMin);
+ textOut->cvtDevToUser(xMax, yMax, &uxMax, &uyMax);
+ if (uxMin > uxMax) {
+ t = uxMin; uxMin = uxMax; uxMax = t;
+ }
+ if (uyMin > uyMax) {
+ t = uyMin; uyMin = uyMax; uyMax = t;
+ }
+ results->append(new FindResult(pg, uxMin, uyMin, uxMax, uyMax));
+ first = gFalse;
+ }
+ }
+
+ delete textOut;
+
+ if (canceled) {
+ deleteGList(results, FindResult);
+ return NULL;
+ }
+
+ return results;
+}
+
GBool PDFCore::cvtWindowToUser(int xw, int yw,
int *pg, double *xu, double *yu) {
@@ -1751,23 +1811,11 @@ LinkAction *PDFCore::findLink(int pg, double x, double y) {
}
Annot *PDFCore::findAnnot(int pg, double x, double y) {
- loadAnnots(pg);
- return annots->find(x, y);
+ return doc->getAnnots()->find(pg, x, y);
}
int PDFCore::findAnnotIdx(int pg, double x, double y) {
- loadAnnots(pg);
- return annots->findIdx(x, y);
-}
-
-Annot *PDFCore::getAnnot(int idx) {
- if (!annots) {
- return NULL;
- }
- if (idx < 0 || idx >= annots->getNumAnnots()) {
- return NULL;
- }
- return annots->getAnnot(idx);
+ return doc->getAnnots()->findIdx(pg, x, y);
}
AcroFormField *PDFCore::findFormField(int pg, double x, double y) {
@@ -1816,7 +1864,8 @@ void PDFCore::setWindowSize(int winWidth, int winHeight) {
startUpdate();
- wx0 = wy0 = 0; // make gcc happy
+ page = wx0 = wy0 = 0; // make gcc happy
+ ux = uy = 0;
doScroll = gFalse;
if (state->getZoom() < 0 && state->displayModeIsContinuous()) {
// save the user coordinates of the appropriate edge of the window
@@ -1879,12 +1928,6 @@ void PDFCore::clearPage() {
links = NULL;
linksPage = 0;
- if (annots) {
- delete annots;
- }
- annots = NULL;
- annotsPage = 0;
-
if (text) {
delete text;
}
@@ -1906,22 +1949,6 @@ void PDFCore::loadLinks(int pg) {
linksPage = pg;
}
-// Load the annotations for <pg>.
-void PDFCore::loadAnnots(int pg) {
- Object annotsObj;
-
- if (annots && annotsPage == pg) {
- return;
- }
- if (annots) {
- delete annots;
- }
- doc->getCatalog()->getPage(pg)->getAnnots(&annotsObj);
- annots = new Annots(doc, &annotsObj);
- annotsObj.free();
- annotsPage = pg;
-}
-
// Extract text from <pg>.
void PDFCore::loadText(int pg) {
TextOutputDev *textOut;
diff --git a/Build/source/libs/xpdf/xpdf-src/xpdf/PDFCore.h b/Build/source/libs/xpdf/xpdf-src/xpdf/PDFCore.h
index accf19d82ef..56ecd958c21 100644
--- a/Build/source/libs/xpdf/xpdf-src/xpdf/PDFCore.h
+++ b/Build/source/libs/xpdf/xpdf-src/xpdf/PDFCore.h
@@ -11,11 +11,10 @@
#include <aconf.h>
-#ifdef USE_GCC_PRAGMAS
-#pragma interface
-#endif
-
#include <stdlib.h>
+#ifndef PDF_PARSER_ONLY
+#include <atomic>
+#endif
#include "SplashTypes.h"
#include "CharTypes.h"
#include "DisplayState.h"
@@ -31,7 +30,6 @@ class Links;
class LinkDest;
class LinkAction;
class Annot;
-class Annots;
class AcroFormField;
class TextPage;
class HighlightFile;
@@ -77,6 +75,34 @@ struct FindResult {
};
//------------------------------------------------------------------------
+// AsyncFindAll
+//------------------------------------------------------------------------
+#ifndef PDF_PARSER_ONLY
+class AsyncFindAll {
+public:
+
+ AsyncFindAll(PDFCore *coreA): core(coreA), canceled(gFalse) {}
+
+ void reset() { canceled = false; }
+
+ // Run the search, returning a list of FindResults -- same as
+ // PDFCore::findAll(). This can be run on a separate thread. If
+ // cancel() is called while the search is running, this function
+ // returns null.
+ GList *run(PDFDoc *doc, Unicode *u, int len, GBool caseSensitive,
+ GBool wholeWord, int firstPage, int lastPage);
+
+ // Cancel a running search, causing run() to return null.
+ void cancel() { canceled = true; }
+
+private:
+
+ PDFCore *core;
+ std::atomic<bool> canceled;
+};
+#endif
+
+//------------------------------------------------------------------------
// PDFCore
//------------------------------------------------------------------------
@@ -256,7 +282,6 @@ public:
LinkAction *findLink(int pg, double x, double y);
Annot *findAnnot(int pg, double x, double y);
int findAnnotIdx(int pg, double x, double y);
- Annot *getAnnot(int idx);
AcroFormField *findFormField(int pg, double x, double y);
int findFormFieldIdx(int pg, double x, double y);
AcroFormField *getFormField(int idx);
@@ -288,6 +313,11 @@ protected:
//--- callbacks to PDFCore subclass
+ // Subclasses can return true here to force PDFCore::finishUpdate()
+ // to always invalidate the window. This is necessary to avoid
+ // flickering on some backends.
+ virtual GBool alwaysInvalidateOnUpdate() { return gFalse; }
+
// Invalidate the specified rectangle (in window coordinates).
virtual void invalidate(int x, int y, int w, int h) = 0;
@@ -304,13 +334,17 @@ protected:
// This is called just after a PDF file is loaded.
virtual void postLoad() {}
+ // This is called just before deleting the PDFDoc. The PDFCore
+ // subclass must shut down any secondary threads that are using the
+ // PDFDoc pointer.
+ virtual void aboutToDeleteDoc() {}
+
//--- internal
int loadFile2(PDFDoc *newDoc);
void addToHistory();
void clearPage();
void loadLinks(int pg);
- void loadAnnots(int pg);
void loadText(int pg);
void getSelectionBBox(int *wxMin, int *wyMin, int *wxMax, int *wyMax);
void getSelectRectListBBox(GList *rects, int *wxMin, int *wyMin,
@@ -318,14 +352,13 @@ protected:
void checkInvalidate(int x, int y, int w, int h);
void invalidateWholeWindow();
+ friend class AsyncFindAll;
+
PDFDoc *doc;
int linksPage; // cached links for one page
Links *links;
- int annotsPage; // cached annotations for one page
- Annots *annots;
-
int textPage; // cached extracted text for one page
double textDPI;
int textRotate;
diff --git a/Build/source/libs/xpdf/xpdf-src/xpdf/PDFDoc.cc b/Build/source/libs/xpdf/xpdf-src/xpdf/PDFDoc.cc
index a6663ea4222..7030904214f 100644
--- a/Build/source/libs/xpdf/xpdf-src/xpdf/PDFDoc.cc
+++ b/Build/source/libs/xpdf/xpdf-src/xpdf/PDFDoc.cc
@@ -8,10 +8,6 @@
#include <aconf.h>
-#ifdef USE_GCC_PRAGMAS
-#pragma implementation
-#endif
-
#include <stdio.h>
#include <stdlib.h>
#include <stddef.h>
@@ -26,6 +22,7 @@
#include "GlobalParams.h"
#include "Page.h"
#include "Catalog.h"
+#include "Annot.h"
#include "Stream.h"
#include "XRef.h"
#include "Link.h"
@@ -178,6 +175,7 @@ PDFDoc::PDFDoc(char *fileNameA, GString *ownerPassword,
int i, j;
#endif
#endif /* 0 */
+
init(coreA);
fileName = new GString(fileNameA);
@@ -204,7 +202,7 @@ PDFDoc::PDFDoc(char *fileNameA, GString *ownerPassword,
file = _wfopen(fileNameU, wfopenReadMode);
} else {
#endif /* 0 */
- file = fopen(fileName->getCString(), fopenReadMode);
+ file = fopen(fileName->getCString(), fopenReadMode);
#if 0
}
#endif /* 0 */
@@ -263,6 +261,7 @@ void PDFDoc::init(PDFCore *coreA) {
str = NULL;
xref = NULL;
catalog = NULL;
+ annots = NULL;
#ifndef DISABLE_OUTLINE
outline = NULL;
#endif
@@ -335,6 +334,9 @@ GBool PDFDoc::setup2(GString *ownerPassword, GString *userPassword,
return gFalse;
}
+ // initialize the Annots object
+ annots = new Annots(this);
+
return gTrue;
}
@@ -347,6 +349,9 @@ PDFDoc::~PDFDoc() {
delete outline;
}
#endif
+ if (annots) {
+ delete annots;
+ }
if (catalog) {
delete catalog;
}
@@ -485,6 +490,7 @@ void PDFDoc::displayPageSlice(OutputDev *out, int page,
abortCheckCbk, abortCheckCbkData);
}
+
Links *PDFDoc::getLinks(int page) {
return catalog->getPage(page)->getLinks();
}
diff --git a/Build/source/libs/xpdf/xpdf-src/xpdf/PDFDoc.h b/Build/source/libs/xpdf/xpdf-src/xpdf/PDFDoc.h
index 2b8eba2cba7..3c1c71c41ed 100644
--- a/Build/source/libs/xpdf/xpdf-src/xpdf/PDFDoc.h
+++ b/Build/source/libs/xpdf/xpdf-src/xpdf/PDFDoc.h
@@ -11,10 +11,6 @@
#include <aconf.h>
-#ifdef USE_GCC_PRAGMAS
-#pragma interface
-#endif
-
#include <stdio.h>
#include "XRef.h"
#include "Catalog.h"
@@ -23,6 +19,7 @@
class GString;
class BaseStream;
class OutputDev;
+class Annots;
class Links;
class LinkAction;
class LinkDest;
@@ -74,6 +71,9 @@ public:
// Get catalog.
Catalog *getCatalog() { return catalog; }
+ // Get annotations.
+ Annots *getAnnots() { return annots; }
+
// Get base stream.
BaseStream *getBaseStream() { return str; }
@@ -121,6 +121,7 @@ public:
GBool (*abortCheckCbk)(void *data) = NULL,
void *abortCheckCbkData = NULL);
+
// Find a page, given its object ID. Returns page number, or 0 if
// not found.
int findPage(int num, int gen) { return catalog->findPage(num, gen); }
@@ -195,6 +196,9 @@ public:
#endif
char *getEmbeddedFileMem(int idx, int *size);
+ // Return true if the document uses JavaScript.
+ GBool usesJavaScript() { return catalog->usesJavaScript(); }
+
private:
@@ -216,6 +220,7 @@ private:
double pdfVersion;
XRef *xref;
Catalog *catalog;
+ Annots *annots;
#ifndef DISABLE_OUTLINE
Outline *outline;
#endif
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() &&
diff --git a/Build/source/libs/xpdf/xpdf-src/xpdf/PSOutputDev.h b/Build/source/libs/xpdf/xpdf-src/xpdf/PSOutputDev.h
index b7223c6cdd8..95908dbe675 100644
--- a/Build/source/libs/xpdf/xpdf-src/xpdf/PSOutputDev.h
+++ b/Build/source/libs/xpdf/xpdf-src/xpdf/PSOutputDev.h
@@ -11,10 +11,6 @@
#include <aconf.h>
-#ifdef USE_GCC_PRAGMAS
-#pragma interface
-#endif
-
#include <stddef.h>
#include "config.h"
#include "Object.h"
@@ -199,8 +195,6 @@ public:
virtual void updateHorizScaling(GfxState *state);
virtual void updateTextPos(GfxState *state);
virtual void updateTextShift(GfxState *state, double shift);
- virtual void saveTextPos(GfxState *state);
- virtual void restoreTextPos(GfxState *state);
//----- path painting
virtual void stroke(GfxState *state);
@@ -219,7 +213,15 @@ public:
virtual void clipToStrokePath(GfxState *state);
//----- text drawing
- virtual void drawString(GfxState *state, GString *s);
+ virtual void drawString(GfxState *state, GString *s,
+ GBool fill, GBool stroke, GBool makePath);
+ virtual void fillTextPath(GfxState *state);
+ virtual void strokeTextPath(GfxState *state);
+ virtual void clipToTextPath(GfxState *state);
+ virtual void clipToTextStrokePath(GfxState *state);
+ virtual void clearTextPath(GfxState *state);
+ virtual void addTextPathToSavedClipPath(GfxState *state);
+ virtual void clipToSavedClipPath(GfxState *state);
virtual void endTextObject(GfxState *state);
//----- image drawing
@@ -295,6 +297,8 @@ private:
PSFontFileInfo *setupExternalType1Font(GfxFont *font, GString *fileName);
PSFontFileInfo *setupEmbeddedType1CFont(GfxFont *font, Ref *id);
PSFontFileInfo *setupEmbeddedOpenTypeT1CFont(GfxFont *font, Ref *id);
+ PSFontFileInfo *setupExternalOpenTypeT1CFont(GfxFont *font,
+ GString *fileName);
PSFontFileInfo *setupEmbeddedTrueTypeFont(GfxFont *font, Ref *id);
PSFontFileInfo *setupExternalTrueTypeFont(GfxFont *font, GString *fileName,
int fontNum);
@@ -489,8 +493,11 @@ private:
PSOutCustomColor // used custom colors
*customColors;
- GBool haveTextClip; // set if text has been drawn with a
- // clipping render mode
+ GBool haveSavedTextPath; // set if text has been drawn with the
+ // 'makePath' argument
+ GBool haveSavedClipPath; // set if the text path has been added
+ // to the saved clipping path (with
+ // addTextPathToSavedClipPath)
GBool inType3Char; // inside a Type 3 CharProc
GString *t3String; // Type 3 content string
diff --git a/Build/source/libs/xpdf/xpdf-src/xpdf/PSTokenizer.cc b/Build/source/libs/xpdf/xpdf-src/xpdf/PSTokenizer.cc
index bbdb0ec44d5..cb525f1be60 100644
--- a/Build/source/libs/xpdf/xpdf-src/xpdf/PSTokenizer.cc
+++ b/Build/source/libs/xpdf/xpdf-src/xpdf/PSTokenizer.cc
@@ -8,10 +8,6 @@
#include <aconf.h>
-#ifdef USE_GCC_PRAGMAS
-#pragma implementation
-#endif
-
#include <stdio.h>
#include <stdlib.h>
#include "gmempp.h"
diff --git a/Build/source/libs/xpdf/xpdf-src/xpdf/PSTokenizer.h b/Build/source/libs/xpdf/xpdf-src/xpdf/PSTokenizer.h
index 4d5ee97f4dd..3f3c8f4066d 100644
--- a/Build/source/libs/xpdf/xpdf-src/xpdf/PSTokenizer.h
+++ b/Build/source/libs/xpdf/xpdf-src/xpdf/PSTokenizer.h
@@ -11,10 +11,6 @@
#include <aconf.h>
-#ifdef USE_GCC_PRAGMAS
-#pragma interface
-#endif
-
#include "gtypes.h"
//------------------------------------------------------------------------
diff --git a/Build/source/libs/xpdf/xpdf-src/xpdf/Page.cc b/Build/source/libs/xpdf/xpdf-src/xpdf/Page.cc
index 368bc68dd8a..322f07063e7 100644
--- a/Build/source/libs/xpdf/xpdf-src/xpdf/Page.cc
+++ b/Build/source/libs/xpdf/xpdf-src/xpdf/Page.cc
@@ -8,10 +8,6 @@
#include <aconf.h>
-#ifdef USE_GCC_PRAGMAS
-#pragma implementation
-#endif
-
#include <stddef.h>
#include "gmempp.h"
#include "Trace.h"
@@ -381,7 +377,6 @@ void Page::displaySlice(OutputDev *out, double hDPI, double vDPI,
PDFRectangle box;
Gfx *gfx;
Object obj;
- Annots *annotList;
AcroForm *form;
int i;
@@ -426,21 +421,20 @@ void Page::displaySlice(OutputDev *out, double hDPI, double vDPI,
// draw (non-form) annotations
if (globalParams->getDrawAnnotations()) {
- annotList = new Annots(doc, getAnnots(&obj));
- obj.free();
- annotList->generateAnnotAppearances();
- if (annotList->getNumAnnots() > 0) {
+ Annots *annots2 = doc->getAnnots();
+ annots2->generateAnnotAppearances(num);
+ int n = annots2->getNumAnnots(num);
+ if (n > 0) {
if (globalParams->getPrintCommands()) {
printf("***** Annotations\n");
}
- for (i = 0; i < annotList->getNumAnnots(); ++i) {
+ for (i = 0; i < n; ++i) {
if (abortCheckCbk && (*abortCheckCbk)(abortCheckCbkData)) {
break;
}
- annotList->getAnnot(i)->draw(gfx, printing);
+ annots2->getAnnot(num, i)->draw(gfx, printing);
}
}
- delete annotList;
}
// draw form fields
@@ -552,3 +546,4 @@ void Page::getDefaultCTM(double *ctm, double hDPI, double vDPI,
delete state;
#endif
}
+
diff --git a/Build/source/libs/xpdf/xpdf-src/xpdf/Page.h b/Build/source/libs/xpdf/xpdf-src/xpdf/Page.h
index fe579e7b3af..0a862265d0f 100644
--- a/Build/source/libs/xpdf/xpdf-src/xpdf/Page.h
+++ b/Build/source/libs/xpdf/xpdf-src/xpdf/Page.h
@@ -11,10 +11,6 @@
#include <aconf.h>
-#ifdef USE_GCC_PRAGMAS
-#pragma interface
-#endif
-
#include "Object.h"
class Dict;
@@ -192,6 +188,7 @@ public:
void getDefaultCTM(double *ctm, double hDPI, double vDPI,
int rotate, GBool useMediaBox, GBool upsideDown);
+
private:
PDFDoc *doc;
diff --git a/Build/source/libs/xpdf/xpdf-src/xpdf/Parser.cc b/Build/source/libs/xpdf/xpdf-src/xpdf/Parser.cc
index 4fad6afae13..c594cf9413b 100644
--- a/Build/source/libs/xpdf/xpdf-src/xpdf/Parser.cc
+++ b/Build/source/libs/xpdf/xpdf-src/xpdf/Parser.cc
@@ -8,10 +8,6 @@
#include <aconf.h>
-#ifdef USE_GCC_PRAGMAS
-#pragma implementation
-#endif
-
#include <stddef.h>
#include <string.h>
#include "gmempp.h"
diff --git a/Build/source/libs/xpdf/xpdf-src/xpdf/Parser.h b/Build/source/libs/xpdf/xpdf-src/xpdf/Parser.h
index bfe5a52bdfc..6e175eb1cea 100644
--- a/Build/source/libs/xpdf/xpdf-src/xpdf/Parser.h
+++ b/Build/source/libs/xpdf/xpdf-src/xpdf/Parser.h
@@ -11,10 +11,6 @@
#include <aconf.h>
-#ifdef USE_GCC_PRAGMAS
-#pragma interface
-#endif
-
#include "Lexer.h"
//------------------------------------------------------------------------
diff --git a/Build/source/libs/xpdf/xpdf-src/xpdf/PreScanOutputDev.cc b/Build/source/libs/xpdf/xpdf-src/xpdf/PreScanOutputDev.cc
index 29f26c00cee..e844e49142f 100644
--- a/Build/source/libs/xpdf/xpdf-src/xpdf/PreScanOutputDev.cc
+++ b/Build/source/libs/xpdf/xpdf-src/xpdf/PreScanOutputDev.cc
@@ -8,10 +8,6 @@
#include <aconf.h>
-#ifdef USE_GCC_PRAGMAS
-#pragma implementation
-#endif
-
#include <math.h>
#include "gmempp.h"
#include "GlobalParams.h"
diff --git a/Build/source/libs/xpdf/xpdf-src/xpdf/PreScanOutputDev.h b/Build/source/libs/xpdf/xpdf-src/xpdf/PreScanOutputDev.h
index ee21e98b148..703026ba19f 100644
--- a/Build/source/libs/xpdf/xpdf-src/xpdf/PreScanOutputDev.h
+++ b/Build/source/libs/xpdf/xpdf-src/xpdf/PreScanOutputDev.h
@@ -11,10 +11,6 @@
#include <aconf.h>
-#ifdef USE_GCC_PRAGMAS
-#pragma interface
-#endif
-
#include "gtypes.h"
#include "GfxState.h"
#include "OutputDev.h"
diff --git a/Build/source/libs/xpdf/xpdf-src/xpdf/SecurityHandler.cc b/Build/source/libs/xpdf/xpdf-src/xpdf/SecurityHandler.cc
index a61a84e8fa2..6f614496859 100644
--- a/Build/source/libs/xpdf/xpdf-src/xpdf/SecurityHandler.cc
+++ b/Build/source/libs/xpdf/xpdf-src/xpdf/SecurityHandler.cc
@@ -8,10 +8,6 @@
#include <aconf.h>
-#ifdef USE_GCC_PRAGMAS
-#pragma implementation
-#endif
-
#include "gmempp.h"
#include "GString.h"
#include "PDFDoc.h"
diff --git a/Build/source/libs/xpdf/xpdf-src/xpdf/SecurityHandler.h b/Build/source/libs/xpdf/xpdf-src/xpdf/SecurityHandler.h
index 63462339bff..05e58cf64c3 100644
--- a/Build/source/libs/xpdf/xpdf-src/xpdf/SecurityHandler.h
+++ b/Build/source/libs/xpdf/xpdf-src/xpdf/SecurityHandler.h
@@ -11,10 +11,6 @@
#include <aconf.h>
-#ifdef USE_GCC_PRAGMAS
-#pragma interface
-#endif
-
#include "gtypes.h"
#include "Object.h"
diff --git a/Build/source/libs/xpdf/xpdf-src/xpdf/ShadingImage.cc b/Build/source/libs/xpdf/xpdf-src/xpdf/ShadingImage.cc
index d8dc24e0fc6..b40c05d52e1 100644
--- a/Build/source/libs/xpdf/xpdf-src/xpdf/ShadingImage.cc
+++ b/Build/source/libs/xpdf/xpdf-src/xpdf/ShadingImage.cc
@@ -8,10 +8,6 @@
#include <aconf.h>
-#ifdef USE_GCC_PRAGMAS
-#pragma implementation
-#endif
-
#include <math.h>
#include "Trace.h"
#include "GfxState.h"
@@ -70,6 +66,14 @@ SplashBitmap *ShadingImage::generateBitmap(GfxState *state,
}
}
+static double max4(double x0, double x1, double x2, double x3) {
+ double t = x0;
+ t = (x1 > t) ? x1 : t;
+ t = (x2 > t) ? x2 : t;
+ t = (x3 > t) ? x3 : t;
+ return t;
+}
+
SplashBitmap *ShadingImage::generateFunctionBitmap(GfxState *state,
GfxFunctionShading *shading,
SplashColorMode mode,
@@ -204,7 +208,8 @@ SplashBitmap *ShadingImage::generateAxialBitmap(GfxState *state,
// compute the inverse CTM
double *ctm = state->getCTM();
double det = ctm[0] * ctm[3] - ctm[1] * ctm[2];
- if (fabs(det) < 0.000001) {
+ if (fabs(det) < 1e-10 * max4(fabs(ctm[0]), fabs(ctm[1]),
+ fabs(ctm[2]), fabs(ctm[3]))) {
return NULL;
}
det = 1 / det;
@@ -468,7 +473,8 @@ SplashBitmap *ShadingImage::generateRadialBitmap(GfxState *state,
// compute the inverse CTM
double *ctm = state->getCTM();
double det = ctm[0] * ctm[3] - ctm[1] * ctm[2];
- if (fabs(det) < 0.000001) {
+ if (fabs(det) < 1e-10 * max4(fabs(ctm[0]), fabs(ctm[1]),
+ fabs(ctm[2]), fabs(ctm[3]))) {
return NULL;
}
det = 1 / det;
diff --git a/Build/source/libs/xpdf/xpdf-src/xpdf/ShadingImage.h b/Build/source/libs/xpdf/xpdf-src/xpdf/ShadingImage.h
index 3bbff6922a4..54f193a9c89 100644
--- a/Build/source/libs/xpdf/xpdf-src/xpdf/ShadingImage.h
+++ b/Build/source/libs/xpdf/xpdf-src/xpdf/ShadingImage.h
@@ -13,10 +13,6 @@
#include <aconf.h>
-#ifdef USE_GCC_PRAGMAS
-#pragma interface
-#endif
-
#include "SplashTypes.h"
class GfxState;
diff --git a/Build/source/libs/xpdf/xpdf-src/xpdf/SplashOutputDev.cc b/Build/source/libs/xpdf/xpdf-src/xpdf/SplashOutputDev.cc
index d758e25b306..581b804f3b0 100644
--- a/Build/source/libs/xpdf/xpdf-src/xpdf/SplashOutputDev.cc
+++ b/Build/source/libs/xpdf/xpdf-src/xpdf/SplashOutputDev.cc
@@ -8,10 +8,6 @@
#include <aconf.h>
-#ifdef USE_GCC_PRAGMAS
-#pragma implementation
-#endif
-
#include <string.h>
#include <math.h>
#include <limits.h>
@@ -598,6 +594,8 @@ struct SplashTransparencyGroup {
SplashBitmap *tBitmap; // bitmap for transparency group
GfxColorSpace *blendingColorSpace;
GBool isolated;
+ GBool inSoftMask; // true if this, or any containing
+ // group, is a soft mask
//----- modified region in tBitmap
int modXMin, modYMin, modXMax, modYMax;
@@ -654,7 +652,8 @@ SplashOutputDev::SplashOutputDev(SplashColorMode colorModeA,
font = NULL;
needFontUpdate = gFalse;
- textClipPath = NULL;
+ savedTextPath = NULL;
+ savedClipPath = NULL;
transpGroupStack = NULL;
@@ -731,8 +730,11 @@ SplashOutputDev::~SplashOutputDev() {
if (bitmap) {
delete bitmap;
}
- if (textClipPath) {
- delete textClipPath;
+ if (savedTextPath) {
+ delete savedTextPath;
+ }
+ if (savedClipPath) {
+ delete savedClipPath;
}
}
@@ -1074,7 +1076,10 @@ void SplashOutputDev::setOverprintMask(GfxState *state,
Guint mask;
GfxCMYK cmyk;
- if (overprintFlag && globalParams->getOverprintPreview()) {
+ // Adobe ignores overprint in soft masks.
+ if (overprintFlag &&
+ !(transpGroupStack && transpGroupStack->inSoftMask) &&
+ globalParams->getOverprintPreview()) {
mask = colorSpace->getOverprintMask();
// The OPM (overprintMode) setting is only relevant when the color
// space is DeviceCMYK or is "implicitly converted to DeviceCMYK".
@@ -2218,27 +2223,24 @@ void SplashOutputDev::drawChar(GfxState *state, double x, double y,
double dx, double dy,
double originX, double originY,
CharCode code, int nBytes,
- Unicode *u, int uLen) {
- SplashPath *path;
- int render;
- GBool doFill, doStroke, doClip;
- SplashStrokeAdjustMode strokeAdjust;
- double m[4];
- GBool horiz;
-
+ Unicode *u, int uLen,
+ GBool fill, GBool stroke, GBool makePath) {
if (skipHorizText || skipRotatedText) {
+ double m[4];
state->getFontTransMat(&m[0], &m[1], &m[2], &m[3]);
// this matches the 'diagonal' test in TextPage::updateFont()
- horiz = m[0] > 0 && fabs(m[1]) < 0.001 &&
- fabs(m[2]) < 0.001 && m[3] < 0;
+ GBool horiz = m[0] > 0 && fabs(m[1]) < 0.001 &&
+ fabs(m[2]) < 0.001 && m[3] < 0;
if ((skipHorizText && horiz) || (skipRotatedText && !horiz)) {
return;
}
}
+ fill = fill && !state->getFillColorSpace()->isNonMarking();
+ stroke = stroke && !state->getStrokeColorSpace()->isNonMarking();
+
// check for invisible text -- this is used by Acrobat Capture
- render = state->getRender();
- if (render == 3) {
+ if (!fill && !stroke && !makePath) {
return;
}
@@ -2252,13 +2254,8 @@ void SplashOutputDev::drawChar(GfxState *state, double x, double y,
x -= originX;
y -= originY;
- doFill = !(render & 1) && !state->getFillColorSpace()->isNonMarking();
- doStroke = ((render & 3) == 1 || (render & 3) == 2) &&
- !state->getStrokeColorSpace()->isNonMarking();
- doClip = render & 4;
-
- path = NULL;
- if (doStroke || doClip) {
+ SplashPath *path = NULL;
+ if (stroke || makePath) {
if ((path = font->getGlyphPath(code))) {
path->offset((SplashCoord)x, (SplashCoord)y);
}
@@ -2267,14 +2264,19 @@ void SplashOutputDev::drawChar(GfxState *state, double x, double y,
// don't use stroke adjustment when stroking text -- the results
// tend to be ugly (because characters with horizontal upper or
// lower edges get misaligned relative to the other characters)
- strokeAdjust = splashStrokeAdjustOff; // make gcc happy
- if (doStroke) {
- strokeAdjust = splash->getStrokeAdjust();
+ SplashStrokeAdjustMode savedStrokeAdjust = splashStrokeAdjustOff;
+ if (stroke) {
+ savedStrokeAdjust = splash->getStrokeAdjust();
splash->setStrokeAdjust(splashStrokeAdjustOff);
}
- // fill and stroke
- if (doFill && doStroke) {
+ // the possible operations are:
+ // - fill
+ // - stroke
+ // - fill + stroke
+ // - makePath
+
+ if (fill && stroke) {
if (path) {
setOverprintMask(state, state->getFillColorSpace(),
state->getFillOverprint(), state->getOverprintMode(),
@@ -2286,37 +2288,33 @@ void SplashOutputDev::drawChar(GfxState *state, double x, double y,
splash->stroke(path);
}
- // fill
- } else if (doFill) {
+ } else if (fill) {
setOverprintMask(state, state->getFillColorSpace(),
state->getFillOverprint(), state->getOverprintMode(),
state->getFillColor());
splash->fillChar((SplashCoord)x, (SplashCoord)y, code, font);
- // stroke
- } else if (doStroke) {
+ } else if (stroke) {
if (path) {
setOverprintMask(state, state->getStrokeColorSpace(),
state->getStrokeOverprint(), state->getOverprintMode(),
state->getStrokeColor());
splash->stroke(path);
}
- }
- // clip
- if (doClip) {
+ } else if (makePath) {
if (path) {
- if (textClipPath) {
- textClipPath->append(path);
+ if (savedTextPath) {
+ savedTextPath->append(path);
} else {
- textClipPath = path;
+ savedTextPath = path;
path = NULL;
}
}
}
- if (doStroke) {
- splash->setStrokeAdjust(strokeAdjust);
+ if (stroke) {
+ splash->setStrokeAdjust(savedStrokeAdjust);
}
if (path) {
@@ -2324,6 +2322,73 @@ void SplashOutputDev::drawChar(GfxState *state, double x, double y,
}
}
+void SplashOutputDev::fillTextPath(GfxState *state) {
+ if (!savedTextPath) {
+ return;
+ }
+ setOverprintMask(state, state->getFillColorSpace(),
+ state->getFillOverprint(), state->getOverprintMode(),
+ state->getFillColor());
+ splash->fill(savedTextPath, gFalse);
+}
+
+void SplashOutputDev::strokeTextPath(GfxState *state) {
+ if (!savedTextPath) {
+ return;
+ }
+ setOverprintMask(state, state->getStrokeColorSpace(),
+ state->getStrokeOverprint(), state->getOverprintMode(),
+ state->getStrokeColor());
+ splash->stroke(savedTextPath);
+}
+
+void SplashOutputDev::clipToTextPath(GfxState *state) {
+ if (!savedTextPath) {
+ return;
+ }
+ splash->clipToPath(savedTextPath, gFalse);
+}
+
+void SplashOutputDev::clipToTextStrokePath(GfxState *state) {
+ if (!savedTextPath) {
+ return;
+ }
+ SplashPath *path = splash->makeStrokePath(savedTextPath,
+ state->getLineWidth(),
+ state->getLineCap(),
+ state->getLineJoin());
+ splash->clipToPath(path, gFalse);
+ delete path;
+}
+
+void SplashOutputDev::clearTextPath(GfxState *state) {
+ if (savedTextPath) {
+ delete savedTextPath;
+ savedTextPath = NULL;
+ }
+}
+
+void SplashOutputDev::addTextPathToSavedClipPath(GfxState *state) {
+ if (savedTextPath) {
+ if (savedClipPath) {
+ savedClipPath->append(savedTextPath);
+ delete savedTextPath;
+ } else {
+ savedClipPath = savedTextPath;
+ }
+ savedTextPath = NULL;
+ }
+}
+
+void SplashOutputDev::clipToSavedClipPath(GfxState *state) {
+ if (!savedClipPath) {
+ return;
+ }
+ splash->clipToPath(savedClipPath, gFalse);
+ delete savedClipPath;
+ savedClipPath = NULL;
+}
+
GBool SplashOutputDev::beginType3Char(GfxState *state, double x, double y,
double dx, double dy,
CharCode code, Unicode *u, int uLen) {
@@ -2679,11 +2744,6 @@ void SplashOutputDev::drawType3Glyph(GfxState *state, T3FontCache *t3Font,
}
void SplashOutputDev::endTextObject(GfxState *state) {
- if (textClipPath) {
- splash->clipToPath(textClipPath, gFalse);
- delete textClipPath;
- textClipPath = NULL;
- }
}
struct SplashOutImageMaskData {
@@ -3855,7 +3915,7 @@ GBool SplashOutputDev::beginTransparencyGroup(GfxState *state, double *bbox,
SplashBitmap *backdropBitmap;
SplashColor color;
double xMin, yMin, xMax, yMax, x, y;
- int bw, bh, tx, ty, w, h, i;
+ int bw, bh, tx, ty, w, h, xx, yy, i;
// transform the bbox
state->transform(bbox[0], bbox[1], &x, &y);
@@ -3928,21 +3988,23 @@ GBool SplashOutputDev::beginTransparencyGroup(GfxState *state, double *bbox,
} else if (ty >= bh) {
ty = bh - 1;
}
- w = (int)ceil(xMax) - tx + 1;
- // NB bw and tx are both non-negative, so 'bw - tx' can't overflow
- if (bw - tx < w) {
- w = bw - tx;
- }
- if (w < 1) {
+ xx = (int)ceil(xMax);
+ if (xx < tx) {
w = 1;
+ } else if (xx > bw - 1) {
+ // NB bw and tx are both non-negative, so 'bw - tx' can't overflow
+ w = bw - tx;
+ } else {
+ w = xx - tx + 1;
}
- h = (int)ceil(yMax) - ty + 1;
- // NB bh and ty are both non-negative, so 'bh - ty' can't overflow
- if (bh - ty < h) {
- h = bh - ty;
- }
- if (h < 1) {
+ yy = (int)ceil(yMax);
+ if (yy < ty) {
h = 1;
+ } else if (yy > bh - 1) {
+ // NB bh and ty are both non-negative, so 'bh - ty' can't overflow
+ h = bh - ty;
+ } else {
+ h = yy - ty + 1;
}
// optimization: a non-isolated group drawn with alpha=1 and
@@ -3973,6 +4035,8 @@ GBool SplashOutputDev::beginTransparencyGroup(GfxState *state, double *bbox,
transpGroup->ty = ty;
transpGroup->blendingColorSpace = blendingColorSpace;
transpGroup->isolated = isolated;
+ transpGroup->inSoftMask = (transpGroupStack && transpGroupStack->inSoftMask)
+ || forSoftMask;
transpGroup->next = transpGroupStack;
transpGroupStack = transpGroup;
diff --git a/Build/source/libs/xpdf/xpdf-src/xpdf/SplashOutputDev.h b/Build/source/libs/xpdf/xpdf-src/xpdf/SplashOutputDev.h
index 5ec70e95509..d021d8922b0 100644
--- a/Build/source/libs/xpdf/xpdf-src/xpdf/SplashOutputDev.h
+++ b/Build/source/libs/xpdf/xpdf-src/xpdf/SplashOutputDev.h
@@ -11,10 +11,6 @@
#include <aconf.h>
-#ifdef USE_GCC_PRAGMAS
-#pragma interface
-#endif
-
#include "gtypes.h"
#include "SplashTypes.h"
#include "config.h"
@@ -129,7 +125,15 @@ public:
virtual void drawChar(GfxState *state, double x, double y,
double dx, double dy,
double originX, double originY,
- CharCode code, int nBytes, Unicode *u, int uLen);
+ CharCode code, int nBytes, Unicode *u, int uLen,
+ GBool fill, GBool stroke, GBool makePath);
+ virtual void fillTextPath(GfxState *state);
+ virtual void strokeTextPath(GfxState *state);
+ virtual void clipToTextPath(GfxState *state);
+ virtual void clipToTextStrokePath(GfxState *state);
+ virtual void clearTextPath(GfxState *state);
+ virtual void addTextPathToSavedClipPath(GfxState *state);
+ virtual void clipToSavedClipPath(GfxState *state);
virtual GBool beginType3Char(GfxState *state, double x, double y,
double dx, double dy,
CharCode code, Unicode *u, int uLen);
@@ -306,7 +310,8 @@ private:
SplashFont *font; // current font
GBool needFontUpdate; // set when the font needs to be updated
- SplashPath *textClipPath; // clipping path built with text object
+ SplashPath *savedTextPath; // path built for text string
+ SplashPath *savedClipPath; // clipping path built with text object
SplashTransparencyGroup * // transparency group stack
transpGroupStack;
diff --git a/Build/source/libs/xpdf/xpdf-src/xpdf/Stream.cc b/Build/source/libs/xpdf/xpdf-src/xpdf/Stream.cc
index 383ac5478ff..8387e55d0b0 100644
--- a/Build/source/libs/xpdf/xpdf-src/xpdf/Stream.cc
+++ b/Build/source/libs/xpdf/xpdf-src/xpdf/Stream.cc
@@ -8,10 +8,6 @@
#include <aconf.h>
-#ifdef USE_GCC_PRAGMAS
-#pragma implementation
-#endif
-
#include <stdio.h>
#include <stdlib.h>
#include <stddef.h>
@@ -2673,6 +2669,7 @@ DCTStream::DCTStream(Stream *strA, GBool colorXformA):
frameBuf[i] = NULL;
}
rowBuf = NULL;
+ memset(quantTables, 0, sizeof(quantTables));
memset(dcHuffTables, 0, sizeof(dcHuffTables));
memset(acHuffTables, 0, sizeof(acHuffTables));
@@ -2894,7 +2891,7 @@ void DCTStream::prepare() {
bufWidth = ((width + mcuWidth - 1) / mcuWidth) * mcuWidth;
bufHeight = ((height + mcuHeight - 1) / mcuHeight) * mcuHeight;
if (bufWidth <= 0 || bufHeight <= 0 ||
- bufWidth > INT_MAX / bufWidth / (int)sizeof(int)) {
+ bufWidth > INT_MAX / bufHeight / (int)sizeof(int)) {
error(errSyntaxError, getPos(), "Invalid image size in DCT stream");
y = height;
prepared = gTrue;
@@ -2942,7 +2939,13 @@ void DCTStream::prepare() {
// allocate a buffer for one row of MCUs
bufWidth = ((width + mcuWidth - 1) / mcuWidth) * mcuWidth;
- rowBuf = (Guchar *)gmallocn(numComps * mcuHeight, bufWidth);
+ if (bufWidth <= 0 || bufWidth > INT_MAX / numComps / mcuHeight) {
+ error(errSyntaxError, getPos(), "Invalid image size in DCT stream");
+ y = height;
+ prepared = gTrue;
+ return;
+ }
+ rowBuf = (Guchar *)gmallocn(bufWidth, numComps * mcuHeight);
rowBufPtr = rowBufEnd = rowBuf;
// initialize counters
@@ -3848,11 +3851,12 @@ int DCTStream::readBit() {
}
GBool DCTStream::readHeader(GBool frame) {
- GBool doScan;
+ GBool haveSOF, doScan;
int n, i;
int c = 0;
// read headers
+ haveSOF = gFalse;
doScan = gFalse;
while (!doScan) {
c = readMarker();
@@ -3867,6 +3871,7 @@ GBool DCTStream::readHeader(GBool frame) {
if (!readBaselineSOF()) {
return gFalse;
}
+ haveSOF = gTrue;
break;
case 0xc2: // SOF2 (progressive)
if (!frame) {
@@ -3877,6 +3882,7 @@ GBool DCTStream::readHeader(GBool frame) {
if (!readProgressiveSOF()) {
return gFalse;
}
+ haveSOF = gTrue;
break;
case 0xc4: // DHT
if (!readHuffmanTables()) {
@@ -3893,6 +3899,10 @@ GBool DCTStream::readHeader(GBool frame) {
case 0xd9: // EOI
return gFalse;
case 0xda: // SOS
+ if (frame && !haveSOF) {
+ error(errSyntaxError, getPos(), "Missing SOF in DCT stream");
+ return gFalse;
+ }
if (!readScanInfo()) {
return gFalse;
}
diff --git a/Build/source/libs/xpdf/xpdf-src/xpdf/Stream.h b/Build/source/libs/xpdf/xpdf-src/xpdf/Stream.h
index 9d084c94895..dc850151bc5 100644
--- a/Build/source/libs/xpdf/xpdf-src/xpdf/Stream.h
+++ b/Build/source/libs/xpdf/xpdf-src/xpdf/Stream.h
@@ -11,10 +11,6 @@
#include <aconf.h>
-#ifdef USE_GCC_PRAGMAS
-#pragma interface
-#endif
-
#include <stdio.h>
#if HAVE_JPEGLIB
#include <jpeglib.h>
@@ -130,6 +126,10 @@ public:
// Does this stream type potentially contain non-printable chars?
virtual GBool isBinary(GBool last = gTrue) = 0;
+ // Does this stream include a "strong" compression filter (anything
+ // other than RLE)?
+ virtual GBool hasStrongCompression() { return gFalse; }
+
// Get the BaseStream of this stream.
virtual BaseStream *getBaseStream() = 0;
@@ -490,6 +490,7 @@ public:
virtual GString *getPSFilter(int psLevel, const char *indent,
GBool okToReadStream);
virtual GBool isBinary(GBool last = gTrue);
+ virtual GBool hasStrongCompression() { return gTrue; }
private:
@@ -573,6 +574,7 @@ public:
virtual GString *getPSFilter(int psLevel, const char *indent,
GBool okToReadStream);
virtual GBool isBinary(GBool last = gTrue);
+ virtual GBool hasStrongCompression() { return gTrue; }
private:
@@ -672,6 +674,7 @@ public:
virtual GString *getPSFilter(int psLevel, const char *indent,
GBool okToReadStream);
virtual GBool isBinary(GBool last = gTrue);
+ virtual GBool hasStrongCompression() { return gTrue; }
Stream *getRawStream() { return str; }
private:
@@ -813,6 +816,7 @@ public:
virtual GString *getPSFilter(int psLevel, const char *indent,
GBool okToReadStream);
virtual GBool isBinary(GBool last = gTrue);
+ virtual GBool hasStrongCompression() { return gTrue; }
private:
diff --git a/Build/source/libs/xpdf/xpdf-src/xpdf/TextOutputDev.cc b/Build/source/libs/xpdf/xpdf-src/xpdf/TextOutputDev.cc
index e2da940bb41..86d08414476 100644
--- a/Build/source/libs/xpdf/xpdf-src/xpdf/TextOutputDev.cc
+++ b/Build/source/libs/xpdf/xpdf-src/xpdf/TextOutputDev.cc
@@ -8,10 +8,6 @@
#include <aconf.h>
-#ifdef USE_GCC_PRAGMAS
-#pragma implementation
-#endif
-
#include <stdio.h>
#include <stdlib.h>
#include <stddef.h>
@@ -65,7 +61,11 @@
// A large character has a font size larger than
// largeCharThreshold * avgFontSize.
-#define largeCharThreshold 1.5
+#define largeCharThreshold 2.0
+
+// Max ratio of large-to-total chars to prefer a large char split over
+// a line split.
+#define largeCharRatio 0.2
// A block will be split vertically only if the resulting chunk widths
// are greater than minChunkWidth * avgFontSize. However, Blocks of
@@ -83,9 +83,9 @@
#define maxWordGapSize 2.5
#define tableModeMaxWordGapSize 1.1
-// Adjacent lines can overlap by at most lineOverlapThreshold *
-// lineHeight.
-#define lineOverlapThreshold 0.33
+// Chars whose baseline is within baselineRange * avgFontSize of a
+// line's current average baseline are added to the line.
+#define baselineRange 0.5
// Subscripts (superscripts) must overlap the next (previous) line by
// minSubSuperscriptVertOverlap * fontSize.
@@ -214,12 +214,14 @@ public:
static int cmpX(const void *p1, const void *p2);
static int cmpY(const void *p1, const void *p2);
+ static int cmpBase(const void *p1, const void *p2);
static int cmpCharPos(const void *p1, const void *p2);
Unicode c;
int charPos;
int charLen;
double xMin, yMin, xMax, yMax;
+ double base;
TextFontInfo *font;
double fontSize;
double colorR,
@@ -249,38 +251,50 @@ TextChar::TextChar(Unicode cA, int charPosA, int charLenA,
yMin = yMinA;
xMax = xMaxA;
yMax = yMaxA;
- // this can happen with vertical writing mode, or with odd values
- // for the char/word spacing parameters
- if (xMin > xMax) {
- t = xMin; xMin = xMax; xMax = t;
- }
- if (yMin > yMax) {
- t = yMin; yMin = yMax; yMax = t;
+ switch (rotA) {
+ case 0:
+ default: base = yMax + fontSizeA * fontA->getDescent(); break;
+ case 1: base = xMin - fontSizeA * fontA->getDescent(); break;
+ case 2: base = yMin - fontSizeA * fontA->getDescent(); break;
+ case 3: base = xMax + fontSizeA * fontA->getDescent(); break;
}
// TextPage::findGaps uses integer coordinates, so clip the char
// bbox to fit in a 32-bit int (this is generally only a problem in
// damaged PDF files)
if (xMin < -1e8) {
xMin = -1e8;
+ } else if (xMin > 1e8) {
+ xMin = 1e8;
}
- if (xMax > 1e8) {
+ if (xMax < -1e8) {
+ xMax = -1e8;
+ } else if (xMax > 1e8) {
xMax = 1e8;
}
if (yMin < -1e8) {
yMin = -1e8;
+ } else if (yMin > 1e8) {
+ yMin = 1e8;
}
- if (yMax > 1e8) {
+ if (yMax < -1e8) {
+ yMax = -1e8;
+ } else if (yMax > 1e8) {
yMax = 1e8;
}
- // zero-width characters will cause problems in the splitting code
- if (rotA & 1) {
- if (yMax - yMin < 1e-6) {
- yMax = yMin + 1e-6;
- }
- } else {
- if (xMax - xMin < 1e-6) {
- xMax = xMin + 1e-6;
- }
+ // this can happen with vertical writing mode, or with odd values
+ // for the char/word spacing parameters
+ if (xMin > xMax) {
+ t = xMin; xMin = xMax; xMax = t;
+ }
+ if (yMin > yMax) {
+ t = yMin; yMin = yMax; yMax = t;
+ }
+ // zero-width/height characters will cause problems in the splitting code
+ if (xMax - xMin < 1e-6) {
+ xMax = xMin + 1e-6;
+ }
+ if (yMax - yMin < 1e-6) {
+ yMax = yMin + 1e-6;
}
rot = (Guchar)rotA;
rotated = (char)rotatedA;
@@ -321,6 +335,19 @@ int TextChar::cmpY(const void *p1, const void *p2) {
}
}
+int TextChar::cmpBase(const void *p1, const void *p2) {
+ const TextChar *ch1 = *(const TextChar **)p1;
+ const TextChar *ch2 = *(const TextChar **)p2;
+
+ if (ch1->base < ch2->base) {
+ return -1;
+ } else if (ch1->base > ch2->base) {
+ return 1;
+ } else {
+ return ch1->charPos - ch2->charPos;
+ }
+}
+
int TextChar::cmpCharPos(const void *p1, const void *p2) {
const TextChar *ch1 = *(const TextChar **)p1;
const TextChar *ch2 = *(const TextChar **)p2;
@@ -985,7 +1012,8 @@ TextLine::TextLine(GList *wordsA, double xMinA, double yMinA,
}
}
//~ need to check for other Unicode chars used as hyphens
- hyphenated = text[len - 1] == (Unicode)'-';
+ hyphenated = text[len - 1] == (Unicode)'-' ||
+ text[len - 1] == (Unicode)0xad;
}
TextLine::~TextLine() {
@@ -1212,6 +1240,7 @@ TextPage::TextPage(TextOutputControl *controlA) {
chars = new GList();
fonts = new GList();
+ primaryRot = 0;
underlines = new GList();
links = new GList();
@@ -1240,6 +1269,15 @@ void TextPage::startPage(GfxState *state) {
if (state) {
pageWidth = state->getPageWidth();
pageHeight = state->getPageHeight();
+ // When rotating characters, the coordinates are flipped using the
+ // page size. See the comment in TextChar::TextChar() about
+ // integer coordinates.
+ if (pageWidth > 1e8) {
+ pageWidth = 1e8;
+ }
+ if (pageHeight > 1e8) {
+ pageHeight = 1e8;
+ }
} else {
pageWidth = pageHeight = 0;
}
@@ -1266,6 +1304,9 @@ void TextPage::clear() {
underlines = new GList();
deleteGList(links, TextLink);
links = new GList();
+ nVisibleChars = 0;
+ nInvisibleChars = 0;
+ nRemovedDupChars = 0;
if (findCols) {
deleteGList(findCols, TextColumn);
@@ -1560,13 +1601,18 @@ void TextPage::addChar(GfxState *state, double x, double y,
} else {
j = i;
}
+ GBool invisible = state->getRender() == 3 || alpha < 0.001;
chars->append(new TextChar(uBuf[j], charPos, nBytes,
xMin, yMin, xMax, yMax,
- curRot, rotated, clipped,
- state->getRender() == 3 || alpha < 0.001,
+ curRot, rotated, clipped, invisible,
curFont, curFontSize,
colToDbl(rgb.r), colToDbl(rgb.g),
colToDbl(rgb.b)));
+ if (invisible) {
+ ++nInvisibleChars;
+ } else {
+ ++nVisibleChars;
+ }
}
}
@@ -1730,7 +1776,7 @@ void TextPage::writeReadingOrder(void *outputStream,
GList *columns;
GBool primaryLR;
GString *s;
- int colIdx, parIdx, lineIdx, rot, n;
+ int colIdx, parIdx, lineIdx, n;
#if 0 //~debug
dumpChars(chars);
@@ -1740,7 +1786,7 @@ void TextPage::writeReadingOrder(void *outputStream,
} else {
overlappingChars = NULL;
}
- rot = rotateChars(chars);
+ primaryRot = rotateChars(chars);
primaryLR = checkPrimaryLR(chars);
tree = splitChars(chars);
#if 0 //~debug
@@ -1748,14 +1794,14 @@ void TextPage::writeReadingOrder(void *outputStream,
#endif
if (!tree) {
// no text
- unrotateChars(chars, rot);
+ unrotateChars(chars, primaryRot);
return;
}
columns = buildColumns(tree, primaryLR);
delete tree;
- unrotateChars(chars, rot);
+ unrotateChars(chars, primaryRot);
if (control.html) {
- rotateUnderlinesAndLinks(rot);
+ rotateUnderlinesAndLinks(primaryRot);
generateUnderlinesAndLinks(columns);
}
if (overlappingChars) {
@@ -1799,10 +1845,10 @@ GList *TextPage::makeColumns() {
GList *overlappingChars;
GList *columns;
GBool primaryLR;
- int rot;
if (control.mode == textOutSimple2Layout) {
primaryLR = checkPrimaryLR(chars);
+ primaryRot = 0;
rotateCharsToZero(chars);
columns = buildSimple2Columns(chars);
unrotateCharsFromZero(chars);
@@ -1813,7 +1859,7 @@ GList *TextPage::makeColumns() {
} else {
overlappingChars = NULL;
}
- rot = rotateChars(chars);
+ primaryRot = rotateChars(chars);
primaryLR = checkPrimaryLR(chars);
if ((tree = splitChars(chars))) {
columns = buildColumns(tree, primaryLR);
@@ -1822,8 +1868,8 @@ GList *TextPage::makeColumns() {
// no text
columns = new GList();
}
- unrotateChars(chars, rot);
- unrotateColumns(columns, rot);
+ unrotateChars(chars, primaryRot);
+ unrotateColumns(columns, primaryRot);
if (control.html) {
generateUnderlinesAndLinks(columns);
}
@@ -1852,7 +1898,7 @@ void TextPage::writePhysLayout(void *outputStream,
GList *overlappingChars;
GList *columns;
GBool primaryLR;
- int ph, colIdx, parIdx, lineIdx, rot, y, i;
+ int ph, colIdx, parIdx, lineIdx, y, i;
#if 0 //~debug
dumpChars(chars);
@@ -1865,7 +1911,7 @@ void TextPage::writePhysLayout(void *outputStream,
} else {
overlappingChars = NULL;
}
- rot = rotateChars(chars);
+ primaryRot = rotateChars(chars);
primaryLR = checkPrimaryLR(chars);
tree = splitChars(chars);
#if 0 //~debug
@@ -1873,15 +1919,15 @@ void TextPage::writePhysLayout(void *outputStream,
#endif
if (!tree) {
// no text
- unrotateChars(chars, rot);
+ unrotateChars(chars, primaryRot);
return;
}
//~ this doesn't correctly handle the right-to-left case
columns = buildColumns(tree, gTrue);
delete tree;
- unrotateChars(chars, rot);
+ unrotateChars(chars, primaryRot);
if (control.html) {
- rotateUnderlinesAndLinks(rot);
+ rotateUnderlinesAndLinks(primaryRot);
generateUnderlinesAndLinks(columns);
}
ph = assignPhysLayoutPositions(columns);
@@ -1940,7 +1986,7 @@ void TextPage::writePhysLayout(void *outputStream,
if (overlappingChars) {
if (overlappingChars->getLength() > 0) {
- TextColumn *col = buildOverlappingTextColumn(overlappingChars);
+ col = buildOverlappingTextColumn(overlappingChars);
(*outputFunc)(outputStream, eol, eolLen);
for (parIdx = 0; parIdx < col->paragraphs->getLength(); ++parIdx) {
par = (TextParagraph *)col->paragraphs->get(parIdx);
@@ -1973,12 +2019,12 @@ void TextPage::writeSimpleLayout(void *outputStream,
GList *superLines;
GString *out;
GBool primaryLR;
- int rot, x, i, j;
+ int x, i, j;
#if 0 //~debug
dumpChars(chars);
#endif
- rot = rotateChars(chars);
+ primaryRot = rotateChars(chars);
primaryLR = checkPrimaryLR(chars);
tree = splitChars(chars);
#if 0 //~debug
@@ -1986,13 +2032,13 @@ void TextPage::writeSimpleLayout(void *outputStream,
#endif
if (!tree) {
// no text
- unrotateChars(chars, rot);
+ unrotateChars(chars, primaryRot);
return;
}
superLines = new GList();
buildSuperLines(tree, superLines);
delete tree;
- unrotateChars(chars, rot);
+ unrotateChars(chars, primaryRot);
assignSimpleLayoutPositions(superLines, uMap);
for (i = 0; i < superLines->getLength(); ++i) {
@@ -2036,6 +2082,7 @@ void TextPage::writeSimple2Layout(void *outputStream,
int colIdx, parIdx, lineIdx;
primaryLR = checkPrimaryLR(chars);
+ primaryRot = 0;
rotateCharsToZero(chars);
#if 0 //~debug
dumpChars(chars);
@@ -2074,9 +2121,9 @@ void TextPage::writeLinePrinter(void *outputStream,
double pitch, lineSpacing, delta;
double yMin0, yShift, xMin0, xShift;
double y, x;
- int rot, n, i, j, k;
+ int n, i, j, k;
- rot = rotateChars(chars);
+ primaryRot = rotateChars(chars);
chars->sort(&TextChar::cmpX);
// don't call removeDuplicates here, because it expects to be
// working on a secondary list that doesn't own the TextChar objects
@@ -2186,7 +2233,7 @@ void TextPage::writeLinePrinter(void *outputStream,
delete line;
}
- unrotateChars(chars, rot);
+ unrotateChars(chars, primaryRot);
}
void TextPage::writeRaw(void *outputStream,
@@ -2451,6 +2498,7 @@ int TextPage::rotateChars(GList *charsA) {
ch->xMax = xMax;
ch->yMin = yMin;
ch->yMax = yMax;
+ ch->base = pageWidth - ch->base;
ch->rot = (ch->rot + 3) & 3;
}
t = pageWidth;
@@ -2468,6 +2516,7 @@ int TextPage::rotateChars(GList *charsA) {
ch->xMax = xMax;
ch->yMin = yMin;
ch->yMax = yMax;
+ ch->base = pageHeight - ch->base;
ch->rot = (ch->rot + 2) & 3;
}
break;
@@ -2515,6 +2564,7 @@ void TextPage::rotateCharsToZero(GList *charsA) {
ch->xMax = xMax;
ch->yMin = yMin;
ch->yMax = yMax;
+ ch->base = pageWidth - ch->base;
break;
case 2:
xMin = pageWidth - ch->xMax;
@@ -2525,6 +2575,7 @@ void TextPage::rotateCharsToZero(GList *charsA) {
ch->xMax = xMax;
ch->yMin = yMin;
ch->yMax = yMax;
+ ch->base = pageHeight - ch->base;
break;
case 3:
xMin = pageHeight - ch->yMax;
@@ -2654,6 +2705,7 @@ void TextPage::unrotateChars(GList *charsA, int rot) {
ch->xMax = xMax;
ch->yMin = yMin;
ch->yMax = yMax;
+ ch->base = pageWidth - ch->base;
ch->rot = (ch->rot + 1) & 3;
}
break;
@@ -2668,6 +2720,7 @@ void TextPage::unrotateChars(GList *charsA, int rot) {
ch->xMax = xMax;
ch->yMin = yMin;
ch->yMax = yMax;
+ ch->base = pageHeight - ch->base;
ch->rot = (ch->rot + 2) & 3;
}
break;
@@ -3220,7 +3273,7 @@ GBool TextPage::checkPrimaryLR(GList *charsA) {
// by x for rot=0,2; by y for rot=1,3.
void TextPage::removeDuplicates(GList *charsA, int rot) {
TextChar *ch, *ch2;
- double xDelta, yDelta;
+ double xDelta, yDelta, xDelta2, yDelta2;
int i, j;
if (rot & 1) {
@@ -3229,6 +3282,10 @@ void TextPage::removeDuplicates(GList *charsA, int rot) {
ch = (TextChar *)charsA->get(i);
xDelta = dupMaxSecDelta * ch->fontSize;
yDelta = dupMaxPriDelta * ch->fontSize;
+ yDelta2 = 0.5 * (ch->yMax - ch->yMin);
+ if (yDelta2 < yDelta) {
+ yDelta = yDelta2;
+ }
j = i + 1;
while (j < charsA->getLength()) {
ch2 = (TextChar *)charsA->get(j);
@@ -3241,6 +3298,7 @@ void TextPage::removeDuplicates(GList *charsA, int rot) {
fabs(ch2->yMax - ch->yMax) < yDelta) {
if (ch->invisible && !ch2->invisible) {
charsA->del(i);
+ ++nRemovedDupChars;
--i;
break;
}
@@ -3248,6 +3306,7 @@ void TextPage::removeDuplicates(GList *charsA, int rot) {
ch->spaceAfter = (char)gTrue;
}
charsA->del(j);
+ ++nRemovedDupChars;
} else {
++j;
}
@@ -3259,6 +3318,10 @@ void TextPage::removeDuplicates(GList *charsA, int rot) {
while (i < charsA->getLength()) {
ch = (TextChar *)charsA->get(i);
xDelta = dupMaxPriDelta * ch->fontSize;
+ xDelta2 = 0.5 * (ch->xMax - ch->xMin);
+ if (xDelta2 < xDelta) {
+ xDelta = xDelta2;
+ }
yDelta = dupMaxSecDelta * ch->fontSize;
j = i + 1;
while (j < charsA->getLength()) {
@@ -3272,6 +3335,7 @@ void TextPage::removeDuplicates(GList *charsA, int rot) {
fabs(ch2->yMax - ch->yMax) < yDelta) {
if (ch->invisible && !ch2->invisible) {
charsA->del(i);
+ ++nRemovedDupChars;
--i;
break;
}
@@ -3279,6 +3343,7 @@ void TextPage::removeDuplicates(GList *charsA, int rot) {
ch->spaceAfter = (char)gTrue;
}
charsA->del(j);
+ ++nRemovedDupChars;
} else {
++j;
}
@@ -3559,7 +3624,7 @@ TextBlock *TextPage::splitChars(GList *charsA) {
}
}
if (chars2->getLength() > 0) {
- tree[rot] = split(chars2, rot, gFalse);
+ tree[rot] = split(chars2, rot);
}
}
delete chars2;
@@ -3590,9 +3655,11 @@ TextBlock *TextPage::splitChars(GList *charsA) {
}
// merge non-primary-rotation text into the primary-rotation tree
+ GBool doReorder = control.mode == textOutReadingOrder &&
+ globalParams->getSeparateRotatedText();
for (rot = 1; rot < 4; ++rot) {
if (tree[rot]) {
- insertIntoTree(tree[rot], tree[0]);
+ insertIntoTree(tree[rot], tree[0], doReorder);
tree[rot] = NULL;
}
}
@@ -3610,7 +3677,7 @@ TextBlock *TextPage::splitChars(GList *charsA) {
}
// Generate a tree of TextBlocks, marked as columns, lines, and words.
-TextBlock *TextPage::split(GList *charsA, int rot, GBool vertOnly) {
+TextBlock *TextPage::split(GList *charsA, int rot) {
TextBlock *blk;
GList *chars2, *chars3;
GList *splitLines;
@@ -3762,18 +3829,13 @@ TextBlock *TextPage::split(GList *charsA, int rot, GBool vertOnly) {
doHorizSplit = doVertSplit = doLineSplit = doLargeCharSplit = gFalse;
smallSplit = gFalse;
if (rot & 1) {
- if (vertOnly) {
- if (nHorizGaps > 0 && horizGapSize > minGapSize * minFontSize) {
- doHorizSplit = gTrue;
- smallSplit = horizGapSize < smallSplitThreshold;
- }
- } else if (control.mode == textOutSimpleLayout) {
+ if (control.mode == textOutSimpleLayout) {
if (nVertGaps > 0) {
doVertSplit = gTrue;
} else if (nHorizGaps > 0 && horizGapSize > minGapSize * minFontSize) {
doHorizSplit = gTrue;
smallSplit = horizGapSize < smallSplitThreshold;
- } else if (!vertOnly && splitLines->getLength() > 1) {
+ } else if (splitLines->getLength() > 1) {
doLineSplit = gTrue;
}
} else if (nHorizGaps > 0 &&
@@ -3786,19 +3848,15 @@ TextBlock *TextPage::split(GList *charsA, int rot, GBool vertOnly) {
smallSplit = horizGapSize < smallSplitThreshold;
} else if (nVertGaps > 0) {
doVertSplit = gTrue;
- } else if (nLargeChars > 0) {
+ } else if (nLargeChars > 0 &&
+ ((nLargeChars < largeCharRatio * charsA->getLength()) ||
+ splitLines->getLength() <= 1)) {
doLargeCharSplit = gTrue;
} else if (splitLines->getLength() > 1) {
doLineSplit = gTrue;
}
} else {
- if (vertOnly) {
- if (nVertGaps > 0 &&
- vertGapSize > minGapSize * minFontSize) {
- doVertSplit = gTrue;
- smallSplit = vertGapSize < smallSplitThreshold;
- }
- } else if (control.mode == textOutSimpleLayout) {
+ if (control.mode == textOutSimpleLayout) {
if (nHorizGaps > 0) {
doHorizSplit = gTrue;
} else if (nVertGaps > 0 && vertGapSize > minGapSize * minFontSize) {
@@ -3817,7 +3875,9 @@ TextBlock *TextPage::split(GList *charsA, int rot, GBool vertOnly) {
smallSplit = vertGapSize < smallSplitThreshold;
} else if (nHorizGaps > 0) {
doHorizSplit = gTrue;
- } else if (nLargeChars > 0) {
+ } else if (nLargeChars > 0 &&
+ ((nLargeChars < largeCharRatio * charsA->getLength()) ||
+ splitLines->getLength() <= 1)) {
doLargeCharSplit = gTrue;
} else if (splitLines->getLength() > 1) {
doLineSplit = gTrue;
@@ -3847,13 +3907,13 @@ TextBlock *TextPage::split(GList *charsA, int rot, GBool vertOnly) {
if (vertGaps->getW(i) > vertGapSize - splitGapSlack * avgFontSize) {
x1 = vertGaps->getX(i);
chars2 = getChars(charsA, x0, yMin - 1, x1, yMax + 1);
- blk->addChild(split(chars2, rot, vertOnly));
+ blk->addChild(split(chars2, rot));
delete chars2;
x0 = x1;
}
}
chars2 = getChars(charsA, x0, yMin - 1, xMax + 1, yMax + 1);
- blk->addChild(split(chars2, rot, vertOnly));
+ blk->addChild(split(chars2, rot));
delete chars2;
// split horizontally
@@ -3874,13 +3934,13 @@ TextBlock *TextPage::split(GList *charsA, int rot, GBool vertOnly) {
if (horizGaps->getW(i) > horizGapSize - splitGapSlack * avgFontSize) {
y1 = horizGaps->getX(i);
chars2 = getChars(charsA, xMin - 1, y0, xMax + 1, y1);
- blk->addChild(split(chars2, rot, gFalse));
+ blk->addChild(split(chars2, rot));
delete chars2;
y0 = y1;
}
}
chars2 = getChars(charsA, xMin - 1, y0, xMax + 1, yMax + 1);
- blk->addChild(split(chars2, rot, gFalse));
+ blk->addChild(split(chars2, rot));
delete chars2;
// split into larger and smaller chars
@@ -3899,7 +3959,7 @@ TextBlock *TextPage::split(GList *charsA, int rot, GBool vertOnly) {
chars3->append(ch);
}
}
- blk = split(chars3, rot, gFalse);
+ blk = split(chars3, rot);
chars2->sort((rot & 1) ? &TextChar::cmpY : &TextChar::cmpX);
insertLargeChars(chars2, blk);
delete chars2;
@@ -3925,12 +3985,21 @@ TextBlock *TextPage::split(GList *charsA, int rot, GBool vertOnly) {
for (i = 0; i < splitLine->chars->getLength(); ++i) {
blk->addChild((TextChar *)splitLine->chars->get(i), gTrue);
}
+#if 0 //~debug
+ printf("line-leaf xMin=%g yMin=%g xMax=%g yMax=%g\n",
+ xMin, pageHeight - yMax, xMax, pageHeight - yMin);
+ printf(" ");
+ for (i = 0; i < splitLine->chars->getLength(); ++i) {
+ printf("%c", ((TextChar *)splitLine->chars->get(i))->c);
+ }
+ printf("\n");
+#endif
} else {
blk = new TextBlock((rot & 1) ? blkVertSplit : blkHorizSplit, rot);
blk->smallSplit = gFalse;
for (i = 0; i < splitLines->getLength(); ++i) {
SplitLine *splitLine = (SplitLine *)splitLines->get(i);
- blk->addChild(split(splitLine->chars, rot, singleLine));
+ blk->addChild(split(splitLine->chars, rot));
}
}
@@ -4058,54 +4127,146 @@ void TextPage::findGaps(GList *charsA, int rot,
}
}
- //----- partition into lines and find horizontal gaps
+ //----- find horizontal gaps
if (rot & 1) {
charsA->sort(&TextChar::cmpX);
- SplitLine *splitLine = NULL;
- double xxMin = 0, xxMax = 0;
+ double xxMax = 0;
for (int i = 0; i < charsA->getLength(); ++i) {
TextChar *ch = (TextChar *)charsA->get(i);
- if (i == 0 ||
- ch->xMin > xxMax - lineOverlapThreshold * (xxMax - xxMin)) {
- if (i > 0 && ch->xMin > xxMax) {
- vertGaps->addGap(0.5 * (ch->xMin + xxMax), ch->xMin - xxMax);
- }
- xxMin = ch->xMin;
+ if (i == 0) {
xxMax = ch->xMax;
- splitLine = new SplitLine(i, i, xxMin, xxMax);
- splitLines->append(splitLine);
- } else {
- splitLine->lastCharIdx = i;
+ } else if (ch->xMin <= xxMax) {
if (ch->xMax > xxMax) {
xxMax = ch->xMax;
- splitLine->yMax = xxMax;
}
+ } else {
+ vertGaps->addGap(0.5 * (ch->xMin + xxMax), ch->xMin - xxMax);
+ xxMax = ch->xMax;
}
}
} else {
charsA->sort(&TextChar::cmpY);
- SplitLine *splitLine = NULL;
- double yyMin = 0, yyMax = 0;
+ double yyMax = 0;
for (int i = 0; i < charsA->getLength(); ++i) {
TextChar *ch = (TextChar *)charsA->get(i);
- if (i == 0 ||
- ch->yMin > yyMax - lineOverlapThreshold * (yyMax - yyMin)) {
- if (i > 0 && ch->yMin > yyMax) {
- horizGaps->addGap(0.5 * (ch->yMin + yyMax), ch->yMin - yyMax);
- }
- yyMin = ch->yMin;
+ if (i == 0) {
yyMax = ch->yMax;
- splitLine = new SplitLine(i, i, yyMin, yyMax);
- splitLines->append(splitLine);
+ } else if (ch->yMin <= yyMax) {
+ if (ch->yMax > yyMax) {
+ yyMax = ch->yMax;
+ }
} else {
- splitLine->lastCharIdx = i;
+ horizGaps->addGap(0.5 * (ch->yMin + yyMax), ch->yMin - yyMax);
+ yyMax = ch->yMax;
+ }
+ }
+ }
+
+ //----- split into lines
+
+ double baseDelta = baselineRange * avgFontSize;
+
+ if (rot & 1) {
+
+ // split into non-overlapping chunks
+ int firstChar = 0;
+ while (firstChar < charsA->getLength()) {
+ TextChar *ch = (TextChar *)charsA->get(firstChar);
+ double xxMax = ch->xMax;
+ int nextChar = firstChar + 1;
+ while (nextChar < charsA->getLength()) {
+ ch = (TextChar *)charsA->get(nextChar);
+ if (ch->xMin > xxMax) {
+ break;
+ }
+ if (ch->xMax > xxMax) {
+ xxMax = ch->xMax;
+ }
+ ++nextChar;
+ }
+
+ // split the chunk [firstChar, nextChar) into lines
+ charsA->sort(firstChar, nextChar - firstChar, &TextChar::cmpBase);
+ int i0 = firstChar;
+ while (i0 < nextChar) {
+ ch = (TextChar *)charsA->get(i0);
+ double baseTotal = ch->base;
+ double baseAvg = baseTotal;
+ double xxMin = ch->xMin;
+ xxMax = ch->xMax;
+ int i1 = i0 + 1;
+ while (i1 < nextChar) {
+ ch = (TextChar *)charsA->get(i1);
+ if (ch->base > baseAvg + baseDelta) {
+ break;
+ }
+ baseTotal += ch->base;
+ if (ch->xMin < xxMin) {
+ xxMin = ch->xMin;
+ }
+ if (ch->xMax > xxMax) {
+ xxMax = ch->xMax;
+ }
+ ++i1;
+ baseAvg = baseTotal / (i1 - i0);
+ }
+ splitLines->append(new SplitLine(i0, i1 - 1, xxMin, xxMax));
+ i0 = i1;
+ }
+ firstChar = nextChar;
+ }
+
+ } else {
+
+ // split into non-overlapping chunks
+ int firstChar = 0;
+ while (firstChar < charsA->getLength()) {
+ TextChar *ch = (TextChar *)charsA->get(firstChar);
+ double yyMax = ch->yMax;
+ int nextChar = firstChar + 1;
+ while (nextChar < charsA->getLength()) {
+ ch = (TextChar *)charsA->get(nextChar);
+ if (ch->yMin > yyMax) {
+ break;
+ }
if (ch->yMax > yyMax) {
yyMax = ch->yMax;
- splitLine->yMax = yyMax;
}
+ ++nextChar;
+ }
+
+ // split the chunk [firstChar, nextChar) into lines
+ charsA->sort(firstChar, nextChar - firstChar, &TextChar::cmpBase);
+ int i0 = firstChar;
+ while (i0 < nextChar) {
+ ch = (TextChar *)charsA->get(i0);
+ double baseTotal = ch->base;
+ double baseAvg = baseTotal;
+ double yyMin = ch->yMin;
+ yyMax = ch->yMax;
+ int i1 = i0 + 1;
+ while (i1 < nextChar) {
+ ch = (TextChar *)charsA->get(i1);
+ if (ch->base > baseAvg + baseDelta) {
+ break;
+ }
+ baseTotal += ch->base;
+ if (ch->yMin < yyMin) {
+ yyMin = ch->yMin;
+ }
+ if (ch->yMax > yyMax) {
+ yyMax = ch->yMax;
+ }
+ ++i1;
+ baseAvg = baseTotal / (i1 - i0);
+ }
+ splitLines->append(new SplitLine(i0, i1 - 1, yyMin, yyMax));
+ i0 = i1;
}
+ firstChar = nextChar;
}
+
}
}
@@ -4197,10 +4358,19 @@ void TextPage::mergeSplitLines(GList *charsA, int rot, GList *splitLines) {
// merge sub/superscripts into correct lines
if (allSubSuper) {
+ idxAbove = 0;
+ idxBelow = 0;
for (int idx = 0; idx < splitLine->chars->getLength(); ++idx) {
TextChar *ch = (TextChar *)splitLine->chars->get(idx);
if (maybeSub && ch->xMin < prevLine->yMax) {
- prevLine->chars->append(ch);
+ while (idxAbove < prevLine->chars->getLength()) {
+ TextChar *ch2 = (TextChar *)prevLine->chars->get(idxAbove);
+ if (ch2->yMin > ch->yMin && ch2->xMin < ch->xMax && ch2->xMax > ch->xMin) {
+ break;
+ }
+ ++idxAbove;
+ }
+ prevLine->chars->insert(idxAbove, ch);
if (ch->xMin < prevLine->yMin) {
prevLine->yMin = ch->xMin;
}
@@ -4208,7 +4378,14 @@ void TextPage::mergeSplitLines(GList *charsA, int rot, GList *splitLines) {
prevLine->yMax = ch->xMax;
}
} else {
- nextLine->chars->append(ch);
+ while (idxBelow < nextLine->chars->getLength()) {
+ TextChar *ch2 = (TextChar *)nextLine->chars->get(idxBelow);
+ if (ch2->yMin > ch->yMin && ch2->xMin < ch->xMax && ch2->xMax > ch->xMin) {
+ break;
+ }
+ ++idxBelow;
+ }
+ nextLine->chars->insert(idxBelow, ch);
if (ch->xMin < nextLine->yMin) {
nextLine->yMin = ch->xMin;
}
@@ -4217,12 +4394,6 @@ void TextPage::mergeSplitLines(GList *charsA, int rot, GList *splitLines) {
}
}
}
- if (maybeSub) {
- prevLine->chars->sort(&TextChar::cmpY);
- }
- if (maybeSuper) {
- nextLine->chars->sort(&TextChar::cmpY);
- }
delete splitLine;
splitLines->del(i);
}
@@ -4252,14 +4423,14 @@ void TextPage::mergeSplitLines(GList *charsA, int rot, GList *splitLines) {
prevLine = (SplitLine *)splitLines->get(i-1);
double minOverlap = minSubSuperscriptVertOverlap
* (prevLine->yMax - prevLine->yMin);
- maybeSub = prevLine->yMax - splitLine->yMin > minOverlap;
+ maybeSub = prevLine->yMax - splitLine->yMin > minOverlap;
}
GBool maybeSuper = gFalse;
if (i < splitLines->getLength() - 1) {
nextLine = (SplitLine *)splitLines->get(i+1);
double minOverlap = minSubSuperscriptVertOverlap
* (nextLine->yMax - nextLine->yMin);
- maybeSuper = splitLine->yMax - nextLine->yMin > minOverlap;
+ maybeSuper = splitLine->yMax - nextLine->yMin > minOverlap;
}
if (!maybeSub && !maybeSuper) {
continue;
@@ -4315,10 +4486,19 @@ void TextPage::mergeSplitLines(GList *charsA, int rot, GList *splitLines) {
// merge sub/superscripts into correct lines
if (allSubSuper) {
+ idxAbove = 0;
+ idxBelow = 0;
for (int idx = 0; idx < splitLine->chars->getLength(); ++idx) {
TextChar *ch = (TextChar *)splitLine->chars->get(idx);
if (maybeSub && ch->yMin < prevLine->yMax) {
- prevLine->chars->append(ch);
+ while (idxAbove < prevLine->chars->getLength()) {
+ TextChar *ch2 = (TextChar *)prevLine->chars->get(idxAbove);
+ if (ch2->xMin > ch->xMin && ch2->yMin < ch->yMax && ch2->yMax > ch->yMin) {
+ break;
+ }
+ ++idxAbove;
+ }
+ prevLine->chars->insert(idxAbove, ch);
if (ch->yMin < prevLine->yMin) {
prevLine->yMin = ch->yMin;
}
@@ -4326,7 +4506,14 @@ void TextPage::mergeSplitLines(GList *charsA, int rot, GList *splitLines) {
prevLine->yMax = ch->yMax;
}
} else {
- nextLine->chars->append(ch);
+ while (idxBelow < nextLine->chars->getLength()) {
+ TextChar *ch2 = (TextChar *)nextLine->chars->get(idxBelow);
+ if (ch2->xMin > ch->xMin && ch2->yMin < ch->yMax && ch2->yMax > ch->yMin) {
+ break;
+ }
+ ++idxBelow;
+ }
+ nextLine->chars->insert(idxBelow, ch);
if (ch->yMin < nextLine->yMin) {
nextLine->yMin = ch->yMin;
}
@@ -4335,12 +4522,6 @@ void TextPage::mergeSplitLines(GList *charsA, int rot, GList *splitLines) {
}
}
}
- if (maybeSub) {
- prevLine->chars->sort(&TextChar::cmpX);
- }
- if (maybeSuper) {
- nextLine->chars->sort(&TextChar::cmpX);
- }
delete splitLine;
splitLines->del(i);
}
@@ -4517,20 +4698,48 @@ void TextPage::insertLargeCharInLeaf(TextChar *ch, TextBlock *blk) {
}
// Merge blk (rot != 0) into primaryTree (rot == 0).
-void TextPage::insertIntoTree(TextBlock *blk, TextBlock *primaryTree) {
- TextBlock *child;
+void TextPage::insertIntoTree(TextBlock *blk, TextBlock *primaryTree,
+ GBool doReorder) {
+ // if we're separating each rotation (only supported in reading
+ // order mode), reorder the block's children as appropriate and then
+ // append the block
+ if (doReorder) {
+ reorderBlocks(blk);
+ primaryTree->children->append(blk);
+
+ // otherwise, insert blocks into the primary tree in the appropriate
+ // locations
+ } else {
- // we insert a whole column at a time - so call insertIntoTree
- // recursively until we get to a column (or line)
+ // we insert a whole column at a time - so call insertIntoTree
+ // recursively until we get to a column (or line)
+ if (blk->tag == blkTagMulticolumn) {
+ while (blk->children->getLength()) {
+ TextBlock *child = (TextBlock *)blk->children->del(0);
+ insertIntoTree(child, primaryTree, doReorder);
+ }
+ delete blk;
- if (blk->tag == blkTagMulticolumn) {
- while (blk->children->getLength()) {
- child = (TextBlock *)blk->children->del(0);
- insertIntoTree(child, primaryTree);
+ } else {
+ insertColumnIntoTree(blk, primaryTree);
}
- delete blk;
- } else {
- insertColumnIntoTree(blk, primaryTree);
+ }
+}
+
+// Reorder non-primary-rotation blocks as appropriate (for reading
+// order mode only).
+void TextPage::reorderBlocks(TextBlock *blk) {
+ if (blk->tag != blkTagMulticolumn) {
+ return;
+ }
+ for (int i = 0; i < blk->children->getLength(); ++i) {
+ reorderBlocks((TextBlock *)blk->children->get(i));
+ }
+ //~ check/test these conditions
+ if ((blk->rot == 1 && blk->type == blkVertSplit) ||
+ blk->rot == 2 ||
+ (blk->rot == 3 && blk->type == blkHorizSplit)) {
+ blk->children->reverse();
}
}
@@ -5095,11 +5304,13 @@ TextLine *TextPage::buildLine(GList *charsA, int rot,
TextWord *word;
double wordSp, lineFontSize, sp;
int dir, dir2;
- GBool rotated, spaceAfter, spaceBefore;
+ GBool rotated2, spaceAfter, spaceBefore;
int i, j;
wordSp = computeWordSpacingThreshold(charsA, rot);
+ adjustCombiningChars(charsA, rot);
+
words = new GList();
lineFontSize = 0;
spaceBefore = gFalse;
@@ -5113,7 +5324,7 @@ TextLine *TextPage::buildLine(GList *charsA, int rot,
: (TextChar *)NULL,
(i < charsA->getLength() - 1) ? (TextChar *)charsA->get(i+1)
: (TextChar *)NULL);
- rotated = ((TextChar *)charsA->get(i))->rotated;
+ rotated2 = ((TextChar *)charsA->get(i))->rotated;
for (j = i+1; j < charsA->getLength(); ++j) {
ch = (TextChar *)charsA->get(j-1);
ch2 = (TextChar *)charsA->get(j);
@@ -5134,7 +5345,7 @@ TextLine *TextPage::buildLine(GList *charsA, int rot,
: (TextChar *)NULL);
if (ch->font != ch2->font ||
fabs(ch->fontSize - ch2->fontSize) > 0.01 ||
- (control.splitRotatedWords && ch2->rotated != rotated) ||
+ (control.splitRotatedWords && ch2->rotated != rotated2) ||
(dir && dir2 && dir2 != dir) ||
(control.mode == textOutRawOrder &&
ch2->charPos != ch->charPos + ch->charLen)) {
@@ -5145,7 +5356,7 @@ TextLine *TextPage::buildLine(GList *charsA, int rot,
}
sp = wordSp - 1;
}
- word = new TextWord(charsA, i, j - i, rot, rotated, dir,
+ word = new TextWord(charsA, i, j - i, rot, rotated2, dir,
(rot >= 2) ? spaceBefore : spaceAfter);
spaceBefore = spaceAfter;
i = j;
@@ -5277,6 +5488,89 @@ double TextPage::computeWordSpacingThreshold(GList *charsA, int rot) {
}
}
+// Move Unicode combining characters around so that they come
+// immediately after the correct base characters.
+//~ this currently won't work for RtL scripts
+void TextPage::adjustCombiningChars(GList *charsA, int rot) {
+ int i = 1;
+ while (i < charsA->getLength()) {
+ TextChar *ch = (TextChar *)charsA->get(i);
+
+ // look for a zero-width combining char
+ if (!(unicodeTypeCombiningMark(ch->c) &&
+ fabs((rot & 1) ? ch->yMax - ch->yMin // width ~= zero
+ : ch->xMax - ch->xMin) < 0.01)) {
+ ++i;
+ continue;
+ }
+
+ // look for a sequence of zero-width combining chars at the same
+ // position (NB: slight negative char spacing can reorder things
+ // so that diacritics for different base chars appear next to each
+ // other)
+ int j;
+ for (j = i + 1; j < charsA->getLength(); ++j) {
+ TextChar *ch2 = (TextChar *)charsA->get(j);
+ if (!(unicodeTypeCombiningMark(ch2->c) &&
+ fabs((rot & 1) ? ch2->yMin - ch->yMax
+ : ch2->xMin - ch->xMax) < 0.01 * ch->fontSize &&
+ fabs((rot & 1) ? ch->yMax - ch->yMin // width ~= zero
+ : ch->xMax - ch->xMin) < 0.01)) {
+ break;
+ }
+ }
+
+ // identify the two previous chars
+ TextChar *prev1 = (i >= 2) ? (TextChar *)charsA->get(i - 2) : NULL;
+ TextChar *prev2 = (TextChar *)charsA->get(i - 1);
+
+ //~ this code currently makes things worse for RtL scripts, so
+ //~ skip any RtL text
+ if (unicodeTypeR(prev2->c)) {
+ ++i;
+ continue;
+ }
+
+ // if the combining chars are placed in the left 3/4 of prev2,
+ // assume the base char is prev1, not prev2, and reorder the chars
+ // accordingly
+ TextChar *base;
+ if (prev1 &&
+ ((rot & 1) ? (ch->yMin < 0.25 * prev2->yMin + 0.75 * prev2->yMax)
+ : (ch->xMin < 0.25 * prev2->xMin + 0.75 * prev2->xMax))) {
+ for (int k = i; k < j; ++k) {
+ charsA->put(k - 1, charsA->get(k));
+ }
+ charsA->put(j - 1, prev2);
+ --i;
+ --j;
+ base = prev1;
+ } else {
+ base = prev2;
+ }
+
+ // sort the diacritics into content stream order
+ // (slight negative char spacing, used for kerning, will push
+ // zero-width diacritics out of order)
+ if (j - i > 1) {
+ charsA->sort(i, j - i, &TextChar::cmpCharPos);
+ }
+
+ // set the diacritics' positions immediately to the right of the
+ // base char
+ for (int k = i; k < j; ++k) {
+ TextChar *ch2 = (TextChar *)charsA->get(k);
+ if (rot & 1) {
+ ch2->yMin = ch2->yMax = base->yMax;
+ } else {
+ ch2->xMin = ch2->xMax = base->xMax;
+ }
+ }
+
+ i = j;
+ }
+}
+
// Check the character's direction: returns 1 for L or Num; -1 for R; 0
// for others.
int TextPage::getCharDirection(TextChar *ch) {
@@ -6624,7 +6918,8 @@ void TextOutputDev::endString(GfxState *state) {
void TextOutputDev::drawChar(GfxState *state, double x, double y,
double dx, double dy,
double originX, double originY,
- CharCode c, int nBytes, Unicode *u, int uLen) {
+ CharCode c, int nBytes, Unicode *u, int uLen,
+ GBool fill, GBool stroke, GBool makePath) {
text->addChar(state, x, y, dx, dy, c, nBytes, u, uLen);
}
diff --git a/Build/source/libs/xpdf/xpdf-src/xpdf/TextOutputDev.h b/Build/source/libs/xpdf/xpdf-src/xpdf/TextOutputDev.h
index 302975cd5f1..fc7bcb616dd 100644
--- a/Build/source/libs/xpdf/xpdf-src/xpdf/TextOutputDev.h
+++ b/Build/source/libs/xpdf/xpdf-src/xpdf/TextOutputDev.h
@@ -11,10 +11,6 @@
#include <aconf.h>
-#ifdef USE_GCC_PRAGMAS
-#pragma interface
-#endif
-
#include <stdio.h>
#include "gtypes.h"
#include "GfxFont.h"
@@ -122,6 +118,9 @@ public:
// Get the width of the 'm' character, if available.
double getMWidth() { return mWidth; }
+ double getAscent() { return ascent; }
+ double getDescent() { return descent; }
+
Ref getFontID() { return fontID; }
private:
@@ -474,10 +473,18 @@ public:
TextWordList *makeWordListForRect(double xMin, double yMin,
double xMax, double yMax);
+ // Get the primary rotation of text on the page.
+ int getPrimaryRotation() { return primaryRot; }
+
// Returns true if the primary character direction is left-to-right,
// false if it is right-to-left.
GBool primaryDirectionIsLR();
+ // Get the counter values.
+ int getNumVisibleChars() { return nVisibleChars; }
+ int getNumInvisibleChars() { return nInvisibleChars; }
+ int getNumRemovedDupChars() { return nRemovedDupChars; }
+
// Returns true if any of the fonts used on this page are likely to
// be problematic when converting text to Unicode.
GBool problematicForUnicode() { return problematic; }
@@ -557,7 +564,7 @@ private:
GList *separateOverlappingText(GList *charsA);
TextColumn *buildOverlappingTextColumn(GList *overlappingChars);
TextBlock *splitChars(GList *charsA);
- TextBlock *split(GList *charsA, int rot, GBool vertOnly);
+ TextBlock *split(GList *charsA, int rot);
GList *getChars(GList *charsA, double xMin, double yMin,
double xMax, double yMax);
void findGaps(GList *charsA, int rot,
@@ -571,7 +578,9 @@ private:
void insertLargeChars(GList *largeChars, TextBlock *blk);
void insertLargeCharsInFirstLeaf(GList *largeChars, TextBlock *blk);
void insertLargeCharInLeaf(TextChar *ch, TextBlock *blk);
- void insertIntoTree(TextBlock *subtree, TextBlock *primaryTree);
+ void insertIntoTree(TextBlock *subtree, TextBlock *primaryTree,
+ GBool doReorder);
+ void reorderBlocks(TextBlock *blk);
void insertColumnIntoTree(TextBlock *column, TextBlock *tree);
void insertClippedChars(GList *clippedChars, TextBlock *tree);
TextBlock *findClippedCharLeaf(TextChar *ch, TextBlock *tree);
@@ -589,6 +598,7 @@ private:
double xMin, double yMin, double xMax, double yMax);
void getLineChars(TextBlock *blk, GList *charsA);
double computeWordSpacingThreshold(GList *charsA, int rot);
+ void adjustCombiningChars(GList *charsA, int rot);
int getCharDirection(TextChar *ch);
int getCharDirection(TextChar *ch, TextChar *left, TextChar *right);
int assignPhysLayoutPositions(GList *columns);
@@ -640,10 +650,15 @@ private:
GList *chars; // [TextChar]
GList *fonts; // all font info objects used on this
// page [TextFontInfo]
+ int primaryRot; // primary rotation
GList *underlines; // [TextUnderline]
GList *links; // [TextLink]
+ int nVisibleChars; // number of visible chars on the page
+ int nInvisibleChars; // number of invisible chars on the page
+ int nRemovedDupChars; // number of duplicate chars removed
+
GList *findCols; // text used by the findText**/findPoint**
// functions [TextColumn]
double lastFindXMin, // coordinates of the last "find" result
@@ -725,7 +740,8 @@ public:
virtual void drawChar(GfxState *state, double x, double y,
double dx, double dy,
double originX, double originY,
- CharCode c, int nBytes, Unicode *u, int uLen);
+ CharCode c, int nBytes, Unicode *u, int uLen,
+ GBool fill, GBool stroke, GBool makePath);
virtual void incCharCount(int nChars);
virtual void beginActualText(GfxState *state, Unicode *u, int uLen);
virtual void endActualText(GfxState *state);
@@ -784,6 +800,11 @@ public:
// Turn extra processing for HTML conversion on or off.
void enableHTMLExtras(GBool html) { control.html = html; }
+ // Get the counter values.
+ int getNumVisibleChars() { return text->nVisibleChars; }
+ int getNumInvisibleChars() { return text->nInvisibleChars; }
+ int getNumRemovedDupChars() { return text->nRemovedDupChars; }
+
private:
void generateBOM();
diff --git a/Build/source/libs/xpdf/xpdf-src/xpdf/TextString.cc b/Build/source/libs/xpdf/xpdf-src/xpdf/TextString.cc
index 8e54a1d5471..5541bc61102 100644
--- a/Build/source/libs/xpdf/xpdf-src/xpdf/TextString.cc
+++ b/Build/source/libs/xpdf/xpdf-src/xpdf/TextString.cc
@@ -8,10 +8,6 @@
#include <aconf.h>
-#ifdef USE_GCC_PRAGMAS
-#pragma implementation
-#endif
-
#include <string.h>
#include "gmem.h"
#include "gmempp.h"
diff --git a/Build/source/libs/xpdf/xpdf-src/xpdf/TextString.h b/Build/source/libs/xpdf/xpdf-src/xpdf/TextString.h
index c296d7d6d7a..909d3259097 100644
--- a/Build/source/libs/xpdf/xpdf-src/xpdf/TextString.h
+++ b/Build/source/libs/xpdf/xpdf-src/xpdf/TextString.h
@@ -15,10 +15,6 @@
#include <aconf.h>
-#ifdef USE_GCC_PRAGMAS
-#pragma interface
-#endif
-
#include "CharTypes.h"
class GString;
diff --git a/Build/source/libs/xpdf/xpdf-src/xpdf/TileCache.cc b/Build/source/libs/xpdf/xpdf-src/xpdf/TileCache.cc
index ff002ed46fc..65e60629bd2 100644
--- a/Build/source/libs/xpdf/xpdf-src/xpdf/TileCache.cc
+++ b/Build/source/libs/xpdf/xpdf-src/xpdf/TileCache.cc
@@ -8,10 +8,6 @@
#include <aconf.h>
-#ifdef USE_GCC_PRAGMAS
-#pragma implementation
-#endif
-
#include "gmem.h"
#include "gmempp.h"
#include "GList.h"
@@ -237,7 +233,7 @@ GThreadReturn TileCacheThreadPool::threadFunc(void *arg) {
}
void TileCacheThreadPool::worker() {
- CachedTileDesc *ct;
+ CachedTileDesc *ct = NULL;
while (1) {
gLockMutex(&mutex);
diff --git a/Build/source/libs/xpdf/xpdf-src/xpdf/TileCache.h b/Build/source/libs/xpdf/xpdf-src/xpdf/TileCache.h
index bea58c4c8fc..1c3f83cba47 100644
--- a/Build/source/libs/xpdf/xpdf-src/xpdf/TileCache.h
+++ b/Build/source/libs/xpdf/xpdf-src/xpdf/TileCache.h
@@ -11,10 +11,6 @@
#include <aconf.h>
-#ifdef USE_GCC_PRAGMAS
-#pragma interface
-#endif
-
#include "gtypes.h"
#include "SplashTypes.h"
diff --git a/Build/source/libs/xpdf/xpdf-src/xpdf/TileCompositor.cc b/Build/source/libs/xpdf/xpdf-src/xpdf/TileCompositor.cc
index 70128a4a47f..eaea7fa5676 100644
--- a/Build/source/libs/xpdf/xpdf-src/xpdf/TileCompositor.cc
+++ b/Build/source/libs/xpdf/xpdf-src/xpdf/TileCompositor.cc
@@ -8,10 +8,6 @@
#include <aconf.h>
-#ifdef USE_GCC_PRAGMAS
-#pragma implementation
-#endif
-
#include <string.h>
#include <math.h>
#include "gmempp.h"
diff --git a/Build/source/libs/xpdf/xpdf-src/xpdf/TileCompositor.h b/Build/source/libs/xpdf/xpdf-src/xpdf/TileCompositor.h
index aa06c9da7bd..9efec4d0a16 100644
--- a/Build/source/libs/xpdf/xpdf-src/xpdf/TileCompositor.h
+++ b/Build/source/libs/xpdf/xpdf-src/xpdf/TileCompositor.h
@@ -11,10 +11,6 @@
#include <aconf.h>
-#ifdef USE_GCC_PRAGMAS
-#pragma interface
-#endif
-
#include "SplashTypes.h"
class GList;
diff --git a/Build/source/libs/xpdf/xpdf-src/xpdf/TileMap.cc b/Build/source/libs/xpdf/xpdf-src/xpdf/TileMap.cc
index d5916627082..fa262a28f94 100644
--- a/Build/source/libs/xpdf/xpdf-src/xpdf/TileMap.cc
+++ b/Build/source/libs/xpdf/xpdf-src/xpdf/TileMap.cc
@@ -8,10 +8,6 @@
#include <aconf.h>
-#ifdef USE_GCC_PRAGMAS
-#pragma implementation
-#endif
-
#include "gmem.h"
#include "gmempp.h"
#include "GList.h"
@@ -903,7 +899,7 @@ void TileMap::cvtDevToUser(int pg, int xd, int yd, double *xu, double *yu) {
void TileMap::getWindowPageRange(int x, int y, int w, int h,
int *firstPage, int *lastPage) {
- GList *tiles;
+ GList *tiles2;
PlacedTileDesc *tile;
int i;
@@ -913,9 +909,9 @@ void TileMap::getWindowPageRange(int x, int y, int w, int h,
}
*firstPage = state->getDoc()->getNumPages();
*lastPage = 0;
- tiles = getTileList();
- for (i = 0; i < tiles->getLength(); ++i) {
- tile = (PlacedTileDesc *)tiles->get(i);
+ tiles2 = getTileList();
+ for (i = 0; i < tiles2->getLength(); ++i) {
+ tile = (PlacedTileDesc *)tiles2->get(i);
if (tile->px < x + w &&
tile->px + tile->tw > x &&
tile->py < y + h &&
@@ -1352,7 +1348,7 @@ void TileMap::updatePageParams() {
// rotate the page boxes
if (page & 1) {
otherPage = page + 1;
- if (otherPage >= state->getDoc()->getNumPages()) {
+ if (otherPage > state->getDoc()->getNumPages()) {
otherPage = page;
}
} else {
diff --git a/Build/source/libs/xpdf/xpdf-src/xpdf/TileMap.h b/Build/source/libs/xpdf/xpdf-src/xpdf/TileMap.h
index 222877c5050..6a2dcb3e672 100644
--- a/Build/source/libs/xpdf/xpdf-src/xpdf/TileMap.h
+++ b/Build/source/libs/xpdf/xpdf-src/xpdf/TileMap.h
@@ -11,10 +11,6 @@
#include <aconf.h>
-#ifdef USE_GCC_PRAGMAS
-#pragma interface
-#endif
-
#include "gtypes.h"
class GList;
diff --git a/Build/source/libs/xpdf/xpdf-src/xpdf/UnicodeMap.cc b/Build/source/libs/xpdf/xpdf-src/xpdf/UnicodeMap.cc
index 833d6fc2f0c..68e38c3a36e 100644
--- a/Build/source/libs/xpdf/xpdf-src/xpdf/UnicodeMap.cc
+++ b/Build/source/libs/xpdf/xpdf-src/xpdf/UnicodeMap.cc
@@ -8,10 +8,6 @@
#include <aconf.h>
-#ifdef USE_GCC_PRAGMAS
-#pragma implementation
-#endif
-
#include <stdio.h>
#include <string.h>
#include "gmem.h"
diff --git a/Build/source/libs/xpdf/xpdf-src/xpdf/UnicodeMap.h b/Build/source/libs/xpdf/xpdf-src/xpdf/UnicodeMap.h
index a15d628b4cc..d932d0e34c9 100644
--- a/Build/source/libs/xpdf/xpdf-src/xpdf/UnicodeMap.h
+++ b/Build/source/libs/xpdf/xpdf-src/xpdf/UnicodeMap.h
@@ -13,10 +13,6 @@
#include <aconf.h>
-#ifdef USE_GCC_PRAGMAS
-#pragma interface
-#endif
-
#include "gtypes.h"
#include "CharTypes.h"
diff --git a/Build/source/libs/xpdf/xpdf-src/xpdf/UnicodeRemapping.cc b/Build/source/libs/xpdf/xpdf-src/xpdf/UnicodeRemapping.cc
index 72dbc0e159c..cfa28a0b79a 100644
--- a/Build/source/libs/xpdf/xpdf-src/xpdf/UnicodeRemapping.cc
+++ b/Build/source/libs/xpdf/xpdf-src/xpdf/UnicodeRemapping.cc
@@ -8,10 +8,6 @@
#include <aconf.h>
-#ifdef USE_GCC_PRAGMAS
-#pragma implementation
-#endif
-
#include <stdio.h>
#include <string.h>
#include "gmem.h"
diff --git a/Build/source/libs/xpdf/xpdf-src/xpdf/UnicodeRemapping.h b/Build/source/libs/xpdf/xpdf-src/xpdf/UnicodeRemapping.h
index dbf435e7dd1..679c002987f 100644
--- a/Build/source/libs/xpdf/xpdf-src/xpdf/UnicodeRemapping.h
+++ b/Build/source/libs/xpdf/xpdf-src/xpdf/UnicodeRemapping.h
@@ -13,10 +13,6 @@
#include <aconf.h>
-#ifdef USE_GCC_PRAGMAS
-#pragma interface
-#endif
-
#include "CharTypes.h"
struct UnicodeRemappingString;
diff --git a/Build/source/libs/xpdf/xpdf-src/xpdf/UnicodeTypeTable.cc b/Build/source/libs/xpdf/xpdf-src/xpdf/UnicodeTypeTable.cc
index e6a91af2756..a19bbe0d655 100644
--- a/Build/source/libs/xpdf/xpdf-src/xpdf/UnicodeTypeTable.cc
+++ b/Build/source/libs/xpdf/xpdf-src/xpdf/UnicodeTypeTable.cc
@@ -25,36 +25,36 @@ static UnicodeMapTableEntry typeTable[256] = {
{ "NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN...NNNNN.....##########.NNNNNNLLLLLLLLLLLLLLLLLLLLLLLLLLNNNNNNLLLLLLLLLLLLLLLLLLLLLLLLLLNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN.N....NNNNLNNNNN..##NLNNN#LNNNNNLLLLLLLLLLLLLLLLLLLLLLLNLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLNLLLLLLLL", 'X' },
{ NULL, 'L' },
{ "LLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLNNLLLLLLLNNNNNNNNNNNNNNLLNNNNNNNNNNNNNNLLLLLNNNNNNNNNLNNNNNNNNNNNNNNNNN", 'X' },
- { "NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNLLLLNNLLLLLLLLNLNNNNNNLNLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLNLLLLLLLLL", 'X' },
- { "LLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLNNNNNNNLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLL", 'X' },
- { "LLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLNNNNN.NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNRNRNNRNNRNRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRR###########", 'X' },
- { "######NNR..R.RNNNNNNNNNNNNNRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRNNNNNNNNNNNNNNNNNNNNN##########.##RRRNRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRNNNNNNN#NNNNNNNRRNNNNNNNRR##########RRRRRR", 'X' },
- { "RRRRRRRRRRRRRRRRRNRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRNNNNNNNNNNNNNNNNNNNNNNNNNNNRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRNNNNNNNNNNNRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRNNNNNNNNNRRNNNNRNNNRR", 'X' },
- { "RRRRRRRRRRRRRRRRRRRRRRNNNNRNNNNNNNNNRNNNRNNNNNRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRNNNRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRNNNNNNNNNNNNNNNNNNNNNNNNNN#NNNNNNNNNNNNNNNNNNNNNNNNNNNNN", 'X' },
- { "NNNLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLNLNLLLLNNNNNNNNLLLLNLLLNNNNNNNLLLLLLLLLLNNLLLLLLLLLLLLLLLLLLLLLLLLLLLLLNLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLNNNLLLLNNNNLLLLLLLLNLLLLLLLLLLLLLLLLLLLLNNLLLLLLLLLLLLLL..LLLLLLL.LLNN", 'X' },
- { "NNNLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLNNNLLLLNNNNNNNNNNNNNNNNNLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLNNLLLNLNNNNNNNNNNNNLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLNNNLLLLNNNNNNNNLLLLNLLLLLLLLLLLLLLLLLLLLNNLLLLLLLLLLLLL.LLLLLLLLNNNNNN", 'X' },
- { "NNLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLNNNLLNLNNNNLLLLLLLLNNNNNNNNNNLLLLLLLLLLLNNLLLLLLLLLLLLLLLLLLLLNNNNNNNNNNNLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLNLLLLLLLLLLLLNLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLNNNNNN.NNNNNN", 'X' },
- { "NLLLNLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLNNNLLLLNNNNNNNNNNNNNNNNNNLLLLLLLLLLLNNLLLLLLLLLLLLLLLLLLLLNNNNNNNLLNLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLNNNLLLLLLLLLLLLLLLNNLLLLLLLLLLLLLLLLLLLLNNLLLLLLLLLLLLLLLNNNNNNNNNNNNN", 'X' },
- { "NNLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLNNLLLLNNNNLLLLLLLLNLLLLLLLLLLLLLLLLLLLLNNLLLLLLLLLLLLLLLLLLLLLLLLLLLLNNLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLNNNNLLLLLLLNNNNNLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLL", 'X' },
- { "LLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLNLLNNNNNNN.....LLLLLLLNNNNNNNNLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLNLLNNNNNNNNNLLLLLLLLLLNNNNNNNLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLL", 'X' },
- { "LLLLLLLLLLLLLLLLLLLLLLLLNNLLLLLLLLLLLLLLLLLLLLLLLLLLLNLNLNNNNNLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLNNNNNNNNNNNNNNNNNNLNNNNNLNNLLLLLNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNLLLLLLLLLNLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLL", 'X' },
- { "LLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLNNNNLNNNNNNLNNLLNNLLLLLLLLLLLLLLLLLLLLLLLLLNNLLLLNNNLLLLLLLLLLLLLLLLNNNNLLLLLLLLLLLLLNLLNNLLLLLLNLLLLLLLLLLLLLLLNLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLL", 'X' },
- { NULL, 'L' },
- { NULL, 'L' },
- { "LLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLNNNNNLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLNNNNNNNNNNLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLNN", 'X' },
+ { "MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMLLLLNNLLLLLLLLNLNNNNNNLNLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLNLLLLLLLLL", 'X' },
+ { "LLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLMMMMMMMLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLL", 'X' },
+ { "LLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLNNNNN.MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMRMRMMRMMRMRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRR###########", 'X' },
+ { "######NNR..R.RNNMMMMMMMMMMMRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRMMMMMMMMMMMMMMMMMMMMM##########.##RRRMRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRMMMMMMM#NMMMMMMRRMMNMMMMRR##########RRRRRR", 'X' },
+ { "RRRRRRRRRRRRRRRRRMRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRMMMMMMMMMMMMMMMMMMMMMMMMMMMRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRMMMMMMMMMMMRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRMMMMMMMMMRRNNNNRMMMRR", 'X' },
+ { "RRRRRRRRRRRRRRRRRRRRRRMMMMRMMMMMMMMMRMMMRMMMMMRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRMMMRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRR###MMMMMMMMMMMMMMRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRMMMMMMMMMMMMMMMMMMMMMMMM#MMMMMMMMMMMMMMMMMMMMMMMMMMMMM", 'X' },
+ { "MMMLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLMLMLLLLMMMMMMMMLLLLMLLLMMMMMMMLLLLLLLLLLMMLLLLLLLLLLLLLLLLLLLLLLLLLLLLLMLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLMMMLLLLMMMMLLLLLLLLMLLLLLLLLLLLLLLLLLLLLMMLLLLLLLLLLLLLL..LLLLLLL.LLMM", 'X' },
+ { "MMMLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLMMMLLLLMMMMMMMMMMMMMMMMMLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLMMLLLMLMMMMMMMMMMMMLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLMMMLLLLMMMMMMMMLLLLMLLLLLLLLLLLLLLLLLLLLMMLLLLLLLLLLLLL.LLLLLLLLMMMMMM", 'X' },
+ { "MMLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLMMMLLMLMMMMLLLLLLLLMMMMMMMMMMLLLLLLLLLLLMMLLLLLLLLLLLLLLLLLLLLMMMMMMMMMMMLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLMLLLLLLLLLLLLMLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLNNNNNN.NMMMMM", 'X' },
+ { "MLLLMLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLMMMLMMMLLLLMMMMMMMMMMMMMMMMMMLLLLLLLLLLLMMLLLLLLLLLLLLLLLLLLLLNNNNNNNLLMLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLMMMLLLLLLLLLLLLLLLMMLLLLLLLLLLLLLLLLLLLLMMLLLLLLLLLLLLLLLLMMMMMMMMMMMM", 'X' },
+ { "MMLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLMMLLLLMMMMLLLLLLLLMLLLLLLLLLLLLLLLLLLLLMMLLLLLLLLLLLLLLLLLLLLLLLLLLLLMMLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLMMMMLLLLLLLMMMMMLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLL", 'X' },
+ { "LLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLMLLMMMMMMM.....LLLLLLLMMMMMMMMLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLMLLMMMMMMMMMLLLLLLLLLLMMMMMMMMLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLL", 'X' },
+ { "LLLLLLLLLLLLLLLLLLLLLLLLMMLLLLLLLLLLLLLLLLLLLLLLLLLLLMLMLMNNNNLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLMMMMMMMMMMMMMMMMMMLMMMMMLMMLLLLLMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMLLLLLLLLLMLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLL", 'X' },
+ { "LLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLMMMMLMMMMMMLMMLLMMLLLLLLLLLLLLLLLLLLLLLLLLLMMLLLLMMMLLLLLLLLLLLLLLLLMMMMLLLLLLLLLLLLLMLLMMLLLLLLMLLLLLLLLLLLLLLLMLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLL", 'X' },
+ { NULL, 'L' },
+ { NULL, 'L' },
+ { "LLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLMMMMMLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLNNNNNNNNNNLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLNN", 'X' },
{ "NLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLL", 'X' },
{ NULL, 'L' },
{ "LLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLNLLLLLLLLLLLLLLLLLLLLLLLLLLNNLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLL", 'X' },
- { "LLLLLLLLLLLLLLLLLLNNNLLLLLLLLLLLLLLLLLLLLLLLLLLLLLNNNLLLLLLLLLLLLLLLLLLLLLLLLLLLLLNNLLLLLLLLLLLLLLLLLLLLLLLLLLLLLNNNLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLNNLNNNNNNNLLLLLLLLNLLNNNNNNNNNNNLLLLLLL.LNLLLLLLLLLLLLNNNNNNNNNNNNNNNNNNNNNN", 'X' },
- { "NNNNNNNNNNNNNNNLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLNNLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLNLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLL", 'X' },
- { "LLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLNNNNLLLLNNLLLLLLLLLNLLLLLLNNNNNNNNNNNNNLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN", 'X' },
- { "LLLLLLLLLLLLLLLLLLLLLLLNNLLNLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLNLNNNNNNNNNLNLLNNNNNNNNLLLLLLNNNNNNNNNNNNNLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN", 'X' },
- { "NNNNLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLNLNNNNNLNLLLLLNLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLNNNNNNNNNLLLLLLLLLNNNNNLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLNNNNLLNNLNNNLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLNLNNLLLNLNNNLLLLLLLLLLLLLL", 'X' },
- { "LLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLNNNNNNNNLLNNLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLNNNNNNNNNNNLNNNNNNNNNNNNNLNNNNNNNLLLLNLLLLLLNLLLNNLLLLLL", 'X' },
- { "LLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN", 'X' },
+ { "LLLLLLLLLLLLLLLLLLMMMLLLLLLLLLLLLLLLLLLLLLLLLLLLLLMMLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLMMLLLLLLLLLLLLLLLLLLLLLLLLLLLLLMMMLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLMMLMMMMMMMLLLLLLLLMLLMMMMMMMMMMMLLLLLLL.LMLLLLLLLLLLLLNNNNNNNNNNNNNNNNNNNNNN", 'X' },
+ { "NNNNNNNNNNNMMMNMLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLMMLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLMLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLL", 'X' },
+ { "LLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLMMMMLLLLMMLLLLLLLLLMLLLLLLMMMNNNNNNNNNNLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN", 'X' },
+ { "LLLLLLLLLLLLLLLLLLLLLLLMMLLMLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLMLMMMMMMMMMLMLLMMMMMMMMLLLLLLMMMMMMMMMMMMMLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM", 'X' },
+ { "MMMMLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLMLMMMMMLMLLLLLMLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLMMMMMMMMMLLLLLLLLLLLMMMLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLMMMMLLMMLMMMLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLMLMMLLLMLMMMLLLLLLLLLLLLLL", 'X' },
+ { "LLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLMMMMMMMMLLMMLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLMMMMMMMMMMMLMMMMMMMMMMMMMLMMMMMMMLLLLMLLLLLLMLLLMMLLLLLL", 'X' },
+ { "LLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM", 'X' },
{ NULL, 'L' },
{ "LLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLNLNNNLLLLLLLLLLLNNNLLLLLLLLLLLLNNNNLLLLLLLLLLLLLNNNLLLLLLLLLLLLLNNN", 'X' },
- { "NNNNNNNNNNNNNNLRNNNNNNNNNNNNNNNNNNNNNNNNNNLRNLR......NNNNNNNNNNNNNNN.NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNLLRNNNNNNNN#L########..NNNL##########..NNNLLLLLLLLLLLLLL...................................NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN", 'X' },
+ { "NNNNNNNNNNNNNNLRNNNNNNNNNNNNNNNNNNNNNNNNNNLRNLR......NNNNNNNNNNNNNNN.NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNLLRNNNNNNNN#L########..NNNL##########..NNNLLLLLLLLLLLLLL....................................MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMNNNNNNNNNNNNNNN", 'X' },
{ "NNLNNNNLNNLLLLLLLLLLNLNNNLLLLLNNNNNNLNLNLNLLLL.LLLLLLLLLLLNNLLLLNNNNNLLLLLNNNNLLNNNNNNNNNNNNNNNNLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN", 'X' },
{ "NNNNNNNNNNNNNNNNNN..NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN", 'X' },
{ "NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLNNNNNNNNNNNNNNNNNNNNNNNNNNLNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN", 'X' },
@@ -66,12 +66,12 @@ static UnicodeMapTableEntry typeTable[256] = {
{ NULL, 'N' },
{ NULL, 'N' },
{ NULL, 'N' },
- { "LLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLNNNNNNLLLLNNNLLNNNNNNNNNNNN", 'X' },
- { "LLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLNNNNNNNNNNNNNNNLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN", 'X' },
+ { "LLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLNNNNNNLLLLMMMLLNNNNNNNNNNNN", 'X' },
+ { "LLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLMMMMMMMMMMMMMMMLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM", 'X' },
{ NULL, 'N' },
{ NULL, 'N' },
- { "NNNNNLLLNNNNNNNNNNNNNNNNNNNNNNNNNLLLLLLLLLNNNNLLNLLLLLNNLLLLLNNNLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLNNNNNNLLLNLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLNLLLL", 'X' },
- { "LLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNLLLLLLLLLLLLLLLLLLLLLLLLLLLL", 'X' },
+ { "NNNNNLLLNNNNNNNNNNNNNNNNNNNNNNNNNLLLLLLLLLMMMMLLNLLLLLNNLLLLLNNNLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLMMMMNNLLLNLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLNLLLL", 'X' },
+ { "LLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNLLLLLLLLLLLLLLLL", 'X' },
{ "LLLLLLLLLLLLLLLLLLLLLLLLLLLLLNNLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLNNNNNNNNNNNNNNNNLLLLLLLLLLLLLLLLLLLLLLLLLLLLNNNLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLNNNNNNNNNNNNNNNLLLLLLLLLLLLNNNNLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLL", 'X' },
{ "LLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLNNNNLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLNNLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLN", 'X' },
{ NULL, 'L' },
@@ -188,12 +188,12 @@ static UnicodeMapTableEntry typeTable[256] = {
{ NULL, 'L' },
{ "LLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLL", 'X' },
{ NULL, 'L' },
- { "LLLLLLLLLLLLLNNNLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLNNNNNNNNNNNNNNNNNLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLNNLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLNNLLLLLLNNNNNNNN", 'X' },
+ { "LLLLLLLLLLLLLNNNLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLMMMMNMMMMMMMMMMNNLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLMMLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLMMLLLLLLNNNNNNNN", 'X' },
{ "NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLNLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLL", 'X' },
- { "LLNLLLNLLLLNLLLLLLLLLLLLLLLLLLLLLLLLLNNLNNNNNLLLLLLLLLLL..LLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLNNNNLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLNNLLLLLLLLLLLLLLLLLLLLNNNNNNNNNNNNNNNNNNNNNNNNLLLLLLLLLLLLLN", 'X' },
- { "LLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLNNNNNNNNLLLLLLLLLLLLLLLLLLLLLLLLLNNNNNNNNNNNLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLNNNNNNLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLNLLNNNNLLNNLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLNLLLLLLLLLLLLLLLLLLLLLLLLLL", 'X' },
- { "LLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLNNNNNNLLNNLLNNLLLLLLLLLLLLNLLLLLLLLNLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLNLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLNLNNNLLNNLLLLLNNLNLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLNNLLLLLLLLNLLLLLLLLL", 'X' },
- { "LLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLNNLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLNLLNLLLLNLLLLLLLLLLLLLLLLLL", 'X' },
+ { "LLMLLLMLLLLMLLLLLLLLLLLLLLLLLLLLLLLLLMMLNNNNMLLLLLLLLLLL..LLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLNNNNLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLMMLLLLLLLLLLLLLLLLLLLLMMMMMMMMMMMMMMMMMMMMMMMMLLLLLLLLLLLLLM", 'X' },
+ { "LLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLMMMMMMMMLLLLLLLLLLLLLLLLLLLLLLLLLMMMMMMMMMMMLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLMMMMMMLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLMLLMMMMLLMMLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLMLLLLLLLLLLLLLLLLLLLLLLLLLL", 'X' },
+ { "LLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLMMMMMMLLMMLLMMLLLLLLLLLLLLMLLLLLLLLMLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLMLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLMLMMMLLMMLLLLLMMLMLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLMMLLLLLLLLMLLLLLLLLL", 'X' },
+ { "LLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLNNLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLMLLMLLLLMLLLLLLLLLLLLLLLLLL", 'X' },
{ NULL, 'L' },
{ NULL, 'L' },
{ NULL, 'L' },
@@ -273,10 +273,10 @@ static UnicodeMapTableEntry typeTable[256] = {
{ NULL, 'L' },
{ NULL, 'L' },
{ NULL, 'L' },
- { "LLLLLLLLLLLLLLLLLLLLLLLLRRRRRRNRRRRRRRRRR.RRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRR", 'X' },
+ { "LLLLLLLLLLLLLLLLLLLLLLLLRRRRRRMRRRRRRRRRR.RRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRR", 'X' },
{ NULL, 'R' },
- { "RRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRNNRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRNNN", 'X' },
- { "NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN.N.NN.NNNNNNNNN.NN..NNNNN..NRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRNNN", 'X' },
+ { "RRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRNNNNNNNNNNNNNNNNNNRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRNNNNNNNNRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRNNN", 'X' },
+ { "MMMMMMMMMMMMMMMMNNNNNNNNNNMMMMMMMMMMMMMMMMMMMMMMNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN.N.NN.NNNNNNNNN.NN..NNNNN..NRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRNNN", 'X' },
{ "NNN...NNNNN.....##########.NNNNNNLLLLLLLLLLLLLLLLLLLLLLLLLLNNNNNNLLLLLLLLLLLLLLLLLLLLLLLLLLNNNNNNNNNNNLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLL.....NNN..NNNNNNNNNNNNNNNNNNNNNNNLL", 'X' }
};
@@ -647,9 +647,9 @@ static UnicodeCaseTableVector caseTable1f = {{
0x1fb0, 0x1fb1, 0x1f70, 0x1f71, 0x1fb3, 0x1fbd, 0x03b9, 0x1fbf,
0x1fc0, 0x1fc1, 0x1fc2, 0x1fc3, 0x1fc4, 0x1fc5, 0x1fc6, 0x1fc7,
0x1f72, 0x1f73, 0x1f74, 0x1f75, 0x1fc3, 0x1fcd, 0x1fce, 0x1fcf,
- 0x1fd0, 0x1fd1, 0x1fd2, 0x1fd3, 0x1fd4, 0x1fd5, 0x1fd6, 0x1fd7,
+ 0x1fd0, 0x1fd1, 0x1fd2, 0x0390, 0x1fd4, 0x1fd5, 0x1fd6, 0x1fd7,
0x1fd0, 0x1fd1, 0x1f76, 0x1f77, 0x1fdc, 0x1fdd, 0x1fde, 0x1fdf,
- 0x1fe0, 0x1fe1, 0x1fe2, 0x1fe3, 0x1fe4, 0x1fe5, 0x1fe6, 0x1fe7,
+ 0x1fe0, 0x1fe1, 0x1fe2, 0x03b0, 0x1fe4, 0x1fe5, 0x1fe6, 0x1fe7,
0x1fe0, 0x1fe1, 0x1f7a, 0x1f7b, 0x1fe5, 0x1fed, 0x1fee, 0x1fef,
0x1ff0, 0x1ff1, 0x1ff2, 0x1ff3, 0x1ff4, 0x1ff5, 0x1ff6, 0x1ff7,
0x1f78, 0x1f79, 0x1f7c, 0x1f7d, 0x1ff3, 0x1ffd, 0x1ffe, 0x1fff
@@ -728,7 +728,7 @@ static UnicodeCaseTableVector caseTable2c = {{
0x2c40, 0x2c41, 0x2c42, 0x2c43, 0x2c44, 0x2c45, 0x2c46, 0x2c47,
0x2c48, 0x2c49, 0x2c4a, 0x2c4b, 0x2c4c, 0x2c4d, 0x2c4e, 0x2c4f,
0x2c50, 0x2c51, 0x2c52, 0x2c53, 0x2c54, 0x2c55, 0x2c56, 0x2c57,
- 0x2c58, 0x2c59, 0x2c5a, 0x2c5b, 0x2c5c, 0x2c5d, 0x2c5e, 0x2c2f,
+ 0x2c58, 0x2c59, 0x2c5a, 0x2c5b, 0x2c5c, 0x2c5d, 0x2c5e, 0x2c5f,
0x2c30, 0x2c31, 0x2c32, 0x2c33, 0x2c34, 0x2c35, 0x2c36, 0x2c37,
0x2c38, 0x2c39, 0x2c3a, 0x2c3b, 0x2c3c, 0x2c3d, 0x2c3e, 0x2c3f,
0x2c40, 0x2c41, 0x2c42, 0x2c43, 0x2c44, 0x2c45, 0x2c46, 0x2c47,
@@ -815,10 +815,10 @@ static UnicodeCaseTableVector caseTablea7 = {{
0xa7a9, 0xa7a9, 0x0266, 0x025c, 0x0261, 0x026c, 0x026a, 0xa7af,
0x029e, 0x0287, 0x029d, 0xab53, 0xa7b5, 0xa7b5, 0xa7b7, 0xa7b7,
0xa7b9, 0xa7b9, 0xa7bb, 0xa7bb, 0xa7bd, 0xa7bd, 0xa7bf, 0xa7bf,
- 0xa7c0, 0xa7c1, 0xa7c3, 0xa7c3, 0xa794, 0x0282, 0x1d8e, 0xa7c8,
+ 0xa7c1, 0xa7c1, 0xa7c3, 0xa7c3, 0xa794, 0x0282, 0x1d8e, 0xa7c8,
0xa7c8, 0xa7ca, 0xa7ca, 0xa7cb, 0xa7cc, 0xa7cd, 0xa7ce, 0xa7cf,
- 0xa7d0, 0xa7d1, 0xa7d2, 0xa7d3, 0xa7d4, 0xa7d5, 0xa7d6, 0xa7d7,
- 0xa7d8, 0xa7d9, 0xa7da, 0xa7db, 0xa7dc, 0xa7dd, 0xa7de, 0xa7df,
+ 0xa7d1, 0xa7d1, 0xa7d2, 0xa7d3, 0xa7d4, 0xa7d5, 0xa7d7, 0xa7d7,
+ 0xa7d9, 0xa7d9, 0xa7da, 0xa7db, 0xa7dc, 0xa7dd, 0xa7de, 0xa7df,
0xa7e0, 0xa7e1, 0xa7e2, 0xa7e3, 0xa7e4, 0xa7e5, 0xa7e6, 0xa7e7,
0xa7e8, 0xa7e9, 0xa7ea, 0xa7eb, 0xa7ec, 0xa7ed, 0xa7ee, 0xa7ef,
0xa7f0, 0xa7f1, 0xa7f2, 0xa7f3, 0xa7f4, 0xa7f6, 0xa7f6, 0xa7f7,
@@ -858,6 +858,40 @@ static UnicodeCaseTableVector caseTableab = {{
0xabf0, 0xabf1, 0xabf2, 0xabf3, 0xabf4, 0xabf5, 0xabf6, 0xabf7,
0xabf8, 0xabf9, 0xabfa, 0xabfb, 0xabfc, 0xabfd, 0xabfe, 0xabff
}};
+static UnicodeCaseTableVector caseTablefb = {{
+ 0xfb00, 0xfb01, 0xfb02, 0xfb03, 0xfb04, 0xfb06, 0xfb06, 0xfb07,
+ 0xfb08, 0xfb09, 0xfb0a, 0xfb0b, 0xfb0c, 0xfb0d, 0xfb0e, 0xfb0f,
+ 0xfb10, 0xfb11, 0xfb12, 0xfb13, 0xfb14, 0xfb15, 0xfb16, 0xfb17,
+ 0xfb18, 0xfb19, 0xfb1a, 0xfb1b, 0xfb1c, 0xfb1d, 0xfb1e, 0xfb1f,
+ 0xfb20, 0xfb21, 0xfb22, 0xfb23, 0xfb24, 0xfb25, 0xfb26, 0xfb27,
+ 0xfb28, 0xfb29, 0xfb2a, 0xfb2b, 0xfb2c, 0xfb2d, 0xfb2e, 0xfb2f,
+ 0xfb30, 0xfb31, 0xfb32, 0xfb33, 0xfb34, 0xfb35, 0xfb36, 0xfb37,
+ 0xfb38, 0xfb39, 0xfb3a, 0xfb3b, 0xfb3c, 0xfb3d, 0xfb3e, 0xfb3f,
+ 0xfb40, 0xfb41, 0xfb42, 0xfb43, 0xfb44, 0xfb45, 0xfb46, 0xfb47,
+ 0xfb48, 0xfb49, 0xfb4a, 0xfb4b, 0xfb4c, 0xfb4d, 0xfb4e, 0xfb4f,
+ 0xfb50, 0xfb51, 0xfb52, 0xfb53, 0xfb54, 0xfb55, 0xfb56, 0xfb57,
+ 0xfb58, 0xfb59, 0xfb5a, 0xfb5b, 0xfb5c, 0xfb5d, 0xfb5e, 0xfb5f,
+ 0xfb60, 0xfb61, 0xfb62, 0xfb63, 0xfb64, 0xfb65, 0xfb66, 0xfb67,
+ 0xfb68, 0xfb69, 0xfb6a, 0xfb6b, 0xfb6c, 0xfb6d, 0xfb6e, 0xfb6f,
+ 0xfb70, 0xfb71, 0xfb72, 0xfb73, 0xfb74, 0xfb75, 0xfb76, 0xfb77,
+ 0xfb78, 0xfb79, 0xfb7a, 0xfb7b, 0xfb7c, 0xfb7d, 0xfb7e, 0xfb7f,
+ 0xfb80, 0xfb81, 0xfb82, 0xfb83, 0xfb84, 0xfb85, 0xfb86, 0xfb87,
+ 0xfb88, 0xfb89, 0xfb8a, 0xfb8b, 0xfb8c, 0xfb8d, 0xfb8e, 0xfb8f,
+ 0xfb90, 0xfb91, 0xfb92, 0xfb93, 0xfb94, 0xfb95, 0xfb96, 0xfb97,
+ 0xfb98, 0xfb99, 0xfb9a, 0xfb9b, 0xfb9c, 0xfb9d, 0xfb9e, 0xfb9f,
+ 0xfba0, 0xfba1, 0xfba2, 0xfba3, 0xfba4, 0xfba5, 0xfba6, 0xfba7,
+ 0xfba8, 0xfba9, 0xfbaa, 0xfbab, 0xfbac, 0xfbad, 0xfbae, 0xfbaf,
+ 0xfbb0, 0xfbb1, 0xfbb2, 0xfbb3, 0xfbb4, 0xfbb5, 0xfbb6, 0xfbb7,
+ 0xfbb8, 0xfbb9, 0xfbba, 0xfbbb, 0xfbbc, 0xfbbd, 0xfbbe, 0xfbbf,
+ 0xfbc0, 0xfbc1, 0xfbc2, 0xfbc3, 0xfbc4, 0xfbc5, 0xfbc6, 0xfbc7,
+ 0xfbc8, 0xfbc9, 0xfbca, 0xfbcb, 0xfbcc, 0xfbcd, 0xfbce, 0xfbcf,
+ 0xfbd0, 0xfbd1, 0xfbd2, 0xfbd3, 0xfbd4, 0xfbd5, 0xfbd6, 0xfbd7,
+ 0xfbd8, 0xfbd9, 0xfbda, 0xfbdb, 0xfbdc, 0xfbdd, 0xfbde, 0xfbdf,
+ 0xfbe0, 0xfbe1, 0xfbe2, 0xfbe3, 0xfbe4, 0xfbe5, 0xfbe6, 0xfbe7,
+ 0xfbe8, 0xfbe9, 0xfbea, 0xfbeb, 0xfbec, 0xfbed, 0xfbee, 0xfbef,
+ 0xfbf0, 0xfbf1, 0xfbf2, 0xfbf3, 0xfbf4, 0xfbf5, 0xfbf6, 0xfbf7,
+ 0xfbf8, 0xfbf9, 0xfbfa, 0xfbfb, 0xfbfc, 0xfbfd, 0xfbfe, 0xfbff
+}};
static UnicodeCaseTableVector caseTableff = {{
0xff00, 0xff01, 0xff02, 0xff03, 0xff04, 0xff05, 0xff06, 0xff07,
0xff08, 0xff09, 0xff0a, 0xff0b, 0xff0c, 0xff0d, 0xff0e, 0xff0f,
@@ -1144,7 +1178,7 @@ static UnicodeCaseTableVector *caseTable[256] = {
NULL,
NULL,
NULL,
- NULL,
+ &caseTablefb,
NULL,
NULL,
NULL,
@@ -1400,8 +1434,8 @@ static Unicode bracketTable2e[256] = {
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0x80002e56, 0x2e55, 0x80002e58,
+ 0x2e57, 0x80002e5a, 0x2e59, 0x80002e5c, 0x2e5b, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
@@ -1807,6 +1841,10 @@ GBool unicodeTypeR(Unicode c) {
return getType(c) == 'R';
}
+GBool unicodeTypeCombiningMark(Unicode c) {
+ return getType(c) == 'M';
+}
+
GBool unicodeTypeDigit(Unicode c) {
return getType(c) == '#';
}
@@ -1833,7 +1871,7 @@ GBool unicodeTypeWord(Unicode c) {
char t;
t = getType(c);
- return t == 'L' || t == 'R' || t == '#';
+ return t == 'L' || t == 'R' || t == '#' || t == 'M';
}
Unicode unicodeToLower(Unicode c) {
diff --git a/Build/source/libs/xpdf/xpdf-src/xpdf/UnicodeTypeTable.h b/Build/source/libs/xpdf/xpdf-src/xpdf/UnicodeTypeTable.h
index e1149fd6bc2..f04361f9266 100644
--- a/Build/source/libs/xpdf/xpdf-src/xpdf/UnicodeTypeTable.h
+++ b/Build/source/libs/xpdf/xpdf-src/xpdf/UnicodeTypeTable.h
@@ -15,6 +15,8 @@ extern GBool unicodeTypeL(Unicode c);
extern GBool unicodeTypeR(Unicode c);
+extern GBool unicodeTypeCombiningMark(Unicode c);
+
extern GBool unicodeTypeDigit(Unicode c);
extern GBool unicodeTypeNumSep(Unicode c);
diff --git a/Build/source/libs/xpdf/xpdf-src/xpdf/WebFont.cc b/Build/source/libs/xpdf/xpdf-src/xpdf/WebFont.cc
index c04b52f937a..24d0896aa84 100644
--- a/Build/source/libs/xpdf/xpdf-src/xpdf/WebFont.cc
+++ b/Build/source/libs/xpdf/xpdf-src/xpdf/WebFont.cc
@@ -8,10 +8,6 @@
#include <aconf.h>
-#ifdef USE_GCC_PRAGMAS
-#pragma implementation
-#endif
-
#include "gmem.h"
#include "gmempp.h"
#include "GHash.h"
diff --git a/Build/source/libs/xpdf/xpdf-src/xpdf/WebFont.h b/Build/source/libs/xpdf/xpdf-src/xpdf/WebFont.h
index 283bdbe914d..c3c8ef1cbdd 100644
--- a/Build/source/libs/xpdf/xpdf-src/xpdf/WebFont.h
+++ b/Build/source/libs/xpdf/xpdf-src/xpdf/WebFont.h
@@ -13,10 +13,6 @@
#include <aconf.h>
-#ifdef USE_GCC_PRAGMAS
-#pragma interface
-#endif
-
#include "gtypes.h"
#include "FoFiBase.h"
#include "GfxFont.h"
diff --git a/Build/source/libs/xpdf/xpdf-src/xpdf/XFAScanner.cc b/Build/source/libs/xpdf/xpdf-src/xpdf/XFAScanner.cc
index 8002a07a7f6..22b2f0d02e6 100644
--- a/Build/source/libs/xpdf/xpdf-src/xpdf/XFAScanner.cc
+++ b/Build/source/libs/xpdf/xpdf-src/xpdf/XFAScanner.cc
@@ -8,10 +8,6 @@
#include <aconf.h>
-#ifdef USE_GCC_PRAGMAS
-#pragma implementation
-#endif
-
#include "GString.h"
#include "GHash.h"
#include "Object.h"
diff --git a/Build/source/libs/xpdf/xpdf-src/xpdf/XFAScanner.h b/Build/source/libs/xpdf/xpdf-src/xpdf/XFAScanner.h
index 00ee6f7fcee..22aac009048 100644
--- a/Build/source/libs/xpdf/xpdf-src/xpdf/XFAScanner.h
+++ b/Build/source/libs/xpdf/xpdf-src/xpdf/XFAScanner.h
@@ -11,10 +11,6 @@
#include <aconf.h>
-#ifdef USE_GCC_PRAGMAS
-#pragma interface
-#endif
-
class GHash;
class ZxElement;
diff --git a/Build/source/libs/xpdf/xpdf-src/xpdf/XRef.cc b/Build/source/libs/xpdf/xpdf-src/xpdf/XRef.cc
index 51af86db5ba..d3f9bcb2906 100644
--- a/Build/source/libs/xpdf/xpdf-src/xpdf/XRef.cc
+++ b/Build/source/libs/xpdf/xpdf-src/xpdf/XRef.cc
@@ -8,10 +8,6 @@
#include <aconf.h>
-#ifdef USE_GCC_PRAGMAS
-#pragma implementation
-#endif
-
#include <stdlib.h>
#include <stddef.h>
#include <string.h>
@@ -133,7 +129,7 @@ public:
// Create an object stream, using object number <objStrNum>,
// generation 0.
- ObjectStream(XRef *xref, int objStrNumA);
+ ObjectStream(XRef *xref, int objStrNumA, int recursion);
GBool isOk() { return ok; }
@@ -155,7 +151,7 @@ private:
GBool ok;
};
-ObjectStream::ObjectStream(XRef *xref, int objStrNumA) {
+ObjectStream::ObjectStream(XRef *xref, int objStrNumA, int recursion) {
Stream *str;
Lexer *lexer;
Parser *parser;
@@ -169,7 +165,7 @@ ObjectStream::ObjectStream(XRef *xref, int objStrNumA) {
objNums = NULL;
ok = gFalse;
- if (!xref->fetch(objStrNum, 0, &objStr)->isStream()) {
+ if (!xref->fetch(objStrNum, 0, &objStr, recursion)->isStream()) {
goto err1;
}
@@ -234,11 +230,10 @@ ObjectStream::ObjectStream(XRef *xref, int objStrNumA) {
lexer->skipToEOF();
delete parser;
- // skip to the first object - this shouldn't be necessary because
- // the First key is supposed to be equal to offsets[0], but just in
- // case...
- if (first < offsets[0]) {
- objStr.getStream()->discardChars(offsets[0] - first);
+ // skip to the first object - this generally shouldn't be needed,
+ // because offsets[0] is normally 0, but just in case...
+ if (offsets[0] > 0) {
+ objStr.getStream()->discardChars(offsets[0]);
}
// parse the objects
@@ -880,6 +875,7 @@ GBool XRef::constructXRef() {
char *p = buf;
char *end = buf;
GBool startOfLine = gTrue;
+ GBool space = gTrue;
GBool eof = gFalse;
while (1) {
if (end - p < 256 && !eof) {
@@ -900,6 +896,7 @@ GBool XRef::constructXRef() {
constructTrailerDict((GFileOffset)(bufPos + (p + 7 - buf)));
p += 7;
startOfLine = gFalse;
+ space = gFalse;
} else if (startOfLine && !strncmp(p, "endstream", 9)) {
if (streamEndsLen == streamEndsSize) {
streamEndsSize += 64;
@@ -909,19 +906,23 @@ GBool XRef::constructXRef() {
streamEnds[streamEndsLen++] = (GFileOffset)(bufPos + (p - buf));
p += 9;
startOfLine = gFalse;
- } else if (startOfLine && *p >= '0' && *p <= '9') {
+ space = gFalse;
+ } else if (space && *p >= '0' && *p <= '9') {
p = constructObjectEntry(p, (GFileOffset)(bufPos + (p - buf)),
&lastObjNum);
startOfLine = gFalse;
+ space = gFalse;
} else if (p[0] == '>' && p[1] == '>') {
p += 2;
startOfLine = gFalse;
+ space = gFalse;
// skip any PDF whitespace except for '\0'
while (*p == '\t' || *p == '\n' || *p == '\x0c' ||
*p == '\r' || *p == ' ') {
if (*p == '\n' || *p == '\r') {
startOfLine = gTrue;
}
+ space = gTrue;
++p;
}
if (!strncmp(p, "stream", 6)) {
@@ -935,12 +936,17 @@ GBool XRef::constructXRef() {
}
p += 6;
startOfLine = gFalse;
+ space = gFalse;
}
} else {
if (*p == '\n' || *p == '\r') {
startOfLine = gTrue;
- } else if (!Lexer::isSpace(*p & 0xff)) {
+ space = gTrue;
+ } else if (Lexer::isSpace(*p & 0xff)) {
+ space = gTrue;
+ } else {
startOfLine = gFalse;
+ space = gFalse;
}
++p;
}
@@ -1263,7 +1269,7 @@ Object *XRef::fetch(int num, int gen, Object *obj, int recursion) {
error(errSyntaxError, -1, "Invalid object stream");
goto err;
}
- if (!getObjectStreamObject((int)e->offset, e->gen, num, obj)) {
+ if (!getObjectStreamObject((int)e->offset, e->gen, num, obj, recursion)) {
goto err;
}
break;
@@ -1297,43 +1303,57 @@ Object *XRef::fetch(int num, int gen, Object *obj, int recursion) {
}
GBool XRef::getObjectStreamObject(int objStrNum, int objIdx,
- int objNum, Object *obj) {
- ObjectStream *objStr;
-
+ int objNum, Object *obj, int recursion) {
+ // check for a cached ObjectStream
#if MULTITHREADED
gLockMutex(&objStrsMutex);
#endif
- if (!(objStr = getObjectStream(objStrNum))) {
+ ObjectStream *objStr = getObjectStreamFromCache(objStrNum);
+ GBool found = gFalse;
+ if (objStr) {
+ objStr->getObject(objIdx, objNum, obj);
+ cleanObjectStreamCache();
+ found = gTrue;
+ }
#if MULTITHREADED
- gUnlockMutex(&objStrsMutex);
+ gUnlockMutex(&objStrsMutex);
#endif
+ if (found) {
+ return gTrue;
+ }
+
+ // load a new ObjectStream
+ objStr = new ObjectStream(this, objStrNum, recursion);
+ if (!objStr->isOk()) {
+ delete objStr;
return gFalse;
}
- cleanObjectStreamCache();
objStr->getObject(objIdx, objNum, obj);
#if MULTITHREADED
+ gLockMutex(&objStrsMutex);
+#endif
+ addObjectStreamToCache(objStr);
+ cleanObjectStreamCache();
+#if MULTITHREADED
gUnlockMutex(&objStrsMutex);
#endif
return gTrue;
}
// NB: objStrsMutex must be locked when calling this function.
-ObjectStream *XRef::getObjectStream(int objStrNum) {
- ObjectStream *objStr;
- int i, j;
-
+ObjectStream *XRef::getObjectStreamFromCache(int objStrNum) {
// check the MRU entry in the cache
if (objStrs[0] && objStrs[0]->getObjStrNum() == objStrNum) {
- objStr = objStrs[0];
+ ObjectStream *objStr = objStrs[0];
objStrLastUse[0] = objStrTime++;
return objStr;
}
// check the rest of the cache
- for (i = 1; i < objStrCacheLength; ++i) {
+ for (int i = 1; i < objStrCacheLength; ++i) {
if (objStrs[i] && objStrs[i]->getObjStrNum() == objStrNum) {
- objStr = objStrs[i];
- for (j = i; j > 0; --j) {
+ ObjectStream *objStr = objStrs[i];
+ for (int j = i; j > 0; --j) {
objStrs[j] = objStrs[j - 1];
objStrLastUse[j] = objStrLastUse[j - 1];
}
@@ -1343,33 +1363,30 @@ ObjectStream *XRef::getObjectStream(int objStrNum) {
}
}
- // load a new ObjectStream
- objStr = new ObjectStream(this, objStrNum);
- if (!objStr->isOk()) {
- delete objStr;
- return NULL;
- }
+ return NULL;
+}
+// NB: objStrsMutex must be locked when calling this function.
+void XRef::addObjectStreamToCache(ObjectStream *objStr) {
// add to the cache
if (objStrCacheLength == objStrCacheSize) {
delete objStrs[objStrCacheSize - 1];
--objStrCacheLength;
}
- for (j = objStrCacheLength; j > 0; --j) {
+ for (int j = objStrCacheLength; j > 0; --j) {
objStrs[j] = objStrs[j - 1];
objStrLastUse[j] = objStrLastUse[j - 1];
}
++objStrCacheLength;
objStrs[0] = objStr;
objStrLastUse[0] = objStrTime++;
-
- return objStr;
}
// If the oldest (least recently used) entry in the object stream
// cache is more than objStrCacheTimeout accesses old (hasn't been
// used in the last objStrCacheTimeout accesses), eject it from the
// cache.
+// NB: objStrsMutex must be locked when calling this function.
void XRef::cleanObjectStreamCache() {
// NB: objStrTime and objStrLastUse[] are unsigned ints, so the
// mod-2^32 arithmetic makes the subtraction work out, even if the
diff --git a/Build/source/libs/xpdf/xpdf-src/xpdf/XRef.h b/Build/source/libs/xpdf/xpdf-src/xpdf/XRef.h
index 10e4e6a7501..662b8351c00 100644
--- a/Build/source/libs/xpdf/xpdf-src/xpdf/XRef.h
+++ b/Build/source/libs/xpdf/xpdf-src/xpdf/XRef.h
@@ -11,10 +11,6 @@
#include <aconf.h>
-#ifdef USE_GCC_PRAGMAS
-#pragma interface
-#endif
-
#include "gtypes.h"
#include "gfile.h"
#include "Object.h"
@@ -183,8 +179,9 @@ private:
GBool constructXRefEntry(int num, int gen, GFileOffset pos,
XRefEntryType type);
GBool getObjectStreamObject(int objStrNum, int objIdx,
- int objNum, Object *obj);
- ObjectStream *getObjectStream(int objStrNum);
+ int objNum, Object *obj, int recursion);
+ ObjectStream *getObjectStreamFromCache(int objStrNum);
+ void addObjectStreamToCache(ObjectStream *objStr);
void cleanObjectStreamCache();
GFileOffset strToFileOffset(char *s);
};
diff --git a/Build/source/libs/xpdf/xpdf-src/xpdf/Zoox.cc b/Build/source/libs/xpdf/xpdf-src/xpdf/Zoox.cc
index 9e4fb47900c..2e41d990b59 100644
--- a/Build/source/libs/xpdf/xpdf-src/xpdf/Zoox.cc
+++ b/Build/source/libs/xpdf/xpdf-src/xpdf/Zoox.cc
@@ -6,10 +6,6 @@
#include <aconf.h>
-#ifdef USE_GCC_PRAGMAS
-#pragma implementation
-#endif
-
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
@@ -279,6 +275,8 @@ bool ZxDoc::parse(const char *data, Guint dataLen) {
parseEnd = data + dataLen;
parseSpace();
+ parseBOM();
+ parseSpace();
parseXMLDecl(this);
parseMisc(this);
parseDocTypeDecl(this);
@@ -783,6 +781,12 @@ GString *ZxDoc::parseQuotedString() {
return s;
}
+void ZxDoc::parseBOM() {
+ if (match("\xef\xbb\xbf")) {
+ parsePtr += 3;
+ }
+}
+
void ZxDoc::parseSpace() {
while (parsePtr < parseEnd && (*parsePtr == '\x20' ||
*parsePtr == '\x09' ||
diff --git a/Build/source/libs/xpdf/xpdf-src/xpdf/Zoox.h b/Build/source/libs/xpdf/xpdf-src/xpdf/Zoox.h
index c04ca95064b..c89cd67b065 100644
--- a/Build/source/libs/xpdf/xpdf-src/xpdf/Zoox.h
+++ b/Build/source/libs/xpdf/xpdf-src/xpdf/Zoox.h
@@ -9,10 +9,6 @@
#include <aconf.h>
-#ifdef USE_GCC_PRAGMAS
-#pragma interface
-#endif
-
#include "gtypes.h"
class GString;
@@ -110,6 +106,7 @@ private:
void parsePI(ZxNode *par);
GString *parseName();
GString *parseQuotedString();
+ void parseBOM();
void parseSpace();
bool match(const char *s);
diff --git a/Build/source/libs/xpdf/xpdf-src/xpdf/config.h b/Build/source/libs/xpdf/xpdf-src/xpdf/config.h
index b41dd492248..6bd00d500ae 100644
--- a/Build/source/libs/xpdf/xpdf-src/xpdf/config.h
+++ b/Build/source/libs/xpdf/xpdf-src/xpdf/config.h
@@ -2,7 +2,7 @@
//
// config.h
//
-// Copyright 1996-2022 Glyph & Cog, LLC
+// Copyright 1996-2024 Glyph & Cog, LLC
//
//========================================================================
@@ -14,13 +14,13 @@
//------------------------------------------------------------------------
// xpdf version
-#define xpdfVersion "4.04"
-#define xpdfVersionNum 4.04
+#define xpdfVersion "4.05"
+#define xpdfVersionNum 4.05
#define xpdfMajorVersion 4
-#define xpdfMinorVersion 4
+#define xpdfMinorVersion 5
#define xpdfUpdateVersion 0
#define xpdfMajorVersionStr "4"
-#define xpdfMinorVersionStr "4"
+#define xpdfMinorVersionStr "5"
#define xpdfUpdateVersionStr "0"
// supported PDF version
@@ -28,11 +28,11 @@
#define supportedPDFVersionNum 2.0
// copyright notice
-#define xpdfCopyright "Copyright 1996-2022 Glyph & Cog, LLC"
+#define xpdfCopyright "Copyright 1996-2024 Glyph & Cog, LLC"
// Windows resource file stuff
-#define winxpdfVersion "WinXpdf 4.04"
-#define xpdfCopyrightAmp "Copyright 1996-2022 Glyph && Cog, LLC"
+#define winxpdfVersion "WinXpdf 4.05"
+#define xpdfCopyrightAmp "Copyright 1996-2024 Glyph && Cog, LLC"
//------------------------------------------------------------------------
// paper size
diff --git a/Build/source/libs/xpdf/xpdf-src/xpdf/pdfdetach.cc b/Build/source/libs/xpdf/xpdf-src/xpdf/pdfdetach.cc
index 581383fe730..1b80fe474b6 100644
--- a/Build/source/libs/xpdf/xpdf-src/xpdf/pdfdetach.cc
+++ b/Build/source/libs/xpdf/xpdf-src/xpdf/pdfdetach.cc
@@ -62,6 +62,10 @@ static ArgDesc argDesc[] = {
};
int main(int argc, char *argv[]) {
+#if USE_EXCEPTIONS
+ try {
+#endif
+
char *fileName;
UnicodeMap *uMap;
GString *ownerPW, *userPW;
@@ -213,4 +217,11 @@ int main(int argc, char *argv[]) {
gMemReport(stderr);
return exitCode;
+
+#if USE_EXCEPTIONS
+ } catch (GMemException e) {
+ fprintf(stderr, "Out of memory\n");
+ return 98;
+ }
+#endif
}
diff --git a/Build/source/libs/xpdf/xpdf-src/xpdf/pdffonts.cc b/Build/source/libs/xpdf/xpdf-src/xpdf/pdffonts.cc
index bde57557c3c..ad9e40d7c62 100644
--- a/Build/source/libs/xpdf/xpdf-src/xpdf/pdffonts.cc
+++ b/Build/source/libs/xpdf/xpdf-src/xpdf/pdffonts.cc
@@ -96,6 +96,10 @@ static char *seenObjs;
static int numObjects;
int main(int argc, char *argv[]) {
+#if USE_EXCEPTIONS
+ try {
+#endif
+
char *fileName;
GString *ownerPW, *userPW;
GBool ok;
@@ -174,22 +178,21 @@ int main(int argc, char *argv[]) {
numObjects = doc->getXRef()->getNumObjects();
seenObjs = (char *)gmalloc(numObjects);
memset(seenObjs, 0, numObjects);
+ annots = doc->getAnnots();
for (pg = firstPage; pg <= lastPage; ++pg) {
page = doc->getCatalog()->getPage(pg);
if ((resDict = page->getResourceDict())) {
scanFonts(resDict, doc);
}
- annots = new Annots(doc, page->getAnnots(&obj1));
- obj1.free();
- for (i = 0; i < annots->getNumAnnots(); ++i) {
- if (annots->getAnnot(i)->getAppearance(&obj1)->isStream()) {
+ int nAnnots = annots->getNumAnnots(pg);
+ for (i = 0; i < nAnnots; ++i) {
+ if (annots->getAnnot(pg, i)->getAppearance(&obj1)->isStream()) {
obj1.streamGetDict()->lookupNF("Resources", &obj2);
scanFonts(&obj2, doc);
obj2.free();
}
obj1.free();
}
- delete annots;
}
if ((form = doc->getCatalog()->getForm())) {
for (i = 0; i < form->getNumFields(); ++i) {
@@ -222,6 +225,13 @@ int main(int argc, char *argv[]) {
gMemReport(stderr);
return exitCode;
+
+#if USE_EXCEPTIONS
+ } catch (GMemException e) {
+ fprintf(stderr, "Out of memory\n");
+ return 98;
+ }
+#endif
}
static void scanFonts(Object *obj, PDFDoc *doc) {
diff --git a/Build/source/libs/xpdf/xpdf-src/xpdf/pdfimages.cc b/Build/source/libs/xpdf/xpdf-src/xpdf/pdfimages.cc
index 346346bce77..303a046932d 100644
--- a/Build/source/libs/xpdf/xpdf-src/xpdf/pdfimages.cc
+++ b/Build/source/libs/xpdf/xpdf-src/xpdf/pdfimages.cc
@@ -76,6 +76,10 @@ static ArgDesc argDesc[] = {
};
int main(int argc, char *argv[]) {
+#if USE_EXCEPTIONS
+ try {
+#endif
+
PDFDoc *doc;
char *fileName;
char *imgRoot;
@@ -171,4 +175,11 @@ int main(int argc, char *argv[]) {
gMemReport(stderr);
return exitCode;
+
+#if USE_EXCEPTIONS
+ } catch (GMemException e) {
+ fprintf(stderr, "Out of memory\n");
+ return 98;
+ }
+#endif
}
diff --git a/Build/source/libs/xpdf/xpdf-src/xpdf/pdfinfo.cc b/Build/source/libs/xpdf/xpdf-src/xpdf/pdfinfo.cc
index 88829b993c3..a1fb5c2327d 100644
--- a/Build/source/libs/xpdf/xpdf-src/xpdf/pdfinfo.cc
+++ b/Build/source/libs/xpdf/xpdf-src/xpdf/pdfinfo.cc
@@ -41,6 +41,7 @@ static void printInfoString(Object *infoDict, const char *infoKey,
const char *xmpKey2,
const char *text, GBool parseDate,
UnicodeMap *uMap);
+static void printCustomInfo(Object *infoDict, UnicodeMap *uMap);
static GString *parseInfoDate(GString *s);
static GString *parseXMPDate(GString *s);
static void printBox(const char *text, PDFRectangle *box);
@@ -50,6 +51,7 @@ static int lastPage = 0;
static GBool printBoxes = gFalse;
static GBool printMetadata = gFalse;
static GBool rawDates = gFalse;
+static GBool printCustom = gFalse;
static char textEncName[128] = "";
static char ownerPassword[33] = "\001";
static char userPassword[33] = "\001";
@@ -68,6 +70,8 @@ static ArgDesc argDesc[] = {
"print the document metadata (XML)"},
{"-rawdates", argFlag, &rawDates, 0,
"print the undecoded date strings directly from the PDF file"},
+ {"-custom", argFlag, &printCustom, 0,
+ "print the custom info dictionary fields"},
{"-enc", argString, textEncName, sizeof(textEncName),
"output text encoding name"},
{"-opw", argString, ownerPassword, sizeof(ownerPassword),
@@ -90,6 +94,10 @@ static ArgDesc argDesc[] = {
};
int main(int argc, char *argv[]) {
+#if USE_EXCEPTIONS
+ try {
+#endif
+
PDFDoc *doc;
char *fileName;
GString *ownerPW, *userPW;
@@ -193,6 +201,9 @@ int main(int argc, char *argv[]) {
printInfoString(&info, "Producer", xmp, "pdf:Producer", NULL, "Producer: ", gFalse, uMap);
printInfoString(&info, "CreationDate", xmp, "xap:CreateDate", "xmp:CreateDate", "CreationDate: ", !rawDates, uMap);
printInfoString(&info, "ModDate", xmp, "xap:ModifyDate", "xmp:ModifyDate", "ModDate: ", !rawDates, uMap);
+ if (printCustom) {
+ printCustomInfo(&info, uMap);
+ }
info.free();
if (xmp) {
delete xmp;
@@ -304,6 +315,9 @@ int main(int argc, char *argv[]) {
// print linearization info
printf("Optimized: %s\n", doc->isLinearized() ? "yes" : "no");
+ // print JavaScript info
+ printf("JavaScript: %s\n", doc->usesJavaScript() ? "yes" : "no");
+
// print PDF version
printf("PDF version: %.1f\n", doc->getPDFVersion());
@@ -333,6 +347,13 @@ int main(int argc, char *argv[]) {
gMemReport(stderr);
return exitCode;
+
+#if USE_EXCEPTIONS
+ } catch (GMemException e) {
+ fprintf(stderr, "Out of memory\n");
+ return 98;
+ }
+#endif
}
static void printInfoString(Object *infoDict, const char *infoKey,
@@ -397,7 +418,7 @@ static void printInfoString(Object *infoDict, const char *infoKey,
if (!parseDate ||
!(value = parseXMPDate(((ZxCharData *)node2)->getData()))) {
tmp = ((ZxCharData *)node2)->getData();
- int i = 0;
+ i = 0;
value = new GString();
while (getUTF8(tmp, &i, &uu)) {
n = uMap->mapUnicode(uu, buf, sizeof(buf));
@@ -414,12 +435,48 @@ static void printInfoString(Object *infoDict, const char *infoKey,
if (value) {
fputs(text, stdout);
- fwrite(value->getCString(), 1, value->getLength(), stdout);
+ fwrite(value->getCString(), 1, value->getLength(), stdout);
fputc('\n', stdout);
delete value;
}
}
+static void printCustomInfo(Object *infoDict, UnicodeMap *uMap) {
+ if (!infoDict->isDict()) {
+ return;
+ }
+ for (int i = 0; i < infoDict->dictGetLength(); ++i) {
+ char *key = infoDict->dictGetKey(i);
+ Object obj;
+ infoDict->dictGetVal(i, &obj);
+ if (obj.isString() &&
+ strcmp(key, "Title") &&
+ strcmp(key, "Subject") &&
+ strcmp(key, "Keywords") &&
+ strcmp(key, "Author") &&
+ strcmp(key, "Creator") &&
+ strcmp(key, "Producer") &&
+ strcmp(key, "CreationDate") &&
+ strcmp(key, "ModDate")) {
+ printf("%s: ", key);
+ int n = 14 - (int)strlen(key);
+ if (n > 0) {
+ printf("%*s", n, "");
+ }
+ TextString *s = new TextString(obj.getString());
+ Unicode *u = s->getUnicode();
+ char buf[8];
+ for (int j = 0; j < s->getLength(); ++j) {
+ n = uMap->mapUnicode(u[j], buf, sizeof(buf));
+ fwrite(buf, 1, n, stdout);
+ }
+ delete s;
+ printf("\n");
+ }
+ obj.free();
+ }
+}
+
static GString *parseInfoDate(GString *s) {
int year, mon, day, hour, min, sec, n;
struct tm tmStruct;
diff --git a/Build/source/libs/xpdf/xpdf-src/xpdf/pdftohtml.cc b/Build/source/libs/xpdf/xpdf-src/xpdf/pdftohtml.cc
index 4c98afed50c..92d78b0e5dc 100644
--- a/Build/source/libs/xpdf/xpdf-src/xpdf/pdftohtml.cc
+++ b/Build/source/libs/xpdf/xpdf-src/xpdf/pdftohtml.cc
@@ -38,7 +38,9 @@ static GBool embedFonts = gFalse;
static GBool skipInvisible = gFalse;
static GBool allInvisible = gFalse;
static GBool formFields = gFalse;
+static GBool includeMetadata = gFalse;
static GBool tableMode = gFalse;
+static GBool overwrite = gFalse;
static char ownerPassword[33] = "\001";
static char userPassword[33] = "\001";
static GBool verbose = gFalse;
@@ -70,8 +72,12 @@ static ArgDesc argDesc[] = {
"treat all text as invisible"},
{"-formfields", argFlag, &formFields, 0,
"convert form fields to HTML"},
+ {"-meta", argFlag, &includeMetadata, 0,
+ "include document metadata in the HTML output"},
{"-table", argFlag, &tableMode, 0,
"use table mode for text extraction"},
+ {"-overwrite", argFlag, &overwrite, 0,
+ "overwrite files in an existing output directory"},
{"-opw", argString, ownerPassword, sizeof(ownerPassword),
"owner password (for encrypted files)"},
{"-upw", argString, userPassword, sizeof(userPassword),
@@ -102,6 +108,10 @@ static int writeToFile(void *file, const char *data, int size) {
}
int main(int argc, char *argv[]) {
+#if USE_EXCEPTIONS
+ try {
+#endif
+
PDFDoc *doc;
char *fileName;
char *htmlDir;
@@ -184,10 +194,19 @@ int main(int argc, char *argv[]) {
// create HTML directory
if (makeDir(htmlDir, 0755)) {
- error(errIO, -1, "Couldn't create HTML output directory '{0:s}'",
- htmlDir);
- exitCode = 2;
- goto err1;
+ if (pathIsDir(htmlDir)) {
+ if (!overwrite) {
+ error(errIO, -1, "HTML output directory '{0:s}' already exists (use '-overwrite' to overwrite it)",
+ htmlDir);
+ exitCode = 2;
+ goto err1;
+ }
+ } else {
+ error(errIO, -1, "Couldn't create HTML output directory '{0:s}'",
+ htmlDir);
+ exitCode = 2;
+ goto err1;
+ }
}
// set up the HTMLGen object
@@ -204,6 +223,7 @@ int main(int argc, char *argv[]) {
htmlGen->setExtractFontFiles(!noFonts);
htmlGen->setEmbedFonts(embedFonts);
htmlGen->setConvertFormFields(formFields);
+ htmlGen->setIncludeMetadata(includeMetadata);
htmlGen->startDoc(doc);
// convert the pages
@@ -271,6 +291,13 @@ int main(int argc, char *argv[]) {
gMemReport(stderr);
return exitCode;
+
+#if USE_EXCEPTIONS
+ } catch (GMemException e) {
+ fprintf(stderr, "Out of memory\n");
+ return 98;
+ }
+#endif
}
static GBool createIndex(char *htmlDir) {
@@ -280,11 +307,12 @@ static GBool createIndex(char *htmlDir) {
htmlFileName = GString::format("{0:s}/index.html", htmlDir);
html = openFile(htmlFileName->getCString(), "w");
- delete htmlFileName;
if (!html) {
error(errIO, -1, "Couldn't open HTML file '{0:t}'", htmlFileName);
+ delete htmlFileName;
return gFalse;
}
+ delete htmlFileName;
fprintf(html, "<html>\n");
fprintf(html, "<body>\n");
diff --git a/Build/source/libs/xpdf/xpdf-src/xpdf/pdftopng.cc b/Build/source/libs/xpdf/xpdf-src/xpdf/pdftopng.cc
index 7f3b97b9d94..e4107f59899 100644
--- a/Build/source/libs/xpdf/xpdf-src/xpdf/pdftopng.cc
+++ b/Build/source/libs/xpdf/xpdf-src/xpdf/pdftopng.cc
@@ -99,6 +99,10 @@ static void writePNGData(png_structp png, SplashBitmap *bitmap);
static void finishPNG(png_structp *png, png_infop *pngInfo);
int main(int argc, char *argv[]) {
+#if USE_EXCEPTIONS
+ try {
+#endif
+
PDFDoc *doc;
char *fileName;
char *pngRoot;
@@ -296,6 +300,13 @@ int main(int argc, char *argv[]) {
gMemReport(stderr);
return exitCode;
+
+#if USE_EXCEPTIONS
+ } catch (GMemException e) {
+ fprintf(stderr, "Out of memory\n");
+ return 98;
+ }
+#endif
}
static void setupPNG(png_structp *png, png_infop *pngInfo, FILE *f,
diff --git a/Build/source/libs/xpdf/xpdf-src/xpdf/pdftoppm.cc b/Build/source/libs/xpdf/xpdf-src/xpdf/pdftoppm.cc
index 28861ef948b..c4dc3494a72 100644
--- a/Build/source/libs/xpdf/xpdf-src/xpdf/pdftoppm.cc
+++ b/Build/source/libs/xpdf/xpdf-src/xpdf/pdftoppm.cc
@@ -98,6 +98,10 @@ static ArgDesc argDesc[] = {
};
int main(int argc, char *argv[]) {
+#if USE_EXCEPTIONS
+ try {
+#endif
+
PDFDoc *doc;
char *fileName;
char *ppmRoot;
@@ -277,4 +281,11 @@ int main(int argc, char *argv[]) {
gMemReport(stderr);
return exitCode;
+
+#if USE_EXCEPTIONS
+ } catch (GMemException e) {
+ fprintf(stderr, "Out of memory\n");
+ return 98;
+ }
+#endif
}
diff --git a/Build/source/libs/xpdf/xpdf-src/xpdf/pdftops.cc b/Build/source/libs/xpdf/xpdf-src/xpdf/pdftops.cc
index 77e90fe0165..c6c7c4767ec 100644
--- a/Build/source/libs/xpdf/xpdf-src/xpdf/pdftops.cc
+++ b/Build/source/libs/xpdf/xpdf-src/xpdf/pdftops.cc
@@ -153,6 +153,10 @@ static ArgDesc argDesc[] = {
};
int main(int argc, char *argv[]) {
+#if USE_EXCEPTIONS
+ try {
+#endif
+
PDFDoc *doc;
char *fileName;
GString *psFileName;
@@ -396,4 +400,11 @@ int main(int argc, char *argv[]) {
gMemReport(stderr);
return exitCode;
+
+#if USE_EXCEPTIONS
+ } catch (GMemException e) {
+ fprintf(stderr, "Out of memory\n");
+ return 98;
+ }
+#endif
}
diff --git a/Build/source/libs/xpdf/xpdf-src/xpdf/pdftotext.cc b/Build/source/libs/xpdf/xpdf-src/xpdf/pdftotext.cc
index d8bf6df5e67..928de607678 100644
--- a/Build/source/libs/xpdf/xpdf-src/xpdf/pdftotext.cc
+++ b/Build/source/libs/xpdf/xpdf-src/xpdf/pdftotext.cc
@@ -132,6 +132,10 @@ static ArgDesc argDesc[] = {
};
int main(int argc, char *argv[]) {
+#if USE_EXCEPTIONS
+ try {
+#endif
+
PDFDoc *doc;
char *fileName;
GString *textFileName;
@@ -329,4 +333,11 @@ int main(int argc, char *argv[]) {
gMemReport(stderr);
return exitCode;
+
+#if USE_EXCEPTIONS
+ } catch (GMemException e) {
+ fprintf(stderr, "Out of memory\n");
+ return 98;
+ }
+#endif
}