summaryrefslogtreecommitdiff
Side-by-side diff
Diffstat (more/less context) (show whitespace changes)
-rw-r--r--noncore/unsupported/qpdf/QOutputDev.h7
-rw-r--r--noncore/unsupported/qpdf/README41
-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.cc94
-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.cc152
-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.cc555
-rw-r--r--noncore/unsupported/qpdf/xpdf/Gfx.h18
-rw-r--r--noncore/unsupported/qpdf/xpdf/GfxFont.cc62
-rw-r--r--noncore/unsupported/qpdf/xpdf/GfxFont.h22
-rw-r--r--noncore/unsupported/qpdf/xpdf/GfxState.cc244
-rw-r--r--noncore/unsupported/qpdf/xpdf/GfxState.h39
-rw-r--r--noncore/unsupported/qpdf/xpdf/GlobalParams.cc229
-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.cc28
-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.cc36
-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.cc67
-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, 2086 insertions, 600 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
@@ -76,12 +76,19 @@ public:
// (Upside-down means (0,0) is the top left corner of the page.)
virtual GBool upsideDown() { return gTrue; }
// 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.
virtual void startPage(int pageNum, GfxState *state);
// End 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,10 +1,10 @@
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.
Changes in 20020406:
- Font substitution handling improved.
- Unknown characters are simply ignored now.
@@ -17,18 +17,25 @@ Changes in 20020407:
Changes in 20020408:
- Progress indicator added
- 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
with a FPU, all doubles have been replaced with a C++ class "fouble" (fixed
double), which operates on 32bit integers with fixed point arithmetic.
This gave a speedup of up to 800% for image rendering.
@@ -49,41 +56,25 @@ ToDo:
in detail.
- Links are currently simply ignored.
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
+ 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 ;)
Robert (griebl@gmx.de)
\ No newline at end of file
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
@@ -19,6 +19,20 @@ static int mapUTF8 ( Unicode u, char *buf, int bufSize )
::memcpy ( buf, utf. data ( ), len );
return len;
}
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
@@ -13,18 +13,18 @@
#include "QPEOutputDev.h"
#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>
#include <qtimer.h>
#include <qfileinfo.h>
#include <qstring.h>
@@ -34,12 +34,18 @@
#include <qdialog.h>
#include <qlabel.h>
#include <qmessagebox.h>
#include "qpdf.h"
+#ifdef QPDF_QPE_ONLY
+#include <qpe/fileselector.h>
+#else
+#include <opie/ofileselector.h>
+#endif
+
int main ( int argc, char **argv )
{
QPEApplication app ( argc, argv );
// read config file
@@ -78,13 +84,18 @@ QPdfDlg::QPdfDlg ( ) : QMainWindow ( )
m_stack-> setSizePolicy ( QSizePolicy ( QSizePolicy::Expanding, QSizePolicy::Expanding ));
setCentralWidget ( m_stack );
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 & )));
m_tb_menu = new QToolBar ( this );
m_tb_menu-> setHorizontalStretchable ( true );
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
@@ -2,18 +2,20 @@
#define __QPDF_H__
#include "aconf.h"
#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;
class QPdfDlg : public QMainWindow {
Q_OBJECT
@@ -65,13 +67,18 @@ protected:
virtual void resizeEvent ( QResizeEvent *e );
virtual void focusInEvent ( QFocusEvent *e );
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;
QPopupMenu *m_pm_zoom;
QToolButton *m_to_find, *m_to_full;
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
@@ -10,13 +10,13 @@ SOURCES = xpdf/Array.cc \
xpdf/Catalog.cc \
xpdf/CharCodeToUnicode.cc \
xpdf/Decrypt.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 \
xpdf/GfxState.cc \
xpdf/GlobalParams.cc \
xpdf/Lexer.cc \
@@ -24,12 +24,13 @@ SOURCES = xpdf/Array.cc \
xpdf/NameToCharCode.cc \
xpdf/Object.cc \
xpdf/OutputDev.cc \
xpdf/PDFDoc.cc \
xpdf/Page.cc \
xpdf/Parser.cc \
+ xpdf/PSTokenizer.cc \
xpdf/Stream.cc \
xpdf/TextOutputDev.cc \
xpdf/UnicodeMap.cc \
xpdf/XRef.cc \
goo/GHash.cc \
goo/GString.cc \
@@ -49,12 +50,12 @@ INCLUDEPATH += . \
.. \
xpdf \
$(OPIEDIR)/include \
../goo \
goo
-LIBS += -L $(OPIEDIR)/lib -lqpe
+LIBS += -L $(OPIEDIR)/lib -lqpe -lopie
DESTDIR = $(OPIEDIR)/bin
TARGET = qpdf
TRANSLATIONS = ../../i18n/de/qpdf.ts
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,29 +1,29 @@
//========================================================================
//
-// FormWidget.cc
+// Annot.cc
//
-// Copyright 2000 Derek B. Noonburg
+// Copyright 2000-2002 Glyph & Cog, LLC
//
//========================================================================
#ifdef __GNUC__
#pragma implementation
#endif
#include <aconf.h>
#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;
ok = gFalse;
xref = xrefA;
@@ -74,66 +74,65 @@ FormWidget::FormWidget(XRef *xrefA, Dict *dict) {
xMin = yMin = 0;
xMax = yMax = 1;
}
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();
}
obj1.free();
}
}
}
-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,67 +1,69 @@
//========================================================================
//
-// 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);
// Get appearance object.
Object *getAppearance(Object *obj) { return appearance.fetch(xref, obj); }
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
@@ -1,11 +1,11 @@
//========================================================================
//
// Array.cc
//
-// Copyright 1996 Derek B. Noonburg
+// Copyright 1996-2002 Glyph & Cog, LLC
//
//========================================================================
#ifdef __GNUC__
#pragma implementation
#endif
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
@@ -1,11 +1,11 @@
//========================================================================
//
// Array.h
//
-// Copyright 1996 Derek B. Noonburg
+// Copyright 1996-2002 Glyph & Cog, LLC
//
//========================================================================
#ifndef ARRAY_H
#define ARRAY_H
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
@@ -1,11 +1,11 @@
//========================================================================
//
// BuiltinFont.h
//
-// Copyright 2001 Derek B. Noonburg
+// Copyright 2001-2002 Glyph & Cog, LLC
//
//========================================================================
#ifndef BUILTINFONT_H
#define BUILTINFONT_H
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
@@ -1,11 +1,11 @@
//========================================================================
//
// BuiltinFontTables.cc
//
-// Copyright 2001 Derek B. Noonburg
+// Copyright 2001-2002 Glyph & Cog, LLC
//
//========================================================================
#include <aconf.h>
#include <stdlib.h>
#include "FontEncodingTables.h"
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
@@ -1,11 +1,11 @@
//========================================================================
//
// BuiltinFontTables.h
//
-// Copyright 2001 Derek B. Noonburg
+// Copyright 2001-2002 Glyph & Cog, LLC
//
//========================================================================
#ifndef BUILTINFONTTABLES_H
#define BUILTINFONTTABLES_H
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
@@ -1,11 +1,11 @@
//========================================================================
//
// CMap.cc
//
-// Copyright 2001 Derek B. Noonburg
+// Copyright 2001-2002 Glyph & Cog, LLC
//
//========================================================================
#ifdef __GNUC__
#pragma implementation
#endif
@@ -17,12 +17,13 @@
#include <ctype.h>
#include "gmem.h"
#include "gfile.h"
#include "GString.h"
#include "Error.h"
#include "GlobalParams.h"
+#include "PSTokenizer.h"
#include "CMap.h"
//------------------------------------------------------------------------
struct CMapVectorEntry {
GBool isVector;
@@ -31,21 +32,26 @@ struct CMapVectorEntry {
CID cid;
};
};
//------------------------------------------------------------------------
+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))) {
// Check for an identity CMap.
if (!cMapNameA->cmp("Identity") || !cMapNameA->cmp("Identity-H")) {
return new CMap(collectionA->copy(), cMapNameA->copy(), 0);
@@ -58,56 +64,70 @@ CMap *CMap::parse(CMapCache *cache, GString *collectionA,
cMapNameA->getCString(), collectionA->getCString());
return NULL;
}
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;
+ 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);
}
- tok2 = strtok(NULL, " \t\r\n");
- tok3 = strtok(NULL, " \t\r\n");
- if (inCodeSpace) {
+ pst->getToken(tok1, sizeof(tok1), &n1);
+ } else if (!strcmp(tok1, "/WMode")) {
+ cmap->wMode = atoi(tok2);
+ pst->getToken(tok1, sizeof(tok1), &n1);
+ } else if (!strcmp(tok2, "begincodespacerange")) {
+ while (pst->getToken(tok1, sizeof(tok1), &n1)) {
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';
+ 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);
- n = (n - 2) / 2;
- cmap->addCodeSpace(cmap->vector, start, end, n);
+ n1 = (n1 - 2) / 2;
+ cmap->addCodeSpace(cmap->vector, start, end, n1);
}
- } else if (inCIDRange) {
+ }
+ pst->getToken(tok1, sizeof(tok1), &n1);
+ } else if (!strcmp(tok2, "begincidrange")) {
+ while (pst->getToken(tok1, sizeof(tok1), &n1)) {
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';
+ 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);
- n = (n - 2) / 2;
- cmap->addCIDs(start, end, n, (CID)atoi(tok3));
+ n1 = (n1 - 2) / 2;
+ cmap->addCIDs(start, end, n1, (CID)atoi(tok3));
}
- } else if (tok2 && !strcmp(tok2, "usecmap")) {
- if (tok1[0] == '/') {
- cmap->useCMap(cache, tok1 + 1);
}
- } 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 {
+ strcpy(tok1, tok2);
}
}
+ delete pst;
fclose(f);
return cmap;
}
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
@@ -1,11 +1,11 @@
//========================================================================
//
// CMap.h
//
-// Copyright 2001 Derek B. Noonburg
+// Copyright 2001-2002 Glyph & Cog, LLC
//
//========================================================================
#ifndef CMAP_H
#define CMAP_H
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
@@ -1,11 +1,11 @@
//========================================================================
//
// Catalog.cc
//
-// Copyright 1996 Derek B. Noonburg
+// Copyright 1996-2002 Glyph & Cog, LLC
//
//========================================================================
#ifdef __GNUC__
#pragma implementation
#endif
@@ -143,13 +143,13 @@ GString *Catalog::readMetadata() {
if (!metadata.isStream()) {
return NULL;
}
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();
s = new GString();
metadata.streamReset();
while ((c = metadata.streamGetChar()) != EOF) {
@@ -262,16 +262,16 @@ LinkDest *Catalog::findDest(GString *name) {
if (!found)
return NULL;
// 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();
} else {
error(-1, "Bad named destination value");
}
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
@@ -1,11 +1,11 @@
//========================================================================
//
// Catalog.h
//
-// Copyright 1996 Derek B. Noonburg
+// Copyright 1996-2002 Glyph & Cog, LLC
//
//========================================================================
#ifndef CATALOG_H
#define CATALOG_H
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
@@ -1,11 +1,11 @@
//========================================================================
//
// CharCodeToUnicode.cc
//
-// Copyright 2001 Derek B. Noonburg
+// Copyright 2001-2002 Glyph & Cog, LLC
//
//========================================================================
#ifdef __GNUC__
#pragma implementation
#endif
@@ -15,12 +15,13 @@
#include <string.h>
#include "gmem.h"
#include "gfile.h"
#include "GString.h"
#include "Error.h"
#include "GlobalParams.h"
+#include "PSTokenizer.h"
#include "CharCodeToUnicode.h"
//------------------------------------------------------------------------
#define maxUnicodeString 8
@@ -29,12 +30,32 @@ struct CharCodeToUnicodeString {
Unicode u[maxUnicodeString];
int len;
};
//------------------------------------------------------------------------
+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;
CharCode size, mapLenA;
char buf[64];
Unicode u;
@@ -72,98 +93,83 @@ CharCodeToUnicode *CharCodeToUnicode::parseCIDToUnicode(GString *collectionA) {
}
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;
Unicode u;
char uHex[5];
int j;
GString *name;
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;
+ 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());
}
- tok2 = strtok(NULL, " \t\r\n");
- tok3 = strtok(NULL, " \t\r\n");
- if (inBFChar) {
+ delete name;
+ }
+ pst->getToken(tok1, sizeof(tok1), &n1);
+ } else if (!strcmp(tok2, "beginbfchar")) {
+ while (pst->getToken(tok1, sizeof(tok1), &n1)) {
if (!strcmp(tok1, "endbfchar")) {
- inBFChar = gFalse;
- } else if (tok2) {
- n1 = strlen(tok1);
- n2 = strlen(tok2);
+ 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) {
oldLen = mapLen;
mapLen = (code1 + 256) & ~255;
map = (Unicode *)grealloc(map, mapLen * sizeof(Unicode));
for (i = oldLen; i < mapLen; ++i) {
map[i] = 0;
}
}
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;
} else {
map[code1] = 0;
if (sMapLen == sMapSize) {
@@ -174,50 +180,54 @@ void CharCodeToUnicode::parseCMap1(char *(*getLineFunc)(char *, int, void *),
sMap[sMapLen].c = code1;
sMap[sMapLen].len = (n2 - 2) / 4;
for (j = 0; j < sMap[sMapLen].len && j < maxUnicodeString; ++j) {
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) {
+ pst->getToken(tok1, sizeof(tok1), &n1);
+ } else if (!strcmp(tok2, "beginbfrange")) {
+ while (pst->getToken(tok1, sizeof(tok1), &n1)) {
if (!strcmp(tok1, "endbfrange")) {
- inBFRange = gFalse;
- } else if (tok2 && tok3) {
- n1 = strlen(tok1);
- n2 = strlen(tok2);
- n3 = strlen(tok3);
+ 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) {
oldLen = mapLen;
mapLen = (code2 + 256) & ~255;
map = (Unicode *)grealloc(map, mapLen * sizeof(Unicode));
for (i = oldLen; i < mapLen; ++i) {
map[i] = 0;
}
}
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) {
map[code1] = u++;
}
} else {
@@ -231,40 +241,26 @@ void CharCodeToUnicode::parseCMap1(char *(*getLineFunc)(char *, int, void *),
sMap[sMapLen].c = code1;
sMap[sMapLen].len = (n3 - 2) / 4;
for (j = 0; j < sMap[sMapLen].len && j < maxUnicodeString; ++j) {
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);
+ pst->getToken(tok1, sizeof(tok1), &n1);
} 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;
+ strcpy(tok1, tok2);
}
}
+ delete pst;
}
CharCodeToUnicode::CharCodeToUnicode(GString *collectionA) {
CharCode i;
collection = 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
@@ -1,13 +1,13 @@
//========================================================================
//
// CharCodeToUnicode.h
//
// Mapping from character codes to Unicode.
//
-// Copyright 2001 Derek B. Noonburg
+// Copyright 2001-2002 Glyph & Cog, LLC
//
//========================================================================
#ifndef CHARCODETOUNICODE_H
#define CHARCODETOUNICODE_H
@@ -47,14 +47,13 @@ public:
// Map a CharCode to Unicode.
int mapToUnicode(CharCode c, Unicode *u, int size);
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,
CharCodeToUnicodeString *sMapA, int sMapLenA);
GString *collection;
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
@@ -1,11 +1,11 @@
//========================================================================
//
// CharTypes.h
//
-// Copyright 2001 Derek B. Noonburg
+// Copyright 2001-2002 Glyph & Cog, LLC
//
//========================================================================
#ifndef CHARTYPES_H
#define CHARTYPES_H
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
@@ -1,11 +1,11 @@
//========================================================================
//
// Decrypt.cc
//
-// Copyright 1996 Derek B. Noonburg
+// Copyright 1996-2002 Glyph & Cog, LLC
//
//========================================================================
#ifdef __GNUC__
#pragma implementation
#endif
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
@@ -1,11 +1,11 @@
//========================================================================
//
// Decrypt.h
//
-// Copyright 1996 Derek B. Noonburg
+// Copyright 1996-2002 Glyph & Cog, LLC
//
//========================================================================
#ifndef DECRYPT_H
#define DECRYPT_H
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
@@ -1,11 +1,11 @@
//========================================================================
//
// Dict.cc
//
-// Copyright 1996 Derek B. Noonburg
+// Copyright 1996-2002 Glyph & Cog, LLC
//
//========================================================================
#ifdef __GNUC__
#pragma implementation
#endif
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
@@ -1,11 +1,11 @@
//========================================================================
//
// Dict.h
//
-// Copyright 1996 Derek B. Noonburg
+// Copyright 1996-2002 Glyph & Cog, LLC
//
//========================================================================
#ifndef DICT_H
#define DICT_H
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
@@ -1,20 +1,20 @@
//========================================================================
//
// DisplayFontTable.h
//
-// Copyright 2001 Derek B. Noonburg
+// Copyright 2001-2002 Glyph & Cog, LLC
//
//========================================================================
static struct {
char *name;
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"},
{"Courier-Oblique", "-*-courier-medium-o-normal-*-%s-*-*-*-*-*-iso8859-1", "Latin1"},
{"Helvetica", "-*-helvetica-medium-r-normal-*-%s-*-*-*-*-*-iso8859-1", "Latin1"},
{"Helvetica-Bold", "-*-helvetica-bold-r-normal-*-%s-*-*-*-*-*-iso8859-1", "Latin1"},
@@ -24,8 +24,8 @@ static struct {
{"Times-Bold", "-*-times-bold-r-normal-*-%s-*-*-*-*-*-iso8859-1", "Latin1"},
{"Times-BoldItalic", "-*-times-bold-i-normal-*-%s-*-*-*-*-*-iso8859-1", "Latin1"},
{"Times-Italic", "-*-times-medium-i-normal-*-%s-*-*-*-*-*-iso8859-1", "Latin1"},
{"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
@@ -1,11 +1,11 @@
//========================================================================
//
// Error.cc
//
-// Copyright 1996 Derek B. Noonburg
+// Copyright 1996-2002 Glyph & Cog, LLC
//
//========================================================================
#ifdef __GNUC__
#pragma implementation
#endif
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
@@ -1,11 +1,11 @@
//========================================================================
//
// Error.h
//
-// Copyright 1996 Derek B. Noonburg
+// Copyright 1996-2002 Glyph & Cog, LLC
//
//========================================================================
#ifndef ERROR_H
#define ERROR_H
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
@@ -1,11 +1,11 @@
//========================================================================
//
// FontEncodingTables.cc
//
-// Copyright 2001 Derek B. Noonburg
+// Copyright 2001-2002 Glyph & Cog, LLC
//
//========================================================================
#include <aconf.h>
#include <stdlib.h>
#include "FontEncodingTables.h"
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
@@ -1,11 +1,11 @@
//========================================================================
//
// FontEncodingTables.h
//
-// Copyright 2001 Derek B. Noonburg
+// Copyright 2001-2002 Glyph & Cog, LLC
//
//========================================================================
#ifndef FONTENCODINGTABLES_H
#define FONTENCODINGTABLES_H
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
@@ -1,11 +1,11 @@
//========================================================================
//
// Function.cc
//
-// Copyright 2001 Derek B. Noonburg
+// Copyright 2001-2002 Glyph & Cog, LLC
//
//========================================================================
#ifdef __GNUC__
#pragma implementation
#endif
@@ -412,33 +412,34 @@ void SampledFunction::transform(fouble *in, fouble *out) {
ExponentialFunction::ExponentialFunction(Object *funcObj, Dict *dict) {
Object obj1, obj2;
GBool hasN;
int i;
ok = gFalse;
- hasN = gFalse;
//----- initialize the generic stuff
if (!init(dict)) {
goto err1;
}
if (m != 1) {
error(-1, "Exponential function with more than one input");
goto err1;
}
+ hasN = hasRange;
//----- default values
for (i = 0; i < funcMaxOutputs; ++i) {
c0[i] = 0;
c1[i] = 1;
}
//----- C0
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;
}
for (i = 0; i < n; ++i) {
obj1.arrayGet(i, &obj2);
@@ -453,12 +454,13 @@ ExponentialFunction::ExponentialFunction(Object *funcObj, Dict *dict) {
obj1.free();
//----- C1
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;
}
for (i = 0; i < n; ++i) {
obj1.arrayGet(i, &obj2);
@@ -477,12 +479,19 @@ ExponentialFunction::ExponentialFunction(Object *funcObj, Dict *dict) {
error(-1, "Function has missing or invalid N");
goto err2;
}
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;
err3:
obj2.free();
err2:
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
@@ -1,11 +1,11 @@
//========================================================================
//
// Function.h
//
-// Copyright 2001 Derek B. Noonburg
+// Copyright 2001-2002 Glyph & Cog, LLC
//
//========================================================================
#ifndef FUNCTION_H
#define FUNCTION_H
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
@@ -1,11 +1,11 @@
//========================================================================
//
// Gfx.cc
//
-// Copyright 1996 Derek B. Noonburg
+// Copyright 1996-2002 Glyph & Cog, LLC
//
//========================================================================
#ifdef __GNUC__
#pragma implementation
#endif
@@ -27,22 +27,33 @@
#include "GfxState.h"
#include "OutputDev.h"
#include "Page.h"
#include "Error.h"
#include "Gfx.h"
+// the MSVC math.h doesn't define this
+#ifndef M_PI
+#define M_PI 3.14159265358979323846
+#endif
+
//------------------------------------------------------------------------
// constants
//------------------------------------------------------------------------
// Max number of splits along the t axis for an axial shading fill.
#define axialMaxSplits 256
// 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
//------------------------------------------------------------------------
Operator Gfx::opTab[] = {
{"\"", 3, {tchkNum, tchkNum, tchkString},
@@ -371,12 +382,13 @@ GBool GfxResources::lookupGState(char *name, Object *obj) {
Gfx::Gfx(XRef *xrefA, OutputDev *outA, int pageNum, Dict *resDict, fouble dpi,
PDFRectangle *box, GBool crop, PDFRectangle *cropBox, int rotate,
GBool printCommandsA) {
int i;
xref = xrefA;
+ subPage = gFalse;
printCommands = printCommandsA;
// start the resource stack
res = new GfxResources(xref, resDict, NULL);
// initialize
@@ -402,28 +414,61 @@ Gfx::Gfx(XRef *xrefA, OutputDev *outA, int pageNum, Dict *resDict, fouble dpi,
state->clip();
out->clip(state);
state->clearPath();
}
}
-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);
}
+ 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) {
Object obj2;
int i;
if (obj->isArray()) {
@@ -446,17 +491,17 @@ void Gfx::display(Object *obj, GBool topLevel) {
parser = NULL;
}
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()) {
// got a command - execute it
if (obj.isCmd()) {
@@ -473,15 +518,15 @@ void Gfx::go(GBool topLevel) {
obj.free();
for (i = 0; i < numArgs; ++i)
args[i].free();
numArgs = 0;
// periodically update display
- if (++numCmds == 200) {
+ if (++updateLevel >= 20000) {
out->dump();
- numCmds = 0;
+ updateLevel = 0;
}
// got an argument - save it
} else if (numArgs < maxArgs) {
args[numArgs++] = obj;
@@ -516,13 +561,13 @@ void Gfx::go(GBool topLevel) {
}
for (i = 0; i < numArgs; ++i)
args[i].free();
}
// update display
- if (topLevel && numCmds > 0) {
+ if (topLevel && updateLevel > 0) {
out->dump();
}
}
void Gfx::execOp(Object *cmd, Object args[], int numArgs) {
Operator *op;
@@ -1135,13 +1180,13 @@ void Gfx::doPatternFill(GBool eoFill) {
GfxTilingPattern *tPat;
GfxColorSpace *cs;
fouble xMin, yMin, xMax, yMax, x, y, x1, y1;
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;
// this is a bit of a kludge -- patterns can be really slow, so we
// skip them if we're only doing text extraction, since they almost
@@ -1186,21 +1231,12 @@ void Gfx::doPatternFill(GBool eoFill) {
m[1] = m1[0] * ictm[1] + m1[1] * ictm[3];
m[2] = m1[2] * ictm[0] + m1[3] * ictm[2];
m[3] = m1[2] * ictm[1] + m1[3] * ictm[3];
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;
imb[1] = -m1[1] * det;
imb[2] = -m1[2] * det;
imb[3] = m1[0] * det;
@@ -1328,86 +1364,40 @@ void Gfx::opShFill(Object args[], int numArgs) {
// do shading type-specific operations
switch (shading->getType()) {
case 2:
doAxialShFill((GfxAxialShading *)shading);
break;
+ case 3:
+ doRadialShFill((GfxRadialShading *)shading);
+ break;
}
// restore graphics state
state = state->restore();
out->restoreState(state);
delete shading;
}
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;
fouble ux0, uy0, ux1, uy1, vx0, vy0, vx1, vy1;
fouble t0, t1, tt;
fouble ta[axialMaxSplits + 1];
int next[axialMaxSplits + 1];
GfxColor color0, color1;
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
shading->getCoords(&x0, &y0, &x1, &y1);
dx = x1 - x0;
dy = y1 - y0;
@@ -1616,12 +1606,208 @@ void Gfx::doAxialShFill(GfxAxialShading *shading) {
vy0 = vy1;
color0 = color1;
i = next[i];
}
}
+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();
if (clip == clipNormal) {
out->clip(state);
} else {
@@ -1797,60 +1983,68 @@ void Gfx::opMoveSetShowText(Object args[], int numArgs) {
doShowText(args[2].getString());
}
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());
} else {
error(getPos(), "Element of show/space array must be number or string");
}
obj.free();
}
}
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];
}
mat = state->getTextMat();
newCTM[0] = mat[0] * oldCTM[0] + mat[1] * oldCTM[2];
@@ -1864,77 +2058,93 @@ void Gfx::doShowText(GString *s) {
newCTM[3] = mat[2] * newCTM[1] + mat[3] * newCTM[3];
newCTM[0] *= state->getFontSize();
newCTM[3] *= state->getFontSize();
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();
while (len > 0) {
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);
+ dx = dx * state->getFontSize() + state->getCharSpace();
+ if (n == 1 && *p == ' ') {
+ dx += state->getWordSpace();
+ }
+ dx *= state->getHorizScaling();
+ dy *= state->getFontSize();
+ state->textTransformDelta(dx, dy, &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");
}
- state = state->restore();
- out->restoreState(state);
+ out->endType3Char(state);
+ if (resDict) {
+ popResources();
+ }
charProc.free();
- dx = dx * state->getFontSize() + state->getCharSpace();
- if (n == 1 && *p == ' ') {
- dx += state->getWordSpace();
}
- dx *= state->getHorizScaling();
- dy *= state->getFontSize();
- state->textTransformDelta(dx, dy, &tdx, &tdy);
- state->shift(tdx, tdy);
+ 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);
+ 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();
+ }
state->textTransformDelta(dx, dy, &tdx, &tdy);
originX *= state->getFontSize();
originY *= state->getFontSize();
state->textTransformDelta(originX, originY, &tOriginX, &tOriginY);
out->drawChar(state, state->getCurX() + riseX, state->getCurY() + riseY,
tdx, tdy, tOriginX, tOriginY, code, u, uLen);
state->shift(tdx, tdy);
p += n;
len -= n;
}
- out->endString(state);
} else {
dx = dy = 0;
p = s->getCString();
len = s->getLength();
nChars = nSpaces = 0;
@@ -1948,29 +2158,42 @@ void Gfx::doShowText(GString *s) {
++nSpaces;
}
++nChars;
p += n;
len -= n;
}
+ if (wMode) {
+ dx *= state->getFontSize();
+ dy = dy * state->getFontSize()
+ + nChars * state->getCharSpace()
+ + nSpaces * state->getWordSpace();
+ } else {
dx = dx * state->getFontSize()
+ nChars * state->getCharSpace()
+ nSpaces * state->getWordSpace();
dx *= state->getHorizScaling();
dy *= state->getFontSize();
+ }
state->textTransformDelta(dx, dy, &tdx, &tdy);
out->drawString(state, s);
state->shift(tdx, tdy);
}
+
+ if (out->useDrawChar()) {
+ out->endString(state);
+ }
+
+ updateLevel += 10 * s->getLength();
}
//------------------------------------------------------------------------
// XObject operators
//------------------------------------------------------------------------
void Gfx::opXObject(Object args[], int numArgs) {
- Object obj1, obj2, refObj;
+ Object obj1, obj2, obj3, refObj;
#if OPI_SUPPORT
Object opiDict;
#endif
if (!res->lookupXObject(args[0].getName(), &obj1)) {
return;
@@ -1990,12 +2213,16 @@ void Gfx::opXObject(Object args[], int numArgs) {
if (obj2.isName("Image")) {
res->lookupXObjectNF(args[0].getName(), &refObj);
doImage(&refObj, obj1.getStream(), gFalse);
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 {
error(getPos(), "XObject subtype is missing or wrong type");
}
obj2.free();
@@ -2145,12 +2372,17 @@ void Gfx::doImage(Object *ref, Stream *str, GBool inlineImg) {
haveMask ? maskColors : (int *)NULL, inlineImg);
delete colorMap;
maskObj.free();
}
+ if ((i = width * height) > 1000) {
+ i = 1000;
+ }
+ updateLevel += i;
+
return;
err2:
obj1.free();
err1:
error(getPos(), "Bad image parameters");
@@ -2212,25 +2444,28 @@ void Gfx::doForm(Object *str) {
// draw it
doForm1(str, resDict, m, bbox);
resObj.free();
}
-void Gfx::doWidgetForm(Object *str, fouble xMin, fouble yMin,
+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();
error(getPos(), "Bad form bounding box");
return;
}
@@ -2238,13 +2473,13 @@ void Gfx::doWidgetForm(Object *str, fouble xMin, fouble yMin,
bboxObj.arrayGet(i, &obj1);
bbox[i] = obj1.getNum();
obj1.free();
}
bboxObj.free();
- // get matrix
+ // get the form matrix
dict->lookup("Matrix", &matrixObj);
if (matrixObj.isArray()) {
for (i = 0; i < 6; ++i) {
matrixObj.arrayGet(i, &obj1);
m[i] = obj1.getNum();
obj1.free();
@@ -2253,22 +2488,70 @@ void Gfx::doWidgetForm(Object *str, fouble xMin, fouble yMin,
m[0] = 1; m[1] = 0;
m[2] = 0; m[3] = 1;
m[4] = 0; m[5] = 0;
}
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];
- // translate to widget rectangle
- m[4] += xMin;
- m[5] += yMin;
+ // 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;
+ }
+
+ // 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);
resDict = resObj.isDict() ? resObj.getDict() : (Dict *)NULL;
// draw it
@@ -2278,17 +2561,16 @@ void Gfx::doWidgetForm(Object *str, fouble xMin, fouble yMin,
bboxObj.free();
}
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);
state = state->save();
// save current parser
@@ -2329,17 +2611,27 @@ void Gfx::doForm1(Object *str, Dict *resDict, fouble *matrix, fouble *bbox) {
// restore graphics state
state = state->restore();
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;
}
//------------------------------------------------------------------------
// in-line image operators
//------------------------------------------------------------------------
@@ -2375,26 +2667,31 @@ Stream *Gfx::buildImageStream() {
dict.initDict(xref);
parser->getObj(&obj);
while (!obj.isCmd("ID") && !obj.isEOF()) {
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
str = new EmbedStream(parser->getStream(), &dict);
str = str->addFilters(&dict);
return str;
@@ -2410,17 +2707,19 @@ void Gfx::opEndImage(Object args[], int numArgs) {
//------------------------------------------------------------------------
// type 3 font operators
//------------------------------------------------------------------------
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());
}
//------------------------------------------------------------------------
// compatibility operators
//------------------------------------------------------------------------
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
@@ -1,11 +1,11 @@
//========================================================================
//
// Gfx.h
//
-// Copyright 1996 Derek B. Noonburg
+// Copyright 1996-2002 Glyph & Cog, LLC
//
//========================================================================
#ifndef GFX_H
#define GFX_H
@@ -24,12 +24,13 @@ class Dict;
class OutputDev;
class GfxFontDict;
class GfxFont;
class GfxPattern;
class GfxShading;
class GfxAxialShading;
+class GfxRadialShading;
class GfxState;
class Gfx;
struct PDFRectangle;
//------------------------------------------------------------------------
// Gfx
@@ -94,27 +95,37 @@ public:
// Constructor for regular output.
Gfx(XRef *xrefA, OutputDev *outA, int pageNum, Dict *resDict, fouble dpi,
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,
+ // 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
GfxClipType clip; // do a clip?
int ignoreUndef; // current BX/EX nesting level
fouble baseMatrix[6]; // default matrix for most recent
@@ -176,12 +187,13 @@ private:
void opCloseFillStroke(Object args[], int numArgs);
void opEOFillStroke(Object args[], int numArgs);
void opCloseEOFillStroke(Object args[], int numArgs);
void doPatternFill(GBool eoFill);
void opShFill(Object args[], int numArgs);
void doAxialShFill(GfxAxialShading *shading);
+ void doRadialShFill(GfxRadialShading *shading);
void doEndPath();
// path clipping operators
void opClip(Object args[], int numArgs);
void opEOClip(Object args[], int numArgs);
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
@@ -1,11 +1,11 @@
//========================================================================
//
// GfxFont.cc
//
-// Copyright 1996-2001 Derek B. Noonburg
+// Copyright 1996-2002 Glyph & Cog, LLC
//
//========================================================================
#ifdef __GNUC__
#pragma implementation
#endif
@@ -451,19 +451,30 @@ Gfx8BitFont::Gfx8BitFont(XRef *xref, char *tagA, Ref idA, GString *nameA,
}
obj2.free();
}
}
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 -----
// Encodings start with a base encoding, which can come from
// (in order of priority):
@@ -510,29 +521,34 @@ Gfx8BitFont::Gfx8BitFont(XRef *xref, char *tagA, Ref idA, GString *nameA,
} else if (obj1.isName("StandardEncoding")) {
hasEncoding = gTrue;
baseEnc = standardEncoding;
}
// 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);
} else {
buf = readEmbFontFile(xref, &len);
}
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) {
delete embFontName;
}
embFontName = new GString(fontFile->getName());
@@ -566,12 +582,13 @@ Gfx8BitFont::Gfx8BitFont(XRef *xref, char *tagA, Ref idA, GString *nameA,
}
// merge differences into encoding
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);
if (obj3.isInt()) {
code = obj3.getInt();
} else if (obj3.isName()) {
@@ -633,14 +650,15 @@ Gfx8BitFont::Gfx8BitFont(XRef *xref, char *tagA, Ref idA, GString *nameA,
} else {
toUnicode[code] = 0;
}
}
// 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] &&
strcmp(charName, ".notdef")) {
n = strlen(charName);
code2 = -1;
@@ -653,12 +671,15 @@ Gfx8BitFont::Gfx8BitFont(XRef *xref, char *tagA, Ref idA, GString *nameA,
} else if (!hex && n >= 2 && n <= 4 &&
isdigit(charName[0]) && isdigit(charName[1])) {
code2 = atoi(charName);
} 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;
}
}
}
@@ -681,16 +702,20 @@ Gfx8BitFont::Gfx8BitFont(XRef *xref, char *tagA, Ref idA, GString *nameA,
fontDict->lookup("LastChar", &obj1);
lastChar = obj1.isInt() ? obj1.getInt() : 255;
obj1.free();
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();
}
// use widths from built-in font
} else if (builtinFont) {
@@ -749,12 +774,15 @@ Gfx8BitFont::~Gfx8BitFont() {
}
}
ctu->decRefCnt();
if (charProcs.isDict()) {
charProcs.free();
}
+ if (resources.isDict()) {
+ resources.free();
+ }
}
int Gfx8BitFont::getNextChar(char *s, int len, CharCode *code,
Unicode *u, int uSize, int *uLen,
fouble *dx, fouble *dy, fouble *ox, fouble *oy) {
CharCode c;
@@ -768,21 +796,29 @@ int Gfx8BitFont::getNextChar(char *s, int len, CharCode *code,
CharCodeToUnicode *Gfx8BitFont::getToUnicode() {
ctu->incRefCnt();
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);
} else {
proc->initNull();
}
return proc;
}
+Dict *Gfx8BitFont::getResources() {
+ return resources.isDict() ? resources.getDict() : (Dict *)NULL;
+}
+
//------------------------------------------------------------------------
// GfxCIDFont
//------------------------------------------------------------------------
static int cmpWidthExcep(const void *w1, const void *w2) {
return ((GfxFontCIDWidthExcep *)w1)->first -
@@ -1183,12 +1219,16 @@ int GfxCIDFont::getNextChar(char *s, int len, CharCode *code,
*ox = vx;
*oy = vy;
return n;
}
+int GfxCIDFont::getWMode() {
+ return cMap ? cMap->getWMode() : 0;
+}
+
CharCodeToUnicode *GfxCIDFont::getToUnicode() {
ctu->incRefCnt();
return ctu;
}
GString *GfxCIDFont::getCollection() {
@@ -1213,13 +1253,13 @@ GfxFontDict::GfxFontDict(XRef *xref, Dict *fontDict) {
obj1.getRef(), obj2.getDict());
if (fonts[i] && !fonts[i]->isOk()) {
delete fonts[i];
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();
obj2.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
@@ -1,11 +1,11 @@
//========================================================================
//
// GfxFont.h
//
-// Copyright 1996-2001 Derek B. Noonburg
+// Copyright 1996-2002 Glyph & Cog, LLC
//
//========================================================================
#ifndef GFXFONT_H
#define GFXFONT_H
@@ -110,14 +110,13 @@ public:
// Returns false if there is no embedded font.
GBool getEmbeddedFontID(Ref *embID)
{ *embID = embFontID; return embFontID.num >= 0; }
// 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.
GString *getExtFontFile() { return extFontFile; }
// Get font descriptor flags.
@@ -134,12 +133,15 @@ public:
fouble *getFontBBox() { return fontBBox; }
// Return the ascent and descent values.
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);
// Get the next char from a string <s> of <len> bytes, returning the
// char <code>, its Unicode mapping <u>, its displacement vector
@@ -152,24 +154,24 @@ public:
fouble *dx, fouble *dy, fouble *ox, fouble *oy) = 0;
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)
GString *name; // font name
GfxFontType type; // type of font
int flags; // font descriptor flags
GString *embFontName; // name of embedded font
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
GBool ok;
};
@@ -201,24 +203,31 @@ public:
// Returns true if the PDF font specified an encoding.
GBool getHasEncoding() { return hasEncoding; }
// 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
char encFree[256]; // boolean for each char name: if set,
// the string is malloc'ed
CharCodeToUnicode *ctu; // char code --> Unicode
GBool hasEncoding;
fouble widths[256]; // character widths
Object charProcs; // Type3 CharProcs dictionary
+ Object resources; // Type 3 Resources dictionary
};
//------------------------------------------------------------------------
// GfxCIDFont
//------------------------------------------------------------------------
@@ -233,12 +242,15 @@ public:
virtual GBool isCIDFont() { return gTrue; }
virtual int getNextChar(char *s, int len, CharCode *code,
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();
// Get the collection name (<registry>-<ordering>).
GString *getCollection();
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
@@ -1,11 +1,11 @@
//========================================================================
//
// GfxState.cc
//
-// Copyright 1996 Derek B. Noonburg
+// Copyright 1996-2002 Glyph & Cog, LLC
//
//========================================================================
#ifdef __GNUC__
#pragma implementation
#endif
@@ -405,15 +405,28 @@ void GfxDeviceCMYKColorSpace::getGray(GfxColor *color, fouble *gray) {
- 0.299 * color->c[0]
- 0.587 * color->c[1]
- 0.114 * color->c[2]);
}
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) {
cmyk->c = clip01(color->c[0]);
cmyk->m = clip01(color->c[1]);
cmyk->y = clip01(color->c[2]);
@@ -1265,16 +1278,12 @@ GfxShading *GfxShading::parse(Object *obj) {
error(-1, "Invalid ShadingType in shading dictionary");
obj1.free();
goto err1;
}
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))) {
error(-1, "Bad color space in shading dictionary");
obj1.free();
goto err1;
@@ -1314,13 +1323,23 @@ GfxShading *GfxShading::parse(Object *obj) {
} else {
error(-1, "Bad BBox in shading dictionary");
}
}
obj1.free();
+ 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;
shading->colorSpace = colorSpaceA;
shading->background = backgroundA;
shading->hasBackground = hasBackgroundA;
@@ -1454,12 +1473,134 @@ void GfxAxialShading::getColor(fouble t, GfxColor *color) {
for (i = 0; i < nFuncs; ++i) {
funcs[i]->transform(&t, &color->c[i]);
}
}
//------------------------------------------------------------------------
+// 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
//------------------------------------------------------------------------
GfxImageColorMap::GfxImageColorMap(int bitsA, Object *decode,
GfxColorSpace *colorSpaceA) {
GfxIndexedColorSpace *indexedCS;
@@ -1915,12 +2056,73 @@ GfxState::GfxState(GfxState *state) {
lineDash = (fouble *)gmalloc(lineDashLength * sizeof(fouble));
memcpy(lineDash, state->lineDash, lineDashLength * sizeof(fouble));
}
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;
x = ctm[0] + ctm[2];
y = ctm[1] + ctm[3];
return w * sqrt(0.5 * (x * x + y * y));
@@ -1943,33 +2145,54 @@ void GfxState::getFontTransMat(fouble *m11, fouble *m12,
*m21 = (textMat[2] * ctm[0] + textMat[3] * ctm[2]) * fontSize;
*m22 = (textMat[2] * ctm[1] + textMat[3] * ctm[3]) * fontSize;
}
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,
fouble d, fouble e, fouble f) {
fouble a1 = ctm[0];
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;
ctm[2] = c * a1 + d * c1;
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) {
if (fillColorSpace) {
delete fillColorSpace;
}
@@ -2048,16 +2271,16 @@ void GfxState::clip() {
}
if (yMax < clipYMax) {
clipYMax = yMax;
}
}
-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;
}
void GfxState::shift(fouble dx, fouble dy) {
curX += dx;
@@ -2092,6 +2315,7 @@ GfxState *GfxState::restore() {
} else {
oldState = this;
}
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
@@ -1,11 +1,11 @@
//========================================================================
//
// GfxState.h
//
-// Copyright 1996 Derek B. Noonburg
+// Copyright 1996-2002 Glyph & Cog, LLC
//
//========================================================================
#ifndef GFXSTATE_H
#define GFXSTATE_H
@@ -565,12 +565,46 @@ private:
Function *funcs[gfxColorMaxComps];
int nFuncs;
GBool extend0, extend1;
};
//------------------------------------------------------------------------
+// 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
//------------------------------------------------------------------------
class GfxImageColorMap {
public:
@@ -780,12 +814,13 @@ public:
int getRender() { return render; }
GfxPath *getPath() { return path; }
fouble getCurX() { return curX; }
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; }
// Is there a current point/path?
GBool isCurPt() { return path->isCurPt(); }
GBool isPath() { return path->isPath(); }
@@ -862,13 +897,13 @@ public:
// Update clip region.
void clip();
// 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.
GfxState *save();
GfxState *restore();
GBool hasSaves() { return saved != NULL; }
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
@@ -1,11 +1,11 @@
//========================================================================
//
// GlobalParams.cc
//
-// Copyright 2001 Derek B. Noonburg
+// Copyright 2001-2002 Glyph & Cog, LLC
//
//========================================================================
#ifdef __GNUC__
#pragma implementation
#endif
@@ -93,42 +93,45 @@ 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;
+ }
}
//------------------------------------------------------------------------
// parsing
//------------------------------------------------------------------------
GlobalParams::GlobalParams(char *cfgFileName) {
UnicodeMap *map;
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);
}
}
nameToUnicode = new NameToCharCode();
@@ -136,12 +139,13 @@ GlobalParams::GlobalParams(char *cfgFileName) {
residentUnicodeMaps = new GHash();
unicodeMaps = new GHash(gTrue);
cMapDirs = new GHash(gTrue);
toUnicodeDirs = new GList();
displayFonts = new GHash();
displayCIDFonts = new GHash();
+ displayNamedCIDFonts = new GHash();
#if HAVE_PAPER_H
const struct paper *paperType;
paperinit();
paperType = paperinfo(systempapername());
psPaperWidth = (int)paperpswidth(paperType);
psPaperHeight = (int)paperpsheight(paperType);
@@ -151,24 +155,30 @@ GlobalParams::GlobalParams(char *cfgFileName) {
psPaperHeight = defPaperHeight;
#endif
psDuplex = gFalse;
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;
#elif defined(MACOS)
textEOL = eolMac;
#else
textEOL = eolUnix;
#endif
fontDirs = new GList();
+ initialZoom = new GString("1");
t1libControl = fontRastAALow;
freetypeControl = fontRastAALow;
urlCommand = NULL;
mapNumericCharNames = gTrue;
errQuiet = gFalse;
@@ -190,12 +200,14 @@ GlobalParams::GlobalParams(char *cfgFileName) {
residentUnicodeMaps->add(map->getEncodingName(), map);
map = new UnicodeMap("ZapfDingbats", zapfDingbatsUnicodeMapRanges,
zapfDingbatsUnicodeMapLen);
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) {
dfp = new DisplayFontParam(displayFontTab[i].name,
displayFontTab[i].xlfd,
displayFontTab[i].encoding);
@@ -216,12 +228,13 @@ GlobalParams::GlobalParams(char *cfgFileName) {
if (!(f = fopen(fileName->getCString(), "r"))) {
delete fileName;
}
}
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
buf[i] = '\0';
}
fileName = grabPath(buf);
@@ -231,12 +244,25 @@ GlobalParams::GlobalParams(char *cfgFileName) {
#endif
if (!(f = fopen(fileName->getCString(), "r"))) {
delete fileName;
}
}
if (f) {
+ 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;
@@ -255,53 +281,86 @@ GlobalParams::GlobalParams(char *cfgFileName) {
p1 = p2 + 1;
}
if (tokens->getLength() > 0 &&
((GString *)tokens->get(0))->getChar(0) != '#') {
cmd = (GString *)tokens->get(0);
- if (!cmd->cmp("nameToUnicode")) {
+ 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, "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, gFalse, displayFontX, fileName, line);
+ parseDisplayFont(tokens, displayFonts, displayFontX, fileName, line);
} else if (!cmd->cmp("displayFontT1")) {
- parseDisplayFont(tokens, gFalse, displayFontT1, fileName, line);
+ parseDisplayFont(tokens, displayFonts, displayFontT1, fileName, line);
} else if (!cmd->cmp("displayFontTT")) {
- parseDisplayFont(tokens, gFalse, displayFontTT, fileName, line);
+ parseDisplayFont(tokens, displayFonts, displayFontTT, fileName, line);
} else if (!cmd->cmp("displayCIDFontX")) {
- parseDisplayFont(tokens, gTrue, displayFontX, fileName, line);
+ 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("psEmbedType1")) {
+ } else if (!cmd->cmp("psEmbedType1Fonts")) {
parseYesNo("psEmbedType1", &psEmbedType1, tokens, fileName, line);
- } else if (!cmd->cmp("psEmbedTrueType")) {
+ } 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);
@@ -321,15 +380,12 @@ GlobalParams::GlobalParams(char *cfgFileName) {
}
}
deleteGList(tokens, GString);
++line;
}
-
- delete fileName;
- }
}
void GlobalParams::parseNameToUnicode(GList *tokens, GString *fileName,
int line) {
GString *name;
char *tok1, *tok2;
@@ -423,13 +479,13 @@ void GlobalParams::parseToUnicodeDir(GList *tokens, GString *fileName,
fileName->getCString(), line);
return;
}
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;
if (tokens->getLength() < 2) {
goto err1;
@@ -455,29 +511,22 @@ void GlobalParams::parseDisplayFont(GList *tokens, GBool isCID,
goto err2;
}
param->tt.fileName = ((GString *)tokens->get(2))->copy();
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))) {
+ if ((old = (DisplayFontParam *)fontHash->remove(param->name))) {
delete old;
}
- displayFonts->add(param->name, param);
- }
+ 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);
}
void GlobalParams::parsePSPaperSize(GList *tokens, GString *fileName,
int line) {
GString *tok;
@@ -513,12 +562,16 @@ void GlobalParams::parsePSLevel(GList *tokens, GString *fileName, int line) {
} else if (!tok->cmp("level1sep")) {
psLevel = psLevel1Sep;
} else if (!tok->cmp("level2")) {
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);
}
}
@@ -539,17 +592,45 @@ void GlobalParams::parsePSFont(GList *tokens, GString *fileName, int line) {
if (tokens->getLength() != 3) {
error(-1, "Bad 'psFont' config file command (%s:%d)",
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) {
error(-1, "Bad 'textEncoding' config file command (%s:%d)",
fileName->getCString(), line);
return;
@@ -585,23 +666,21 @@ void GlobalParams::parseFontDir(GList *tokens, GString *fileName, int line) {
fileName->getCString(), line);
return;
}
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,
GList *tokens, GString *fileName,
int line) {
GString *tok;
@@ -615,12 +694,25 @@ void GlobalParams::parseFontRastControl(char *cmdName, FontRastControl *val,
if (!setFontRastControl(val, tok->getCString())) {
error(-1, "Bad '%s' config file command (%s:%d)",
cmdName, fileName->getCString(), line);
}
}
+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;
if (tokens->getLength() != 2) {
error(-1, "Bad '%s' config file command (%s:%d)",
@@ -651,18 +743,22 @@ GlobalParams::~GlobalParams() {
deleteGHash(cidToUnicodes, GString);
deleteGHash(residentUnicodeMaps, UnicodeMap);
deleteGHash(unicodeMaps, GString);
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;
}
cMapDirs->startIter(&iter);
while (cMapDirs->getNext(&iter, &key, (void **)&list)) {
@@ -749,20 +845,56 @@ FILE *GlobalParams::findToUnicodeFile(GString *name) {
}
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;
FILE *f;
int i;
@@ -863,16 +995,28 @@ void GlobalParams::setPSEmbedType1(GBool embed) {
}
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);
}
GBool GlobalParams::setTextEOL(char *s) {
@@ -885,12 +1029,17 @@ GBool GlobalParams::setTextEOL(char *s) {
} else {
return gFalse;
}
return gTrue;
}
+void GlobalParams::setInitialZoom(char *s) {
+ delete initialZoom;
+ initialZoom = new GString(s);
+}
+
GBool GlobalParams::setT1libControl(char *s) {
return setFontRastControl(&t1libControl, s);
}
GBool GlobalParams::setFreeTypeControl(char *s) {
return setFontRastControl(&freetypeControl, 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
@@ -1,11 +1,11 @@
//========================================================================
//
// GlobalParams.h
//
-// Copyright 2001 Derek B. Noonburg
+// Copyright 2001-2002 Glyph & Cog, LLC
//
//========================================================================
#ifndef GLOBALPARAMS_H
#define GLOBALPARAMS_H
@@ -42,14 +42,15 @@ enum DisplayFontParamKind {
displayFontTT
};
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 {
GString *xlfd;
GString *encoding;
} x;
@@ -76,26 +77,34 @@ 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();
};
//------------------------------------------------------------------------
enum PSLevel {
psLevel1,
psLevel1Sep,
psLevel2,
- psLevel2Sep
+ psLevel2Sep,
+ psLevel3,
+ psLevel3Sep
};
//------------------------------------------------------------------------
enum EndOfLineKind {
eolUnix, // LF
@@ -122,25 +131,30 @@ public:
FILE *getCIDToUnicodeFile(GString *collection);
UnicodeMap *getResidentUnicodeMap(GString *encodingName);
FILE *getUnicodeMapFile(GString *encodingName);
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; }
GBool getMapNumericCharNames() { return mapNumericCharNames; }
GBool getErrQuiet() { return errQuiet; }
@@ -156,35 +170,44 @@ public:
void setPSPaperWidth(int width);
void setPSPaperHeight(int height);
void setPSDuplex(GBool duplex);
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);
void parseYesNo(char *cmdName, GBool *flag,
GList *tokens, GString *fileName, int line);
GBool setFontRastControl(FontRastControl *val, char *s);
@@ -209,27 +232,35 @@ private:
// name [GList[GString]]
GList *toUnicodeDirs; // list of ToUnicode CMap dirs [GString]
GHash *displayFonts; // display font info, indexed by font name
// [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
GBool psDuplex; // enable duplexing in PostScript?
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;
GString *urlCommand; // command executed for URL links
GBool mapNumericCharNames; // map numeric char names (from font subsets)?
GBool errQuiet; // suppress error messages?
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
@@ -1,11 +1,11 @@
//========================================================================
//
// Lexer.cc
//
-// Copyright 1996 Derek B. Noonburg
+// Copyright 1996-2002 Glyph & Cog, LLC
//
//========================================================================
#ifdef __GNUC__
#pragma implementation
#endif
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
@@ -1,11 +1,11 @@
//========================================================================
//
// Lexer.h
//
-// Copyright 1996 Derek B. Noonburg
+// Copyright 1996-2002 Glyph & Cog, LLC
//
//========================================================================
#ifndef LEXER_H
#define LEXER_H
@@ -48,19 +48,20 @@ public:
void skipChar() { getChar(); }
// Get stream.
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:
int getChar();
int lookChar();
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
@@ -1,11 +1,11 @@
//========================================================================
//
// Link.cc
//
-// Copyright 1996 Derek B. Noonburg
+// Copyright 1996-2002 Glyph & Cog, LLC
//
//========================================================================
#ifdef __GNUC__
#pragma implementation
#endif
@@ -26,37 +26,33 @@
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();
- }
// get destination type
a->get(1, &obj1);
// XYZ link
if (obj1.isName("XYZ")) {
@@ -218,13 +214,13 @@ LinkGoTo::LinkGoTo(Object *destObj) {
namedDest = new GString(destObj->getName());
} else if (destObj->isString()) {
namedDest = destObj->getString()->copy();
// destination dictionary
} else if (destObj->isArray()) {
- dest = new LinkDest(destObj->getArray(), gTrue);
+ dest = new LinkDest(destObj->getArray());
if (!dest->isOk()) {
delete dest;
dest = NULL;
}
// error
@@ -256,13 +252,13 @@ LinkGoToR::LinkGoToR(Object *fileSpecObj, Object *destObj) {
namedDest = new GString(destObj->getName());
} else if (destObj->isString()) {
namedDest = destObj->getString()->copy();
// destination dictionary
} else if (destObj->isArray()) {
- dest = new LinkDest(destObj->getArray(), gFalse);
+ dest = new LinkDest(destObj->getArray());
if (!dest->isOk()) {
delete dest;
dest = NULL;
}
// error
@@ -443,13 +439,13 @@ Link::Link(Dict *dict, GString *baseURI) {
t = y1;
y1 = y2;
y2 = t;
}
// get border
- borderW = 0;
+ borderW = 1;
if (!dict->lookup("Border", &obj1)->isNull()) {
if (obj1.isArray() && obj1.arrayGetLength() >= 3) {
if (obj1.arrayGet(2, &obj2)->isNum()) {
borderW = obj2.getNum();
} else {
error(-1, "Bad annotation border");
@@ -579,13 +575,13 @@ Links::~Links() {
gfree(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();
}
}
return NULL;
}
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
@@ -1,11 +1,11 @@
//========================================================================
//
// Link.h
//
-// Copyright 1996 Derek B. Noonburg
+// Copyright 1996-2002 Glyph & Cog, LLC
//
//========================================================================
#ifndef LINK_H
#define LINK_H
@@ -60,16 +60,14 @@ enum LinkDestKind {
destFitBV
};
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); }
// Was the LinkDest created successfully?
GBool isOk() { return ok; }
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
@@ -1,11 +1,11 @@
//========================================================================
//
// NameToCharCode.cc
//
-// Copyright 2001 Derek B. Noonburg
+// Copyright 2001-2002 Glyph & Cog, LLC
//
//========================================================================
#ifdef __GNUC__
#pragma implementation
#endif
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
@@ -1,11 +1,11 @@
//========================================================================
//
// NameToCharCode.h
//
-// Copyright 2001 Derek B. Noonburg
+// Copyright 2001-2002 Glyph & Cog, LLC
//
//========================================================================
#ifndef NAMETOCHARCODE_H
#define NAMETOCHARCODE_H
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
@@ -1,11 +1,11 @@
//========================================================================
//
// NameToUnicodeTable.h
//
-// Copyright 2001 Derek B. Noonburg
+// Copyright 2001-2002 Glyph & Cog, LLC
//
//========================================================================
static struct {
Unicode u;
char *name;
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
@@ -1,11 +1,11 @@
//========================================================================
//
// Object.cc
//
-// Copyright 1996 Derek B. Noonburg
+// Copyright 1996-2002 Glyph & Cog, LLC
//
//========================================================================
#ifdef __GNUC__
#pragma implementation
#endif
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
@@ -1,11 +1,11 @@
//========================================================================
//
// Object.h
//
-// Copyright 1996 Derek B. Noonburg
+// Copyright 1996-2002 Glyph & Cog, LLC
//
//========================================================================
#ifndef OBJECT_H
#define OBJECT_H
@@ -173,14 +173,14 @@ public:
GBool streamIs(char *dictType);
void streamReset();
void streamClose();
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.
char *getTypeName();
void print(FILE *f = stdout);
@@ -284,16 +284,16 @@ inline int Object::streamGetChar()
inline int Object::streamLookChar()
{ return stream->lookChar(); }
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(); }
#endif
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
@@ -1,11 +1,11 @@
//========================================================================
//
// OutputDev.cc
//
-// Copyright 1996 Derek B. Noonburg
+// Copyright 1996-2002 Glyph & Cog, LLC
//
//========================================================================
#ifdef __GNUC__
#pragma implementation
#endif
@@ -56,12 +56,17 @@ void OutputDev::updateAll(GfxState *state) {
updateLineWidth(state);
updateFillColor(state);
updateStrokeColor(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) {
int i, j;
if (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
@@ -1,11 +1,11 @@
//========================================================================
//
// OutputDev.h
//
-// Copyright 1996 Derek B. Noonburg
+// Copyright 1996-2002 Glyph & Cog, LLC
//
//========================================================================
#ifndef OUTPUTDEV_H
#define OUTPUTDEV_H
@@ -43,12 +43,16 @@ public:
// (Upside-down means (0,0) is the top left corner of the page.)
virtual GBool upsideDown() = 0;
// 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; }
//----- initialization and control
// Set default transform matrix.
@@ -116,12 +120,15 @@ public:
virtual void endString(GfxState *state) {}
virtual void drawChar(GfxState *state, fouble x, fouble y,
fouble dx, fouble dy,
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,
int width, int height, GBool invert,
GBool inlineImg);
virtual void drawImage(GfxState *state, Object *ref, Stream *str,
@@ -131,12 +138,20 @@ public:
#if OPI_SUPPORT
//----- OPI functions
virtual void opiBegin(GfxState *state, Dict *opiDict);
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
fouble defICTM[6]; // inverse of default CTM
};
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
@@ -1,11 +1,11 @@
//========================================================================
//
// PDFDoc.cc
//
-// Copyright 1996 Derek B. Noonburg
+// Copyright 1996-2002 Glyph & Cog, LLC
//
//========================================================================
#ifdef __GNUC__
#pragma implementation
#endif
@@ -21,12 +21,13 @@
#include "Catalog.h"
#include "Stream.h"
#include "XRef.h"
#include "Link.h"
#include "OutputDev.h"
#include "Error.h"
+#include "ErrorCodes.h"
#include "Lexer.h"
#include "Parser.h"
#include "PDFDoc.h"
//------------------------------------------------------------------------
@@ -40,12 +41,13 @@
PDFDoc::PDFDoc(GString *fileNameA, GString *ownerPassword,
GString *userPassword, GBool printCommandsA) {
Object obj;
GString *fileName2;
ok = gFalse;
+ errCode = errNone;
file = NULL;
str = NULL;
xref = NULL;
catalog = NULL;
links = NULL;
@@ -54,40 +56,43 @@ PDFDoc::PDFDoc(GString *fileNameA, GString *ownerPassword,
// try to open file
fileName = fileNameA;
fileName2 = NULL;
#ifdef VMS
if (!(file = fopen(fileName->getCString(), "rb", "ctx=stm"))) {
error(-1, "Couldn't open file '%s'", fileName->getCString());
+ errCode = errOpenFile;
return;
}
#else
if (!(file = fopen(fileName->getCString(), "rb"))) {
fileName2 = fileName->copy();
fileName2->lowerCase();
if (!(file = fopen(fileName2->getCString(), "rb"))) {
fileName2->upperCase();
if (!(file = fopen(fileName2->getCString(), "rb"))) {
error(-1, "Couldn't open file '%s'", fileName->getCString());
delete fileName2;
+ errCode = errOpenFile;
return;
}
}
delete fileName2;
}
#endif
// create stream
obj.initNull();
- str = new FileStream(file, 0, -1, &obj);
+ str = new FileStream(file, 0, gFalse, 0, &obj);
ok = setup(ownerPassword, userPassword);
}
PDFDoc::PDFDoc(BaseStream *strA, GString *ownerPassword,
GString *userPassword, GBool printCommandsA) {
ok = gFalse;
+ errCode = errNone;
fileName = NULL;
file = NULL;
str = strA;
xref = NULL;
catalog = NULL;
links = NULL;
@@ -100,19 +105,21 @@ GBool PDFDoc::setup(GString *ownerPassword, GString *userPassword) {
checkHeader();
// read xref table
xref = new XRef(str, ownerPassword, userPassword);
if (!xref->isOk()) {
error(-1, "Couldn't read xref table");
+ errCode = xref->getErrorCode();
return gFalse;
}
// read catalog
catalog = new Catalog(xref, printCommands);
if (!catalog->isOk()) {
error(-1, "Couldn't read page catalog");
+ errCode = errBadCatalog;
return gFalse;
}
// done
return gTrue;
}
@@ -201,14 +208,15 @@ GBool PDFDoc::isLinearized() {
Parser *parser;
Object obj1, obj2, obj3, obj4, obj5;
GBool lin;
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);
parser->getObj(&obj4);
if (obj1.isInt() && obj2.isInt() && obj3.isCmd("obj") &&
obj4.isDict()) {
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
@@ -1,11 +1,11 @@
//========================================================================
//
// PDFDoc.h
//
-// Copyright 1996 Derek B. Noonburg
+// Copyright 1996-2002 Glyph & Cog, LLC
//
//========================================================================
#ifndef PDFDOC_H
#define PDFDOC_H
@@ -39,12 +39,15 @@ public:
GString *userPassword = NULL, GBool printCommandsA = gFalse);
~PDFDoc();
// 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; }
// Get the xref table.
XRef *getXRef() { return xref; }
@@ -134,9 +137,10 @@ private:
XRef *xref;
Catalog *catalog;
Links *links;
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
@@ -1,11 +1,11 @@
//========================================================================
//
// Page.cc
//
-// Copyright 1996 Derek B. Noonburg
+// Copyright 1996-2002 Glyph & Cog, LLC
//
//========================================================================
#ifdef __GNUC__
#pragma implementation
#endif
@@ -17,13 +17,13 @@
#include "Dict.h"
#include "XRef.h"
#include "Link.h"
#include "OutputDev.h"
#ifndef PDF_PARSER_ONLY
#include "Gfx.h"
-#include "FormWidget.h"
+#include "Annot.h"
#endif
#include "Error.h"
#include "Page.h"
//------------------------------------------------------------------------
// PageAttrs
@@ -90,22 +90,36 @@ PageAttrs::PageAttrs(PageAttrs *attrs, Dict *dict) {
rotate += 360;
}
while (rotate >= 360) {
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()) {
resources.free();
obj1.copy(&resources);
}
obj1.free();
}
PageAttrs::~PageAttrs() {
+ lastModified.free();
+ boxColorInfo.free();
+ group.free();
+ metadata.free();
+ pieceInfo.free();
+ separationInfo.free();
resources.free();
}
GBool PageAttrs::readBox(Dict *dict, char *key, PDFRectangle *box) {
PDFRectangle tmp;
Object obj1, obj2;
@@ -206,13 +220,13 @@ void Page::display(OutputDev *out, fouble dpi, int rotate,
#ifndef PDF_PARSER_ONLY
PDFRectangle *box, *cropBox;
Gfx *gfx;
Object obj;
Link *link;
int i;
- FormWidgets *formWidgets;
+ Annots *annotList;
box = getBox();
cropBox = getCropBox();
if (printCommands) {
printf("***** MediaBox = ll:%g,%g ur:%g,%g\n",
@@ -244,24 +258,24 @@ void Page::display(OutputDev *out, fouble dpi, int rotate,
link = links->getLink(i);
out->drawLink(link, catalog);
}
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");
+ if (annotList->getNumAnnots() > 0) {
+ if (printCommands) {
+ printf("***** Annotations\n");
}
- for (i = 0; i < formWidgets->getNumWidgets(); ++i) {
- formWidgets->getWidget(i)->draw(gfx);
+ for (i = 0; i < annotList->getNumAnnots(); ++i) {
+ annotList->getAnnot(i)->draw(gfx);
}
- if (formWidgets->getNumWidgets() > 0) {
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
@@ -1,11 +1,11 @@
//========================================================================
//
// Page.h
//
-// Copyright 1996 Derek B. Noonburg
+// Copyright 1996-2002 Glyph & Cog, LLC
//
//========================================================================
#ifndef PAGE_H
#define PAGE_H
@@ -48,12 +48,26 @@ public:
PDFRectangle *getCropBox() { return &cropBox; }
GBool isCropped() { return haveCropBox; }
PDFRectangle *getBleedBox() { return &bleedBox; }
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; }
private:
GBool readBox(Dict *dict, char *key, PDFRectangle *box);
@@ -63,12 +77,18 @@ private:
GBool haveCropBox;
GBool limitToCropBox;
PDFRectangle bleedBox;
PDFRectangle trimBox;
PDFRectangle artBox;
int rotate;
+ Object lastModified;
+ Object boxColorInfo;
+ Object group;
+ Object metadata;
+ Object pieceInfo;
+ Object separationInfo;
Object resources;
};
//------------------------------------------------------------------------
// Page
//------------------------------------------------------------------------
@@ -94,12 +114,18 @@ public:
fouble getWidth() { return attrs->getBox()->x2 - attrs->getBox()->x1; }
fouble getHeight() { return attrs->getBox()->y2 - attrs->getBox()->y1; }
PDFRectangle *getBleedBox() { return attrs->getBleedBox(); }
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(); }
// Get annotations array.
Object *getAnnots(Object *obj) { return annots.fetch(xref, obj); }
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
@@ -1,11 +1,11 @@
//========================================================================
//
// Parser.cc
//
-// Copyright 1996 Derek B. Noonburg
+// Copyright 1996-2002 Glyph & Cog, LLC
//
//========================================================================
#ifdef __GNUC__
#pragma implementation
#endif
@@ -152,36 +152,37 @@ Object *Parser::getObj(Object *obj) {
return obj;
}
Stream *Parser::makeStream(Object *dict) {
Object obj;
Stream *str;
- int pos, endPos, length;
+ Guint pos, endPos, length;
// get stream start position
lexer->skipToNextLine();
pos = lexer->getPos();
// 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");
obj.free();
return NULL;
}
// 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);
// skip over stream data
lexer->setPos(pos + length);
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
@@ -1,11 +1,11 @@
//========================================================================
//
// Parser.h
//
-// Copyright 1996 Derek B. Noonburg
+// Copyright 1996-2002 Glyph & Cog, LLC
//
//========================================================================
#ifndef PARSER_H
#define PARSER_H
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
@@ -1,13 +1,13 @@
//========================================================================
//
// Stream-CCITT.h
//
// Tables for CCITT Fax decoding.
//
-// Copyright 1996 Derek B. Noonburg
+// Copyright 1996-2002 Glyph & Cog, LLC
//
//========================================================================
struct CCITTCode {
short bits;
short n;
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
@@ -1,11 +1,11 @@
//========================================================================
//
// Stream.cc
//
-// Copyright 1996 Derek B. Noonburg
+// Copyright 1996-2002 Glyph & Cog, LLC
//
//========================================================================
#ifdef __GNUC__
#pragma implementation
#endif
@@ -300,13 +300,13 @@ FilterStream::~FilterStream() {
}
void FilterStream::close() {
str->close();
}
-void FilterStream::setPos(int pos) {
+void FilterStream::setPos(Guint pos, int dir) {
error(-1, "Internal: called setPos() on FilterStream");
}
//------------------------------------------------------------------------
// ImageStream
//------------------------------------------------------------------------
@@ -551,60 +551,74 @@ 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
if (decrypt)
decrypt->reset();
#endif
}
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;
}
}
GBool FileStream::fillBuf() {
int n;
#ifndef NO_DECRYPTION
char *p;
#endif
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;
}
n = fread(buf, 1, n, f);
bufEnd = buf + n;
@@ -618,66 +632,165 @@ GBool FileStream::fillBuf() {
}
}
#endif
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;
}
void FileStream::moveStart(int delta) {
start += delta;
bufPtr = bufEnd = buf;
bufPos = start;
}
//------------------------------------------------------------------------
+// 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
//------------------------------------------------------------------------
EmbedStream::EmbedStream(Stream *strA, Object *dictA):
BaseStream(dictA) {
str = strA;
}
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");
}
//------------------------------------------------------------------------
// ASCIIHexStream
//------------------------------------------------------------------------
@@ -956,17 +1069,13 @@ void LZWStream::reset() {
error(getPos(), "Couldn't popen '%s'", zCmd->getCString());
unlink(zName->getCString());
delete zName;
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;
return;
}
zName->del(zName->getLength() - 2, 2);
@@ -3284,12 +3393,62 @@ int FixedLengthEncoder::lookChar() {
if (length >= 0 && count >= length)
return EOF;
return str->getChar();
}
//------------------------------------------------------------------------
+// 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
//------------------------------------------------------------------------
ASCII85Encoder::ASCII85Encoder(Stream *strA):
FilterStream(strA) {
bufPtr = bufEnd = buf;
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
@@ -1,11 +1,11 @@
//========================================================================
//
// Stream.h
//
-// Copyright 1996 Derek B. Noonburg
+// Copyright 1996-2002 Glyph & Cog, LLC
//
//========================================================================
#ifndef STREAM_H
#define STREAM_H
@@ -75,14 +75,16 @@ public:
// Get next line from stream.
virtual char *getLine(char *buf, int size);
// 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);
// Does this stream type potentially contain non-printable chars?
virtual GBool isBinary(GBool last = gTrue) = 0;
@@ -115,24 +117,26 @@ private:
class BaseStream: public Stream {
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
protected:
Decrypt *decrypt;
@@ -153,13 +157,13 @@ class FilterStream: public Stream {
public:
FilterStream(Stream *strA);
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(); }
protected:
Stream *str;
@@ -239,40 +243,81 @@ private:
#define fileStreamBufSize 256
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();
virtual int getChar()
{ return (bufPtr >= bufEnd && !fillBuf()) ? EOF : (*bufPtr++ & 0xff); }
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:
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;
};
//------------------------------------------------------------------------
// EmbedStream
//
// This is a special stream type used for embedded streams (inline
@@ -284,21 +329,22 @@ private:
class EmbedStream: public BaseStream {
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:
Stream *str;
};
@@ -656,12 +702,43 @@ private:
int length;
int count;
};
//------------------------------------------------------------------------
+// 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
//------------------------------------------------------------------------
class ASCII85Encoder: public FilterStream {
public:
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
@@ -1,11 +1,11 @@
//========================================================================
//
// TextOutputDev.cc
//
-// Copyright 1997 Derek B. Noonburg
+// Copyright 1997-2002 Glyph & Cog, LLC
//
//========================================================================
#ifdef __GNUC__
#pragma implementation
#endif
@@ -45,12 +45,18 @@ TextString::TextString(GfxState *state, fouble fontSize) {
} else {
// this means that the PDF file draws text without a current font,
// which should never happen
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;
len = size = 0;
yxNext = NULL;
xyNext = NULL;
@@ -96,12 +102,13 @@ TextPage::~TextPage() {
void TextPage::updateFont(GfxState *state) {
GfxFont *font;
fouble *fm;
char *name;
int code;
+ fouble w;
// adjust the font size
fontSize = state->getTransformedFontSize();
if ((font = state->getFont()) && font->getType() == fontType3) {
// This is a hack which makes it possible to deal with some Type 3
// fonts. The problem is that it's impossible to know what the
@@ -113,14 +120,17 @@ void TextPage::updateFont(GfxState *state) {
if ((name = ((Gfx8BitFont *)font)->getCharName(code)) &&
name[0] == 'm' && name[1] == '\0') {
break;
}
}
if (code < 256) {
+ w = ((Gfx8BitFont *)font)->getWidth(code);
+ if (w != 0) {
// 600 is a generic average 'm' width -- yes, this is a hack
- fontSize *= ((Gfx8BitFont *)font)->getWidth(code) / 0.6;
+ fontSize *= w / 0.6;
+ }
}
fm = font->getFontMatrix();
if (fm[0] != 0) {
fontSize *= fabs(fm[3] / fm[0]);
}
}
@@ -151,14 +161,16 @@ void TextPage::addChar(GfxState *state, fouble x, fouble y,
}
state->textTransformDelta(state->getCharSpace() * state->getHorizScaling(),
0, &dx2, &dy2);
dx -= dx2;
dy -= dy2;
state->transformDelta(dx, dy, &w1, &h1);
+ 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]);
}
}
void TextPage::endString() {
@@ -426,13 +438,13 @@ GString *TextPage::getText(fouble xMin, fouble yMin,
s->append(eol, eolLen);
}
uMap->decRefCnt();
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;
TextString *str1, *str2, *str3;
fouble yMin, yMax;
int col1, col2, d, i;
@@ -495,43 +507,43 @@ void TextPage::dump(FILE *f) {
}
}
str1->col = col1;
}
#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) {
fputc(str1->text[i] & 0xff, stdout);
}
printf("'\n");
}
- fprintf(f, "~~~~~~~~~~\n");
+ fprintf((FILE *)outputStream, "~~~~~~~~~~\n");
#endif
// output
col1 = 0;
yMax = yxStrings ? yxStrings->yMax : fouble(0);
for (str1 = yxStrings; str1; str1 = str1->yxNext) {
// line this string up with the correct column
if (rawOrder && col1 == 0) {
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);
}
}
// increment column
col1 += str1->len;
@@ -544,13 +556,13 @@ void TextPage::dump(FILE *f) {
if (!(str1->yxNext &&
!(rawOrder && str1->yxNext->yMax < str1->yMin) &&
str1->yxNext->yMin < 0.2*str1->yMin + 0.8*str1->yMax &&
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) {
// find yMin for next line
yMin = str1->yxNext->yMin;
@@ -570,26 +582,26 @@ void TextPage::dump(FILE *f) {
if (rawOrder && d > 2) {
d = 2;
} else if (!rawOrder && d > 5) {
d = 5;
}
for (; d > 0; --d) {
- fwrite(eol, 1, eolLen, f);
+ (*outputFunc)(outputStream, eol, eolLen);
}
}
// set up for next line
col1 = 0;
yMax = str1->yxNext ? str1->yxNext->yMax : fouble(0);
}
}
// 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();
}
void TextPage::clear() {
TextString *p1, *p2;
@@ -608,57 +620,72 @@ 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;
ok = gTrue;
// open file
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;
}
}
void TextOutputDev::startPage(int pageNum, GfxState *state) {
text->clear();
}
void TextOutputDev::endPage() {
text->coalesce();
- if (f) {
- text->dump(f);
+ if (outputStream) {
+ text->dump(outputStream, outputFunc);
}
}
void TextOutputDev::updateFont(GfxState *state) {
text->updateFont(state);
}
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
@@ -1,11 +1,11 @@
//========================================================================
//
// TextOutputDev.h
//
-// Copyright 1997 Derek B. Noonburg
+// Copyright 1997-2002 Glyph & Cog, LLC
//
//========================================================================
#ifndef TEXTOUTPUTDEV_H
#define TEXTOUTPUTDEV_H
@@ -19,12 +19,16 @@
#include "OutputDev.h"
class GfxState;
class GString;
//------------------------------------------------------------------------
+
+typedef void (*TextOutputFunc)(void *stream, char *text, int len);
+
+//------------------------------------------------------------------------
// TextString
//------------------------------------------------------------------------
class TextString {
public:
@@ -94,13 +98,13 @@ public:
// Get the text which is inside the specified rectangle.
GString *getText(fouble xMin, fouble yMin,
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();
private:
@@ -125,12 +129,16 @@ public:
// Open a text output file. If <fileName> is NULL, no file is
// written (this is useful, e.g., for searching text). If
// <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();
// Check if file was successfully created.
virtual GBool isOk() { return ok; }
@@ -140,12 +148,16 @@ public:
// (Upside-down means (0,0) is the top left corner of the page.)
virtual GBool upsideDown() { return gTrue; }
// 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.
@@ -176,14 +188,16 @@ public:
GBool top, GBool bottom,
fouble *xMin, fouble *yMin,
fouble *xMax, fouble *yMax);
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?
};
#endif
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
@@ -1,11 +1,11 @@
//========================================================================
//
// UnicodeMap.cc
//
-// Copyright 2001 Derek B. Noonburg
+// Copyright 2001-2002 Glyph & Cog, LLC
//
//========================================================================
#ifdef __GNUC__
#pragma implementation
#endif
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
@@ -1,13 +1,13 @@
//========================================================================
//
// UnicodeMap.h
//
// Mapping from Unicode to an encoding.
//
-// Copyright 2001 Derek B. Noonburg
+// Copyright 2001-2002 Glyph & Cog, LLC
//
//========================================================================
#ifndef UNICODEMAP_H
#define UNICODEMAP_H
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
@@ -1,21 +1,23 @@
//========================================================================
//
// UnicodeMapTables.h
//
-// Copyright 2001 Derek B. Noonburg
+// Copyright 2001-2002 Glyph & Cog, LLC
//
//========================================================================
static UnicodeMapRange latin1UnicodeMapRanges[] = {
{ 0x000a, 0x000a, 0x0a, 1 },
{ 0x000c, 0x000d, 0x0c, 1 },
{ 0x0020, 0x007e, 0x20, 1 },
{ 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 },
{ 0x0152, 0x0152, 0x4f45, 2 },
{ 0x0153, 0x0153, 0x6f65, 2 },
{ 0x0160, 0x0160, 0x53, 1 },
@@ -38,12 +40,29 @@ static UnicodeMapRange latin1UnicodeMapRanges[] = {
{ 0x2026, 0x2026, 0x2e2e2e, 3 },
{ 0x2039, 0x2039, 0x3c, 1 },
{ 0x203a, 0x203a, 0x3e, 1 },
{ 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 },
{ 0xfb03, 0xfb03, 0x666669, 3 },
{ 0xfb04, 0xfb04, 0x66666c, 3 }
};
@@ -132,12 +151,51 @@ static UnicodeMapRange ascii7UnicodeMapRanges[] = {
{ 0x201c, 0x201c, 0x22, 1 },
{ 0x201d, 0x201d, 0x22, 1 },
{ 0x2022, 0x2022, 0x2a, 1 },
{ 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 },
{ 0xfb03, 0xfb03, 0x666669, 3 },
{ 0xfb04, 0xfb04, 0x66666c, 3 }
};
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
@@ -1,11 +1,11 @@
//========================================================================
//
// XRef.cc
//
-// Copyright 1996 Derek B. Noonburg
+// Copyright 1996-2002 Glyph & Cog, LLC
//
//========================================================================
#ifdef __GNUC__
#pragma implementation
#endif
@@ -22,12 +22,13 @@
#include "Parser.h"
#include "Dict.h"
#ifndef NO_DECRYPTION
#include "Decrypt.h"
#endif
#include "Error.h"
+#include "ErrorCodes.h"
#include "XRef.h"
//------------------------------------------------------------------------
#define xrefSearchSize 1024 // read this many bytes at end of file
// to look for 'startxref'
@@ -46,16 +47,17 @@
//------------------------------------------------------------------------
// XRef
//------------------------------------------------------------------------
XRef::XRef(BaseStream *strA, GString *ownerPassword, GString *userPassword) {
- int pos;
+ Guint pos;
int i;
ok = gTrue;
+ errCode = errNone;
size = 0;
entries = NULL;
streamEnds = NULL;
streamEndsLen = 0;
// read the trailer
@@ -64,31 +66,33 @@ XRef::XRef(BaseStream *strA, GString *ownerPassword, GString *userPassword) {
pos = readTrailer();
// if there was a problem with the trailer,
// try to reconstruct the xref table
if (pos == 0) {
if (!(ok = constructXRef())) {
+ errCode = errDamaged;
return;
}
// trailer is ok - read the xref table
} 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)) ;
// if there was a problem with the xref table,
// try to reconstruct it
if (!ok) {
gfree(entries);
size = 0;
entries = NULL;
if (!(ok = constructXRef())) {
+ errCode = errDamaged;
return;
}
}
}
// now set the trailer dictionary's xref pointer so we can fetch
@@ -98,12 +102,13 @@ XRef::XRef(BaseStream *strA, GString *ownerPassword, GString *userPassword) {
// check for encryption
#ifndef NO_DECRYPTION
encrypted = gFalse;
#endif
if (checkEncrypted(ownerPassword, userPassword)) {
ok = gFalse;
+ errCode = errEncrypted;
return;
}
}
XRef::~XRef() {
gfree(entries);
@@ -112,23 +117,24 @@ XRef::~XRef() {
gfree(streamEnds);
}
}
// 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;
buf[n] = c;
}
buf[n] = '\0';
@@ -138,13 +144,13 @@ int XRef::readTrailer() {
if (!strncmp(&buf[i], "startxref", 9))
break;
}
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 --
// this won't work for linearized files.)
str->setPos(start + pos);
for (i = 0; i < 4; ++i)
@@ -173,14 +179,15 @@ int XRef::readTrailer() {
pos1 += (p - buf) + n * 20;
}
pos1 += 7;
// 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);
if (obj.isInt())
size = obj.getInt();
else
@@ -201,13 +208,13 @@ int XRef::readTrailer() {
// return first xref position
return pos;
}
// 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];
GBool more;
int first, newSize, n, i, j;
int c;
@@ -258,27 +265,27 @@ GBool XRef::readXRef(int *pos) {
// check for buggy PDF files with an incorrect (too small) xref
// table size
if (first + n > size) {
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;
}
for (i = first; i < first + n; ++i) {
for (j = 0; j < 20; ++j) {
if ((c = str->getChar()) == EOF) {
goto err2;
}
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') {
entries[i].used = gTrue;
} else if (s[17] == 'f') {
entries[i].used = gFalse;
@@ -290,34 +297,35 @@ GBool XRef::readXRef(int *pos) {
// instead of 0.
if (i == 1 && first == 1 &&
entries[1].offset == 0 && entries[1].gen == 65535 &&
!entries[1].used) {
i = first = 0;
entries[0] = entries[1];
- entries[1].offset = -1;
+ entries[1].offset = 0xffffffff;
}
}
}
}
// 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;
}
obj.free();
parser->getObj(&obj);
if (!obj.isDict()) {
goto err1;
}
obj.getDict()->lookupNF("Prev", &obj2);
if (obj2.isInt()) {
- *pos = obj2.getInt();
+ *pos = (Guint)obj2.getInt();
more = gTrue;
} else {
more = gFalse;
}
obj.free();
obj2.free();
@@ -334,13 +342,13 @@ GBool XRef::readXRef(int *pos) {
// Attempt to construct an xref table for a damaged file.
GBool XRef::constructXRef() {
Parser *parser;
Object obj;
char buf[256];
- int pos;
+ Guint pos;
int num, gen;
int newSize;
int streamEndsSize;
char *p;
int i;
GBool gotRoot;
@@ -357,14 +365,15 @@ GBool XRef::constructXRef() {
}
p = buf;
// 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);
if (trailerDict.isDict()) {
trailerDict.dictLookupNF("Root", &obj);
if (obj.isRef()) {
@@ -400,13 +409,13 @@ GBool XRef::constructXRef() {
if (!strncmp(p, "obj", 3)) {
if (num >= size) {
newSize = (num + 1 + 255) & ~255;
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;
}
if (!entries[num].used || gen >= entries[num].gen) {
entries[num].offset = pos - start;
@@ -418,13 +427,14 @@ 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;
}
}
if (gotRoot)
@@ -577,16 +587,17 @@ Object *XRef::fetch(int num, int gen, Object *obj) {
if (num < 0 || num >= size) {
obj->initNull();
return 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);
if (obj1.isInt() && obj1.getInt() == num &&
obj2.isInt() && obj2.getInt() == gen &&
obj3.isCmd("obj")) {
@@ -615,18 +626,18 @@ Object *XRef::getDocInfo(Object *obj) {
// Added for the pdftex project.
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;
b = streamEndsLen - 1;
// invariant: streamEnds[a] < streamStart <= streamEnds[b]
while (b - a > 1) {
@@ -634,8 +645,21 @@ int XRef::getStreamEnd(int streamStart) {
if (streamStart <= streamEnds[m]) {
b = m;
} else {
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
@@ -1,11 +1,11 @@
//========================================================================
//
// XRef.h
//
-// Copyright 1996 Derek B. Noonburg
+// Copyright 1996-2002 Glyph & Cog, LLC
//
//========================================================================
#ifndef XREF_H
#define XREF_H
@@ -21,13 +21,13 @@ class Stream;
//------------------------------------------------------------------------
// XRef
//------------------------------------------------------------------------
struct XRefEntry {
- int offset;
+ Guint offset;
int gen;
GBool used;
};
class XRef {
public:
@@ -38,12 +38,15 @@ public:
// Destructor.
~XRef();
// 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; }
#else
GBool isEncrypted() { return gFalse; }
#endif
@@ -65,47 +68,49 @@ public:
Object *getDocInfoNF(Object *obj);
// Return the number of objects in the xref table.
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
GBool encrypted; // true if file is encrypted
int encVersion; // encryption algorithm
int encRevision; // security handler revision
int keyLength; // length of key, in bytes
int permFlags; // permission bits
Guchar fileKey[16]; // file decryption key
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