summaryrefslogtreecommitdiff
path: root/noncore/unsupported/qpdf
authorsandman <sandman>2002-05-23 23:51:52 (UTC)
committer sandman <sandman>2002-05-23 23:51:52 (UTC)
commit2f3bb7b07f833273d966d41813e68bfe8b9d8d76 (patch) (side-by-side diff)
tree00beb1bd9e7f4ba79e22334a0d258269b28f4564 /noncore/unsupported/qpdf
parent6e82b45dd416ceeba78765717b700e853c96a137 (diff)
downloadopie-2f3bb7b07f833273d966d41813e68bfe8b9d8d76.zip
opie-2f3bb7b07f833273d966d41813e68bfe8b9d8d76.tar.gz
opie-2f3bb7b07f833273d966d41813e68bfe8b9d8d76.tar.bz2
Port to xpdf 1.01
Diffstat (limited to 'noncore/unsupported/qpdf') (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
@@ -79,6 +79,13 @@ public:
// Does this device use drawChar() or drawString()?
virtual GBool useDrawChar() { return gTrue; }
+ // 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
// Start a page.
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
@@ -1,7 +1,7 @@
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
OutputDev which renders directly to a QPixmap via QPainter calls.
@@ -20,12 +20,19 @@ Changes in 20020408:
- Problems with type 3 fonts (not fully supported by XPDF) solved
- Heavy optimizations in the image rendering code
-Changed in 20020413:
+Changes in 20020413:
- Fixed crash in find routine
- Stylus selection reworked
- Cursor-key navigation added
- Various crashes related to recursive calling of XPDF fixed
+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
+
Changes to xpdf:
- xpdf calculates nearly everything with doubles. Since ARMs are not equipped
@@ -52,36 +59,20 @@ 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
old format.
- 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)
+
Have fun ;)
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
@@ -22,3 +22,17 @@ static int mapUTF8 ( Unicode u, char *buf, int bufSize )
else
return 0;
}
+
+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
@@ -16,12 +16,12 @@
#include <qpe/qpeapplication.h>
#include <qpe/resource.h>
#include <qpe/applnk.h>
-#include <qpe/fileselector.h>
#include <qpe/qcopenvelope_qws.h>
#include <qclipboard.h>
#include <qtoolbar.h>
+#include <qtoolbutton.h>
#include <qmenubar.h>
#include <qpopupmenu.h>
#include <qwidgetstack.h>
@@ -37,6 +37,12 @@
#include "qpdf.h"
+#ifdef QPDF_QPE_ONLY
+#include <qpe/fileselector.h>
+#else
+#include <opie/ofileselector.h>
+#endif
+
int main ( int argc, char **argv )
{
@@ -81,7 +87,12 @@ QPdfDlg::QPdfDlg ( ) : QMainWindow ( )
m_outdev = new QPEOutputDev ( m_stack );
connect ( m_outdev, SIGNAL( selectionChanged ( const QRect & )), this, SLOT( copyToClipboard ( const QRect & )));
+#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 ( )));
connect ( m_filesel, SIGNAL( fileSelected ( const DocLnk & )), this, SLOT( openFile ( const DocLnk & )));
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
@@ -5,12 +5,14 @@
#include <qmainwindow.h>
+#define QPDF_QPE_ONLY 1 // ofileselector does not work right currently
class QPEOutputDev;
class PDFDoc;
class DocLnk;
class FileSelector;
+class OFileSelector;
class QWidgetStack;
class QLineEdit;
@@ -68,7 +70,12 @@ protected:
private:
QWidgetStack *m_stack;
QPEOutputDev *m_outdev;
+
+#ifdef QPDF_QPE_ONLY
FileSelector *m_filesel;
+#else
+ OFileSelector *m_filesel;
+#endif
QToolBar *m_tb_menu, *m_tb_tool, *m_tb_find;
QLineEdit *m_findedit;
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
@@ -13,7 +13,7 @@ SOURCES = xpdf/Array.cc \
xpdf/Dict.cc \
xpdf/Error.cc \
xpdf/FontEncodingTables.cc \
- xpdf/FormWidget.cc \
+ xpdf/Annot.cc \
xpdf/Function.cc \
xpdf/Gfx.cc \
xpdf/GfxFont.cc \
@@ -27,6 +27,7 @@ SOURCES = xpdf/Array.cc \
xpdf/PDFDoc.cc \
xpdf/Page.cc \
xpdf/Parser.cc \
+ xpdf/PSTokenizer.cc \
xpdf/Stream.cc \
xpdf/TextOutputDev.cc \
xpdf/UnicodeMap.cc \
@@ -52,7 +53,7 @@ INCLUDEPATH += . \
../goo \
goo
-LIBS += -L $(OPIEDIR)/lib -lqpe
+LIBS += -L $(OPIEDIR)/lib -lqpe -lopie
DESTDIR = $(OPIEDIR)/bin
TARGET = qpdf
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
@@ -1,8 +1,8 @@
//========================================================================
//
-// FormWidget.cc
+// Annot.cc
//
-// Copyright 2000 Derek B. Noonburg
+// Copyright 2000-2002 Glyph & Cog, LLC
//
//========================================================================
@@ -14,13 +14,13 @@
#include "gmem.h"
#include "Object.h"
#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;
fouble t;
@@ -77,49 +77,48 @@ FormWidget::FormWidget(XRef *xrefA, Dict *dict) {
obj1.free();
}
-FormWidget::~FormWidget() {
+Annot::~Annot() {
appearance.free();
}
-void FormWidget::draw(Gfx *gfx) {
+void Annot::draw(Gfx *gfx) {
Object obj;
if (appearance.fetch(xref, &obj)->isStream()) {
- gfx->doWidgetForm(&obj, xMin, yMin, xMax, yMax);
+ gfx->doAnnot(&obj, xMin, yMin, xMax, yMax);
}
obj.free();
}
//------------------------------------------------------------------------
-// FormWidgets
+// Annots
//------------------------------------------------------------------------
-FormWidgets::FormWidgets(XRef *xref, Object *annots) {
- FormWidget *widget;
+Annots::Annots(XRef *xref, Object *annotsObj) {
+ Annot *annot;
Object obj1, obj2;
int size;
int i;
- 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);
if (obj2.isName("Widget") ||
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;
}
}
obj2.free();
@@ -129,11 +128,11 @@ 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
@@ -1,30 +1,32 @@
//========================================================================
//
-// FormWidget.h
+// Annot.h
//
-// Copyright 2000 Derek B. Noonburg
+// Copyright 2000-2002 Glyph & Cog, LLC
//
//========================================================================
-#ifndef FORMWIDGET_H
-#define FORMWIDGET_H
+#ifndef ANNOT_H
+#define ANNOT_H
#ifdef __GNUC__
#pragma interface
#endif
+#include <aconf.h>
+
class XRef;
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; }
void draw(Gfx *gfx);
@@ -37,31 +39,31 @@ private:
XRef *xref; // the xref table for this PDF file
Object appearance; // a reference to the Form XObject stream
// for the normal appearance
- fouble xMin, yMin, // widget rectangle
+ fouble xMin, yMin, // annotation rectangle
xMax, yMax;
GBool ok;
};
//------------------------------------------------------------------------
-// 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]; }
private:
- FormWidget **widgets;
- int nWidgets;
+ Annot **annots;
+ int nAnnots;
};
#endif
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
@@ -2,7 +2,7 @@
//
// Array.cc
//
-// 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
@@ -2,7 +2,7 @@
//
// Array.h
//
-// 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
@@ -2,7 +2,7 @@
//
// BuiltinFont.h
//
-// 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
@@ -2,7 +2,7 @@
//
// BuiltinFontTables.cc
//
-// 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
@@ -2,7 +2,7 @@
//
// BuiltinFontTables.h
//
-// 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
@@ -2,7 +2,7 @@
//
// CMap.cc
//
-// Copyright 2001 Derek B. Noonburg
+// Copyright 2001-2002 Glyph & Cog, LLC
//
//========================================================================
@@ -20,6 +20,7 @@
#include "GString.h"
#include "Error.h"
#include "GlobalParams.h"
+#include "PSTokenizer.h"
#include "CMap.h"
//------------------------------------------------------------------------
@@ -34,15 +35,20 @@ struct CMapVectorEntry {
//------------------------------------------------------------------------
+static int getCharFromFile(void *data) {
+ return fgetc((FILE *)data);
+}
+
+//------------------------------------------------------------------------
+
CMap *CMap::parse(CMapCache *cache, GString *collectionA,
GString *cMapNameA) {
FILE *f;
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;
if (!(f = globalParams->findCMapFile(collectionA, cMapNameA))) {
@@ -61,50 +67,64 @@ CMap *CMap::parse(CMapCache *cache, GString *collectionA,
cmap = new CMap(collectionA->copy(), cMapNameA->copy());
- 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] == '/') {
cmap->useCMap(cache, tok1 + 1);
}
+ 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;
fclose(f);
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
@@ -2,7 +2,7 @@
//
// CMap.h
//
-// 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
@@ -2,7 +2,7 @@
//
// Catalog.cc
//
-// Copyright 1996 Derek B. Noonburg
+// Copyright 1996-2002 Glyph & Cog, LLC
//
//========================================================================
@@ -146,7 +146,7 @@ GString *Catalog::readMetadata() {
}
dict = metadata.streamGetDict();
if (!dict->lookup("Subtype", &obj)->isName("XML")) {
- error(-1, "Unknown Metadata type: '%s'\n",
+ error(-1, "Unknown Metadata type: '%s'",
obj.isName() ? obj.getName() : "???");
}
obj.free();
@@ -265,10 +265,10 @@ LinkDest *Catalog::findDest(GString *name) {
// construct LinkDest
dest = NULL;
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
error(-1, "Bad named destination value");
obj2.free();
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
@@ -2,7 +2,7 @@
//
// Catalog.h
//
-// 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
@@ -2,7 +2,7 @@
//
// CharCodeToUnicode.cc
//
-// Copyright 2001 Derek B. Noonburg
+// Copyright 2001-2002 Glyph & Cog, LLC
//
//========================================================================
@@ -18,6 +18,7 @@
#include "GString.h"
#include "Error.h"
#include "GlobalParams.h"
+#include "PSTokenizer.h"
#include "CharCodeToUnicode.h"
//------------------------------------------------------------------------
@@ -32,6 +33,26 @@ 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) {
FILE *f;
Unicode *mapA;
@@ -75,47 +96,20 @@ CharCodeToUnicode *CharCodeToUnicode::make8BitToUnicode(Unicode *toUnicode) {
return new CharCodeToUnicode(NULL, toUnicode, 256, gTrue, NULL, 0);
}
-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) {
CharCodeToUnicode *ctu;
char *p;
ctu = new CharCodeToUnicode(NULL);
p = buf->getCString();
- ctu->parseCMap1((char *(*)(char *, int, void *))&getLineFromString,
- &p, nBits);
+ ctu->parseCMap1(&getCharFromString, &p, nBits);
return ctu;
}
-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;
CharCode oldLen, i;
CharCode code1, code2;
@@ -126,28 +120,40 @@ void CharCodeToUnicode::parseCMap1(char *(*getLineFunc)(char *, int, void *),
FILE *f;
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;
}
tok1[n1 - 1] = tok2[n2 - 1] = '\0';
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;
}
if (code1 >= mapLen) {
@@ -160,7 +166,7 @@ void CharCodeToUnicode::parseCMap1(char *(*getLineFunc)(char *, int, void *),
}
if (n2 == 6) {
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;
}
map[code1] = u;
@@ -177,31 +183,35 @@ void CharCodeToUnicode::parseCMap1(char *(*getLineFunc)(char *, int, void *),
strncpy(uHex, tok2 + 1 + j*4, 4);
uHex[4] = '\0';
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");
}
}
++sMapLen;
}
- } 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] == '>' &&
n2 == 2 + nDigits && tok2[0] == '<' && tok2[n2 - 1] == '>' &&
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;
}
tok1[n1 - 1] = tok2[n2 - 1] = tok3[n3 - 1] = '\0';
if (sscanf(tok1 + 1, "%x", &code1) != 1 ||
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;
}
if (code2 >= mapLen) {
@@ -214,7 +224,7 @@ void CharCodeToUnicode::parseCMap1(char *(*getLineFunc)(char *, int, void *),
}
if (n3 == 6) {
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;
}
for (; code1 <= code2; ++code1) {
@@ -234,34 +244,20 @@ void CharCodeToUnicode::parseCMap1(char *(*getLineFunc)(char *, int, void *),
strncpy(uHex, tok3 + 1 + j*4, 4);
uHex[4] = '\0';
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");
}
}
sMap[sMapLen].u[sMap[sMapLen].len - 1] += i;
++sMapLen;
}
}
- } 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;
}
CharCodeToUnicode::CharCodeToUnicode(GString *collectionA) {
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
@@ -4,7 +4,7 @@
//
// Mapping from character codes to Unicode.
//
-// Copyright 2001 Derek B. Noonburg
+// Copyright 2001-2002 Glyph & Cog, LLC
//
//========================================================================
@@ -50,8 +50,7 @@ public:
private:
- void parseCMap1(char *(*getLineFunc)(char *, int, void *),
- void *data, int nBits);
+ void parseCMap1(int (*getCharFunc)(void *), void *data, int nBits);
CharCodeToUnicode(GString *collectionA);
CharCodeToUnicode(GString *collectionA, Unicode *mapA,
CharCode mapLenA, GBool copyMap,
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
@@ -2,7 +2,7 @@
//
// CharTypes.h
//
-// 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
@@ -2,7 +2,7 @@
//
// Decrypt.cc
//
-// 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
@@ -2,7 +2,7 @@
//
// Decrypt.h
//
-// 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
@@ -2,7 +2,7 @@
//
// Dict.cc
//
-// 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
@@ -2,7 +2,7 @@
//
// Dict.h
//
-// 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
@@ -2,7 +2,7 @@
//
// DisplayFontTable.h
//
-// Copyright 2001 Derek B. Noonburg
+// Copyright 2001-2002 Glyph & Cog, LLC
//
//========================================================================
@@ -11,7 +11,7 @@ static struct {
char *xlfd;
char *encoding;
} displayFontTab[] = {
-#if _NO_USE_FOR_QPE
+#if 0
{"Courier", "-*-courier-medium-r-normal-*-%s-*-*-*-*-*-iso8859-1", "Latin1"},
{"Courier-Bold", "-*-courier-bold-r-normal-*-%s-*-*-*-*-*-iso8859-1", "Latin1"},
{"Courier-BoldOblique", "-*-courier-bold-o-normal-*-%s-*-*-*-*-*-iso8859-1", "Latin1"},
@@ -27,5 +27,5 @@ static struct {
{"Times-Roman", "-*-times-medium-r-normal-*-%s-*-*-*-*-*-iso8859-1", "Latin1"},
{"ZapfDingbats", "-*-zapfdingbats-medium-r-normal-*-%s-*-*-*-*-*-*-*", "ZapfDingbats"},
#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
@@ -2,7 +2,7 @@
//
// Error.cc
//
-// 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
@@ -2,7 +2,7 @@
//
// Error.h
//
-// 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
@@ -2,7 +2,7 @@
//
// FontEncodingTables.cc
//
-// 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
@@ -2,7 +2,7 @@
//
// FontEncodingTables.h
//
-// 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
@@ -2,7 +2,7 @@
//
// Function.cc
//
-// Copyright 2001 Derek B. Noonburg
+// Copyright 2001-2002 Glyph & Cog, LLC
//
//========================================================================
@@ -415,7 +415,6 @@ ExponentialFunction::ExponentialFunction(Object *funcObj, Dict *dict) {
int i;
ok = gFalse;
- hasN = gFalse;
//----- initialize the generic stuff
if (!init(dict)) {
@@ -425,6 +424,7 @@ ExponentialFunction::ExponentialFunction(Object *funcObj, Dict *dict) {
error(-1, "Exponential function with more than one input");
goto err1;
}
+ hasN = hasRange;
//----- default values
for (i = 0; i < funcMaxOutputs; ++i) {
@@ -436,6 +436,7 @@ ExponentialFunction::ExponentialFunction(Object *funcObj, Dict *dict) {
if (dict->lookup("C0", &obj1)->isArray()) {
if (!hasN) {
n = obj1.arrayGetLength();
+ hasN = gTrue;
} else if (obj1.arrayGetLength() != n) {
error(-1, "Function's C0 array is wrong length");
goto err2;
@@ -456,6 +457,7 @@ ExponentialFunction::ExponentialFunction(Object *funcObj, Dict *dict) {
if (dict->lookup("C1", &obj1)->isArray()) {
if (!hasN) {
n = obj1.arrayGetLength();
+ hasN = gTrue;
} else if (obj1.arrayGetLength() != n) {
error(-1, "Function's C1 array is wrong length");
goto err2;
@@ -480,6 +482,13 @@ ExponentialFunction::ExponentialFunction(Object *funcObj, Dict *dict) {
e = obj1.getNum();
obj1.free();
+ // 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;
return;
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
@@ -2,7 +2,7 @@
//
// Function.h
//
-// 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
@@ -2,7 +2,7 @@
//
// Gfx.cc
//
-// Copyright 1996 Derek B. Noonburg
+// Copyright 1996-2002 Glyph & Cog, LLC
//
//========================================================================
@@ -30,6 +30,11 @@
#include "Error.h"
#include "Gfx.h"
+// the MSVC math.h doesn't define this
+#ifndef M_PI
+#define M_PI 3.14159265358979323846
+#endif
+
//------------------------------------------------------------------------
// constants
//------------------------------------------------------------------------
@@ -40,6 +45,12 @@
// Max delta allowed in any color component for an axial shading fill.
#define axialColorDelta (1 / 256.0)
+// 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)
+
//------------------------------------------------------------------------
// Operator table
//------------------------------------------------------------------------
@@ -374,6 +385,7 @@ Gfx::Gfx(XRef *xrefA, OutputDev *outA, int pageNum, Dict *resDict, fouble dpi,
int i;
xref = xrefA;
+ subPage = gFalse;
printCommands = printCommandsA;
// start the resource stack
@@ -405,21 +417,54 @@ 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()) {
state = state->restore();
out->restoreState(state);
}
- out->endPage();
+ if (!subPage) {
+ out->endPage();
+ }
while (res) {
- resPtr = res->getNext();
- delete res;
- res = resPtr;
+ popResources();
}
- if (state)
+ if (state) {
delete state;
+ }
}
void Gfx::display(Object *obj, GBool topLevel) {
@@ -449,11 +494,11 @@ void Gfx::display(Object *obj, GBool topLevel) {
void Gfx::go(GBool topLevel) {
Object obj;
Object args[maxArgs];
- int numCmds, numArgs;
+ int numArgs;
int i;
// scan a sequence of objects
- numCmds = 0;
+ updateLevel = 0;
numArgs = 0;
parser->getObj(&obj);
while (!obj.isEOF()) {
@@ -476,9 +521,9 @@ void Gfx::go(GBool topLevel) {
numArgs = 0;
// periodically update display
- if (++numCmds == 200) {
+ if (++updateLevel >= 20000) {
out->dump();
- numCmds = 0;
+ updateLevel = 0;
}
// got an argument - save it
@@ -519,7 +564,7 @@ void Gfx::go(GBool topLevel) {
}
// update display
- if (topLevel && numCmds > 0) {
+ if (topLevel && updateLevel > 0) {
out->dump();
}
}
@@ -1138,7 +1183,7 @@ void Gfx::doPatternFill(GBool eoFill) {
fouble cxMin, cyMin, cxMax, cyMax;
int xi0, yi0, xi1, yi1, xi, yi;
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;
fouble xstep, ystep;
int i;
@@ -1189,15 +1234,6 @@ void Gfx::doPatternFill(GBool eoFill) {
m[4] = m1[4] * ictm[0] + m1[5] * ictm[2] + ictm[4];
m[5] = m1[4] * ictm[1] + m1[5] * ictm[3] + ictm[5];
- // 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
det = 1 / (m1[0] * m1[3] - m1[1] * m1[2]);
imb[0] = m1[3] * det;
@@ -1331,6 +1367,9 @@ void Gfx::opShFill(Object args[], int numArgs) {
case 2:
doAxialShFill((GfxAxialShading *)shading);
break;
+ case 3:
+ doRadialShFill((GfxRadialShading *)shading);
+ break;
}
// restore graphics state
@@ -1343,9 +1382,6 @@ void Gfx::opShFill(Object args[], int numArgs) {
void Gfx::doAxialShFill(GfxAxialShading *shading) {
fouble xMin, yMin, xMax, yMax;
fouble x0, y0, x1, y1;
- fouble det;
- fouble *ctm;
- fouble ictm[6];
fouble dx, dy, mul;
fouble tMin, tMax, t, tx, ty;
fouble s[4], sMin, sMax, tmp;
@@ -1357,54 +1393,8 @@ void Gfx::doAxialShFill(GfxAxialShading *shading) {
int nComps;
int i, j, k, kk;
- // 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);
// compute min and max t values, based on the four corners of the
// clip region bbox
@@ -1619,6 +1609,202 @@ 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() {
if (state->isPath() && clip != clipNone) {
state->clip();
@@ -1800,17 +1986,23 @@ void Gfx::opMoveSetShowText(Object args[], int numArgs) {
void Gfx::opShowSpaceText(Object args[], int numArgs) {
Array *a;
Object obj;
+ int wMode;
int i;
if (!state->getFont()) {
error(getPos(), "No font in show/space");
return;
}
+ wMode = state->getFont()->getWMode();
a = args[0].getArray();
for (i = 0; i < a->getLength(); ++i) {
a->get(i, &obj);
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());
} else if (obj.isString()) {
doShowText(obj.getString());
@@ -1823,31 +2015,33 @@ void Gfx::opShowSpaceText(Object args[], int numArgs) {
void Gfx::doShowText(GString *s) {
GfxFont *font;
+ int wMode;
fouble riseX, riseY;
CharCode code;
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;
if (fontChanged) {
out->updateFont(state);
fontChanged = gFalse;
}
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();
for (i = 0; i < 6; ++i) {
oldCTM[i] = mat[i];
@@ -1867,6 +2061,8 @@ void Gfx::doShowText(GString *s) {
newCTM[0] *= state->getHorizScaling();
newCTM[2] *= state->getHorizScaling();
state->textTransformDelta(0, state->getRise(), &riseX, &riseY);
+ curX = state->getCurX();
+ curY = state->getCurY();
oldParser = parser;
p = s->getCString();
len = s->getLength();
@@ -1874,21 +2070,6 @@ void Gfx::doShowText(GString *s) {
n = font->getNextChar(p, len, &code,
u, (int)(sizeof(u) / sizeof(Unicode)), &uLen,
&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();
if (n == 1 && *p == ' ') {
dx += state->getWordSpace();
@@ -1896,31 +2077,61 @@ void Gfx::doShowText(GString *s) {
dx *= state->getHorizScaling();
dy *= state->getFontSize();
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;
len -= n;
}
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();
len = s->getLength();
while (len > 0) {
n = font->getNextChar(p, len, &code,
u, (int)(sizeof(u) / sizeof(Unicode)), &uLen,
&dx, &dy, &originX, &originY);
- dx = dx * state->getFontSize() + state->getCharSpace();
- if (n == 1 && *p == ' ') {
- dx += state->getWordSpace();
+ 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);
originX *= state->getFontSize();
originY *= state->getFontSize();
@@ -1931,7 +2142,6 @@ void Gfx::doShowText(GString *s) {
p += n;
len -= n;
}
- out->endString(state);
} else {
dx = dy = 0;
@@ -1951,15 +2161,28 @@ void Gfx::doShowText(GString *s) {
p += n;
len -= n;
}
- 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);
out->drawString(state, s);
state->shift(tdx, tdy);
}
+
+ if (out->useDrawChar()) {
+ out->endString(state);
+ }
+
+ updateLevel += 10 * s->getLength();
}
//------------------------------------------------------------------------
@@ -1967,7 +2190,7 @@ void Gfx::doShowText(GString *s) {
//------------------------------------------------------------------------
void Gfx::opXObject(Object args[], int numArgs) {
- Object obj1, obj2, refObj;
+ Object obj1, obj2, obj3, refObj;
#if OPI_SUPPORT
Object opiDict;
#endif
@@ -1993,6 +2216,10 @@ void Gfx::opXObject(Object args[], int numArgs) {
refObj.free();
} else if (obj2.isName("Form")) {
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()) {
error(getPos(), "Unknown XObject subtype '%s'", obj2.getName());
} else {
@@ -2148,6 +2375,11 @@ void Gfx::doImage(Object *ref, Stream *str, GBool inlineImg) {
maskObj.free();
}
+ if ((i = width * height) > 1000) {
+ i = 1000;
+ }
+ updateLevel += i;
+
return;
err2:
@@ -2215,19 +2447,22 @@ void Gfx::doForm(Object *str) {
resObj.free();
}
-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;
Object matrixObj, bboxObj, resObj;
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;
// get stream dict
dict = str->streamGetDict();
- // get bounding box
+ // get the form bounding box
dict->lookup("BBox", &bboxObj);
if (!bboxObj.isArray()) {
bboxObj.free();
@@ -2241,7 +2476,7 @@ void Gfx::doWidgetForm(Object *str, fouble xMin, fouble yMin,
}
bboxObj.free();
- // get matrix
+ // get the form matrix
dict->lookup("Matrix", &matrixObj);
if (matrixObj.isArray()) {
for (i = 0; i < 6; ++i) {
@@ -2256,16 +2491,64 @@ void Gfx::doWidgetForm(Object *str, fouble xMin, fouble yMin,
}
matrixObj.free();
- // 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;
// get resources
dict->lookup("Resources", &resObj);
@@ -2281,11 +2564,10 @@ void Gfx::doWidgetForm(Object *str, fouble xMin, fouble yMin,
void Gfx::doForm1(Object *str, Dict *resDict, fouble *matrix, fouble *bbox) {
Parser *oldParser;
fouble oldBaseMatrix[6];
- GfxResources *resPtr;
int i;
// push new resources on stack
- res = new GfxResources(xref, resDict, res);
+ pushResources(resDict);
// save current graphics state
out->saveState(state);
@@ -2332,11 +2614,21 @@ void Gfx::doForm1(Object *str, Dict *resDict, fouble *matrix, fouble *bbox) {
out->restoreState(state);
// pop resource stack
+ popResources();
+
+ return;
+}
+
+void Gfx::pushResources(Dict *resDict) {
+ res = new GfxResources(xref, resDict, res);
+}
+
+void Gfx::popResources() {
+ GfxResources *resPtr;
+
resPtr = res->getNext();
delete res;
res = resPtr;
-
- return;
}
//------------------------------------------------------------------------
@@ -2378,19 +2670,24 @@ Stream *Gfx::buildImageStream() {
if (!obj.isName()) {
error(getPos(), "Inline image dictionary key must be a name object");
obj.free();
- parser->getObj(&obj);
} else {
key = copyString(obj.getName());
obj.free();
parser->getObj(&obj);
- if (obj.isEOF() || obj.isError())
+ if (obj.isEOF() || obj.isError()) {
+ gfree(key);
break;
+ }
dict.dictAdd(key, &obj);
}
parser->getObj(&obj);
}
- if (obj.isEOF())
+ if (obj.isEOF()) {
error(getPos(), "End of file in inline image");
+ obj.free();
+ dict.free();
+ return NULL;
+ }
obj.free();
// make stream
@@ -2413,11 +2710,13 @@ 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());
}
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
@@ -2,7 +2,7 @@
//
// Gfx.h
//
-// Copyright 1996 Derek B. Noonburg
+// Copyright 1996-2002 Glyph & Cog, LLC
//
//========================================================================
@@ -27,6 +27,7 @@ class GfxFont;
class GfxPattern;
class GfxShading;
class GfxAxialShading;
+class GfxRadialShading;
class GfxState;
class Gfx;
struct PDFRectangle;
@@ -97,21 +98,31 @@ public:
PDFRectangle *box, GBool crop, PDFRectangle *cropBox, int rotate,
GBool printCommandsA);
- // Destructor.
+ // Constructor for a sub-page object.
+ Gfx(XRef *xrefA, OutputDev *outA, Dict *resDict,
+ PDFRectangle *box, GBool crop, PDFRectangle *cropBox);
+
~Gfx();
// Interpret a stream or array of streams.
void display(Object *obj, GBool topLevel = gTrue);
- 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();
private:
XRef *xref; // the xref table for this PDF file
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;
GfxState *state; // current graphics state
GBool fontChanged; // set if font or text matrix has changed
@@ -179,6 +190,7 @@ private:
void doPatternFill(GBool eoFill);
void opShFill(Object args[], int numArgs);
void doAxialShFill(GfxAxialShading *shading);
+ void doRadialShFill(GfxRadialShading *shading);
void doEndPath();
// path clipping operators
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
@@ -2,7 +2,7 @@
//
// GfxFont.cc
//
-// Copyright 1996-2001 Derek B. Noonburg
+// Copyright 1996-2002 Glyph & Cog, LLC
//
//========================================================================
@@ -454,13 +454,24 @@ Gfx8BitFont::Gfx8BitFont(XRef *xref, char *tagA, Ref idA, GString *nameA,
}
obj1.free();
- // 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");
charProcs.free();
}
+ if (!fontDict->lookup("Resources", &resources)->isDict()) {
+ resources.free();
+ }
}
//----- build the font encoding -----
@@ -513,9 +524,11 @@ 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)) {
if (extFontFile) {
buf = readExtFontFile(&len);
@@ -524,12 +537,15 @@ Gfx8BitFont::Gfx8BitFont(XRef *xref, char *tagA, Ref idA, GString *nameA,
}
if (buf) {
#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);
}
if (fontFile->getName()) {
if (embFontName) {
@@ -569,6 +585,7 @@ Gfx8BitFont::Gfx8BitFont(XRef *xref, char *tagA, Ref idA, GString *nameA,
if (obj1.isDict()) {
obj1.dictLookup("Differences", &obj2);
if (obj2.isArray()) {
+ hasEncoding = gTrue;
code = 0;
for (i = 0; i < obj2.arrayGetLength(); ++i) {
obj2.arrayGet(i, &obj3);
@@ -636,8 +653,9 @@ 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()) {
for (code = 0; code < 256; ++code) {
if ((charName = enc[code]) && !toUnicode[code] &&
@@ -656,6 +674,9 @@ Gfx8BitFont::Gfx8BitFont(XRef *xref, char *tagA, Ref idA, GString *nameA,
} else if (n >= 3 && n <= 5 &&
isdigit(charName[1]) && isdigit(charName[2])) {
code2 = atoi(charName+1);
+ } else if (n >= 4 && n <= 6 &&
+ isdigit(charName[2]) && isdigit(charName[3])) {
+ code2 = atoi(charName+2);
}
if (code2 >= 0 && code2 <= 0xff) {
toUnicode[code] = (Unicode)code2;
@@ -684,10 +705,14 @@ Gfx8BitFont::Gfx8BitFont(XRef *xref, char *tagA, Ref idA, GString *nameA,
mul = (type == fontType3) ? fontMat[0] : fouble(0.001);
fontDict->lookup("Widths", &obj1);
if (obj1.isArray()) {
+ flags |= fontFixedWidth;
for (code = firstChar; code <= lastChar; ++code) {
obj1.arrayGet(code - firstChar, &obj2);
if (obj2.isNum()) {
widths[code] = obj2.getNum() * mul;
+ if (widths[code] != widths[firstChar]) {
+ flags &= ~fontFixedWidth;
+ }
}
obj2.free();
}
@@ -752,6 +777,9 @@ Gfx8BitFont::~Gfx8BitFont() {
if (charProcs.isDict()) {
charProcs.free();
}
+ if (resources.isDict()) {
+ resources.free();
+ }
}
int Gfx8BitFont::getNextChar(char *s, int len, CharCode *code,
@@ -771,6 +799,10 @@ CharCodeToUnicode *Gfx8BitFont::getToUnicode() {
return ctu;
}
+Dict *Gfx8BitFont::getCharProcs() {
+ return charProcs.isDict() ? charProcs.getDict() : (Dict *)NULL;
+}
+
Object *Gfx8BitFont::getCharProc(int code, Object *proc) {
if (charProcs.isDict()) {
charProcs.dictLookup(enc[code], proc);
@@ -780,6 +812,10 @@ Object *Gfx8BitFont::getCharProc(int code, Object *proc) {
return proc;
}
+Dict *Gfx8BitFont::getResources() {
+ return resources.isDict() ? resources.getDict() : (Dict *)NULL;
+}
+
//------------------------------------------------------------------------
// GfxCIDFont
//------------------------------------------------------------------------
@@ -1186,6 +1222,10 @@ int GfxCIDFont::getNextChar(char *s, int len, CharCode *code,
return n;
}
+int GfxCIDFont::getWMode() {
+ return cMap ? cMap->getWMode() : 0;
+}
+
CharCodeToUnicode *GfxCIDFont::getToUnicode() {
ctu->incRefCnt();
return ctu;
@@ -1216,7 +1256,7 @@ GfxFontDict::GfxFontDict(XRef *xref, Dict *fontDict) {
fonts[i] = NULL;
}
} else {
- error(-1, "font resource is not a dictionary");
+ error(-1, "font resource is not a dictionary reference");
fonts[i] = NULL;
}
obj1.free();
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
@@ -2,7 +2,7 @@
//
// GfxFont.h
//
-// Copyright 1996-2001 Derek B. Noonburg
+// Copyright 1996-2002 Glyph & Cog, LLC
//
//========================================================================
@@ -113,8 +113,7 @@ public:
// Get the PostScript font name for the embedded font. Returns
// NULL if there is no embedded font.
- char *getEmbeddedFontName()
- { return embFontName ? embFontName->getCString() : (char *)NULL; }
+ GString *getEmbeddedFontName() { return embFontName; }
// Get the name of the external font file. Returns NULL if there
// is no external font file.
@@ -137,6 +136,9 @@ public:
fouble getAscent() { return ascent; }
fouble getDescent() { return descent; }
+ // Return the writing mode (0=horizontal, 1=vertical).
+ virtual int getWMode() { return 0; }
+
// Read an external or embedded font file into a buffer.
char *readExtFontFile(int *len);
char *readEmbFontFile(XRef *xref, int *len);
@@ -155,7 +157,7 @@ protected:
void readFontDescriptor(XRef *xref, Dict *fontDict);
CharCodeToUnicode *readToUnicodeCMap(Dict *fontDict, int nBits);
- void GfxFont::findExtFontFile();
+ void findExtFontFile();
GString *tag; // PDF font tag
Ref id; // reference (used as unique ID)
@@ -166,7 +168,7 @@ protected:
Ref embFontID; // ref to embedded font file stream
GString *extFontFile; // external font file name
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
fouble ascent; // max height above baseline
fouble descent; // max depth below baseline
@@ -204,9 +206,15 @@ public:
// Get width of a character or string.
fouble getWidth(Guchar c) { return widths[c]; }
+ // Return the Type 3 CharProc dictionary, or NULL if none.
+ Dict *getCharProcs();
+
// Return the Type 3 CharProc for the character associated with <code>.
Object *getCharProc(int code, Object *proc);
+ // Return the Type 3 Resources dictionary, or NULL if none.
+ Dict *getResources();
+
private:
char *enc[256]; // char code --> char name
@@ -215,7 +223,8 @@ private:
CharCodeToUnicode *ctu; // char code --> Unicode
GBool hasEncoding;
fouble widths[256]; // character widths
- Object charProcs; // Type3 CharProcs dictionary
+ Object charProcs; // Type 3 CharProcs dictionary
+ Object resources; // Type 3 Resources dictionary
};
//------------------------------------------------------------------------
@@ -236,6 +245,9 @@ public:
Unicode *u, int uSize, int *uLen,
fouble *dx, fouble *dy, fouble *ox, fouble *oy);
+ // Return the writing mode (0=horizontal, 1=vertical).
+ virtual int getWMode();
+
// Return the Unicode map.
CharCodeToUnicode *getToUnicode();
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
@@ -2,7 +2,7 @@
//
// GfxState.cc
//
-// Copyright 1996 Derek B. Noonburg
+// Copyright 1996-2002 Glyph & Cog, LLC
//
//========================================================================
@@ -408,9 +408,22 @@ 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);
}
void GfxDeviceCMYKColorSpace::getCMYK(GfxColor *color, GfxCMYK *cmyk) {
@@ -1268,10 +1281,6 @@ GfxShading *GfxShading::parse(Object *obj) {
}
typeA = obj1.getInt();
obj1.free();
- if (typeA != 2) {
- error(-1, "Unimplemented shading type %d", typeA);
- goto err1;
- }
obj->dictLookup("ColorSpace", &obj1);
if (!(colorSpaceA = GfxColorSpace::parse(&obj1))) {
@@ -1317,7 +1326,17 @@ GfxShading *GfxShading::parse(Object *obj) {
}
obj1.free();
- 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;
+ }
if (shading) {
shading->type = typeA;
@@ -1457,6 +1476,128 @@ 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
//------------------------------------------------------------------------
@@ -1918,6 +2059,67 @@ GfxState::GfxState(GfxState *state) {
saved = NULL;
}
+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) {
fouble x, y;
@@ -1946,12 +2148,23 @@ void GfxState::getFontTransMat(fouble *m11, fouble *m12,
void GfxState::setCTM(fouble a, fouble b, fouble c,
fouble d, fouble e, fouble f) {
+ int i;
+
ctm[0] = a;
ctm[1] = b;
ctm[2] = c;
ctm[3] = d;
ctm[4] = e;
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);
+ }
+ }
}
void GfxState::concatCTM(fouble a, fouble b, fouble c,
@@ -1960,6 +2173,7 @@ void GfxState::concatCTM(fouble a, fouble b, fouble c,
fouble b1 = ctm[1];
fouble c1 = ctm[2];
fouble d1 = ctm[3];
+ int i;
ctm[0] = a * a1 + b * c1;
ctm[1] = a * b1 + b * d1;
@@ -1967,6 +2181,15 @@ void GfxState::concatCTM(fouble a, fouble b, fouble c,
ctm[3] = c * b1 + d * d1;
ctm[4] = e * a1 + f * c1 + ctm[4];
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);
+ }
+ }
}
void GfxState::setFillColorSpace(GfxColorSpace *colorSpace) {
@@ -2051,10 +2274,10 @@ 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;
curY += dy;
}
@@ -2095,3 +2318,4 @@ GfxState *GfxState::restore() {
return oldState;
}
+
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
@@ -2,7 +2,7 @@
//
// GfxState.h
//
-// Copyright 1996 Derek B. Noonburg
+// Copyright 1996-2002 Glyph & Cog, LLC
//
//========================================================================
@@ -568,6 +568,40 @@ 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
//------------------------------------------------------------------------
@@ -783,6 +817,7 @@ public:
fouble getCurY() { return curY; }
void getClipBBox(fouble *xMin, fouble *yMin, fouble *xMax, fouble *yMax)
{ *xMin = clipXMin; *yMin = clipYMin; *xMax = clipXMax; *yMax = clipYMax; }
+ void getUserClipBBox(fouble *xMin, fouble *yMin, fouble *xMax, fouble *yMax);
fouble getLineX() { return lineX; }
fouble getLineY() { return lineY; }
@@ -865,7 +900,7 @@ public:
// Text position.
void textMoveTo(fouble tx, fouble ty)
{ 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);
// Push/pop GfxState on/off stack.
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
@@ -2,7 +2,7 @@
//
// GlobalParams.cc
//
-// Copyright 2001 Derek B. Noonburg
+// Copyright 2001-2002 Glyph & Cog, LLC
//
//========================================================================
@@ -96,14 +96,20 @@ DisplayFontParam::~DisplayFontParam() {
// PSFontParam
//------------------------------------------------------------------------
-PSFontParam::PSFontParam(GString *pdfFontNameA, GString *psFontNameA) {
+PSFontParam::PSFontParam(GString *pdfFontNameA, int wModeA,
+ GString *psFontNameA, GString *encodingA) {
pdfFontName = pdfFontNameA;
+ wMode = wModeA;
psFontName = psFontNameA;
+ encoding = encodingA;
}
PSFontParam::~PSFontParam() {
delete pdfFontName;
delete psFontName;
+ if (encoding) {
+ delete encoding;
+ }
}
//------------------------------------------------------------------------
@@ -115,17 +121,14 @@ GlobalParams::GlobalParams(char *cfgFileName) {
DisplayFontParam *dfp;
GString *fileName;
FILE *f;
- char buf[512];
- int line;
- GList *tokens;
- GString *cmd;
- char *p1, *p2;
int i;
initBuiltinFontTables();
+ // 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]) {
macRomanReverseMap->add(macRomanEncoding[i], (CharCode)i);
}
@@ -139,6 +142,7 @@ GlobalParams::GlobalParams(char *cfgFileName) {
toUnicodeDirs = new GList();
displayFonts = new GHash();
displayCIDFonts = new GHash();
+ displayNamedCIDFonts = new GHash();
#if HAVE_PAPER_H
const struct paper *paperType;
paperinit();
@@ -154,9 +158,14 @@ GlobalParams::GlobalParams(char *cfgFileName) {
psLevel = psLevel2;
psFile = NULL;
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");
#if defined(WIN32)
textEOL = eolDOS;
@@ -166,6 +175,7 @@ GlobalParams::GlobalParams(char *cfgFileName) {
textEOL = eolUnix;
#endif
fontDirs = new GList();
+ initialZoom = new GString("1");
t1libControl = fontRastAALow;
freetypeControl = fontRastAALow;
urlCommand = NULL;
@@ -193,6 +203,8 @@ GlobalParams::GlobalParams(char *cfgFileName) {
residentUnicodeMaps->add(map->getEncodingName(), map);
map = new UnicodeMap("UTF-8", &mapUTF8);
residentUnicodeMaps->add(map->getEncodingName(), map);
+ map = new UnicodeMap("UCS-2", &mapUCS2);
+ residentUnicodeMaps->add(map->getEncodingName(), map);
// default displayFonts table
for (i = 0; displayFontTab[i].name; ++i) {
@@ -219,6 +231,7 @@ GlobalParams::GlobalParams(char *cfgFileName) {
}
if (!f) {
#if defined(WIN32) && !defined(__CYGWIN32__)
+ char buf[512];
i = GetModuleFileName(NULL, buf, sizeof(buf));
if (i <= 0 || i >= sizeof(buf)) {
// error or path too long for buffer - just use the current dir
@@ -234,98 +247,141 @@ 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;
}
}
@@ -426,7 +482,7 @@ void GlobalParams::parseToUnicodeDir(GList *tokens, GString *fileName,
toUnicodeDirs->append(((GString *)tokens->get(1))->copy());
}
-void GlobalParams::parseDisplayFont(GList *tokens, GBool isCID,
+void GlobalParams::parseDisplayFont(GList *tokens, GHash *fontHash,
DisplayFontParamKind kind,
GString *fileName, int line) {
DisplayFontParam *param, *old;
@@ -458,23 +514,16 @@ void GlobalParams::parseDisplayFont(GList *tokens, GBool isCID,
break;
}
- 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;
err2:
delete param;
err1:
- error(-1, "Bad 'displayFont...' config file command (%s:%d)",
+ error(-1, "Bad 'display*Font*' config file command (%s:%d)",
fileName->getCString(), line);
}
@@ -516,6 +565,10 @@ void GlobalParams::parsePSLevel(GList *tokens, GString *fileName, int line) {
psLevel = psLevel2;
} else if (!tok->cmp("level2sep")) {
psLevel = psLevel2Sep;
+ } else if (!tok->cmp("level3")) {
+ psLevel = psLevel3;
+ } else if (!tok->cmp("level3Sep")) {
+ psLevel = psLevel3Sep;
} else {
error(-1, "Bad 'psLevel' config file command (%s:%d)",
fileName->getCString(), line);
@@ -542,11 +595,39 @@ void GlobalParams::parsePSFont(GList *tokens, GString *fileName, int line) {
fileName->getCString(), line);
return;
}
- 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);
}
+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,
int line) {
if (tokens->getLength() != 2) {
@@ -588,17 +669,15 @@ void GlobalParams::parseFontDir(GList *tokens, GString *fileName, int line) {
fontDirs->append(((GString *)tokens->get(1))->copy());
}
-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);
return;
}
- if (urlCommand) {
- delete urlCommand;
- }
- urlCommand = ((GString *)tokens->get(1))->copy();
+ delete initialZoom;
+ initialZoom = ((GString *)tokens->get(1))->copy();
}
void GlobalParams::parseFontRastControl(char *cmdName, FontRastControl *val,
@@ -618,6 +697,19 @@ 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,
GList *tokens, GString *fileName, int line) {
GString *tok;
@@ -654,12 +746,16 @@ GlobalParams::~GlobalParams() {
deleteGList(toUnicodeDirs, GString);
deleteGHash(displayFonts, DisplayFontParam);
deleteGHash(displayCIDFonts, DisplayFontParam);
+ deleteGHash(displayNamedCIDFonts, DisplayFontParam);
if (psFile) {
delete psFile;
}
deleteGHash(psFonts, PSFontParam);
+ deleteGList(psNamedFonts16, PSFontParam);
+ deleteGList(psFonts16, PSFontParam);
delete textEncoding;
deleteGList(fontDirs, GString);
+ delete initialZoom;
if (urlCommand) {
delete urlCommand;
}
@@ -752,14 +848,50 @@ DisplayFontParam *GlobalParams::getDisplayFont(GString *fontName) {
return (DisplayFontParam *)displayFonts->lookup(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;
}
PSFontParam *GlobalParams::getPSFont(GString *fontName) {
return (PSFontParam *)psFonts->lookup(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,
char *ext1, char *ext2) {
GString *dir, *fileName;
@@ -866,10 +998,22 @@ void GlobalParams::setPSEmbedTrueType(GBool embed) {
psEmbedTrueType = embed;
}
+void GlobalParams::setPSEmbedCIDPostScript(GBool embed) {
+ psEmbedCIDPostScript = embed;
+}
+
+void GlobalParams::setPSEmbedCIDTrueType(GBool embed) {
+ psEmbedCIDTrueType = embed;
+}
+
void GlobalParams::setPSOPI(GBool opi) {
psOPI = opi;
}
+void GlobalParams::setPSASCIIHex(GBool hex) {
+ psASCIIHex = hex;
+}
+
void GlobalParams::setTextEncoding(char *encodingName) {
delete textEncoding;
textEncoding = new GString(encodingName);
@@ -888,6 +1032,11 @@ GBool GlobalParams::setTextEOL(char *s) {
return gTrue;
}
+void GlobalParams::setInitialZoom(char *s) {
+ delete initialZoom;
+ initialZoom = new GString(s);
+}
+
GBool GlobalParams::setT1libControl(char *s) {
return setFontRastControl(&t1libControl, 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
@@ -2,7 +2,7 @@
//
// GlobalParams.h
//
-// Copyright 2001 Derek B. Noonburg
+// Copyright 2001-2002 Glyph & Cog, LLC
//
//========================================================================
@@ -45,8 +45,9 @@ enum DisplayFontParamKind {
class DisplayFontParam {
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;
union {
struct {
@@ -79,10 +80,16 @@ enum FontRastControl {
class PSFontParam {
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();
};
@@ -92,7 +99,9 @@ enum PSLevel {
psLevel1,
psLevel1Sep,
psLevel2,
- psLevel2Sep
+ psLevel2Sep,
+ psLevel3,
+ psLevel3Sep
};
//------------------------------------------------------------------------
@@ -125,19 +134,24 @@ public:
FILE *findCMapFile(GString *collection, GString *cMapName);
FILE *findToUnicodeFile(GString *name);
DisplayFontParam *getDisplayFont(GString *fontName);
- DisplayFontParam *getDisplayCIDFont(GString *collection);
+ DisplayFontParam *getDisplayCIDFont(GString *fontName, GString *collection);
GString *getPSFile() { return psFile; }
int getPSPaperWidth() { return psPaperWidth; }
int getPSPaperHeight() { return psPaperHeight; }
GBool getPSDuplex() { return psDuplex; }
PSLevel getPSLevel() { return psLevel; }
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; }
EndOfLineKind getTextEOL() { return textEOL; }
GString *findFontFile(GString *fontName, char *ext1, char *ext2);
+ GString *getInitialZoom() { return initialZoom; }
FontRastControl getT1libControl() { return t1libControl; }
FontRastControl getFreeTypeControl() { return freetypeControl; }
GString *getURLCommand() { return urlCommand; }
@@ -159,29 +173,38 @@ public:
void setPSLevel(PSLevel level);
void setPSEmbedType1(GBool embed);
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);
GBool setFreeTypeControl(char *s);
void setErrQuiet(GBool errQuietA);
private:
+ void parseFile(GString *fileName, FILE *f);
void parseNameToUnicode(GList *tokens, GString *fileName, int line);
void parseCIDToUnicode(GList *tokens, GString *fileName, int line);
void parseUnicodeMap(GList *tokens, GString *fileName, int line);
void parseCMapDir(GList *tokens, GString *fileName, int line);
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);
void parsePSFile(GList *tokens, GString *fileName, int line);
void parsePSPaperSize(GList *tokens, GString *fileName, int line);
void parsePSLevel(GList *tokens, GString *fileName, int line);
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);
void parseTextEOL(GList *tokens, GString *fileName, int line);
void parseFontDir(GList *tokens, GString *fileName, int line);
+ void parseInitialZoom(GList *tokens, GString *fileName, int line);
void parseFontRastControl(char *cmdName, FontRastControl *val,
GList *tokens, GString *fileName, int line);
void parseURLCommand(GList *tokens, GString *fileName, int line);
@@ -212,6 +235,8 @@ private:
// [DisplayFontParam]
GHash *displayCIDFonts; // display CID font info, indexed by
// collection [DisplayFontParam]
+ GHash *displayNamedCIDFonts; // display CID font info, indexed by
+ // font name [DisplayFontParam]
GString *psFile; // PostScript file or command (for xpdf)
int psPaperWidth; // paper size, in PostScript points, for
int psPaperHeight; // PostScript output
@@ -219,14 +244,20 @@ private:
PSLevel psLevel; // PostScript level to generate
GHash *psFonts; // PostScript font info, indexed by PDF
// 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
// output
EndOfLineKind textEOL; // type of EOL marker to use for text
// output
GList *fontDirs; // list of font dirs [GString]
+ GString *initialZoom; // initial zoom level
FontRastControl t1libControl; // t1lib rasterization mode
FontRastControl // FreeType rasterization mode
freetypeControl;
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
@@ -2,7 +2,7 @@
//
// Lexer.cc
//
-// 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
@@ -2,7 +2,7 @@
//
// Lexer.h
//
-// Copyright 1996 Derek B. Noonburg
+// Copyright 1996-2002 Glyph & Cog, LLC
//
//========================================================================
@@ -51,13 +51,14 @@ public:
Stream *getStream()
{ return curStr.isNone() ? (Stream *)NULL : curStr.getStream(); }
- // 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); }
private:
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
@@ -2,7 +2,7 @@
//
// Link.cc
//
-// Copyright 1996 Derek B. Noonburg
+// Copyright 1996-2002 Glyph & Cog, LLC
//
//========================================================================
@@ -29,31 +29,27 @@ static GString *getFileSpecName(Object *fileSpecObj);
// LinkDest
//------------------------------------------------------------------------
-LinkDest::LinkDest(Array *a, GBool pageIsRefA) {
+LinkDest::LinkDest(Array *a) {
Object obj1, obj2;
// initialize fields
- pageIsRef = pageIsRefA;
left = bottom = right = top = zoom = 0;
ok = gFalse;
// 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();
// get destination type
a->get(1, &obj1);
@@ -221,7 +217,7 @@ LinkGoTo::LinkGoTo(Object *destObj) {
// destination dictionary
} else if (destObj->isArray()) {
- dest = new LinkDest(destObj->getArray(), gTrue);
+ dest = new LinkDest(destObj->getArray());
if (!dest->isOk()) {
delete dest;
dest = NULL;
@@ -259,7 +255,7 @@ LinkGoToR::LinkGoToR(Object *fileSpecObj, Object *destObj) {
// destination dictionary
} else if (destObj->isArray()) {
- dest = new LinkDest(destObj->getArray(), gFalse);
+ dest = new LinkDest(destObj->getArray());
if (!dest->isOk()) {
delete dest;
dest = NULL;
@@ -446,7 +442,7 @@ Link::Link(Dict *dict, GString *baseURI) {
}
// get border
- borderW = 0;
+ borderW = 1;
if (!dict->lookup("Border", &obj1)->isNull()) {
if (obj1.isArray() && obj1.arrayGetLength() >= 3) {
if (obj1.arrayGet(2, &obj2)->isNum()) {
@@ -582,7 +578,7 @@ Links::~Links() {
LinkAction *Links::find(fouble x, fouble y) {
int i;
- for (i = 0; i < numLinks; ++i) {
+ for (i = numLinks - 1; i >= 0; --i) {
if (links[i]->inRect(x, y)) {
return links[i]->getAction();
}
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
@@ -2,7 +2,7 @@
//
// Link.h
//
-// Copyright 1996 Derek B. Noonburg
+// Copyright 1996-2002 Glyph & Cog, LLC
//
//========================================================================
@@ -63,10 +63,8 @@ enum LinkDestKind {
class LinkDest {
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);
// Copy a LinkDest.
LinkDest *copy() { return new LinkDest(this); }
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
@@ -2,7 +2,7 @@
//
// NameToCharCode.cc
//
-// 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
@@ -2,7 +2,7 @@
//
// NameToCharCode.h
//
-// 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
@@ -2,7 +2,7 @@
//
// NameToUnicodeTable.h
//
-// 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
@@ -2,7 +2,7 @@
//
// Object.cc
//
-// 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
@@ -2,7 +2,7 @@
//
// Object.h
//
-// Copyright 1996 Derek B. Noonburg
+// Copyright 1996-2002 Glyph & Cog, LLC
//
//========================================================================
@@ -176,8 +176,8 @@ public:
int streamGetChar();
int streamLookChar();
char *streamGetLine(char *buf, int size);
- int streamGetPos();
- void streamSetPos(int pos);
+ Guint streamGetPos();
+ void streamSetPos(Guint pos, int dir = 0);
Dict *streamGetDict();
// Output.
@@ -287,11 +287,11 @@ inline int Object::streamLookChar()
inline char *Object::streamGetLine(char *buf, int size)
{ return stream->getLine(buf, 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); }
inline Dict *Object::streamGetDict()
{ return stream->getDict(); }
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
@@ -2,7 +2,7 @@
//
// OutputDev.cc
//
-// Copyright 1996 Derek B. Noonburg
+// Copyright 1996-2002 Glyph & Cog, LLC
//
//========================================================================
@@ -59,6 +59,11 @@ void OutputDev::updateAll(GfxState *state) {
updateFont(state);
}
+GBool OutputDev::beginType3Char(GfxState *state,
+ CharCode code, Unicode *u, int uLen) {
+ return gFalse;
+}
+
void OutputDev::drawImageMask(GfxState *state, Object *ref, Stream *str,
int width, int height, GBool invert,
GBool inlineImg) {
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
@@ -2,7 +2,7 @@
//
// OutputDev.h
//
-// Copyright 1996 Derek B. Noonburg
+// Copyright 1996-2002 Glyph & Cog, LLC
//
//========================================================================
@@ -46,6 +46,10 @@ public:
// Does this device use drawChar() or drawString()?
virtual GBool useDrawChar() = 0;
+ // 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?
virtual GBool needNonText() { return gTrue; }
@@ -119,6 +123,9 @@ public:
fouble originX, fouble originY,
CharCode code, Unicode *u, int uLen) {}
virtual void drawString(GfxState *state, GString *s) {}
+ virtual GBool beginType3Char(GfxState *state,
+ CharCode code, Unicode *u, int uLen);
+ virtual void endType3Char(GfxState *state) {}
//----- image drawing
virtual void drawImageMask(GfxState *state, Object *ref, Stream *str,
@@ -134,6 +141,14 @@ public:
virtual void opiEnd(GfxState *state, Dict *opiDict);
#endif
+ //----- 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:
fouble defCTM[6]; // default coordinate transform matrix
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
@@ -2,7 +2,7 @@
//
// PDFDoc.cc
//
-// Copyright 1996 Derek B. Noonburg
+// Copyright 1996-2002 Glyph & Cog, LLC
//
//========================================================================
@@ -24,6 +24,7 @@
#include "Link.h"
#include "OutputDev.h"
#include "Error.h"
+#include "ErrorCodes.h"
#include "Lexer.h"
#include "Parser.h"
#include "PDFDoc.h"
@@ -43,6 +44,7 @@ PDFDoc::PDFDoc(GString *fileNameA, GString *ownerPassword,
GString *fileName2;
ok = gFalse;
+ errCode = errNone;
file = NULL;
str = NULL;
@@ -57,6 +59,7 @@ PDFDoc::PDFDoc(GString *fileNameA, GString *ownerPassword,
#ifdef VMS
if (!(file = fopen(fileName->getCString(), "rb", "ctx=stm"))) {
error(-1, "Couldn't open file '%s'", fileName->getCString());
+ errCode = errOpenFile;
return;
}
#else
@@ -68,6 +71,7 @@ PDFDoc::PDFDoc(GString *fileNameA, GString *ownerPassword,
if (!(file = fopen(fileName2->getCString(), "rb"))) {
error(-1, "Couldn't open file '%s'", fileName->getCString());
delete fileName2;
+ errCode = errOpenFile;
return;
}
}
@@ -77,7 +81,7 @@ PDFDoc::PDFDoc(GString *fileNameA, GString *ownerPassword,
// create stream
obj.initNull();
- str = new FileStream(file, 0, -1, &obj);
+ str = new FileStream(file, 0, gFalse, 0, &obj);
ok = setup(ownerPassword, userPassword);
}
@@ -85,6 +89,7 @@ PDFDoc::PDFDoc(GString *fileNameA, GString *ownerPassword,
PDFDoc::PDFDoc(BaseStream *strA, GString *ownerPassword,
GString *userPassword, GBool printCommandsA) {
ok = gFalse;
+ errCode = errNone;
fileName = NULL;
file = NULL;
str = strA;
@@ -103,6 +108,7 @@ GBool PDFDoc::setup(GString *ownerPassword, GString *userPassword) {
xref = new XRef(str, ownerPassword, userPassword);
if (!xref->isOk()) {
error(-1, "Couldn't read xref table");
+ errCode = xref->getErrorCode();
return gFalse;
}
@@ -110,6 +116,7 @@ GBool PDFDoc::setup(GString *ownerPassword, GString *userPassword) {
catalog = new Catalog(xref, printCommands);
if (!catalog->isOk()) {
error(-1, "Couldn't read page catalog");
+ errCode = errBadCatalog;
return gFalse;
}
@@ -204,8 +211,9 @@ GBool PDFDoc::isLinearized() {
lin = gFalse;
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);
parser->getObj(&obj2);
parser->getObj(&obj3);
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
@@ -2,7 +2,7 @@
//
// PDFDoc.h
//
-// Copyright 1996 Derek B. Noonburg
+// Copyright 1996-2002 Glyph & Cog, LLC
//
//========================================================================
@@ -42,6 +42,9 @@ public:
// Was PDF document successfully opened?
GBool isOk() { return ok; }
+ // Get the error code (if isOk() returns false).
+ int getErrorCode() { return errCode; }
+
// Get file name.
GString *getFileName() { return fileName; }
@@ -137,6 +140,7 @@ private:
GBool printCommands;
GBool ok;
+ int errCode;
};
#endif
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
@@ -2,7 +2,7 @@
//
// Page.cc
//
-// Copyright 1996 Derek B. Noonburg
+// Copyright 1996-2002 Glyph & Cog, LLC
//
//========================================================================
@@ -20,7 +20,7 @@
#include "OutputDev.h"
#ifndef PDF_PARSER_ONLY
#include "Gfx.h"
-#include "FormWidget.h"
+#include "Annot.h"
#endif
#include "Error.h"
#include "Page.h"
@@ -93,6 +93,14 @@ PageAttrs::PageAttrs(PageAttrs *attrs, Dict *dict) {
rotate -= 360;
}
+ // 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
dict->lookup("Resources", &obj1);
if (obj1.isDict()) {
@@ -103,6 +111,12 @@ PageAttrs::PageAttrs(PageAttrs *attrs, Dict *dict) {
}
PageAttrs::~PageAttrs() {
+ lastModified.free();
+ boxColorInfo.free();
+ group.free();
+ metadata.free();
+ pieceInfo.free();
+ separationInfo.free();
resources.free();
}
@@ -209,7 +223,7 @@ void Page::display(OutputDev *out, fouble dpi, int rotate,
Object obj;
Link *link;
int i;
- FormWidgets *formWidgets;
+ Annots *annotList;
box = getBox();
cropBox = getCropBox();
@@ -247,20 +261,20 @@ void Page::display(OutputDev *out, fouble dpi, int rotate,
out->dump();
}
- // 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;
delete gfx;
#endif
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
@@ -2,7 +2,7 @@
//
// Page.h
//
-// Copyright 1996 Derek B. Noonburg
+// Copyright 1996-2002 Glyph & Cog, LLC
//
//========================================================================
@@ -51,6 +51,20 @@ public:
PDFRectangle *getTrimBox() { return &trimBox; }
PDFRectangle *getArtBox() { return &artBox; }
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()
{ return resources.isDict() ? resources.getDict() : (Dict *)NULL; }
@@ -66,6 +80,12 @@ private:
PDFRectangle trimBox;
PDFRectangle artBox;
int rotate;
+ Object lastModified;
+ Object boxColorInfo;
+ Object group;
+ Object metadata;
+ Object pieceInfo;
+ Object separationInfo;
Object resources;
};
@@ -97,6 +117,12 @@ public:
PDFRectangle *getTrimBox() { return attrs->getTrimBox(); }
PDFRectangle *getArtBox() { return attrs->getArtBox(); }
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(); }
// Get resource dictionary.
Dict *getResourceDict() { return attrs->getResourceDict(); }
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
@@ -2,7 +2,7 @@
//
// Parser.cc
//
-// Copyright 1996 Derek B. Noonburg
+// Copyright 1996-2002 Glyph & Cog, LLC
//
//========================================================================
@@ -155,7 +155,7 @@ Object *Parser::getObj(Object *obj) {
Stream *Parser::makeStream(Object *dict) {
Object obj;
Stream *str;
- int pos, endPos, length;
+ Guint pos, endPos, length;
// get stream start position
lexer->skipToNextLine();
@@ -164,7 +164,7 @@ Stream *Parser::makeStream(Object *dict) {
// get length
dict->dictLookup("Length", &obj);
if (obj.isInt()) {
- length = obj.getInt();
+ length = (Guint)obj.getInt();
obj.free();
} else {
error(getPos(), "Bad 'Length' attribute in stream");
@@ -173,12 +173,13 @@ 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;
}
// make base stream
- str = lexer->getStream()->getBaseStream()->makeSubStream(pos, length, dict);
+ str = lexer->getStream()->getBaseStream()->makeSubStream(pos, gTrue,
+ length, dict);
// get filters
str = str->addFilters(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
@@ -2,7 +2,7 @@
//
// Parser.h
//
-// 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
@@ -4,7 +4,7 @@
//
// Tables for CCITT Fax decoding.
//
-// 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
@@ -2,7 +2,7 @@
//
// Stream.cc
//
-// Copyright 1996 Derek B. Noonburg
+// Copyright 1996-2002 Glyph & Cog, LLC
//
//========================================================================
@@ -303,7 +303,7 @@ void FilterStream::close() {
str->close();
}
-void FilterStream::setPos(int pos) {
+void FilterStream::setPos(Guint pos, int dir) {
error(-1, "Internal: called setPos() on FilterStream");
}
@@ -554,27 +554,37 @@ GBool StreamPredictor::getNextLine() {
// FileStream
//------------------------------------------------------------------------
-FileStream::FileStream(FILE *fA, int startA, int lengthA, Object *dictA):
+FileStream::FileStream(FILE *fA, Guint startA, GBool limitedA,
+ Guint lengthA, Object *dictA):
BaseStream(dictA) {
f = fA;
start = startA;
+ limited = limitedA;
length = lengthA;
bufPtr = bufEnd = buf;
bufPos = start;
- savePos = -1;
+ savePos = 0;
+ saved = gFalse;
}
FileStream::~FileStream() {
close();
}
-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);
}
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;
bufPos = start;
#ifndef NO_DECRYPTION
@@ -584,9 +594,13 @@ 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;
}
}
@@ -598,10 +612,10 @@ GBool FileStream::fillBuf() {
bufPos += bufEnd - buf;
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;
} else {
n = fileStreamBufSize;
@@ -621,23 +635,37 @@ GBool FileStream::fillBuf() {
return gTrue;
}
-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__
//~ work around a bug in cygwin's implementation of fseek
rewind(f);
#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
}
bufPtr = bufEnd = buf;
}
@@ -649,6 +677,90 @@ 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
//------------------------------------------------------------------------
@@ -660,21 +772,22 @@ EmbedStream::EmbedStream(Stream *strA, Object *dictA):
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");
return NULL;
}
-void EmbedStream::setPos(int pos) {
+void EmbedStream::setPos(Guint pos, int dir) {
error(-1, "Internal: called setPos() on EmbedStream");
}
-int EmbedStream::getStart() {
+Guint EmbedStream::getStart() {
error(-1, "Internal: called getStart() on EmbedStream");
return 0;
}
-void EmbedStream::moveStart(int start) {
+void EmbedStream::moveStart(int delta) {
error(-1, "Internal: called moveStart() on EmbedStream");
}
@@ -959,11 +1072,7 @@ void LZWStream::reset() {
return;
}
#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());
unlink(zName->getCString());
delete zName;
@@ -3287,6 +3396,56 @@ 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
@@ -2,7 +2,7 @@
//
// Stream.h
//
-// Copyright 1996 Derek B. Noonburg
+// Copyright 1996-2002 Glyph & Cog, LLC
//
//========================================================================
@@ -78,8 +78,10 @@ public:
// Get current position in file.
virtual int getPos() = 0;
- // 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;
// Get PostScript command for the filter(s).
virtual GString *getPSFilter(char *indent);
@@ -118,18 +120,20 @@ public:
BaseStream(Object *dictA);
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; }
virtual Dict *getDict() { return dict.getDict(); }
// 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;
#ifndef NO_DECRYPTION
// 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
#ifndef NO_DECRYPTION
@@ -156,7 +160,7 @@ public:
virtual ~FilterStream();
virtual void close();
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(); }
virtual Dict *getDict() { return str->getDict(); }
@@ -242,9 +246,11 @@ private:
class FileStream: public BaseStream {
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; }
virtual void reset();
virtual void close();
@@ -253,9 +259,9 @@ public:
virtual int lookChar()
{ return (bufPtr >= bufEnd && !fillBuf()) ? EOF : (*bufPtr & 0xff); }
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);
private:
@@ -263,13 +269,52 @@ private:
GBool fillBuf();
FILE *f;
- int start;
- int length;
+ Guint start;
+ GBool limited;
+ Guint length;
char buf[fileStreamBufSize];
char *bufPtr;
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;
};
//------------------------------------------------------------------------
@@ -287,15 +332,16 @@ public:
EmbedStream(Stream *strA, Object *dictA);
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(); }
virtual void reset() {}
virtual int getChar() { return str->getChar(); }
virtual int lookChar() { return str->lookChar(); }
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);
private:
@@ -659,6 +705,37 @@ 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
@@ -2,7 +2,7 @@
//
// TextOutputDev.cc
//
-// Copyright 1997 Derek B. Noonburg
+// Copyright 1997-2002 Glyph & Cog, LLC
//
//========================================================================
@@ -48,6 +48,12 @@ TextString::TextString(GfxState *state, fouble fontSize) {
yMin = y - 0.95 * fontSize;
yMax = y + 0.35 * 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;
text = NULL;
xRight = NULL;
@@ -99,6 +105,7 @@ void TextPage::updateFont(GfxState *state) {
fouble *fm;
char *name;
int code;
+ fouble w;
// adjust the font size
fontSize = state->getTransformedFontSize();
@@ -116,8 +123,11 @@ 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;
+ }
}
fm = font->getFontMatrix();
if (fm[0] != 0) {
@@ -154,8 +164,10 @@ void TextPage::addChar(GfxState *state, fouble x, fouble y,
dx -= dx2;
dy -= dy2;
state->transformDelta(dx, dy, &w1, &h1);
- w1 /= uLen;
- h1 /= uLen;
+ if (uLen != 0) {
+ w1 /= uLen;
+ h1 /= uLen;
+ }
for (i = 0; i < uLen; ++i) {
curStr->addChar(state, x1 + i*w1, y1 + i*h1, w1, h1, u[i]);
}
@@ -429,7 +441,7 @@ GString *TextPage::getText(fouble xMin, fouble yMin,
return s;
}
-void TextPage::dump(FILE *f) {
+void TextPage::dump(void *outputStream, TextOutputFunc outputFunc) {
UnicodeMap *uMap;
char space[8], eol[16], eop[8], buf[8];
int spaceLen, eolLen, eopLen, n;
@@ -498,9 +510,9 @@ 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,
(int)str1->xMax, (int)str1->yMax, str1->col);
for (i = 0; i < str1->len; ++i) {
@@ -508,7 +520,7 @@ void TextPage::dump(FILE *f) {
}
printf("'\n");
}
- fprintf(f, "~~~~~~~~~~\n");
+ fprintf((FILE *)outputStream, "~~~~~~~~~~\n");
#endif
// output
@@ -521,14 +533,14 @@ void TextPage::dump(FILE *f) {
col1 = str1->col;
} else {
for (; col1 < str1->col; ++col1) {
- fwrite(space, 1, spaceLen, f);
+ (*outputFunc)(outputStream, space, spaceLen);
}
}
// print the string
for (i = 0; i < str1->len; ++i) {
if ((n = uMap->mapUnicode(str1->text[i], buf, sizeof(buf))) > 0) {
- fwrite(buf, 1, n, f);
+ (*outputFunc)(outputStream, buf, n);
}
}
@@ -547,7 +559,7 @@ void TextPage::dump(FILE *f) {
str1->yxNext->xMin >= str1->xMax)) {
// print a return
- fwrite(eol, 1, eolLen, f);
+ (*outputFunc)(outputStream, eol, eolLen);
// print extra vertical space if necessary
if (str1->yxNext) {
@@ -573,7 +585,7 @@ void TextPage::dump(FILE *f) {
d = 5;
}
for (; d > 0; --d) {
- fwrite(eol, 1, eolLen, f);
+ (*outputFunc)(outputStream, eol, eolLen);
}
}
@@ -584,9 +596,9 @@ 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);
uMap->decRefCnt();
}
@@ -611,6 +623,10 @@ void TextPage::clear() {
// TextOutputDev
//------------------------------------------------------------------------
+static void outputToFile(void *stream, char *text, int len) {
+ fwrite(text, 1, len, (FILE *)stream);
+}
+
TextOutputDev::TextOutputDev(char *fileName, GBool rawOrderA, GBool append) {
text = NULL;
rawOrder = rawOrderA;
@@ -620,28 +636,39 @@ TextOutputDev::TextOutputDev(char *fileName, GBool rawOrderA, GBool append) {
needClose = gFalse;
if (fileName) {
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;
} else {
error(-1, "Couldn't open text file '%s'", fileName);
ok = gFalse;
return;
}
+ outputFunc = &outputToFile;
} else {
- f = NULL;
+ outputStream = NULL;
}
// set up text object
text = new TextPage(rawOrder);
}
+TextOutputDev::TextOutputDev(TextOutputFunc func, void *stream,
+ GBool rawOrderA) {
+ outputFunc = func;
+ outputStream = stream;
+ needClose = gFalse;
+ rawOrder = rawOrderA;
+ text = new TextPage(rawOrder);
+ ok = gTrue;
+}
+
TextOutputDev::~TextOutputDev() {
if (needClose) {
#ifdef MACOS
- ICS_MapRefNumAndAssign((short)f->handle);
+ ICS_MapRefNumAndAssign((short)((FILE *)outputStream)->handle);
#endif
- fclose(f);
+ fclose((FILE *)outputStream);
}
if (text) {
delete text;
@@ -654,8 +681,8 @@ void TextOutputDev::startPage(int pageNum, GfxState *state) {
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
@@ -2,7 +2,7 @@
//
// TextOutputDev.h
//
-// Copyright 1997 Derek B. Noonburg
+// Copyright 1997-2002 Glyph & Cog, LLC
//
//========================================================================
@@ -22,6 +22,10 @@ class GfxState;
class GString;
//------------------------------------------------------------------------
+
+typedef void (*TextOutputFunc)(void *stream, char *text, int len);
+
+//------------------------------------------------------------------------
// TextString
//------------------------------------------------------------------------
@@ -97,7 +101,7 @@ public:
fouble xMax, fouble yMax);
// Dump contents of page to a file.
- void dump(FILE *f);
+ void dump(void *outputStream, TextOutputFunc outputFunc);
// Clear the page.
void clear();
@@ -128,6 +132,10 @@ public:
// <rawOrder> is true, the text is kept in content stream order.
TextOutputDev(char *fileName, GBool rawOrderA, GBool append);
+ // 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.
virtual ~TextOutputDev();
@@ -143,6 +151,10 @@ public:
// Does this device use drawChar() or drawString()?
virtual GBool useDrawChar() { return gTrue; }
+ // 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; }
@@ -179,8 +191,10 @@ public:
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
GBool rawOrder; // keep text in content stream order
GBool ok; // set up ok?
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
@@ -2,7 +2,7 @@
//
// UnicodeMap.cc
//
-// 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
@@ -4,7 +4,7 @@
//
// Mapping from Unicode to an encoding.
//
-// 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
@@ -2,7 +2,7 @@
//
// UnicodeMapTables.h
//
-// Copyright 2001 Derek B. Noonburg
+// Copyright 2001-2002 Glyph & Cog, LLC
//
//========================================================================
@@ -13,6 +13,8 @@ static UnicodeMapRange latin1UnicodeMapRanges[] = {
{ 0x00a0, 0x00a0, 0x20, 1 },
{ 0x00a1, 0x00ac, 0xa1, 1 },
{ 0x00ae, 0x00ff, 0xae, 1 },
+ { 0x010c, 0x010c, 0x43, 1 },
+ { 0x010d, 0x010d, 0x63, 1 },
{ 0x0131, 0x0131, 0x69, 1 },
{ 0x0141, 0x0141, 0x4c, 1 },
{ 0x0142, 0x0142, 0x6c, 1 },
@@ -41,6 +43,23 @@ static UnicodeMapRange latin1UnicodeMapRanges[] = {
{ 0x2044, 0x2044, 0x2f, 1 },
{ 0x2122, 0x2122, 0x544d, 2 },
{ 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 },
{ 0xfb01, 0xfb01, 0x6669, 2 },
{ 0xfb02, 0xfb02, 0x666c, 2 },
@@ -135,6 +154,45 @@ static UnicodeMapRange ascii7UnicodeMapRanges[] = {
{ 0x2026, 0x2026, 0x2e2e2e, 3 },
{ 0x2122, 0x2122, 0x544d, 2 },
{ 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 },
{ 0xfb01, 0xfb01, 0x6669, 2 },
{ 0xfb02, 0xfb02, 0x666c, 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
@@ -2,7 +2,7 @@
//
// XRef.cc
//
-// Copyright 1996 Derek B. Noonburg
+// Copyright 1996-2002 Glyph & Cog, LLC
//
//========================================================================
@@ -25,6 +25,7 @@
#include "Decrypt.h"
#endif
#include "Error.h"
+#include "ErrorCodes.h"
#include "XRef.h"
//------------------------------------------------------------------------
@@ -49,10 +50,11 @@
//------------------------------------------------------------------------
XRef::XRef(BaseStream *strA, GString *ownerPassword, GString *userPassword) {
- int pos;
+ Guint pos;
int i;
ok = gTrue;
+ errCode = errNone;
size = 0;
entries = NULL;
streamEnds = NULL;
@@ -67,6 +69,7 @@ XRef::XRef(BaseStream *strA, GString *ownerPassword, GString *userPassword) {
// try to reconstruct the xref table
if (pos == 0) {
if (!(ok = constructXRef())) {
+ errCode = errDamaged;
return;
}
@@ -74,7 +77,7 @@ XRef::XRef(BaseStream *strA, GString *ownerPassword, GString *userPassword) {
} else {
entries = (XRefEntry *)gmalloc(size * sizeof(XRefEntry));
for (i = 0; i < size; ++i) {
- entries[i].offset = -1;
+ entries[i].offset = 0xffffffff;
entries[i].used = gFalse;
}
while (readXRef(&pos)) ;
@@ -86,6 +89,7 @@ XRef::XRef(BaseStream *strA, GString *ownerPassword, GString *userPassword) {
size = 0;
entries = NULL;
if (!(ok = constructXRef())) {
+ errCode = errDamaged;
return;
}
}
@@ -101,6 +105,7 @@ XRef::XRef(BaseStream *strA, GString *ownerPassword, GString *userPassword) {
#endif
if (checkEncrypted(ownerPassword, userPassword)) {
ok = gFalse;
+ errCode = errEncrypted;
return;
}
}
@@ -115,17 +120,18 @@ XRef::~XRef() {
// Read startxref position, xref table size, and root. Returns
// first xref position.
-int XRef::readTrailer() {
+Guint XRef::readTrailer() {
Parser *parser;
Object obj;
char buf[xrefSearchSize+1];
- int n, pos, pos1;
+ int n;
+ Guint pos, pos1;
char *p;
int c;
int i;
// read last xrefSearchSize bytes
- str->setPos(-xrefSearchSize);
+ str->setPos(xrefSearchSize, -1);
for (n = 0; n < xrefSearchSize; ++n) {
if ((c = str->getChar()) == EOF)
break;
@@ -141,7 +147,7 @@ int XRef::readTrailer() {
if (i < 0)
return 0;
for (p = &buf[i+9]; isspace(*p); ++p) ;
- pos = lastXRefPos = atoi(p);
+ pos = lastXRefPos = strToUnsigned(p);
// find trailer dict by looking after first xref table
// (NB: we can't just use the trailer dict at the end of the file --
@@ -176,8 +182,9 @@ int XRef::readTrailer() {
// read trailer dict
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);
if (trailerDict.isDict()) {
trailerDict.dictLookupNF("Size", &obj);
@@ -204,7 +211,7 @@ 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;
Object obj, obj2;
char s[20];
@@ -261,7 +268,7 @@ GBool XRef::readXRef(int *pos) {
newSize = size + 256;
entries = (XRefEntry *)grealloc(entries, newSize * sizeof(XRefEntry));
for (i = size; i < newSize; ++i) {
- entries[i].offset = -1;
+ entries[i].offset = 0xffffffff;
entries[i].used = gFalse;
}
size = newSize;
@@ -273,9 +280,9 @@ GBool XRef::readXRef(int *pos) {
}
s[j] = (char)c;
}
- 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';
entries[i].gen = atoi(&s[11]);
if (s[17] == 'n') {
@@ -293,7 +300,7 @@ GBool XRef::readXRef(int *pos) {
!entries[1].used) {
i = first = 0;
entries[0] = entries[1];
- entries[1].offset = -1;
+ entries[1].offset = 0xffffffff;
}
}
}
@@ -301,8 +308,9 @@ GBool XRef::readXRef(int *pos) {
// read prev pointer from trailer dictionary
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);
if (!obj.isCmd("trailer")) {
goto err1;
@@ -314,7 +322,7 @@ GBool XRef::readXRef(int *pos) {
}
obj.getDict()->lookupNF("Prev", &obj2);
if (obj2.isInt()) {
- *pos = obj2.getInt();
+ *pos = (Guint)obj2.getInt();
more = gTrue;
} else {
more = gFalse;
@@ -337,7 +345,7 @@ GBool XRef::constructXRef() {
Parser *parser;
Object obj;
char buf[256];
- int pos;
+ Guint pos;
int num, gen;
int newSize;
int streamEndsSize;
@@ -360,8 +368,9 @@ GBool XRef::constructXRef() {
// got trailer dictionary
if (!strncmp(p, "trailer", 7)) {
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())
trailerDict.free();
parser->getObj(&trailerDict);
@@ -403,7 +412,7 @@ GBool XRef::constructXRef() {
entries = (XRefEntry *)
grealloc(entries, newSize * sizeof(XRefEntry));
for (i = size; i < newSize; ++i) {
- entries[i].offset = -1;
+ entries[i].offset = 0xffffffff;
entries[i].used = gFalse;
}
size = newSize;
@@ -421,7 +430,8 @@ GBool XRef::constructXRef() {
} else if (!strncmp(p, "endstream", 9)) {
if (streamEndsLen == streamEndsSize) {
streamEndsSize += 64;
- streamEnds = (int *)grealloc(streamEnds, streamEndsSize * sizeof(int));
+ streamEnds = (Guint *)grealloc(streamEnds,
+ streamEndsSize * sizeof(int));
}
streamEnds[streamEndsLen++] = pos;
}
@@ -580,10 +590,11 @@ 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);
parser->getObj(&obj2);
parser->getObj(&obj3);
@@ -618,12 +629,12 @@ Object *XRef::getDocInfoNF(Object *obj) {
return trailerDict.dictLookupNF("Info", obj);
}
-int XRef::getStreamEnd(int streamStart) {
+GBool XRef::getStreamEnd(Guint streamStart, Guint *streamEnd) {
int a, b, m;
if (streamEndsLen == 0 ||
streamStart > streamEnds[streamEndsLen - 1]) {
- return -1;
+ return gFalse;
}
a = -1;
@@ -637,5 +648,18 @@ int XRef::getStreamEnd(int streamStart) {
a = m;
}
}
- 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
@@ -2,7 +2,7 @@
//
// XRef.h
//
-// Copyright 1996 Derek B. Noonburg
+// Copyright 1996-2002 Glyph & Cog, LLC
//
//========================================================================
@@ -24,7 +24,7 @@ class Stream;
//------------------------------------------------------------------------
struct XRefEntry {
- int offset;
+ Guint offset;
int gen;
GBool used;
};
@@ -41,6 +41,9 @@ public:
// Is xref table valid?
GBool isOk() { return ok; }
+ // Get the error code (if isOk() returns false).
+ int getErrorCode() { return errCode; }
+
// Is the file encrypted?
#ifndef NO_DECRYPTION
GBool isEncrypted() { return encrypted; }
@@ -68,28 +71,29 @@ public:
int getNumObjects() { return size; }
// Return the offset of the last xref table.
- int getLastXRefPos() { return lastXRefPos; }
+ Guint getLastXRefPos() { return lastXRefPos; }
// Return the catalog object reference.
int getRootNum() { return rootNum; }
int getRootGen() { return rootGen; }
// 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);
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)
XRefEntry *entries; // xref entries
int size; // size of <entries> array
int rootNum, rootGen; // catalog dict
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
int streamEndsLen; // number of valid entries in streamEnds
#ifndef NO_DECRYPTION
@@ -102,10 +106,11 @@ private:
GBool ownerPasswordOk; // true if owner password is correct
#endif
- int readTrailer();
- GBool readXRef(int *pos);
+ Guint readTrailer();
+ GBool readXRef(Guint *pos);
GBool constructXRef();
GBool checkEncrypted(GString *ownerPassword, GString *userPassword);
+ Guint strToUnsigned(char *s);
};
#endif