summaryrefslogtreecommitdiff
Side-by-side diff
Diffstat (more/less context) (ignore whitespace changes)
-rw-r--r--noncore/unsupported/qpdf/QOutputDev.h7
-rw-r--r--noncore/unsupported/qpdf/README45
-rw-r--r--noncore/unsupported/qpdf/UTF8.h14
-rw-r--r--noncore/unsupported/qpdf/qpdf.cpp13
-rw-r--r--noncore/unsupported/qpdf/qpdf.h7
-rw-r--r--noncore/unsupported/qpdf/qpdf.pro5
-rw-r--r--noncore/unsupported/qpdf/xpdf/Annot.cc (renamed from noncore/unsupported/qpdf/xpdf/FormWidget.cc)53
-rw-r--r--noncore/unsupported/qpdf/xpdf/Annot.h (renamed from noncore/unsupported/qpdf/xpdf/FormWidget.h)40
-rw-r--r--noncore/unsupported/qpdf/xpdf/Array.cc2
-rw-r--r--noncore/unsupported/qpdf/xpdf/Array.h2
-rw-r--r--noncore/unsupported/qpdf/xpdf/BuiltinFont.h2
-rw-r--r--noncore/unsupported/qpdf/xpdf/BuiltinFontTables.cc2
-rw-r--r--noncore/unsupported/qpdf/xpdf/BuiltinFontTables.h2
-rw-r--r--noncore/unsupported/qpdf/xpdf/CMap.cc104
-rw-r--r--noncore/unsupported/qpdf/xpdf/CMap.h2
-rw-r--r--noncore/unsupported/qpdf/xpdf/Catalog.cc8
-rw-r--r--noncore/unsupported/qpdf/xpdf/Catalog.h2
-rw-r--r--noncore/unsupported/qpdf/xpdf/CharCodeToUnicode.cc160
-rw-r--r--noncore/unsupported/qpdf/xpdf/CharCodeToUnicode.h5
-rw-r--r--noncore/unsupported/qpdf/xpdf/CharTypes.h2
-rw-r--r--noncore/unsupported/qpdf/xpdf/Decrypt.cc2
-rw-r--r--noncore/unsupported/qpdf/xpdf/Decrypt.h2
-rw-r--r--noncore/unsupported/qpdf/xpdf/Dict.cc2
-rw-r--r--noncore/unsupported/qpdf/xpdf/Dict.h2
-rw-r--r--noncore/unsupported/qpdf/xpdf/DisplayFontTable.h6
-rw-r--r--noncore/unsupported/qpdf/xpdf/Error.cc2
-rw-r--r--noncore/unsupported/qpdf/xpdf/Error.h2
-rw-r--r--noncore/unsupported/qpdf/xpdf/ErrorCodes.h24
-rw-r--r--noncore/unsupported/qpdf/xpdf/FontEncodingTables.cc2
-rw-r--r--noncore/unsupported/qpdf/xpdf/FontEncodingTables.h2
-rw-r--r--noncore/unsupported/qpdf/xpdf/Function.cc13
-rw-r--r--noncore/unsupported/qpdf/xpdf/Function.h2
-rw-r--r--noncore/unsupported/qpdf/xpdf/Gfx.cc589
-rw-r--r--noncore/unsupported/qpdf/xpdf/Gfx.h20
-rw-r--r--noncore/unsupported/qpdf/xpdf/GfxFont.cc62
-rw-r--r--noncore/unsupported/qpdf/xpdf/GfxFont.h24
-rw-r--r--noncore/unsupported/qpdf/xpdf/GfxState.cc246
-rw-r--r--noncore/unsupported/qpdf/xpdf/GfxState.h39
-rw-r--r--noncore/unsupported/qpdf/xpdf/GlobalParams.cc381
-rw-r--r--noncore/unsupported/qpdf/xpdf/GlobalParams.h49
-rw-r--r--noncore/unsupported/qpdf/xpdf/Lexer.cc2
-rw-r--r--noncore/unsupported/qpdf/xpdf/Lexer.h11
-rw-r--r--noncore/unsupported/qpdf/xpdf/Link.cc34
-rw-r--r--noncore/unsupported/qpdf/xpdf/Link.h8
-rw-r--r--noncore/unsupported/qpdf/xpdf/NameToCharCode.cc2
-rw-r--r--noncore/unsupported/qpdf/xpdf/NameToCharCode.h2
-rw-r--r--noncore/unsupported/qpdf/xpdf/NameToUnicodeTable.h2
-rw-r--r--noncore/unsupported/qpdf/xpdf/Object.cc2
-rw-r--r--noncore/unsupported/qpdf/xpdf/Object.h12
-rw-r--r--noncore/unsupported/qpdf/xpdf/OutputDev.cc7
-rw-r--r--noncore/unsupported/qpdf/xpdf/OutputDev.h17
-rw-r--r--noncore/unsupported/qpdf/xpdf/PDFDoc.cc16
-rw-r--r--noncore/unsupported/qpdf/xpdf/PDFDoc.h6
-rw-r--r--noncore/unsupported/qpdf/xpdf/PSTokenizer.cc133
-rw-r--r--noncore/unsupported/qpdf/xpdf/PSTokenizer.h39
-rw-r--r--noncore/unsupported/qpdf/xpdf/Page.cc40
-rw-r--r--noncore/unsupported/qpdf/xpdf/Page.h28
-rw-r--r--noncore/unsupported/qpdf/xpdf/Parser.cc11
-rw-r--r--noncore/unsupported/qpdf/xpdf/Parser.h2
-rw-r--r--noncore/unsupported/qpdf/xpdf/Stream-CCITT.h2
-rw-r--r--noncore/unsupported/qpdf/xpdf/Stream.cc215
-rw-r--r--noncore/unsupported/qpdf/xpdf/Stream.h113
-rw-r--r--noncore/unsupported/qpdf/xpdf/TextOutputDev.cc73
-rw-r--r--noncore/unsupported/qpdf/xpdf/TextOutputDev.h22
-rw-r--r--noncore/unsupported/qpdf/xpdf/UnicodeMap.cc2
-rw-r--r--noncore/unsupported/qpdf/xpdf/UnicodeMap.h2
-rw-r--r--noncore/unsupported/qpdf/xpdf/UnicodeMapTables.h60
-rw-r--r--noncore/unsupported/qpdf/xpdf/XRef.cc80
-rw-r--r--noncore/unsupported/qpdf/xpdf/XRef.h25
69 files changed, 2201 insertions, 715 deletions
diff --git a/noncore/unsupported/qpdf/QOutputDev.h b/noncore/unsupported/qpdf/QOutputDev.h
index 2958062..f3c5a01 100644
--- a/noncore/unsupported/qpdf/QOutputDev.h
+++ b/noncore/unsupported/qpdf/QOutputDev.h
@@ -81,2 +81,9 @@ public:
+ // Does this device use beginType3Char/endType3Char? Otherwise,
+ // text in Type 3 fonts will be drawn with drawChar/drawString.
+ virtual GBool interpretType3Chars() { return gFalse; }
+
+ // Does this device need non-text content?
+ virtual GBool needNonText() { return gFalse; }
+
//----- initialization and control
diff --git a/noncore/unsupported/qpdf/README b/noncore/unsupported/qpdf/README
index 36ce6bc..65e7aaf 100644
--- a/noncore/unsupported/qpdf/README
+++ b/noncore/unsupported/qpdf/README
@@ -3,3 +3,3 @@ QPDF - a PDF viewer for the Qtopia environment
-This tool is based on xpdf (currently 1.00). It uses the (mostly unmodified -
+This tool is based on xpdf (currently 1.01). It uses the (mostly unmodified -
see below) xpdf PDF rendering engine. The Qtopia adaption was done with a new
@@ -22,3 +22,3 @@ Changes in 20020408:
-Changed in 20020413:
+Changes in 20020413:
- Fixed crash in find routine
@@ -28,2 +28,9 @@ Changed in 20020413:
+Changes in 20020417:
+ - Fixed crash in XPDF regarding 0-length strings.
+ - Fast sqrt, rint and fabs functions added.
+
+Changes in 20020524:
+ - Ported to xpdf 1.01
+
@@ -54,23 +61,8 @@ ToDo:
Install:
- - xpdf-1.00
- Get the tarball for xpdf, version 1.0, untar it and ./configure it.
- (No special flags are needed for ./configure - it simply has to run)
-
- - qpdf
- Make sure your QPEDIR / TMAKEPATH variables are correctly !
-
- cd into the xpdf directory (xpdf-1.00) and untar the qpdf tarball. This
- should create a subdirectory qpdf.
- cd into this directory and start the script "./setup-qpdf". This
- incorporates the above mentioned patches into xpdf.
-
- Now do a make.
-
- Copy the files qpdf, qpdf_icon.png and qpdf.desktop to the appropriate
- directories on your iPaq or:
- If you want a ipk, just run ./mkipkg
+ - Qpdf is now fully integrated into Opie. For compilation and installation
+ instructions see http://opie.handhelds.org.
- compress / uncompress
- If you run a normal familiar installation, it the standard gzip (I tested
- 1.2.4-33 ipkg) can handle the compression format used in PDF files, when
+ If you run a normal familiar installation, the standard gzip (I tested
+ 1.2.4-33 ipkg) can handle the compression format used in PDF files, when
called as uncompress. The BusyBox version of gzip can _not_ handle this
@@ -78,8 +70,7 @@ Install:
- If you do not have a working uncompress installed on your iPaq, you can
- simply use the one in the contrib directory of the tarball (make uncompress
- a link to compress).
- [I could not find an official tarball for compress -- this is the SuSE
- version cross-compiled for ARM]
-
+ If you do not have a working uncompress installed on your iPaq, you could
+ simply use the old compress package.
+ (I could not find an official tarball for compress -- I used the SuSE
+ version cross-compiled for ARM for myself, but I will make an ipk soon)
+
diff --git a/noncore/unsupported/qpdf/UTF8.h b/noncore/unsupported/qpdf/UTF8.h
index aacf663..95adecf 100644
--- a/noncore/unsupported/qpdf/UTF8.h
+++ b/noncore/unsupported/qpdf/UTF8.h
@@ -24 +24,15 @@ static int mapUTF8 ( Unicode u, char *buf, int bufSize )
}
+
+static int mapUCS2 ( Unicode u, char *buf, int bufSize)
+{
+ if (u <= 0xffff) {
+ if (bufSize < 2)
+ return 0;
+
+ buf[0] = (char)((u >> 8) & 0xff);
+ buf[1] = (char)(u & 0xff);
+ return 2;
+ }
+ else
+ return 0;
+}
diff --git a/noncore/unsupported/qpdf/qpdf.cpp b/noncore/unsupported/qpdf/qpdf.cpp
index 6c268ec..f338509 100644
--- a/noncore/unsupported/qpdf/qpdf.cpp
+++ b/noncore/unsupported/qpdf/qpdf.cpp
@@ -18,3 +18,2 @@
#include <qpe/applnk.h>
-#include <qpe/fileselector.h>
#include <qpe/qcopenvelope_qws.h>
@@ -24,2 +23,3 @@
#include <qtoolbar.h>
+#include <qtoolbutton.h>
#include <qmenubar.h>
@@ -39,2 +39,8 @@
+#ifdef QPDF_QPE_ONLY
+#include <qpe/fileselector.h>
+#else
+#include <opie/ofileselector.h>
+#endif
+
@@ -83,3 +89,8 @@ QPdfDlg::QPdfDlg ( ) : QMainWindow ( )
+#ifdef QPDF_QPE_ONLY
m_filesel = new FileSelector ( "application/pdf", m_stack, "fs", false, true );
+#else
+ m_filesel = new OFileSelector ( "application/pdf", m_stack, "fs", false, true );
+#endif
+
connect ( m_filesel, SIGNAL( closeMe ( )), this, SLOT( closeFileSelector ( )));
diff --git a/noncore/unsupported/qpdf/qpdf.h b/noncore/unsupported/qpdf/qpdf.h
index b4ce554..8b3cff9 100644
--- a/noncore/unsupported/qpdf/qpdf.h
+++ b/noncore/unsupported/qpdf/qpdf.h
@@ -7,2 +7,3 @@
+#define QPDF_QPE_ONLY 1 // ofileselector does not work right currently
@@ -13,2 +14,3 @@ class DocLnk;
class FileSelector;
+class OFileSelector;
class QWidgetStack;
@@ -70,3 +72,8 @@ private:
QPEOutputDev *m_outdev;
+
+#ifdef QPDF_QPE_ONLY
FileSelector *m_filesel;
+#else
+ OFileSelector *m_filesel;
+#endif
diff --git a/noncore/unsupported/qpdf/qpdf.pro b/noncore/unsupported/qpdf/qpdf.pro
index 0c2e38b..fe5abfb 100644
--- a/noncore/unsupported/qpdf/qpdf.pro
+++ b/noncore/unsupported/qpdf/qpdf.pro
@@ -15,3 +15,3 @@ SOURCES = xpdf/Array.cc \
xpdf/FontEncodingTables.cc \
- xpdf/FormWidget.cc \
+ xpdf/Annot.cc \
xpdf/Function.cc \
@@ -29,2 +29,3 @@ SOURCES = xpdf/Array.cc \
xpdf/Parser.cc \
+ xpdf/PSTokenizer.cc \
xpdf/Stream.cc \
@@ -54,3 +55,3 @@ INCLUDEPATH += . \
-LIBS += -L $(OPIEDIR)/lib -lqpe
+LIBS += -L $(OPIEDIR)/lib -lqpe -lopie
diff --git a/noncore/unsupported/qpdf/xpdf/FormWidget.cc b/noncore/unsupported/qpdf/xpdf/Annot.cc
index 05c67a4..49ae50a 100644
--- a/noncore/unsupported/qpdf/xpdf/FormWidget.cc
+++ b/noncore/unsupported/qpdf/xpdf/Annot.cc
@@ -2,5 +2,5 @@
//
-// FormWidget.cc
+// Annot.cc
//
-// Copyright 2000 Derek B. Noonburg
+// Copyright 2000-2002 Glyph & Cog, LLC
//
@@ -16,9 +16,9 @@
#include "Gfx.h"
-#include "FormWidget.h"
+#include "Annot.h"
//------------------------------------------------------------------------
-// FormWidget
+// Annot
//------------------------------------------------------------------------
-FormWidget::FormWidget(XRef *xrefA, Dict *dict) {
+Annot::Annot(XRef *xrefA, Dict *dict) {
Object apObj, asObj, obj1, obj2;
@@ -79,3 +79,3 @@ FormWidget::FormWidget(XRef *xrefA, Dict *dict) {
-FormWidget::~FormWidget() {
+Annot::~Annot() {
appearance.free();
@@ -83,3 +83,3 @@ FormWidget::~FormWidget() {
-void FormWidget::draw(Gfx *gfx) {
+void Annot::draw(Gfx *gfx) {
Object obj;
@@ -87,3 +87,3 @@ void FormWidget::draw(Gfx *gfx) {
if (appearance.fetch(xref, &obj)->isStream()) {
- gfx->doWidgetForm(&obj, xMin, yMin, xMax, yMax);
+ gfx->doAnnot(&obj, xMin, yMin, xMax, yMax);
}
@@ -93,7 +93,7 @@ void FormWidget::draw(Gfx *gfx) {
//------------------------------------------------------------------------
-// FormWidgets
+// Annots
//------------------------------------------------------------------------
-FormWidgets::FormWidgets(XRef *xref, Object *annots) {
- FormWidget *widget;
+Annots::Annots(XRef *xref, Object *annotsObj) {
+ Annot *annot;
Object obj1, obj2;
@@ -102,9 +102,9 @@ FormWidgets::FormWidgets(XRef *xref, Object *annots) {
- widgets = NULL;
+ annots = NULL;
size = 0;
- nWidgets = 0;
+ nAnnots = 0;
- if (annots->isArray()) {
- for (i = 0; i < annots->arrayGetLength(); ++i) {
- if (annots->arrayGet(i, &obj1)->isDict()) {
+ if (annotsObj->isArray()) {
+ for (i = 0; i < annotsObj->arrayGetLength(); ++i) {
+ if (annotsObj->arrayGet(i, &obj1)->isDict()) {
obj1.dictLookup("Subtype", &obj2);
@@ -112,12 +112,11 @@ FormWidgets::FormWidgets(XRef *xref, Object *annots) {
obj2.isName("Stamp")) {
- widget = new FormWidget(xref, obj1.getDict());
- if (widget->isOk()) {
- if (nWidgets >= size) {
+ annot = new Annot(xref, obj1.getDict());
+ if (annot->isOk()) {
+ if (nAnnots >= size) {
size += 16;
- widgets = (FormWidget **)grealloc(widgets,
- size * sizeof(FormWidget *));
+ annots = (Annot **)grealloc(annots, size * sizeof(Annot *));
}
- widgets[nWidgets++] = widget;
+ annots[nAnnots++] = annot;
} else {
- delete widget;
+ delete annot;
}
@@ -131,9 +130,9 @@ FormWidgets::FormWidgets(XRef *xref, Object *annots) {
-FormWidgets::~FormWidgets() {
+Annots::~Annots() {
int i;
- for (i = 0; i < nWidgets; ++i) {
- delete widgets[i];
+ for (i = 0; i < nAnnots; ++i) {
+ delete annots[i];
}
- gfree(widgets);
+ gfree(annots);
}
diff --git a/noncore/unsupported/qpdf/xpdf/FormWidget.h b/noncore/unsupported/qpdf/xpdf/Annot.h
index 7f07889..0cc33dd 100644
--- a/noncore/unsupported/qpdf/xpdf/FormWidget.h
+++ b/noncore/unsupported/qpdf/xpdf/Annot.h
@@ -2,5 +2,5 @@
//
-// FormWidget.h
+// Annot.h
//
-// Copyright 2000 Derek B. Noonburg
+// Copyright 2000-2002 Glyph & Cog, LLC
//
@@ -8,4 +8,4 @@
-#ifndef FORMWIDGET_H
-#define FORMWIDGET_H
+#ifndef ANNOT_H
+#define ANNOT_H
@@ -15,2 +15,4 @@
+#include <aconf.h>
+
class XRef;
@@ -19,10 +21,10 @@ class Gfx;
//------------------------------------------------------------------------
-// FormWidget
+// Annot
//------------------------------------------------------------------------
-class FormWidget {
+class Annot {
public:
- FormWidget(XRef *xrefA, Dict *dict);
- ~FormWidget();
+ Annot(XRef *xrefA, Dict *dict);
+ ~Annot();
GBool isOk() { return ok; }
@@ -39,3 +41,3 @@ private:
// for the normal appearance
- fouble xMin, yMin, // widget rectangle
+ fouble xMin, yMin, // annotation rectangle
xMax, yMax;
@@ -45,16 +47,16 @@ private:
//------------------------------------------------------------------------
-// FormWidgets
+// Annots
//------------------------------------------------------------------------
-class FormWidgets {
+class Annots {
public:
- // Extract widgets from array of annotations.
- FormWidgets(XRef *xref, Object *annots);
+ // Extract non-link annotations from array of annotations.
+ Annots(XRef *xref, Object *annotsObj);
- ~FormWidgets();
+ ~Annots();
- // Iterate through list of widgets.
- int getNumWidgets() { return nWidgets; }
- FormWidget *getWidget(int i) { return widgets[i]; }
+ // Iterate through list of annotations.
+ int getNumAnnots() { return nAnnots; }
+ Annot *getAnnot(int i) { return annots[i]; }
@@ -62,4 +64,4 @@ private:
- FormWidget **widgets;
- int nWidgets;
+ Annot **annots;
+ int nAnnots;
};
diff --git a/noncore/unsupported/qpdf/xpdf/Array.cc b/noncore/unsupported/qpdf/xpdf/Array.cc
index 5743fe6..fbdde49 100644
--- a/noncore/unsupported/qpdf/xpdf/Array.cc
+++ b/noncore/unsupported/qpdf/xpdf/Array.cc
@@ -4,3 +4,3 @@
//
-// Copyright 1996 Derek B. Noonburg
+// Copyright 1996-2002 Glyph & Cog, LLC
//
diff --git a/noncore/unsupported/qpdf/xpdf/Array.h b/noncore/unsupported/qpdf/xpdf/Array.h
index 1616fc3..a118f68 100644
--- a/noncore/unsupported/qpdf/xpdf/Array.h
+++ b/noncore/unsupported/qpdf/xpdf/Array.h
@@ -4,3 +4,3 @@
//
-// Copyright 1996 Derek B. Noonburg
+// Copyright 1996-2002 Glyph & Cog, LLC
//
diff --git a/noncore/unsupported/qpdf/xpdf/BuiltinFont.h b/noncore/unsupported/qpdf/xpdf/BuiltinFont.h
index b4fa24c..a795311 100644
--- a/noncore/unsupported/qpdf/xpdf/BuiltinFont.h
+++ b/noncore/unsupported/qpdf/xpdf/BuiltinFont.h
@@ -4,3 +4,3 @@
//
-// Copyright 2001 Derek B. Noonburg
+// Copyright 2001-2002 Glyph & Cog, LLC
//
diff --git a/noncore/unsupported/qpdf/xpdf/BuiltinFontTables.cc b/noncore/unsupported/qpdf/xpdf/BuiltinFontTables.cc
index 6833972..845abcd 100644
--- a/noncore/unsupported/qpdf/xpdf/BuiltinFontTables.cc
+++ b/noncore/unsupported/qpdf/xpdf/BuiltinFontTables.cc
@@ -4,3 +4,3 @@
//
-// Copyright 2001 Derek B. Noonburg
+// Copyright 2001-2002 Glyph & Cog, LLC
//
diff --git a/noncore/unsupported/qpdf/xpdf/BuiltinFontTables.h b/noncore/unsupported/qpdf/xpdf/BuiltinFontTables.h
index 9a17ce9..3a8892e 100644
--- a/noncore/unsupported/qpdf/xpdf/BuiltinFontTables.h
+++ b/noncore/unsupported/qpdf/xpdf/BuiltinFontTables.h
@@ -4,3 +4,3 @@
//
-// Copyright 2001 Derek B. Noonburg
+// Copyright 2001-2002 Glyph & Cog, LLC
//
diff --git a/noncore/unsupported/qpdf/xpdf/CMap.cc b/noncore/unsupported/qpdf/xpdf/CMap.cc
index 57809f0..b49cffd 100644
--- a/noncore/unsupported/qpdf/xpdf/CMap.cc
+++ b/noncore/unsupported/qpdf/xpdf/CMap.cc
@@ -4,3 +4,3 @@
//
-// Copyright 2001 Derek B. Noonburg
+// Copyright 2001-2002 Glyph & Cog, LLC
//
@@ -22,2 +22,3 @@
#include "GlobalParams.h"
+#include "PSTokenizer.h"
#include "CMap.h"
@@ -36,2 +37,8 @@ struct CMapVectorEntry {
+static int getCharFromFile(void *data) {
+ return fgetc((FILE *)data);
+}
+
+//------------------------------------------------------------------------
+
CMap *CMap::parse(CMapCache *cache, GString *collectionA,
@@ -40,7 +47,6 @@ CMap *CMap::parse(CMapCache *cache, GString *collectionA,
CMap *cmap;
- char buf[256];
- GBool inCodeSpace, inCIDRange;
- char *tok1, *tok2, *tok3;
+ PSTokenizer *pst;
+ char tok1[256], tok2[256], tok3[256];
+ int n1, n2, n3;
Guint start, end;
- Guint n;
@@ -63,35 +69,6 @@ CMap *CMap::parse(CMapCache *cache, GString *collectionA,
- inCodeSpace = inCIDRange = gFalse;
- while (getLine(buf, sizeof(buf), f)) {
- tok1 = strtok(buf, " \t\r\n");
- if (!tok1 || tok1[0] == '%') {
- continue;
- }
- tok2 = strtok(NULL, " \t\r\n");
- tok3 = strtok(NULL, " \t\r\n");
- if (inCodeSpace) {
- if (!strcmp(tok1, "endcodespacerange")) {
- inCodeSpace = gFalse;
- } else if (tok2 && tok1[0] == '<' && tok2[0] == '<' &&
- (n = strlen(tok1)) == strlen(tok2) &&
- n >= 4 && (n & 1) == 0) {
- tok1[n - 1] = tok2[n - 1] = '\0';
- sscanf(tok1 + 1, "%x", &start);
- sscanf(tok2 + 1, "%x", &end);
- n = (n - 2) / 2;
- cmap->addCodeSpace(cmap->vector, start, end, n);
- }
- } else if (inCIDRange) {
- if (!strcmp(tok1, "endcidrange")) {
- inCIDRange = gFalse;
- } else if (tok2 && tok3 && tok1[0] == '<' && tok2[0] == '<' &&
- (n = strlen(tok1)) == strlen(tok2) &&
- n >= 4 && (n & 1) == 0) {
- tok1[n - 1] = tok2[n - 1] = '\0';
- sscanf(tok1 + 1, "%x", &start);
- sscanf(tok2 + 1, "%x", &end);
- n = (n - 2) / 2;
- cmap->addCIDs(start, end, n, (CID)atoi(tok3));
- }
- } else if (tok2 && !strcmp(tok2, "usecmap")) {
+ pst = new PSTokenizer(&getCharFromFile, f);
+ pst->getToken(tok1, sizeof(tok1), &n1);
+ while (pst->getToken(tok2, sizeof(tok2), &n2)) {
+ if (!strcmp(tok2, "usecmap")) {
if (tok1[0] == '/') {
@@ -99,10 +76,53 @@ CMap *CMap::parse(CMapCache *cache, GString *collectionA,
}
+ pst->getToken(tok1, sizeof(tok1), &n1);
} else if (!strcmp(tok1, "/WMode")) {
cmap->wMode = atoi(tok2);
- } else if (tok2 && !strcmp(tok2, "begincodespacerange")) {
- inCodeSpace = gTrue;
- } else if (tok2 && !strcmp(tok2, "begincidrange")) {
- inCIDRange = gTrue;
+ pst->getToken(tok1, sizeof(tok1), &n1);
+ } else if (!strcmp(tok2, "begincodespacerange")) {
+ while (pst->getToken(tok1, sizeof(tok1), &n1)) {
+ if (!strcmp(tok1, "endcodespacerange")) {
+ break;
+ }
+ if (!pst->getToken(tok2, sizeof(tok2), &n2) ||
+ !strcmp(tok2, "endcodespacerange")) {
+ error(-1, "Illegal entry in codespacerange block in CMap");
+ break;
+ }
+ if (tok1[0] == '<' && tok2[0] == '<' &&
+ n1 == n2 && n1 >= 4 && (n1 & 1) == 0) {
+ tok1[n1 - 1] = tok2[n1 - 1] = '\0';
+ sscanf(tok1 + 1, "%x", &start);
+ sscanf(tok2 + 1, "%x", &end);
+ n1 = (n1 - 2) / 2;
+ cmap->addCodeSpace(cmap->vector, start, end, n1);
+ }
+ }
+ pst->getToken(tok1, sizeof(tok1), &n1);
+ } else if (!strcmp(tok2, "begincidrange")) {
+ while (pst->getToken(tok1, sizeof(tok1), &n1)) {
+ if (!strcmp(tok1, "endcidrange")) {
+ break;
+ }
+ if (!pst->getToken(tok2, sizeof(tok2), &n2) ||
+ !strcmp(tok2, "endcidrange") ||
+ !pst->getToken(tok3, sizeof(tok3), &n3) ||
+ !strcmp(tok3, "endcidrange")) {
+ error(-1, "Illegal entry in cidrange block in CMap");
+ break;
+ }
+ if (tok1[0] == '<' && tok2[0] == '<' &&
+ n1 == n2 && n1 >= 4 && (n1 & 1) == 0) {
+ tok1[n1 - 1] = tok2[n1 - 1] = '\0';
+ sscanf(tok1 + 1, "%x", &start);
+ sscanf(tok2 + 1, "%x", &end);
+ n1 = (n1 - 2) / 2;
+ cmap->addCIDs(start, end, n1, (CID)atoi(tok3));
+ }
+ }
+ pst->getToken(tok1, sizeof(tok1), &n1);
+ } else {
+ strcpy(tok1, tok2);
}
}
+ delete pst;
diff --git a/noncore/unsupported/qpdf/xpdf/CMap.h b/noncore/unsupported/qpdf/xpdf/CMap.h
index 8b29ef7..fe49acf 100644
--- a/noncore/unsupported/qpdf/xpdf/CMap.h
+++ b/noncore/unsupported/qpdf/xpdf/CMap.h
@@ -4,3 +4,3 @@
//
-// Copyright 2001 Derek B. Noonburg
+// Copyright 2001-2002 Glyph & Cog, LLC
//
diff --git a/noncore/unsupported/qpdf/xpdf/Catalog.cc b/noncore/unsupported/qpdf/xpdf/Catalog.cc
index 6a0c2d5..1212e2e 100644
--- a/noncore/unsupported/qpdf/xpdf/Catalog.cc
+++ b/noncore/unsupported/qpdf/xpdf/Catalog.cc
@@ -4,3 +4,3 @@
//
-// Copyright 1996 Derek B. Noonburg
+// Copyright 1996-2002 Glyph & Cog, LLC
//
@@ -148,3 +148,3 @@ GString *Catalog::readMetadata() {
if (!dict->lookup("Subtype", &obj)->isName("XML")) {
- error(-1, "Unknown Metadata type: '%s'\n",
+ error(-1, "Unknown Metadata type: '%s'",
obj.isName() ? obj.getName() : "???");
@@ -267,6 +267,6 @@ LinkDest *Catalog::findDest(GString *name) {
if (obj1.isArray()) {
- dest = new LinkDest(obj1.getArray(), gTrue);
+ dest = new LinkDest(obj1.getArray());
} else if (obj1.isDict()) {
if (obj1.dictLookup("D", &obj2)->isArray())
- dest = new LinkDest(obj2.getArray(), gTrue);
+ dest = new LinkDest(obj2.getArray());
else
diff --git a/noncore/unsupported/qpdf/xpdf/Catalog.h b/noncore/unsupported/qpdf/xpdf/Catalog.h
index 197f5b8..afad803 100644
--- a/noncore/unsupported/qpdf/xpdf/Catalog.h
+++ b/noncore/unsupported/qpdf/xpdf/Catalog.h
@@ -4,3 +4,3 @@
//
-// Copyright 1996 Derek B. Noonburg
+// Copyright 1996-2002 Glyph & Cog, LLC
//
diff --git a/noncore/unsupported/qpdf/xpdf/CharCodeToUnicode.cc b/noncore/unsupported/qpdf/xpdf/CharCodeToUnicode.cc
index 6793398..912981e 100644
--- a/noncore/unsupported/qpdf/xpdf/CharCodeToUnicode.cc
+++ b/noncore/unsupported/qpdf/xpdf/CharCodeToUnicode.cc
@@ -4,3 +4,3 @@
//
-// Copyright 2001 Derek B. Noonburg
+// Copyright 2001-2002 Glyph & Cog, LLC
//
@@ -20,2 +20,3 @@
#include "GlobalParams.h"
+#include "PSTokenizer.h"
#include "CharCodeToUnicode.h"
@@ -34,2 +35,22 @@ struct CharCodeToUnicodeString {
+static int getCharFromString(void *data) {
+ char *p;
+ int c;
+
+ p = *(char **)data;
+ if (*p) {
+ c = *p++;
+ *(char **)data = p;
+ } else {
+ c = EOF;
+ }
+ return c;
+}
+
+static int getCharFromFile(void *data) {
+ return fgetc((FILE *)data);
+}
+
+//------------------------------------------------------------------------
+
CharCodeToUnicode *CharCodeToUnicode::parseCIDToUnicode(GString *collectionA) {
@@ -77,27 +98,2 @@ CharCodeToUnicode *CharCodeToUnicode::make8BitToUnicode(Unicode *toUnicode) {
-static char *getLineFromString(char *buf, int size, char **s) {
- char c;
- int i;
-
- i = 0;
- while (i < size - 1 && **s) {
- buf[i++] = c = *(*s)++;
- if (c == '\x0a') {
- break;
- }
- if (c == '\x0d') {
- if (**s == '\x0a' && i < size - 1) {
- buf[i++] = '\x0a';
- ++*s;
- }
- break;
- }
- }
- buf[i] = '\0';
- if (i == 0) {
- return NULL;
- }
- return buf;
-}
-
CharCodeToUnicode *CharCodeToUnicode::parseCMap(GString *buf, int nBits) {
@@ -108,4 +104,3 @@ CharCodeToUnicode *CharCodeToUnicode::parseCMap(GString *buf, int nBits) {
p = buf->getCString();
- ctu->parseCMap1((char *(*)(char *, int, void *))&getLineFromString,
- &p, nBits);
+ ctu->parseCMap1(&getCharFromString, &p, nBits);
return ctu;
@@ -113,7 +108,6 @@ CharCodeToUnicode *CharCodeToUnicode::parseCMap(GString *buf, int nBits) {
-void CharCodeToUnicode::parseCMap1(char *(*getLineFunc)(char *, int, void *),
- void *data, int nBits) {
- char buf[256];
- GBool inBFChar, inBFRange;
- char *tok1, *tok2, *tok3;
+void CharCodeToUnicode::parseCMap1(int (*getCharFunc)(void *), void *data,
+ int nBits) {
+ PSTokenizer *pst;
+ char tok1[256], tok2[256], tok3[256];
int nDigits, n1, n2, n3;
@@ -128,19 +122,31 @@ void CharCodeToUnicode::parseCMap1(char *(*getLineFunc)(char *, int, void *),
nDigits = nBits / 4;
- inBFChar = inBFRange = gFalse;
- while ((*getLineFunc)(buf, sizeof(buf), data)) {
- tok1 = strtok(buf, " \t\r\n");
- if (!tok1 || tok1[0] == '%') {
- continue;
- }
- tok2 = strtok(NULL, " \t\r\n");
- tok3 = strtok(NULL, " \t\r\n");
- if (inBFChar) {
- if (!strcmp(tok1, "endbfchar")) {
- inBFChar = gFalse;
- } else if (tok2) {
- n1 = strlen(tok1);
- n2 = strlen(tok2);
+ pst = new PSTokenizer(getCharFunc, data);
+ pst->getToken(tok1, sizeof(tok1), &n1);
+ while (pst->getToken(tok2, sizeof(tok2), &n2)) {
+ if (!strcmp(tok2, "usecmap")) {
+ if (tok1[0] == '/') {
+ name = new GString(tok1 + 1);
+ if ((f = globalParams->findToUnicodeFile(name))) {
+ parseCMap1(&getCharFromFile, f, nBits);
+ fclose(f);
+ } else {
+ error(-1, "Couldn't find ToUnicode CMap file for '%s'",
+ name->getCString());
+ }
+ delete name;
+ }
+ pst->getToken(tok1, sizeof(tok1), &n1);
+ } else if (!strcmp(tok2, "beginbfchar")) {
+ while (pst->getToken(tok1, sizeof(tok1), &n1)) {
+ if (!strcmp(tok1, "endbfchar")) {
+ break;
+ }
+ if (!pst->getToken(tok2, sizeof(tok2), &n2) ||
+ !strcmp(tok2, "endbfchar")) {
+ error(-1, "Illegal entry in bfchar block in ToUnicode CMap");
+ break;
+ }
if (!(n1 == 2 + nDigits && tok1[0] == '<' && tok1[n1 - 1] == '>' &&
tok2[0] == '<' && tok2[n2 - 1] == '>')) {
- error(-1, "Illegal line in bfchar block in ToUnicode CMap");
+ error(-1, "Illegal entry in bfchar block in ToUnicode CMap");
continue;
@@ -149,3 +155,3 @@ void CharCodeToUnicode::parseCMap1(char *(*getLineFunc)(char *, int, void *),
if (sscanf(tok1 + 1, "%x", &code1) != 1) {
- error(-1, "Illegal line in bfchar block in ToUnicode CMap");
+ error(-1, "Illegal entry in bfchar block in ToUnicode CMap");
continue;
@@ -162,3 +168,3 @@ void CharCodeToUnicode::parseCMap1(char *(*getLineFunc)(char *, int, void *),
if (sscanf(tok2 + 1, "%x", &u) != 1) {
- error(-1, "Illegal line in bfchar block in ToUnicode CMap");
+ error(-1, "Illegal entry in bfchar block in ToUnicode CMap");
continue;
@@ -179,3 +185,3 @@ void CharCodeToUnicode::parseCMap1(char *(*getLineFunc)(char *, int, void *),
if (sscanf(uHex, "%x", &sMap[sMapLen].u[j]) != 1) {
- error(-1, "Illegal line in bfchar block in ToUnicode CMap");
+ error(-1, "Illegal entry in bfchar block in ToUnicode CMap");
}
@@ -184,12 +190,16 @@ void CharCodeToUnicode::parseCMap1(char *(*getLineFunc)(char *, int, void *),
}
- } else {
- error(-1, "Illegal bfchar block in ToUnicode CMap");
}
- } else if (inBFRange) {
- if (!strcmp(tok1, "endbfrange")) {
- inBFRange = gFalse;
- } else if (tok2 && tok3) {
- n1 = strlen(tok1);
- n2 = strlen(tok2);
- n3 = strlen(tok3);
+ pst->getToken(tok1, sizeof(tok1), &n1);
+ } else if (!strcmp(tok2, "beginbfrange")) {
+ while (pst->getToken(tok1, sizeof(tok1), &n1)) {
+ if (!strcmp(tok1, "endbfrange")) {
+ break;
+ }
+ if (!pst->getToken(tok2, sizeof(tok2), &n2) ||
+ !strcmp(tok2, "endbfrange") ||
+ !pst->getToken(tok3, sizeof(tok3), &n3) ||
+ !strcmp(tok3, "endbfrange")) {
+ error(-1, "Illegal entry in bfrange block in ToUnicode CMap");
+ break;
+ }
if (!(n1 == 2 + nDigits && tok1[0] == '<' && tok1[n1 - 1] == '>' &&
@@ -197,3 +207,3 @@ void CharCodeToUnicode::parseCMap1(char *(*getLineFunc)(char *, int, void *),
tok3[0] == '<' && tok3[n3 - 1] == '>')) {
- error(-1, "Illegal line in bfrange block in ToUnicode CMap");
+ error(-1, "Illegal entry in bfrange block in ToUnicode CMap");
continue;
@@ -203,3 +213,3 @@ void CharCodeToUnicode::parseCMap1(char *(*getLineFunc)(char *, int, void *),
sscanf(tok2 + 1, "%x", &code2) != 1) {
- error(-1, "Illegal line in bfrange block in ToUnicode CMap");
+ error(-1, "Illegal entry in bfrange block in ToUnicode CMap");
continue;
@@ -216,3 +226,3 @@ void CharCodeToUnicode::parseCMap1(char *(*getLineFunc)(char *, int, void *),
if (sscanf(tok3 + 1, "%x", &u) != 1) {
- error(-1, "Illegal line in bfrange block in ToUnicode CMap");
+ error(-1, "Illegal entry in bfrange block in ToUnicode CMap");
continue;
@@ -236,3 +246,3 @@ void CharCodeToUnicode::parseCMap1(char *(*getLineFunc)(char *, int, void *),
if (sscanf(uHex, "%x", &sMap[sMapLen].u[j]) != 1) {
- error(-1, "Illegal line in bfrange block in ToUnicode CMap");
+ error(-1, "Illegal entry in bfrange block in ToUnicode CMap");
}
@@ -243,23 +253,9 @@ void CharCodeToUnicode::parseCMap1(char *(*getLineFunc)(char *, int, void *),
}
- } else {
- error(-1, "Illegal bfrange block in ToUnicode CMap");
}
- } else if (tok2 && !strcmp(tok2, "usecmap")) {
- if (tok1[0] == '/') {
- name = new GString(tok1 + 1);
- if ((f = globalParams->findToUnicodeFile(name))) {
- parseCMap1((char *(*)(char *, int, void *))&getLine, f, nBits);
- fclose(f);
- } else {
- error(-1, "Couldn't find ToUnicode CMap file for '%s'",
- name->getCString());
- }
- delete name;
- }
- } else if (tok2 && !strcmp(tok2, "beginbfchar")) {
- inBFChar = gTrue;
- } else if (tok2 && !strcmp(tok2, "beginbfrange")) {
- inBFRange = gTrue;
+ pst->getToken(tok1, sizeof(tok1), &n1);
+ } else {
+ strcpy(tok1, tok2);
}
}
+ delete pst;
}
diff --git a/noncore/unsupported/qpdf/xpdf/CharCodeToUnicode.h b/noncore/unsupported/qpdf/xpdf/CharCodeToUnicode.h
index c811d72..06916c8 100644
--- a/noncore/unsupported/qpdf/xpdf/CharCodeToUnicode.h
+++ b/noncore/unsupported/qpdf/xpdf/CharCodeToUnicode.h
@@ -6,3 +6,3 @@
//
-// Copyright 2001 Derek B. Noonburg
+// Copyright 2001-2002 Glyph & Cog, LLC
//
@@ -52,4 +52,3 @@ private:
- void parseCMap1(char *(*getLineFunc)(char *, int, void *),
- void *data, int nBits);
+ void parseCMap1(int (*getCharFunc)(void *), void *data, int nBits);
CharCodeToUnicode(GString *collectionA);
diff --git a/noncore/unsupported/qpdf/xpdf/CharTypes.h b/noncore/unsupported/qpdf/xpdf/CharTypes.h
index 8938be5..bae2f26 100644
--- a/noncore/unsupported/qpdf/xpdf/CharTypes.h
+++ b/noncore/unsupported/qpdf/xpdf/CharTypes.h
@@ -4,3 +4,3 @@
//
-// Copyright 2001 Derek B. Noonburg
+// Copyright 2001-2002 Glyph & Cog, LLC
//
diff --git a/noncore/unsupported/qpdf/xpdf/Decrypt.cc b/noncore/unsupported/qpdf/xpdf/Decrypt.cc
index 2def802..8de4091 100644
--- a/noncore/unsupported/qpdf/xpdf/Decrypt.cc
+++ b/noncore/unsupported/qpdf/xpdf/Decrypt.cc
@@ -4,3 +4,3 @@
//
-// Copyright 1996 Derek B. Noonburg
+// Copyright 1996-2002 Glyph & Cog, LLC
//
diff --git a/noncore/unsupported/qpdf/xpdf/Decrypt.h b/noncore/unsupported/qpdf/xpdf/Decrypt.h
index 1bdb2b7..52afb2f 100644
--- a/noncore/unsupported/qpdf/xpdf/Decrypt.h
+++ b/noncore/unsupported/qpdf/xpdf/Decrypt.h
@@ -4,3 +4,3 @@
//
-// Copyright 1996 Derek B. Noonburg
+// Copyright 1996-2002 Glyph & Cog, LLC
//
diff --git a/noncore/unsupported/qpdf/xpdf/Dict.cc b/noncore/unsupported/qpdf/xpdf/Dict.cc
index 1a49ca5..5eb077e 100644
--- a/noncore/unsupported/qpdf/xpdf/Dict.cc
+++ b/noncore/unsupported/qpdf/xpdf/Dict.cc
@@ -4,3 +4,3 @@
//
-// Copyright 1996 Derek B. Noonburg
+// Copyright 1996-2002 Glyph & Cog, LLC
//
diff --git a/noncore/unsupported/qpdf/xpdf/Dict.h b/noncore/unsupported/qpdf/xpdf/Dict.h
index c4f1ea5..b994514 100644
--- a/noncore/unsupported/qpdf/xpdf/Dict.h
+++ b/noncore/unsupported/qpdf/xpdf/Dict.h
@@ -4,3 +4,3 @@
//
-// Copyright 1996 Derek B. Noonburg
+// Copyright 1996-2002 Glyph & Cog, LLC
//
diff --git a/noncore/unsupported/qpdf/xpdf/DisplayFontTable.h b/noncore/unsupported/qpdf/xpdf/DisplayFontTable.h
index 048e25d..8e73486 100644
--- a/noncore/unsupported/qpdf/xpdf/DisplayFontTable.h
+++ b/noncore/unsupported/qpdf/xpdf/DisplayFontTable.h
@@ -4,3 +4,3 @@
//
-// Copyright 2001 Derek B. Noonburg
+// Copyright 2001-2002 Glyph & Cog, LLC
//
@@ -13,3 +13,3 @@ static struct {
} displayFontTab[] = {
-#if _NO_USE_FOR_QPE
+#if 0
{"Courier", "-*-courier-medium-r-normal-*-%s-*-*-*-*-*-iso8859-1", "Latin1"},
@@ -29,3 +29,3 @@ static struct {
#endif
- {NULL}
+ {NULL,0,0}
};
diff --git a/noncore/unsupported/qpdf/xpdf/Error.cc b/noncore/unsupported/qpdf/xpdf/Error.cc
index 8763846..3eae5c9 100644
--- a/noncore/unsupported/qpdf/xpdf/Error.cc
+++ b/noncore/unsupported/qpdf/xpdf/Error.cc
@@ -4,3 +4,3 @@
//
-// Copyright 1996 Derek B. Noonburg
+// Copyright 1996-2002 Glyph & Cog, LLC
//
diff --git a/noncore/unsupported/qpdf/xpdf/Error.h b/noncore/unsupported/qpdf/xpdf/Error.h
index 151e961..77801c5 100644
--- a/noncore/unsupported/qpdf/xpdf/Error.h
+++ b/noncore/unsupported/qpdf/xpdf/Error.h
@@ -4,3 +4,3 @@
//
-// Copyright 1996 Derek B. Noonburg
+// Copyright 1996-2002 Glyph & Cog, LLC
//
diff --git a/noncore/unsupported/qpdf/xpdf/ErrorCodes.h b/noncore/unsupported/qpdf/xpdf/ErrorCodes.h
new file mode 100644
index 0000000..4e0d38a
--- a/dev/null
+++ b/noncore/unsupported/qpdf/xpdf/ErrorCodes.h
@@ -0,0 +1,24 @@
+//========================================================================
+//
+// ErrorCodes.h
+//
+// Copyright 2002 Glyph & Cog, LLC
+//
+//========================================================================
+
+#ifndef ERRORCODES_H
+#define ERRORCODES_H
+
+#define errNone 0 // no error
+
+#define errOpenFile 1 // couldn't open the PDF file
+
+#define errBadCatalog 2 // couldn't read the page catalog
+
+#define errDamaged 3 // PDF file was damaged and couldn't be
+ // repaired
+
+#define errEncrypted 4 // file was encrypted and password was
+ // incorrect or not supplied
+
+#endif
diff --git a/noncore/unsupported/qpdf/xpdf/FontEncodingTables.cc b/noncore/unsupported/qpdf/xpdf/FontEncodingTables.cc
index 12a1a27..bd5f9cf 100644
--- a/noncore/unsupported/qpdf/xpdf/FontEncodingTables.cc
+++ b/noncore/unsupported/qpdf/xpdf/FontEncodingTables.cc
@@ -4,3 +4,3 @@
//
-// Copyright 2001 Derek B. Noonburg
+// Copyright 2001-2002 Glyph & Cog, LLC
//
diff --git a/noncore/unsupported/qpdf/xpdf/FontEncodingTables.h b/noncore/unsupported/qpdf/xpdf/FontEncodingTables.h
index 4646a43..deee0a8 100644
--- a/noncore/unsupported/qpdf/xpdf/FontEncodingTables.h
+++ b/noncore/unsupported/qpdf/xpdf/FontEncodingTables.h
@@ -4,3 +4,3 @@
//
-// Copyright 2001 Derek B. Noonburg
+// Copyright 2001-2002 Glyph & Cog, LLC
//
diff --git a/noncore/unsupported/qpdf/xpdf/Function.cc b/noncore/unsupported/qpdf/xpdf/Function.cc
index 815cc89..ebf3718 100644
--- a/noncore/unsupported/qpdf/xpdf/Function.cc
+++ b/noncore/unsupported/qpdf/xpdf/Function.cc
@@ -4,3 +4,3 @@
//
-// Copyright 2001 Derek B. Noonburg
+// Copyright 2001-2002 Glyph & Cog, LLC
//
@@ -417,3 +417,2 @@ ExponentialFunction::ExponentialFunction(Object *funcObj, Dict *dict) {
ok = gFalse;
- hasN = gFalse;
@@ -427,2 +426,3 @@ ExponentialFunction::ExponentialFunction(Object *funcObj, Dict *dict) {
}
+ hasN = hasRange;
@@ -438,2 +438,3 @@ ExponentialFunction::ExponentialFunction(Object *funcObj, Dict *dict) {
n = obj1.arrayGetLength();
+ hasN = gTrue;
} else if (obj1.arrayGetLength() != n) {
@@ -458,2 +459,3 @@ ExponentialFunction::ExponentialFunction(Object *funcObj, Dict *dict) {
n = obj1.arrayGetLength();
+ hasN = gTrue;
} else if (obj1.arrayGetLength() != n) {
@@ -482,2 +484,9 @@ ExponentialFunction::ExponentialFunction(Object *funcObj, Dict *dict) {
+ // this isn't supposed to happen, but I've run into (broken) PDF
+ // files where it does
+ if (!hasN) {
+ error(-1, "Exponential function does not define number of output values");
+ n = 1;
+ }
+
ok = gTrue;
diff --git a/noncore/unsupported/qpdf/xpdf/Function.h b/noncore/unsupported/qpdf/xpdf/Function.h
index a223359..deb4630 100644
--- a/noncore/unsupported/qpdf/xpdf/Function.h
+++ b/noncore/unsupported/qpdf/xpdf/Function.h
@@ -4,3 +4,3 @@
//
-// Copyright 2001 Derek B. Noonburg
+// Copyright 2001-2002 Glyph & Cog, LLC
//
diff --git a/noncore/unsupported/qpdf/xpdf/Gfx.cc b/noncore/unsupported/qpdf/xpdf/Gfx.cc
index c19971c..17d613e 100644
--- a/noncore/unsupported/qpdf/xpdf/Gfx.cc
+++ b/noncore/unsupported/qpdf/xpdf/Gfx.cc
@@ -4,3 +4,3 @@
//
-// Copyright 1996 Derek B. Noonburg
+// Copyright 1996-2002 Glyph & Cog, LLC
//
@@ -32,2 +32,7 @@
+// the MSVC math.h doesn't define this
+#ifndef M_PI
+#define M_PI 3.14159265358979323846
+#endif
+
//------------------------------------------------------------------------
@@ -42,2 +47,8 @@
+// Max number of splits along the t axis for a radial shading fill.
+#define radialMaxSplits 256
+
+// Max delta allowed in any color component for a radial shading fill.
+#define radialColorDelta (1 / 256.0)
+
//------------------------------------------------------------------------
@@ -376,2 +387,3 @@ Gfx::Gfx(XRef *xrefA, OutputDev *outA, int pageNum, Dict *resDict, fouble dpi,
xref = xrefA;
+ subPage = gFalse;
printCommands = printCommandsA;
@@ -407,5 +419,37 @@ Gfx::Gfx(XRef *xrefA, OutputDev *outA, int pageNum, Dict *resDict, fouble dpi,
-Gfx::~Gfx() {
- GfxResources *resPtr;
+Gfx::Gfx(XRef *xrefA, OutputDev *outA, Dict *resDict,
+ PDFRectangle *box, GBool crop, PDFRectangle *cropBox) {
+ int i;
+ xref = xrefA;
+ subPage = gTrue;
+ printCommands = gFalse;
+
+ // start the resource stack
+ res = new GfxResources(xref, resDict, NULL);
+
+ // initialize
+ out = outA;
+ state = new GfxState(72, box, 0, gFalse);
+ fontChanged = gFalse;
+ clip = clipNone;
+ ignoreUndef = 0;
+ for (i = 0; i < 6; ++i) {
+ baseMatrix[i] = state->getCTM()[i];
+ }
+
+ // set crop box
+ if (crop) {
+ state->moveTo(cropBox->x1, cropBox->y1);
+ state->lineTo(cropBox->x2, cropBox->y1);
+ state->lineTo(cropBox->x2, cropBox->y2);
+ state->lineTo(cropBox->x1, cropBox->y2);
+ state->closePath();
+ state->clip();
+ out->clip(state);
+ state->clearPath();
+ }
+}
+
+Gfx::~Gfx() {
while (state->hasSaves()) {
@@ -414,10 +458,11 @@ Gfx::~Gfx() {
}
- out->endPage();
+ if (!subPage) {
+ out->endPage();
+ }
while (res) {
- resPtr = res->getNext();
- delete res;
- res = resPtr;
+ popResources();
}
- if (state)
+ if (state) {
delete state;
+ }
}
@@ -451,3 +496,3 @@ void Gfx::go(GBool topLevel) {
Object args[maxArgs];
- int numCmds, numArgs;
+ int numArgs;
int i;
@@ -455,3 +500,3 @@ void Gfx::go(GBool topLevel) {
// scan a sequence of objects
- numCmds = 0;
+ updateLevel = 0;
numArgs = 0;
@@ -478,5 +523,5 @@ void Gfx::go(GBool topLevel) {
// periodically update display
- if (++numCmds == 200) {
+ if (++updateLevel >= 20000) {
out->dump();
- numCmds = 0;
+ updateLevel = 0;
}
@@ -521,3 +566,3 @@ void Gfx::go(GBool topLevel) {
// update display
- if (topLevel && numCmds > 0) {
+ if (topLevel && updateLevel > 0) {
out->dump();
@@ -1140,3 +1185,3 @@ void Gfx::doPatternFill(GBool eoFill) {
fouble *ctm, *btm, *ptm;
- fouble m[6], ictm[6], m1[6], im[6], imb[6];
+ fouble m[6], ictm[6], m1[6], imb[6];
fouble det;
@@ -1191,11 +1236,2 @@ void Gfx::doPatternFill(GBool eoFill) {
- // construct a (current space) -> (pattern space) transform matrix
- det = 1 / (m[0] * m[3] - m[1] * m[2]);
- im[0] = m[3] * det;
- im[1] = -m[1] * det;
- im[2] = -m[2] * det;
- im[3] = m[0] * det;
- im[4] = (m[2] * m[5] - m[3] * m[4]) * det;
- im[5] = (m[1] * m[4] - m[0] * m[5]) * det;
-
// construct a (base space) -> (pattern space) transform matrix
@@ -1333,2 +1369,5 @@ void Gfx::opShFill(Object args[], int numArgs) {
break;
+ case 3:
+ doRadialShFill((GfxRadialShading *)shading);
+ break;
}
@@ -1345,5 +1384,2 @@ void Gfx::doAxialShFill(GfxAxialShading *shading) {
fouble x0, y0, x1, y1;
- fouble det;
- fouble *ctm;
- fouble ictm[6];
fouble dx, dy, mul;
@@ -1359,50 +1395,4 @@ void Gfx::doAxialShFill(GfxAxialShading *shading) {
- // get clip region bbox and transform to current user space
- state->getClipBBox(&x0, &y0, &x1, &y1);
- ctm = state->getCTM();
- det = 1 / (ctm[0] * ctm[3] - ctm[1] * ctm[2]);
- ictm[0] = ctm[3] * det;
- ictm[1] = -ctm[1] * det;
- ictm[2] = -ctm[2] * det;
- ictm[3] = ctm[0] * det;
- ictm[4] = (ctm[2] * ctm[5] - ctm[3] * ctm[4]) * det;
- ictm[5] = (ctm[1] * ctm[4] - ctm[0] * ctm[5]) * det;
- xMin = xMax = x0 * ictm[0] + y0 * ictm[2] + ictm[4];
- yMin = yMax = x0 * ictm[1] + y0 * ictm[3] + ictm[5];
- tx = x0 * ictm[0] + y1 * ictm[2] + ictm[4];
- ty = x0 * ictm[1] + y1 * ictm[3] + ictm[5];
- if (tx < xMin) {
- xMin = tx;
- } else if (tx > xMax) {
- xMax = tx;
- }
- if (ty < yMin) {
- yMin = ty;
- } else if (ty > yMax) {
- yMax = ty;
- }
- tx = x1 * ictm[0] + y0 * ictm[2] + ictm[4];
- ty = x1 * ictm[1] + y0 * ictm[3] + ictm[5];
- if (tx < xMin) {
- xMin = tx;
- } else if (tx > xMax) {
- xMax = tx;
- }
- if (ty < yMin) {
- yMin = ty;
- } else if (ty > yMax) {
- yMax = ty;
- }
- tx = x1 * ictm[0] + y1 * ictm[2] + ictm[4];
- ty = x1 * ictm[1] + y1 * ictm[3] + ictm[5];
- if (tx < xMin) {
- xMin = tx;
- } else if (tx > xMax) {
- xMax = tx;
- }
- if (ty < yMin) {
- yMin = ty;
- } else if (ty > yMax) {
- yMax = ty;
- }
+ // get the clip region bbox
+ state->getUserClipBBox(&xMin, &yMin, &xMax, &yMax);
@@ -1621,2 +1611,198 @@ void Gfx::doAxialShFill(GfxAxialShading *shading) {
+void Gfx::doRadialShFill(GfxRadialShading *shading) {
+ fouble sMin, sMax, xMin, yMin, xMax, yMax;
+ fouble x0, y0, r0, x1, y1, r1, t0, t1;
+ int nComps;
+ GfxColor colorA, colorB;
+ fouble xa, ya, xb, yb, ra, rb;
+ fouble ta, tb, sa, sb;
+ int ia, ib, k, n;
+ fouble *ctm;
+ fouble angle, t;
+
+ // get the shading info
+ shading->getCoords(&x0, &y0, &r0, &x1, &y1, &r1);
+ t0 = shading->getDomain0();
+ t1 = shading->getDomain1();
+ nComps = shading->getColorSpace()->getNComps();
+
+ // compute the (possibly extended) s range
+ sMin = 0;
+ sMax = 1;
+ if (shading->getExtend0()) {
+ if (r0 < r1) {
+ // extend the smaller end
+ sMin = -r0 / (r1 - r0);
+ } else {
+ // extend the larger end
+ //~ this computes the diagonal of the bounding box -- we should
+ //~ really compute the intersection of the moving/expanding
+ //~ circles with each of the four corners and look for the max
+ //~ radius
+ state->getUserClipBBox(&xMin, &yMin, &xMax, &yMax);
+ sMin = (sqrt((xMax - xMin) * (xMax - xMin) +
+ (yMax - yMin) * (yMax - yMin)) - r0) / (r1 - r0);
+ if (sMin > 0) {
+ sMin = 0;
+ } else if (sMin < -20) {
+ // sanity check
+ sMin = -20;
+ }
+ }
+ }
+ if (shading->getExtend1()) {
+ if (r1 < r0) {
+ // extend the smaller end
+ sMax = -r0 / (r1 - r0);
+ } else if (r1 > r0) {
+ // extend the larger end
+ state->getUserClipBBox(&xMin, &yMin, &xMax, &yMax);
+ sMax = (sqrt((xMax - xMin) * (xMax - xMin) +
+ (yMax - yMin) * (yMax - yMin)) - r0) / (r1 - r0);
+ if (sMax < 1) {
+ sMin = 1;
+ } else if (sMax > 20) {
+ // sanity check
+ sMax = 20;
+ }
+ }
+ }
+
+ // compute the number of steps into which circles must be divided to
+ // achieve a curve flatness of 0.1 pixel in device space for the
+ // largest circle (note that "device space" is 72 dpi when generating
+ // PostScript, hence the relatively small 0.1 pixel accuracy)
+ ctm = state->getCTM();
+ t = fabs(ctm[0]);
+ if (fabs(ctm[1]) > t) {
+ t = fabs(ctm[1]);
+ }
+ if (fabs(ctm[2]) > t) {
+ t = fabs(ctm[2]);
+ }
+ if (fabs(ctm[3]) > t) {
+ t = fabs(ctm[3]);
+ }
+ if (r0 > r1) {
+ t *= r0;
+ } else {
+ t *= r1;
+ }
+ if (t < 1) {
+ n = 3;
+ } else {
+ n = (int)(M_PI / acos(1 - 0.1 / t));
+ if (n < 3) {
+ n = 3;
+ } else if (n > 200) {
+ n = 200;
+ }
+ }
+
+ // Traverse the t axis and do the shading.
+ //
+ // This generates and fills a series of rings. Each ring is defined
+ // by two circles:
+ // sa, ta, xa, ya, ra, colorA
+ // sb, tb, xb, yb, rb, colorB
+ //
+ // The s/t axis is divided into radialMaxSplits parts; these parts
+ // are combined as much as possible while respecting the
+ // radialColorDelta parameter.
+
+ // setup for the start circle
+ ia = 0;
+ sa = sMin;
+ ta = t0 + sa * (t1 - t0);
+ xa = x0 + sa * (x1 - x0);
+ ya = y0 + sa * (y1 - y0);
+ ra = r0 + sa * (r1 - r0);
+ if (ta < t0) {
+ shading->getColor(t0, &colorA);
+ } else if (ta > t1) {
+ shading->getColor(t1, &colorA);
+ } else {
+ shading->getColor(ta, &colorA);
+ }
+
+ while (ia < radialMaxSplits) {
+
+ // go as far along the t axis (toward t1) as we can, such that the
+ // color difference is within the tolerance (radialColorDelta) --
+ // this uses bisection (between the current value, t, and t1),
+ // limited to radialMaxSplits points along the t axis
+ ib = radialMaxSplits;
+ sb = sMin + ((fouble)ib / (fouble)radialMaxSplits) * (sMax - sMin);
+ tb = t0 + sb * (t1 - t0);
+ if (tb < t0) {
+ shading->getColor(t0, &colorB);
+ } else if (tb > t1) {
+ shading->getColor(t1, &colorB);
+ } else {
+ shading->getColor(tb, &colorB);
+ }
+ while (ib - ia > 1) {
+ for (k = 0; k < nComps; ++k) {
+ if (fabs(colorB.c[k] - colorA.c[k]) > radialColorDelta) {
+ break;
+ }
+ }
+ if (k == nComps) {
+ break;
+ }
+ ib = (ia + ib) / 2;
+ sb = sMin + ((fouble)ib / (fouble)radialMaxSplits) * (sMax - sMin);
+ tb = t0 + sb * (t1 - t0);
+ if (tb < t0) {
+ shading->getColor(t0, &colorB);
+ } else if (tb > t1) {
+ shading->getColor(t1, &colorB);
+ } else {
+ shading->getColor(tb, &colorB);
+ }
+ }
+
+ // compute center and radius of the circle
+ xb = x0 + sb * (x1 - x0);
+ yb = y0 + sb * (y1 - y0);
+ rb = r0 + sb * (r1 - r0);
+
+ // use the average of the colors at the two circles
+ for (k = 0; k < nComps; ++k) {
+ colorA.c[k] = 0.5 * (colorA.c[k] + colorB.c[k]);
+ }
+ state->setFillColor(&colorA);
+ out->updateFillColor(state);
+
+ // construct path for first circle
+ state->moveTo(xa + ra, ya);
+ for (k = 1; k < n; ++k) {
+ angle = ((fouble)k / (fouble)n) * 2 * M_PI;
+ state->lineTo(xa + ra * cos(angle), ya + ra * sin(angle));
+ }
+ state->closePath();
+
+ // construct and append path for second circle
+ state->moveTo(xb + rb, yb);
+ for (k = 1; k < n; ++k) {
+ angle = ((fouble)k / (fouble)n) * 2 * M_PI;
+ state->lineTo(xb + rb * cos(angle), yb + rb * sin(angle));
+ }
+ state->closePath();
+
+ // fill the ring
+ out->eoFill(state);
+ state->clearPath();
+
+ // step to the next value of t
+ ia = ib;
+ sa = sb;
+ ta = tb;
+ xa = xb;
+ ya = yb;
+ ra = rb;
+ colorA = colorB;
+ }
+}
+
void Gfx::doEndPath() {
@@ -1802,2 +1988,3 @@ void Gfx::opShowSpaceText(Object args[], int numArgs) {
Object obj;
+ int wMode;
int i;
@@ -1808,2 +1995,3 @@ void Gfx::opShowSpaceText(Object args[], int numArgs) {
}
+ wMode = state->getFont()->getWMode();
a = args[0].getArray();
@@ -1812,3 +2000,7 @@ void Gfx::opShowSpaceText(Object args[], int numArgs) {
if (obj.isNum()) {
- state->textShift(-obj.getNum() * 0.001 * state->getFontSize());
+ if (wMode) {
+ state->textShift(0, -obj.getNum() * 0.001 * state->getFontSize());
+ } else {
+ state->textShift(-obj.getNum() * 0.001 * state->getFontSize(), 0);
+ }
out->updateTextShift(state, obj.getNum());
@@ -1825,2 +2017,3 @@ void Gfx::doShowText(GString *s) {
GfxFont *font;
+ int wMode;
fouble riseX, riseY;
@@ -1828,6 +2021,11 @@ void Gfx::doShowText(GString *s) {
Unicode u[8];
- fouble dx, dy, dx2, dy2, tdx, tdy;
+ fouble x, y, dx, dy, dx2, dy2, curX, curY, tdx, tdy;
fouble originX, originY, tOriginX, tOriginY;
+ fouble oldCTM[6], newCTM[6];
+ fouble *mat;
+ Object charProc;
+ Dict *resDict;
+ Parser *oldParser;
char *p;
- int len, n, uLen, nChars, nSpaces;
+ int len, n, uLen, nChars, nSpaces, i;
@@ -1838,14 +2036,10 @@ void Gfx::doShowText(GString *s) {
font = state->getFont();
+ wMode = font->getWMode();
-#if 0 //~type3
- fouble x, y;
- fouble oldCTM[6], newCTM[6];
- fouble *mat;
- Object charProc;
- Parser *oldParser;
- int i;
-
- //~ also check out->renderType3()
- if (font->getType() == fontType3) {
+ if (out->useDrawChar()) {
out->beginString(state, s);
+ }
+
+ // handle a Type 3 char
+ if (font->getType() == fontType3 && out->interpretType3Chars()) {
mat = state->getCTM();
@@ -1869,2 +2063,4 @@ void Gfx::doShowText(GString *s) {
state->textTransformDelta(0, state->getRise(), &riseX, &riseY);
+ curX = state->getCurX();
+ curY = state->getCurY();
oldParser = parser;
@@ -1876,17 +2072,2 @@ void Gfx::doShowText(GString *s) {
&dx, &dy, &originX, &originY);
- state->transform(state->getCurX() + riseX, state->getCurY() + riseY,
- &x, &y);
- out->saveState(state);
- state = state->save();
- state->setCTM(newCTM[0], newCTM[1], newCTM[2], newCTM[3], x, y);
- //~ out->updateCTM(???)
- ((Gfx8BitFont *)font)->getCharProc(code, &charProc);
- if (charProc.isStream()) {
- display(&charProc, gFalse);
- } else {
- error(getPos(), "Missing or bad Type3 CharProc entry");
- }
- state = state->restore();
- out->restoreState(state);
- charProc.free();
dx = dx * state->getFontSize() + state->getCharSpace();
@@ -1898,3 +2079,30 @@ void Gfx::doShowText(GString *s) {
state->textTransformDelta(dx, dy, &tdx, &tdy);
- state->shift(tdx, tdy);
+ state->transform(curX + riseX, curY + riseY, &x, &y);
+ out->saveState(state);
+ state = state->save();
+ state->setCTM(newCTM[0], newCTM[1], newCTM[2], newCTM[3], x, y);
+ //~ out->updateCTM(???)
+ if (!out->beginType3Char(state, code, u, uLen)) {
+ ((Gfx8BitFont *)font)->getCharProc(code, &charProc);
+ if ((resDict = ((Gfx8BitFont *)font)->getResources())) {
+ pushResources(resDict);
+ }
+ if (charProc.isStream()) {
+ display(&charProc, gFalse);
+ } else {
+ error(getPos(), "Missing or bad Type3 CharProc entry");
+ }
+ out->endType3Char(state);
+ if (resDict) {
+ popResources();
+ }
+ charProc.free();
+ }
+ state = state->restore();
+ out->restoreState(state);
+ // GfxState::restore() does *not* restore the current position,
+ // so we track it here with (curX, curY)
+ curX += tdx;
+ curY += tdy;
+ state->moveTo(curX, curY);
p += n;
@@ -1903,10 +2111,5 @@ void Gfx::doShowText(GString *s) {
parser = oldParser;
- out->endString(state);
- return;
- }
-#endif
- if (out->useDrawChar()) {
+ } else if (out->useDrawChar()) {
state->textTransformDelta(0, state->getRise(), &riseX, &riseY);
- out->beginString(state, s);
p = s->getCString();
@@ -1917,8 +2120,16 @@ void Gfx::doShowText(GString *s) {
&dx, &dy, &originX, &originY);
- dx = dx * state->getFontSize() + state->getCharSpace();
- if (n == 1 && *p == ' ') {
- dx += state->getWordSpace();
+ if (wMode) {
+ dx *= state->getFontSize();
+ dy = dy * state->getFontSize() + state->getCharSpace();
+ if (n == 1 && *p == ' ') {
+ dy += state->getWordSpace();
+ }
+ } else {
+ dx = dx * state->getFontSize() + state->getCharSpace();
+ if (n == 1 && *p == ' ') {
+ dx += state->getWordSpace();
+ }
+ dx *= state->getHorizScaling();
+ dy *= state->getFontSize();
}
- dx *= state->getHorizScaling();
- dy *= state->getFontSize();
state->textTransformDelta(dx, dy, &tdx, &tdy);
@@ -1933,3 +2144,2 @@ void Gfx::doShowText(GString *s) {
}
- out->endString(state);
@@ -1953,7 +2163,14 @@ void Gfx::doShowText(GString *s) {
}
- dx = dx * state->getFontSize()
- + nChars * state->getCharSpace()
- + nSpaces * state->getWordSpace();
- dx *= state->getHorizScaling();
- dy *= state->getFontSize();
+ if (wMode) {
+ dx *= state->getFontSize();
+ dy = dy * state->getFontSize()
+ + nChars * state->getCharSpace()
+ + nSpaces * state->getWordSpace();
+ } else {
+ dx = dx * state->getFontSize()
+ + nChars * state->getCharSpace()
+ + nSpaces * state->getWordSpace();
+ dx *= state->getHorizScaling();
+ dy *= state->getFontSize();
+ }
state->textTransformDelta(dx, dy, &tdx, &tdy);
@@ -1962,2 +2179,8 @@ void Gfx::doShowText(GString *s) {
}
+
+ if (out->useDrawChar()) {
+ out->endString(state);
+ }
+
+ updateLevel += 10 * s->getLength();
}
@@ -1969,3 +2192,3 @@ void Gfx::doShowText(GString *s) {
void Gfx::opXObject(Object args[], int numArgs) {
- Object obj1, obj2, refObj;
+ Object obj1, obj2, obj3, refObj;
#if OPI_SUPPORT
@@ -1995,2 +2218,6 @@ void Gfx::opXObject(Object args[], int numArgs) {
doForm(&obj1);
+ } else if (obj2.isName("PS")) {
+ obj1.streamGetDict()->lookup("Level1", &obj3);
+ out->psXObject(obj1.getStream(),
+ obj3.isStream() ? obj3.getStream() : (Stream *)NULL);
} else if (obj2.isName()) {
@@ -2150,2 +2377,7 @@ void Gfx::doImage(Object *ref, Stream *str, GBool inlineImg) {
+ if ((i = width * height) > 1000) {
+ i = 1000;
+ }
+ updateLevel += i;
+
return;
@@ -2217,4 +2449,4 @@ void Gfx::doForm(Object *str) {
-void Gfx::doWidgetForm(Object *str, fouble xMin, fouble yMin,
- fouble xMax, fouble yMax) {
+void Gfx::doAnnot(Object *str, fouble xMin, fouble yMin,
+ fouble xMax, fouble yMax) {
Dict *dict, *resDict;
@@ -2222,4 +2454,7 @@ void Gfx::doWidgetForm(Object *str, fouble xMin, fouble yMin,
Object obj1;
- fouble m[6], bbox[6];
- fouble sx, sy;
+ fouble m[6], bbox[6], ictm[6];
+ fouble *ctm;
+ fouble formX0, formY0, formX1, formY1;
+ fouble annotX0, annotY0, annotX1, annotY1;
+ fouble det, x, y, sx, sy;
int i;
@@ -2229,3 +2464,3 @@ void Gfx::doWidgetForm(Object *str, fouble xMin, fouble yMin,
- // get bounding box
+ // get the form bounding box
dict->lookup("BBox", &bboxObj);
@@ -2243,3 +2478,3 @@ void Gfx::doWidgetForm(Object *str, fouble xMin, fouble yMin,
- // get matrix
+ // get the form matrix
dict->lookup("Matrix", &matrixObj);
@@ -2258,12 +2493,60 @@ void Gfx::doWidgetForm(Object *str, fouble xMin, fouble yMin,
- // scale form bbox to widget rectangle
- sx = fabs((xMax - xMin) / (bbox[2] - bbox[0]));
- sy = fabs((yMax - yMin) / (bbox[3] - bbox[1]));
- m[0] *= sx; m[1] *= sy;
- m[2] *= sx; m[3] *= sy;
- m[4] *= sx; m[5] *= sy;
+ // transform the form bbox from form space to user space
+ formX0 = bbox[0] * m[0] + bbox[1] * m[2] + m[4];
+ formY0 = bbox[0] * m[1] + bbox[1] * m[3] + m[5];
+ formX1 = bbox[2] * m[0] + bbox[3] * m[2] + m[4];
+ formY1 = bbox[2] * m[1] + bbox[3] * m[3] + m[5];
+
+ // transform the annotation bbox from default user space to user
+ // space: (bbox * baseMatrix) * iCTM
+ ctm = state->getCTM();
+ det = 1 / (ctm[0] * ctm[3] - ctm[1] * ctm[2]);
+ ictm[0] = ctm[3] * det;
+ ictm[1] = -ctm[1] * det;
+ ictm[2] = -ctm[2] * det;
+ ictm[3] = ctm[0] * det;
+ ictm[4] = (ctm[2] * ctm[5] - ctm[3] * ctm[4]) * det;
+ ictm[5] = (ctm[1] * ctm[4] - ctm[0] * ctm[5]) * det;
+ x = baseMatrix[0] * xMin + baseMatrix[2] * yMin + baseMatrix[4];
+ y = baseMatrix[1] * xMin + baseMatrix[3] * yMin + baseMatrix[5];
+ annotX0 = ictm[0] * x + ictm[2] * y + ictm[4];
+ annotY0 = ictm[1] * x + ictm[3] * y + ictm[5];
+ x = baseMatrix[0] * xMax + baseMatrix[2] * yMax + baseMatrix[4];
+ y = baseMatrix[1] * xMax + baseMatrix[3] * yMax + baseMatrix[5];
+ annotX1 = ictm[0] * x + ictm[2] * y + ictm[4];
+ annotY1 = ictm[1] * x + ictm[3] * y + ictm[5];
+
+ // swap min/max coords
+ if (formX0 > formX1) {
+ x = formX0; formX0 = formX1; formX1 = x;
+ }
+ if (formY0 > formY1) {
+ y = formY0; formY0 = formY1; formY1 = y;
+ }
+ if (annotX0 > annotX1) {
+ x = annotX0; annotX0 = annotX1; annotX1 = x;
+ }
+ if (annotY0 > annotY1) {
+ y = annotY0; annotY0 = annotY1; annotY1 = y;
+ }
- // translate to widget rectangle
- m[4] += xMin;
- m[5] += yMin;
+ // scale the form to fit the annotation bbox
+ if (formX1 == formX0) {
+ // this shouldn't happen
+ sx = 1;
+ } else {
+ sx = (annotX1 - annotX0) / (formX1 - formX0);
+ }
+ if (formY1 == formY0) {
+ // this shouldn't happen
+ sy = 1;
+ } else {
+ sy = (annotY1 - annotY0) / (formY1 - formY0);
+ }
+ m[0] *= sx;
+ m[2] *= sx;
+ m[4] = (m[4] - formX0) * sx + annotX0;
+ m[1] *= sy;
+ m[3] *= sy;
+ m[5] = (m[5] - formY0) * sy + annotY0;
@@ -2283,3 +2566,2 @@ void Gfx::doForm1(Object *str, Dict *resDict, fouble *matrix, fouble *bbox) {
fouble oldBaseMatrix[6];
- GfxResources *resPtr;
int i;
@@ -2287,3 +2569,3 @@ void Gfx::doForm1(Object *str, Dict *resDict, fouble *matrix, fouble *bbox) {
// push new resources on stack
- res = new GfxResources(xref, resDict, res);
+ pushResources(resDict);
@@ -2334,2 +2616,14 @@ void Gfx::doForm1(Object *str, Dict *resDict, fouble *matrix, fouble *bbox) {
// pop resource stack
+ popResources();
+
+ return;
+}
+
+void Gfx::pushResources(Dict *resDict) {
+ res = new GfxResources(xref, resDict, res);
+}
+
+void Gfx::popResources() {
+ GfxResources *resPtr;
+
resPtr = res->getNext();
@@ -2337,4 +2631,2 @@ void Gfx::doForm1(Object *str, Dict *resDict, fouble *matrix, fouble *bbox) {
res = resPtr;
-
- return;
}
@@ -2380,3 +2672,2 @@ Stream *Gfx::buildImageStream() {
obj.free();
- parser->getObj(&obj);
} else {
@@ -2385,4 +2676,6 @@ Stream *Gfx::buildImageStream() {
parser->getObj(&obj);
- if (obj.isEOF() || obj.isError())
+ if (obj.isEOF() || obj.isError()) {
+ gfree(key);
break;
+ }
dict.dictAdd(key, &obj);
@@ -2391,4 +2684,8 @@ Stream *Gfx::buildImageStream() {
}
- if (obj.isEOF())
+ if (obj.isEOF()) {
error(getPos(), "End of file in inline image");
+ obj.free();
+ dict.free();
+ return NULL;
+ }
obj.free();
@@ -2415,3 +2712,3 @@ void Gfx::opEndImage(Object args[], int numArgs) {
void Gfx::opSetCharWidth(Object args[], int numArgs) {
- error(getPos(), "Encountered 'd0' operator in content stream");
+ out->type3D0(state, args[0].getNum(), args[1].getNum());
}
@@ -2419,3 +2716,5 @@ void Gfx::opSetCharWidth(Object args[], int numArgs) {
void Gfx::opSetCacheDevice(Object args[], int numArgs) {
- error(getPos(), "Encountered 'd1' operator in content stream");
+ out->type3D1(state, args[0].getNum(), args[1].getNum(),
+ args[2].getNum(), args[3].getNum(),
+ args[4].getNum(), args[5].getNum());
}
diff --git a/noncore/unsupported/qpdf/xpdf/Gfx.h b/noncore/unsupported/qpdf/xpdf/Gfx.h
index be5f2c2..2ecfb24 100644
--- a/noncore/unsupported/qpdf/xpdf/Gfx.h
+++ b/noncore/unsupported/qpdf/xpdf/Gfx.h
@@ -4,3 +4,3 @@
//
-// Copyright 1996 Derek B. Noonburg
+// Copyright 1996-2002 Glyph & Cog, LLC
//
@@ -29,2 +29,3 @@ class GfxShading;
class GfxAxialShading;
+class GfxRadialShading;
class GfxState;
@@ -99,3 +100,6 @@ public:
- // Destructor.
+ // Constructor for a sub-page object.
+ Gfx(XRef *xrefA, OutputDev *outA, Dict *resDict,
+ PDFRectangle *box, GBool crop, PDFRectangle *cropBox);
+
~Gfx();
@@ -105,4 +109,9 @@ public:
- void doWidgetForm(Object *str, fouble xMin, fouble yMin,
- fouble xMax, fouble yMax);
+ // Display an annotation, given its appearance (a Form XObject) and
+ // bounding box (in default user space).
+ void doAnnot(Object *str, fouble xMin, fouble yMin,
+ fouble xMax, fouble yMax);
+
+ void pushResources(Dict *resDict);
+ void popResources();
@@ -112,4 +121,6 @@ private:
OutputDev *out; // output device
+ GBool subPage; // is this a sub-page object?
GBool printCommands; // print the drawing commands (for debugging)
GfxResources *res; // resource stack
+ int updateLevel;
@@ -181,2 +192,3 @@ private:
void doAxialShFill(GfxAxialShading *shading);
+ void doRadialShFill(GfxRadialShading *shading);
void doEndPath();
diff --git a/noncore/unsupported/qpdf/xpdf/GfxFont.cc b/noncore/unsupported/qpdf/xpdf/GfxFont.cc
index 518f97b..8d722d6 100644
--- a/noncore/unsupported/qpdf/xpdf/GfxFont.cc
+++ b/noncore/unsupported/qpdf/xpdf/GfxFont.cc
@@ -4,3 +4,3 @@
//
-// Copyright 1996-2001 Derek B. Noonburg
+// Copyright 1996-2002 Glyph & Cog, LLC
//
@@ -456,6 +456,14 @@ Gfx8BitFont::Gfx8BitFont(XRef *xref, char *tagA, Ref idA, GString *nameA,
- // get Type3 font definition
+ // get Type 3 bounding box, font definition, and resources
if (type == fontType3) {
- fontDict->lookup("CharProcs", &charProcs);
- if (!charProcs.isDict()) {
+ if (fontDict->lookup("FontBBox", &obj1)->isArray()) {
+ for (i = 0; i < 4 && i < obj1.arrayGetLength(); ++i) {
+ if (obj1.arrayGet(i, &obj2)->isNum()) {
+ fontBBox[i] = obj2.getNum();
+ }
+ obj2.free();
+ }
+ }
+ obj1.free();
+ if (!fontDict->lookup("CharProcs", &charProcs)->isDict()) {
error(-1, "Missing or invalid CharProcs dictionary in Type 3 font");
@@ -463,2 +471,5 @@ Gfx8BitFont::Gfx8BitFont(XRef *xref, char *tagA, Ref idA, GString *nameA,
}
+ if (!fontDict->lookup("Resources", &resources)->isDict()) {
+ resources.free();
+ }
}
@@ -515,5 +526,7 @@ Gfx8BitFont::Gfx8BitFont(XRef *xref, char *tagA, Ref idA, GString *nameA,
// check embedded or external font file for base encoding
+ // (only for Type 1 fonts - trying to get an encoding out of a
+ // TrueType font is a losing proposition)
fontFile = NULL;
buf = NULL;
- if ((type == fontType1 || type == fontType1C || type == fontTrueType) &&
+ if ((type == fontType1 || type == fontType1C) &&
(extFontFile || embFontID.num >= 0)) {
@@ -526,8 +539,11 @@ Gfx8BitFont::Gfx8BitFont(XRef *xref, char *tagA, Ref idA, GString *nameA,
#if 0
+ if (type == fontType1C && !strncmp(buf, "%!", 2)) {
+ // various tools (including Adobe's) occasionally embed Type 1
+ // fonts but label them Type 1C
+ type = fontType1;
+ }
if (type == fontType1) {
fontFile = new Type1FontFile(buf, len);
- } else if (type == fontType1C) {
- fontFile = new Type1CFontFile(buf, len);
} else {
- fontFile = new TrueTypeFontFile(buf, len);
+ fontFile = new Type1CFontFile(buf, len);
}
@@ -571,2 +587,3 @@ Gfx8BitFont::Gfx8BitFont(XRef *xref, char *tagA, Ref idA, GString *nameA,
if (obj2.isArray()) {
+ hasEncoding = gTrue;
code = 0;
@@ -638,4 +655,5 @@ Gfx8BitFont::Gfx8BitFont(XRef *xref, char *tagA, Ref idA, GString *nameA,
// pass 2: try to fill in the missing chars, looking for names of
- // the form 'Axx', 'xx', 'Ann', or 'nn', where 'A' is any letter,
- // 'xx' is two hex digits, and 'nn' is 2-4 decimal digits
+ // the form 'Axx', 'xx', 'Ann', 'ABnn', or 'nn', where 'A' and 'B'
+ // are any letters, 'xx' is two hex digits, and 'nn' is 2-4
+ // decimal digits
if (missing && globalParams->getMapNumericCharNames()) {
@@ -658,2 +676,5 @@ Gfx8BitFont::Gfx8BitFont(XRef *xref, char *tagA, Ref idA, GString *nameA,
code2 = atoi(charName+1);
+ } else if (n >= 4 && n <= 6 &&
+ isdigit(charName[2]) && isdigit(charName[3])) {
+ code2 = atoi(charName+2);
}
@@ -686,2 +707,3 @@ Gfx8BitFont::Gfx8BitFont(XRef *xref, char *tagA, Ref idA, GString *nameA,
if (obj1.isArray()) {
+ flags |= fontFixedWidth;
for (code = firstChar; code <= lastChar; ++code) {
@@ -690,2 +712,5 @@ Gfx8BitFont::Gfx8BitFont(XRef *xref, char *tagA, Ref idA, GString *nameA,
widths[code] = obj2.getNum() * mul;
+ if (widths[code] != widths[firstChar]) {
+ flags &= ~fontFixedWidth;
+ }
}
@@ -754,2 +779,5 @@ Gfx8BitFont::~Gfx8BitFont() {
}
+ if (resources.isDict()) {
+ resources.free();
+ }
}
@@ -773,2 +801,6 @@ CharCodeToUnicode *Gfx8BitFont::getToUnicode() {
+Dict *Gfx8BitFont::getCharProcs() {
+ return charProcs.isDict() ? charProcs.getDict() : (Dict *)NULL;
+}
+
Object *Gfx8BitFont::getCharProc(int code, Object *proc) {
@@ -782,2 +814,6 @@ Object *Gfx8BitFont::getCharProc(int code, Object *proc) {
+Dict *Gfx8BitFont::getResources() {
+ return resources.isDict() ? resources.getDict() : (Dict *)NULL;
+}
+
//------------------------------------------------------------------------
@@ -1188,2 +1224,6 @@ int GfxCIDFont::getNextChar(char *s, int len, CharCode *code,
+int GfxCIDFont::getWMode() {
+ return cMap ? cMap->getWMode() : 0;
+}
+
CharCodeToUnicode *GfxCIDFont::getToUnicode() {
@@ -1218,3 +1258,3 @@ GfxFontDict::GfxFontDict(XRef *xref, Dict *fontDict) {
} else {
- error(-1, "font resource is not a dictionary");
+ error(-1, "font resource is not a dictionary reference");
fonts[i] = NULL;
diff --git a/noncore/unsupported/qpdf/xpdf/GfxFont.h b/noncore/unsupported/qpdf/xpdf/GfxFont.h
index b1aa952..8e9fe38 100644
--- a/noncore/unsupported/qpdf/xpdf/GfxFont.h
+++ b/noncore/unsupported/qpdf/xpdf/GfxFont.h
@@ -4,3 +4,3 @@
//
-// Copyright 1996-2001 Derek B. Noonburg
+// Copyright 1996-2002 Glyph & Cog, LLC
//
@@ -115,4 +115,3 @@ public:
// NULL if there is no embedded font.
- char *getEmbeddedFontName()
- { return embFontName ? embFontName->getCString() : (char *)NULL; }
+ GString *getEmbeddedFontName() { return embFontName; }
@@ -139,2 +138,5 @@ public:
+ // Return the writing mode (0=horizontal, 1=vertical).
+ virtual int getWMode() { return 0; }
+
// Read an external or embedded font file into a buffer.
@@ -157,3 +159,3 @@ protected:
CharCodeToUnicode *readToUnicodeCMap(Dict *fontDict, int nBits);
- void GfxFont::findExtFontFile();
+ void findExtFontFile();
@@ -168,3 +170,3 @@ protected:
fouble fontMat[6]; // font matrix (Type 3 only)
- fouble fontBBox[4]; // font bounding box
+ fouble fontBBox[4]; // font bounding box (Type 3 only)
fouble missingWidth; // "default" width
@@ -206,2 +208,5 @@ public:
+ // Return the Type 3 CharProc dictionary, or NULL if none.
+ Dict *getCharProcs();
+
// Return the Type 3 CharProc for the character associated with <code>.
@@ -209,2 +214,5 @@ public:
+ // Return the Type 3 Resources dictionary, or NULL if none.
+ Dict *getResources();
+
private:
@@ -217,3 +225,4 @@ private:
fouble widths[256]; // character widths
- Object charProcs; // Type3 CharProcs dictionary
+ Object charProcs; // Type 3 CharProcs dictionary
+ Object resources; // Type 3 Resources dictionary
};
@@ -238,2 +247,5 @@ public:
+ // Return the writing mode (0=horizontal, 1=vertical).
+ virtual int getWMode();
+
// Return the Unicode map.
diff --git a/noncore/unsupported/qpdf/xpdf/GfxState.cc b/noncore/unsupported/qpdf/xpdf/GfxState.cc
index af4e0d4..befd45a 100644
--- a/noncore/unsupported/qpdf/xpdf/GfxState.cc
+++ b/noncore/unsupported/qpdf/xpdf/GfxState.cc
@@ -4,3 +4,3 @@
//
-// Copyright 1996 Derek B. Noonburg
+// Copyright 1996-2002 Glyph & Cog, LLC
//
@@ -410,5 +410,18 @@ void GfxDeviceCMYKColorSpace::getGray(GfxColor *color, fouble *gray) {
void GfxDeviceCMYKColorSpace::getRGB(GfxColor *color, GfxRGB *rgb) {
- rgb->r = clip01(1 - (color->c[0] + color->c[3]));
- rgb->g = clip01(1 - (color->c[1] + color->c[3]));
- rgb->b = clip01(1 - (color->c[2] + color->c[3]));
+ fouble c, m, y, aw, ac, am, ay, ar, ag, ab;
+
+ c = clip01(color->c[0] + color->c[3]);
+ m = clip01(color->c[1] + color->c[3]);
+ y = clip01(color->c[2] + color->c[3]);
+ aw = (1-c) * (1-m) * (1-y);
+ ac = c * (1-m) * (1-y);
+ am = (1-c) * m * (1-y);
+ ay = (1-c) * (1-m) * y;
+ ar = (1-c) * m * y;
+ ag = c * (1-m) * y;
+ ab = c * m * (1-y);
+ rgb->r = clip01(aw + 0.9137*am + 0.9961*ay + 0.9882*ar);
+ rgb->g = clip01(aw + 0.6196*ac + ay + 0.5176*ag);
+ rgb->b = clip01(aw + 0.7804*ac + 0.5412*am + 0.0667*ar + 0.2118*ag +
+ 0.4863*ab);
}
@@ -1270,6 +1283,2 @@ GfxShading *GfxShading::parse(Object *obj) {
obj1.free();
- if (typeA != 2) {
- error(-1, "Unimplemented shading type %d", typeA);
- goto err1;
- }
@@ -1319,3 +1328,13 @@ GfxShading *GfxShading::parse(Object *obj) {
- shading = GfxAxialShading::parse(obj->getDict());
+ switch (typeA) {
+ case 2:
+ shading = GfxAxialShading::parse(obj->getDict());
+ break;
+ case 3:
+ shading = GfxRadialShading::parse(obj->getDict());
+ break;
+ default:
+ error(-1, "Unimplemented shading type %d", typeA);
+ goto err1;
+ }
@@ -1459,2 +1478,124 @@ void GfxAxialShading::getColor(fouble t, GfxColor *color) {
//------------------------------------------------------------------------
+// GfxRadialShading
+//------------------------------------------------------------------------
+
+GfxRadialShading::GfxRadialShading(fouble x0A, fouble y0A, fouble r0A,
+ fouble x1A, fouble y1A, fouble r1A,
+ fouble t0A, fouble t1A,
+ Function **funcsA, int nFuncsA,
+ GBool extend0A, GBool extend1A) {
+ int i;
+
+ x0 = x0A;
+ y0 = y0A;
+ r0 = r0A;
+ x1 = x1A;
+ y1 = y1A;
+ r1 = r1A;
+ t0 = t0A;
+ t1 = t1A;
+ nFuncs = nFuncsA;
+ for (i = 0; i < nFuncs; ++i) {
+ funcs[i] = funcsA[i];
+ }
+ extend0 = extend0A;
+ extend1 = extend1A;
+}
+
+GfxRadialShading::~GfxRadialShading() {
+ int i;
+
+ for (i = 0; i < nFuncs; ++i) {
+ delete funcs[i];
+ }
+}
+
+GfxRadialShading *GfxRadialShading::parse(Dict *dict) {
+ fouble x0A, y0A, r0A, x1A, y1A, r1A;
+ fouble t0A, t1A;
+ Function *funcsA[gfxColorMaxComps];
+ int nFuncsA;
+ GBool extend0A, extend1A;
+ Object obj1, obj2;
+ int i;
+
+ x0A = y0A = r0A = x1A = y1A = r1A = 0;
+ if (dict->lookup("Coords", &obj1)->isArray() &&
+ obj1.arrayGetLength() == 6) {
+ x0A = obj1.arrayGet(0, &obj2)->getNum();
+ obj2.free();
+ y0A = obj1.arrayGet(1, &obj2)->getNum();
+ obj2.free();
+ r0A = obj1.arrayGet(2, &obj2)->getNum();
+ obj2.free();
+ x1A = obj1.arrayGet(3, &obj2)->getNum();
+ obj2.free();
+ y1A = obj1.arrayGet(4, &obj2)->getNum();
+ obj2.free();
+ r1A = obj1.arrayGet(5, &obj2)->getNum();
+ obj2.free();
+ } else {
+ error(-1, "Missing or invalid Coords in shading dictionary");
+ goto err1;
+ }
+ obj1.free();
+
+ t0A = 0;
+ t1A = 1;
+ if (dict->lookup("Domain", &obj1)->isArray() &&
+ obj1.arrayGetLength() == 2) {
+ t0A = obj1.arrayGet(0, &obj2)->getNum();
+ obj2.free();
+ t1A = obj1.arrayGet(1, &obj2)->getNum();
+ obj2.free();
+ }
+ obj1.free();
+
+ dict->lookup("Function", &obj1);
+ if (obj1.isArray()) {
+ nFuncsA = obj1.arrayGetLength();
+ for (i = 0; i < nFuncsA; ++i) {
+ obj1.arrayGet(i, &obj2);
+ if (!(funcsA[i] = Function::parse(&obj2))) {
+ obj1.free();
+ obj2.free();
+ goto err1;
+ }
+ obj2.free();
+ }
+ } else {
+ nFuncsA = 1;
+ if (!(funcsA[0] = Function::parse(&obj1))) {
+ obj1.free();
+ goto err1;
+ }
+ }
+ obj1.free();
+
+ extend0A = extend1A = gFalse;
+ if (dict->lookup("Extend", &obj1)->isArray() &&
+ obj1.arrayGetLength() == 2) {
+ extend0A = obj1.arrayGet(0, &obj2)->getBool();
+ obj2.free();
+ extend1A = obj1.arrayGet(1, &obj2)->getBool();
+ obj2.free();
+ }
+ obj1.free();
+
+ return new GfxRadialShading(x0A, y0A, r0A, x1A, y1A, r1A, t0A, t1A,
+ funcsA, nFuncsA, extend0A, extend1A);
+
+ err1:
+ return NULL;
+}
+
+void GfxRadialShading::getColor(fouble t, GfxColor *color) {
+ int i;
+
+ for (i = 0; i < nFuncs; ++i) {
+ funcs[i]->transform(&t, &color->c[i]);
+ }
+}
+
+//------------------------------------------------------------------------
// GfxImageColorMap
@@ -1920,2 +2061,63 @@ GfxState::GfxState(GfxState *state) {
+void GfxState::getUserClipBBox(fouble *xMin, fouble *yMin,
+ fouble *xMax, fouble *yMax) {
+ fouble ictm[6];
+ fouble xMin1, yMin1, xMax1, yMax1, det, tx, ty;
+
+ // invert the CTM
+ det = 1 / (ctm[0] * ctm[3] - ctm[1] * ctm[2]);
+ ictm[0] = ctm[3] * det;
+ ictm[1] = -ctm[1] * det;
+ ictm[2] = -ctm[2] * det;
+ ictm[3] = ctm[0] * det;
+ ictm[4] = (ctm[2] * ctm[5] - ctm[3] * ctm[4]) * det;
+ ictm[5] = (ctm[1] * ctm[4] - ctm[0] * ctm[5]) * det;
+
+ // transform all four corners of the clip bbox; find the min and max
+ // x and y values
+ xMin1 = xMax1 = clipXMin * ictm[0] + clipYMin * ictm[2] + ictm[4];
+ yMin1 = yMax1 = clipXMin * ictm[1] + clipYMin * ictm[3] + ictm[5];
+ tx = clipXMin * ictm[0] + clipYMax * ictm[2] + ictm[4];
+ ty = clipXMin * ictm[1] + clipYMax * ictm[3] + ictm[5];
+ if (tx < xMin1) {
+ xMin1 = tx;
+ } else if (tx > xMax1) {
+ xMax1 = tx;
+ }
+ if (ty < yMin1) {
+ yMin1 = ty;
+ } else if (ty > yMax1) {
+ yMax1 = ty;
+ }
+ tx = clipXMax * ictm[0] + clipYMin * ictm[2] + ictm[4];
+ ty = clipXMax * ictm[1] + clipYMin * ictm[3] + ictm[5];
+ if (tx < xMin1) {
+ xMin1 = tx;
+ } else if (tx > xMax1) {
+ xMax1 = tx;
+ }
+ if (ty < yMin1) {
+ yMin1 = ty;
+ } else if (ty > yMax1) {
+ yMax1 = ty;
+ }
+ tx = clipXMax * ictm[0] + clipYMax * ictm[2] + ictm[4];
+ ty = clipXMax * ictm[1] + clipYMax * ictm[3] + ictm[5];
+ if (tx < xMin1) {
+ xMin1 = tx;
+ } else if (tx > xMax1) {
+ xMax1 = tx;
+ }
+ if (ty < yMin1) {
+ yMin1 = ty;
+ } else if (ty > yMax1) {
+ yMax1 = ty;
+ }
+
+ *xMin = xMin1;
+ *yMin = yMin1;
+ *xMax = xMax1;
+ *yMax = yMax1;
+}
+
fouble GfxState::transformWidth(fouble w) {
@@ -1948,2 +2150,4 @@ void GfxState::setCTM(fouble a, fouble b, fouble c,
fouble d, fouble e, fouble f) {
+ int i;
+
ctm[0] = a;
@@ -1954,2 +2158,11 @@ void GfxState::setCTM(fouble a, fouble b, fouble c,
ctm[5] = f;
+
+ // avoid FP exceptions on badly messed up PDF files
+ for (i = 0; i < 6; ++i) {
+ if (ctm[i] > fouble(1e3)) {
+ ctm[i] = fouble(1e3);
+ } else if (ctm[i] < -fouble(1e3)) {
+ ctm[i] = -fouble(1e3);
+ }
+ }
}
@@ -1962,2 +2175,3 @@ void GfxState::concatCTM(fouble a, fouble b, fouble c,
fouble d1 = ctm[3];
+ int i;
@@ -1969,2 +2183,11 @@ void GfxState::concatCTM(fouble a, fouble b, fouble c,
ctm[5] = e * b1 + f * d1 + ctm[5];
+
+ // avoid FP exceptions on badly messed up PDF files
+ for (i = 0; i < 6; ++i) {
+ if (ctm[i] > fouble(1e3)) {
+ ctm[i] = fouble(1e3);
+ } else if (ctm[i] < -fouble(1e3)) {
+ ctm[i] = -fouble(1e3);
+ }
+ }
}
@@ -2053,6 +2276,6 @@ void GfxState::clip() {
-void GfxState::textShift(fouble tx) {
+void GfxState::textShift(fouble tx, fouble ty) {
fouble dx, dy;
- textTransformDelta(tx, 0, &dx, &dy);
+ textTransformDelta(tx, ty, &dx, &dy);
curX += dx;
@@ -2097 +2320,2 @@ GfxState *GfxState::restore() {
}
+
diff --git a/noncore/unsupported/qpdf/xpdf/GfxState.h b/noncore/unsupported/qpdf/xpdf/GfxState.h
index 7fe16ea..328f9a8 100644
--- a/noncore/unsupported/qpdf/xpdf/GfxState.h
+++ b/noncore/unsupported/qpdf/xpdf/GfxState.h
@@ -4,3 +4,3 @@
//
-// Copyright 1996 Derek B. Noonburg
+// Copyright 1996-2002 Glyph & Cog, LLC
//
@@ -570,2 +570,36 @@ private:
//------------------------------------------------------------------------
+// GfxRadialShading
+//------------------------------------------------------------------------
+
+class GfxRadialShading: public GfxShading {
+public:
+
+ GfxRadialShading(fouble x0A, fouble y0A, fouble r0A,
+ fouble x1A, fouble y1A, fouble r1A,
+ fouble t0A, fouble t1A,
+ Function **funcsA, int nFuncsA,
+ GBool extend0A, GBool extend1A);
+ virtual ~GfxRadialShading();
+
+ static GfxRadialShading *parse(Dict *dict);
+
+ void getCoords(fouble *x0A, fouble *y0A, fouble *r0A,
+ fouble *x1A, fouble *y1A, fouble *r1A)
+ { *x0A = x0; *y0A = y0; *r0A = r0; *x1A = x1; *y1A = y1; *r1A = r1; }
+ fouble getDomain0() { return t0; }
+ fouble getDomain1() { return t1; }
+ void getColor(fouble t, GfxColor *color);
+ GBool getExtend0() { return extend0; }
+ GBool getExtend1() { return extend1; }
+
+private:
+
+ fouble x0, y0, r0, x1, y1, r1;
+ fouble t0, t1;
+ Function *funcs[gfxColorMaxComps];
+ int nFuncs;
+ GBool extend0, extend1;
+};
+
+//------------------------------------------------------------------------
// GfxImageColorMap
@@ -785,2 +819,3 @@ public:
{ *xMin = clipXMin; *yMin = clipYMin; *xMax = clipXMax; *yMax = clipYMax; }
+ void getUserClipBBox(fouble *xMin, fouble *yMin, fouble *xMax, fouble *yMax);
fouble getLineX() { return lineX; }
@@ -867,3 +902,3 @@ public:
{ lineX = tx; lineY = ty; textTransform(tx, ty, &curX, &curY); }
- void textShift(fouble tx);
+ void textShift(fouble tx, fouble ty);
void shift(fouble dx, fouble dy);
diff --git a/noncore/unsupported/qpdf/xpdf/GlobalParams.cc b/noncore/unsupported/qpdf/xpdf/GlobalParams.cc
index 8be58a3..0bc908e 100644
--- a/noncore/unsupported/qpdf/xpdf/GlobalParams.cc
+++ b/noncore/unsupported/qpdf/xpdf/GlobalParams.cc
@@ -4,3 +4,3 @@
//
-// Copyright 2001 Derek B. Noonburg
+// Copyright 2001-2002 Glyph & Cog, LLC
//
@@ -98,5 +98,8 @@ DisplayFontParam::~DisplayFontParam() {
-PSFontParam::PSFontParam(GString *pdfFontNameA, GString *psFontNameA) {
+PSFontParam::PSFontParam(GString *pdfFontNameA, int wModeA,
+ GString *psFontNameA, GString *encodingA) {
pdfFontName = pdfFontNameA;
+ wMode = wModeA;
psFontName = psFontNameA;
+ encoding = encodingA;
}
@@ -106,2 +109,5 @@ PSFontParam::~PSFontParam() {
delete psFontName;
+ if (encoding) {
+ delete encoding;
+ }
}
@@ -117,7 +123,2 @@ GlobalParams::GlobalParams(char *cfgFileName) {
FILE *f;
- char buf[512];
- int line;
- GList *tokens;
- GString *cmd;
- char *p1, *p2;
int i;
@@ -126,4 +127,6 @@ GlobalParams::GlobalParams(char *cfgFileName) {
+ // scan the encoding in reverse because we want the lowest-numbered
+ // index for each char name ('space' is encoded twice)
macRomanReverseMap = new NameToCharCode();
- for (i = 0; i < 256; ++i) {
+ for (i = 255; i >= 0; --i) {
if (macRomanEncoding[i]) {
@@ -141,2 +144,3 @@ GlobalParams::GlobalParams(char *cfgFileName) {
displayCIDFonts = new GHash();
+ displayNamedCIDFonts = new GHash();
#if HAVE_PAPER_H
@@ -156,5 +160,10 @@ GlobalParams::GlobalParams(char *cfgFileName) {
psFonts = new GHash();
+ psNamedFonts16 = new GList();
+ psFonts16 = new GList();
psEmbedType1 = gTrue;
psEmbedTrueType = gTrue;
+ psEmbedCIDPostScript = gTrue;
+ psEmbedCIDTrueType = gTrue;
psOPI = gFalse;
+ psASCIIHex = gFalse;
textEncoding = new GString("Latin1");
@@ -168,2 +177,3 @@ GlobalParams::GlobalParams(char *cfgFileName) {
fontDirs = new GList();
+ initialZoom = new GString("1");
t1libControl = fontRastAALow;
@@ -195,2 +205,4 @@ GlobalParams::GlobalParams(char *cfgFileName) {
residentUnicodeMaps->add(map->getEncodingName(), map);
+ map = new UnicodeMap("UCS-2", &mapUCS2);
+ residentUnicodeMaps->add(map->getEncodingName(), map);
@@ -221,2 +233,3 @@ GlobalParams::GlobalParams(char *cfgFileName) {
#if defined(WIN32) && !defined(__CYGWIN32__)
+ char buf[512];
i = GetModuleFileName(NULL, buf, sizeof(buf));
@@ -236,94 +249,137 @@ GlobalParams::GlobalParams(char *cfgFileName) {
if (f) {
- line = 1;
- while (fgets(buf, sizeof(buf) - 1, f)) {
-
- // break the line into tokens
- tokens = new GList();
- p1 = buf;
- while (*p1) {
- for (; *p1 && isspace(*p1); ++p1) ;
- if (!*p1) {
- break;
- }
- if (*p1 == '"' || *p1 == '\'') {
- for (p2 = p1 + 1; *p2 && *p2 != *p1; ++p2) ;
- ++p1;
- } else {
- for (p2 = p1 + 1; *p2 && !isspace(*p2); ++p2) ;
- }
- tokens->append(new GString(p1, p2 - p1));
- p1 = p2 + 1;
+ parseFile(fileName, f);
+ delete fileName;
+ }
+}
+
+void GlobalParams::parseFile(GString *fileName, FILE *f) {
+ int line;
+ GList *tokens;
+ GString *cmd, *incFile;
+ char *p1, *p2;
+ char buf[512];
+ FILE *f2;
+
+ line = 1;
+ while (fgets(buf, sizeof(buf) - 1, f)) {
+
+ // break the line into tokens
+ tokens = new GList();
+ p1 = buf;
+ while (*p1) {
+ for (; *p1 && isspace(*p1); ++p1) ;
+ if (!*p1) {
+ break;
+ }
+ if (*p1 == '"' || *p1 == '\'') {
+ for (p2 = p1 + 1; *p2 && *p2 != *p1; ++p2) ;
+ ++p1;
+ } else {
+ for (p2 = p1 + 1; *p2 && !isspace(*p2); ++p2) ;
}
+ tokens->append(new GString(p1, p2 - p1));
+ p1 = p2 + 1;
+ }
- if (tokens->getLength() > 0 &&
- ((GString *)tokens->get(0))->getChar(0) != '#') {
- cmd = (GString *)tokens->get(0);
- if (!cmd->cmp("nameToUnicode")) {
- parseNameToUnicode(tokens, fileName, line);
- } else if (!cmd->cmp("cidToUnicode")) {
- parseCIDToUnicode(tokens, fileName, line);
- } else if (!cmd->cmp("unicodeMap")) {
- parseUnicodeMap(tokens, fileName, line);
- } else if (!cmd->cmp("cMapDir")) {
- parseCMapDir(tokens, fileName, line);
- } else if (!cmd->cmp("toUnicodeDir")) {
- parseToUnicodeDir(tokens, fileName, line);
- } else if (!cmd->cmp("displayFontX")) {
- parseDisplayFont(tokens, gFalse, displayFontX, fileName, line);
- } else if (!cmd->cmp("displayFontT1")) {
- parseDisplayFont(tokens, gFalse, displayFontT1, fileName, line);
- } else if (!cmd->cmp("displayFontTT")) {
- parseDisplayFont(tokens, gFalse, displayFontTT, fileName, line);
- } else if (!cmd->cmp("displayCIDFontX")) {
- parseDisplayFont(tokens, gTrue, displayFontX, fileName, line);
- } else if (!cmd->cmp("psFile")) {
- parsePSFile(tokens, fileName, line);
- } else if (!cmd->cmp("psFont")) {
- parsePSFont(tokens, fileName, line);
- } else if (!cmd->cmp("psPaperSize")) {
- parsePSPaperSize(tokens, fileName, line);
- } else if (!cmd->cmp("psDuplex")) {
- parseYesNo("psDuplex", &psDuplex, tokens, fileName, line);
- } else if (!cmd->cmp("psLevel")) {
- parsePSLevel(tokens, fileName, line);
- } else if (!cmd->cmp("psEmbedType1")) {
- parseYesNo("psEmbedType1", &psEmbedType1, tokens, fileName, line);
- } else if (!cmd->cmp("psEmbedTrueType")) {
- parseYesNo("psEmbedTrueType", &psEmbedTrueType,
- tokens, fileName, line);
- } else if (!cmd->cmp("psOPI")) {
- parseYesNo("psOPI", &psOPI, tokens, fileName, line);
- } else if (!cmd->cmp("textEncoding")) {
- parseTextEncoding(tokens, fileName, line);
- } else if (!cmd->cmp("textEOL")) {
- parseTextEOL(tokens, fileName, line);
- } else if (!cmd->cmp("fontDir")) {
- parseFontDir(tokens, fileName, line);
- } else if (!cmd->cmp("t1libControl")) {
- parseFontRastControl("t1libControl", &t1libControl,
- tokens, fileName, line);
- } else if (!cmd->cmp("freetypeControl")) {
- parseFontRastControl("freetypeControl", &freetypeControl,
- tokens, fileName, line);
- } else if (!cmd->cmp("urlCommand")) {
- parseURLCommand(tokens, fileName, line);
- } else if (!cmd->cmp("mapNumericCharNames")) {
- parseYesNo("mapNumericCharNames", &mapNumericCharNames,
- tokens, fileName, line);
- } else if (!cmd->cmp("errQuiet")) {
- parseYesNo("errQuiet", &errQuiet, tokens, fileName, line);
- } else if (!cmd->cmp("fontpath") || !cmd->cmp("fontmap")) {
- error(-1, "Unknown config file command");
- error(-1, "-- the config file format has changed since Xpdf 0.9x");
+ if (tokens->getLength() > 0 &&
+ ((GString *)tokens->get(0))->getChar(0) != '#') {
+ cmd = (GString *)tokens->get(0);
+ if (!cmd->cmp("include")) {
+ if (tokens->getLength() == 2) {
+ incFile = (GString *)tokens->get(1);
+ if ((f2 = fopen(incFile->getCString(), "r"))) {
+ parseFile(incFile, f2);
+ fclose(f2);
+ } else {
+ error(-1, "Couldn't find included config file: '%s' (%s:%d)",
+ incFile->getCString(), fileName->getCString(), line);
+ }
} else {
- error(-1, "Unknown config file command '%s' (%s:%d)",
- cmd->getCString(), fileName->getCString(), line);
+ error(-1, "Bad 'include' config file command (%s:%d)",
+ fileName->getCString(), line);
}
+ } else if (!cmd->cmp("nameToUnicode")) {
+ parseNameToUnicode(tokens, fileName, line);
+ } else if (!cmd->cmp("cidToUnicode")) {
+ parseCIDToUnicode(tokens, fileName, line);
+ } else if (!cmd->cmp("unicodeMap")) {
+ parseUnicodeMap(tokens, fileName, line);
+ } else if (!cmd->cmp("cMapDir")) {
+ parseCMapDir(tokens, fileName, line);
+ } else if (!cmd->cmp("toUnicodeDir")) {
+ parseToUnicodeDir(tokens, fileName, line);
+ } else if (!cmd->cmp("displayFontX")) {
+ parseDisplayFont(tokens, displayFonts, displayFontX, fileName, line);
+ } else if (!cmd->cmp("displayFontT1")) {
+ parseDisplayFont(tokens, displayFonts, displayFontT1, fileName, line);
+ } else if (!cmd->cmp("displayFontTT")) {
+ parseDisplayFont(tokens, displayFonts, displayFontTT, fileName, line);
+ } else if (!cmd->cmp("displayCIDFontX")) {
+ parseDisplayFont(tokens, displayCIDFonts,
+ displayFontX, fileName, line);
+ } else if (!cmd->cmp("displayNamedCIDFontX")) {
+ parseDisplayFont(tokens, displayNamedCIDFonts,
+ displayFontX, fileName, line);
+ } else if (!cmd->cmp("psFile")) {
+ parsePSFile(tokens, fileName, line);
+ } else if (!cmd->cmp("psFont")) {
+ parsePSFont(tokens, fileName, line);
+ } else if (!cmd->cmp("psNamedFont16")) {
+ parsePSFont16("psNamedFont16", psNamedFonts16,
+ tokens, fileName, line);
+ } else if (!cmd->cmp("psFont16")) {
+ parsePSFont16("psFont16", psFonts16, tokens, fileName, line);
+ } else if (!cmd->cmp("psPaperSize")) {
+ parsePSPaperSize(tokens, fileName, line);
+ } else if (!cmd->cmp("psDuplex")) {
+ parseYesNo("psDuplex", &psDuplex, tokens, fileName, line);
+ } else if (!cmd->cmp("psLevel")) {
+ parsePSLevel(tokens, fileName, line);
+ } else if (!cmd->cmp("psEmbedType1Fonts")) {
+ parseYesNo("psEmbedType1", &psEmbedType1, tokens, fileName, line);
+ } else if (!cmd->cmp("psEmbedTrueTypeFonts")) {
+ parseYesNo("psEmbedTrueType", &psEmbedTrueType,
+ tokens, fileName, line);
+ } else if (!cmd->cmp("psEmbedCIDPostScriptFonts")) {
+ parseYesNo("psEmbedCIDPostScript", &psEmbedCIDPostScript,
+ tokens, fileName, line);
+ } else if (!cmd->cmp("psEmbedCIDTrueTypeFonts")) {
+ parseYesNo("psEmbedCIDTrueType", &psEmbedCIDTrueType,
+ tokens, fileName, line);
+ } else if (!cmd->cmp("psOPI")) {
+ parseYesNo("psOPI", &psOPI, tokens, fileName, line);
+ } else if (!cmd->cmp("psASCIIHex")) {
+ parseYesNo("psASCIIHex", &psASCIIHex, tokens, fileName, line);
+ } else if (!cmd->cmp("textEncoding")) {
+ parseTextEncoding(tokens, fileName, line);
+ } else if (!cmd->cmp("textEOL")) {
+ parseTextEOL(tokens, fileName, line);
+ } else if (!cmd->cmp("fontDir")) {
+ parseFontDir(tokens, fileName, line);
+ } else if (!cmd->cmp("initialZoom")) {
+ parseInitialZoom(tokens, fileName, line);
+ } else if (!cmd->cmp("t1libControl")) {
+ parseFontRastControl("t1libControl", &t1libControl,
+ tokens, fileName, line);
+ } else if (!cmd->cmp("freetypeControl")) {
+ parseFontRastControl("freetypeControl", &freetypeControl,
+ tokens, fileName, line);
+ } else if (!cmd->cmp("urlCommand")) {
+ parseURLCommand(tokens, fileName, line);
+ } else if (!cmd->cmp("mapNumericCharNames")) {
+ parseYesNo("mapNumericCharNames", &mapNumericCharNames,
+ tokens, fileName, line);
+ } else if (!cmd->cmp("errQuiet")) {
+ parseYesNo("errQuiet", &errQuiet, tokens, fileName, line);
+ } else if (!cmd->cmp("fontpath") || !cmd->cmp("fontmap")) {
+ error(-1, "Unknown config file command");
+ error(-1, "-- the config file format has changed since Xpdf 0.9x");
+ } else {
+ error(-1, "Unknown config file command '%s' (%s:%d)",
+ cmd->getCString(), fileName->getCString(), line);
}
-
- deleteGList(tokens, GString);
- ++line;
}
- delete fileName;
+ deleteGList(tokens, GString);
+ ++line;
}
@@ -428,3 +484,3 @@ void GlobalParams::parseToUnicodeDir(GList *tokens, GString *fileName,
-void GlobalParams::parseDisplayFont(GList *tokens, GBool isCID,
+void GlobalParams::parseDisplayFont(GList *tokens, GHash *fontHash,
DisplayFontParamKind kind,
@@ -460,13 +516,6 @@ void GlobalParams::parseDisplayFont(GList *tokens, GBool isCID,
- if (isCID) {
- if ((old = (DisplayFontParam *)displayCIDFonts->remove(param->name))) {
- delete old;
- }
- displayCIDFonts->add(param->name, param);
- } else {
- if ((old = (DisplayFontParam *)displayFonts->remove(param->name))) {
- delete old;
- }
- displayFonts->add(param->name, param);
+ if ((old = (DisplayFontParam *)fontHash->remove(param->name))) {
+ delete old;
}
+ fontHash->add(param->name, param);
return;
@@ -476,3 +525,3 @@ void GlobalParams::parseDisplayFont(GList *tokens, GBool isCID,
err1:
- error(-1, "Bad 'displayFont...' config file command (%s:%d)",
+ error(-1, "Bad 'display*Font*' config file command (%s:%d)",
fileName->getCString(), line);
@@ -518,2 +567,6 @@ void GlobalParams::parsePSLevel(GList *tokens, GString *fileName, int line) {
psLevel = psLevel2Sep;
+ } else if (!tok->cmp("level3")) {
+ psLevel = psLevel3;
+ } else if (!tok->cmp("level3Sep")) {
+ psLevel = psLevel3Sep;
} else {
@@ -544,4 +597,4 @@ void GlobalParams::parsePSFont(GList *tokens, GString *fileName, int line) {
}
- param = new PSFontParam(((GString *)tokens->get(1))->copy(),
- ((GString *)tokens->get(2))->copy());
+ param = new PSFontParam(((GString *)tokens->get(1))->copy(), 0,
+ ((GString *)tokens->get(2))->copy(), NULL);
psFonts->add(param->pdfFontName, param);
@@ -549,2 +602,30 @@ void GlobalParams::parsePSFont(GList *tokens, GString *fileName, int line) {
+void GlobalParams::parsePSFont16(char *cmdName, GList *fontList,
+ GList *tokens, GString *fileName, int line) {
+ PSFontParam *param;
+ int wMode;
+ GString *tok;
+
+ if (tokens->getLength() != 5) {
+ error(-1, "Bad '%s' config file command (%s:%d)",
+ cmdName, fileName->getCString(), line);
+ return;
+ }
+ tok = (GString *)tokens->get(2);
+ if (!tok->cmp("H")) {
+ wMode = 0;
+ } else if (!tok->cmp("V")) {
+ wMode = 1;
+ } else {
+ error(-1, "Bad '%s' config file command (%s:%d)",
+ cmdName, fileName->getCString(), line);
+ return;
+ }
+ param = new PSFontParam(((GString *)tokens->get(1))->copy(),
+ wMode,
+ ((GString *)tokens->get(3))->copy(),
+ ((GString *)tokens->get(4))->copy());
+ fontList->append(param);
+}
+
void GlobalParams::parseTextEncoding(GList *tokens, GString *fileName,
@@ -590,6 +671,6 @@ void GlobalParams::parseFontDir(GList *tokens, GString *fileName, int line) {
-void GlobalParams::parseURLCommand(GList *tokens, GString *fileName,
- int line) {
+void GlobalParams::parseInitialZoom(GList *tokens,
+ GString *fileName, int line) {
if (tokens->getLength() != 2) {
- error(-1, "Bad 'urlCommand' config file command (%s:%d)",
+ error(-1, "Bad 'initialZoom' config file command (%s:%d)",
fileName->getCString(), line);
@@ -597,6 +678,4 @@ void GlobalParams::parseURLCommand(GList *tokens, GString *fileName,
}
- if (urlCommand) {
- delete urlCommand;
- }
- urlCommand = ((GString *)tokens->get(1))->copy();
+ delete initialZoom;
+ initialZoom = ((GString *)tokens->get(1))->copy();
}
@@ -620,2 +699,15 @@ void GlobalParams::parseFontRastControl(char *cmdName, FontRastControl *val,
+void GlobalParams::parseURLCommand(GList *tokens, GString *fileName,
+ int line) {
+ if (tokens->getLength() != 2) {
+ error(-1, "Bad 'urlCommand' config file command (%s:%d)",
+ fileName->getCString(), line);
+ return;
+ }
+ if (urlCommand) {
+ delete urlCommand;
+ }
+ urlCommand = ((GString *)tokens->get(1))->copy();
+}
+
void GlobalParams::parseYesNo(char *cmdName, GBool *flag,
@@ -656,2 +748,3 @@ GlobalParams::~GlobalParams() {
deleteGHash(displayCIDFonts, DisplayFontParam);
+ deleteGHash(displayNamedCIDFonts, DisplayFontParam);
if (psFile) {
@@ -660,4 +753,7 @@ GlobalParams::~GlobalParams() {
deleteGHash(psFonts, PSFontParam);
+ deleteGList(psNamedFonts16, PSFontParam);
+ deleteGList(psFonts16, PSFontParam);
delete textEncoding;
deleteGList(fontDirs, GString);
+ delete initialZoom;
if (urlCommand) {
@@ -754,4 +850,11 @@ DisplayFontParam *GlobalParams::getDisplayFont(GString *fontName) {
-DisplayFontParam *GlobalParams::getDisplayCIDFont(GString *collection) {
- return (DisplayFontParam *)displayCIDFonts->lookup(collection);
+DisplayFontParam *GlobalParams::getDisplayCIDFont(GString *fontName,
+ GString *collection) {
+ DisplayFontParam *dfp;
+
+ if (!fontName ||
+ !(dfp = (DisplayFontParam *)displayNamedCIDFonts->lookup(fontName))) {
+ dfp = (DisplayFontParam *)displayCIDFonts->lookup(collection);
+ }
+ return dfp;
}
@@ -762,2 +865,31 @@ PSFontParam *GlobalParams::getPSFont(GString *fontName) {
+PSFontParam *GlobalParams::getPSFont16(GString *fontName,
+ GString *collection, int wMode) {
+ PSFontParam *p;
+ int i;
+
+ p = NULL;
+ if (fontName) {
+ for (i = 0; i < psNamedFonts16->getLength(); ++i) {
+ p = (PSFontParam *)psNamedFonts16->get(i);
+ if (!p->pdfFontName->cmp(fontName) &&
+ p->wMode == wMode) {
+ break;
+ }
+ p = NULL;
+ }
+ }
+ if (!p && collection) {
+ for (i = 0; i < psFonts16->getLength(); ++i) {
+ p = (PSFontParam *)psFonts16->get(i);
+ if (!p->pdfFontName->cmp(collection) &&
+ p->wMode == wMode) {
+ break;
+ }
+ p = NULL;
+ }
+ }
+ return p;
+}
+
GString *GlobalParams::findFontFile(GString *fontName,
@@ -868,2 +1000,10 @@ void GlobalParams::setPSEmbedTrueType(GBool embed) {
+void GlobalParams::setPSEmbedCIDPostScript(GBool embed) {
+ psEmbedCIDPostScript = embed;
+}
+
+void GlobalParams::setPSEmbedCIDTrueType(GBool embed) {
+ psEmbedCIDTrueType = embed;
+}
+
void GlobalParams::setPSOPI(GBool opi) {
@@ -872,2 +1012,6 @@ void GlobalParams::setPSOPI(GBool opi) {
+void GlobalParams::setPSASCIIHex(GBool hex) {
+ psASCIIHex = hex;
+}
+
void GlobalParams::setTextEncoding(char *encodingName) {
@@ -890,2 +1034,7 @@ GBool GlobalParams::setTextEOL(char *s) {
+void GlobalParams::setInitialZoom(char *s) {
+ delete initialZoom;
+ initialZoom = new GString(s);
+}
+
GBool GlobalParams::setT1libControl(char *s) {
diff --git a/noncore/unsupported/qpdf/xpdf/GlobalParams.h b/noncore/unsupported/qpdf/xpdf/GlobalParams.h
index ecbb5fc..b651110 100644
--- a/noncore/unsupported/qpdf/xpdf/GlobalParams.h
+++ b/noncore/unsupported/qpdf/xpdf/GlobalParams.h
@@ -4,3 +4,3 @@
//
-// Copyright 2001 Derek B. Noonburg
+// Copyright 2001-2002 Glyph & Cog, LLC
//
@@ -47,4 +47,5 @@ public:
- GString *name; // font name for 8-bit fonts;
- // collection name for CID fonts
+ GString *name; // font name for 8-bit fonts and named
+ // CID fonts; collection name for
+ // generic CID fonts
DisplayFontParamKind kind;
@@ -81,6 +82,12 @@ public:
- GString *pdfFontName;
- GString *psFontName;
+ GString *pdfFontName; // PDF font name for 8-bit fonts and
+ // named 16-bit fonts; char collection
+ // name for generic 16-bit fonts
+ int wMode; // writing mode (0=horiz, 1=vert) for
+ // 16-bit fonts
+ GString *psFontName; // PostScript font name
+ GString *encoding; // encoding, for 16-bit fonts only
- PSFontParam(GString *pdfFontNameA, GString *psFontNameA);
+ PSFontParam(GString *pdfFontNameA, int wModeA,
+ GString *psFontNameA, GString *encodingA);
~PSFontParam();
@@ -94,3 +101,5 @@ enum PSLevel {
psLevel2,
- psLevel2Sep
+ psLevel2Sep,
+ psLevel3,
+ psLevel3Sep
};
@@ -127,3 +136,3 @@ public:
DisplayFontParam *getDisplayFont(GString *fontName);
- DisplayFontParam *getDisplayCIDFont(GString *collection);
+ DisplayFontParam *getDisplayCIDFont(GString *fontName, GString *collection);
GString *getPSFile() { return psFile; }
@@ -134,5 +143,9 @@ public:
PSFontParam *getPSFont(GString *fontName);
+ PSFontParam *getPSFont16(GString *fontName, GString *collection, int wMode);
GBool getPSEmbedType1() { return psEmbedType1; }
GBool getPSEmbedTrueType() { return psEmbedTrueType; }
+ GBool getPSEmbedCIDPostScript() { return psEmbedCIDPostScript; }
+ GBool getPSEmbedCIDTrueType() { return psEmbedCIDTrueType; }
GBool getPSOPI() { return psOPI; }
+ GBool getPSASCIIHex() { return psASCIIHex; }
GString *getTextEncodingName() { return textEncoding; }
@@ -140,2 +153,3 @@ public:
GString *findFontFile(GString *fontName, char *ext1, char *ext2);
+ GString *getInitialZoom() { return initialZoom; }
FontRastControl getT1libControl() { return t1libControl; }
@@ -161,5 +175,9 @@ public:
void setPSEmbedTrueType(GBool embed);
+ void setPSEmbedCIDPostScript(GBool embed);
+ void setPSEmbedCIDTrueType(GBool embed);
void setPSOPI(GBool opi);
+ void setPSASCIIHex(GBool hex);
void setTextEncoding(char *encodingName);
GBool setTextEOL(char *s);
+ void setInitialZoom(char *s);
GBool setT1libControl(char *s);
@@ -170,2 +188,3 @@ private:
+ void parseFile(GString *fileName, FILE *f);
void parseNameToUnicode(GList *tokens, GString *fileName, int line);
@@ -175,3 +194,4 @@ private:
void parseToUnicodeDir(GList *tokens, GString *fileName, int line);
- void parseDisplayFont(GList *tokens, GBool isCID, DisplayFontParamKind kind,
+ void parseDisplayFont(GList *tokens, GHash *fontHash,
+ DisplayFontParamKind kind,
GString *fileName, int line);
@@ -181,2 +201,4 @@ private:
void parsePSFont(GList *tokens, GString *fileName, int line);
+ void parsePSFont16(char *cmdName, GList *fontList,
+ GList *tokens, GString *fileName, int line);
void parseTextEncoding(GList *tokens, GString *fileName, int line);
@@ -184,2 +206,3 @@ private:
void parseFontDir(GList *tokens, GString *fileName, int line);
+ void parseInitialZoom(GList *tokens, GString *fileName, int line);
void parseFontRastControl(char *cmdName, FontRastControl *val,
@@ -214,2 +237,4 @@ private:
// collection [DisplayFontParam]
+ GHash *displayNamedCIDFonts; // display CID font info, indexed by
+ // font name [DisplayFontParam]
GString *psFile; // PostScript file or command (for xpdf)
@@ -221,5 +246,10 @@ private:
// font name [PSFontParam]
+ GList *psNamedFonts16; // named 16-bit fonts [PSFontParam]
+ GList *psFonts16; // generic 16-bit fonts [PSFontParam]
GBool psEmbedType1; // embed Type 1 fonts?
GBool psEmbedTrueType; // embed TrueType fonts?
+ GBool psEmbedCIDPostScript; // embed CID PostScript fonts?
+ GBool psEmbedCIDTrueType; // embed CID TrueType fonts?
GBool psOPI; // generate PostScript OPI comments?
+ GBool psASCIIHex; // use ASCIIHex instead of ASCII85?
GString *textEncoding; // encoding (unicodeMap) to use for text
@@ -229,2 +259,3 @@ private:
GList *fontDirs; // list of font dirs [GString]
+ GString *initialZoom; // initial zoom level
FontRastControl t1libControl; // t1lib rasterization mode
diff --git a/noncore/unsupported/qpdf/xpdf/Lexer.cc b/noncore/unsupported/qpdf/xpdf/Lexer.cc
index fff4bcb..a258950 100644
--- a/noncore/unsupported/qpdf/xpdf/Lexer.cc
+++ b/noncore/unsupported/qpdf/xpdf/Lexer.cc
@@ -4,3 +4,3 @@
//
-// Copyright 1996 Derek B. Noonburg
+// Copyright 1996-2002 Glyph & Cog, LLC
//
diff --git a/noncore/unsupported/qpdf/xpdf/Lexer.h b/noncore/unsupported/qpdf/xpdf/Lexer.h
index 5edbeda..8a01ab2 100644
--- a/noncore/unsupported/qpdf/xpdf/Lexer.h
+++ b/noncore/unsupported/qpdf/xpdf/Lexer.h
@@ -4,3 +4,3 @@
//
-// Copyright 1996 Derek B. Noonburg
+// Copyright 1996-2002 Glyph & Cog, LLC
//
@@ -53,9 +53,10 @@ public:
- // Get current position in file.
+ // Get current position in file. This is only used for error
+ // messages, so it returns an int instead of a Guint.
int getPos()
- { return curStr.isNone() ? -1 : curStr.streamGetPos(); }
+ { return curStr.isNone() ? -1 : (int)curStr.streamGetPos(); }
// Set position in file.
- void setPos(int pos)
- { if (!curStr.isNone()) curStr.streamSetPos(pos); }
+ void setPos(Guint pos, int dir = 0)
+ { if (!curStr.isNone()) curStr.streamSetPos(pos, dir); }
diff --git a/noncore/unsupported/qpdf/xpdf/Link.cc b/noncore/unsupported/qpdf/xpdf/Link.cc
index 79a5f6e..c25ec43 100644
--- a/noncore/unsupported/qpdf/xpdf/Link.cc
+++ b/noncore/unsupported/qpdf/xpdf/Link.cc
@@ -4,3 +4,3 @@
//
-// Copyright 1996 Derek B. Noonburg
+// Copyright 1996-2002 Glyph & Cog, LLC
//
@@ -31,3 +31,3 @@ static GString *getFileSpecName(Object *fileSpecObj);
-LinkDest::LinkDest(Array *a, GBool pageIsRefA) {
+LinkDest::LinkDest(Array *a) {
Object obj1, obj2;
@@ -35,3 +35,2 @@ LinkDest::LinkDest(Array *a, GBool pageIsRefA) {
// initialize fields
- pageIsRef = pageIsRefA;
left = bottom = right = top = zoom = 0;
@@ -40,18 +39,15 @@ LinkDest::LinkDest(Array *a, GBool pageIsRefA) {
// get page
- if (pageIsRef) {
- if (!a->getNF(0, &obj1)->isRef()) {
- error(-1, "Bad annotation destination");
- goto err2;
- }
+ a->getNF(0, &obj1);
+ if (obj1.isInt()) {
+ pageNum = obj1.getInt() + 1;
+ pageIsRef = gFalse;
+ } else if (obj1.isRef()) {
pageRef.num = obj1.getRefNum();
pageRef.gen = obj1.getRefGen();
- obj1.free();
+ pageIsRef = gTrue;
} else {
- if (!a->get(0, &obj1)->isInt()) {
- error(-1, "Bad annotation destination");
- goto err2;
- }
- pageNum = obj1.getInt() + 1;
- obj1.free();
+ error(-1, "Bad annotation destination");
+ goto err2;
}
+ obj1.free();
@@ -223,3 +219,3 @@ LinkGoTo::LinkGoTo(Object *destObj) {
} else if (destObj->isArray()) {
- dest = new LinkDest(destObj->getArray(), gTrue);
+ dest = new LinkDest(destObj->getArray());
if (!dest->isOk()) {
@@ -261,3 +257,3 @@ LinkGoToR::LinkGoToR(Object *fileSpecObj, Object *destObj) {
} else if (destObj->isArray()) {
- dest = new LinkDest(destObj->getArray(), gFalse);
+ dest = new LinkDest(destObj->getArray());
if (!dest->isOk()) {
@@ -448,3 +444,3 @@ Link::Link(Dict *dict, GString *baseURI) {
// get border
- borderW = 0;
+ borderW = 1;
if (!dict->lookup("Border", &obj1)->isNull()) {
@@ -584,3 +580,3 @@ LinkAction *Links::find(fouble x, fouble y) {
- for (i = 0; i < numLinks; ++i) {
+ for (i = numLinks - 1; i >= 0; --i) {
if (links[i]->inRect(x, y)) {
diff --git a/noncore/unsupported/qpdf/xpdf/Link.h b/noncore/unsupported/qpdf/xpdf/Link.h
index 0ad4581..7b5ba86 100644
--- a/noncore/unsupported/qpdf/xpdf/Link.h
+++ b/noncore/unsupported/qpdf/xpdf/Link.h
@@ -4,3 +4,3 @@
//
-// Copyright 1996 Derek B. Noonburg
+// Copyright 1996-2002 Glyph & Cog, LLC
//
@@ -65,6 +65,4 @@ public:
- // Build a LinkDest from the array. If <pageIsRef> is true, the
- // page is specified by an object reference; otherwise the page is
- // specified by a (zero-relative) page number.
- LinkDest(Array *a, GBool pageIsRef1);
+ // Build a LinkDest from the array.
+ LinkDest(Array *a);
diff --git a/noncore/unsupported/qpdf/xpdf/NameToCharCode.cc b/noncore/unsupported/qpdf/xpdf/NameToCharCode.cc
index 06be2f4..b9cde77 100644
--- a/noncore/unsupported/qpdf/xpdf/NameToCharCode.cc
+++ b/noncore/unsupported/qpdf/xpdf/NameToCharCode.cc
@@ -4,3 +4,3 @@
//
-// Copyright 2001 Derek B. Noonburg
+// Copyright 2001-2002 Glyph & Cog, LLC
//
diff --git a/noncore/unsupported/qpdf/xpdf/NameToCharCode.h b/noncore/unsupported/qpdf/xpdf/NameToCharCode.h
index 9f9b1c3..22e41b6 100644
--- a/noncore/unsupported/qpdf/xpdf/NameToCharCode.h
+++ b/noncore/unsupported/qpdf/xpdf/NameToCharCode.h
@@ -4,3 +4,3 @@
//
-// Copyright 2001 Derek B. Noonburg
+// Copyright 2001-2002 Glyph & Cog, LLC
//
diff --git a/noncore/unsupported/qpdf/xpdf/NameToUnicodeTable.h b/noncore/unsupported/qpdf/xpdf/NameToUnicodeTable.h
index 7ca635e..432fafb 100644
--- a/noncore/unsupported/qpdf/xpdf/NameToUnicodeTable.h
+++ b/noncore/unsupported/qpdf/xpdf/NameToUnicodeTable.h
@@ -4,3 +4,3 @@
//
-// Copyright 2001 Derek B. Noonburg
+// Copyright 2001-2002 Glyph & Cog, LLC
//
diff --git a/noncore/unsupported/qpdf/xpdf/Object.cc b/noncore/unsupported/qpdf/xpdf/Object.cc
index 5ecade3..6d92c6a 100644
--- a/noncore/unsupported/qpdf/xpdf/Object.cc
+++ b/noncore/unsupported/qpdf/xpdf/Object.cc
@@ -4,3 +4,3 @@
//
-// Copyright 1996 Derek B. Noonburg
+// Copyright 1996-2002 Glyph & Cog, LLC
//
diff --git a/noncore/unsupported/qpdf/xpdf/Object.h b/noncore/unsupported/qpdf/xpdf/Object.h
index 000ffa0..7a67a7d 100644
--- a/noncore/unsupported/qpdf/xpdf/Object.h
+++ b/noncore/unsupported/qpdf/xpdf/Object.h
@@ -4,3 +4,3 @@
//
-// Copyright 1996 Derek B. Noonburg
+// Copyright 1996-2002 Glyph & Cog, LLC
//
@@ -178,4 +178,4 @@ public:
char *streamGetLine(char *buf, int size);
- int streamGetPos();
- void streamSetPos(int pos);
+ Guint streamGetPos();
+ void streamSetPos(Guint pos, int dir = 0);
Dict *streamGetDict();
@@ -289,7 +289,7 @@ inline char *Object::streamGetLine(char *buf, int size)
-inline int Object::streamGetPos()
+inline Guint Object::streamGetPos()
{ return stream->getPos(); }
-inline void Object::streamSetPos(int pos)
- { stream->setPos(pos); }
+inline void Object::streamSetPos(Guint pos, int dir)
+ { stream->setPos(pos, dir); }
diff --git a/noncore/unsupported/qpdf/xpdf/OutputDev.cc b/noncore/unsupported/qpdf/xpdf/OutputDev.cc
index 3c02835..1004f0f 100644
--- a/noncore/unsupported/qpdf/xpdf/OutputDev.cc
+++ b/noncore/unsupported/qpdf/xpdf/OutputDev.cc
@@ -4,3 +4,3 @@
//
-// Copyright 1996 Derek B. Noonburg
+// Copyright 1996-2002 Glyph & Cog, LLC
//
@@ -61,2 +61,7 @@ void OutputDev::updateAll(GfxState *state) {
+GBool OutputDev::beginType3Char(GfxState *state,
+ CharCode code, Unicode *u, int uLen) {
+ return gFalse;
+}
+
void OutputDev::drawImageMask(GfxState *state, Object *ref, Stream *str,
diff --git a/noncore/unsupported/qpdf/xpdf/OutputDev.h b/noncore/unsupported/qpdf/xpdf/OutputDev.h
index 04cbace..398c035 100644
--- a/noncore/unsupported/qpdf/xpdf/OutputDev.h
+++ b/noncore/unsupported/qpdf/xpdf/OutputDev.h
@@ -4,3 +4,3 @@
//
-// Copyright 1996 Derek B. Noonburg
+// Copyright 1996-2002 Glyph & Cog, LLC
//
@@ -48,2 +48,6 @@ public:
+ // Does this device use beginType3Char/endType3Char? Otherwise,
+ // text in Type 3 fonts will be drawn with drawChar/drawString.
+ virtual GBool interpretType3Chars() = 0;
+
// Does this device need non-text content?
@@ -121,2 +125,5 @@ public:
virtual void drawString(GfxState *state, GString *s) {}
+ virtual GBool beginType3Char(GfxState *state,
+ CharCode code, Unicode *u, int uLen);
+ virtual void endType3Char(GfxState *state) {}
@@ -136,2 +143,10 @@ public:
+ //----- Type 3 font operators
+ virtual void type3D0(GfxState *state, fouble wx, fouble wy) {}
+ virtual void type3D1(GfxState *state, fouble wx, fouble wy,
+ fouble llx, fouble lly, fouble urx, fouble ury) {}
+
+ //----- PostScript XObjects
+ virtual void psXObject(Stream *psStream, Stream *level1Stream) {}
+
private:
diff --git a/noncore/unsupported/qpdf/xpdf/PDFDoc.cc b/noncore/unsupported/qpdf/xpdf/PDFDoc.cc
index 4bbe9b7..97dfa55 100644
--- a/noncore/unsupported/qpdf/xpdf/PDFDoc.cc
+++ b/noncore/unsupported/qpdf/xpdf/PDFDoc.cc
@@ -4,3 +4,3 @@
//
-// Copyright 1996 Derek B. Noonburg
+// Copyright 1996-2002 Glyph & Cog, LLC
//
@@ -26,2 +26,3 @@
#include "Error.h"
+#include "ErrorCodes.h"
#include "Lexer.h"
@@ -45,2 +46,3 @@ PDFDoc::PDFDoc(GString *fileNameA, GString *ownerPassword,
ok = gFalse;
+ errCode = errNone;
@@ -59,2 +61,3 @@ PDFDoc::PDFDoc(GString *fileNameA, GString *ownerPassword,
error(-1, "Couldn't open file '%s'", fileName->getCString());
+ errCode = errOpenFile;
return;
@@ -70,2 +73,3 @@ PDFDoc::PDFDoc(GString *fileNameA, GString *ownerPassword,
delete fileName2;
+ errCode = errOpenFile;
return;
@@ -79,3 +83,3 @@ PDFDoc::PDFDoc(GString *fileNameA, GString *ownerPassword,
obj.initNull();
- str = new FileStream(file, 0, -1, &obj);
+ str = new FileStream(file, 0, gFalse, 0, &obj);
@@ -87,2 +91,3 @@ PDFDoc::PDFDoc(BaseStream *strA, GString *ownerPassword,
ok = gFalse;
+ errCode = errNone;
fileName = NULL;
@@ -105,2 +110,3 @@ GBool PDFDoc::setup(GString *ownerPassword, GString *userPassword) {
error(-1, "Couldn't read xref table");
+ errCode = xref->getErrorCode();
return gFalse;
@@ -112,2 +118,3 @@ GBool PDFDoc::setup(GString *ownerPassword, GString *userPassword) {
error(-1, "Couldn't read page catalog");
+ errCode = errBadCatalog;
return gFalse;
@@ -206,4 +213,5 @@ GBool PDFDoc::isLinearized() {
obj1.initNull();
- parser = new Parser(xref, new Lexer(xref, str->makeSubStream(str->getStart(),
- -1, &obj1)));
+ parser = new Parser(xref,
+ new Lexer(xref,
+ str->makeSubStream(str->getStart(), gFalse, 0, &obj1)));
parser->getObj(&obj1);
diff --git a/noncore/unsupported/qpdf/xpdf/PDFDoc.h b/noncore/unsupported/qpdf/xpdf/PDFDoc.h
index 592095e..3157683 100644
--- a/noncore/unsupported/qpdf/xpdf/PDFDoc.h
+++ b/noncore/unsupported/qpdf/xpdf/PDFDoc.h
@@ -4,3 +4,3 @@
//
-// Copyright 1996 Derek B. Noonburg
+// Copyright 1996-2002 Glyph & Cog, LLC
//
@@ -44,2 +44,5 @@ public:
+ // Get the error code (if isOk() returns false).
+ int getErrorCode() { return errCode; }
+
// Get file name.
@@ -139,2 +142,3 @@ private:
GBool ok;
+ int errCode;
};
diff --git a/noncore/unsupported/qpdf/xpdf/PSTokenizer.cc b/noncore/unsupported/qpdf/xpdf/PSTokenizer.cc
new file mode 100644
index 0000000..8d654bd
--- a/dev/null
+++ b/noncore/unsupported/qpdf/xpdf/PSTokenizer.cc
@@ -0,0 +1,133 @@
+//========================================================================
+//
+// PSTokenizer.cc
+//
+// Copyright 2002 Glyph & Cog, LLC
+//
+//========================================================================
+
+#ifdef __GNUC__
+#pragma implementation
+#endif
+
+#include <stdio.h>
+#include <stdlib.h>
+#include "PSTokenizer.h"
+
+//------------------------------------------------------------------------
+
+// A '1' in this array means the character is white space. A '1' or
+// '2' means the character ends a name or command.
+static char specialChars[256] = {
+ 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 1, 1, 0, 0, // 0x
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 1x
+ 1, 0, 0, 0, 0, 2, 0, 0, 2, 2, 0, 0, 0, 0, 0, 2, // 2x
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 2, 0, // 3x
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 4x
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 2, 0, 0, // 5x
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 6x
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 2, 0, 0, // 7x
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 8x
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 9x
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // ax
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // bx
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // cx
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // dx
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // ex
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 // fx
+};
+
+//------------------------------------------------------------------------
+
+PSTokenizer::PSTokenizer(int (*getCharFuncA)(void *), void *dataA) {
+ getCharFunc = getCharFuncA;
+ data = dataA;
+ charBuf = -1;
+}
+
+PSTokenizer::~PSTokenizer() {
+}
+
+GBool PSTokenizer::getToken(char *buf, int size, int *length) {
+ GBool comment, backslash;
+ int c;
+ int i;
+
+ // skip whitespace and comments
+ comment = gFalse;
+ while (1) {
+ if ((c = getChar()) == EOF) {
+ buf[0] = '\0';
+ *length = 0;
+ return gFalse;
+ }
+ if (comment) {
+ if (c == '\x0a' || c == '\x0d') {
+ comment = gFalse;
+ }
+ } else if (c == '%') {
+ comment = gTrue;
+ } else if (specialChars[c] != 1) {
+ break;
+ }
+ }
+
+ // read a token
+ i = 0;
+ buf[i++] = c;
+ if (c == '(') {
+ backslash = gFalse;
+ while ((c = lookChar()) != EOF) {
+ if (i < size - 1) {
+ buf[i++] = c;
+ }
+ getChar();
+ if (c == '\\') {
+ backslash = gTrue;
+ } else if (!backslash && c == ')') {
+ break;
+ } else {
+ backslash = gFalse;
+ }
+ }
+ } else if (c == '<') {
+ while ((c = lookChar()) != EOF) {
+ getChar();
+ if (i < size - 1) {
+ buf[i++] = c;
+ }
+ if (c == '>') {
+ break;
+ }
+ }
+ } else if (c != '[' && c != ']') {
+ while ((c = lookChar()) != EOF && !specialChars[c]) {
+ getChar();
+ if (i < size - 1) {
+ buf[i++] = c;
+ }
+ }
+ }
+ buf[i] = '\0';
+ *length = i;
+
+ return gTrue;
+}
+
+int PSTokenizer::lookChar() {
+ if (charBuf < 0) {
+ charBuf = (*getCharFunc)(data);
+ }
+ return charBuf;
+}
+
+int PSTokenizer::getChar() {
+ int c;
+
+ if (charBuf < 0) {
+ charBuf = (*getCharFunc)(data);
+ }
+ c = charBuf;
+ charBuf = -1;
+ return c;
+}
diff --git a/noncore/unsupported/qpdf/xpdf/PSTokenizer.h b/noncore/unsupported/qpdf/xpdf/PSTokenizer.h
new file mode 100644
index 0000000..1053c67
--- a/dev/null
+++ b/noncore/unsupported/qpdf/xpdf/PSTokenizer.h
@@ -0,0 +1,39 @@
+//========================================================================
+//
+// PSTokenizer.h
+//
+// Copyright 2002 Glyph & Cog, LLC
+//
+//========================================================================
+
+#ifndef PSTOKENIZER_H
+#define PSTOKENIZER_H
+
+#ifdef __GNUC__
+#pragma interface
+#endif
+
+#include "gtypes.h"
+
+//------------------------------------------------------------------------
+
+class PSTokenizer {
+public:
+
+ PSTokenizer(int (*getCharFuncA)(void *), void *dataA);
+ ~PSTokenizer();
+
+ // Get the next PostScript token. Returns false at end-of-stream.
+ GBool getToken(char *buf, int size, int *length);
+
+private:
+
+ int lookChar();
+ int getChar();
+
+ int (*getCharFunc)(void *);
+ void *data;
+ int charBuf;
+};
+
+#endif
diff --git a/noncore/unsupported/qpdf/xpdf/Page.cc b/noncore/unsupported/qpdf/xpdf/Page.cc
index 17c4481..9cc08c4 100644
--- a/noncore/unsupported/qpdf/xpdf/Page.cc
+++ b/noncore/unsupported/qpdf/xpdf/Page.cc
@@ -4,3 +4,3 @@
//
-// Copyright 1996 Derek B. Noonburg
+// Copyright 1996-2002 Glyph & Cog, LLC
//
@@ -22,3 +22,3 @@
#include "Gfx.h"
-#include "FormWidget.h"
+#include "Annot.h"
#endif
@@ -95,2 +95,10 @@ PageAttrs::PageAttrs(PageAttrs *attrs, Dict *dict) {
+ // misc attributes
+ dict->lookup("LastModified", &lastModified);
+ dict->lookup("BoxColorInfo", &boxColorInfo);
+ dict->lookup("Group", &group);
+ dict->lookup("Metadata", &metadata);
+ dict->lookup("PieceInfo", &pieceInfo);
+ dict->lookup("SeparationInfo", &separationInfo);
+
// resource dictionary
@@ -105,2 +113,8 @@ PageAttrs::PageAttrs(PageAttrs *attrs, Dict *dict) {
PageAttrs::~PageAttrs() {
+ lastModified.free();
+ boxColorInfo.free();
+ group.free();
+ metadata.free();
+ pieceInfo.free();
+ separationInfo.free();
resources.free();
@@ -211,3 +225,3 @@ void Page::display(OutputDev *out, fouble dpi, int rotate,
int i;
- FormWidgets *formWidgets;
+ Annots *annotList;
@@ -249,16 +263,16 @@ void Page::display(OutputDev *out, fouble dpi, int rotate,
- // draw AcroForm widgets
+ // draw non-link annotations
//~ need to reset CTM ???
- formWidgets = new FormWidgets(xref, annots.fetch(xref, &obj));
+ annotList = new Annots(xref, annots.fetch(xref, &obj));
obj.free();
- if (printCommands && formWidgets->getNumWidgets() > 0) {
- printf("***** AcroForm widgets\n");
- }
- for (i = 0; i < formWidgets->getNumWidgets(); ++i) {
- formWidgets->getWidget(i)->draw(gfx);
- }
- if (formWidgets->getNumWidgets() > 0) {
+ if (annotList->getNumAnnots() > 0) {
+ if (printCommands) {
+ printf("***** Annotations\n");
+ }
+ for (i = 0; i < annotList->getNumAnnots(); ++i) {
+ annotList->getAnnot(i)->draw(gfx);
+ }
out->dump();
}
- delete formWidgets;
+ delete annotList;
diff --git a/noncore/unsupported/qpdf/xpdf/Page.h b/noncore/unsupported/qpdf/xpdf/Page.h
index 203878f..57e802a 100644
--- a/noncore/unsupported/qpdf/xpdf/Page.h
+++ b/noncore/unsupported/qpdf/xpdf/Page.h
@@ -4,3 +4,3 @@
//
-// Copyright 1996 Derek B. Noonburg
+// Copyright 1996-2002 Glyph & Cog, LLC
//
@@ -53,2 +53,16 @@ public:
int getRotate() { return rotate; }
+ GString *getLastModified()
+ { return lastModified.isString()
+ ? lastModified.getString() : (GString *)NULL; }
+ Dict *getBoxColorInfo()
+ { return boxColorInfo.isDict() ? boxColorInfo.getDict() : (Dict *)NULL; }
+ Dict *getGroup()
+ { return group.isDict() ? group.getDict() : (Dict *)NULL; }
+ Stream *getMetadata()
+ { return metadata.isStream() ? metadata.getStream() : (Stream *)NULL; }
+ Dict *getPieceInfo()
+ { return pieceInfo.isDict() ? pieceInfo.getDict() : (Dict *)NULL; }
+ Dict *getSeparationInfo()
+ { return separationInfo.isDict()
+ ? separationInfo.getDict() : (Dict *)NULL; }
Dict *getResourceDict()
@@ -68,2 +82,8 @@ private:
int rotate;
+ Object lastModified;
+ Object boxColorInfo;
+ Object group;
+ Object metadata;
+ Object pieceInfo;
+ Object separationInfo;
Object resources;
@@ -99,2 +119,8 @@ public:
int getRotate() { return attrs->getRotate(); }
+ GString *getLastModified() { return attrs->getLastModified(); }
+ Dict *getBoxColorInfo() { return attrs->getBoxColorInfo(); }
+ Dict *getGroup() { return attrs->getGroup(); }
+ Stream *getMetadata() { return attrs->getMetadata(); }
+ Dict *getPieceInfo() { return attrs->getPieceInfo(); }
+ Dict *getSeparationInfo() { return attrs->getSeparationInfo(); }
diff --git a/noncore/unsupported/qpdf/xpdf/Parser.cc b/noncore/unsupported/qpdf/xpdf/Parser.cc
index a98753d..4df53c9 100644
--- a/noncore/unsupported/qpdf/xpdf/Parser.cc
+++ b/noncore/unsupported/qpdf/xpdf/Parser.cc
@@ -4,3 +4,3 @@
//
-// Copyright 1996 Derek B. Noonburg
+// Copyright 1996-2002 Glyph & Cog, LLC
//
@@ -157,3 +157,3 @@ Stream *Parser::makeStream(Object *dict) {
Stream *str;
- int pos, endPos, length;
+ Guint pos, endPos, length;
@@ -166,3 +166,3 @@ Stream *Parser::makeStream(Object *dict) {
if (obj.isInt()) {
- length = obj.getInt();
+ length = (Guint)obj.getInt();
obj.free();
@@ -175,3 +175,3 @@ Stream *Parser::makeStream(Object *dict) {
// check for length in damaged file
- if ((endPos = xref->getStreamEnd(pos)) >= 0) {
+ if (xref->getStreamEnd(pos, &endPos)) {
length = endPos - pos;
@@ -180,3 +180,4 @@ Stream *Parser::makeStream(Object *dict) {
// make base stream
- str = lexer->getStream()->getBaseStream()->makeSubStream(pos, length, dict);
+ str = lexer->getStream()->getBaseStream()->makeSubStream(pos, gTrue,
+ length, dict);
diff --git a/noncore/unsupported/qpdf/xpdf/Parser.h b/noncore/unsupported/qpdf/xpdf/Parser.h
index 463d998..c11475b 100644
--- a/noncore/unsupported/qpdf/xpdf/Parser.h
+++ b/noncore/unsupported/qpdf/xpdf/Parser.h
@@ -4,3 +4,3 @@
//
-// Copyright 1996 Derek B. Noonburg
+// Copyright 1996-2002 Glyph & Cog, LLC
//
diff --git a/noncore/unsupported/qpdf/xpdf/Stream-CCITT.h b/noncore/unsupported/qpdf/xpdf/Stream-CCITT.h
index 1af8742..f5a77b0 100644
--- a/noncore/unsupported/qpdf/xpdf/Stream-CCITT.h
+++ b/noncore/unsupported/qpdf/xpdf/Stream-CCITT.h
@@ -6,3 +6,3 @@
//
-// Copyright 1996 Derek B. Noonburg
+// Copyright 1996-2002 Glyph & Cog, LLC
//
diff --git a/noncore/unsupported/qpdf/xpdf/Stream.cc b/noncore/unsupported/qpdf/xpdf/Stream.cc
index 18490d4..c558478 100644
--- a/noncore/unsupported/qpdf/xpdf/Stream.cc
+++ b/noncore/unsupported/qpdf/xpdf/Stream.cc
@@ -4,3 +4,3 @@
//
-// Copyright 1996 Derek B. Noonburg
+// Copyright 1996-2002 Glyph & Cog, LLC
//
@@ -305,3 +305,3 @@ void FilterStream::close() {
-void FilterStream::setPos(int pos) {
+void FilterStream::setPos(Guint pos, int dir) {
error(-1, "Internal: called setPos() on FilterStream");
@@ -556,3 +556,4 @@ GBool StreamPredictor::getNextLine() {
-FileStream::FileStream(FILE *fA, int startA, int lengthA, Object *dictA):
+FileStream::FileStream(FILE *fA, Guint startA, GBool limitedA,
+ Guint lengthA, Object *dictA):
BaseStream(dictA) {
@@ -560,2 +561,3 @@ FileStream::FileStream(FILE *fA, int startA, int lengthA, Object *dictA):
start = startA;
+ limited = limitedA;
length = lengthA;
@@ -563,3 +565,4 @@ FileStream::FileStream(FILE *fA, int startA, int lengthA, Object *dictA):
bufPos = start;
- savePos = -1;
+ savePos = 0;
+ saved = gFalse;
}
@@ -570,4 +573,5 @@ FileStream::~FileStream() {
-Stream *FileStream::makeSubStream(int startA, int lengthA, Object *dictA) {
- return new FileStream(f, startA, lengthA, dictA);
+Stream *FileStream::makeSubStream(Guint startA, GBool limitedA,
+ Guint lengthA, Object *dictA) {
+ return new FileStream(f, startA, limitedA, lengthA, dictA);
}
@@ -575,4 +579,10 @@ Stream *FileStream::makeSubStream(int startA, int lengthA, Object *dictA) {
void FileStream::reset() {
- savePos = (int)ftell(f);
+#if HAVE_FSEEK64
+ savePos = (Guint)ftell64(f);
+ fseek64(f, start, SEEK_SET);
+#else
+ savePos = (Guint)ftell(f);
fseek(f, start, SEEK_SET);
+#endif
+ saved = gTrue;
bufPtr = bufEnd = buf;
@@ -586,5 +596,9 @@ void FileStream::reset() {
void FileStream::close() {
- if (savePos >= 0) {
+ if (saved) {
+#if HAVE_FSEEK64
+ fseek64(f, savePos, SEEK_SET);
+#else
fseek(f, savePos, SEEK_SET);
- savePos = -1;
+#endif
+ saved = gFalse;
}
@@ -600,6 +614,6 @@ GBool FileStream::fillBuf() {
bufPtr = bufEnd = buf;
- if (length >= 0 && bufPos >= start + length) {
+ if (limited && bufPos >= start + length) {
return gFalse;
}
- if (length >= 0 && bufPos + fileStreamBufSize > start + length) {
+ if (limited && bufPos + fileStreamBufSize > start + length) {
n = start + length - bufPos;
@@ -623,13 +637,22 @@ GBool FileStream::fillBuf() {
-void FileStream::setPos(int pos) {
- long size;
+void FileStream::setPos(Guint pos, int dir) {
+ Guint size;
- if (pos >= 0) {
+ if (dir >= 0) {
+#if HAVE_FSEEK64
+ fseek64(f, pos, SEEK_SET);
+#else
fseek(f, pos, SEEK_SET);
+#endif
bufPos = pos;
} else {
+#if HAVE_FSEEK64
+ fseek64(f, 0, SEEK_END);
+ size = (Guint)ftell64(f);
+#else
fseek(f, 0, SEEK_END);
- size = ftell(f);
- if (pos < -size)
- pos = (int)(-size);
+ size = (Guint)ftell(f);
+#endif
+ if (pos > size)
+ pos = (Guint)size;
#ifdef __CYGWIN32__
@@ -638,4 +661,9 @@ void FileStream::setPos(int pos) {
#endif
- fseek(f, pos, SEEK_END);
- bufPos = (int)ftell(f);
+#if HAVE_FSEEK64
+ fseek64(f, -(int)pos, SEEK_END);
+ bufPos = (Guint)ftell64(f);
+#else
+ fseek(f, -(int)pos, SEEK_END);
+ bufPos = (Guint)ftell(f);
+#endif
}
@@ -651,2 +679,86 @@ void FileStream::moveStart(int delta) {
//------------------------------------------------------------------------
+// MemStream
+//------------------------------------------------------------------------
+
+MemStream::MemStream(char *bufA, Guint lengthA, Object *dictA):
+ BaseStream(dictA) {
+ buf = bufA;
+ needFree = gFalse;
+ length = lengthA;
+ bufEnd = buf + length;
+ bufPtr = buf;
+}
+
+MemStream::~MemStream() {
+ if (needFree) {
+ gfree(buf);
+ }
+}
+
+Stream *MemStream::makeSubStream(Guint start, GBool limited,
+ Guint lengthA, Object *dictA) {
+ Guint newLength;
+
+ if (!limited || start + lengthA > length) {
+ newLength = length - start;
+ } else {
+ newLength = lengthA;
+ }
+ return new MemStream(buf + start, newLength, dictA);
+}
+
+void MemStream::reset() {
+ bufPtr = buf;
+#ifndef NO_DECRYPTION
+ if (decrypt) {
+ decrypt->reset();
+ }
+#endif
+}
+
+void MemStream::close() {
+}
+
+void MemStream::setPos(Guint pos, int dir) {
+ if (dir >= 0) {
+ if (pos > length) {
+ bufPtr = bufEnd;
+ } else {
+ bufPtr = buf + pos;
+ }
+ } else {
+ if (pos > length) {
+ bufPtr = buf;
+ } else {
+ bufPtr = bufEnd - pos;
+ }
+ }
+}
+
+void MemStream::moveStart(int delta) {
+ buf += delta;
+ bufPtr = buf;
+}
+
+#ifndef NO_DECRYPTION
+void MemStream::doDecryption(Guchar *fileKey, int keyLength,
+ int objNum, int objGen) {
+ char *newBuf;
+ char *p, *q;
+
+ this->BaseStream::doDecryption(fileKey, keyLength, objNum, objGen);
+ if (decrypt) {
+ newBuf = (char *)gmalloc(bufEnd - buf);
+ for (p = buf, q = newBuf; p < bufEnd; ++p, ++q) {
+ *q = (char)decrypt->decryptByte((Guchar)*p);
+ }
+ bufEnd = newBuf + (bufEnd - buf);
+ bufPtr = newBuf + (bufPtr - buf);
+ buf = newBuf;
+ needFree = gTrue;
+ }
+}
+#endif
+
+//------------------------------------------------------------------------
// EmbedStream
@@ -662,3 +774,4 @@ EmbedStream::~EmbedStream() {
-Stream *EmbedStream::makeSubStream(int start, int length, Object *dictA) {
+Stream *EmbedStream::makeSubStream(Guint start, GBool limited,
+ Guint length, Object *dictA) {
error(-1, "Internal: called makeSubStream() on EmbedStream");
@@ -667,3 +780,3 @@ Stream *EmbedStream::makeSubStream(int start, int length, Object *dictA) {
-void EmbedStream::setPos(int pos) {
+void EmbedStream::setPos(Guint pos, int dir) {
error(-1, "Internal: called setPos() on EmbedStream");
@@ -671,3 +784,3 @@ void EmbedStream::setPos(int pos) {
-int EmbedStream::getStart() {
+Guint EmbedStream::getStart() {
error(-1, "Internal: called getStart() on EmbedStream");
@@ -676,3 +789,3 @@ int EmbedStream::getStart() {
-void EmbedStream::moveStart(int start) {
+void EmbedStream::moveStart(int delta) {
error(-1, "Internal: called moveStart() on EmbedStream");
@@ -961,7 +1074,3 @@ void LZWStream::reset() {
#else // HAVE_POPEN
-#ifdef VMS
- if (!system(zCmd->getCString())) {
-#else
- if (system(zCmd->getCString())) {
-#endif
+ if (!executeCommand(zCmd->getCString())) {
error(getPos(), "Couldn't execute '%s'", zCmd->getCString());
@@ -3289,2 +3398,52 @@ int FixedLengthEncoder::lookChar() {
//------------------------------------------------------------------------
+// ASCIIHexEncoder
+//------------------------------------------------------------------------
+
+ASCIIHexEncoder::ASCIIHexEncoder(Stream *strA):
+ FilterStream(strA) {
+ bufPtr = bufEnd = buf;
+ lineLen = 0;
+ eof = gFalse;
+}
+
+ASCIIHexEncoder::~ASCIIHexEncoder() {
+ if (str->isEncoder()) {
+ delete str;
+ }
+}
+
+void ASCIIHexEncoder::reset() {
+ str->reset();
+ bufPtr = bufEnd = buf;
+ lineLen = 0;
+ eof = gFalse;
+}
+
+void ASCIIHexEncoder::close() {
+}
+
+GBool ASCIIHexEncoder::fillBuf() {
+ static char *hex = "0123456789abcdef";
+ int c;
+
+ if (eof) {
+ return gFalse;
+ }
+ bufPtr = bufEnd = buf;
+ if ((c = str->getChar()) == EOF) {
+ *bufEnd++ = '>';
+ eof = gTrue;
+ } else {
+ if (lineLen >= 64) {
+ *bufEnd++ = '\n';
+ lineLen = 0;
+ }
+ *bufEnd++ = hex[(c >> 4) & 0x0f];
+ *bufEnd++ = hex[c & 0x0f];
+ lineLen += 2;
+ }
+ return gTrue;
+}
+
+//------------------------------------------------------------------------
// ASCII85Encoder
diff --git a/noncore/unsupported/qpdf/xpdf/Stream.h b/noncore/unsupported/qpdf/xpdf/Stream.h
index 1f9c561..3319dcc 100644
--- a/noncore/unsupported/qpdf/xpdf/Stream.h
+++ b/noncore/unsupported/qpdf/xpdf/Stream.h
@@ -4,3 +4,3 @@
//
-// Copyright 1996 Derek B. Noonburg
+// Copyright 1996-2002 Glyph & Cog, LLC
//
@@ -80,4 +80,6 @@ public:
- // Go to a position in the stream.
- virtual void setPos(int pos) = 0;
+ // Go to a position in the stream. If <dir> is negative, the
+ // position is from the end of the file; otherwise the position is
+ // from the start of the file.
+ virtual void setPos(Guint pos, int dir = 0) = 0;
@@ -120,4 +122,5 @@ public:
virtual ~BaseStream();
- virtual Stream *makeSubStream(int start, int length, Object *dict) = 0;
- virtual void setPos(int pos) = 0;
+ virtual Stream *makeSubStream(Guint start, GBool limited,
+ Guint length, Object *dict) = 0;
+ virtual void setPos(Guint pos, int dir = 0) = 0;
virtual BaseStream *getBaseStream() { return this; }
@@ -126,3 +129,3 @@ public:
// Get/set position of first byte of stream within the file.
- virtual int getStart() = 0;
+ virtual Guint getStart() = 0;
virtual void moveStart(int delta) = 0;
@@ -131,3 +134,4 @@ public:
// Set decryption for this stream.
- void doDecryption(Guchar *fileKey, int keyLength, int objNum, int objGen);
+ virtual void doDecryption(Guchar *fileKey, int keyLength,
+ int objNum, int objGen);
#endif
@@ -158,3 +162,3 @@ public:
virtual int getPos() { return str->getPos(); }
- virtual void setPos(int pos);
+ virtual void setPos(Guint pos, int dir = 0);
virtual BaseStream *getBaseStream() { return str->getBaseStream(); }
@@ -244,5 +248,7 @@ public:
- FileStream(FILE *fA, int startA, int lengthA, Object *dictA);
+ FileStream(FILE *fA, Guint startA, GBool limitedA,
+ Guint lengthA, Object *dictA);
virtual ~FileStream();
- virtual Stream *makeSubStream(int startA, int lengthA, Object *dictA);
+ virtual Stream *makeSubStream(Guint startA, GBool limitedA,
+ Guint lengthA, Object *dictA);
virtual StreamKind getKind() { return strFile; }
@@ -255,5 +261,5 @@ public:
virtual int getPos() { return bufPos + (bufPtr - buf); }
- virtual void setPos(int pos);
+ virtual void setPos(Guint pos, int dir = 0);
virtual GBool isBinary(GBool last = gTrue) { return last; }
- virtual int getStart() { return start; }
+ virtual Guint getStart() { return start; }
virtual void moveStart(int delta);
@@ -265,4 +271,5 @@ private:
FILE *f;
- int start;
- int length;
+ Guint start;
+ GBool limited;
+ Guint length;
char buf[fileStreamBufSize];
@@ -270,4 +277,42 @@ private:
char *bufEnd;
- int bufPos;
+ Guint bufPos;
int savePos;
+ GBool saved;
+};
+
+//------------------------------------------------------------------------
+// MemStream
+//------------------------------------------------------------------------
+
+class MemStream: public BaseStream {
+public:
+
+ MemStream(char *bufA, Guint lengthA, Object *dictA);
+ virtual ~MemStream();
+ virtual Stream *makeSubStream(Guint start, GBool limited,
+ Guint lengthA, Object *dictA);
+ virtual StreamKind getKind() { return strWeird; }
+ virtual void reset();
+ virtual void close();
+ virtual int getChar()
+ { return (bufPtr < bufEnd) ? (*bufPtr++ & 0xff) : EOF; }
+ virtual int lookChar()
+ { return (bufPtr < bufEnd) ? (*bufPtr & 0xff) : EOF; }
+ virtual int getPos() { return bufPtr - buf; }
+ virtual void setPos(Guint pos, int dir = 0);
+ virtual GBool isBinary(GBool last = gTrue) { return last; }
+ virtual Guint getStart() { return 0; }
+ virtual void moveStart(int delta);
+#ifndef NO_DECRYPTION
+ virtual void doDecryption(Guchar *fileKey, int keyLength,
+ int objNum, int objGen);
+#endif
+
+private:
+
+ char *buf;
+ Guint length;
+ GBool needFree;
+ char *bufEnd;
+ char *bufPtr;
};
@@ -289,3 +334,4 @@ public:
virtual ~EmbedStream();
- virtual Stream *makeSubStream(int start, int length, Object *dictA);
+ virtual Stream *makeSubStream(Guint start, GBool limited,
+ Guint length, Object *dictA);
virtual StreamKind getKind() { return str->getKind(); }
@@ -295,5 +341,5 @@ public:
virtual int getPos() { return str->getPos(); }
- virtual void setPos(int pos);
+ virtual void setPos(Guint pos, int dir = 0);
virtual GBool isBinary(GBool last = gTrue) { return last; }
- virtual int getStart();
+ virtual Guint getStart();
virtual void moveStart(int delta);
@@ -661,2 +707,33 @@ private:
//------------------------------------------------------------------------
+// ASCIIHexEncoder
+//------------------------------------------------------------------------
+
+class ASCIIHexEncoder: public FilterStream {
+public:
+
+ ASCIIHexEncoder(Stream *strA);
+ virtual ~ASCIIHexEncoder();
+ virtual StreamKind getKind() { return strWeird; }
+ virtual void reset();
+ virtual void close();
+ virtual int getChar()
+ { return (bufPtr >= bufEnd && !fillBuf()) ? EOF : (*bufPtr++ & 0xff); }
+ virtual int lookChar()
+ { return (bufPtr >= bufEnd && !fillBuf()) ? EOF : (*bufPtr & 0xff); }
+ virtual GString *getPSFilter(char *indent) { return NULL; }
+ virtual GBool isBinary(GBool last = gTrue) { return gFalse; }
+ virtual GBool isEncoder() { return gTrue; }
+
+private:
+
+ char buf[4];
+ char *bufPtr;
+ char *bufEnd;
+ int lineLen;
+ GBool eof;
+
+ GBool fillBuf();
+};
+
+//------------------------------------------------------------------------
// ASCII85Encoder
diff --git a/noncore/unsupported/qpdf/xpdf/TextOutputDev.cc b/noncore/unsupported/qpdf/xpdf/TextOutputDev.cc
index aa9366a..d3b0137 100644
--- a/noncore/unsupported/qpdf/xpdf/TextOutputDev.cc
+++ b/noncore/unsupported/qpdf/xpdf/TextOutputDev.cc
@@ -4,3 +4,3 @@
//
-// Copyright 1997 Derek B. Noonburg
+// Copyright 1997-2002 Glyph & Cog, LLC
//
@@ -50,2 +50,8 @@ TextString::TextString(GfxState *state, fouble fontSize) {
}
+ if (yMin == yMax) {
+ // this is a sanity check for a case that shouldn't happen -- but
+ // if it does happen, we want to avoid dividing by zero later
+ yMin = y;
+ yMax = y + 1;
+ }
col = 0;
@@ -101,2 +107,3 @@ void TextPage::updateFont(GfxState *state) {
int code;
+ fouble w;
@@ -118,4 +125,7 @@ void TextPage::updateFont(GfxState *state) {
if (code < 256) {
- // 600 is a generic average 'm' width -- yes, this is a hack
- fontSize *= ((Gfx8BitFont *)font)->getWidth(code) / 0.6;
+ w = ((Gfx8BitFont *)font)->getWidth(code);
+ if (w != 0) {
+ // 600 is a generic average 'm' width -- yes, this is a hack
+ fontSize *= w / 0.6;
+ }
}
@@ -156,4 +166,6 @@ void TextPage::addChar(GfxState *state, fouble x, fouble y,
state->transformDelta(dx, dy, &w1, &h1);
- w1 /= uLen;
- h1 /= uLen;
+ if (uLen != 0) {
+ w1 /= uLen;
+ h1 /= uLen;
+ }
for (i = 0; i < uLen; ++i) {
@@ -431,3 +443,3 @@ GString *TextPage::getText(fouble xMin, fouble yMin,
-void TextPage::dump(FILE *f) {
+void TextPage::dump(void *outputStream, TextOutputFunc outputFunc) {
UnicodeMap *uMap;
@@ -500,5 +512,5 @@ void TextPage::dump(FILE *f) {
#if 0 //~ for debugging
- fprintf(f, "~~~~~~~~~~\n");
+ fprintf((FILE *)outputStream, "~~~~~~~~~~\n");
for (str1 = yxStrings; str1; str1 = str1->yxNext) {
- fprintf(f, "(%4d,%4d) - (%4d,%4d) [%3d] '",
+ fprintf((FILE *)outputStream, "(%4d,%4d) - (%4d,%4d) [%3d] '",
(int)str1->xMin, (int)str1->yMin,
@@ -510,3 +522,3 @@ void TextPage::dump(FILE *f) {
}
- fprintf(f, "~~~~~~~~~~\n");
+ fprintf((FILE *)outputStream, "~~~~~~~~~~\n");
#endif
@@ -523,3 +535,3 @@ void TextPage::dump(FILE *f) {
for (; col1 < str1->col; ++col1) {
- fwrite(space, 1, spaceLen, f);
+ (*outputFunc)(outputStream, space, spaceLen);
}
@@ -530,3 +542,3 @@ void TextPage::dump(FILE *f) {
if ((n = uMap->mapUnicode(str1->text[i], buf, sizeof(buf))) > 0) {
- fwrite(buf, 1, n, f);
+ (*outputFunc)(outputStream, buf, n);
}
@@ -549,3 +561,3 @@ void TextPage::dump(FILE *f) {
// print a return
- fwrite(eol, 1, eolLen, f);
+ (*outputFunc)(outputStream, eol, eolLen);
@@ -575,3 +587,3 @@ void TextPage::dump(FILE *f) {
for (; d > 0; --d) {
- fwrite(eol, 1, eolLen, f);
+ (*outputFunc)(outputStream, eol, eolLen);
}
@@ -586,5 +598,5 @@ void TextPage::dump(FILE *f) {
// end of page
- fwrite(eol, 1, eolLen, f);
- fwrite(eop, 1, eopLen, f);
- fwrite(eol, 1, eolLen, f);
+ (*outputFunc)(outputStream, eol, eolLen);
+ (*outputFunc)(outputStream, eop, eopLen);
+ (*outputFunc)(outputStream, eol, eolLen);
@@ -613,2 +625,6 @@ void TextPage::clear() {
+static void outputToFile(void *stream, char *text, int len) {
+ fwrite(text, 1, len, (FILE *)stream);
+}
+
TextOutputDev::TextOutputDev(char *fileName, GBool rawOrderA, GBool append) {
@@ -622,4 +638,4 @@ TextOutputDev::TextOutputDev(char *fileName, GBool rawOrderA, GBool append) {
if (!strcmp(fileName, "-")) {
- f = stdout;
- } else if ((f = fopen(fileName, append ? "a" : "w"))) {
+ outputStream = stdout;
+ } else if ((outputStream = fopen(fileName, append ? "ab" : "wb"))) {
needClose = gTrue;
@@ -630,4 +646,5 @@ TextOutputDev::TextOutputDev(char *fileName, GBool rawOrderA, GBool append) {
}
+ outputFunc = &outputToFile;
} else {
- f = NULL;
+ outputStream = NULL;
}
@@ -638,2 +655,12 @@ TextOutputDev::TextOutputDev(char *fileName, GBool rawOrderA, GBool append) {
+TextOutputDev::TextOutputDev(TextOutputFunc func, void *stream,
+ GBool rawOrderA) {
+ outputFunc = func;
+ outputStream = stream;
+ needClose = gFalse;
+ rawOrder = rawOrderA;
+ text = new TextPage(rawOrder);
+ ok = gTrue;
+}
+
TextOutputDev::~TextOutputDev() {
@@ -641,5 +668,5 @@ TextOutputDev::~TextOutputDev() {
#ifdef MACOS
- ICS_MapRefNumAndAssign((short)f->handle);
+ ICS_MapRefNumAndAssign((short)((FILE *)outputStream)->handle);
#endif
- fclose(f);
+ fclose((FILE *)outputStream);
}
@@ -656,4 +683,4 @@ void TextOutputDev::endPage() {
text->coalesce();
- if (f) {
- text->dump(f);
+ if (outputStream) {
+ text->dump(outputStream, outputFunc);
}
diff --git a/noncore/unsupported/qpdf/xpdf/TextOutputDev.h b/noncore/unsupported/qpdf/xpdf/TextOutputDev.h
index 4c71e5e..f0f238e 100644
--- a/noncore/unsupported/qpdf/xpdf/TextOutputDev.h
+++ b/noncore/unsupported/qpdf/xpdf/TextOutputDev.h
@@ -4,3 +4,3 @@
//
-// Copyright 1997 Derek B. Noonburg
+// Copyright 1997-2002 Glyph & Cog, LLC
//
@@ -24,2 +24,6 @@ class GString;
//------------------------------------------------------------------------
+
+typedef void (*TextOutputFunc)(void *stream, char *text, int len);
+
+//------------------------------------------------------------------------
// TextString
@@ -99,3 +103,3 @@ public:
// Dump contents of page to a file.
- void dump(FILE *f);
+ void dump(void *outputStream, TextOutputFunc outputFunc);
@@ -130,2 +134,6 @@ public:
+ // Create a TextOutputDev which will write to a generic stream. If
+ // <rawOrder> is true, the text is kept in content stream order.
+ TextOutputDev(TextOutputFunc func, void *stream, GBool rawOrderA);
+
// Destructor.
@@ -145,2 +153,6 @@ public:
+ // Does this device use beginType3Char/endType3Char? Otherwise,
+ // text in Type 3 fonts will be drawn with drawChar/drawString.
+ virtual GBool interpretType3Chars() { return gFalse; }
+
// Does this device need non-text content?
@@ -181,4 +193,6 @@ private:
- FILE *f; // text file
- GBool needClose; // need to close the file?
+ TextOutputFunc outputFunc; // output function
+ void *outputStream; // output stream
+ GBool needClose; // need to close the output file?
+ // (only if outputStream is a FILE*)
TextPage *text; // text for the current page
diff --git a/noncore/unsupported/qpdf/xpdf/UnicodeMap.cc b/noncore/unsupported/qpdf/xpdf/UnicodeMap.cc
index ab823b1..75f23d2 100644
--- a/noncore/unsupported/qpdf/xpdf/UnicodeMap.cc
+++ b/noncore/unsupported/qpdf/xpdf/UnicodeMap.cc
@@ -4,3 +4,3 @@
//
-// Copyright 2001 Derek B. Noonburg
+// Copyright 2001-2002 Glyph & Cog, LLC
//
diff --git a/noncore/unsupported/qpdf/xpdf/UnicodeMap.h b/noncore/unsupported/qpdf/xpdf/UnicodeMap.h
index 4d982c8..274c447 100644
--- a/noncore/unsupported/qpdf/xpdf/UnicodeMap.h
+++ b/noncore/unsupported/qpdf/xpdf/UnicodeMap.h
@@ -6,3 +6,3 @@
//
-// Copyright 2001 Derek B. Noonburg
+// Copyright 2001-2002 Glyph & Cog, LLC
//
diff --git a/noncore/unsupported/qpdf/xpdf/UnicodeMapTables.h b/noncore/unsupported/qpdf/xpdf/UnicodeMapTables.h
index 6fcd44e..51dee98 100644
--- a/noncore/unsupported/qpdf/xpdf/UnicodeMapTables.h
+++ b/noncore/unsupported/qpdf/xpdf/UnicodeMapTables.h
@@ -4,3 +4,3 @@
//
-// Copyright 2001 Derek B. Noonburg
+// Copyright 2001-2002 Glyph & Cog, LLC
//
@@ -15,2 +15,4 @@ static UnicodeMapRange latin1UnicodeMapRanges[] = {
{ 0x00ae, 0x00ff, 0xae, 1 },
+ { 0x010c, 0x010c, 0x43, 1 },
+ { 0x010d, 0x010d, 0x63, 1 },
{ 0x0131, 0x0131, 0x69, 1 },
@@ -43,2 +45,19 @@ static UnicodeMapRange latin1UnicodeMapRanges[] = {
{ 0x2212, 0x2212, 0x2d, 1 },
+ { 0xf6f9, 0xf6f9, 0x4c, 1 },
+ { 0xf6fa, 0xf6fa, 0x4f45, 2 },
+ { 0xf6fc, 0xf6fc, 0xb0, 1 },
+ { 0xf6fd, 0xf6fd, 0x53, 1 },
+ { 0xf6fe, 0xf6fe, 0x7e, 1 },
+ { 0xf6ff, 0xf6ff, 0x5a, 1 },
+ { 0xf721, 0xf721, 0x21, 1 },
+ { 0xf724, 0xf724, 0x24, 1 },
+ { 0xf726, 0xf726, 0x26, 1 },
+ { 0xf730, 0xf739, 0x30, 1 },
+ { 0xf73f, 0xf73f, 0x3f, 1 },
+ { 0xf761, 0xf77a, 0x41, 1 },
+ { 0xf7a1, 0xf7a2, 0xa1, 1 },
+ { 0xf7bf, 0xf7bf, 0xbf, 1 },
+ { 0xf7e0, 0xf7f6, 0xc0, 1 },
+ { 0xf7f8, 0xf7fe, 0xd8, 1 },
+ { 0xf7ff, 0xf7ff, 0x59, 1 },
{ 0xfb00, 0xfb00, 0x6666, 2 },
@@ -137,2 +156,41 @@ static UnicodeMapRange ascii7UnicodeMapRanges[] = {
{ 0x2212, 0x2212, 0x2d, 1 },
+ { 0xf6f9, 0xf6f9, 0x4c, 1 },
+ { 0xf6fa, 0xf6fa, 0x4f45, 2 },
+ { 0xf6fd, 0xf6fd, 0x53, 1 },
+ { 0xf6fe, 0xf6fe, 0x7e, 1 },
+ { 0xf6ff, 0xf6ff, 0x5a, 1 },
+ { 0xf721, 0xf721, 0x21, 1 },
+ { 0xf724, 0xf724, 0x24, 1 },
+ { 0xf726, 0xf726, 0x26, 1 },
+ { 0xf730, 0xf739, 0x30, 1 },
+ { 0xf73f, 0xf73f, 0x3f, 1 },
+ { 0xf761, 0xf77a, 0x41, 1 },
+ { 0xf7e0, 0xf7e0, 0x41, 1 },
+ { 0xf7e1, 0xf7e1, 0x41, 1 },
+ { 0xf7e2, 0xf7e2, 0x41, 1 },
+ { 0xf7e3, 0xf7e3, 0x41, 1 },
+ { 0xf7e4, 0xf7e4, 0x41, 1 },
+ { 0xf7e5, 0xf7e5, 0x41, 1 },
+ { 0xf7e6, 0xf7e6, 0x4145, 2 },
+ { 0xf7e7, 0xf7e7, 0x43, 1 },
+ { 0xf7e8, 0xf7e8, 0x45, 1 },
+ { 0xf7e9, 0xf7e9, 0x45, 1 },
+ { 0xf7ea, 0xf7ea, 0x45, 1 },
+ { 0xf7eb, 0xf7eb, 0x45, 1 },
+ { 0xf7ec, 0xf7ec, 0x49, 1 },
+ { 0xf7ed, 0xf7ed, 0x49, 1 },
+ { 0xf7ee, 0xf7ee, 0x49, 1 },
+ { 0xf7ef, 0xf7ef, 0x49, 1 },
+ { 0xf7f1, 0xf7f2, 0x4e, 1 },
+ { 0xf7f3, 0xf7f3, 0x4f, 1 },
+ { 0xf7f4, 0xf7f4, 0x4f, 1 },
+ { 0xf7f5, 0xf7f5, 0x4f, 1 },
+ { 0xf7f6, 0xf7f6, 0x4f, 1 },
+ { 0xf7f8, 0xf7f8, 0x4f, 1 },
+ { 0xf7f9, 0xf7f9, 0x55, 1 },
+ { 0xf7fa, 0xf7fa, 0x55, 1 },
+ { 0xf7fb, 0xf7fb, 0x55, 1 },
+ { 0xf7fc, 0xf7fc, 0x55, 1 },
+ { 0xf7fd, 0xf7fd, 0x59, 1 },
+ { 0xf7ff, 0xf7ff, 0x59, 1 },
{ 0xfb00, 0xfb00, 0x6666, 2 },
diff --git a/noncore/unsupported/qpdf/xpdf/XRef.cc b/noncore/unsupported/qpdf/xpdf/XRef.cc
index 5d526e9..0e1bbc9 100644
--- a/noncore/unsupported/qpdf/xpdf/XRef.cc
+++ b/noncore/unsupported/qpdf/xpdf/XRef.cc
@@ -4,3 +4,3 @@
//
-// Copyright 1996 Derek B. Noonburg
+// Copyright 1996-2002 Glyph & Cog, LLC
//
@@ -27,2 +27,3 @@
#include "Error.h"
+#include "ErrorCodes.h"
#include "XRef.h"
@@ -51,3 +52,3 @@
XRef::XRef(BaseStream *strA, GString *ownerPassword, GString *userPassword) {
- int pos;
+ Guint pos;
int i;
@@ -55,2 +56,3 @@ XRef::XRef(BaseStream *strA, GString *ownerPassword, GString *userPassword) {
ok = gTrue;
+ errCode = errNone;
size = 0;
@@ -69,2 +71,3 @@ XRef::XRef(BaseStream *strA, GString *ownerPassword, GString *userPassword) {
if (!(ok = constructXRef())) {
+ errCode = errDamaged;
return;
@@ -76,3 +79,3 @@ XRef::XRef(BaseStream *strA, GString *ownerPassword, GString *userPassword) {
for (i = 0; i < size; ++i) {
- entries[i].offset = -1;
+ entries[i].offset = 0xffffffff;
entries[i].used = gFalse;
@@ -88,2 +91,3 @@ XRef::XRef(BaseStream *strA, GString *ownerPassword, GString *userPassword) {
if (!(ok = constructXRef())) {
+ errCode = errDamaged;
return;
@@ -103,2 +107,3 @@ XRef::XRef(BaseStream *strA, GString *ownerPassword, GString *userPassword) {
ok = gFalse;
+ errCode = errEncrypted;
return;
@@ -117,3 +122,3 @@ XRef::~XRef() {
// first xref position.
-int XRef::readTrailer() {
+Guint XRef::readTrailer() {
Parser *parser;
@@ -121,3 +126,4 @@ int XRef::readTrailer() {
char buf[xrefSearchSize+1];
- int n, pos, pos1;
+ int n;
+ Guint pos, pos1;
char *p;
@@ -127,3 +133,3 @@ int XRef::readTrailer() {
// read last xrefSearchSize bytes
- str->setPos(-xrefSearchSize);
+ str->setPos(xrefSearchSize, -1);
for (n = 0; n < xrefSearchSize; ++n) {
@@ -143,3 +149,3 @@ int XRef::readTrailer() {
for (p = &buf[i+9]; isspace(*p); ++p) ;
- pos = lastXRefPos = atoi(p);
+ pos = lastXRefPos = strToUnsigned(p);
@@ -178,4 +184,5 @@ int XRef::readTrailer() {
obj.initNull();
- parser = new Parser(NULL, new Lexer(NULL, str->makeSubStream(start + pos1,
- -1, &obj)));
+ parser = new Parser(NULL,
+ new Lexer(NULL,
+ str->makeSubStream(start + pos1, gFalse, 0, &obj)));
parser->getObj(&trailerDict);
@@ -206,3 +213,3 @@ int XRef::readTrailer() {
// Read an xref table and the prev pointer from the trailer.
-GBool XRef::readXRef(int *pos) {
+GBool XRef::readXRef(Guint *pos) {
Parser *parser;
@@ -263,3 +270,3 @@ GBool XRef::readXRef(int *pos) {
for (i = size; i < newSize; ++i) {
- entries[i].offset = -1;
+ entries[i].offset = 0xffffffff;
entries[i].used = gFalse;
@@ -275,5 +282,5 @@ GBool XRef::readXRef(int *pos) {
}
- if (entries[i].offset < 0) {
+ if (entries[i].offset == 0xffffffff) {
s[10] = '\0';
- entries[i].offset = atoi(s);
+ entries[i].offset = strToUnsigned(s);
s[16] = '\0';
@@ -295,3 +302,3 @@ GBool XRef::readXRef(int *pos) {
entries[0] = entries[1];
- entries[1].offset = -1;
+ entries[1].offset = 0xffffffff;
}
@@ -303,4 +310,5 @@ GBool XRef::readXRef(int *pos) {
obj.initNull();
- parser = new Parser(NULL, new Lexer(NULL, str->makeSubStream(str->getPos(),
- -1, &obj)));
+ parser = new Parser(NULL,
+ new Lexer(NULL,
+ str->makeSubStream(str->getPos(), gFalse, 0, &obj)));
parser->getObj(&obj);
@@ -316,3 +324,3 @@ GBool XRef::readXRef(int *pos) {
if (obj2.isInt()) {
- *pos = obj2.getInt();
+ *pos = (Guint)obj2.getInt();
more = gTrue;
@@ -339,3 +347,3 @@ GBool XRef::constructXRef() {
char buf[256];
- int pos;
+ Guint pos;
int num, gen;
@@ -362,4 +370,5 @@ GBool XRef::constructXRef() {
obj.initNull();
- parser = new Parser(NULL, new Lexer(NULL,
- str->makeSubStream(start + pos + 7, -1, &obj)));
+ parser = new Parser(NULL,
+ new Lexer(NULL,
+ str->makeSubStream(start + pos + 7, gFalse, 0, &obj)));
if (!trailerDict.isNone())
@@ -405,3 +414,3 @@ GBool XRef::constructXRef() {
for (i = size; i < newSize; ++i) {
- entries[i].offset = -1;
+ entries[i].offset = 0xffffffff;
entries[i].used = gFalse;
@@ -423,3 +432,4 @@ GBool XRef::constructXRef() {
streamEndsSize += 64;
- streamEnds = (int *)grealloc(streamEnds, streamEndsSize * sizeof(int));
+ streamEnds = (Guint *)grealloc(streamEnds,
+ streamEndsSize * sizeof(int));
}
@@ -582,6 +592,7 @@ Object *XRef::fetch(int num, int gen, Object *obj) {
e = &entries[num];
- if (e->gen == gen && e->offset >= 0) {
+ if (e->gen == gen && e->offset != 0xffffffff) {
obj1.initNull();
- parser = new Parser(this, new Lexer(this,
- str->makeSubStream(start + e->offset, -1, &obj1)));
+ parser = new Parser(this,
+ new Lexer(this,
+ str->makeSubStream(start + e->offset, gFalse, 0, &obj1)));
parser->getObj(&obj1);
@@ -620,3 +631,3 @@ Object *XRef::getDocInfoNF(Object *obj) {
-int XRef::getStreamEnd(int streamStart) {
+GBool XRef::getStreamEnd(Guint streamStart, Guint *streamEnd) {
int a, b, m;
@@ -625,3 +636,3 @@ int XRef::getStreamEnd(int streamStart) {
streamStart > streamEnds[streamEndsLen - 1]) {
- return -1;
+ return gFalse;
}
@@ -639,3 +650,16 @@ int XRef::getStreamEnd(int streamStart) {
}
- return streamEnds[b];
+ *streamEnd = streamEnds[b];
+ return gTrue;
+}
+
+Guint XRef::strToUnsigned(char *s) {
+ Guint x;
+ char *p;
+ int i;
+
+ x = 0;
+ for (p = s, i = 0; *p && isdigit(*p) && i < 10; ++p, ++i) {
+ x = 10 * x + (*p - '0');
+ }
+ return x;
}
diff --git a/noncore/unsupported/qpdf/xpdf/XRef.h b/noncore/unsupported/qpdf/xpdf/XRef.h
index a44c495..7876fa6 100644
--- a/noncore/unsupported/qpdf/xpdf/XRef.h
+++ b/noncore/unsupported/qpdf/xpdf/XRef.h
@@ -4,3 +4,3 @@
//
-// Copyright 1996 Derek B. Noonburg
+// Copyright 1996-2002 Glyph & Cog, LLC
//
@@ -26,3 +26,3 @@ class Stream;
struct XRefEntry {
- int offset;
+ Guint offset;
int gen;
@@ -43,2 +43,5 @@ public:
+ // Get the error code (if isOk() returns false).
+ int getErrorCode() { return errCode; }
+
// Is the file encrypted?
@@ -70,3 +73,3 @@ public:
// Return the offset of the last xref table.
- int getLastXRefPos() { return lastXRefPos; }
+ Guint getLastXRefPos() { return lastXRefPos; }
@@ -77,4 +80,4 @@ public:
// Get end position for a stream in a damaged file.
- // Returns -1 if unknown or file is not damaged.
- int getStreamEnd(int streamStart);
+ // Returns false if unknown or file is not damaged.
+ GBool getStreamEnd(Guint streamStart, Guint *streamEnd);
@@ -83,3 +86,3 @@ private:
BaseStream *str; // input stream
- int start; // offset in file (to allow for garbage
+ Guint start; // offset in file (to allow for garbage
// at beginning of file)
@@ -89,5 +92,6 @@ private:
GBool ok; // true if xref table is valid
+ int errCode; // error code (if <ok> is false)
Object trailerDict; // trailer dictionary
- int lastXRefPos; // offset of last xref table
- int *streamEnds; // 'endstream' positions - only used in
+ Guint lastXRefPos; // offset of last xref table
+ Guint *streamEnds; // 'endstream' positions - only used in
// damaged files
@@ -104,6 +108,7 @@ private:
- int readTrailer();
- GBool readXRef(int *pos);
+ Guint readTrailer();
+ GBool readXRef(Guint *pos);
GBool constructXRef();
GBool checkEncrypted(GString *ownerPassword, GString *userPassword);
+ Guint strToUnsigned(char *s);
};