[poppler] poppler/poppler: ABWOutputDev.cc, 1.2, 1.3 ABWOutputDev.h, 1.1, 1.2 Annot.cc, 1.9, 1.10 Annot.h, 1.5, 1.6 ArthurOutputDev.cc, 1.12, 1.13 Catalog.cc, 1.19, 1.20 Catalog.h, 1.11, 1.12 CharCodeToUnicode.cc, 1.5, 1.6 DCTStream.cc, 1.5, 1.6 DCTStream.h, 1.6, 1.7 Decrypt.cc, 1.3, 1.4 Decrypt.h, 1.2, 1.3 Dict.cc, 1.6, 1.7 Dict.h, 1.5, 1.6 FontInfo.cc, 1.11, 1.12 Form.cc, 1.3, 1.4 Form.h, 1.2, 1.3 Function.cc, 1.6, 1.7 Function.h, 1.2, 1.3 Gfx.cc, 1.14, 1.15 Gfx.h, 1.3, 1.4 GfxFont.cc, 1.10, 1.11 GfxFont.h, 1.5, 1.6 GfxState.cc, 1.14, 1.15 GfxState.h, 1.6, 1.7 GlobalParams.cc, 1.19, 1.20 GlobalParams.h, 1.8, 1.9 JBIG2Stream.cc, 1.9, 1.10 JBIG2Stream.h, 1.2, 1.3 JPXStream.cc, 1.6, 1.7 JPXStream.h, 1.2, 1.3 Lexer.cc, 1.5, 1.6 Link.cc, 1.5, 1.6 Link.h, 1.3, 1.4 Makefile.am, 1.30, 1.31 Object.cc, 1.3, 1.4 Object.h, 1.4, 1.5 Outline.cc, 1.5, 1.6 OutputDev.cc, 1.4, 1.5 OutputDev.h, 1.5, 1.6 PDFDoc.cc, 1.10, 1.11 PDFDoc.h, 1.7, 1.8 PSOutputDev.cc, 1.14, 1.15 PSOutputDev.h, 1.7, 1.8 PSTokenizer.cc, 1.2, 1.3 Page.cc, 1.17, 1.18 Page.h, 1.8, 1.9 PageLabelInfo.cc, 1.7, 1.8 Parser.cc, 1.7, 1.8 Parser.h, 1.3, 1.4 PreScanOutputDev.cc, 1.1, 1.2 PreScanOutputDev.h, 1.1, 1.2 SecurityHandler.cc, 1.2, 1.3 SecurityHandler.h, 1.1, 1.2 SplashOutputDev.cc, 1.12, 1.13 SplashOutputDev.h, 1.4, 1.5 Stream.cc, 1.15, 1.16 Stream.h, 1.11, 1.12 TextOutputDev.cc, 1.22, 1.23 TextOutputDev.h, 1.12, 1.13 UGooString.cc, 1.5, NONE UGooString.h, 1.2, NONE XRef.cc, 1.14, 1.15 XRef.h, 1.7, 1.8
Albert Astals Cid
aacid at kemper.freedesktop.org
Wed Apr 25 12:59:22 PDT 2007
- Previous message: [poppler] poppler/splash: Splash.cc, 1.10, 1.11 Splash.h, 1.3,
1.4 SplashBitmap.cc, 1.4, 1.5 SplashBitmap.h, 1.2,
1.3 SplashClip.cc, 1.2, 1.3 SplashClip.h, 1.2,
1.3 SplashFTFont.cc, 1.7, 1.8 SplashFTFont.h, 1.1.1.1,
1.2 SplashFTFontEngine.cc, 1.4, 1.5 SplashFTFontEngine.h, 1.3,
1.4 SplashFTFontFile.cc, 1.3, 1.4 SplashFTFontFile.h, 1.2,
1.3 SplashFont.cc, 1.3, 1.4 SplashFont.h, 1.2,
1.3 SplashFontEngine.cc, 1.4, 1.5 SplashFontEngine.h, 1.2,
1.3 SplashFontFile.cc, 1.3, 1.4 SplashFontFile.h, 1.2,
1.3 SplashMath.h, 1.2, 1.3 SplashPath.cc, 1.3,
1.4 SplashPath.h, 1.3, 1.4 SplashPattern.cc, 1.2,
1.3 SplashPattern.h, 1.2, 1.3 SplashScreen.cc, 1.3,
1.4 SplashScreen.h, 1.2, 1.3 SplashState.cc, 1.3,
1.4 SplashState.h, 1.2, 1.3 SplashT1Font.cc, 1.2,
1.3 SplashT1Font.h, 1.2, 1.3 SplashT1FontEngine.cc, 1.2,
1.3 SplashT1FontFile.cc, 1.3, 1.4 SplashT1FontFile.h, 1.2,
1.3 SplashTypes.h, 1.5, 1.6 SplashXPath.cc, 1.3,
1.4 SplashXPath.h, 1.1.1.1, 1.2 SplashXPathScanner.cc, 1.4,
1.5 SplashXPathScanner.h, 1.1.1.1, 1.2
- Next message: [poppler] 0.6 schedule
- Messages sorted by:
[ date ]
[ thread ]
[ subject ]
[ author ]
Update of /cvs/poppler/poppler/poppler
In directory kemper:/tmp/cvs-serv1447/poppler
Modified Files:
ABWOutputDev.cc ABWOutputDev.h Annot.cc Annot.h
ArthurOutputDev.cc Catalog.cc Catalog.h CharCodeToUnicode.cc
DCTStream.cc DCTStream.h Decrypt.cc Decrypt.h Dict.cc Dict.h
FontInfo.cc Form.cc Form.h Function.cc Function.h Gfx.cc Gfx.h
GfxFont.cc GfxFont.h GfxState.cc GfxState.h GlobalParams.cc
GlobalParams.h JBIG2Stream.cc JBIG2Stream.h JPXStream.cc
JPXStream.h Lexer.cc Link.cc Link.h Makefile.am Object.cc
Object.h Outline.cc OutputDev.cc OutputDev.h PDFDoc.cc
PDFDoc.h PSOutputDev.cc PSOutputDev.h PSTokenizer.cc Page.cc
Page.h PageLabelInfo.cc Parser.cc Parser.h SecurityHandler.cc
SecurityHandler.h SplashOutputDev.cc SplashOutputDev.h
Stream.cc Stream.h TextOutputDev.cc TextOutputDev.h XRef.cc
XRef.h
Added Files:
PreScanOutputDev.cc PreScanOutputDev.h
Removed Files:
UGooString.cc UGooString.h
Log Message:
Merge xpdf302branch in HEAD as noone vetoed it.
Testing more than welcome
Index: ABWOutputDev.cc
===================================================================
RCS file: /cvs/poppler/poppler/poppler/ABWOutputDev.cc,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -d -r1.2 -r1.3
--- ABWOutputDev.cc 6 Apr 2007 15:27:52 -0000 1.2
+++ ABWOutputDev.cc 25 Apr 2007 19:59:10 -0000 1.3
@@ -27,7 +27,6 @@
#include "GfxState.h"
#include "GlobalParams.h"
#include "ABWOutputDev.h"
-#include "UGooString.h"
#include "PDFDoc.h"
#include <libxml/parser.h>
Index: ABWOutputDev.h
===================================================================
RCS file: /cvs/poppler/poppler/poppler/ABWOutputDev.h,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -d -r1.1 -r1.2
--- ABWOutputDev.h 4 Apr 2007 02:42:29 -0000 1.1
+++ ABWOutputDev.h 25 Apr 2007 19:59:10 -0000 1.2
@@ -18,7 +18,6 @@
#include "goo/GooList.h"
#include "GfxFont.h"
#include "OutputDev.h"
-#include "Link.h"
#include "Catalog.h"
#include "UnicodeMap.h"
#include "PDFDoc.h"
Index: Annot.cc
===================================================================
RCS file: /cvs/poppler/poppler/poppler/Annot.cc,v
retrieving revision 1.9
retrieving revision 1.10
diff -u -d -r1.9 -r1.10
--- Annot.cc 6 Mar 2007 22:27:18 -0000 1.9
+++ Annot.cc 25 Apr 2007 19:59:10 -0000 1.10
@@ -13,18 +13,74 @@
#endif
#include <stdlib.h>
+#include <math.h>
#include "goo/gmem.h"
+#include "GooList.h"
+#include "Error.h"
#include "Object.h"
#include "Catalog.h"
#include "Gfx.h"
#include "Lexer.h"
[...1782 lines suppressed...]
+ }
+ obj1.free();
+ }
+}
+
+Annot *Annots::findAnnot(Ref *ref) {
+ int i;
+
+ for (i = 0; i < nAnnots; ++i) {
+ if (annots[i]->match(ref)) {
+ return annots[i];
+ }
+ }
+ return NULL;
+}
+
+
Annots::~Annots() {
int i;
Index: Annot.h
===================================================================
RCS file: /cvs/poppler/poppler/poppler/Annot.h,v
retrieving revision 1.5
retrieving revision 1.6
diff -u -d -r1.5 -r1.6
--- Annot.h 25 Feb 2007 00:34:21 -0000 1.5
+++ Annot.h 25 Apr 2007 19:59:10 -0000 1.6
@@ -18,7 +18,43 @@
class Catalog;
class CharCodeToUnicode;
class GfxFont;
-class FormWidget;
+class GfxFontDict;
+
+//------------------------------------------------------------------------
+// AnnotBorderStyle
+//------------------------------------------------------------------------
+
+enum AnnotBorderType {
+ annotBorderSolid,
+ annotBorderDashed,
+ annotBorderBeveled,
+ annotBorderInset,
+ annotBorderUnderlined
+};
+
+class AnnotBorderStyle {
+public:
+
+ AnnotBorderStyle(AnnotBorderType typeA, double widthA,
+ double *dashA, int dashLengthA,
+ double rA, double gA, double bA);
+ ~AnnotBorderStyle();
+
+ AnnotBorderType getType() { return type; }
+ double getWidth() { return width; }
+ void getDash(double **dashA, int *dashLengthA)
+ { *dashA = dash; *dashLengthA = dashLength; }
+ void getColor(double *rA, double *gA, double *bA)
+ { *rA = r; *gA = g; *bA = b; }
+
+private:
+
+ AnnotBorderType type;
+ double width;
+ double *dash;
+ int dashLength;
+ double r, g, b;
+};
//------------------------------------------------------------------------
// Annot
@@ -32,30 +68,57 @@
~Annot();
GBool isOk() { return ok; }
- void draw(Gfx *gfx);
+ void draw(Gfx *gfx, GBool printing);
// Get appearance object.
Object *getAppearance(Object *obj) { return appearance.fetch(xref, obj); }
GBool textField() { return isTextField; }
+ AnnotBorderStyle *getBorderStyle () { return borderStyle; }
+
+ GBool match(Ref *refA)
+ { return ref.num == refA->num && ref.gen == refA->gen; }
+
+ void generateFieldAppearance(Dict *field, Dict *annot, Dict *acroForm);
+
double getXMin() { return xMin; }
double getYMin() { return yMin; }
double getFontSize() { return fontSize; }
private:
- void writeTextString (GooString* vStr, CharCodeToUnicode* ccToUnicode, GooString* appearBuf, GfxFont* font);
- void generateAppearance(Dict *acroForm, Dict *dict);
+// void writeTextString (GooString* vStr, CharCodeToUnicode* ccToUnicode, GooString* appearBuf, GfxFont* font);
+// void generateAppearance(Dict *acroForm, Dict *dict);
+ void setColor(Array *a, GBool fill, int adjust);
+ void drawText(GooString *text, GooString *da, GfxFontDict *fontDict,
+ GBool multiline, int comb, int quadding,
+ GBool txField, GBool forceZapfDingbats);
+ void drawListBox(GooString **text, GBool *selection,
+ int nOptions, int topIdx,
+ GooString *da, GfxFontDict *fontDict, GBool quadding);
+ void getNextLine(GooString *text, int start,
+ GfxFont *font, double fontSize, double wMax,
+ int *end, double *width, int *next);
+ void drawCircle(double cx, double cy, double r, GBool fill);
+ void drawCircleTopLeft(double cx, double cy, double r);
+ void drawCircleBottomRight(double cx, double cy, double r);
+ Object *fieldLookup(Dict *field, char *key, Object *obj);
void readArrayNum(Object *pdfArray, int key, double *value);
+ // write vStr[i:j[ in appearBuf
+ void writeTextString (GooString *text, GooString *appearBuf, int *i, int j, CharCodeToUnicode *ccToUnicode);
void initialize (XRef *xrefA, Dict *acroForm, Dict *dict, Catalog *catalog);
XRef *xref; // the xref table for this PDF file
+ Ref ref; // object ref identifying this annotation
+ GooString *type; // annotation type
Object appearance; // a reference to the Form XObject stream
// for the normal appearance
GooString *appearBuf;
+ Guint flags;
double xMin, yMin, // annotation rectangle
xMax, yMax;
+ AnnotBorderStyle *borderStyle;
double fontSize;
GBool ok;
GBool regen, isTextField;
@@ -63,8 +126,6 @@
bool hasRef;
bool hidden;
- Ref ref;
- FormWidget* widget;
};
//------------------------------------------------------------------------
@@ -74,7 +135,7 @@
class Annots {
public:
- // Extract non-link annotations from array of annotations.
+ // Build a list of Annot objects.
Annots(XRef *xref, Catalog *catalog, Object *annotsObj);
~Annots();
@@ -83,7 +144,15 @@
int getNumAnnots() { return nAnnots; }
Annot *getAnnot(int i) { return annots[i]; }
+ // (Re)generate the appearance streams for all annotations belonging
+ // to a form field.
+ void generateAppearances(Dict *acroForm);
+
+
private:
+ void scanFieldAppearances(Dict *node, Ref *ref, Dict *parent,
+ Dict *acroForm);
+ Annot *findAnnot(Ref *ref);
Annot **annots;
int nAnnots;
Index: ArthurOutputDev.cc
===================================================================
RCS file: /cvs/poppler/poppler/poppler/ArthurOutputDev.cc,v
retrieving revision 1.12
retrieving revision 1.13
diff -u -d -r1.12 -r1.13
--- ArthurOutputDev.cc 13 Nov 2006 19:16:44 -0000 1.12
+++ ArthurOutputDev.cc 25 Apr 2007 19:59:10 -0000 1.13
@@ -241,6 +241,8 @@
void ArthurOutputDev::updateFont(GfxState *state)
{
+#warning fix this, probably update with updated code from SplashOutputdev
+/*
GfxFont *gfxFont;
GfxFontType fontType;
SplashOutFontFileID *id;
@@ -403,7 +405,7 @@
err2:
delete id;
- err1:
+ err1:*/
return;
}
@@ -513,9 +515,12 @@
qPath.quadTo(x0+fontPath->pts[i].x, y0+fontPath->pts[i].y,
x0+fontPath->pts[i+1].x, y0+fontPath->pts[i+1].y);
++i;
- } else if (fontPath->flags[i] & splashPathArcCW) {
- qDebug() << "Need to implement arc";
- } else {
+ }
+#warning FIX THIS
+// else if (fontPath->flags[i] & splashPathArcCW) {
+// qDebug() << "Need to implement arc";
+// }
+ else {
qPath.lineTo(x0+fontPath->pts[i].x, y0+fontPath->pts[i].y);
}
if (fontPath->flags[i] & splashPathLast) {
Index: Catalog.cc
===================================================================
RCS file: /cvs/poppler/poppler/poppler/Catalog.cc,v
retrieving revision 1.19
retrieving revision 1.20
diff -u -d -r1.19 -r1.20
--- Catalog.cc 24 Feb 2007 23:32:23 -0000 1.19
+++ Catalog.cc 25 Apr 2007 19:59:10 -0000 1.20
@@ -2,7 +2,7 @@
//
// Catalog.cc
//
-// Copyright 1996-2003 Glyph & Cog, LLC
+// Copyright 1996-2007 Glyph & Cog, LLC
//
//========================================================================
@@ -23,23 +23,17 @@
#include "Error.h"
#include "Link.h"
#include "PageLabelInfo.h"
-#include "UGooString.h"
#include "Catalog.h"
#include "Form.h"
-// This define is used to limit the depth of recursive readPageTree calls
-// This is needed because the page tree nodes can reference their parents
-// leaving us in an infinite loop
-// Most sane pdf documents don't have a call depth higher than 10
-#define MAX_CALL_DEPTH 1000
-
//------------------------------------------------------------------------
// Catalog
//------------------------------------------------------------------------
Catalog::Catalog(XRef *xrefA) {
- Object catDict, pagesDict;
+ Object catDict, pagesDict, pagesDictRef;
Object obj, obj2;
+ char *alreadyRead;
int numPages0;
int i;
@@ -91,7 +85,16 @@
pageRefs[i].num = -1;
pageRefs[i].gen = -1;
}
- numPages = readPageTree(pagesDict.getDict(), NULL, 0, 0);
+ alreadyRead = (char *)gmalloc(xref->getNumObjects());
+ memset(alreadyRead, 0, xref->getNumObjects());
+ if (catDict.dictLookupNF("Pages", &pagesDictRef)->isRef() &&
+ pagesDictRef.getRefNum() >= 0 &&
+ pagesDictRef.getRefNum() < xref->getNumObjects()) {
+ alreadyRead[pagesDictRef.getRefNum()] = 1;
+ }
+ pagesDictRef.free();
+ numPages = readPageTree(pagesDict.getDict(), NULL, 0, alreadyRead);
+ gfree(alreadyRead);
if (numPages != numPages0) {
error(-1, "Page count in top-level pages object is incorrect");
}
@@ -234,7 +237,8 @@
return s;
}
-int Catalog::readPageTree(Dict *pagesDict, PageAttrs *attrs, int start, int callDepth) {
+int Catalog::readPageTree(Dict *pagesDict, PageAttrs *attrs, int start,
+ char *alreadyRead) {
Object kids;
Object kid;
Object kidRef;
@@ -250,6 +254,17 @@
goto err1;
}
for (i = 0; i < kids.arrayGetLength(); ++i) {
+ kids.arrayGetNF(i, &kidRef);
+ if (kidRef.isRef() &&
+ kidRef.getRefNum() >= 0 &&
+ kidRef.getRefNum() < xref->getNumObjects()) {
+ if (alreadyRead[kidRef.getRefNum()]) {
+ error(-1, "Loop in Pages tree");
+ kidRef.free();
+ continue;
+ }
+ alreadyRead[kidRef.getRefNum()] = 1;
+ }
kids.arrayGet(i, &kid);
if (kid.isDict("Page")) {
attrs2 = new PageAttrs(attrs1, kid.getDict());
@@ -269,28 +284,23 @@
}
}
pages[start] = page;
- kids.arrayGetNF(i, &kidRef);
if (kidRef.isRef()) {
pageRefs[start].num = kidRef.getRefNum();
pageRefs[start].gen = kidRef.getRefGen();
}
- kidRef.free();
++start;
// This should really be isDict("Pages"), but I've seen at least one
// PDF file where the /Type entry is missing.
} else if (kid.isDict()) {
- if (callDepth > MAX_CALL_DEPTH) {
- error(-1, "Limit of %d recursive calls reached while reading the page tree. If your document is correct and not a test to try to force a crash, please report a bug.", MAX_CALL_DEPTH);
- } else {
- if ((start = readPageTree(kid.getDict(), attrs1, start, callDepth + 1))
- < 0)
- goto err2;
- }
+ if ((start = readPageTree(kid.getDict(), attrs1, start, alreadyRead))
+ < 0)
+ goto err2;
} else {
error(-1, "Kid object (page %d) is wrong type (%s)",
start+1, kid.getTypeName());
}
kid.free();
+ kidRef.free();
}
delete attrs1;
kids.free();
@@ -317,7 +327,7 @@
return 0;
}
-LinkDest *Catalog::findDest(UGooString *name) {
+LinkDest *Catalog::findDest(GooString *name) {
LinkDest *dest;
Object obj1, obj2;
GBool found;
@@ -325,7 +335,7 @@
// try named destination dictionary then name tree
found = gFalse;
if (dests.isDict()) {
- if (!dests.dictLookup(*name, &obj1)->isNull())
+ if (!dests.dictLookup(name->getCString(), &obj1)->isNull())
found = gTrue;
else
obj1.free();
@@ -377,7 +387,7 @@
delete[] descString;
GooString *createDate = new GooString();
GooString *modDate = new GooString();
- Stream *efStream;
+ Stream *efStream = NULL;
if (obj.isRef()) {
if (obj.fetch(xref, &efDict)->isDict()) {
// efDict matches Table 3.40 in the PDF1.6 spec
@@ -452,7 +462,7 @@
return embeddedFile;
}
-NameTree::NameTree(void)
+NameTree::NameTree()
{
size = 0;
length = 0;
@@ -460,23 +470,20 @@
}
NameTree::Entry::Entry(Array *array, int index) {
- GooString n;
- if (!array->getString(index, &n) || !array->getNF(index + 1, &value)) {
+ if (!array->getString(index, &name) || !array->getNF(index + 1, &value)) {
Object aux;
array->get(index, &aux);
if (aux.isString() && array->getNF(index + 1, &value) )
{
- n.append(aux.getString());
+ name.append(aux.getString());
}
else
error(-1, "Invalid page tree");
}
- name = new UGooString(n);
}
NameTree::Entry::~Entry() {
value.free();
- delete name;
}
void NameTree::addEntry(Entry *entry)
@@ -531,13 +538,13 @@
int NameTree::Entry::cmp(const void *voidKey, const void *voidEntry)
{
- UGooString *key = (UGooString *) voidKey;
+ GooString *key = (GooString *) voidKey;
Entry *entry = *(NameTree::Entry **) voidEntry;
- return key->cmp(entry->name);
+ return key->cmp(&entry->name);
}
-GBool NameTree::lookup(UGooString *name, Object *obj)
+GBool NameTree::lookup(GooString *name, Object *obj)
{
Entry **entry;
char *cname;
@@ -548,9 +555,7 @@
(*entry)->value.fetch(xref, obj);
return gTrue;
} else {
- cname = name->getCString();
- printf("failed to look up %s\n", cname);
- delete[] cname;
+ printf("failed to look up %s\n", name->getCString());
obj->initNull();
return gFalse;
}
@@ -565,10 +570,10 @@
}
}
-UGooString *NameTree::getName(int index)
+GooString *NameTree::getName(int index)
{
if (index < length) {
- return entries[index]->name;
+ return &entries[index]->name;
} else {
return NULL;
}
Index: Catalog.h
===================================================================
RCS file: /cvs/poppler/poppler/poppler/Catalog.h,v
retrieving revision 1.11
retrieving revision 1.12
diff -u -d -r1.11 -r1.12
--- Catalog.h 24 Feb 2007 23:32:23 -0000 1.11
+++ Catalog.h 25 Apr 2007 19:59:10 -0000 1.12
@@ -2,7 +2,7 @@
//
// Catalog.h
//
-// Copyright 1996-2003 Glyph & Cog, LLC
+// Copyright 1996-2007 Glyph & Cog, LLC
//
//========================================================================
@@ -19,7 +19,6 @@
class PageAttrs;
struct Ref;
class LinkDest;
-class UGooString;
class PageLabelInfo;
class Form;
@@ -32,18 +31,18 @@
NameTree();
void init(XRef *xref, Object *tree);
void parse(Object *tree);
- GBool lookup(UGooString *name, Object *obj);
+ GBool lookup(GooString *name, Object *obj);
void free();
int numEntries() { return length; };
// iterator accessor
Object getValue(int i);
- UGooString *getName(int i);
+ GooString *getName(int i);
private:
struct Entry {
Entry(Array *array, int index);
~Entry();
- UGooString *name;
+ GooString name;
Object value;
void free();
static int cmp(const void *key, const void *entry);
@@ -136,7 +135,9 @@
// Find a named destination. Returns the link destination, or
// NULL if <name> is not a destination.
- LinkDest *findDest(UGooString *name);
+ LinkDest *findDest(GooString *name);
+
+ Object *getDests() { return &dests; }
// Get the number of embedded files
int numEmbeddedFiles() { return embeddedFileNameTree.numEntries(); }
@@ -197,7 +198,8 @@
PageMode pageMode; // page mode
PageLayout pageLayout; // page layout
- int readPageTree(Dict *pages, PageAttrs *attrs, int start, int callDepth);
+ int readPageTree(Dict *pages, PageAttrs *attrs, int start,
+ char *alreadyRead);
Object *findDestInTree(Object *tree, GooString *name, Object *obj);
};
Index: CharCodeToUnicode.cc
===================================================================
RCS file: /cvs/poppler/poppler/poppler/CharCodeToUnicode.cc,v
retrieving revision 1.5
retrieving revision 1.6
diff -u -d -r1.5 -r1.6
--- CharCodeToUnicode.cc 24 Feb 2007 23:32:23 -0000 1.5
+++ CharCodeToUnicode.cc 25 Apr 2007 19:59:10 -0000 1.6
@@ -243,18 +243,8 @@
}
if (!(n1 == 2 + nDigits && tok1[0] == '<' && tok1[n1 - 1] == '>' &&
tok2[0] == '<' && tok2[n2 - 1] == '>')) {
-
- // check there was no line jump inside the token and so the length is
- // longer than it should be
- int countAux = 0;
- for (int k = 0; k < n1; k++)
- if (tok1[k] != '\n' && tok1[k] != '\r') countAux++;
-
- if (!(countAux == 2 + nDigits && tok1[0] == '<' && tok1[n1 - 1] == '>' &&
- tok2[0] == '<' && tok2[n2 - 1] == '>')) {
- error(-1, "Illegal entry in bfchar block in ToUnicode CMap");
- continue;
- }
+ 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) {
@@ -278,21 +268,8 @@
}
if (!(n1 == 2 + nDigits && tok1[0] == '<' && tok1[n1 - 1] == '>' &&
n2 == 2 + nDigits && tok2[0] == '<' && tok2[n2 - 1] == '>')) {
- // check there was no line jump inside the token and so the length is
- // longer than it should be
- int countAux = 0;
- for (int k = 0; k < n1; k++)
- if (tok1[k] != '\n' && tok1[k] != '\r') countAux++;
-
- int countAux2 = 0;
- for (int k = 0; k < n1; k++)
- if (tok2[k] != '\n' && tok2[k] != '\r') countAux++;
-
- if (!(countAux == 2 + nDigits && tok1[0] == '<' && tok1[n1 - 1] == '>' &&
- countAux2 == 2 + nDigits && tok2[0] == '<' && tok2[n2 - 1] == '>')) {
- error(-1, "Illegal entry in bfrange block in ToUnicode CMap");
- continue;
- }
+ error(-1, "Illegal entry in bfrange block in ToUnicode CMap");
+ continue;
}
tok1[n1 - 1] = tok2[n2 - 1] = '\0';
if (sscanf(tok1 + 1, "%x", &code1) != 1 ||
Index: DCTStream.cc
===================================================================
RCS file: /cvs/poppler/poppler/poppler/DCTStream.cc,v
retrieving revision 1.5
retrieving revision 1.6
diff -u -d -r1.5 -r1.6
--- DCTStream.cc 28 Jun 2006 19:23:52 -0000 1.5
+++ DCTStream.cc 25 Apr 2007 19:59:10 -0000 1.6
@@ -52,7 +52,7 @@
{
}
-DCTStream::DCTStream(Stream *strA):
+DCTStream::DCTStream(Stream *strA, int colorXformA) :
FilterStream(strA) {
init();
}
Index: DCTStream.h
===================================================================
RCS file: /cvs/poppler/poppler/poppler/DCTStream.h,v
retrieving revision 1.6
retrieving revision 1.7
diff -u -d -r1.6 -r1.7
--- DCTStream.h 28 Jun 2006 19:23:52 -0000 1.6
+++ DCTStream.h 25 Apr 2007 19:59:10 -0000 1.7
@@ -50,7 +50,7 @@
class DCTStream: public FilterStream {
public:
- DCTStream(Stream *strA);
+ DCTStream(Stream *strA, int colorXformA);
virtual ~DCTStream();
virtual StreamKind getKind() { return strDCT; }
virtual void reset();
@@ -70,4 +70,4 @@
JSAMPARRAY row_buffer;
};
-#endif
+#endif
Index: Decrypt.cc
===================================================================
RCS file: /cvs/poppler/poppler/poppler/Decrypt.cc,v
retrieving revision 1.3
retrieving revision 1.4
diff -u -d -r1.3 -r1.4
--- Decrypt.cc 16 Sep 2005 18:29:18 -0000 1.3
+++ Decrypt.cc 25 Apr 2007 19:59:10 -0000 1.4
@@ -18,6 +18,9 @@
static void rc4InitKey(Guchar *key, int keyLen, Guchar *state);
static Guchar rc4DecryptByte(Guchar *state, Guchar *x, Guchar *y, Guchar c);
+static void aesKeyExpansion(DecryptAESState *s,
+ Guchar *objKey, int objKeyLen);
+static void aesDecryptBlock(DecryptAESState *s, Guchar *in, GBool last);
static void md5(Guchar *msg, int msgLen, Guchar *digest);
static Guchar passwordPad[32] = {
@@ -31,37 +34,6 @@
// Decrypt
//------------------------------------------------------------------------
-Decrypt::Decrypt(Guchar *fileKey, int keyLength, int objNum, int objGen) {
- int i;
-
- // construct object key
- for (i = 0; i < keyLength; ++i) {
- objKey[i] = fileKey[i];
- }
- objKey[keyLength] = objNum & 0xff;
- objKey[keyLength + 1] = (objNum >> 8) & 0xff;
- objKey[keyLength + 2] = (objNum >> 16) & 0xff;
- objKey[keyLength + 3] = objGen & 0xff;
- objKey[keyLength + 4] = (objGen >> 8) & 0xff;
- md5(objKey, keyLength + 5, objKey);
-
- // set up for decryption
- x = y = 0;
- if ((objKeyLength = keyLength + 5) > 16) {
- objKeyLength = 16;
- }
- rc4InitKey(objKey, objKeyLength, state);
-}
-
-void Decrypt::reset() {
- x = y = 0;
- rc4InitKey(objKey, objKeyLength, state);
-}
-
-Guchar Decrypt::decryptByte(Guchar c) {
- return rc4DecryptByte(state, &x, &y, c);
-}
-
GBool Decrypt::makeFileKey(int encVersion, int encRevision, int keyLength,
GooString *ownerKey, GooString *userKey,
int permissions, GooString *fileID,
@@ -206,6 +178,144 @@
}
//------------------------------------------------------------------------
+// DecryptStream
+//------------------------------------------------------------------------
+
+DecryptStream::DecryptStream(Stream *strA, Guchar *fileKey,
+ CryptAlgorithm algoA, int keyLength,
+ int objNum, int objGen):
+ FilterStream(strA)
+{
+ int n, i;
+
+ algo = algoA;
+
+ // construct object key
+ for (i = 0; i < keyLength; ++i) {
+ objKey[i] = fileKey[i];
+ }
+ objKey[keyLength] = objNum & 0xff;
+ objKey[keyLength + 1] = (objNum >> 8) & 0xff;
+ objKey[keyLength + 2] = (objNum >> 16) & 0xff;
+ objKey[keyLength + 3] = objGen & 0xff;
+ objKey[keyLength + 4] = (objGen >> 8) & 0xff;
+ if (algo == cryptAES) {
+ objKey[keyLength + 5] = 0x73; // 's'
+ objKey[keyLength + 6] = 0x41; // 'A'
+ objKey[keyLength + 7] = 0x6c; // 'l'
+ objKey[keyLength + 8] = 0x54; // 'T'
+ n = keyLength + 9;
+ } else {
+ n = keyLength + 5;
+ }
+ md5(objKey, n, objKey);
+ if ((objKeyLength = keyLength + 5) > 16) {
+ objKeyLength = 16;
+ }
+}
+
+DecryptStream::~DecryptStream() {
+ delete str;
+}
+
+void DecryptStream::reset() {
+ int i;
+
+ str->reset();
+ switch (algo) {
+ case cryptRC4:
+ state.rc4.x = state.rc4.y = 0;
+ rc4InitKey(objKey, objKeyLength, state.rc4.state);
+ state.rc4.buf = EOF;
+ break;
+ case cryptAES:
+ aesKeyExpansion(&state.aes, objKey, objKeyLength);
+ for (i = 0; i < 16; ++i) {
+ state.aes.cbc[i] = str->getChar();
+ }
+ state.aes.bufIdx = 16;
+ break;
+ }
+}
+
+int DecryptStream::getChar() {
+ Guchar in[16];
+ int c, i;
+
+ c = EOF; // make gcc happy
+ switch (algo) {
+ case cryptRC4:
+ if (state.rc4.buf == EOF) {
+ c = str->getChar();
+ if (c != EOF) {
+ state.rc4.buf = rc4DecryptByte(state.rc4.state, &state.rc4.x,
+ &state.rc4.y, (Guchar)c);
+ }
+ }
+ c = state.rc4.buf;
+ state.rc4.buf = EOF;
+ break;
+ case cryptAES:
+ if (state.aes.bufIdx == 16) {
+ for (i = 0; i < 16; ++i) {
+ if ((c = str->getChar()) == EOF) {
+ return EOF;
+ }
+ in[i] = (Guchar)c;
+ }
+ aesDecryptBlock(&state.aes, in, str->lookChar() == EOF);
+ }
+ if (state.aes.bufIdx == 16) {
+ c = EOF;
+ } else {
+ c = state.aes.buf[state.aes.bufIdx++];
+ }
+ break;
+ }
+ return c;
+}
+
+int DecryptStream::lookChar() {
+ Guchar in[16];
+ int c, i;
+
+ c = EOF; // make gcc happy
+ switch (algo) {
+ case cryptRC4:
+ if (state.rc4.buf == EOF) {
+ c = str->getChar();
+ if (c != EOF) {
+ state.rc4.buf = rc4DecryptByte(state.rc4.state, &state.rc4.x,
+ &state.rc4.y, (Guchar)c);
+ }
+ }
+ c = state.rc4.buf;
+ break;
+ case cryptAES:
+ if (state.aes.bufIdx == 16) {
+ for (i = 0; i < 16; ++i) {
+ if ((c = str->getChar()) == EOF) {
+ return EOF;
+ }
+ in[i] = c;
+ }
+ aesDecryptBlock(&state.aes, in, str->lookChar() == EOF);
+ }
+ if (state.aes.bufIdx == 16) {
+ c = EOF;
+ } else {
+ c = state.aes.buf[state.aes.bufIdx];
+ }
+ break;
+ }
+ return c;
+}
+
+GBool DecryptStream::isBinary(GBool last) {
+ return str->isBinary(last);
+}
+
+//------------------------------------------------------------------------
// RC4-compatible decryption
//------------------------------------------------------------------------
@@ -239,6 +349,261 @@
}
//------------------------------------------------------------------------
+// AES decryption
+//------------------------------------------------------------------------
+
+static Guchar sbox[256] = {
+ 0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5, 0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76,
+ 0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0, 0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0,
+ 0xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc, 0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15,
+ 0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a, 0x07, 0x12, 0x80, 0xe2, 0xeb, 0x27, 0xb2, 0x75,
+ 0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0, 0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3, 0x2f, 0x84,
+ 0x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b, 0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf,
+ 0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85, 0x45, 0xf9, 0x02, 0x7f, 0x50, 0x3c, 0x9f, 0xa8,
+ 0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5, 0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2,
+ 0xcd, 0x0c, 0x13, 0xec, 0x5f, 0x97, 0x44, 0x17, 0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19, 0x73,
+ 0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88, 0x46, 0xee, 0xb8, 0x14, 0xde, 0x5e, 0x0b, 0xdb,
+ 0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c, 0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79,
+ 0xe7, 0xc8, 0x37, 0x6d, 0x8d, 0xd5, 0x4e, 0xa9, 0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a, 0xae, 0x08,
+ 0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6, 0xe8, 0xdd, 0x74, 0x1f, 0x4b, 0xbd, 0x8b, 0x8a,
+ 0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e, 0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e,
+ 0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94, 0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf,
+ 0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68, 0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16
+};
+
+static Guchar invSbox[256] = {
+ 0x52, 0x09, 0x6a, 0xd5, 0x30, 0x36, 0xa5, 0x38, 0xbf, 0x40, 0xa3, 0x9e, 0x81, 0xf3, 0xd7, 0xfb,
+ 0x7c, 0xe3, 0x39, 0x82, 0x9b, 0x2f, 0xff, 0x87, 0x34, 0x8e, 0x43, 0x44, 0xc4, 0xde, 0xe9, 0xcb,
+ 0x54, 0x7b, 0x94, 0x32, 0xa6, 0xc2, 0x23, 0x3d, 0xee, 0x4c, 0x95, 0x0b, 0x42, 0xfa, 0xc3, 0x4e,
+ 0x08, 0x2e, 0xa1, 0x66, 0x28, 0xd9, 0x24, 0xb2, 0x76, 0x5b, 0xa2, 0x49, 0x6d, 0x8b, 0xd1, 0x25,
+ 0x72, 0xf8, 0xf6, 0x64, 0x86, 0x68, 0x98, 0x16, 0xd4, 0xa4, 0x5c, 0xcc, 0x5d, 0x65, 0xb6, 0x92,
+ 0x6c, 0x70, 0x48, 0x50, 0xfd, 0xed, 0xb9, 0xda, 0x5e, 0x15, 0x46, 0x57, 0xa7, 0x8d, 0x9d, 0x84,
+ 0x90, 0xd8, 0xab, 0x00, 0x8c, 0xbc, 0xd3, 0x0a, 0xf7, 0xe4, 0x58, 0x05, 0xb8, 0xb3, 0x45, 0x06,
+ 0xd0, 0x2c, 0x1e, 0x8f, 0xca, 0x3f, 0x0f, 0x02, 0xc1, 0xaf, 0xbd, 0x03, 0x01, 0x13, 0x8a, 0x6b,
+ 0x3a, 0x91, 0x11, 0x41, 0x4f, 0x67, 0xdc, 0xea, 0x97, 0xf2, 0xcf, 0xce, 0xf0, 0xb4, 0xe6, 0x73,
+ 0x96, 0xac, 0x74, 0x22, 0xe7, 0xad, 0x35, 0x85, 0xe2, 0xf9, 0x37, 0xe8, 0x1c, 0x75, 0xdf, 0x6e,
+ 0x47, 0xf1, 0x1a, 0x71, 0x1d, 0x29, 0xc5, 0x89, 0x6f, 0xb7, 0x62, 0x0e, 0xaa, 0x18, 0xbe, 0x1b,
+ 0xfc, 0x56, 0x3e, 0x4b, 0xc6, 0xd2, 0x79, 0x20, 0x9a, 0xdb, 0xc0, 0xfe, 0x78, 0xcd, 0x5a, 0xf4,
+ 0x1f, 0xdd, 0xa8, 0x33, 0x88, 0x07, 0xc7, 0x31, 0xb1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xec, 0x5f,
+ 0x60, 0x51, 0x7f, 0xa9, 0x19, 0xb5, 0x4a, 0x0d, 0x2d, 0xe5, 0x7a, 0x9f, 0x93, 0xc9, 0x9c, 0xef,
+ 0xa0, 0xe0, 0x3b, 0x4d, 0xae, 0x2a, 0xf5, 0xb0, 0xc8, 0xeb, 0xbb, 0x3c, 0x83, 0x53, 0x99, 0x61,
+ 0x17, 0x2b, 0x04, 0x7e, 0xba, 0x77, 0xd6, 0x26, 0xe1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0c, 0x7d
+};
+
+static Guint rcon[11] = {
+ 0x00000000, // unused
+ 0x01000000,
+ 0x02000000,
+ 0x04000000,
+ 0x08000000,
+ 0x10000000,
+ 0x20000000,
+ 0x40000000,
+ 0x80000000,
+ 0x1b000000,
+ 0x36000000
+};
+
+static inline Guint subWord(Guint x) {
+ return (sbox[x >> 24] << 24)
+ | (sbox[(x >> 16) & 0xff] << 16)
+ | (sbox[(x >> 8) & 0xff] << 8)
+ | sbox[x & 0xff];
+}
+
+static inline Guint rotWord(Guint x) {
+ return ((x << 8) & 0xffffffff) | (x >> 24);
+}
+
+static inline void invSubBytes(Guchar *state) {
+ int i;
+
+ for (i = 0; i < 16; ++i) {
+ state[i] = invSbox[state[i]];
+ }
+}
+
+static inline void invShiftRows(Guchar *state) {
+ Guchar t;
+
+ t = state[7];
+ state[7] = state[6];
+ state[6] = state[5];
+ state[5] = state[4];
+ state[4] = t;
+
+ t = state[8];
+ state[8] = state[10];
+ state[10] = t;
+ t = state[9];
+ state[9] = state[11];
+ state[11] = t;
+
+ t = state[12];
+ state[12] = state[13];
+ state[13] = state[14];
+ state[14] = state[15];
+ state[15] = t;
+}
+
+// {09} \cdot s
+static inline Guchar mul09(Guchar s) {
+ Guchar s2, s4, s8;
+
+ s2 = (s & 0x80) ? ((s << 1) ^ 0x1b) : (s << 1);
+ s4 = (s2 & 0x80) ? ((s2 << 1) ^ 0x1b) : (s2 << 1);
+ s8 = (s4 & 0x80) ? ((s4 << 1) ^ 0x1b) : (s4 << 1);
+ return s ^ s8;
+}
+
+// {0b} \cdot s
+static inline Guchar mul0b(Guchar s) {
+ Guchar s2, s4, s8;
+
+ s2 = (s & 0x80) ? ((s << 1) ^ 0x1b) : (s << 1);
+ s4 = (s2 & 0x80) ? ((s2 << 1) ^ 0x1b) : (s2 << 1);
+ s8 = (s4 & 0x80) ? ((s4 << 1) ^ 0x1b) : (s4 << 1);
+ return s ^ s2 ^ s8;
+}
+
+// {0d} \cdot s
+static inline Guchar mul0d(Guchar s) {
+ Guchar s2, s4, s8;
+
+ s2 = (s & 0x80) ? ((s << 1) ^ 0x1b) : (s << 1);
+ s4 = (s2 & 0x80) ? ((s2 << 1) ^ 0x1b) : (s2 << 1);
+ s8 = (s4 & 0x80) ? ((s4 << 1) ^ 0x1b) : (s4 << 1);
+ return s ^ s4 ^ s8;
+}
+
+// {0e} \cdot s
+static inline Guchar mul0e(Guchar s) {
+ Guchar s2, s4, s8;
+
+ s2 = (s & 0x80) ? ((s << 1) ^ 0x1b) : (s << 1);
+ s4 = (s2 & 0x80) ? ((s2 << 1) ^ 0x1b) : (s2 << 1);
+ s8 = (s4 & 0x80) ? ((s4 << 1) ^ 0x1b) : (s4 << 1);
+ return s2 ^ s4 ^ s8;
+}
+
+static inline void invMixColumns(Guchar *state) {
+ int c;
+ Guchar s0, s1, s2, s3;
+
+ for (c = 0; c < 4; ++c) {
+ s0 = state[c];
+ s1 = state[4+c];
+ s2 = state[8+c];
+ s3 = state[12+c];
+ state[c] = mul0e(s0) ^ mul0b(s1) ^ mul0d(s2) ^ mul09(s3);
+ state[4+c] = mul09(s0) ^ mul0e(s1) ^ mul0b(s2) ^ mul0d(s3);
+ state[8+c] = mul0d(s0) ^ mul09(s1) ^ mul0e(s2) ^ mul0b(s3);
+ state[12+c] = mul0b(s0) ^ mul0d(s1) ^ mul09(s2) ^ mul0e(s3);
+ }
+}
+
+static inline void invMixColumnsW(Guint *w) {
+ int c;
+ Guchar s0, s1, s2, s3;
+
+ for (c = 0; c < 4; ++c) {
+ s0 = w[c] >> 24;
+ s1 = w[c] >> 16;
+ s2 = w[c] >> 8;
+ s3 = w[c];
+ w[c] = ((mul0e(s0) ^ mul0b(s1) ^ mul0d(s2) ^ mul09(s3)) << 24)
+ | ((mul09(s0) ^ mul0e(s1) ^ mul0b(s2) ^ mul0d(s3)) << 16)
+ | ((mul0d(s0) ^ mul09(s1) ^ mul0e(s2) ^ mul0b(s3)) << 8)
+ | (mul0b(s0) ^ mul0d(s1) ^ mul09(s2) ^ mul0e(s3));
+ }
+}
+
+static inline void addRoundKey(Guchar *state, Guint *w) {
+ int c;
+
+ for (c = 0; c < 4; ++c) {
+ state[c] ^= w[c] >> 24;
+ state[4+c] ^= w[c] >> 16;
+ state[8+c] ^= w[c] >> 8;
+ state[12+c] ^= w[c];
+ }
+}
+
+static void aesKeyExpansion(DecryptAESState *s,
+ Guchar *objKey, int /*objKeyLen*/) {
+ Guint temp;
+ int i, round;
+
+ //~ this assumes objKeyLen == 16
+
+ for (i = 0; i < 4; ++i) {
+ s->w[i] = (objKey[4*i] << 24) + (objKey[4*i+1] << 16) +
+ (objKey[4*i+2] << 8) + objKey[4*i+3];
+ }
+ for (i = 4; i < 44; ++i) {
+ temp = s->w[i-1];
+ if (!(i & 3)) {
+ temp = subWord(rotWord(temp)) ^ rcon[i/4];
+ }
+ s->w[i] = s->w[i-4] ^ temp;
+ }
+ for (round = 1; round <= 9; ++round) {
+ invMixColumnsW(&s->w[round * 4]);
+ }
+}
+
+static void aesDecryptBlock(DecryptAESState *s, Guchar *in, GBool last) {
+ int c, round, n, i;
+
+ // initial state
+ for (c = 0; c < 4; ++c) {
+ s->state[c] = in[4*c];
+ s->state[4+c] = in[4*c+1];
+ s->state[8+c] = in[4*c+2];
+ s->state[12+c] = in[4*c+3];
+ }
+
+ // round 0
+ addRoundKey(s->state, &s->w[10 * 4]);
+
+ // rounds 1-9
+ for (round = 9; round >= 1; --round) {
+ invSubBytes(s->state);
+ invShiftRows(s->state);
+ invMixColumns(s->state);
+ addRoundKey(s->state, &s->w[round * 4]);
+ }
+
+ // round 10
+ invSubBytes(s->state);
+ invShiftRows(s->state);
+ addRoundKey(s->state, &s->w[0]);
+
+ // CBC
+ for (c = 0; c < 4; ++c) {
+ s->buf[4*c] = s->state[c] ^ s->cbc[4*c];
+ s->buf[4*c+1] = s->state[4+c] ^ s->cbc[4*c+1];
+ s->buf[4*c+2] = s->state[8+c] ^ s->cbc[4*c+2];
+ s->buf[4*c+3] = s->state[12+c] ^ s->cbc[4*c+3];
+ }
+
+ // save the input block for the next CBC
+ for (i = 0; i < 16; ++i) {
+ s->cbc[i] = in[i];
+ }
+
+ // remove padding
+ s->bufIdx = 0;
+ if (last) {
+ n = s->buf[15];
+ for (i = 15; i >= n; --i) {
+ s->buf[i] = s->buf[i-n];
+ }
+ s->bufIdx = n;
+ }
+}
+
+//------------------------------------------------------------------------
// MD5 message digest
//------------------------------------------------------------------------
Index: Decrypt.h
===================================================================
RCS file: /cvs/poppler/poppler/poppler/Decrypt.h,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -d -r1.2 -r1.3
--- Decrypt.h 16 Sep 2005 18:29:18 -0000 1.2
+++ Decrypt.h 25 Apr 2007 19:59:10 -0000 1.3
@@ -15,6 +15,8 @@
#include "goo/gtypes.h"
#include "goo/GooString.h"
+#include "Object.h"
+#include "Stream.h"
//------------------------------------------------------------------------
// Decrypt
@@ -23,15 +25,6 @@
class Decrypt {
public:
- // Initialize the decryptor object.
- Decrypt(Guchar *fileKey, int keyLength, int objNum, int objGen);
-
- // Reset decryption.
- void reset();
-
- // Decrypt one byte.
- Guchar decryptByte(Guchar c);
-
// Generate a file key. The <fileKey> buffer must have space for at
// least 16 bytes. Checks <ownerPassword> and then <userPassword>
// and returns true if either is correct. Sets <ownerPasswordOk> if
@@ -51,11 +44,50 @@
int permissions, GooString *fileID,
GooString *userPassword, Guchar *fileKey,
GBool encryptMetadata);
+};
- int objKeyLength;
- Guchar objKey[21];
+//------------------------------------------------------------------------
+// DecryptStream
+//------------------------------------------------------------------------
+
+struct DecryptRC4State {
Guchar state[256];
Guchar x, y;
+ int buf;
+};
+
+struct DecryptAESState {
+ Guint w[44];
+ Guchar state[16];
+ Guchar cbc[16];
+ Guchar buf[16];
+ int bufIdx;
+};
+
+class DecryptStream: public FilterStream {
+public:
+
+ DecryptStream(Stream *strA, Guchar *fileKey,
+ CryptAlgorithm algoA, int keyLength,
+ int objNum, int objGen);
+ virtual ~DecryptStream();
+ virtual StreamKind getKind() { return strWeird; }
+ virtual void reset();
+ virtual int getChar();
+ virtual int lookChar();
+ virtual GBool isBinary(GBool last);
+ virtual Stream *getUndecodedStream() { return this; }
+
+private:
+
+ CryptAlgorithm algo;
+ int objKeyLength;
+ Guchar objKey[16 + 9];
+
+ union {
+ DecryptRC4State rc4;
+ DecryptAESState aes;
+ } state;
};
#endif
Index: Dict.cc
===================================================================
RCS file: /cvs/poppler/poppler/poppler/Dict.cc,v
retrieving revision 1.6
retrieving revision 1.7
diff -u -d -r1.6 -r1.7
--- Dict.cc 24 Feb 2007 23:32:23 -0000 1.6
+++ Dict.cc 25 Apr 2007 19:59:10 -0000 1.7
@@ -16,7 +16,6 @@
#include <string.h>
#include "goo/gmem.h"
#include "Object.h"
-#include "UGooString.h"
#include "XRef.h"
#include "Dict.h"
@@ -35,13 +34,13 @@
int i;
for (i = 0; i < length; ++i) {
- delete entries[i].key;
+ gfree(entries[i].key);
entries[i].val.free();
}
gfree(entries);
}
-void Dict::addOwnKeyVal(UGooString *key, Object *val) {
+void Dict::add(char *key, Object *val) {
if (length == size) {
if (length == 0) {
size = 8;
@@ -55,24 +54,24 @@
++length;
}
-inline DictEntry *Dict::find(const UGooString &key) {
+inline DictEntry *Dict::find(char *key) {
int i;
for (i = 0; i < length; ++i) {
- if (!key.cmp(entries[i].key))
+ if (!strcmp(key, entries[i].key))
return &entries[i];
}
return NULL;
}
-void Dict::remove(const UGooString &key) {
+void Dict::remove(char *key) {
int i;
bool found = false;
DictEntry tmp;
if(length == 0) return;
for(i=0; i<length; i++) {
- if (!key.cmp(entries[i].key)) {
+ if (!strcmp(key, entries[i].key)) {
found = true;
break;
}
@@ -85,14 +84,14 @@
entries[i] = tmp;
}
-void Dict::set(const UGooString &key, Object *val) {
+void Dict::set(char *key, Object *val) {
DictEntry *e;
e = find (key);
if (e) {
e->val.free();
e->val = *val;
} else {
- add (key, val);
+ add (copyString(key), val);
}
}
@@ -103,13 +102,13 @@
return (e = find("Type")) && e->val.isName(type);
}
-Object *Dict::lookup(const UGooString &key, Object *obj) {
+Object *Dict::lookup(char *key, Object *obj) {
DictEntry *e;
return (e = find(key)) ? e->val.fetch(xref, obj) : obj->initNull();
}
-Object *Dict::lookupNF(const UGooString &key, Object *obj) {
+Object *Dict::lookupNF(char *key, Object *obj) {
DictEntry *e;
return (e = find(key)) ? e->val.copy(obj) : obj->initNull();
@@ -135,7 +134,7 @@
return success;
}
-UGooString *Dict::getKey(int i) {
+char *Dict::getKey(int i) {
return entries[i].key;
}
Index: Dict.h
===================================================================
RCS file: /cvs/poppler/poppler/poppler/Dict.h,v
retrieving revision 1.5
retrieving revision 1.6
diff -u -d -r1.5 -r1.6
--- Dict.h 24 Feb 2007 23:32:23 -0000 1.5
+++ Dict.h 25 Apr 2007 19:59:10 -0000 1.6
@@ -14,14 +14,13 @@
#endif
#include "Object.h"
-#include "UGooString.h"
//------------------------------------------------------------------------
// Dict
//------------------------------------------------------------------------
struct DictEntry {
- UGooString *key;
+ char *key;
Object val;
};
@@ -41,31 +40,25 @@
// Get number of entries.
int getLength() { return length; }
- // Add an entry
- void addOwnKeyVal(UGooString *key, Object *val);
- // FIXME: should also be renamed to addOwnVal()
- void add(const UGooString &key, Object *val) {
- addOwnKeyVal(new UGooString(key), val);
- }
- void addOwnVal(const char *key, Object *val) {
- addOwnKeyVal(new UGooString(key), val);
- }
+ // Add an entry. NB: does not copy key.
+ void add(char *key, Object *val);
+
// Update the value of an existing entry, otherwise create it
- void set(const UGooString &key, Object *val);
+ void set(char *key, Object *val);
// Remove an entry. This invalidate indexes
- void remove(const UGooString &key);
+ void remove(char *key);
// Check if dictionary is of specified type.
GBool is(char *type);
// Look up an entry and return the value. Returns a null object
// if <key> is not in the dictionary.
- Object *lookup(const UGooString &key, Object *obj);
- Object *lookupNF(const UGooString &key, Object *obj);
+ Object *lookup(char *key, Object *obj);
+ Object *lookupNF(char *key, Object *obj);
GBool lookupInt(const char *key, const char *alt_key, int *value);
// Iterative accessors.
- UGooString *getKey(int i);
+ char *getKey(int i);
Object *getVal(int i, Object *obj);
Object *getValNF(int i, Object *obj);
@@ -82,7 +75,7 @@
int length; // number of entries in dictionary
int ref; // reference count
- DictEntry *find(const UGooString &key);
+ DictEntry *find(char *key);
};
#endif
Index: FontInfo.cc
===================================================================
RCS file: /cvs/poppler/poppler/poppler/FontInfo.cc,v
retrieving revision 1.11
retrieving revision 1.12
diff -u -d -r1.11 -r1.12
--- FontInfo.cc 14 May 2006 16:11:54 -0000 1.11
+++ FontInfo.cc 25 Apr 2007 19:59:10 -0000 1.12
@@ -12,7 +12,6 @@
#include "Annot.h"
#include "PDFDoc.h"
#include "FontInfo.h"
-#include "UGooString.h"
FontInfoScanner::FontInfoScanner(PDFDoc *docA) {
doc = docA;
Index: Form.cc
===================================================================
RCS file: /cvs/poppler/poppler/poppler/Form.cc,v
retrieving revision 1.3
retrieving revision 1.4
diff -u -d -r1.3 -r1.4
--- Form.cc 6 Mar 2007 22:27:18 -0000 1.3
+++ Form.cc 25 Apr 2007 19:59:10 -0000 1.4
@@ -21,7 +21,6 @@
#include "Array.h"
#include "Dict.h"
#include "Form.h"
-#include "UGooString.h"
#include "XRef.h"
#include "PDFDocEncoding.h"
#include "Annot.h"
@@ -202,9 +201,9 @@
for(int j=0; j<length2; j++) {
Object obj3;
tmpDict2->getVal(j, &obj3);
- UGooString *key = tmpDict2->getKey(j);
- if(strcmp(key->getCString(), "Off")) { //if we don't have Off, we have the name of the "on" state
- onStr = strdup(key->getCString());
+ char *key = tmpDict2->getKey(j);
+ if(strcmp(key, "Off")) { //if we don't have Off, we have the name of the "on" state
+ onStr = strdup(key);
}
obj3.free();
}
@@ -1066,7 +1065,7 @@
oref.free();
}
- checkForNeedAppearances();
+ checkForNeedAppearances(acroForm);
}
Form::~Form() {
@@ -1076,21 +1075,19 @@
delete [] rootFields;
}
-void Form::checkForNeedAppearances ()
+void Form::checkForNeedAppearances (Object *acroForm)
{
//NeedAppearances needs to be set to 'true' in the AcroForm entry of the Catalog to enable dynamic appearance generation
Object* catalog = new Object();
- Object acroForm;
Ref catRef;
catRef.gen = xref->getRootGen();
catRef.num = xref->getRootNum();
catalog = xref->getCatalog(catalog);
- catalog->dictLookup("AcroForm", &acroForm);
+ catalog->dictLookup("AcroForm", acroForm);
Object obj1;
obj1.initBool(true);
- acroForm.dictSet("NeedAppearances", &obj1);
- obj1.free();
- catalog->dictSet("AcroForm", &acroForm);
+ acroForm->dictSet("NeedAppearances", &obj1);
+ catalog->dictSet("AcroForm", acroForm);
xref->setModifiedObject(catalog, catRef);
}
Index: Form.h
===================================================================
RCS file: /cvs/poppler/poppler/poppler/Form.h,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -d -r1.2 -r1.3
--- Form.h 25 Feb 2007 00:34:21 -0000 1.2
+++ Form.h 25 Apr 2007 19:59:10 -0000 1.3
@@ -436,7 +436,7 @@
void createFieldFromDict (Object* obj, FormField** ptr, XRef *xref, const Ref& aref);
void postWidgetsLoad();
- void checkForNeedAppearances ();
+ void checkForNeedAppearances (Object *acroForm);
private:
FormField** rootFields;
int numFields;
Index: Function.cc
===================================================================
RCS file: /cvs/poppler/poppler/poppler/Function.cc,v
retrieving revision 1.6
retrieving revision 1.7
diff -u -d -r1.6 -r1.7
--- Function.cc 10 Dec 2006 05:24:56 -0000 1.6
+++ Function.cc 25 Apr 2007 19:59:10 -0000 1.7
@@ -22,7 +22,6 @@
#include "Stream.h"
#include "Error.h"
#include "Function.h"
-#include "UGooString.h"
//------------------------------------------------------------------------
// Function
@@ -191,10 +190,11 @@
Object obj1, obj2;
Guint buf, bitMask;
int bits;
- int s;
+ Guint s;
int i;
samples = NULL;
+ sBuf = NULL;
ok = gFalse;
//----- initialize the generic stuff
@@ -205,6 +205,14 @@
error(-1, "Type 0 function is missing range");
goto err1;
}
+ if (m > sampledFuncMaxInputs) {
+ error(-1, "Sampled functions with more than %d inputs are unsupported",
+ sampledFuncMaxInputs);
+ goto err1;
+ }
+
+ //----- buffer
+ sBuf = (double *)gmallocn(1 << m, sizeof(double));
//----- get the stream
if (!funcObj->isStream()) {
@@ -240,7 +248,7 @@
goto err2;
}
sampleBits = obj1.getInt();
- sampleMul = 1.0 / (double)((1 << sampleBits) - 1);
+ sampleMul = 1.0 / (pow(2.0, (double)sampleBits) - 1);
obj1.free();
//----- Encode
@@ -348,12 +356,16 @@
if (samples) {
gfree(samples);
}
+ if (sBuf) {
+ gfree(sBuf);
+ }
}
SampledFunction::SampledFunction(SampledFunction *func) {
memcpy(this, func, sizeof(SampledFunction));
samples = (double *)gmallocn(nSamples, sizeof(double));
memcpy(samples, func->samples, nSamples * sizeof(double));
+ sBuf = (double *)gmallocn(1 << m, sizeof(double));
}
void SampledFunction::transform(double *in, double *out) {
@@ -361,7 +373,6 @@
int e[funcMaxInputs][2];
double efrac0[funcMaxInputs];
double efrac1[funcMaxInputs];
- double s[1 << funcMaxInputs];
int i, j, k, idx, t;
// map input values into sample array
@@ -390,18 +401,18 @@
for (k = 0, t = j; k < m; ++k, t >>= 1) {
idx += idxMul[k] * (e[k][t & 1]);
}
- if (idx >= 0 && idx < nSamples) s[j] = samples[idx];
+ sBuf[j] = samples[idx];
}
// do m sets of interpolations
for (j = 0, t = (1<<m); j < m; ++j, t >>= 1) {
for (k = 0; k < t; k += 2) {
- s[k >> 1] = efrac0[j] * s[k] + efrac1[j] * s[k+1];
+ sBuf[k >> 1] = efrac0[j] * sBuf[k] + efrac1[j] * sBuf[k+1];
}
}
// map output value to range
- out[i] = s[0] * (decode[i][1] - decode[i][0]) + decode[i][0];
+ out[i] = sBuf[0] * (decode[i][1] - decode[i][0]) + decode[i][0];
if (out[i] < range[i][0]) {
out[i] = range[i][0];
} else if (out[i] > range[i][1]) {
@@ -541,6 +552,7 @@
funcs = NULL;
bounds = NULL;
encode = NULL;
+ scale = NULL;
//----- initialize the generic stuff
if (!init(dict)) {
@@ -560,6 +572,7 @@
funcs = (Function **)gmallocn(k, sizeof(Function *));
bounds = (double *)gmallocn(k + 1, sizeof(double));
encode = (double *)gmallocn(2 * k, sizeof(double));
+ scale = (double *)gmallocn(k, sizeof(double));
for (i = 0; i < k; ++i) {
funcs[i] = NULL;
}
@@ -610,6 +623,17 @@
}
obj1.free();
+ //----- pre-compute the scale factors
+ for (i = 0; i < k; ++i) {
+ if (bounds[i] == bounds[i+1]) {
+ // avoid a divide-by-zero -- in this situation, function i will
+ // never be used anyway
+ scale[i] = 0;
+ } else {
+ scale[i] = (encode[2*i+1] - encode[2*i]) / (bounds[i+1] - bounds[i]);
+ }
+ }
+
ok = gTrue;
return;
@@ -631,6 +655,8 @@
memcpy(bounds, func->bounds, (k + 1) * sizeof(double));
encode = (double *)gmallocn(2 * k, sizeof(double));
memcpy(encode, func->encode, 2 * k * sizeof(double));
+ scale = (double *)gmallocn(k, sizeof(double));
+ memcpy(scale, func->scale, k * sizeof(double));
ok = gTrue;
}
@@ -647,6 +673,7 @@
gfree(funcs);
gfree(bounds);
gfree(encode);
+ gfree(scale);
}
void StitchingFunction::transform(double *in, double *out) {
@@ -665,8 +692,7 @@
break;
}
}
- x = encode[2*i] + ((x - bounds[i]) / (bounds[i+1] - bounds[i])) *
- (encode[2*i+1] - encode[2*i]);
+ x = encode[2*i] + (x - bounds[i]) * scale[i];
funcs[i]->transform(&x, out);
}
@@ -1182,14 +1208,25 @@
GooString *PostScriptFunction::getToken(Stream *str) {
GooString *s;
int c;
+ GBool comment;
s = new GooString();
- do {
- c = str->getChar();
- if (c != EOF) {
- codeString->append(c);
+ comment = gFalse;
+ while (1) {
+ if ((c = str->getChar()) == EOF) {
+ break;
}
- } while (c != EOF && isspace(c));
+ codeString->append(c);
+ if (comment) {
+ if (c == '\x0a' || c == '\x0d') {
+ comment = gFalse;
+ }
+ } else if (c == '%') {
+ comment = gTrue;
+ } else if (!isspace(c)) {
+ break;
+ }
+ }
if (c == '{' || c == '}') {
s->append((char)c);
} else if (isdigit(c) || c == '.' || c == '-') {
Index: Function.h
===================================================================
RCS file: /cvs/poppler/poppler/poppler/Function.h,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -d -r1.2 -r1.3
--- Function.h 16 Oct 2005 14:58:14 -0000 1.2
+++ Function.h 25 Apr 2007 19:59:10 -0000 1.3
@@ -25,8 +25,9 @@
// Function
//------------------------------------------------------------------------
-#define funcMaxInputs 8
-#define funcMaxOutputs 32
+#define funcMaxInputs 32
+#define funcMaxOutputs 32
+#define sampledFuncMaxInputs 16
class Function {
public:
@@ -129,6 +130,7 @@
int idxMul[funcMaxInputs]; // sample array index multipliers
double *samples; // the samples
int nSamples; // size of the samples array
+ double *sBuf; // buffer for the transform function
GBool ok;
};
@@ -178,6 +180,7 @@
Function *getFunc(int i) { return funcs[i]; }
double *getBounds() { return bounds; }
double *getEncode() { return encode; }
+ double *getScale() { return scale; }
private:
@@ -187,6 +190,7 @@
Function **funcs;
double *bounds;
double *encode;
+ double *scale;
GBool ok;
};
Index: Gfx.cc
===================================================================
RCS file: /cvs/poppler/poppler/poppler/Gfx.cc,v
retrieving revision 1.14
retrieving revision 1.15
diff -u -d -r1.14 -r1.15
--- Gfx.cc 22 Mar 2007 20:56:25 -0000 1.14
+++ Gfx.cc 25 Apr 2007 19:59:10 -0000 1.15
@@ -32,10 +32,10 @@
#include "GfxState.h"
#include "OutputDev.h"
#include "Page.h"
+#include "Annot.h"
#include "Error.h"
#include "Gfx.h"
#include "ProfileData.h"
-#include "UGooString.h"
// the MSVC math.h doesn't define this
#ifndef M_PI
[...1760 lines suppressed...]
+ }
+ state->setLineDash(dash2, dashLength, 0);
+ out->updateLineDash(state);
+ }
+ //~ this doesn't currently handle the beveled and engraved styles
+ state->clearPath();
+ state->moveTo(annotX0, out->upsideDown() ? annotY1 : annotY0);
+ state->lineTo(annotX1, out->upsideDown() ? annotY1 : annotY0);
+ if (borderStyle->getType() != annotBorderUnderlined) {
+ state->lineTo(annotX1, out->upsideDown() ? annotY0 : annotY1);
+ state->lineTo(annotX0, out->upsideDown() ? annotY0 : annotY1);
+ state->closePath();
+ }
+ out->stroke(state);
+ }
+}
+
void Gfx::saveState() {
out->saveState(state);
state = state->save();
Index: Gfx.h
===================================================================
RCS file: /cvs/poppler/poppler/poppler/Gfx.h,v
retrieving revision 1.3
retrieving revision 1.4
diff -u -d -r1.3 -r1.4
--- Gfx.h 30 Oct 2005 20:29:05 -0000 1.3
+++ Gfx.h 25 Apr 2007 19:59:10 -0000 1.4
@@ -22,6 +22,7 @@
class Stream;
class Parser;
class Dict;
+class Function;
class OutputDev;
class GfxFontDict;
class GfxFont;
@@ -37,12 +38,12 @@
struct GfxPatch;
class GfxState;
struct GfxColor;
+class GfxColorSpace;
class Gfx;
class PDFRectangle;
+class AnnotBorderStyle;
//------------------------------------------------------------------------
-// Gfx
-//------------------------------------------------------------------------
enum GfxClipType {
clipNone,
@@ -62,7 +63,7 @@
tchkNone // used to avoid empty initializer lists
};
-#define maxArgs 8
+#define maxArgs 33
struct Operator {
char name[4];
@@ -71,6 +72,8 @@
void (Gfx::*func)(Object args[], int numArgs);
};
+//------------------------------------------------------------------------
+
class GfxResources {
public:
@@ -98,6 +101,10 @@
GfxResources *next;
};
+//------------------------------------------------------------------------
+// Gfx
+//------------------------------------------------------------------------
+
class Gfx {
public:
@@ -119,10 +126,10 @@
// Interpret a stream or array of streams.
void display(Object *obj, GBool topLevel = gTrue);
- // Display an annotation, given its appearance (a Form XObject) and
- // bounding box (in default user space).
- void doAnnot(Object *str, double xMin, double yMin,
- double xMax, double yMax);
+ // Display an annotation, given its appearance (a Form XObject),
+ // border style, and bounding box (in default user space).
+ void drawAnnot(Object *str, AnnotBorderStyle *borderStyle,
+ double xMin, double yMin, double xMax, double yMax);
// Save graphics state.
void saveState();
@@ -176,6 +183,10 @@
void opSetMiterLimit(Object args[], int numArgs);
void opSetLineWidth(Object args[], int numArgs);
void opSetExtGState(Object args[], int numArgs);
+ void doSoftMask(Object *str, GBool alpha,
+ GfxColorSpace *blendingColorSpace,
+ GBool isolated, GBool knockout,
+ Function *transferFunc, GfxColor *backdropColor);
void opSetRenderingIntent(Object args[], int numArgs);
// color operators
@@ -212,8 +223,11 @@
void opEOFillStroke(Object args[], int numArgs);
void opCloseEOFillStroke(Object args[], int numArgs);
void doPatternFill(GBool eoFill);
- void doTilingPatternFill(GfxTilingPattern *tPat, GBool eoFill);
- void doShadingPatternFill(GfxShadingPattern *sPat, GBool eoFill);
+ void doPatternStroke();
+ void doTilingPatternFill(GfxTilingPattern *tPat,
+ GBool stroke, GBool eoFill);
+ void doShadingPatternFill(GfxShadingPattern *sPat,
+ GBool stroke, GBool eoFill);
void opShFill(Object args[], int numArgs);
void doFunctionShFill(GfxFunctionShading *shading);
void doFunctionShFill1(GfxFunctionShading *shading,
@@ -265,7 +279,12 @@
void opXObject(Object args[], int numArgs);
void doImage(Object *ref, Stream *str, GBool inlineImg);
void doForm(Object *str);
- void doForm1(Object *str, Dict *resDict, double *matrix, double *bbox);
+ void doForm1(Object *str, Dict *resDict, double *matrix, double *bbox,
+ GBool transpGroup = gFalse, GBool softMask = gFalse,
+ GfxColorSpace *blendingColorSpace = NULL,
+ GBool isolated = gFalse, GBool knockout = gFalse,
+ GBool alpha = gFalse, Function *transferFunc = NULL,
+ GfxColor *backdropColor = NULL);
// in-line image operators
void opBeginImage(Object args[], int numArgs);
Index: GfxFont.cc
===================================================================
RCS file: /cvs/poppler/poppler/poppler/GfxFont.cc,v
retrieving revision 1.10
retrieving revision 1.11
diff -u -d -r1.10 -r1.11
--- GfxFont.cc 24 Feb 2007 23:32:23 -0000 1.10
+++ GfxFont.cc 25 Apr 2007 19:59:10 -0000 1.11
@@ -28,7 +28,6 @@
#include <fofi/FoFiType1.h>
#include <fofi/FoFiType1C.h>
#include <fofi/FoFiTrueType.h>
-#include "UGooString.h"
#include "GfxFont.h"
//------------------------------------------------------------------------
@@ -264,29 +263,42 @@
if (obj2.fetch(xref, &obj3)->isStream()) {
obj3.streamGetDict()->lookup("Subtype", &obj4);
if (obj4.isName("Type1")) {
- embFontID = obj2.getRef();
+ embFontID = obj2.getRef();
if (type != fontType1) {
error(-1, "Mismatch between font type and embedded font file");
type = fontType1;
}
} else if (obj4.isName("Type1C")) {
- embFontID = obj2.getRef();
+ embFontID = obj2.getRef();
if (type != fontType1 && type != fontType1C) {
error(-1, "Mismatch between font type and embedded font file");
}
type = fontType1C;
} else if (obj4.isName("TrueType")) {
- embFontID = obj2.getRef();
+ embFontID = obj2.getRef();
if (type != fontTrueType) {
error(-1, "Mismatch between font type and embedded font file");
type = fontTrueType;
}
} else if (obj4.isName("CIDFontType0C")) {
- embFontID = obj2.getRef();
+ embFontID = obj2.getRef();
if (type != fontCIDType0) {
error(-1, "Mismatch between font type and embedded font file");
}
type = fontCIDType0C;
+ } else if (obj4.isName("OpenType")) {
+ embFontID = obj2.getRef();
+ if (type == fontTrueType) {
+ type = fontTrueTypeOT;
+ } else if (type == fontType1) {
+ type = fontType1COT;
+ } else if (type == fontCIDType0) {
+ type = fontCIDType0COT;
+ } else if (type == fontCIDType2) {
+ type = fontCIDType2OT;
+ } else {
+ error(-1, "Mismatch between font type and embedded font file");
+ }
} else {
error(-1, "Unknown embedded font type '%s'",
obj4.isName() ? obj4.getName() : "???");
@@ -804,6 +816,15 @@
}
}
}
+
+ // if the 'mapUnknownCharNames' flag is set, do a simple pass-through
+ // mapping for unknown character names
+ } else if (missing && globalParams->getMapUnknownCharNames()) {
+ for (code = 0; code < 256; ++code) {
+ if (!toUnicode[code]) {
+ toUnicode[code] = code;
+ }
+ }
}
// construct the char code -> Unicode mapping object
@@ -1026,10 +1047,10 @@
useMacRoman = gTrue;
}
} else {
- if (macRomanCmap >= 0) {
- cmap = macRomanCmap;
- } else if (msSymbolCmap >= 0) {
+ if (msSymbolCmap >= 0) {
cmap = msSymbolCmap;
+ } else if (macRomanCmap >= 0) {
+ cmap = macRomanCmap;
}
}
@@ -1215,9 +1236,9 @@
n = utu->mapToUnicode((CharCode)uBuf[0], uBuf, 8);
if (n >= 1) {
ctu->setMapping(c, uBuf, n);
+ }
+ }
}
- }
- }
utu->decRefCnt();
} else {
ctu = utu;
@@ -1637,10 +1658,8 @@
r.gen = 999999;
}
}
- char *aux = fontDict->getKey(i)->getCString();
- fonts[i] = GfxFont::makeFont(xref, aux,
+ fonts[i] = GfxFont::makeFont(xref, fontDict->getKey(i),
r, obj2.getDict());
- delete[] aux;
if (fonts[i] && !fonts[i]->isOk()) {
delete fonts[i];
fonts[i] = NULL;
Index: GfxFont.h
===================================================================
RCS file: /cvs/poppler/poppler/poppler/GfxFont.h,v
retrieving revision 1.5
retrieving revision 1.6
diff -u -d -r1.5 -r1.6
--- GfxFont.h 24 Feb 2007 23:32:23 -0000 1.5
+++ GfxFont.h 25 Apr 2007 19:59:10 -0000 1.6
@@ -33,12 +33,16 @@
fontUnknownType,
fontType1,
fontType1C,
+ fontType1COT,
fontType3,
fontTrueType,
+ fontTrueTypeOT,
//----- GfxCIDFont
fontCIDType0,
fontCIDType0C,
- fontCIDType2
+ fontCIDType0COT,
+ fontCIDType2,
+ fontCIDType2OT
};
//------------------------------------------------------------------------
@@ -161,6 +165,7 @@
GooString *getExtFontFile() { return extFontFile; }
// Get font descriptor flags.
+ int getFlags() { return flags; }
GBool isFixedWidth() { return flags & fontFixedWidth; }
GBool isSerif() { return flags & fontSerif; }
GBool isSymbolic() { return flags & fontSymbolic; }
Index: GfxState.cc
===================================================================
RCS file: /cvs/poppler/poppler/poppler/GfxState.cc,v
retrieving revision 1.14
retrieving revision 1.15
diff -u -d -r1.14 -r1.15
--- GfxState.cc 30 Jul 2006 20:31:31 -0000 1.14
+++ GfxState.cc 25 Apr 2007 19:59:10 -0000 1.15
@@ -22,7 +22,6 @@
#include "Page.h"
#include "GfxState.h"
#include "GfxFont.h"
-#include "UGooString.h"
//------------------------------------------------------------------------
@@ -62,12 +61,12 @@
//------------------------------------------------------------------------
-struct gfxBlendModeName {
+struct GfxBlendModeInfo {
char *name;
GfxBlendMode mode;
};
-static gfxBlendModeName gfxBlendModeNames[] = {
+static GfxBlendModeInfo gfxBlendModeNames[] = {
{ "Normal", gfxBlendNormal },
{ "Compatible", gfxBlendNormal },
{ "Multiply", gfxBlendMultiply },
@@ -88,7 +87,7 @@
};
#define nGfxBlendModeNames \
- ((int)((sizeof(gfxBlendModeNames) / sizeof(gfxBlendModeName))))
+ ((int)((sizeof(gfxBlendModeNames) / sizeof(GfxBlendModeInfo))))
//------------------------------------------------------------------------
//
@@ -264,6 +263,10 @@
cmyk->k = clip01(gfxColorComp1 - color->c[0]);
}
+void GfxDeviceGrayColorSpace::getDefaultColor(GfxColor *color) {
+ color->c[0] = 0;
+}
+
//------------------------------------------------------------------------
// GfxCalGrayColorSpace
//------------------------------------------------------------------------
@@ -361,6 +364,10 @@
cmyk->k = clip01(gfxColorComp1 - color->c[0]);
}
+void GfxCalGrayColorSpace::getDefaultColor(GfxColor *color) {
+ color->c[0] = 0;
+}
+
//------------------------------------------------------------------------
// GfxDeviceRGBColorSpace
//------------------------------------------------------------------------
@@ -426,6 +433,12 @@
cmyk->k = k;
}
+void GfxDeviceRGBColorSpace::getDefaultColor(GfxColor *color) {
+ color->c[0] = 0;
+ color->c[1] = 0;
+ color->c[2] = 0;
+}
+
//------------------------------------------------------------------------
// GfxCalRGBColorSpace
//------------------------------------------------------------------------
@@ -577,6 +590,12 @@
cmyk->k = k;
}
+void GfxCalRGBColorSpace::getDefaultColor(GfxColor *color) {
+ color->c[0] = 0;
+ color->c[1] = 0;
+ color->c[2] = 0;
+}
+
//------------------------------------------------------------------------
// GfxDeviceCMYKColorSpace
//------------------------------------------------------------------------
@@ -667,6 +686,13 @@
cmyk->k = clip01(color->c[3]);
}
+void GfxDeviceCMYKColorSpace::getDefaultColor(GfxColor *color) {
+ color->c[0] = 0;
+ color->c[1] = 0;
+ color->c[2] = 0;
+ color->c[3] = gfxColorComp1;
+}
+
//------------------------------------------------------------------------
// GfxLabColorSpace
//------------------------------------------------------------------------
@@ -782,7 +808,7 @@
getRGB(color, &rgb);
*gray = clip01((GfxColorComp)(0.299 * rgb.r +
- 0.587 * rgb.g +
+ 0.587 * rgb.g +
0.114 * rgb.b + 0.5));
}
@@ -844,6 +870,24 @@
cmyk->k = k;
}
+void GfxLabColorSpace::getDefaultColor(GfxColor *color) {
+ color->c[0] = 0;
+ if (aMin > 0) {
+ color->c[1] = dblToCol(aMin);
+ } else if (aMax < 0) {
+ color->c[1] = dblToCol(aMax);
+ } else {
+ color->c[1] = 0;
+ }
+ if (bMin > 0) {
+ color->c[2] = dblToCol(bMin);
+ } else if (bMax < 0) {
+ color->c[2] = dblToCol(bMax);
+ } else {
+ color->c[2] = 0;
+ }
+}
+
void GfxLabColorSpace::getDefaultRanges(double *decodeLow, double *decodeRange,
int maxImgPixel) {
decodeLow[0] = 0;
@@ -974,6 +1018,20 @@
alt->getCMYK(color, cmyk);
}
+void GfxICCBasedColorSpace::getDefaultColor(GfxColor *color) {
+ int i;
+
+ for (i = 0; i < nComps; ++i) {
+ if (rangeMin[i] > 0) {
+ color->c[i] = dblToCol(rangeMin[i]);
+ } else if (rangeMax[i] < 0) {
+ color->c[i] = dblToCol(rangeMax[i]);
+ } else {
+ color->c[i] = 0;
+ }
+ }
+}
+
void GfxICCBasedColorSpace::getDefaultRanges(double *decodeLow,
double *decodeRange,
int maxImgPixel) {
@@ -1142,6 +1200,10 @@
base->getCMYK(mapColorToBase(color, &color2), cmyk);
}
+void GfxIndexedColorSpace::getDefaultColor(GfxColor *color) {
+ color->c[0] = 0;
+}
+
void GfxIndexedColorSpace::getDefaultRanges(double *decodeLow,
double *decodeRange,
int maxImgPixel) {
@@ -1159,6 +1221,7 @@
name = nameA;
alt = altA;
func = funcA;
+ nonMarking = !name->cmp("None");
}
GfxSeparationColorSpace::~GfxSeparationColorSpace() {
@@ -1255,6 +1318,10 @@
alt->getCMYK(&color2, cmyk);
}
+void GfxSeparationColorSpace::getDefaultColor(GfxColor *color) {
+ color->c[0] = gfxColorComp1;
+}
+
//------------------------------------------------------------------------
// GfxDeviceNColorSpace
//------------------------------------------------------------------------
@@ -1265,6 +1332,7 @@
nComps = nCompsA;
alt = altA;
func = funcA;
+ nonMarking = gFalse;
}
GfxDeviceNColorSpace::~GfxDeviceNColorSpace() {
@@ -1285,6 +1353,7 @@
for (i = 0; i < nComps; ++i) {
cs->names[i] = names[i]->copy();
}
+ cs->nonMarking = nonMarking;
return cs;
}
@@ -1334,8 +1403,12 @@
}
obj1.free();
cs = new GfxDeviceNColorSpace(nCompsA, altA, funcA);
+ cs->nonMarking = gTrue;
for (i = 0; i < nCompsA; ++i) {
cs->names[i] = namesA[i];
+ if (namesA[i]->cmp("None")) {
+ cs->nonMarking = gFalse;
+ }
}
return cs;
@@ -1396,6 +1469,14 @@
alt->getCMYK(&color2, cmyk);
}
+void GfxDeviceNColorSpace::getDefaultColor(GfxColor *color) {
+ int i;
+
+ for (i = 0; i < nComps; ++i) {
+ color->c[i] = gfxColorComp1;
+ }
+}
+
//------------------------------------------------------------------------
// GfxPatternColorSpace
//------------------------------------------------------------------------
@@ -1451,6 +1532,10 @@
cmyk->k = 1;
}
+void GfxPatternColorSpace::getDefaultColor(GfxColor * /*color*/) {
+ // not used
+}
+
//------------------------------------------------------------------------
// Pattern
//------------------------------------------------------------------------
@@ -3265,6 +3350,11 @@
maxPixel = (1 << bits) - 1;
colorSpace = colorSpaceA;
+ // initialize
+ for (k = 0; k < gfxColorMaxComps; ++k) {
+ lookup[k] = NULL;
+ }
+
// get decode map
if (decode->isNull()) {
nComps = colorSpace->getNComps();
@@ -3299,9 +3389,6 @@
// Optimization: for Indexed and Separation color spaces (which have
// only one component), we store color values in the lookup table
// rather than component values.
- for (k = 0; k < gfxColorMaxComps; ++k) {
- lookup[k] = NULL;
- }
colorSpace2 = NULL;
nComps2 = 0;
if (colorSpace->getMode() == csIndexed) {
@@ -3371,9 +3458,6 @@
obj.free();
err1:
ok = gFalse;
- for (k = 0; k < gfxColorMaxComps; ++k) {
- lookup[k] = NULL;
- }
byte_lookup = NULL;
}
@@ -3741,10 +3825,12 @@
// GfxState
//------------------------------------------------------------------------
-GfxState::GfxState(double hDPI, double vDPI, PDFRectangle *pageBox,
+GfxState::GfxState(double hDPIA, double vDPIA, PDFRectangle *pageBox,
int rotateA, GBool upsideDown) {
double kx, ky;
+ hDPI = hDPIA;
+ vDPI = vDPIA;
rotate = rotateA;
px1 = pageBox->x1;
py1 = pageBox->y1;
@@ -3801,6 +3887,7 @@
strokeOpacity = 1;
fillOverprint = gFalse;
strokeOverprint = gFalse;
+ transfer[0] = transfer[1] = transfer[2] = transfer[3] = NULL;
lineWidth = 1;
lineDash = NULL;
@@ -3810,6 +3897,7 @@
lineJoin = 0;
lineCap = 0;
miterLimit = 10;
+ strokeAdjust = gFalse;
font = NULL;
fontSize = 0;
@@ -3836,6 +3924,8 @@
}
GfxState::~GfxState() {
+ int i;
+
if (fillColorSpace) {
delete fillColorSpace;
}
@@ -3848,6 +3938,11 @@
if (strokePattern) {
delete strokePattern;
}
+ for (i = 0; i < 4; ++i) {
+ if (transfer[i]) {
+ delete transfer[i];
+ }
+ }
gfree(lineDash);
if (path) {
// this gets set to NULL by restore()
@@ -3863,6 +3958,8 @@
// Used for copy();
GfxState::GfxState(GfxState *state) {
+ int i;
+
memcpy(this, state, sizeof(GfxState));
if (fillColorSpace) {
fillColorSpace = state->fillColorSpace->copy();
@@ -3876,6 +3973,11 @@
if (strokePattern) {
strokePattern = state->strokePattern->copy();
}
+ for (i = 0; i < 4; ++i) {
+ if (transfer[i]) {
+ transfer[i] = state->transfer[i]->copy();
+ }
+ }
if (lineDashLength > 0) {
lineDash = (double *)gmallocn(lineDashLength, sizeof(double));
memcpy(lineDash, state->lineDash, lineDashLength * sizeof(double));
@@ -4024,6 +4126,15 @@
}
}
+void GfxState::shiftCTM(double tx, double ty) {
+ ctm[4] += tx;
+ ctm[5] += ty;
+ clipXMin += tx;
+ clipYMin += ty;
+ clipXMax += tx;
+ clipYMax += ty;
+}
+
void GfxState::setFillColorSpace(GfxColorSpace *colorSpace) {
if (fillColorSpace) {
delete fillColorSpace;
@@ -4060,6 +4171,17 @@
fontSize = fontSizeA;
}
+void GfxState::setTransfer(Function **funcs) {
+ int i;
+
+ for (i = 0; i < 4; ++i) {
+ if (transfer[i]) {
+ delete transfer[i];
+ }
+ transfer[i] = funcs[i];
+ }
+}
+
void GfxState::setLineDash(double *dash, int length, double start) {
if (lineDash)
gfree(lineDash);
@@ -4114,6 +4236,69 @@
}
}
+void GfxState::clipToStrokePath() {
+ double xMin, yMin, xMax, yMax, x, y, t0, t1;
+ GfxSubpath *subpath;
+ int i, j;
+
+ xMin = xMax = yMin = yMax = 0; // make gcc happy
+ for (i = 0; i < path->getNumSubpaths(); ++i) {
+ subpath = path->getSubpath(i);
+ for (j = 0; j < subpath->getNumPoints(); ++j) {
+ transform(subpath->getX(j), subpath->getY(j), &x, &y);
+ if (i == 0 && j == 0) {
+ xMin = xMax = x;
+ yMin = yMax = y;
+ } else {
+ if (x < xMin) {
+ xMin = x;
+ } else if (x > xMax) {
+ xMax = x;
+ }
+ if (y < yMin) {
+ yMin = y;
+ } else if (y > yMax) {
+ yMax = y;
+ }
+ }
+ }
+ }
+
+ // allow for the line width
+ //~ miter joins can extend farther than this
+ t0 = fabs(ctm[0]);
+ t1 = fabs(ctm[2]);
+ if (t0 > t1) {
+ xMin -= 0.5 * lineWidth * t0;
+ xMax += 0.5 * lineWidth * t0;
+ } else {
+ xMin -= 0.5 * lineWidth * t1;
+ xMax += 0.5 * lineWidth * t1;
+ }
+ t0 = fabs(ctm[0]);
+ t1 = fabs(ctm[3]);
+ if (t0 > t1) {
+ yMin -= 0.5 * lineWidth * t0;
+ yMax += 0.5 * lineWidth * t0;
+ } else {
+ yMin -= 0.5 * lineWidth * t1;
+ yMax += 0.5 * lineWidth * t1;
+ }
+
+ if (xMin > clipXMin) {
+ clipXMin = xMin;
+ }
+ if (yMin > clipYMin) {
+ clipYMin = yMin;
+ }
+ if (xMax < clipXMax) {
+ clipXMax = xMax;
+ }
+ if (yMax < clipYMax) {
+ clipYMax = yMax;
+ }
+}
+
void GfxState::textShift(double tx, double ty) {
double dx, dy;
Index: GfxState.h
===================================================================
RCS file: /cvs/poppler/poppler/poppler/GfxState.h,v
retrieving revision 1.6
retrieving revision 1.7
diff -u -d -r1.6 -r1.7
--- GfxState.h 13 May 2006 16:01:57 -0000 1.6
+++ GfxState.h 25 Apr 2007 19:59:10 -0000 1.7
@@ -156,11 +156,18 @@
// Return the number of color components.
virtual int getNComps() = 0;
+ // Get this color space's default color.
+ virtual void getDefaultColor(GfxColor *color) = 0;
+
// Return the default ranges for each component, assuming an image
// with a max pixel value of <maxImgPixel>.
virtual void getDefaultRanges(double *decodeLow, double *decodeRange,
int maxImgPixel);
+ // Returns true if painting operations in this color space never
+ // mark the page (e.g., the "None" colorant).
+ virtual GBool isNonMarking() { return gFalse; }
+
// Return the number of color space modes
static int getNumColorSpaceModes();
@@ -189,6 +196,7 @@
virtual void getRGBLine(Guchar *in, unsigned int *out, int length);
virtual int getNComps() { return 1; }
+ virtual void getDefaultColor(GfxColor *color);
private:
};
@@ -215,6 +223,7 @@
virtual void getRGBLine(Guchar *in, unsigned int *out, int length);
virtual int getNComps() { return 1; }
+ virtual void getDefaultColor(GfxColor *color);
// CalGray-specific access.
double getWhiteX() { return whiteX; }
@@ -251,6 +260,7 @@
virtual void getRGBLine(Guchar *in, unsigned int *out, int length);
virtual int getNComps() { return 3; }
+ virtual void getDefaultColor(GfxColor *color);
private:
};
@@ -277,6 +287,7 @@
virtual void getRGBLine(Guchar *in, unsigned int *out, int length);
virtual int getNComps() { return 3; }
+ virtual void getDefaultColor(GfxColor *color);
// CalRGB-specific access.
double getWhiteX() { return whiteX; }
@@ -295,7 +306,7 @@
double whiteX, whiteY, whiteZ; // white point
double blackX, blackY, blackZ; // black point
double gammaR, gammaG, gammaB; // gamma values
- double mat[9]; // ABC -> XYZ transform matrix
+ double mat[9]; // ABC -> XYZ transform matrix
};
//------------------------------------------------------------------------
@@ -315,6 +326,7 @@
virtual void getCMYK(GfxColor *color, GfxCMYK *cmyk);
virtual int getNComps() { return 4; }
+ virtual void getDefaultColor(GfxColor *color);
private:
};
@@ -339,6 +351,7 @@
virtual void getCMYK(GfxColor *color, GfxCMYK *cmyk);
virtual int getNComps() { return 3; }
+ virtual void getDefaultColor(GfxColor *color);
virtual void getDefaultRanges(double *decodeLow, double *decodeRange,
int maxImgPixel);
@@ -385,6 +398,7 @@
virtual void getRGBLine(Guchar *in, unsigned int *out, int length);
virtual int getNComps() { return nComps; }
+ virtual void getDefaultColor(GfxColor *color);
virtual void getDefaultRanges(double *decodeLow, double *decodeRange,
int maxImgPixel);
@@ -422,6 +436,7 @@
virtual void getRGBLine(Guchar *in, unsigned int *out, int length);
virtual int getNComps() { return 1; }
+ virtual void getDefaultColor(GfxColor *color);
virtual void getDefaultRanges(double *decodeLow, double *decodeRange,
int maxImgPixel);
@@ -460,6 +475,9 @@
virtual void getCMYK(GfxColor *color, GfxCMYK *cmyk);
virtual int getNComps() { return 1; }
+ virtual void getDefaultColor(GfxColor *color);
+
+ virtual GBool isNonMarking() { return nonMarking; }
// Separation-specific access.
GooString *getName() { return name; }
@@ -471,6 +489,7 @@
GooString *name; // colorant name
GfxColorSpace *alt; // alternate color space
Function *func; // tint transform (into alternate color space)
+ GBool nonMarking;
};
//------------------------------------------------------------------------
@@ -493,6 +512,9 @@
virtual void getCMYK(GfxColor *color, GfxCMYK *cmyk);
virtual int getNComps() { return nComps; }
+ virtual void getDefaultColor(GfxColor *color);
+
+ virtual GBool isNonMarking() { return nonMarking; }
// DeviceN-specific access.
GooString *getColorantName(int i) { return names[i]; }
@@ -506,6 +528,7 @@
*names[gfxColorMaxComps];
GfxColorSpace *alt; // alternate color space
Function *func; // tint transform (into alternate color space)
+ GBool nonMarking;
};
//------------------------------------------------------------------------
@@ -528,6 +551,7 @@
virtual void getCMYK(GfxColor *color, GfxCMYK *cmyk);
virtual int getNComps() { return 0; }
+ virtual void getDefaultColor(GfxColor *color);
// Pattern-specific access.
GfxColorSpace *getUnder() { return under; }
@@ -1014,7 +1038,7 @@
// Construct a default GfxState, for a device with resolution <hDPI>
// x <vDPI>, page box <pageBox>, page rotation <rotateA>, and
// coordinate system specified by <upsideDown>.
- GfxState(double hDPI, double vDPI, PDFRectangle *pageBox,
+ GfxState(double hDPIA, double vDPIA, PDFRectangle *pageBox,
int rotateA, GBool upsideDown);
// Destructor.
@@ -1024,6 +1048,8 @@
GfxState *copy() { return new GfxState(this); }
// Accessors.
+ double getHDPI() { return hDPI; }
+ double getVDPI() { return vDPI; }
double *getCTM() { return ctm; }
void getCTM(Matrix *m) { memcpy (m->m, ctm, sizeof m->m); }
double getX1() { return px1; }
@@ -1056,6 +1082,7 @@
double getStrokeOpacity() { return strokeOpacity; }
GBool getFillOverprint() { return fillOverprint; }
GBool getStrokeOverprint() { return strokeOverprint; }
+ Function **getTransfer() { return transfer; }
double getLineWidth() { return lineWidth; }
void getLineDash(double **dash, int *length, double *start)
{ *dash = lineDash; *length = lineDashLength; *start = lineDashStart; }
@@ -1063,6 +1090,7 @@
int getLineJoin() { return lineJoin; }
int getLineCap() { return lineCap; }
double getMiterLimit() { return miterLimit; }
+ GBool getStrokeAdjust() { return strokeAdjust; }
GfxFont *getFont() { return font; }
double getFontSize() { return fontSize; }
double *getTextMat() { return textMat; }
@@ -1110,6 +1138,7 @@
double d, double e, double f);
void concatCTM(double a, double b, double c,
double d, double e, double f);
+ void shiftCTM(double tx, double ty);
void setFillColorSpace(GfxColorSpace *colorSpace);
void setStrokeColorSpace(GfxColorSpace *colorSpace);
void setFillColor(GfxColor *color) { fillColor = *color; }
@@ -1121,12 +1150,14 @@
void setStrokeOpacity(double opac) { strokeOpacity = opac; }
void setFillOverprint(GBool op) { fillOverprint = op; }
void setStrokeOverprint(GBool op) { strokeOverprint = op; }
+ void setTransfer(Function **funcs);
void setLineWidth(double width) { lineWidth = width; }
void setLineDash(double *dash, int length, double start);
void setFlatness(int flatness1) { flatness = flatness1; }
void setLineJoin(int lineJoin1) { lineJoin = lineJoin1; }
void setLineCap(int lineCap1) { lineCap = lineCap1; }
void setMiterLimit(double limit) { miterLimit = limit; }
+ void setStrokeAdjust(GBool sa) { strokeAdjust = sa; }
void setFont(GfxFont *fontA, double fontSizeA);
void setTextMat(double a, double b, double c,
double d, double e, double f)
@@ -1159,6 +1190,7 @@
// Update clip region.
void clip();
+ void clipToStrokePath();
// Text position.
void textSetPos(double tx, double ty) { lineX = tx; lineY = ty; }
@@ -1177,6 +1209,7 @@
private:
+ double hDPI, vDPI; // resolution
double ctm[6]; // coord transform matrix
double px1, py1, px2, py2; // page corners (user coords)
double pageWidth, pageHeight; // page size (pixels)
@@ -1193,6 +1226,10 @@
double strokeOpacity; // stroke opacity
GBool fillOverprint; // fill overprint
GBool strokeOverprint; // stroke overprint
+ Function *transfer[4]; // transfer function (entries may be: all
+ // NULL = identity; last three NULL =
+ // single function; all four non-NULL =
+ // R,G,B,gray functions)
double lineWidth; // line width
double *lineDash; // line dash
@@ -1202,6 +1239,7 @@
int lineJoin; // line join style
int lineCap; // line cap style
double miterLimit; // line miter limit
+ GBool strokeAdjust; // stroke adjustment
GfxFont *font; // font
double fontSize; // font size
Index: GlobalParams.cc
===================================================================
RCS file: /cvs/poppler/poppler/poppler/GlobalParams.cc,v
retrieving revision 1.19
retrieving revision 1.20
diff -u -d -r1.19 -r1.20
--- GlobalParams.cc 24 Feb 2007 23:43:35 -0000 1.19
+++ GlobalParams.cc 25 Apr 2007 19:59:10 -0000 1.20
@@ -42,6 +42,10 @@
#include "GlobalParams.h"
#include "GfxFont.h"
+#ifdef WIN32
+# define strcasecmp stricmp
+#endif
+
#if MULTITHREADED
# define lockGlobalParams gLockMutex(&mutex)
# define lockUnicodeMapCache gLockMutex(&unicodeMapCacheMutex)
@@ -115,6 +119,251 @@
}
}
+#ifdef WIN32
+
+//------------------------------------------------------------------------
+// WinFontInfo
+//------------------------------------------------------------------------
+
+class WinFontInfo: public DisplayFontParam {
+public:
+
+ GBool bold, italic;
+
+ static WinFontInfo *make(GString *nameA, GBool boldA, GBool italicA,
+ HKEY regKey, char *winFontDir);
+ WinFontInfo(GString *nameA, GBool boldA, GBool italicA,
+ GString *fileNameA);
+ virtual ~WinFontInfo();
+ GBool equals(WinFontInfo *fi);
+};
+
+WinFontInfo *WinFontInfo::make(GString *nameA, GBool boldA, GBool italicA,
+ HKEY regKey, char *winFontDir) {
+ GString *regName;
+ GString *fileNameA;
+ char buf[MAX_PATH];
+ DWORD n;
+ char c;
+ int i;
+
+ //----- find the font file
+ fileNameA = NULL;
+ regName = nameA->copy();
+ if (boldA) {
+ regName->append(" Bold");
+ }
+ if (italicA) {
+ regName->append(" Italic");
+ }
+ regName->append(" (TrueType)");
+ n = sizeof(buf);
+ if (RegQueryValueEx(regKey, regName->getCString(), NULL, NULL,
+ (LPBYTE)buf, &n) == ERROR_SUCCESS) {
+ fileNameA = new GString(winFontDir);
+ fileNameA->append('\\')->append(buf);
+ }
+ delete regName;
+ if (!fileNameA) {
+ delete nameA;
+ return NULL;
+ }
+
+ //----- normalize the font name
+ i = 0;
+ while (i < nameA->getLength()) {
+ c = nameA->getChar(i);
+ if (c == ' ' || c == ',' || c == '-') {
+ nameA->del(i);
+ } else {
+ ++i;
+ }
+ }
+
+ return new WinFontInfo(nameA, boldA, italicA, fileNameA);
+}
+
+WinFontInfo::WinFontInfo(GString *nameA, GBool boldA, GBool italicA,
+ GString *fileNameA):
+ DisplayFontParam(nameA, displayFontTT)
+{
+ bold = boldA;
+ italic = italicA;
+ tt.fileName = fileNameA;
+}
+
+WinFontInfo::~WinFontInfo() {
+}
+
+GBool WinFontInfo::equals(WinFontInfo *fi) {
+ return !name->cmp(fi->name) && bold == fi->bold && italic == fi->italic;
+}
+
+//------------------------------------------------------------------------
+// WinFontList
+//------------------------------------------------------------------------
+
+class WinFontList {
+public:
+
+ WinFontList(char *winFontDirA);
+ ~WinFontList();
+ WinFontInfo *find(GString *font);
+
+private:
+
+ void add(WinFontInfo *fi);
+ static int CALLBACK enumFunc1(CONST LOGFONT *font,
+ CONST TEXTMETRIC *metrics,
+ DWORD type, LPARAM data);
+ static int CALLBACK enumFunc2(CONST LOGFONT *font,
+ CONST TEXTMETRIC *metrics,
+ DWORD type, LPARAM data);
+
+ GList *fonts; // [WinFontInfo]
+ HDC dc; // (only used during enumeration)
+ HKEY regKey; // (only used during enumeration)
+ char *winFontDir; // (only used during enumeration)
+};
+
+WinFontList::WinFontList(char *winFontDirA) {
+ OSVERSIONINFO version;
+ char *path;
+
+ fonts = new GList();
+ dc = GetDC(NULL);
+ winFontDir = winFontDirA;
+ version.dwOSVersionInfoSize = sizeof(version);
+ GetVersionEx(&version);
+ if (version.dwPlatformId == VER_PLATFORM_WIN32_NT) {
+ path = "SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Fonts\\";
+ } else {
+ path = "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Fonts\\";
+ }
+ if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, path, 0,
+ KEY_QUERY_VALUE | KEY_ENUMERATE_SUB_KEYS,
+ ®Key) == ERROR_SUCCESS) {
+ EnumFonts(dc, NULL, &WinFontList::enumFunc1, (LPARAM)this);
+ RegCloseKey(regKey);
+ }
+ ReleaseDC(NULL, dc);
+}
+
+WinFontList::~WinFontList() {
+ deleteGList(fonts, WinFontInfo);
+}
+
+void WinFontList::add(WinFontInfo *fi) {
+ int i;
+
+ for (i = 0; i < fonts->getLength(); ++i) {
+ if (((WinFontInfo *)fonts->get(i))->equals(fi)) {
+ delete fi;
+ return;
+ }
+ }
+ fonts->append(fi);
+}
+
+WinFontInfo *WinFontList::find(GString *font) {
+ GString *name;
+ GBool bold, italic;
+ WinFontInfo *fi;
+ char c;
+ int n, i;
+
+ name = font->copy();
+
+ // remove space, comma, dash chars
+ i = 0;
+ while (i < name->getLength()) {
+ c = name->getChar(i);
+ if (c == ' ' || c == ',' || c == '-') {
+ name->del(i);
+ } else {
+ ++i;
+ }
+ }
+ n = name->getLength();
+
+ // remove trailing "MT" (Foo-MT, Foo-BoldMT, etc.)
+ if (!strcmp(name->getCString() + n - 2, "MT")) {
+ name->del(n - 2, 2);
+ n -= 2;
+ }
+
+ // look for "Italic"
+ if (!strcmp(name->getCString() + n - 6, "Italic")) {
+ name->del(n - 6, 6);
+ italic = gTrue;
+ n -= 6;
+ } else {
+ italic = gFalse;
+ }
+
+ // look for "Bold"
+ if (!strcmp(name->getCString() + n - 4, "Bold")) {
+ name->del(n - 4, 4);
+ bold = gTrue;
+ n -= 4;
+ } else {
+ bold = gFalse;
+ }
+
+ // remove trailing "MT" (FooMT-Bold, etc.)
+ if (!strcmp(name->getCString() + n - 2, "MT")) {
+ name->del(n - 2, 2);
+ n -= 2;
+ }
+
+ // remove trailing "PS"
+ if (!strcmp(name->getCString() + n - 2, "PS")) {
+ name->del(n - 2, 2);
+ n -= 2;
+ }
+
+ // search for the font
+ fi = NULL;
+ for (i = 0; i < fonts->getLength(); ++i) {
+ fi = (WinFontInfo *)fonts->get(i);
+ if (!fi->name->cmp(name) && fi->bold == bold && fi->italic == italic) {
+ break;
+ }
+ fi = NULL;
+ }
+
+ delete name;
+ return fi;
+}
+
+int CALLBACK WinFontList::enumFunc1(CONST LOGFONT *font,
+ CONST TEXTMETRIC *metrics,
+ DWORD type, LPARAM data) {
+ WinFontList *fl = (WinFontList *)data;
+
+ EnumFonts(fl->dc, font->lfFaceName, &WinFontList::enumFunc2, (LPARAM)fl);
+ return 1;
+}
+
+int CALLBACK WinFontList::enumFunc2(CONST LOGFONT *font,
+ CONST TEXTMETRIC *metrics,
+ DWORD type, LPARAM data) {
+ WinFontList *fl = (WinFontList *)data;
+ WinFontInfo *fi;
+
+ if (type & TRUETYPE_FONTTYPE) {
+ if ((fi = WinFontInfo::make(new GString(font->lfFaceName),
+ font->lfWeight >= 600,
+ font->lfItalic ? gTrue : gFalse,
+ fl->regKey, fl->winFontDir))) {
+ fl->add(fi);
+ }
+ }
+ return 1;
+}
+
+#endif // WIN32
+
//------------------------------------------------------------------------
// PSFontParam
//------------------------------------------------------------------------
@@ -330,6 +579,7 @@
psEmbedTrueType = gTrue;
psEmbedCIDPostScript = gTrue;
psEmbedCIDTrueType = gTrue;
+ psPreload = gFalse;
psOPI = gFalse;
psASCIIHex = gFalse;
textEncoding = new GooString("UTF-8");
@@ -345,7 +595,16 @@
fontDirs = new GooList();
enableFreeType = gTrue;
antialias = gTrue;
+ vectorAntialias = gTrue;
+ strokeAdjust = gTrue;
+ screenType = screenUnset;
+ screenSize = -1;
+ screenDotRadius = -1;
+ screenGamma = 1.0;
+ screenBlackThreshold = 0.0;
+ screenWhiteThreshold = 1.0;
mapNumericCharNames = gTrue;
+ mapUnknownCharNames = gFalse;
printCommands = gFalse;
profileCommands = gFalse;
errQuiet = gFalse;
@@ -356,6 +615,10 @@
unicodeMapCache = new UnicodeMapCache();
cMapCache = new CMapCache();
+#ifdef WIN32
+ winFontList = NULL;
+#endif
+
#ifdef ENABLE_PLUGINS
plugins = new GooList();
securityHandlers = new GooList();
@@ -508,6 +771,11 @@
deleteGooHash(unicodeMaps, GooString);
deleteGooList(toUnicodeDirs, GooString);
deleteGooHash(displayFonts, DisplayFontParam);
+#ifdef WIN32
+ if (winFontList) {
+ delete winFontList;
+ }
+#endif
deleteGooHash(psFonts, PSFontParam);
deleteGooList(psNamedFonts16, PSFontParam);
deleteGooList(psFonts16, PSFontParam);
@@ -542,6 +810,12 @@
void GlobalParams::setBaseDir(char *dir) {
delete baseDir;
baseDir = new GooString(dir);
+
+#ifdef WIN32
+ if (winFontDir[0]) {
+ winFontList = new WinFontList(winFontDir);
+ }
+#endif
}
//------------------------------------------------------------------------
@@ -970,6 +1244,15 @@
return e;
}
+GBool GlobalParams::getPSPreload() {
+ GBool preload;
+
+ lockGlobalParams;
+ preload = psPreload;
+ unlockGlobalParams;
+ return preload;
+}
+
GBool GlobalParams::getPSOPI() {
GBool opi;
@@ -1067,6 +1350,78 @@
return f;
}
+GBool GlobalParams::getVectorAntialias() {
+ GBool f;
+
+ lockGlobalParams;
+ f = vectorAntialias;
+ unlockGlobalParams;
+ return f;
+}
+
+GBool GlobalParams::getStrokeAdjust() {
+ GBool f;
+
+ lockGlobalParams;
+ f = strokeAdjust;
+ unlockGlobalParams;
+ return f;
+}
+
+ScreenType GlobalParams::getScreenType() {
+ ScreenType t;
+
+ lockGlobalParams;
+ t = screenType;
+ unlockGlobalParams;
+ return t;
+}
+
+int GlobalParams::getScreenSize() {
+ int size;
+
+ lockGlobalParams;
+ size = screenSize;
+ unlockGlobalParams;
+ return size;
+}
+
+int GlobalParams::getScreenDotRadius() {
+ int r;
+
+ lockGlobalParams;
+ r = screenDotRadius;
+ unlockGlobalParams;
+ return r;
+}
+
+double GlobalParams::getScreenGamma() {
+ double gamma;
+
+ lockGlobalParams;
+ gamma = screenGamma;
+ unlockGlobalParams;
+ return gamma;
+}
+
+double GlobalParams::getScreenBlackThreshold() {
+ double thresh;
+
+ lockGlobalParams;
+ thresh = screenBlackThreshold;
+ unlockGlobalParams;
+ return thresh;
+}
+
+double GlobalParams::getScreenWhiteThreshold() {
+ double thresh;
+
+ lockGlobalParams;
+ thresh = screenWhiteThreshold;
+ unlockGlobalParams;
+ return thresh;
+}
+
GBool GlobalParams::getMapNumericCharNames() {
GBool map;
@@ -1076,6 +1431,15 @@
return map;
}
+GBool GlobalParams::getMapUnknownCharNames() {
+ GBool map;
+
+ lockGlobalParams;
+ map = mapUnknownCharNames;
+ unlockGlobalParams;
+ return map;
+}
+
GBool GlobalParams::getPrintCommands() {
GBool p;
@@ -1095,12 +1459,9 @@
}
GBool GlobalParams::getErrQuiet() {
- GBool q;
-
- lockGlobalParams;
- q = errQuiet;
- unlockGlobalParams;
- return q;
+ // no locking -- this function may get called from inside a locked
+ // section
+ return errQuiet;
}
CharCodeToUnicode *GlobalParams::getCIDToUnicode(GooString *collection) {
@@ -1226,6 +1587,12 @@
unlockGlobalParams;
}
+void GlobalParams::setPSPreload(GBool preload) {
+ lockGlobalParams;
+ psPreload = preload;
+ unlockGlobalParams;
+}
+
void GlobalParams::setPSOPI(GBool opi) {
lockGlobalParams;
psOPI = opi;
@@ -1292,12 +1659,27 @@
return ok;
}
+GBool GlobalParams::setVectorAntialias(char *s) {
+ GBool ok;
+
+ lockGlobalParams;
+ ok = parseYesNo2(s, &vectorAntialias);
+ unlockGlobalParams;
+ return ok;
+}
+
void GlobalParams::setMapNumericCharNames(GBool map) {
lockGlobalParams;
mapNumericCharNames = map;
unlockGlobalParams;
}
+void GlobalParams::setMapUnknownCharNames(GBool map) {
+ lockGlobalParams;
+ mapUnknownCharNames = map;
+ unlockGlobalParams;
+}
+
void GlobalParams::setPrintCommands(GBool printCommandsA) {
lockGlobalParams;
printCommands = printCommandsA;
@@ -1332,7 +1714,7 @@
lockGlobalParams;
for (i = 0; i < securityHandlers->getLength(); ++i) {
hdlr = (XpdfSecurityHandler *)securityHandlers->get(i);
- if (!stricmp(hdlr->name, name)) {
+ if (!strcasecmp(hdlr->name, name)) {
unlockGlobalParams;
return hdlr;
}
@@ -1342,6 +1724,7 @@
if (!loadPlugin("security", name)) {
return NULL;
}
+ deleteGList(keyBindings, KeyBinding);
lockGlobalParams;
for (i = 0; i < securityHandlers->getLength(); ++i) {
@@ -1352,6 +1735,8 @@
}
}
unlockGlobalParams;
+#else
+ (void)name;
#endif
return NULL;
Index: GlobalParams.h
===================================================================
RCS file: /cvs/poppler/poppler/poppler/GlobalParams.h,v
retrieving revision 1.8
retrieving revision 1.9
diff -u -d -r1.8 -r1.9
--- GlobalParams.h 24 Feb 2007 23:43:35 -0000 1.8
+++ GlobalParams.h 25 Apr 2007 19:59:10 -0000 1.9
@@ -36,6 +36,9 @@
struct XpdfSecurityHandler;
class GlobalParams;
class GfxFont;
+#ifdef WIN32
+class WinFontList;
+#endif
//------------------------------------------------------------------------
@@ -71,7 +74,7 @@
};
DisplayFontParam(GooString *nameA, DisplayFontParamKind kindA);
- ~DisplayFontParam();
+ virtual ~DisplayFontParam();
};
//------------------------------------------------------------------------
@@ -113,6 +116,15 @@
//------------------------------------------------------------------------
+enum ScreenType {
+ screenUnset,
+ screenDispersed,
+ screenClustered,
+ screenStochasticClustered
+};
+
+//------------------------------------------------------------------------
+
class GlobalParams {
public:
@@ -145,6 +157,7 @@
GBool getPSEmbedTrueType();
GBool getPSEmbedCIDPostScript();
GBool getPSEmbedCIDTrueType();
+ GBool getPSPreload();
GBool getPSOPI();
GBool getPSASCIIHex();
GooString *getTextEncodingName();
@@ -154,7 +167,16 @@
GooString *findFontFile(GooString *fontName, char **exts);
GBool getEnableFreeType();
GBool getAntialias();
+ GBool getVectorAntialias();
+ GBool getStrokeAdjust();
+ ScreenType getScreenType();
+ int getScreenSize();
+ int getScreenDotRadius();
+ double getScreenGamma();
+ double getScreenBlackThreshold();
+ double getScreenWhiteThreshold();
GBool getMapNumericCharNames();
+ GBool getMapUnknownCharNames();
GBool getPrintCommands();
GBool getProfileCommands();
GBool getErrQuiet();
@@ -177,6 +199,7 @@
void setPSEmbedTrueType(GBool embed);
void setPSEmbedCIDPostScript(GBool embed);
void setPSEmbedCIDTrueType(GBool embed);
+ void setPSPreload(GBool preload);
void setPSOPI(GBool opi);
void setPSASCIIHex(GBool hex);
void setTextEncoding(char *encodingName);
@@ -185,7 +208,9 @@
void setTextKeepTinyChars(GBool keep);
GBool setEnableFreeType(char *s);
GBool setAntialias(char *s);
+ GBool setVectorAntialias(char *s);
void setMapNumericCharNames(GBool map);
+ void setMapUnknownCharNames(GBool map);
void setPrintCommands(GBool printCommandsA);
void setProfileCommands(GBool profileCommandsA);
void setErrQuiet(GBool errQuietA);
@@ -230,6 +255,9 @@
GooList *toUnicodeDirs; // list of ToUnicode CMap dirs [GooString]
GooHash *displayFonts; // display font info, indexed by font name
// [DisplayFontParam]
+#ifdef WIN32
+ WinFontList *winFontList; // system TrueType fonts
+#endif
GBool psExpandSmaller; // expand smaller pages to fill paper
GBool psShrinkLarger; // shrink larger pages to fit paper
GBool psCenter; // center pages on the paper
@@ -242,6 +270,8 @@
GBool psEmbedTrueType; // embed TrueType fonts?
GBool psEmbedCIDPostScript; // embed CID PostScript fonts?
GBool psEmbedCIDTrueType; // embed CID TrueType fonts?
+ GBool psPreload; // preload PostScript images and forms into
+ // memory
GBool psOPI; // generate PostScript OPI comments?
GBool psASCIIHex; // use ASCIIHex instead of ASCII85?
GooString *textEncoding; // encoding (unicodeMap) to use for text
@@ -253,7 +283,16 @@
GooList *fontDirs; // list of font dirs [GooString]
GBool enableFreeType; // FreeType enable flag
GBool antialias; // anti-aliasing enable flag
+ GBool vectorAntialias; // vector anti-aliasing enable flag
+ GBool strokeAdjust; // stroke adjustment enable flag
+ ScreenType screenType; // halftone screen type
+ int screenSize; // screen matrix size
+ int screenDotRadius; // screen dot radius
+ double screenGamma; // screen gamma correction
+ double screenBlackThreshold; // screen black clamping threshold
+ double screenWhiteThreshold; // screen white clamping threshold
GBool mapNumericCharNames; // map numeric char names (from font subsets)?
+ GBool mapUnknownCharNames; // map unknown char names?
GBool printCommands; // print the drawing commands
GBool profileCommands; // profile the drawing commands
GBool errQuiet; // suppress error messages?
Index: JBIG2Stream.cc
===================================================================
RCS file: /cvs/poppler/poppler/poppler/JBIG2Stream.cc,v
retrieving revision 1.9
retrieving revision 1.10
diff -u -d -r1.9 -r1.10
--- JBIG2Stream.cc 29 Apr 2006 15:23:41 -0000 1.9
+++ JBIG2Stream.cc 25 Apr 2007 19:59:10 -0000 1.10
@@ -1106,7 +1106,7 @@
// JBIG2Stream
//------------------------------------------------------------------------
-JBIG2Stream::JBIG2Stream(Stream *strA, Object *globalsStream):
+JBIG2Stream::JBIG2Stream(Stream *strA, Object *globalsStreamA):
FilterStream(strA)
{
pageBitmap = NULL;
@@ -1131,22 +1131,15 @@
huffDecoder = new JBIG2HuffmanDecoder();
mmrDecoder = new JBIG2MMRDecoder();
- segments = globalSegments = new GooList();
- if (globalsStream->isStream()) {
- curStr = globalsStream->getStream();
- curStr->reset();
- arithDecoder->setStream(curStr);
- huffDecoder->setStream(curStr);
- mmrDecoder->setStream(curStr);
- readSegments();
- }
-
- segments = NULL;
+ globalsStreamA->copy(&globalsStream);
+ segments = globalSegments = NULL;
curStr = NULL;
dataPtr = dataEnd = NULL;
}
JBIG2Stream::~JBIG2Stream() {
+ close();
+ globalsStream.free();
delete arithDecoder;
delete genericRegionStats;
delete refinementRegionStats;
@@ -1166,28 +1159,25 @@
delete iaidStats;
delete huffDecoder;
delete mmrDecoder;
- if (pageBitmap) {
- delete pageBitmap;
- }
- if (segments) {
- deleteGooList(segments, JBIG2Segment);
- }
- if (globalSegments) {
- deleteGooList(globalSegments, JBIG2Segment);
- }
delete str;
}
void JBIG2Stream::reset() {
- if (pageBitmap) {
- delete pageBitmap;
- pageBitmap = NULL;
- }
- if (segments) {
- deleteGooList(segments, JBIG2Segment);
+ // read the globals stream
+ globalSegments = new GooList();
+ if (globalsStream.isStream()) {
+ segments = globalSegments;
+ curStr = globalsStream.getStream();
+ curStr->reset();
+ arithDecoder->setStream(curStr);
+ huffDecoder->setStream(curStr);
+ mmrDecoder->setStream(curStr);
+ readSegments();
+ curStr->close();
}
- segments = new GooList();
+ // read the main stream
+ segments = new GooList();
curStr = str;
curStr->reset();
arithDecoder->setStream(curStr);
@@ -1199,10 +1189,27 @@
dataPtr = pageBitmap->getDataPtr();
dataEnd = dataPtr + pageBitmap->getDataSize();
} else {
- dataPtr = NULL;
+ dataPtr = dataEnd = NULL;
}
}
+void JBIG2Stream::close() {
+ if (pageBitmap) {
+ delete pageBitmap;
+ pageBitmap = NULL;
+ }
+ if (segments) {
+ deleteGooList(segments, JBIG2Segment);
+ segments = NULL;
+ }
+ if (globalSegments) {
+ deleteGooList(globalSegments, JBIG2Segment);
+ globalSegments = NULL;
+ }
+ dataPtr = dataEnd = NULL;
+ FilterStream::close();
+}
+
int JBIG2Stream::getChar() {
if (dataPtr && dataPtr < dataEnd) {
return (*dataPtr++ ^ 0xff) & 0xff;
@@ -2361,6 +2368,14 @@
error(getPos(), "Bad grid size in JBIG2 halftone segment");
return;
}
+ if (w == 0 || h == 0 || w >= INT_MAX / h) {
+ error(getPos(), "Bad bitmap size in JBIG2 halftone segment");
+ return;
+ }
+ if (gridH == 0 || gridW >= INT_MAX / gridH) {
+ error(getPos(), "Bad grid size in JBIG2 halftone segment");
+ return;
+ }
// get pattern dictionary
if (nRefSegs != 1) {
@@ -2372,14 +2387,6 @@
error(getPos(), "Bad symbol dictionary reference in JBIG2 halftone segment");
return;
}
- if (gridH == 0 || gridW >= INT_MAX / gridH) {
- error(getPos(), "Bad size in JBIG2 halftone segment");
- return;
- }
- if (w == 0 || h >= INT_MAX / w) {
- error(getPos(), "Bad size in JBIG2 bitmap segment");
- return;
- }
patternDict = (JBIG2PatternDict *)seg;
bpp = 0;
@@ -2411,9 +2418,9 @@
skipBitmap = new JBIG2Bitmap(0, gridW, gridH);
skipBitmap->clearToZero();
for (m = 0; m < gridH; ++m) {
- xx = gridX + m * stepY;
- yy = gridY + m * stepX;
for (n = 0; n < gridW; ++n) {
+ xx = gridX + m * stepY + n * stepX;
+ yy = gridY + m * stepX - n * stepY;
if (((xx + (int)patW) >> 8) <= 0 || (xx >> 8) >= (int)w ||
((yy + (int)patH) >> 8) <= 0 || (yy >> 8) >= (int)h) {
skipBitmap->setPixel(n, m);
@@ -2459,8 +2466,10 @@
}
}
- delete skipBitmap;
gfree(grayImg);
+ if (skipBitmap) {
+ delete skipBitmap;
+ }
// combine the region bitmap into the page bitmap
if (imm) {
@@ -3013,11 +3022,6 @@
JBIG2BitmapPtr tpgrCXPtr0, tpgrCXPtr1, tpgrCXPtr2;
int x, y, pix;
- if (w < 0 || h <= 0 || w >= INT_MAX / h) {
- error(-1, "invalid width/height");
- return NULL;
- }
-
bitmap = new JBIG2Bitmap(0, w, h);
bitmap->clearToZero();
@@ -3396,7 +3400,7 @@
iardwStats->reset();
iardhStats->reset();
iariStats->reset();
- if (iaidStats->getContextSize() == symCodeLen + 1) {
+ if (iaidStats->getContextSize() == 1 << (symCodeLen + 1)) {
iaidStats->reset();
} else {
delete iaidStats;
Index: JBIG2Stream.h
===================================================================
RCS file: /cvs/poppler/poppler/poppler/JBIG2Stream.h,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -d -r1.2 -r1.3
--- JBIG2Stream.h 31 Aug 2005 09:51:41 -0000 1.2
+++ JBIG2Stream.h 25 Apr 2007 19:59:10 -0000 1.3
@@ -31,10 +31,11 @@
class JBIG2Stream: public FilterStream {
public:
- JBIG2Stream(Stream *strA, Object *globalsStream);
+ JBIG2Stream(Stream *strA, Object *globalsStreamA);
virtual ~JBIG2Stream();
virtual StreamKind getKind() { return strJBIG2; }
virtual void reset();
+ virtual void close();
virtual int getChar();
virtual int lookChar();
virtual GooString *getPSFilter(int psLevel, char *indent);
@@ -107,6 +108,7 @@
GBool readULong(Guint *x);
GBool readLong(int *x);
+ Object globalsStream;
Guint pageW, pageH, curPageH;
Guint pageDefPixel;
JBIG2Bitmap *pageBitmap;
Index: JPXStream.cc
===================================================================
RCS file: /cvs/poppler/poppler/poppler/JPXStream.cc,v
retrieving revision 1.6
retrieving revision 1.7
diff -u -d -r1.6 -r1.7
--- JPXStream.cc 21 Dec 2005 22:09:47 -0000 1.6
+++ JPXStream.cc 25 Apr 2007 19:59:10 -0000 1.7
@@ -177,6 +177,59 @@
//------------------------------------------------------------------------
+#if 1 //----- disable coverage tracking
+
+#define cover(idx)
+
+#else //----- enable coverage tracking
+
+class JPXCover {
+public:
+
+ JPXCover(int sizeA);
+ ~JPXCover();
+ void incr(int idx);
+
+private:
+
+ int size, used;
+ int *data;
+};
+
+JPXCover::JPXCover(int sizeA) {
+ size = sizeA;
+ used = -1;
+ data = (int *)gmallocn(size, sizeof(int));
+ memset(data, 0, size * sizeof(int));
+}
+
+JPXCover::~JPXCover() {
+ int i;
+
+ printf("JPX coverage:\n");
+ for (i = 0; i <= used; ++i) {
+ printf(" %4d: %8d\n", i, data[i]);
+ }
+ gfree(data);
+}
+
+void JPXCover::incr(int idx) {
+ if (idx < size) {
+ ++data[idx];
+ if (idx > used) {
+ used = idx;
+ }
+ }
+}
+
+JPXCover jpxCover(150);
+
+#define cover(idx) jpxCover.incr(idx)
+
+#endif //----- coverage tracking
+
+//------------------------------------------------------------------------
+
JPXStream::JPXStream(Stream *strA):
FilterStream(strA)
{
@@ -196,6 +249,24 @@
}
JPXStream::~JPXStream() {
+ close();
+ delete str;
+}
+
+void JPXStream::reset() {
+ str->reset();
+ if (readBoxes()) {
+ curY = img.yOffset;
+ } else {
+ // readBoxes reported an error, so we go immediately to EOF
+ curY = img.ySize;
+ }
+ curX = img.xOffset;
+ curComp = 0;
+ readBufLen = 0;
+}
+
+void JPXStream::close() {
JPXTile *tile;
JPXTileComp *tileComp;
JPXResLevel *resLevel;
@@ -205,19 +276,23 @@
Guint comp, i, k, r, pre, sb;
gfree(bpc);
+ bpc = NULL;
if (havePalette) {
gfree(palette.bpc);
gfree(palette.c);
+ havePalette = gFalse;
}
if (haveCompMap) {
gfree(compMap.comp);
gfree(compMap.type);
gfree(compMap.pComp);
+ haveCompMap = gFalse;
}
if (haveChannelDefn) {
gfree(channelDefn.idx);
gfree(channelDefn.type);
gfree(channelDefn.assoc);
+ haveChannelDefn = gFalse;
}
if (img.tiles) {
@@ -236,7 +311,7 @@
for (pre = 0; pre < 1; ++pre) {
precinct = &resLevel->precincts[pre];
if (precinct->subbands) {
- for (sb = 0; sb < (r == 0 ? 1 : 3); ++sb) {
+ for (sb = 0; sb < (Guint)(r == 0 ? 1 : 3); ++sb) {
subband = &precinct->subbands[sb];
gfree(subband->inclusion);
gfree(subband->zeroBitPlane);
@@ -267,21 +342,9 @@
}
}
gfree(img.tiles);
+ img.tiles = NULL;
}
- delete str;
-}
-
-void JPXStream::reset() {
- str->reset();
- if (readBoxes()) {
- curY = img.yOffset;
- } else {
- // readBoxes reported an error, so we go immediately to EOF
- curY = img.ySize;
- }
- curX = img.xOffset;
- curComp = 0;
- readBufLen = 0;
+ FilterStream::close();
}
int JPXStream::getChar() {
@@ -394,8 +457,10 @@
} else {
while (readBoxHdr(&boxType, &boxLen, &dataLen)) {
if (boxType == 0x6a703268) { // JP2 header
+ cover(0);
// skip the superbox
} else if (boxType == 0x69686472) { // image header
+ cover(1);
if (readULong(&dummy) &&
readULong(&dummy) &&
readUWord(&dummy) &&
@@ -407,6 +472,7 @@
haveBPC = gTrue;
}
} else if (boxType == 0x636F6C72) { // color specification
+ cover(2);
if (readByte(&csMeth) &&
readByte(&csPrec1) &&
readByte(&dummy2)) {
@@ -440,11 +506,13 @@
}
}
} else if (boxType == 0x6A703263) { // codestream
+ cover(3);
if (!(haveBPC && haveCSMode)) {
getImageParams2(bitsPerComponent, csMode);
}
break;
} else {
+ cover(4);
for (i = 0; i < dataLen; ++i) {
str->getChar();
}
@@ -462,6 +530,7 @@
while (readMarkerHdr(&segType, &segLen)) {
if (segType == 0x51) { // SIZ - image and tile size
+ cover(5);
if (readUWord(&dummy) &&
readULong(&dummy) &&
readULong(&dummy) &&
@@ -485,6 +554,7 @@
}
break;
} else {
+ cover(6);
if (segLen > 2) {
for (i = 0; i < segLen - 2; ++i) {
str->getChar();
@@ -505,6 +575,7 @@
// wrapper) -- this appears to be a violation of the PDF spec, but
// Acrobat allows it
if (str->lookChar() == 0xff) {
+ cover(7);
error(getPos(), "Naked JPEG 2000 codestream, missing JP2/JPX wrapper");
readCodestream(0);
nComps = img.nComps;
@@ -525,8 +596,10 @@
// some things which should be subboxes of the JP2 header box
// show up outside of it - so we simply ignore the JP2 header
// box
+ cover(8);
break;
case 0x69686472: // image header
+ cover(9);
if (!readULong(&height) ||
!readULong(&width) ||
!readUWord(&nComps) ||
@@ -548,6 +621,7 @@
haveImgHdr = gTrue;
break;
case 0x62706363: // bits per component
+ cover(10);
if (!haveImgHdr) {
error(getPos(), "Found bits per component box before image header box in JPX stream");
return gFalse;
@@ -564,11 +638,13 @@
}
break;
case 0x636F6C72: // color specification
+ cover(11);
if (!readColorSpecBox(dataLen)) {
return gFalse;
}
break;
case 0x70636c72: // palette
+ cover(12);
if (!readUWord(&palette.nEntries) ||
!readUByte(&palette.nComps)) {
error(getPos(), "Unexpected EOF in JPX stream");
@@ -597,6 +673,7 @@
havePalette = gTrue;
break;
case 0x636d6170: // component mapping
+ cover(13);
compMap.nChannels = dataLen / 4;
compMap.comp = (Guint *)gmallocn(compMap.nChannels, sizeof(Guint));
compMap.type = (Guint *)gmallocn(compMap.nChannels, sizeof(Guint));
@@ -612,6 +689,7 @@
haveCompMap = gTrue;
break;
case 0x63646566: // channel definition
+ cover(14);
if (!readUWord(&channelDefn.nChannels)) {
error(getPos(), "Unexpected EOF in JPX stream");
return gFalse;
@@ -633,6 +711,7 @@
haveChannelDefn = gTrue;
break;
case 0x6A703263: // contiguous codestream
+ cover(15);
if (!bpc) {
error(getPos(), "JPX stream is missing the image header box");
}
@@ -644,6 +723,7 @@
}
break;
default:
+ cover(16);
for (i = 0; i < dataLen; ++i) {
if (str->getChar() == EOF) {
error(getPos(), "Unexpected EOF in JPX stream");
@@ -670,6 +750,7 @@
}
switch (newCS.meth) {
case 1: // enumerated colorspace
+ cover(17);
if (!readULong(&csEnum)) {
goto err;
}
@@ -712,6 +793,7 @@
}
} else if (dataLen == 7) {
//~ this assumes the 8-bit case
+ cover(92);
newCS.enumerated.cieLab.rl = 100;
newCS.enumerated.cieLab.ol = 0;
newCS.enumerated.cieLab.ra = 255;
@@ -758,6 +840,7 @@
case 2: // restricted ICC profile
case 3: // any ICC profile (JPX)
case 4: // vendor color (JPX)
+ cover(18);
for (i = 0; i < dataLen - 3; ++i) {
if (str->getChar() == EOF) {
goto err;
@@ -784,7 +867,7 @@
int segType;
GBool haveSIZ, haveCOD, haveQCD, haveSOT;
Guint precinctSize, style;
- Guint segLen, capabilities, nTiles, comp, i, j, r;
+ Guint segLen, capabilities, comp, i, j, r;
//----- main header
haveSIZ = haveCOD = haveQCD = haveSOT = gFalse;
@@ -796,8 +879,10 @@
switch (segType) {
case 0x4f: // SOC - start of codestream
// marker only
+ cover(19);
break;
case 0x51: // SIZ - image and tile size
+ cover(20);
if (!readUWord(&capabilities) ||
!readULong(&img.xSize) ||
!readULong(&img.ySize) ||
@@ -819,13 +904,14 @@
/ img.xTileSize;
img.nYTiles = (img.ySize - img.yTileOffset + img.yTileSize - 1)
/ img.yTileSize;
- nTiles = img.nXTiles * img.nYTiles;
// check for overflow before allocating memory
- if (nTiles == 0 || nTiles / img.nXTiles != img.nYTiles) {
+ if (img.nXTiles <= 0 || img.nYTiles <= 0 ||
+ img.nXTiles >= INT_MAX / img.nYTiles) {
error(getPos(), "Bad tile count in JPX SIZ marker segment");
return gFalse;
}
- img.tiles = (JPXTile *)gmallocn(nTiles, sizeof(JPXTile));
+ img.tiles = (JPXTile *)gmallocn(img.nXTiles * img.nYTiles,
+ sizeof(JPXTile));
for (i = 0; i < img.nXTiles * img.nYTiles; ++i) {
img.tiles[i].tileComps = (JPXTileComp *)gmallocn(img.nComps,
sizeof(JPXTileComp));
@@ -854,6 +940,7 @@
haveSIZ = gTrue;
break;
case 0x52: // COD - coding style default
+ cover(21);
if (!readUByte(&img.tiles[0].tileComps[0].style) ||
!readUByte(&img.tiles[0].progOrder) ||
!readUWord(&img.tiles[0].nLayers) ||
@@ -900,6 +987,7 @@
}
for (r = 0; r <= img.tiles[0].tileComps[0].nDecompLevels; ++r) {
if (img.tiles[0].tileComps[0].style & 0x01) {
+ cover(91);
if (!readUByte(&precinctSize)) {
error(getPos(), "Error in JPX COD marker segment");
return gFalse;
@@ -928,6 +1016,7 @@
haveCOD = gTrue;
break;
case 0x53: // COC - coding style component
+ cover(22);
if (!haveCOD) {
error(getPos(), "JPX COC marker segment before COD segment");
return gFalse;
@@ -997,6 +1086,7 @@
}
break;
case 0x5c: // QCD - quantization default
+ cover(23);
if (!readUByte(&img.tiles[0].tileComps[0].quantStyle)) {
error(getPos(), "Error in JPX QCD marker segment");
return gFalse;
@@ -1060,6 +1150,7 @@
haveQCD = gTrue;
break;
case 0x5d: // QCC - quantization component
+ cover(24);
if (!haveQCD) {
error(getPos(), "JPX QCC marker segment before QCD segment");
return gFalse;
@@ -1127,6 +1218,7 @@
}
break;
case 0x5e: // RGN - region of interest
+ cover(25);
#if 1 //~ ROI is unimplemented
fprintf(stderr, "RGN\n");
for (i = 0; i < segLen - 2; ++i) {
@@ -1147,6 +1239,7 @@
#endif
break;
case 0x5f: // POC - progression order change
+ cover(26);
#if 1 //~ progression order changes are unimplemented
fprintf(stderr, "POC\n");
for (i = 0; i < segLen - 2; ++i) {
@@ -1174,6 +1267,7 @@
#endif
break;
case 0x60: // PPM - packed packet headers, main header
+ cover(27);
#if 1 //~ packed packet headers are unimplemented
fprintf(stderr, "PPM\n");
for (i = 0; i < segLen - 2; ++i) {
@@ -1186,6 +1280,7 @@
break;
case 0x55: // TLM - tile-part lengths
// skipped
+ cover(28);
for (i = 0; i < segLen - 2; ++i) {
if (str->getChar() == EOF) {
error(getPos(), "Error in JPX TLM marker segment");
@@ -1195,6 +1290,7 @@
break;
case 0x57: // PLM - packet length, main header
// skipped
+ cover(29);
for (i = 0; i < segLen - 2; ++i) {
if (str->getChar() == EOF) {
error(getPos(), "Error in JPX PLM marker segment");
@@ -1204,6 +1300,7 @@
break;
case 0x63: // CRG - component registration
// skipped
+ cover(30);
for (i = 0; i < segLen - 2; ++i) {
if (str->getChar() == EOF) {
error(getPos(), "Error in JPX CRG marker segment");
@@ -1213,6 +1310,7 @@
break;
case 0x64: // COM - comment
// skipped
+ cover(31);
for (i = 0; i < segLen - 2; ++i) {
if (str->getChar() == EOF) {
error(getPos(), "Error in JPX COM marker segment");
@@ -1221,9 +1319,11 @@
}
break;
case 0x90: // SOT - start of tile
+ cover(32);
haveSOT = gTrue;
break;
default:
+ cover(33);
error(getPos(), "Unknown marker segment %02x in JPX stream", segType);
for (i = 0; i < segLen - 2; ++i) {
if (str->getChar() == EOF) {
@@ -1324,6 +1424,7 @@
tilePartLen -= 2 + segLen;
switch (segType) {
case 0x52: // COD - coding style default
+ cover(34);
if (!readUByte(&img.tiles[tileIdx].tileComps[0].style) ||
!readUByte(&img.tiles[tileIdx].progOrder) ||
!readUWord(&img.tiles[tileIdx].nLayers) ||
@@ -1391,6 +1492,7 @@
}
break;
case 0x53: // COC - coding style component
+ cover(35);
if ((img.nComps > 256 && !readUWord(&comp)) ||
(img.nComps <= 256 && !readUByte(&comp)) ||
comp >= img.nComps ||
@@ -1432,6 +1534,7 @@
}
break;
case 0x5c: // QCD - quantization default
+ cover(36);
if (!readUByte(&img.tiles[tileIdx].tileComps[0].quantStyle)) {
error(getPos(), "Error in JPX QCD marker segment");
return gFalse;
@@ -1491,6 +1594,7 @@
}
break;
case 0x5d: // QCC - quantization component
+ cover(37);
if ((img.nComps > 256 && !readUWord(&comp)) ||
(img.nComps <= 256 && !readUByte(&comp)) ||
comp >= img.nComps ||
@@ -1542,6 +1646,7 @@
}
break;
case 0x5e: // RGN - region of interest
+ cover(38);
#if 1 //~ ROI is unimplemented
fprintf(stderr, "RGN\n");
for (i = 0; i < segLen - 2; ++i) {
@@ -1562,6 +1667,7 @@
#endif
break;
case 0x5f: // POC - progression order change
+ cover(39);
#if 1 //~ progression order changes are unimplemented
fprintf(stderr, "POC\n");
for (i = 0; i < segLen - 2; ++i) {
@@ -1589,6 +1695,7 @@
#endif
break;
case 0x61: // PPT - packed packet headers, tile-part hdr
+ cover(40);
#if 1 //~ packed packet headers are unimplemented
fprintf(stderr, "PPT\n");
for (i = 0; i < segLen - 2; ++i) {
@@ -1600,6 +1707,7 @@
#endif
case 0x58: // PLT - packet length, tile-part header
// skipped
+ cover(41);
for (i = 0; i < segLen - 2; ++i) {
if (str->getChar() == EOF) {
error(getPos(), "Error in JPX PLT marker segment");
@@ -1609,6 +1717,7 @@
break;
case 0x64: // COM - comment
// skipped
+ cover(42);
for (i = 0; i < segLen - 2; ++i) {
if (str->getChar() == EOF) {
error(getPos(), "Error in JPX COM marker segment");
@@ -1617,9 +1726,11 @@
}
break;
case 0x93: // SOD - start of data
+ cover(43);
haveSOD = gTrue;
break;
default:
+ cover(44);
error(getPos(), "Unknown marker segment %02x in JPX tile-part stream",
segType);
for (i = 0; i < segLen - 2; ++i) {
@@ -1817,6 +1928,7 @@
while (1) {
if (tilePartToEOC) {
//~ peek for an EOC marker
+ cover(93);
} else if (tilePartLen == 0) {
break;
}
@@ -1827,13 +1939,17 @@
//----- packet header
+ // setup
+ startBitBuf(tilePartLen);
+
// zero-length flag
if (!readBits(1, &bits)) {
goto err;
}
if (!bits) {
// packet is empty -- clear all code-block inclusion flags
- for (sb = 0; sb < (tile->res == 0 ? 1 : 3); ++sb) {
+ cover(45);
+ for (sb = 0; sb < (Guint)(tile->res == 0 ? 1 : 3); ++sb) {
subband = &precinct->subbands[sb];
for (cbY = 0; cbY < subband->nYCBs; ++cbY) {
for (cbX = 0; cbX < subband->nXCBs; ++cbX) {
@@ -1844,7 +1960,7 @@
}
} else {
- for (sb = 0; sb < (tile->res == 0 ? 1 : 3); ++sb) {
+ for (sb = 0; sb < (Guint)(tile->res == 0 ? 1 : 3); ++sb) {
subband = &precinct->subbands[sb];
for (cbY = 0; cbY < subband->nYCBs; ++cbY) {
for (cbX = 0; cbX < subband->nXCBs; ++cbX) {
@@ -1852,16 +1968,19 @@
// skip code-blocks with no coefficients
if (cb->x0 >= cb->x1 || cb->y0 >= cb->y1) {
+ cover(46);
cb->included = gFalse;
continue;
}
// code-block inclusion
if (cb->seen) {
+ cover(47);
if (!readBits(1, &cb->included)) {
goto err;
}
} else {
+ cover(48);
ttVal = 0;
i = 0;
for (level = subband->maxTTLevel; level >= 0; --level) {
@@ -1895,9 +2014,11 @@
}
if (cb->included) {
+ cover(49);
// zero bit-plane count
if (!cb->seen) {
+ cover(50);
ttVal = 0;
i = 0;
for (level = subband->maxTTLevel; level >= 0; --level) {
@@ -1931,26 +2052,33 @@
goto err;
}
if (bits == 0) {
+ cover(51);
cb->nCodingPasses = 1;
} else {
if (!readBits(1, &bits)) {
goto err;
}
if (bits == 0) {
+ cover(52);
cb->nCodingPasses = 2;
} else {
+ cover(53);
if (!readBits(2, &bits)) {
goto err;
}
if (bits < 3) {
+ cover(54);
cb->nCodingPasses = 3 + bits;
} else {
+ cover(55);
if (!readBits(5, &bits)) {
goto err;
}
if (bits < 31) {
+ cover(56);
cb->nCodingPasses = 6 + bits;
} else {
+ cover(57);
if (!readBits(7, &bits)) {
goto err;
}
@@ -1984,12 +2112,11 @@
}
}
}
- tilePartLen -= byteCount;
- clearBitBuf();
+ tilePartLen = finishBitBuf();
//----- packet data
- for (sb = 0; sb < (tile->res == 0 ? 1 : 3); ++sb) {
+ for (sb = 0; sb < (Guint)(tile->res == 0 ? 1 : 3); ++sb) {
subband = &precinct->subbands[sb];
for (cbY = 0; cbY < subband->nYCBs; ++cbY) {
for (cbX = 0; cbX < subband->nXCBs; ++cbX) {
@@ -2010,6 +2137,7 @@
switch (tile->progOrder) {
case 0: // layer, resolution level, component, precinct
+ cover(58);
if (++tile->comp == img.nComps) {
tile->comp = 0;
if (++tile->res == tile->maxNDecompLevels + 1) {
@@ -2021,6 +2149,7 @@
}
break;
case 1: // resolution level, layer, component, precinct
+ cover(59);
if (++tile->comp == img.nComps) {
tile->comp = 0;
if (++tile->layer == tile->nLayers) {
@@ -2033,6 +2162,7 @@
break;
case 2: // resolution level, precinct, component, layer
//~ this isn't correct -- see B.12.1.3
+ cover(60);
if (++tile->layer == tile->nLayers) {
tile->layer = 0;
if (++tile->comp == img.nComps) {
@@ -2045,6 +2175,7 @@
break;
case 3: // precinct, component, resolution level, layer
//~ this isn't correct -- see B.12.1.4
+ cover(61);
if (++tile->layer == tile->nLayers) {
tile->layer = 0;
if (++tile->res == tile->maxNDecompLevels + 1) {
@@ -2057,6 +2188,7 @@
break;
case 4: // component, precinct, resolution level, layer
//~ this isn't correct -- see B.12.1.5
+ cover(62);
if (++tile->layer == tile->nLayers) {
tile->layer = 0;
if (++tile->res == tile->maxNDecompLevels + 1) {
@@ -2089,8 +2221,10 @@
Guint i, x, y0, y1, y2;
if (cb->arithDecoder) {
+ cover(63);
cb->arithDecoder->restart(cb->dataLen);
} else {
+ cover(64);
cb->arithDecoder = new JArithmeticDecoder();
cb->arithDecoder->setStream(str, cb->dataLen);
cb->arithDecoder->start();
@@ -2105,6 +2239,7 @@
//----- significance propagation pass
case jpxPassSigProp:
+ cover(65);
for (y0 = cb->y0, coeff0 = cb->coeffs;
y0 < cb->y1;
y0 += 4, coeff0 += 4 << tileComp->codeBlockW) {
@@ -2182,6 +2317,7 @@
//----- magnitude refinement pass
case jpxPassMagRef:
+ cover(66);
for (y0 = cb->y0, coeff0 = cb->coeffs;
y0 < cb->y1;
y0 += 4, coeff0 += 4 << tileComp->codeBlockW) {
@@ -2243,6 +2379,7 @@
//----- cleanup pass
case jpxPassCleanup:
+ cover(67);
for (y0 = cb->y0, coeff0 = cb->coeffs;
y0 < cb->y1;
y0 += 4, coeff0 += 4 << tileComp->codeBlockW) {
@@ -2404,6 +2541,8 @@
Guint nx0, ny0, nx1, ny1;
Guint r, cbX, cbY, x, y;
+ cover(68);
+
//----- (NL)LL subband (resolution level 0)
resLevel = &tileComp->resLevels[0];
@@ -2414,14 +2553,17 @@
qStyle = tileComp->quantStyle & 0x1f;
guard = (tileComp->quantStyle >> 5) & 7;
if (qStyle == 0) {
+ cover(69);
eps = (tileComp->quantSteps[0] >> 3) & 0x1f;
shift = guard + eps - 1;
mu = 0; // make gcc happy
} else {
+ cover(70);
shift = guard - 1 + tileComp->prec;
mu = (double)(0x800 + (tileComp->quantSteps[0] & 0x7ff)) / 2048.0;
}
if (tileComp->transform == 0) {
+ cover(71);
shift += fracBits;
}
@@ -2441,18 +2583,24 @@
if (val != 0) {
shift2 = shift - (cb->nZeroBitPlanes + coeff->len);
if (shift2 > 0) {
+ cover(94);
val = (val << shift2) + (1 << (shift2 - 1));
} else {
+ cover(95);
val >>= -shift2;
}
if (qStyle == 0) {
+ cover(96);
if (tileComp->transform == 0) {
+ cover(97);
val &= -1 << fracBits;
}
} else {
+ cover(98);
val = (int)((double)val * mu);
}
if (coeff->flags & jpxCoeffSign) {
+ cover(99);
val = -val;
}
}
@@ -2473,11 +2621,13 @@
// and inverse transform to get (n-1)LL, which will be stored
// in the upper-left corner of the tile-component data array
if (r == tileComp->nDecompLevels) {
+ cover(72);
nx0 = tileComp->x0;
ny0 = tileComp->y0;
nx1 = tileComp->x1;
ny1 = tileComp->y1;
} else {
+ cover(73);
nx0 = tileComp->resLevels[r+1].x0;
ny0 = tileComp->resLevels[r+1].y0;
nx1 = tileComp->resLevels[r+1].x1;
@@ -2530,18 +2680,22 @@
// i-quant parameters
if (qStyle == 0) {
+ cover(100);
eps = (tileComp->quantSteps[3*r - 2 + sb] >> 3) & 0x1f;
shift = guard + eps - 1;
mu = 0; // make gcc happy
} else {
+ cover(101);
shift = guard + tileComp->prec;
if (sb == 2) {
+ cover(102);
++shift;
}
t = tileComp->quantSteps[qStyle == 1 ? 0 : (3*r - 2 + sb)];
mu = (double)(0x800 + (t & 0x7ff)) / 2048.0;
}
if (tileComp->transform == 0) {
+ cover(103);
shift += fracBits;
}
@@ -2564,18 +2718,23 @@
if (val != 0) {
shift2 = shift - (cb->nZeroBitPlanes + coeff->len);
if (shift2 > 0) {
+ cover(74);
val = (val << shift2) + (1 << (shift2 - 1));
} else {
+ cover(75);
val >>= -shift2;
}
if (qStyle == 0) {
+ cover(76);
if (tileComp->transform == 0) {
val &= -1 << fracBits;
}
} else {
+ cover(77);
val = (int)((double)val * mu);
}
if (coeff->flags & jpxCoeffSign) {
+ cover(78);
val = -val;
}
}
@@ -2612,11 +2771,14 @@
//----- special case for length = 1
if (i1 - i0 == 1) {
+ cover(79);
if (i0 & 1) {
+ cover(104);
*data >>= 1;
}
} else {
+ cover(80);
// choose an offset: this makes even buf[] indexes correspond to
// odd values of i, and vice versa
@@ -2632,19 +2794,25 @@
//----- extend right
buf[end] = buf[end - 2];
if (i1 - i0 == 2) {
+ cover(81);
buf[end+1] = buf[offset + 1];
buf[end+2] = buf[offset];
buf[end+3] = buf[offset + 1];
} else {
+ cover(82);
buf[end+1] = buf[end - 3];
if (i1 - i0 == 3) {
+ cover(105);
buf[end+2] = buf[offset + 1];
buf[end+3] = buf[offset + 2];
} else {
+ cover(106);
buf[end+2] = buf[end - 4];
if (i1 - i0 == 4) {
+ cover(107);
buf[end+3] = buf[offset + 1];
} else {
+ cover(108);
buf[end+3] = buf[end - 5];
}
}
@@ -2655,12 +2823,14 @@
buf[offset - 2] = buf[offset + 2];
buf[offset - 3] = buf[offset + 3];
if (offset == 4) {
+ cover(83);
buf[0] = buf[offset + 4];
}
//----- 9-7 irreversible filter
if (tileComp->transform == 0) {
+ cover(84);
// step 1 (even)
for (i = 1; i <= end + 2; i += 2) {
buf[i] = (int)(idwtKappa * buf[i]);
@@ -2689,6 +2859,7 @@
//----- 5-3 reversible filter
} else {
+ cover(85);
// step 1 (even)
for (i = 3; i <= end; i += 2) {
buf[i] -= (buf[i-1] + buf[i+1] + 2) >> 2;
@@ -2717,6 +2888,7 @@
//----- inverse multi-component transform
if (tile->multiComp == 1) {
+ cover(86);
if (img.nComps < 3 ||
tile->tileComps[0].hSep != tile->tileComps[1].hSep ||
tile->tileComps[0].vSep != tile->tileComps[1].vSep ||
@@ -2727,6 +2899,7 @@
// inverse irreversible multiple component transform
if (tile->tileComps[0].transform == 0) {
+ cover(87);
j = 0;
for (y = 0; y < tile->tileComps[0].y1 - tile->tileComps[0].y0; ++y) {
for (x = 0; x < tile->tileComps[0].x1 - tile->tileComps[0].x0; ++x) {
@@ -2743,6 +2916,7 @@
// inverse reversible multiple component transform
} else {
+ cover(88);
j = 0;
for (y = 0; y < tile->tileComps[0].y1 - tile->tileComps[0].y0; ++y) {
for (x = 0; x < tile->tileComps[0].x1 - tile->tileComps[0].x0; ++x) {
@@ -2764,6 +2938,7 @@
// signed: clip
if (tileComp->sgned) {
+ cover(89);
minVal = -(1 << (tileComp->prec - 1));
maxVal = (1 << (tileComp->prec - 1)) - 1;
dataPtr = tileComp->data;
@@ -2771,11 +2946,14 @@
for (x = 0; x < tileComp->x1 - tileComp->x0; ++x) {
coeff = *dataPtr;
if (tileComp->transform == 0) {
+ cover(109);
coeff >>= fracBits;
}
if (coeff < minVal) {
+ cover(110);
coeff = minVal;
} else if (coeff > maxVal) {
+ cover(111);
coeff = maxVal;
}
*dataPtr++ = coeff;
@@ -2784,6 +2962,7 @@
// unsigned: inverse DC level shift and clip
} else {
+ cover(90);
maxVal = (1 << tileComp->prec) - 1;
zeroVal = 1 << (tileComp->prec - 1);
dataPtr = tileComp->data;
@@ -2791,12 +2970,15 @@
for (x = 0; x < tileComp->x1 - tileComp->x0; ++x) {
coeff = *dataPtr;
if (tileComp->transform == 0) {
+ cover(112);
coeff >>= fracBits;
}
coeff += zeroVal;
if (coeff < 0) {
+ cover(113);
coeff = 0;
} else if (coeff > maxVal) {
+ cover(114);
coeff = maxVal;
}
*dataPtr++ = coeff;
@@ -2929,10 +3111,10 @@
int c;
while (bitBufLen < nBits) {
- if ((c = str->getChar()) == EOF) {
+ if (byteCount == 0 || (c = str->getChar()) == EOF) {
return gFalse;
}
- ++byteCount;
+ --byteCount;
if (bitBufSkip) {
bitBuf = (bitBuf << 7) | (c & 0x7f);
bitBufLen += 7;
@@ -2947,8 +3129,16 @@
return gTrue;
}
-void JPXStream::clearBitBuf() {
+void JPXStream::startBitBuf(Guint byteCountA) {
bitBufLen = 0;
bitBufSkip = gFalse;
- byteCount = 0;
+ byteCount = byteCountA;
+}
+
+Guint JPXStream::finishBitBuf() {
+ if (bitBufSkip) {
+ str->getChar();
+ --byteCount;
+ }
+ return byteCount;
}
Index: JPXStream.h
===================================================================
RCS file: /cvs/poppler/poppler/poppler/JPXStream.h,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -d -r1.2 -r1.3
--- JPXStream.h 31 Aug 2005 15:28:46 -0000 1.2
+++ JPXStream.h 25 Apr 2007 19:59:10 -0000 1.3
@@ -17,6 +17,7 @@
#include "Object.h"
#include "Stream.h"
+class JArithmeticDecoder;
class JArithmeticDecoderStats;
//------------------------------------------------------------------------
@@ -275,6 +276,7 @@
virtual ~JPXStream();
virtual StreamKind getKind() { return strJPX; }
virtual void reset();
+ virtual void close();
virtual int getChar();
virtual int lookChar();
virtual GooString *getPSFilter(int psLevel, char *indent);
@@ -315,7 +317,8 @@
GBool readULong(Guint *x);
GBool readNBytes(int nBytes, GBool signd, int *x);
GBool readBits(int nBits, Guint *x);
- void clearBitBuf();
+ void startBitBuf(Guint byteCountA);
+ Guint finishBitBuf();
Guint nComps; // number of components
Guint *bpc; // bits per component, for each component
@@ -336,8 +339,7 @@
int bitBufLen; // number of bits in bitBuf
GBool bitBufSkip; // true if next bit should be skipped
// (for bit stuffing)
- Guint byteCount; // number of bytes read since last call
- // to clearBitBuf
+ Guint byteCount; // number of available bytes left
Guint curX, curY, curComp; // current position for lookChar/getChar
Guint readBuf; // read buffer
Index: Lexer.cc
===================================================================
RCS file: /cvs/poppler/poppler/poppler/Lexer.cc,v
retrieving revision 1.5
retrieving revision 1.6
diff -u -d -r1.5 -r1.6
--- Lexer.cc 4 Feb 2007 00:16:43 -0000 1.5
+++ Lexer.cc 25 Apr 2007 19:59:10 -0000 1.6
@@ -319,11 +319,13 @@
// we are growing see if the document is not malformed and we are growing too much
if (objNum != -1)
{
- int newObjNum = xref->getNumEntry(getPos());
+ int newObjNum = xref->getNumEntry(curStr.streamGetPos());
if (newObjNum != objNum)
{
error(getPos(), "Unterminated string");
done = gTrue;
+ delete s;
+ n = -2;
}
}
}
@@ -331,11 +333,15 @@
++n;
}
} while (!done);
- if (!s)
- s = new GooString(tokBuf, n);
- else
- s->append(tokBuf, n);
- obj->initString(s);
+ if (n >= 0) {
+ if (!s)
+ s = new GooString(tokBuf, n);
+ else
+ s->append(tokBuf, n);
+ obj->initString(s);
+ } else {
+ obj->initEOF();
+ }
break;
// name
Index: Link.cc
===================================================================
RCS file: /cvs/poppler/poppler/poppler/Link.cc,v
retrieving revision 1.5
retrieving revision 1.6
diff -u -d -r1.5 -r1.6
--- Link.cc 8 Oct 2006 20:38:47 -0000 1.5
+++ Link.cc 25 Apr 2007 19:59:10 -0000 1.6
@@ -22,7 +22,6 @@
#include "Dict.h"
#include "Link.h"
#include "Sound.h"
-#include "UGooString.h"
//------------------------------------------------------------------------
// LinkAction
@@ -296,7 +295,7 @@
kind = destFitH;
if (!a->get(2, &obj2)->isNum()) {
error(-1, "Bad annotation destination position");
- goto err1;
+ kind = destFit;
}
top = obj2.getNum();
obj2.free();
@@ -310,7 +309,7 @@
kind = destFitV;
if (!a->get(2, &obj2)->isNum()) {
error(-1, "Bad annotation destination position");
- goto err1;
+ kind = destFit;
}
left = obj2.getNum();
obj2.free();
@@ -324,25 +323,25 @@
kind = destFitR;
if (!a->get(2, &obj2)->isNum()) {
error(-1, "Bad annotation destination position");
- goto err1;
+ kind = destFit;
}
left = obj2.getNum();
obj2.free();
if (!a->get(3, &obj2)->isNum()) {
error(-1, "Bad annotation destination position");
- goto err1;
+ kind = destFit;
}
bottom = obj2.getNum();
obj2.free();
if (!a->get(4, &obj2)->isNum()) {
error(-1, "Bad annotation destination position");
- goto err1;
+ kind = destFit;
}
right = obj2.getNum();
obj2.free();
if (!a->get(5, &obj2)->isNum()) {
error(-1, "Bad annotation destination position");
- goto err1;
+ kind = destFit;
}
top = obj2.getNum();
obj2.free();
@@ -364,7 +363,7 @@
kind = destFitBH;
if (!a->get(2, &obj2)->isNum()) {
error(-1, "Bad annotation destination position");
- goto err1;
+ kind = destFit;
}
top = obj2.getNum();
obj2.free();
@@ -378,7 +377,7 @@
kind = destFitBV;
if (!a->get(2, &obj2)->isNum()) {
error(-1, "Bad annotation destination position");
- goto err1;
+ kind = destFit;
}
left = obj2.getNum();
obj2.free();
@@ -427,9 +426,9 @@
// named destination
if (destObj->isName()) {
- namedDest = new UGooString(destObj->getName());
+ namedDest = new GooString(destObj->getName());
} else if (destObj->isString()) {
- namedDest = new UGooString(*destObj->getString());
+ namedDest = destObj->getString()->copy();
// destination dictionary
} else if (destObj->isArray()) {
@@ -465,9 +464,9 @@
// named destination
if (destObj->isName()) {
- namedDest = new UGooString(destObj->getName());
+ namedDest = new GooString(destObj->getName());
} else if (destObj->isString()) {
- namedDest = new UGooString(*destObj->getString());
+ namedDest = destObj->getString()->copy();
// destination dictionary
} else if (destObj->isArray()) {
@@ -691,42 +690,13 @@
}
//------------------------------------------------------------------------
-// LinkBorderStyle
-//------------------------------------------------------------------------
-
-LinkBorderStyle::LinkBorderStyle(LinkBorderType typeA, double widthA,
- double *dashA, int dashLengthA,
- double rA, double gA, double bA) {
- type = typeA;
- width = widthA;
- dash = dashA;
- dashLength = dashLengthA;
- r = rA;
- g = gA;
- b = bA;
-}
-
-LinkBorderStyle::~LinkBorderStyle() {
- if (dash) {
- gfree(dash);
- }
-}
-
-//------------------------------------------------------------------------
// Link
//------------------------------------------------------------------------
Link::Link(Dict *dict, GooString *baseURI) {
- Object obj1, obj2, obj3;
- LinkBorderType borderType;
- double borderWidth;
- double *borderDash;
- int borderDashLength;
- double borderR, borderG, borderB;
+ Object obj1, obj2;
double t;
- int i;
- borderStyle = NULL;
action = NULL;
ok = gFalse;
@@ -771,97 +741,6 @@
y2 = t;
}
- // get the border style info
- borderType = linkBorderSolid;
- borderWidth = 1;
- borderDash = NULL;
- borderDashLength = 0;
- borderR = 0;
- borderG = 0;
- borderB = 1;
- if (dict->lookup("BS", &obj1)->isDict()) {
- if (obj1.dictLookup("S", &obj2)->isName()) {
- if (obj2.isName("S")) {
- borderType = linkBorderSolid;
- } else if (obj2.isName("D")) {
- borderType = linkBorderDashed;
- } else if (obj2.isName("B")) {
- borderType = linkBorderEmbossed;
- } else if (obj2.isName("I")) {
- borderType = linkBorderEngraved;
- } else if (obj2.isName("U")) {
- borderType = linkBorderUnderlined;
- }
- }
- obj2.free();
- if (obj1.dictLookup("W", &obj2)->isNum()) {
- borderWidth = obj2.getNum();
- }
- obj2.free();
- if (obj1.dictLookup("D", &obj2)->isArray()) {
- borderDashLength = obj2.arrayGetLength();
- borderDash = (double *)gmallocn(borderDashLength, sizeof(double));
- for (i = 0; i < borderDashLength; ++i) {
- if (obj2.arrayGet(i, &obj3)->isNum()) {
- borderDash[i] = obj3.getNum();
- } else {
- borderDash[i] = 1;
- }
- obj3.free();
- }
- }
- obj2.free();
- } else {
- obj1.free();
- if (dict->lookup("Border", &obj1)->isArray()) {
- if (obj1.arrayGetLength() >= 3) {
- if (obj1.arrayGet(2, &obj2)->isNum()) {
- borderWidth = obj2.getNum();
- }
- obj2.free();
- if (obj1.arrayGetLength() >= 4) {
- if (obj1.arrayGet(3, &obj2)->isArray()) {
- borderType = linkBorderDashed;
- borderDashLength = obj2.arrayGetLength();
- borderDash = (double *)gmallocn(borderDashLength, sizeof(double));
- for (i = 0; i < borderDashLength; ++i) {
- if (obj2.arrayGet(i, &obj3)->isNum()) {
- borderDash[i] = obj3.getNum();
- } else {
- borderDash[i] = 1;
- }
- obj3.free();
- }
- } else {
- // Adobe draws no border at all if the last element is of
- // the wrong type.
- borderWidth = 0;
- }
- obj2.free();
- }
- }
- }
- }
- obj1.free();
- if (dict->lookup("C", &obj1)->isArray() && obj1.arrayGetLength() == 3) {
- if (obj1.arrayGet(0, &obj2)->isNum()) {
- borderR = obj2.getNum();
- }
- obj1.free();
- if (obj1.arrayGet(1, &obj2)->isNum()) {
- borderG = obj2.getNum();
- }
- obj1.free();
- if (obj1.arrayGet(2, &obj2)->isNum()) {
- borderB = obj2.getNum();
- }
- obj1.free();
- }
- obj1.free();
- borderStyle = new LinkBorderStyle(borderType, borderWidth,
- borderDash, borderDashLength,
- borderR, borderG, borderB);
-
// look for destination
if (!dict->lookup("Dest", &obj1)->isNull()) {
action = LinkAction::parseDest(&obj1);
@@ -889,9 +768,6 @@
}
Link::~Link() {
- if (borderStyle) {
- delete borderStyle;
- }
if (action) {
delete action;
}
Index: Link.h
===================================================================
RCS file: /cvs/poppler/poppler/poppler/Link.h,v
retrieving revision 1.3
retrieving revision 1.4
diff -u -d -r1.3 -r1.4
--- Link.h 8 Oct 2006 20:38:47 -0000 1.3
+++ Link.h 25 Apr 2007 19:59:10 -0000 1.4
@@ -16,7 +16,6 @@
#include "Object.h"
class GooString;
-class UGooString;
class Array;
class Dict;
class Sound;
@@ -137,13 +136,13 @@
// Accessors.
virtual LinkActionKind getKind() { return actionGoTo; }
LinkDest *getDest() { return dest; }
- UGooString *getNamedDest() { return namedDest; }
+ GooString *getNamedDest() { return namedDest; }
private:
LinkDest *dest; // regular destination (NULL for remote
// link with bad destination)
- UGooString *namedDest; // named destination (only one of dest and
+ GooString *namedDest; // named destination (only one of dest and
// and namedDest may be non-NULL)
};
@@ -168,14 +167,14 @@
virtual LinkActionKind getKind() { return actionGoToR; }
GooString *getFileName() { return fileName; }
LinkDest *getDest() { return dest; }
- UGooString *getNamedDest() { return namedDest; }
+ GooString *getNamedDest() { return namedDest; }
private:
GooString *fileName; // file name
LinkDest *dest; // regular destination (NULL for remote
// link with bad destination)
- UGooString *namedDest; // named destination (only one of dest and
+ GooString *namedDest; // named destination (only one of dest and
// and namedDest may be non-NULL)
};
@@ -333,42 +332,6 @@
};
//------------------------------------------------------------------------
-// LinkBorderStyle
-//------------------------------------------------------------------------
-
-enum LinkBorderType {
- linkBorderSolid,
- linkBorderDashed,
- linkBorderEmbossed,
- linkBorderEngraved,
- linkBorderUnderlined
-};
-
-class LinkBorderStyle {
-public:
-
- LinkBorderStyle(LinkBorderType typeA, double widthA,
- double *dashA, int dashLengthA,
- double rA, double gA, double bA);
- ~LinkBorderStyle();
-
- LinkBorderType getType() { return type; }
- double getWidth() { return width; }
- void getDash(double **dashA, int *dashLengthA)
- { *dashA = dash; *dashLengthA = dashLength; }
- void getColor(double *rA, double *gA, double *bA)
- { *rA = r; *gA = g; *bA = b; }
-
-private:
-
- LinkBorderType type;
- double width;
- double *dash;
- int dashLength;
- double r, g, b;
-};
-
-//------------------------------------------------------------------------
// Link
//------------------------------------------------------------------------
@@ -395,14 +358,10 @@
void getRect(double *xa1, double *ya1, double *xa2, double *ya2)
{ *xa1 = x1; *ya1 = y1; *xa2 = x2; *ya2 = y2; }
- // Get the border style info.
- LinkBorderStyle *getBorderStyle() { return borderStyle; }
-
private:
double x1, y1; // lower left corner
double x2, y2; // upper right corner
- LinkBorderStyle *borderStyle; // border style
LinkAction *action; // action
GBool ok; // is link valid?
};
Index: Makefile.am
===================================================================
RCS file: /cvs/poppler/poppler/poppler/Makefile.am,v
retrieving revision 1.30
retrieving revision 1.31
diff -u -d -r1.30 -r1.31
--- Makefile.am 4 Apr 2007 02:42:29 -0000 1.30
+++ Makefile.am 25 Apr 2007 19:59:10 -0000 1.31
@@ -154,6 +154,7 @@
PDFDoc.h \
PDFDocEncoding.h \
ProfileData.h \
+ PreScanOutputDev.h \
PSTokenizer.h \
Stream-CCITT.h \
Stream.h \
@@ -171,7 +172,6 @@
PSOutputDev.h \
TextOutputDev.h \
SecurityHandler.h \
- UGooString.h \
UTF8.h \
XpdfPluginAPI.h \
Sound.h \
@@ -218,6 +218,7 @@
PDFDoc.cc \
PDFDocEncoding.cc \
ProfileData.cc \
+ PreScanOutputDev.cc \
PSTokenizer.cc \
Stream.cc \
UnicodeMap.cc \
@@ -228,7 +229,6 @@
PageLabelInfo.h \
PageLabelInfo.cc \
SecurityHandler.cc \
- UGooString.cc \
Sound.cc \
XpdfPluginAPI.cc
Index: Object.cc
===================================================================
RCS file: /cvs/poppler/poppler/poppler/Object.cc,v
retrieving revision 1.3
retrieving revision 1.4
diff -u -d -r1.3 -r1.4
--- Object.cc 25 Feb 2006 12:30:30 -0000 1.3
+++ Object.cc 25 Apr 2007 19:59:10 -0000 1.4
@@ -18,7 +18,6 @@
#include "Dict.h"
#include "Error.h"
#include "Stream.h"
-#include "UGooString.h"
#include "XRef.h"
//------------------------------------------------------------------------
@@ -185,7 +184,7 @@
case objDict:
fprintf(f, "<<");
for (i = 0; i < dictGetLength(); ++i) {
- fprintf(f, " /%s ", dictGetKey(i)->getCString());
+ fprintf(f, " /%s ", dictGetKey(i));
dictGetValNF(i, &obj);
obj.print(f);
obj.free();
@@ -228,5 +227,7 @@
fprintf(f, " %-20s: %6d\n", objTypeNames[i], numAlloc[i]);
}
}
+#else
+ (void)f;
#endif
}
Index: Object.h
===================================================================
RCS file: /cvs/poppler/poppler/poppler/Object.h,v
retrieving revision 1.4
retrieving revision 1.5
diff -u -d -r1.4 -r1.5
--- Object.h 24 Feb 2007 23:32:23 -0000 1.4
+++ Object.h 25 Apr 2007 19:59:10 -0000 1.5
@@ -23,7 +23,6 @@
class Array;
class Dict;
class Stream;
-class UGooString;
//------------------------------------------------------------------------
// Ref
@@ -168,14 +167,12 @@
// Dict accessors.
int dictGetLength();
- void dictAddOwnKeyVal(UGooString *key, Object *val);
- void dictAdd(const UGooString &key, Object *val);
- void dictAddOwnVal(const char *key, Object *val);
- void dictSet(const UGooString &key, Object *val);
+ void dictAdd(char *key, Object *val);
+ void dictSet(char *key, Object *val);
GBool dictIs(char *dictType);
- Object *dictLookup(const UGooString &key, Object *obj);
- Object *dictLookupNF(const UGooString &key, Object *obj);
- UGooString *dictGetKey(int i);
+ Object *dictLookup(char *key, Object *obj);
+ Object *dictLookupNF(char *key, Object *obj);
+ char *dictGetKey(int i);
Object *dictGetVal(int i, Object *obj);
Object *dictGetValNF(int i, Object *obj);
@@ -246,16 +243,10 @@
inline int Object::dictGetLength()
{ return dict->getLength(); }
-inline void Object::dictAdd(const UGooString &key, Object *val)
+inline void Object::dictAdd(char *key, Object *val)
{ dict->add(key, val); }
-inline void Object::dictAddOwnVal(const char *key, Object *val)
- { dict->addOwnVal(key, val); }
-
-inline void Object::dictAddOwnKeyVal(UGooString *key, Object *val)
- { dict->addOwnKeyVal(key, val); }
-
-inline void Object::dictSet(const UGooString &key, Object *val)
+inline void Object::dictSet(char *key, Object *val)
{ dict->set(key, val); }
inline GBool Object::dictIs(char *dictType)
@@ -264,13 +255,13 @@
inline GBool Object::isDict(char *dictType)
{ return type == objDict && dictIs(dictType); }
-inline Object *Object::dictLookup(const UGooString &key, Object *obj)
+inline Object *Object::dictLookup(char *key, Object *obj)
{ return dict->lookup(key, obj); }
-inline Object *Object::dictLookupNF(const UGooString &key, Object *obj)
+inline Object *Object::dictLookupNF(char *key, Object *obj)
{ return dict->lookupNF(key, obj); }
-inline UGooString *Object::dictGetKey(int i)
+inline char *Object::dictGetKey(int i)
{ return dict->getKey(i); }
inline Object *Object::dictGetVal(int i, Object *obj)
Index: Outline.cc
===================================================================
RCS file: /cvs/poppler/poppler/poppler/Outline.cc,v
retrieving revision 1.5
retrieving revision 1.6
diff -u -d -r1.5 -r1.6
--- Outline.cc 18 Jan 2006 22:32:13 -0000 1.5
+++ Outline.cc 25 Apr 2007 19:59:10 -0000 1.6
@@ -18,7 +18,6 @@
#include "Link.h"
#include "PDFDocEncoding.h"
#include "Outline.h"
-#include "UGooString.h"
//------------------------------------------------------------------------
Index: OutputDev.cc
===================================================================
RCS file: /cvs/poppler/poppler/poppler/OutputDev.cc,v
retrieving revision 1.4
retrieving revision 1.5
diff -u -d -r1.4 -r1.5
--- OutputDev.cc 4 Feb 2006 21:10:41 -0000 1.4
+++ OutputDev.cc 25 Apr 2007 19:59:10 -0000 1.5
@@ -56,6 +56,7 @@
updateLineCap(state);
updateMiterLimit(state);
updateLineWidth(state);
+ updateStrokeAdjust(state);
updateFillColorSpace(state);
updateFillColor(state);
updateStrokeColorSpace(state);
@@ -65,6 +66,7 @@
updateStrokeOpacity(state);
updateFillOverprint(state);
updateStrokeOverprint(state);
+ updateTransfer(state);
updateFont(state);
}
Index: OutputDev.h
===================================================================
RCS file: /cvs/poppler/poppler/poppler/OutputDev.h,v
retrieving revision 1.5
retrieving revision 1.6
diff -u -d -r1.5 -r1.6
--- OutputDev.h 4 Feb 2006 21:10:41 -0000 1.5
+++ OutputDev.h 25 Apr 2007 19:59:10 -0000 1.6
@@ -21,14 +21,18 @@
class GooHash;
class GooString;
class GfxState;
+struct GfxColor;
class GfxColorSpace;
class GfxImageColorMap;
class GfxFunctionShading;
class GfxAxialShading;
class GfxRadialShading;
class Stream;
+class Links;
class Link;
class Catalog;
+class Page;
+class Function;
//------------------------------------------------------------------------
// OutputDev
@@ -62,6 +66,10 @@
// will be reduced to a series of other drawing operations.
virtual GBool useShadedFills() { return gFalse; }
+ // Does this device use drawForm()? If this returns false,
+ // form-type XObjects will be interpreted (i.e., unrolled).
+ virtual GBool useDrawForm() { return gFalse; }
+
// Does this device use beginType3Char/endType3Char? Otherwise,
// text in Type 3 fonts will be drawn with drawChar/drawString.
virtual GBool interpretType3Chars() = 0;
@@ -74,8 +82,20 @@
// Set default transform matrix.
virtual void setDefaultCTM(double *ctm);
+ // Check to see if a page slice should be displayed. If this
+ // returns false, the page display is aborted. Typically, an
+ // OutputDev will use some alternate means to display the page
+ // before returning false.
+ virtual GBool checkPageSlice(Page *page, double hDPI, double vDPI,
+ int rotate, GBool useMediaBox, GBool crop,
+ int sliceX, int sliceY, int sliceW, int sliceH,
+ GBool printing, Catalog * catalog,
+ GBool (* abortCheckCbk)(void *data) = NULL,
+ void * abortCheckCbkData = NULL)
+ { return gTrue; }
+
// Start a page.
- virtual void startPage(int /*pageNum*/, GfxState * /*state*/) {}
+ virtual void startPage(int pageNum, GfxState *state) {}
// End a page.
virtual void endPage() {}
@@ -92,9 +112,6 @@
double *getDefCTM() { return defCTM; }
double *getDefICTM() { return defICTM; }
- //----- link borders
- virtual void drawLink(Link * /*link*/, Catalog * /*catalog*/) {}
-
//----- save/restore graphics state
virtual void saveState(GfxState * /*state*/) {}
virtual void restoreState(GfxState * /*state*/) {}
@@ -109,6 +126,7 @@
virtual void updateLineCap(GfxState * /*state*/) {}
virtual void updateMiterLimit(GfxState * /*state*/) {}
virtual void updateLineWidth(GfxState * /*state*/) {}
+ virtual void updateStrokeAdjust(GfxState * /*state*/) {}
virtual void updateFillColorSpace(GfxState * /*state*/) {}
virtual void updateStrokeColorSpace(GfxState * /*state*/) {}
virtual void updateFillColor(GfxState * /*state*/) {}
@@ -118,6 +136,7 @@
virtual void updateStrokeOpacity(GfxState * /*state*/) {}
virtual void updateFillOverprint(GfxState * /*state*/) {}
virtual void updateStrokeOverprint(GfxState * /*state*/) {}
+ virtual void updateTransfer(GfxState * /*state*/) {}
//----- update text state
virtual void updateFont(GfxState * /*state*/) {}
@@ -139,14 +158,18 @@
double * /*mat*/, double * /*bbox*/,
int /*x0*/, int /*y0*/, int /*x1*/, int /*y1*/,
double /*xStep*/, double /*yStep*/) {}
- virtual void functionShadedFill(GfxState * /*state*/,
- GfxFunctionShading * /*shading*/) {}
- virtual void axialShadedFill(GfxState * /*state*/, GfxAxialShading * /*shading*/) {}
- virtual void radialShadedFill(GfxState * /*state*/, GfxRadialShading * /*shading*/) {}
+ virtual GBool functionShadedFill(GfxState * /*state*/,
+ GfxFunctionShading * /*shading*/)
+ { return gFalse; }
+ virtual GBool axialShadedFill(GfxState * /*state*/, GfxAxialShading * /*shading*/)
+ { return gFalse; }
+ virtual GBool radialShadedFill(GfxState * /*state*/, GfxRadialShading * /*shading*/)
+ { return gFalse; }
//----- path clipping
virtual void clip(GfxState * /*state*/) {}
virtual void eoClip(GfxState * /*state*/) {}
+ virtual void clipToStrokePath(GfxState * /*state*/) {}
//----- text drawing
virtual void beginStringOp(GfxState * /*state*/) {}
@@ -204,6 +227,9 @@
virtual void type3D1(GfxState * /*state*/, double /*wx*/, double /*wy*/,
double /*llx*/, double /*lly*/, double /*urx*/, double /*ury*/) {}
+ //----- form XObjects
+ virtual void drawForm(Ref /*id*/) {}
+
//----- PostScript XObjects
virtual void psXObject(Stream * /*psStream*/, Stream * /*level1Stream*/) {}
@@ -212,7 +238,25 @@
virtual GooHash *getProfileHash() {return profileHash; }
virtual GooHash *endProfile();
-
+ //----- transparency groups and soft masks
+ virtual void beginTransparencyGroup(GfxState * /*state*/, double * /*bbox*/,
+ GfxColorSpace * /*blendingColorSpace*/,
+ GBool /*isolated*/, GBool /*knockout*/,
+ GBool /*forSoftMask*/) {}
+ virtual void endTransparencyGroup(GfxState * /*state*/) {}
+ virtual void paintTransparencyGroup(GfxState * /*state*/, double * /*bbox*/) {}
+ virtual void setSoftMask(GfxState * /*state*/, double * /*bbox*/, GBool /*alpha*/,
+ Function * /*transferFunc*/, GfxColor * /*backdropColor*/) {}
+ virtual void clearSoftMask(GfxState * /*state*/) {}
+
+ //----- links
+ virtual void processLink(Link * /*link*/, Catalog * /*catalog*/) {}
+
+#if 1 //~tmp: turn off anti-aliasing temporarily
+ virtual GBool getVectorAntialias() { return gFalse; }
+ virtual void setVectorAntialias(GBool /*vaa*/) {}
+#endif
+
private:
double defCTM[6]; // default coordinate transform matrix
Index: PDFDoc.cc
===================================================================
RCS file: /cvs/poppler/poppler/poppler/PDFDoc.cc,v
retrieving revision 1.10
retrieving revision 1.11
diff -u -d -r1.10 -r1.11
--- PDFDoc.cc 18 Jan 2006 22:32:13 -0000 1.10
+++ PDFDoc.cc 25 Apr 2007 19:59:10 -0000 1.11
@@ -38,7 +38,6 @@
#include "Outline.h"
#endif
#include "PDFDoc.h"
-#include "UGooString.h"
//------------------------------------------------------------------------
@@ -63,7 +62,6 @@
str = NULL;
xref = NULL;
catalog = NULL;
- links = NULL;
#ifndef DISABLE_OUTLINE
outline = NULL;
#endif
@@ -121,7 +119,6 @@
str = NULL;
xref = NULL;
catalog = NULL;
- links = NULL;
#ifndef DISABLE_OUTLINE
outline = NULL;
#endif
@@ -166,12 +163,15 @@
ok = gFalse;
errCode = errNone;
guiData = guiDataA;
- fileName = NULL;
+ if (strA->getFileName()) {
+ fileName = strA->getFileName()->copy();
+ } else {
+ fileName = NULL;
+ }
file = NULL;
str = strA;
xref = NULL;
catalog = NULL;
- links = NULL;
#ifndef DISABLE_OUTLINE
outline = NULL;
#endif
@@ -239,9 +239,6 @@
if (fileName) {
delete fileName;
}
- if (links) {
- delete links;
- }
}
@@ -330,7 +327,8 @@
secHdlr->getFileKey(),
secHdlr->getFileKeyLength(),
secHdlr->getEncVersion(),
- secHdlr->getEncRevision());
+ secHdlr->getEncRevision(),
+ secHdlr->getEncAlgorithm());
ret = gTrue;
} else {
// authorization failed
@@ -349,36 +347,25 @@
return ret;
}
-void PDFDoc::displayPage(OutputDev *out, int page, double hDPI, double vDPI,
- int rotate, GBool useMediaBox, GBool crop, GBool doLinks,
+void PDFDoc::displayPage(OutputDev *out, int page,
+ double hDPI, double vDPI, int rotate,
+ GBool useMediaBox, GBool crop, GBool printing,
GBool (*abortCheckCbk)(void *data),
void *abortCheckCbkData,
GBool (*annotDisplayDecideCbk)(Annot *annot, void *user_data),
void *annotDisplayDecideCbkData) {
- Page *p;
-
if (globalParams->getPrintCommands()) {
printf("***** page %d *****\n", page);
}
- p = catalog->getPage(page);
- if (doLinks) {
- if (links) {
- delete links;
- }
- getLinks(p);
- p->display(out, hDPI, vDPI, rotate, useMediaBox, crop, links, catalog,
- abortCheckCbk, abortCheckCbkData,
- annotDisplayDecideCbk, annotDisplayDecideCbkData);
- } else {
- p->display(out, hDPI, vDPI, rotate, useMediaBox, crop, NULL, catalog,
- abortCheckCbk, abortCheckCbkData,
- annotDisplayDecideCbk, annotDisplayDecideCbkData);
- }
+ catalog->getPage(page)->display(out, hDPI, vDPI,
+ rotate, useMediaBox, crop, printing, catalog,
+ abortCheckCbk, abortCheckCbkData,
+ annotDisplayDecideCbk, annotDisplayDecideCbkData);
}
void PDFDoc::displayPages(OutputDev *out, int firstPage, int lastPage,
- double hDPI, double vDPI, int rotate, GBool useMediaBox,
- GBool crop, GBool doLinks,
+ double hDPI, double vDPI, int rotate,
+ GBool useMediaBox, GBool crop, GBool printing,
GBool (*abortCheckCbk)(void *data),
void *abortCheckCbkData,
GBool (*annotDisplayDecideCbk)(Annot *annot, void *user_data),
@@ -386,49 +373,34 @@
int page;
for (page = firstPage; page <= lastPage; ++page) {
- displayPage(out, page, hDPI, vDPI, rotate, useMediaBox, crop, doLinks,
+ displayPage(out, page, hDPI, vDPI, rotate, useMediaBox, crop, printing,
abortCheckCbk, abortCheckCbkData,
annotDisplayDecideCbk, annotDisplayDecideCbkData);
}
}
void PDFDoc::displayPageSlice(OutputDev *out, int page,
- double hDPI, double vDPI,
- int rotate, GBool useMediaBox, GBool crop, GBool doLinks,
+ double hDPI, double vDPI, int rotate,
+ GBool useMediaBox, GBool crop, GBool printing,
int sliceX, int sliceY, int sliceW, int sliceH,
GBool (*abortCheckCbk)(void *data),
void *abortCheckCbkData,
GBool (*annotDisplayDecideCbk)(Annot *annot, void *user_data),
void *annotDisplayDecideCbkData) {
- Page *p;
-
- p = catalog->getPage(page);
- if (doLinks)
- {
- if (links) {
- delete links;
- }
- getLinks(p);
- p->displaySlice(out, hDPI, vDPI, rotate, useMediaBox, crop,
- sliceX, sliceY, sliceW, sliceH,
- links, catalog,
- abortCheckCbk, abortCheckCbkData,
- annotDisplayDecideCbk, annotDisplayDecideCbkData);
- } else {
- p->displaySlice(out, hDPI, vDPI, rotate, useMediaBox, crop,
- sliceX, sliceY, sliceW, sliceH,
- NULL, catalog,
- abortCheckCbk, abortCheckCbkData,
- annotDisplayDecideCbk, annotDisplayDecideCbkData);
- }
+ catalog->getPage(page)->displaySlice(out, hDPI, vDPI,
+ rotate, useMediaBox, crop,
+ sliceX, sliceY, sliceW, sliceH,
+ printing, catalog,
+ abortCheckCbk, abortCheckCbkData,
+ annotDisplayDecideCbk, annotDisplayDecideCbkData);
}
-Links *PDFDoc::takeLinks() {
- Links *ret;
-
- ret = links;
- links = NULL;
- return ret;
+Links *PDFDoc::getLinks(int page) {
+ return catalog->getPage(page)->getLinks(catalog);
+}
+
+void PDFDoc::processLinks(OutputDev *out, int page) {
+ catalog->getPage(page)->processLinks(out, catalog);
}
GBool PDFDoc::isLinearized() {
@@ -440,7 +412,8 @@
obj1.initNull();
parser = new Parser(xref,
new Lexer(xref,
- str->makeSubStream(str->getStart(), gFalse, 0, &obj1)));
+ str->makeSubStream(str->getStart(), gFalse, 0, &obj1)),
+ gTrue);
parser->getObj(&obj1);
parser->getObj(&obj2);
parser->getObj(&obj3);
@@ -477,10 +450,3 @@
fclose(f);
return gTrue;
}
-
-void PDFDoc::getLinks(Page *page) {
- Object obj;
-
- links = new Links(page->getAnnots(&obj), catalog->getBaseURI());
- obj.free();
-}
Index: PDFDoc.h
===================================================================
RCS file: /cvs/poppler/poppler/poppler/PDFDoc.h,v
retrieving revision 1.7
retrieving revision 1.8
diff -u -d -r1.7 -r1.8
--- PDFDoc.h 18 Jan 2006 22:32:13 -0000 1.7
+++ PDFDoc.h 25 Apr 2007 19:59:10 -0000 1.8
@@ -87,8 +87,9 @@
Object *getStructTreeRoot() { return catalog->getStructTreeRoot(); }
// Display a page.
- void displayPage(OutputDev *out, int page, double hDPI, double vDPI,
- int rotate, GBool useMediaBox, GBool crop, GBool doLinks,
+ void displayPage(OutputDev *out, int page,
+ double hDPI, double vDPI, int rotate,
+ GBool useMediaBox, GBool crop, GBool printing,
GBool (*abortCheckCbk)(void *data) = NULL,
void *abortCheckCbkData = NULL,
GBool (*annotDisplayDecideCbk)(Annot *annot, void *user_data) = NULL,
@@ -97,7 +98,7 @@
// Display a range of pages.
void displayPages(OutputDev *out, int firstPage, int lastPage,
double hDPI, double vDPI, int rotate,
- GBool useMediaBox, GBool crop, GBool doLinks,
+ GBool useMediaBox, GBool crop, GBool printing,
GBool (*abortCheckCbk)(void *data) = NULL,
void *abortCheckCbkData = NULL,
GBool (*annotDisplayDecideCbk)(Annot *annot, void *user_data) = NULL,
@@ -105,8 +106,8 @@
// Display part of a page.
void displayPageSlice(OutputDev *out, int page,
- double hDPI, double vDPI,
- int rotate, GBool useMediaBox, GBool crop, GBool doLinks,
+ double hDPI, double vDPI, int rotate,
+ GBool useMediaBox, GBool crop, GBool printing,
int sliceX, int sliceY, int sliceW, int sliceH,
GBool (*abortCheckCbk)(void *data) = NULL,
void *abortCheckCbkData = NULL,
@@ -119,13 +120,17 @@
// Returns the links for the current page, transferring ownership to
// the caller.
- Links *takeLinks();
+ Links *getLinks(int page);
// Find a named destination. Returns the link destination, or
// NULL if <name> is not a destination.
- LinkDest *findDest(UGooString *name)
+ LinkDest *findDest(GooString *name)
{ return catalog->findDest(name); }
+ // Process the links for a page.
+ void processLinks(OutputDev *out, int page);
+
+
#ifndef DISABLE_OUTLINE
// Return the outline object.
Outline *getOutline() { return outline; }
@@ -175,7 +180,6 @@
GBool checkFooter();
void checkHeader();
GBool checkEncryption(GooString *ownerPassword, GooString *userPassword);
- void getLinks(Page *page);
GooString *fileName;
FILE *file;
@@ -184,7 +188,6 @@
double pdfVersion;
XRef *xref;
Catalog *catalog;
- Links *links;
#ifndef DISABLE_OUTLINE
Outline *outline;
#endif
Index: PSOutputDev.cc
===================================================================
RCS file: /cvs/poppler/poppler/poppler/PSOutputDev.cc,v
retrieving revision 1.14
retrieving revision 1.15
diff -u -d -r1.14 -r1.15
--- PSOutputDev.cc 5 Apr 2007 12:13:51 -0000 1.14
+++ PSOutputDev.cc 25 Apr 2007 19:59:10 -0000 1.15
@@ -34,14 +34,30 @@
#include "Page.h"
#include "Stream.h"
#include "Annot.h"
+#include "XRef.h"
+#include "PreScanOutputDev.h"
+#if HAVE_SPLASH
+# include "splash/Splash.h"
+# include "splash/SplashBitmap.h"
+# include "SplashOutputDev.h"
+#endif
#include "PSOutputDev.h"
[...3957 lines suppressed...]
+ step = 2;
+ } else {
+ i = 0;
+ step = 1;
+ }
+ for (j = 0; i < s->getLength() && j < 200; i += step) {
+ c = s->getChar(i) & 0xff;
+ if (c == '\\') {
+ writePS("\\\\");
+ j += 2;
+ } else if (c < 0x20 || c > 0x7e || (j == 0 && c == '(')) {
+ writePSFmt("\\{0:03o}", c);
+ j += 4;
+ } else {
+ writePSChar(c);
+ ++j;
+ }
+ }
+ writePS("\n");
+}
Index: PSOutputDev.h
===================================================================
RCS file: /cvs/poppler/poppler/poppler/PSOutputDev.h,v
retrieving revision 1.7
retrieving revision 1.8
diff -u -d -r1.7 -r1.8
--- PSOutputDev.h 1 Jun 2006 06:42:25 -0000 1.7
+++ PSOutputDev.h 25 Apr 2007 19:59:10 -0000 1.8
@@ -24,6 +24,7 @@
class GfxColorSpace;
class GfxSeparationColorSpace;
class PDFRectangle;
+struct PSFont8Info;
struct PSFont16Enc;
class PSOutCustomColor;
class Function;
@@ -93,7 +94,11 @@
// radialShadedFill()? If this returns false, these shaded fills
// will be reduced to a series of other drawing operations.
virtual GBool useShadedFills()
- { return level == psLevel2 || level == psLevel3; }
+ { return level >= psLevel2; }
+
+ // Does this device use drawForm()? If this returns false,
+ // form-type XObjects will be interpreted (i.e., unrolled).
+ virtual GBool useDrawForm() { return preload; }
// Does this device use beginType3Char/endType3Char? Otherwise,
// text in Type 3 fonts will be drawn with drawChar/drawString.
@@ -120,6 +125,17 @@
//----- initialization and control
+ // Check to see if a page slice should be displayed. If this
+ // returns false, the page display is aborted. Typically, an
+ // OutputDev will use some alternate means to display the page
+ // before returning false.
+ virtual GBool checkPageSlice(Page *page, double hDPI, double vDPI,
+ int rotate, GBool useMediaBox, GBool crop,
+ int sliceX, int sliceY, int sliceW, int sliceH,
+ GBool printing, Catalog *catalog,
+ GBool (*abortCheckCbk)(void *data) = NULL,
+ void *abortCheckCbkData = NULL);
+
// Start a page.
virtual void startPage(int pageNum, GfxState *state);
@@ -145,6 +161,7 @@
virtual void updateStrokeColor(GfxState *state);
virtual void updateFillOverprint(GfxState *state);
virtual void updateStrokeOverprint(GfxState *state);
+ virtual void updateTransfer(GfxState *state);
//----- update text state
virtual void updateFont(GfxState *state);
@@ -166,14 +183,15 @@
double *mat, double *bbox,
int x0, int y0, int x1, int y1,
double xStep, double yStep);
- virtual void functionShadedFill(GfxState *state,
- GfxFunctionShading *shading);
- virtual void axialShadedFill(GfxState *state, GfxAxialShading *shading);
- virtual void radialShadedFill(GfxState *state, GfxRadialShading *shading);
+ virtual GBool functionShadedFill(GfxState *state,
+ GfxFunctionShading *shading);
+ virtual GBool axialShadedFill(GfxState *state, GfxAxialShading *shading);
+ virtual GBool radialShadedFill(GfxState *state, GfxRadialShading *shading);
//----- path clipping
virtual void clip(GfxState *state);
virtual void eoClip(GfxState *state);
+ virtual void clipToStrokePath(GfxState *state);
//----- text drawing
virtual void drawString(GfxState *state, GooString *s);
@@ -203,6 +221,9 @@
virtual void type3D1(GfxState *state, double wx, double wy,
double llx, double lly, double urx, double ury);
+ //----- form XObjects
+ virtual void drawForm(Ref ref);
+
//----- PostScript XObjects
virtual void psXObject(Stream *psStream, Stream *level1Stream);
@@ -236,15 +257,19 @@
void setupEmbeddedType1Font(Ref *id, GooString *psName);
void setupExternalType1Font(GooString *fileName, GooString *psName);
void setupEmbeddedType1CFont(GfxFont *font, Ref *id, GooString *psName);
+ void setupEmbeddedOpenTypeT1CFont(GfxFont *font, Ref *id, GooString *psName);
void setupEmbeddedTrueTypeFont(GfxFont *font, Ref *id, GooString *psName);
GooString *setupExternalTrueTypeFont(GfxFont *font);
void setupEmbeddedCIDType0Font(GfxFont *font, Ref *id, GooString *psName);
void setupEmbeddedCIDTrueTypeFont(GfxFont *font, Ref *id, GooString *psName,
GBool needVerticalMetrics);
+ void setupEmbeddedOpenTypeCFFFont(GfxFont *font, Ref *id, GooString *psName);
GooString *setupExternalCIDTrueTypeFont(GfxFont *font, GooString *fileName, int faceIndex = 0);
void setupType3Font(GfxFont *font, GooString *psName, Dict *parentResDict);
void setupImages(Dict *resDict);
void setupImage(Ref id, Stream *str);
+ void setupForms(Dict *resDict);
+ void setupForm(Ref id, Object *strObj);
void addProcessColor(double c, double m, double y, double k);
void addCustomColor(GfxSeparationColorSpace *sepCS);
void doPath(GfxPath *path);
@@ -259,8 +284,14 @@
Stream *str, int width, int height, int len,
int *maskColors, Stream *maskStr,
int maskWidth, int maskHeight, GBool maskInvert);
+ void doImageL3(Object *ref, GfxImageColorMap *colorMap,
+ GBool invert, GBool inlineImg,
+ Stream *str, int width, int height, int len,
+ int *maskColors, Stream *maskStr,
+ int maskWidth, int maskHeight, GBool maskInvert);
void dumpColorSpaceL2(GfxColorSpace *colorSpace,
- GBool genXform, GBool updateColors);
+ GBool genXform, GBool updateColors,
+ GBool map01);
#if OPI_SUPPORT
void opiBegin20(GfxState *state, Dict *dict);
void opiBegin13(GfxState *state, Dict *dict);
@@ -271,10 +302,11 @@
void cvtFunction(Function *func);
void writePSChar(char c);
void writePS(char *s);
- void writePSFmt(const char *fmt, ...) GCC_PRINTF_FORMAT(2, 3);
+ void writePSFmt(const char *fmt, ...);
void writePSString(GooString *s);
void writePSName(char *s);
GooString *filterPSName(GooString *name);
+ void writePSTextLine(GooString *s);
PSLevel level; // PostScript level (1, 2, separation)
PSOutMode mode; // PostScript mode (PS, EPS, form)
@@ -282,6 +314,8 @@
int paperHeight; // height of paper, in pts
int imgLLX, imgLLY, // imageable area, in pts
imgURX, imgURY;
+ GBool preload; // load all images into memory, and
+ // predefine forms
PSOutputFunc outputFunc;
void *outputStream;
@@ -307,9 +341,18 @@
int fontFileNameSize; // size of fontFileNames array
int nextTrueTypeNum; // next unique number to append to a TrueType
// font name
+ PSFont8Info *font8Info; // info for 8-bit fonts
+ int font8InfoLen; // number of entries in font8Info array
+ int font8InfoSize; // size of font8Info array
PSFont16Enc *font16Enc; // encodings for substitute 16-bit fonts
int font16EncLen; // number of entries in font16Enc array
int font16EncSize; // size of font16Enc array
+ Ref *imgIDs; // list of image IDs for in-memory images
+ int imgIDLen; // number of entries in imgIDs array
+ int imgIDSize; // size of imgIDs array
+ Ref *formIDs; // list of IDs for predefined forms
+ int formIDLen; // number of entries in formIDs array
+ int formIDSize; // size of formIDs array
GooList *xobjStack; // stack of XObject dicts currently being
// processed
int numSaves; // current number of gsaves
@@ -341,6 +384,7 @@
double t3WX, t3WY, // Type 3 character parameters
t3LLX, t3LLY, t3URX, t3URY;
GBool t3Cacheable; // cleared if char is not cacheable
+ GBool t3NeedsRestore; // set if a 'q' operator was issued
#if OPI_SUPPORT
int opi13Nest; // nesting level of OPI 1.3 objects
Index: PSTokenizer.cc
===================================================================
RCS file: /cvs/poppler/poppler/poppler/PSTokenizer.cc,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -d -r1.2 -r1.3
--- PSTokenizer.cc 23 Dec 2006 13:12:14 -0000 1.2
+++ PSTokenizer.cc 25 Apr 2007 19:59:10 -0000 1.3
@@ -98,7 +98,7 @@
} else if (c == '<') {
while ((c = lookChar()) != EOF) {
consumeChar();
- if (i < size) {
+ if (i < size && specialChars[c] != 1) {
buf[i++] = c;
}
if (c == '>') {
Index: Page.cc
===================================================================
RCS file: /cvs/poppler/poppler/poppler/Page.cc,v
retrieving revision 1.17
retrieving revision 1.18
diff -u -d -r1.17 -r1.18
--- Page.cc 7 Mar 2007 19:15:32 -0000 1.17
+++ Page.cc 25 Apr 2007 19:59:10 -0000 1.18
@@ -2,7 +2,7 @@
//
// Page.cc
//
-// Copyright 1996-2003 Glyph & Cog, LLC
+// Copyright 1996-2007 Glyph & Cog, LLC
//
//========================================================================
@@ -30,10 +30,37 @@
#endif
#include "Error.h"
#include "Page.h"
-#include "UGooString.h"
+#include "Catalog.h"
#include "Form.h"
//------------------------------------------------------------------------
+// PDFRectangle
+//------------------------------------------------------------------------
+
+void PDFRectangle::clipTo(PDFRectangle *rect) {
+ if (x1 < rect->x1) {
+ x1 = rect->x1;
+ } else if (x1 > rect->x2) {
+ x1 = rect->x2;
+ }
+ if (x2 < rect->x1) {
+ x2 = rect->x1;
+ } else if (x2 > rect->x2) {
+ x2 = rect->x2;
+ }
+ if (y1 < rect->y1) {
+ y1 = rect->y1;
+ } else if (y1 > rect->y2) {
+ y1 = rect->y2;
+ }
+ if (y2 < rect->y1) {
+ y2 = rect->y1;
+ } else if (y2 > rect->y2) {
+ y2 = rect->y2;
+ }
+}
+
+//------------------------------------------------------------------------
// PageAttrs
//------------------------------------------------------------------------
@@ -96,6 +123,12 @@
artBox = cropBox;
readBox(dict, "ArtBox", &artBox);
+ // clip all other boxes to the media box
+ cropBox.clipTo(&mediaBox);
+ bleedBox.clipTo(&mediaBox);
+ trimBox.clipTo(&mediaBox);
+ artBox.clipTo(&mediaBox);
+
// rotate
dict->lookup("Rotate", &obj1);
if (obj1.isInt()) {
@@ -280,14 +313,23 @@
contents.free();
}
+Links *Page::getLinks(Catalog *catalog) {
+ Links *links;
+ Object obj;
+
+ links = new Links(getAnnots(&obj), catalog->getBaseURI());
+ obj.free();
+ return links;
+}
+
void Page::display(OutputDev *out, double hDPI, double vDPI,
int rotate, GBool useMediaBox, GBool crop,
- Links *links, Catalog *catalog,
+ GBool printing, Catalog *catalog,
GBool (*abortCheckCbk)(void *data),
void *abortCheckCbkData,
GBool (*annotDisplayDecideCbk)(Annot *annot, void *user_data),
void *annotDisplayDecideCbkData) {
- displaySlice(out, hDPI, vDPI, rotate, useMediaBox, crop, -1, -1, -1, -1, links, catalog,
+ displaySlice(out, hDPI, vDPI, rotate, useMediaBox, crop, -1, -1, -1, -1, printing, catalog,
abortCheckCbk, abortCheckCbkData,
annotDisplayDecideCbk, annotDisplayDecideCbkData);
}
@@ -295,15 +337,14 @@
Gfx *Page::createGfx(OutputDev *out, double hDPI, double vDPI,
int rotate, GBool useMediaBox, GBool crop,
int sliceX, int sliceY, int sliceW, int sliceH,
- Links *links, Catalog *catalog,
+ GBool printing, Catalog *catalog,
GBool (*abortCheckCbk)(void *data),
void *abortCheckCbkData,
GBool (*annotDisplayDecideCbk)(Annot *annot, void *user_data),
void *annotDisplayDecideCbkData) {
- PDFRectangle *mediaBox, *cropBox, *baseBox;
+ PDFRectangle *mediaBox, *cropBox;
PDFRectangle box;
Gfx *gfx;
- double kx, ky;
rotate += getRotate();
if (rotate >= 360) {
@@ -312,59 +353,9 @@
rotate += 360;
}
- mediaBox = getMediaBox();
+ makeBox(hDPI, vDPI, rotate, useMediaBox, out->upsideDown(),
+ sliceX, sliceY, sliceW, sliceH, &box, &crop);
cropBox = getCropBox();
- if (sliceW >= 0 && sliceH >= 0) {
- baseBox = useMediaBox ? mediaBox : cropBox;
- kx = 72.0 / hDPI;
- ky = 72.0 / vDPI;
- if (rotate == 90) {
- if (out->upsideDown()) {
- box.x1 = baseBox->x1 + ky * sliceY;
- box.x2 = baseBox->x1 + ky * (sliceY + sliceH);
- } else {
- box.x1 = baseBox->x2 - ky * (sliceY + sliceH);
- box.x2 = baseBox->x2 - ky * sliceY;
- }
- box.y1 = baseBox->y1 + kx * sliceX;
- box.y2 = baseBox->y1 + kx * (sliceX + sliceW);
- } else if (rotate == 180) {
- box.x1 = baseBox->x2 - kx * (sliceX + sliceW);
- box.x2 = baseBox->x2 - kx * sliceX;
- if (out->upsideDown()) {
- box.y1 = baseBox->y1 + ky * sliceY;
- box.y2 = baseBox->y1 + ky * (sliceY + sliceH);
- } else {
- box.y1 = baseBox->y2 - ky * (sliceY + sliceH);
- box.y2 = baseBox->y2 - ky * sliceY;
- }
- } else if (rotate == 270) {
- if (out->upsideDown()) {
- box.x1 = baseBox->x2 - ky * (sliceY + sliceH);
- box.x2 = baseBox->x2 - ky * sliceY;
- } else {
- box.x1 = baseBox->x1 + ky * sliceY;
- box.x2 = baseBox->x1 + ky * (sliceY + sliceH);
- }
- box.y1 = baseBox->y2 - kx * (sliceX + sliceW);
- box.y2 = baseBox->y2 - kx * sliceX;
- } else {
- box.x1 = baseBox->x1 + kx * sliceX;
- box.x2 = baseBox->x1 + kx * (sliceX + sliceW);
- if (out->upsideDown()) {
- box.y1 = baseBox->y2 - ky * (sliceY + sliceH);
- box.y2 = baseBox->y2 - ky * sliceY;
- } else {
- box.y1 = baseBox->y1 + ky * sliceY;
- box.y2 = baseBox->y1 + ky * (sliceY + sliceH);
- }
- }
- } else if (useMediaBox) {
- box = *mediaBox;
- } else {
- box = *cropBox;
- crop = gFalse;
- }
if (globalParams->getPrintCommands()) {
printf("***** MediaBox = ll:%g,%g ur:%g,%g\n",
@@ -384,20 +375,27 @@
void Page::displaySlice(OutputDev *out, double hDPI, double vDPI,
int rotate, GBool useMediaBox, GBool crop,
int sliceX, int sliceY, int sliceW, int sliceH,
- Links *links, Catalog *catalog,
+ GBool printing, Catalog *catalog,
GBool (*abortCheckCbk)(void *data),
void *abortCheckCbkData,
GBool (*annotDisplayDecideCbk)(Annot *annot, void *user_data),
void *annotDisplayDecideCbkData) {
Gfx *gfx;
Object obj;
- Link *link;
Annots *annotList;
+ Dict *acroForm;
int i;
+
+ if (!out->checkPageSlice(this, hDPI, vDPI, rotate, useMediaBox, crop,
+ sliceX, sliceY, sliceW, sliceH,
+ printing, catalog,
+ abortCheckCbk, abortCheckCbkData)) {
+ return;
+ }
gfx = createGfx(out, hDPI, vDPI, rotate, useMediaBox, crop,
sliceX, sliceY, sliceW, sliceH,
- links, catalog,
+ printing, catalog,
abortCheckCbk, abortCheckCbkData,
annotDisplayDecideCbk, annotDisplayDecideCbkData);
@@ -409,20 +407,20 @@
}
obj.free();
- // draw links
- if (links) {
- gfx->saveState();
- for (i = 0; i < links->getNumLinks(); ++i) {
- link = links->getLink(i);
- out->drawLink(link, catalog);
- }
- gfx->restoreState();
- out->dump();
- }
- // draw non-link annotations
- annotList = new Annots(xref, catalog, annots.fetch(xref, &obj));
+ // draw annotations
+ annotList = new Annots(xref, catalog, getAnnots(&obj));
obj.free();
+ acroForm = catalog->getAcroForm()->isDict() ?
+ catalog->getAcroForm()->getDict() : NULL;
+ if (acroForm) {
+ if (acroForm->lookup("NeedAppearances", &obj)) {
+ if (obj.isBool() && obj.getBool()) {
+ annotList->generateAppearances(acroForm);
+ }
+ }
+ obj.free();
+ }
if (annotList->getNumAnnots() > 0) {
if (globalParams->getPrintCommands()) {
printf("***** Annotations\n");
@@ -432,7 +430,7 @@
if ((annotDisplayDecideCbk &&
(*annotDisplayDecideCbk)(annot, annotDisplayDecideCbkData)) ||
!annotDisplayDecideCbk) {
- annot->draw(gfx);
+ annotList->getAnnot(i)->draw(gfx, printing);
}
}
out->dump();
@@ -560,8 +558,81 @@
return success;
}
+void Page::makeBox(double hDPI, double vDPI, int rotate,
+ GBool useMediaBox, GBool upsideDown,
+ double sliceX, double sliceY, double sliceW, double sliceH,
+ PDFRectangle *box, GBool *crop) {
+ PDFRectangle *mediaBox, *cropBox, *baseBox;
+ double kx, ky;
+
+ mediaBox = getMediaBox();
+ cropBox = getCropBox();
+ if (sliceW >= 0 && sliceH >= 0) {
+ baseBox = useMediaBox ? mediaBox : cropBox;
+ kx = 72.0 / hDPI;
+ ky = 72.0 / vDPI;
+ if (rotate == 90) {
+ if (upsideDown) {
+ box->x1 = baseBox->x1 + ky * sliceY;
+ box->x2 = baseBox->x1 + ky * (sliceY + sliceH);
+ } else {
+ box->x1 = baseBox->x2 - ky * (sliceY + sliceH);
+ box->x2 = baseBox->x2 - ky * sliceY;
+ }
+ box->y1 = baseBox->y1 + kx * sliceX;
+ box->y2 = baseBox->y1 + kx * (sliceX + sliceW);
+ } else if (rotate == 180) {
+ box->x1 = baseBox->x2 - kx * (sliceX + sliceW);
+ box->x2 = baseBox->x2 - kx * sliceX;
+ if (upsideDown) {
+ box->y1 = baseBox->y1 + ky * sliceY;
+ box->y2 = baseBox->y1 + ky * (sliceY + sliceH);
+ } else {
+ box->y1 = baseBox->y2 - ky * (sliceY + sliceH);
+ box->y2 = baseBox->y2 - ky * sliceY;
+ }
+ } else if (rotate == 270) {
+ if (upsideDown) {
+ box->x1 = baseBox->x2 - ky * (sliceY + sliceH);
+ box->x2 = baseBox->x2 - ky * sliceY;
+ } else {
+ box->x1 = baseBox->x1 + ky * sliceY;
+ box->x2 = baseBox->x1 + ky * (sliceY + sliceH);
+ }
+ box->y1 = baseBox->y2 - kx * (sliceX + sliceW);
+ box->y2 = baseBox->y2 - kx * sliceX;
+ } else {
+ box->x1 = baseBox->x1 + kx * sliceX;
+ box->x2 = baseBox->x1 + kx * (sliceX + sliceW);
+ if (upsideDown) {
+ box->y1 = baseBox->y2 - ky * (sliceY + sliceH);
+ box->y2 = baseBox->y2 - ky * sliceY;
+ } else {
+ box->y1 = baseBox->y1 + ky * sliceY;
+ box->y2 = baseBox->y1 + ky * (sliceY + sliceH);
+ }
+ }
+ } else if (useMediaBox) {
+ *box = *mediaBox;
+ } else {
+ *box = *cropBox;
+ *crop = gFalse;
+ }
+}
+
+void Page::processLinks(OutputDev *out, Catalog *catalog) {
+ Links *links;
+ int i;
+
+ links = getLinks(catalog);
+ for (i = 0; i < links->getNumLinks(); ++i) {
+ out->processLink(links->getLink(i), catalog);
+ }
+ delete links;
+}
+
void Page::getDefaultCTM(double *ctm, double hDPI, double vDPI,
- int rotate, GBool upsideDown) {
+ int rotate, GBool useMediaBox, GBool upsideDown) {
GfxState *state;
int i;
rotate += getRotate();
@@ -570,7 +641,9 @@
} else if (rotate < 0) {
rotate += 360;
}
- state = new GfxState(hDPI, vDPI, getMediaBox(), rotate, upsideDown);
+ state = new GfxState(hDPI, vDPI,
+ useMediaBox ? getMediaBox() : getCropBox(),
+ rotate, upsideDown);
for (i = 0; i < 6; ++i) {
ctm[i] = state->getCTM()[i];
}
Index: Page.h
===================================================================
RCS file: /cvs/poppler/poppler/poppler/Page.h,v
retrieving revision 1.8
retrieving revision 1.9
diff -u -d -r1.8 -r1.9
--- Page.h 24 Feb 2007 23:32:23 -0000 1.8
+++ Page.h 25 Apr 2007 19:59:10 -0000 1.9
@@ -36,6 +36,7 @@
PDFRectangle(double x1A, double y1A, double x2A, double y2A)
{ x1 = x1A; y1 = y1A; x2 = x2A; y2 = y2A; }
GBool isValid() { return x1 != 0 || y1 != 0 || x2 != 0 || y2 != 0; }
+ void clipTo(PDFRectangle *rect);
};
//------------------------------------------------------------------------
@@ -115,6 +116,7 @@
GBool isOk() { return ok; }
// Get page parameters.
+ int getNum() { return num; }
PDFRectangle *getMediaBox() { return attrs->getMediaBox(); }
PDFRectangle *getCropBox() { return attrs->getCropBox(); }
GBool isCropped() { return attrs->isCropped(); }
@@ -143,6 +145,9 @@
// Get annotations array.
Object *getAnnots(Object *obj) { return annots.fetch(xref, obj); }
+ // Return a list of links.
+ Links *getLinks(Catalog *catalog);
+
// Get contents.
Object *getContents(Object *obj) { return contents.fetch(xref, obj); }
@@ -167,7 +172,7 @@
Gfx *createGfx(OutputDev *out, double hDPI, double vDPI,
int rotate, GBool useMediaBox, GBool crop,
int sliceX, int sliceY, int sliceW, int sliceH,
- Links *links, Catalog *catalog,
+ GBool printing, Catalog *catalog,
GBool (*abortCheckCbk)(void *data),
void *abortCheckCbkData,
GBool (*annotDisplayDecideCbk)(Annot *annot, void *user_data),
@@ -176,7 +181,7 @@
// Display a page.
void display(OutputDev *out, double hDPI, double vDPI,
int rotate, GBool useMediaBox, GBool crop,
- Links *links, Catalog *catalog,
+ GBool printing, Catalog *catalog,
GBool (*abortCheckCbk)(void *data) = NULL,
void *abortCheckCbkData = NULL,
GBool (*annotDisplayDecideCbk)(Annot *annot, void *user_data) = NULL,
@@ -186,17 +191,24 @@
void displaySlice(OutputDev *out, double hDPI, double vDPI,
int rotate, GBool useMediaBox, GBool crop,
int sliceX, int sliceY, int sliceW, int sliceH,
- Links *links, Catalog *catalog,
+ GBool printing, Catalog *catalog,
GBool (*abortCheckCbk)(void *data) = NULL,
void *abortCheckCbkData = NULL,
GBool (*annotDisplayDecideCbk)(Annot *annot, void *user_data) = NULL,
void *annotDisplayDecideCbkData = NULL);
void display(Gfx *gfx);
-
+
+ void makeBox(double hDPI, double vDPI, int rotate,
+ GBool useMediaBox, GBool upsideDown,
+ double sliceX, double sliceY, double sliceW, double sliceH,
+ PDFRectangle *box, GBool *crop);
+
+ void processLinks(OutputDev *out, Catalog *catalog);
+
// Get the page's default CTM.
void getDefaultCTM(double *ctm, double hDPI, double vDPI,
- int rotate, GBool upsideDown);
+ int rotate, GBool useMediaBox, GBool upsideDown);
private:
Index: PageLabelInfo.cc
===================================================================
RCS file: /cvs/poppler/poppler/poppler/PageLabelInfo.cc,v
retrieving revision 1.7
retrieving revision 1.8
diff -u -d -r1.7 -r1.8
--- PageLabelInfo.cc 28 Dec 2006 15:51:44 -0000 1.7
+++ PageLabelInfo.cc 25 Apr 2007 19:59:10 -0000 1.8
@@ -3,7 +3,6 @@
#include <stdlib.h>
#include <stdio.h>
#include <assert.h>
-#include "UGooString.h"
#include "PageLabelInfo.h"
Index: Parser.cc
===================================================================
RCS file: /cvs/poppler/poppler/poppler/Parser.cc,v
retrieving revision 1.7
retrieving revision 1.8
diff -u -d -r1.7 -r1.8
--- Parser.cc 28 Dec 2006 15:51:44 -0000 1.7
+++ Parser.cc 25 Apr 2007 19:59:10 -0000 1.8
@@ -16,16 +16,16 @@
#include "Object.h"
#include "Array.h"
#include "Dict.h"
+#include "Decrypt.h"
#include "Parser.h"
#include "XRef.h"
#include "Error.h"
-#include "Decrypt.h"
-#include "UGooString.h"
-Parser::Parser(XRef *xrefA, Lexer *lexerA) {
+Parser::Parser(XRef *xrefA, Lexer *lexerA, GBool allowStreamsA) {
xref = xrefA;
lexer = lexerA;
inlineImg = 0;
+ allowStreams = allowStreamsA;
lexer->getObj(&buf1);
lexer->getObj(&buf2);
}
@@ -36,17 +36,16 @@
delete lexer;
}
-Object *Parser::getObj(Object *obj,
- Guchar *fileKey, int keyLength,
+Object *Parser::getObj(Object *obj, Guchar *fileKey,
+ CryptAlgorithm encAlgorithm, int keyLength,
int objNum, int objGen) {
- UGooString key;
+ char *key;
Stream *str;
Object obj2;
int num;
- Decrypt *decrypt;
- GooString *s;
- char *p;
- int i;
+ DecryptStream *decrypt;
+ GooString *s, *s2;
+ int c;
// refill buffer after inline image data
if (inlineImg == 2) {
@@ -62,7 +61,8 @@
shift();
obj->initArray(xref);
while (!buf1.isCmd("]") && !buf1.isEOF())
- obj->arrayAdd(getObj(&obj2, fileKey, keyLength, objNum, objGen));
+ obj->arrayAdd(getObj(&obj2, fileKey, encAlgorithm, keyLength,
+ objNum, objGen));
if (buf1.isEOF())
error(getPos(), "End of file inside array");
shift();
@@ -77,23 +77,23 @@
shift();
} else {
// buf1 might go away in shift(), so construct the key
- key.Set(buf1.getName());
+ key = copyString(buf1.getName());
shift();
if (buf1.isEOF() || buf1.isError()) {
+ gfree(key);
break;
}
- obj->dictAdd(key, getObj(&obj2, fileKey, keyLength, objNum, objGen));
+ obj->dictAdd(key, getObj(&obj2, fileKey, encAlgorithm, keyLength, objNum, objGen));
}
}
if (buf1.isEOF())
error(getPos(), "End of file inside dictionary");
- if (buf2.isCmd("stream")) {
- if ((str = makeStream(obj))) {
+ // stream objects are not allowed inside content streams or
+ // object streams
+ if (allowStreams && buf2.isCmd("stream")) {
+ if ((str = makeStream(obj, fileKey, encAlgorithm, keyLength,
+ objNum, objGen))) {
obj->initStream(str);
- if (fileKey) {
- str->getBaseStream()->doDecryption(fileKey, keyLength,
- objNum, objGen);
- }
} else {
obj->free();
obj->initError();
@@ -116,15 +116,19 @@
// string
} else if (buf1.isString() && fileKey) {
- buf1.copy(obj);
- s = obj->getString();
- decrypt = new Decrypt(fileKey, keyLength, objNum, objGen);
- for (i = 0, p = obj->getString()->getCString();
- i < s->getLength();
- ++i, ++p) {
- *p = decrypt->decryptByte(*p);
+ s = buf1.getString();
+ s2 = new GooString();
+ obj2.initNull();
+ decrypt = new DecryptStream(new MemStream(s->getCString(), 0,
+ s->getLength(), &obj2),
+ fileKey, encAlgorithm, keyLength,
+ objNum, objGen);
+ decrypt->reset();
+ while ((c = decrypt->getChar()) != EOF) {
+ s2->append((char)c);
}
delete decrypt;
+ obj->initString(s2);
shift();
// simple object
@@ -140,7 +144,9 @@
return obj;
}
-Stream *Parser::makeStream(Object *dict) {
+Stream *Parser::makeStream(Object *dict, Guchar *fileKey,
+ CryptAlgorithm encAlgorithm, int keyLength,
+ int objNum, int objGen) {
Object obj;
BaseStream *baseStr;
Stream *str;
@@ -196,6 +202,12 @@
// make base stream
str = baseStr->makeSubStream(pos, gTrue, length, dict);
+ // handle decryption
+ if (fileKey) {
+ str = new DecryptStream(str, fileKey, encAlgorithm, keyLength,
+ objNum, objGen);
+ }
+
// get filters
str = str->addFilters(dict);
Index: Parser.h
===================================================================
RCS file: /cvs/poppler/poppler/poppler/Parser.h,v
retrieving revision 1.3
retrieving revision 1.4
diff -u -d -r1.3 -r1.4
--- Parser.h 17 Jan 2006 21:35:31 -0000 1.3
+++ Parser.h 25 Apr 2007 19:59:10 -0000 1.4
@@ -23,14 +23,14 @@
public:
// Constructor.
- Parser(XRef *xrefA, Lexer *lexerA);
+ Parser(XRef *xrefA, Lexer *lexerA, GBool allowStreamsA);
// Destructor.
~Parser();
// Get the next object from the input stream.
- Object *getObj(Object *obj,
- Guchar *fileKey = NULL, int keyLength = 0,
+ Object *getObj(Object *obj, Guchar *fileKey = NULL,
+ CryptAlgorithm encAlgorithm = cryptRC4, int keyLength = 0,
int objNum = 0, int objGen = 0);
// Get stream.
@@ -43,10 +43,13 @@
XRef *xref; // the xref table for this PDF file
Lexer *lexer; // input stream
+ GBool allowStreams; // parse stream objects?
Object buf1, buf2; // next two tokens
int inlineImg; // set when inline image data is encountered
- Stream *makeStream(Object *dict);
+ Stream *makeStream(Object *dict, Guchar *fileKey,
+ CryptAlgorithm encAlgorithm, int keyLength,
+ int objNum, int objGen);
void shift(int objNum = -1);
};
Index: SecurityHandler.cc
===================================================================
RCS file: /cvs/poppler/poppler/poppler/SecurityHandler.cc,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -d -r1.2 -r1.3
--- SecurityHandler.cc 18 Jan 2006 22:32:13 -0000 1.2
+++ SecurityHandler.cc 25 Apr 2007 19:59:10 -0000 1.3
@@ -26,7 +26,6 @@
# include "XpdfPluginAPI.h"
#endif
#include "SecurityHandler.h"
-#include "UGooString.h"
//------------------------------------------------------------------------
// SecurityHandler
@@ -35,7 +34,9 @@
SecurityHandler *SecurityHandler::make(PDFDoc *docA, Object *encryptDictA) {
Object filterObj;
SecurityHandler *secHdlr;
+#ifdef ENABLE_PLUGINS
XpdfSecurityHandler *xsh;
+#endif
encryptDictA->dictLookup("Filter", &filterObj);
if (filterObj.isName("Standard")) {
@@ -152,6 +153,7 @@
permObj.isInt()) {
encVersion = versionObj.getInt();
encRevision = revisionObj.getInt();
+ encAlgorithm = cryptRC4;
// revision 2 forces a 40-bit key - some buggy PDF generators
// set the Length value incorrectly
if (encRevision == 2 || !lengthObj.isInt()) {
@@ -171,7 +173,8 @@
!strcmp(streamFilterObj.getName(), stringFilterObj.getName())) {
if (cryptFiltersObj.dictLookup(streamFilterObj.getName(),
&cryptFilterObj)->isDict()) {
- if (cryptFilterObj.dictLookup("CFM", &cfmObj)->isName("V2")) {
+ cryptFilterObj.dictLookup("CFM", &cfmObj);
+ if (cfmObj.isName("V2")) {
encVersion = 2;
encRevision = 3;
if (cryptFilterObj.dictLookup("Length", &cfLengthObj)->isInt()) {
@@ -179,6 +182,15 @@
fileKeyLength = cfLengthObj.getInt();
}
cfLengthObj.free();
+ } else if (cfmObj.isName("AESV2")) {
+ encVersion = 2;
+ encRevision = 3;
+ encAlgorithm = cryptAES;
+ if (cryptFilterObj.dictLookup("Length", &cfLengthObj)->isInt()) {
+ //~ according to the spec, this should be cfLengthObj / 8
+ fileKeyLength = cfLengthObj.getInt();
+ }
+ cfLengthObj.free();
}
cfmObj.free();
}
@@ -311,6 +323,7 @@
{
encryptDictA->copy(&encryptDict);
xsh = xshA;
+ encAlgorithm = cryptRC4; //~ this should be obtained via getKey
ok = gFalse;
if (!(*xsh->newDoc)(xsh->handlerData, (XpdfDoc)docA,
Index: SecurityHandler.h
===================================================================
RCS file: /cvs/poppler/poppler/poppler/SecurityHandler.h,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -d -r1.1 -r1.2
--- SecurityHandler.h 16 Sep 2005 18:29:18 -0000 1.1
+++ SecurityHandler.h 25 Apr 2007 19:59:10 -0000 1.2
@@ -75,6 +75,7 @@
virtual int getFileKeyLength() = 0;
virtual int getEncVersion() = 0;
virtual int getEncRevision() = 0;
+ virtual CryptAlgorithm getEncAlgorithm() = 0;
protected:
@@ -102,6 +103,7 @@
virtual int getFileKeyLength() { return fileKeyLength; }
virtual int getEncVersion() { return encVersion; }
virtual int getEncRevision() { return encRevision; }
+ virtual CryptAlgorithm getEncAlgorithm() { return encAlgorithm; }
private:
@@ -112,6 +114,7 @@
int encVersion;
int encRevision;
GBool encryptMetadata;
+ CryptAlgorithm encAlgorithm;
GooString *ownerKey, *userKey;
GooString *fileID;
@@ -140,6 +143,7 @@
virtual Guchar *getFileKey() { return fileKey; }
virtual int getFileKeyLength() { return fileKeyLength; }
virtual int getEncVersion() { return encVersion; }
+ virtual CryptAlgorithm getEncAlgorithm() { return encAlgorithm; }
private:
@@ -150,6 +154,7 @@
Guchar fileKey[16];
int fileKeyLength;
int encVersion;
+ CryptAlgorithm encAlgorithm;
GBool ok;
};
#endif // ENABLE_PLUGINS
Index: SplashOutputDev.cc
===================================================================
RCS file: /cvs/poppler/poppler/poppler/SplashOutputDev.cc,v
retrieving revision 1.12
retrieving revision 1.13
diff -u -d -r1.12 -r1.13
--- SplashOutputDev.cc 19 Dec 2006 20:27:55 -0000 1.12
+++ SplashOutputDev.cc 25 Apr 2007 19:59:10 -0000 1.13
@@ -37,6 +37,19 @@
#include "splash/Splash.h"
#include "SplashOutputDev.h"
+#ifdef VMS
+#if (__VMS_VER < 70000000)
+extern "C" int unlink(char *filename);
+#endif
+#endif
+
+//------------------------------------------------------------------------
+
[...2325 lines suppressed...]
ret = bitmap;
- bitmap = new SplashBitmap(1, 1, bitmapRowPad, colorMode, bitmapTopDown);
+ bitmap = new SplashBitmap(1, 1, bitmapRowPad, colorMode,
+ colorMode != splashModeMono1, bitmapTopDown);
return ret;
}
@@ -2508,3 +2699,12 @@
#endif
}
+#if 1 //~tmp: turn off anti-aliasing temporarily
+GBool SplashOutputDev::getVectorAntialias() {
+ return splash->getVectorAntialias();
+}
+
+void SplashOutputDev::setVectorAntialias(GBool vaa) {
+ splash->setVectorAntialias(vaa);
+}
+#endif
Index: SplashOutputDev.h
===================================================================
RCS file: /cvs/poppler/poppler/poppler/SplashOutputDev.h,v
retrieving revision 1.4
retrieving revision 1.5
diff -u -d -r1.4 -r1.5
--- SplashOutputDev.h 30 Oct 2005 20:29:05 -0000 1.4
+++ SplashOutputDev.h 25 Apr 2007 19:59:10 -0000 1.5
@@ -29,6 +29,7 @@
class T3FontCache;
struct T3FontCacheTag;
struct T3GlyphStack;
+struct SplashTransparencyGroup;
//------------------------------------------------------------------------
@@ -72,9 +73,6 @@
// End a page.
virtual void endPage();
- //----- link borders
- virtual void drawLink(Link *link, Catalog *catalog);
-
//----- save/restore graphics state
virtual void saveState(GfxState *state);
virtual void restoreState(GfxState *state);
@@ -89,6 +87,7 @@
virtual void updateLineCap(GfxState *state);
virtual void updateMiterLimit(GfxState *state);
virtual void updateLineWidth(GfxState *state);
+ virtual void updateStrokeAdjust(GfxState *state);
virtual void updateFillColor(GfxState *state);
virtual void updateStrokeColor(GfxState *state);
virtual void updateBlendMode(GfxState *state);
@@ -106,6 +105,7 @@
//----- path clipping
virtual void clip(GfxState *state);
virtual void eoClip(GfxState *state);
+ virtual void clipToStrokePath(GfxState *state);
//----- text drawing
virtual void drawChar(GfxState *state, double x, double y,
@@ -142,6 +142,17 @@
virtual void type3D1(GfxState *state, double wx, double wy,
double llx, double lly, double urx, double ury);
+ //----- transparency groups and soft masks
+ virtual void beginTransparencyGroup(GfxState *state, double *bbox,
+ GfxColorSpace *blendingColorSpace,
+ GBool isolated, GBool knockout,
+ GBool forSoftMask);
+ virtual void endTransparencyGroup(GfxState *state);
+ virtual void paintTransparencyGroup(GfxState *state, double *bbox);
+ virtual void setSoftMask(GfxState *state, double *bbox, GBool alpha,
+ Function *transferFunc, GfxColor *backdropColor);
+ virtual void clearSoftMask(GfxState *state);
+
//----- special access
// Called to indicate that a new PDF document has been loaded.
@@ -175,28 +186,39 @@
SplashFont *getCurrentFont() { return font; }
+#if 1 //~tmp: turn off anti-aliasing temporarily
+ virtual GBool getVectorAntialias();
+ virtual void setVectorAntialias(GBool vaa);
+#endif
+
private:
+ void setupScreenParams(double hDPI, double vDPI);
#if SPLASH_CMYK
SplashPattern *getColor(GfxGray gray, GfxRGB *rgb, GfxCMYK *cmyk);
#else
SplashPattern *getColor(GfxGray gray, GfxRGB *rgb);
#endif
SplashPath *convertPath(GfxState *state, GfxPath *path);
+ void doUpdateFont(GfxState *state);
void drawType3Glyph(T3FontCache *t3Font,
- T3FontCacheTag *tag, Guchar *data,
- double x, double y);
+ T3FontCacheTag *tag, Guchar *data);
static GBool imageMaskSrc(void *data, SplashColorPtr line);
- static GBool imageSrc(void *data, SplashColorPtr line);
- static GBool alphaImageSrc(void *data, SplashColorPtr line);
- static GBool maskedImageSrc(void *data, SplashColorPtr line);
+ static GBool imageSrc(void *data, SplashColorPtr colorLine,
+ Guchar *alphaLine);
+ static GBool alphaImageSrc(void *data, SplashColorPtr line,
+ Guchar *alphaLine);
+ static GBool maskedImageSrc(void *data, SplashColorPtr line,
+ Guchar *alphaLine);
SplashColorMode colorMode;
int bitmapRowPad;
GBool bitmapTopDown;
GBool allowAntialias;
+ GBool vectorAntialias;
GBool reverseVideo; // reverse video mode
SplashColor paperColor; // paper color
+ SplashScreenParams screenParams;
XRef *xref; // xref table for current document
@@ -212,6 +234,9 @@
SplashFont *font; // current font
GBool needFontUpdate; // set when the font needs to be updated
SplashPath *textClipPath; // clipping path built with text object
+
+ SplashTransparencyGroup * // transparency group stack
+ transpGroupStack;
};
#endif
Index: Stream.cc
===================================================================
RCS file: /cvs/poppler/poppler/poppler/Stream.cc,v
retrieving revision 1.15
retrieving revision 1.16
diff -u -d -r1.15 -r1.16
--- Stream.cc 13 Jan 2007 23:19:21 -0000 1.15
+++ Stream.cc 25 Apr 2007 19:59:10 -0000 1.16
@@ -27,13 +27,11 @@
#include "Error.h"
#include "Object.h"
#include "Lexer.h"
-#include "Decrypt.h"
#include "GfxState.h"
#include "Stream.h"
#include "JBIG2Stream.h"
#include "JPXStream.h"
#include "Stream-CCITT.h"
-#include "UGooString.h"
#ifdef ENABLE_LIBJPEG
#include "DCTStream.h"
@@ -151,6 +149,7 @@
int encoding;
GBool endOfLine, byteAlign, endOfBlock, black;
int columns, rows;
+ int colorXform;
Object globals, obj;
if (!strcmp(name, "ASCIIHexDecode") || !strcmp(name, "AHx")) {
@@ -236,7 +235,14 @@
str = new CCITTFaxStream(str, encoding, endOfLine, byteAlign,
columns, rows, endOfBlock, black);
} else if (!strcmp(name, "DCTDecode") || !strcmp(name, "DCT")) {
- str = new DCTStream(str);
+ colorXform = -1;
+ if (params->isDict()) {
+ if (params->dictLookup("ColorTransform", &obj)->isInt()) {
+ colorXform = obj.getInt();
+ }
+ obj.free();
+ }
+ str = new DCTStream(str, colorXform);
} else if (!strcmp(name, "FlateDecode") || !strcmp(name, "Fl")) {
pred = 1;
columns = 1;
@@ -282,18 +288,10 @@
BaseStream::BaseStream(Object *dictA) {
dict = *dictA;
- decrypt = NULL;
}
BaseStream::~BaseStream() {
dict.free();
- if (decrypt)
- delete decrypt;
-}
-
-void BaseStream::doDecryption(Guchar *fileKey, int keyLength,
- int objNum, int objGen) {
- decrypt = new Decrypt(fileKey, keyLength, objNum, objGen);
}
//------------------------------------------------------------------------
@@ -411,8 +409,6 @@
StreamPredictor::StreamPredictor(Stream *strA, int predictorA,
int widthA, int nCompsA, int nBitsA) {
- int totalBits;
-
str = strA;
predictor = predictorA;
width = widthA;
@@ -428,15 +424,9 @@
nVals * nBits + 7 < 0) {
return;
}
- totalBits = nVals * nBits;
- if (totalBits == 0 ||
- (totalBits / nBits) / nComps != width ||
- totalBits + 7 < 0) {
- return;
- }
pixBytes = (nComps * nBits + 7) >> 3;
- rowBytes = ((totalBits + 7) >> 3) + pixBytes;
- if (rowBytes < 0) {
+ rowBytes = ((nVals * nBits + 7) >> 3) + pixBytes;
+ if (rowBytes <= 0) {
return;
}
predLine = (Guchar *)gmalloc(rowBytes);
@@ -560,17 +550,17 @@
j = k = pixBytes;
for (i = 0; i < width; ++i) {
for (kk = 0; kk < nComps; ++kk) {
- if (inBits < nBits) {
- inBuf = (inBuf << 8) | (predLine[j++] & 0xff);
- inBits += 8;
- }
- upLeftBuf[kk] = (upLeftBuf[kk] +
- (inBuf >> (inBits - nBits))) & bitMask;
- inBits -= nBits;
+ if (inBits < nBits) {
+ inBuf = (inBuf << 8) | (predLine[j++] & 0xff);
+ inBits += 8;
+ }
+ upLeftBuf[kk] = (Guchar)((upLeftBuf[kk] +
+ (inBuf >> (inBits - nBits))) & bitMask);
+ inBits -= nBits;
outBuf = (outBuf << nBits) | upLeftBuf[kk];
- outBits += nBits;
+ outBits += nBits;
if (outBits >= 8) {
- predLine[k++] = (Guchar)(outBuf >> (outBits - 8));
+ predLine[k++] = (Guchar)(outBuf >> (outBits - 8));
outBits -= 8;
}
}
@@ -628,8 +618,6 @@
saved = gTrue;
bufPtr = bufEnd = buf;
bufPos = start;
- if (decrypt)
- decrypt->reset();
}
void FileStream::close() {
@@ -647,7 +635,6 @@
GBool FileStream::fillBuf() {
int n;
- char *p;
bufPos += bufEnd - buf;
bufPtr = bufEnd = buf;
@@ -664,11 +651,6 @@
if (bufPtr >= bufEnd) {
return gFalse;
}
- if (decrypt) {
- for (p = buf; p < bufEnd; ++p) {
- *p = (char)decrypt->decryptByte((Guchar)*p);
- }
- }
return gTrue;
}
@@ -757,9 +739,6 @@
void MemStream::reset() {
bufPtr = buf + start;
- if (decrypt) {
- decrypt->reset();
- }
}
void MemStream::close() {
@@ -787,25 +766,6 @@
bufPtr = buf + start;
}
-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(length);
- for (p = buf + start, q = newBuf; p < bufEnd; ++p, ++q) {
- *q = (char)decrypt->decryptByte((Guchar)*p);
- }
- bufEnd = newBuf + length;
- bufPtr = newBuf + (bufPtr - (buf + start));
- start = 0;
- buf = newBuf;
- needFree = gTrue;
- }
-}
-
//------------------------------------------------------------------------
// EmbedStream
//------------------------------------------------------------------------
@@ -1291,14 +1251,17 @@
endOfLine = endOfLineA;
byteAlign = byteAlignA;
columns = columnsA;
- if (columns + 3 < 1 || columns + 4 < 1 || columns < 1) {
+ if (columns < 1) {
columns = 1;
}
+ if (columns + 4 <= 0) {
+ columns = INT_MAX - 4;
+ }
rows = rowsA;
endOfBlock = endOfBlockA;
black = blackA;
- refLine = (short *)gmallocn(columns + 4, sizeof(short));
- codingLine = (short *)gmallocn(columns + 3, sizeof(short));
+ refLine = (short *)gmallocn(columns + 3, sizeof(short));
+ codingLine = (short *)gmallocn(columns + 2, sizeof(short));
eof = gFalse;
row = 0;
@@ -1326,7 +1289,7 @@
nextLine2D = encoding < 0;
inputBits = 0;
codingLine[0] = 0;
- codingLine[1] = refLine[2] = columns;
+ codingLine[1] = columns;
a0 = 1;
buf = EOF;
@@ -1362,8 +1325,27 @@
// 2-D encoding
if (nextLine2D) {
- for (i = 0; codingLine[i] < columns; ++i)
+ // state:
+ // a0New = current position in coding line (0 <= a0New <= columns)
+ // codingLine[a0] = last change in coding line
+ // (black-to-white if a0 is even,
+ // white-to-black if a0 is odd)
+ // refLine[b1] = next change in reference line of opposite color
+ // to a0
+ // invariants:
+ // 0 <= codingLine[a0] <= a0New
+ // <= refLine[b1] <= refLine[b1+1] <= columns
+ // 0 <= a0 <= columns+1
+ // refLine[0] = 0
+ // refLine[n] = refLine[n+1] = columns
+ // -- for some 1 <= n <= columns+1
+ // end condition:
+ // 0 = codingLine[0] <= codingLine[1] < codingLine[2] < ...
+ // < codingLine[n-1] < codingLine[n] = columns
+ // -- where 1 <= n <= columns+1
+ for (i = 0; codingLine[i] < columns; ++i) {
refLine[i] = codingLine[i];
+ }
refLine[i] = refLine[i + 1] = columns;
b1 = 1;
a0New = codingLine[a0 = 0] = 0;
@@ -1395,68 +1377,93 @@
} while (code3 >= 64);
}
if (code1 > 0 || code2 > 0) {
- codingLine[a0 + 1] = a0New + code1;
+ if (a0New + code1 <= columns) {
+ codingLine[a0 + 1] = a0New + code1;
+ } else {
+ codingLine[a0 + 1] = columns;
+ }
++a0;
- a0New = codingLine[a0 + 1] = codingLine[a0] + code2;
+ if (codingLine[a0] + code2 <= columns) {
+ codingLine[a0 + 1] = codingLine[a0] + code2;
+ } else {
+ codingLine[a0 + 1] = columns;
+ }
++a0;
- while (refLine[b1] <= codingLine[a0] && refLine[b1] < columns)
+ a0New = codingLine[a0];
+ while (refLine[b1] <= a0New && refLine[b1] < columns) {
b1 += 2;
+ }
}
break;
case twoDimVert0:
- a0New = codingLine[++a0] = refLine[b1];
if (refLine[b1] < columns) {
+ a0New = codingLine[++a0] = refLine[b1];
++b1;
- while (refLine[b1] <= codingLine[a0] && refLine[b1] < columns)
+ while (refLine[b1] <= a0New && refLine[b1] < columns) {
b1 += 2;
+ }
+ } else {
+ a0New = codingLine[++a0] = columns;
}
break;
case twoDimVertR1:
- a0New = codingLine[++a0] = refLine[b1] + 1;
- if (refLine[b1] < columns) {
+ if (refLine[b1] + 1 < columns) {
+ a0New = codingLine[++a0] = refLine[b1] + 1;
++b1;
- while (refLine[b1] <= codingLine[a0] && refLine[b1] < columns)
+ while (refLine[b1] <= a0New && refLine[b1] < columns) {
b1 += 2;
+ }
+ } else {
+ a0New = codingLine[++a0] = columns;
}
break;
case twoDimVertL1:
- if (a0 == 0 || refLine[b1] - 1 > a0New) {
- a0New = codingLine[++a0] = refLine[b1] - 1;
- --b1;
- while (refLine[b1] <= codingLine[a0] && refLine[b1] < columns)
- b1 += 2;
+ if (refLine[b1] - 1 > a0New || (a0 == 0 && refLine[b1] == 1)) {
+ a0New = codingLine[++a0] = refLine[b1] - 1;
+ --b1;
+ while (refLine[b1] <= a0New && refLine[b1] < columns) {
+ b1 += 2;
+ }
}
break;
case twoDimVertR2:
- a0New = codingLine[++a0] = refLine[b1] + 2;
- if (refLine[b1] < columns) {
+ if (refLine[b1] + 2 < columns) {
+ a0New = codingLine[++a0] = refLine[b1] + 2;
++b1;
- while (refLine[b1] <= codingLine[a0] && refLine[b1] < columns)
+ while (refLine[b1] <= a0New && refLine[b1] < columns) {
b1 += 2;
+ }
+ } else {
+ a0New = codingLine[++a0] = columns;
}
break;
case twoDimVertL2:
- if (a0 == 0 || refLine[b1] - 2 > a0New) {
- a0New = codingLine[++a0] = refLine[b1] - 2;
- --b1;
- while (refLine[b1] <= codingLine[a0] && refLine[b1] < columns)
- b1 += 2;
+ if (refLine[b1] - 2 > a0New || (a0 == 0 && refLine[b1] == 2)) {
+ a0New = codingLine[++a0] = refLine[b1] - 2;
+ --b1;
+ while (refLine[b1] <= a0New && refLine[b1] < columns) {
+ b1 += 2;
+ }
}
break;
case twoDimVertR3:
- a0New = codingLine[++a0] = refLine[b1] + 3;
- if (refLine[b1] < columns) {
+ if (refLine[b1] + 3 < columns) {
+ a0New = codingLine[++a0] = refLine[b1] + 3;
++b1;
- while (refLine[b1] <= codingLine[a0] && refLine[b1] < columns)
+ while (refLine[b1] <= a0New && refLine[b1] < columns) {
b1 += 2;
+ }
+ } else {
+ a0New = codingLine[++a0] = columns;
}
break;
case twoDimVertL3:
- if (a0 == 0 || refLine[b1] - 3 > a0New) {
- a0New = codingLine[++a0] = refLine[b1] - 3;
- --b1;
- while (refLine[b1] <= codingLine[a0] && refLine[b1] < columns)
- b1 += 2;
+ if (refLine[b1] - 3 > a0New || (a0 == 0 && refLine[b1] == 3)) {
+ a0New = codingLine[++a0] = refLine[b1] - 3;
+ --b1;
+ while (refLine[b1] <= a0New && refLine[b1] < columns) {
+ b1 += 2;
+ }
}
break;
case EOF:
@@ -1480,16 +1487,18 @@
} while (code3 >= 64);
codingLine[a0+1] = codingLine[a0] + code1;
++a0;
- if (codingLine[a0] >= columns)
+ if (codingLine[a0] >= columns) {
break;
+ }
code2 = 0;
do {
code2 += code3 = getBlackCode();
} while (code3 >= 64);
codingLine[a0+1] = codingLine[a0] + code2;
++a0;
- if (codingLine[a0] >= columns)
+ if (codingLine[a0] >= columns) {
break;
+ }
}
}
@@ -1826,6 +1835,7 @@
return str->isBinary(gTrue);
}
+#warning LIBJPEG DCTSTream is broken, fix it
#ifndef ENABLE_LIBJPEG
//------------------------------------------------------------------------
@@ -1872,10 +1882,11 @@
63
};
-DCTStream::DCTStream(Stream *strA):
+DCTStream::DCTStream(Stream *strA, GBool colorXformA):
FilterStream(strA) {
int i, j;
+ colorXform = colorXformA;
progressive = interleaved = gFalse;
width = height = 0;
mcuWidth = mcuHeight = 0;
@@ -1901,20 +1912,8 @@
}
DCTStream::~DCTStream() {
- int i, j;
-
+ close();
delete str;
- if (progressive || !interleaved) {
- for (i = 0; i < numComps; ++i) {
- gfree(frameBuf[i]);
- }
- } else {
- for (i = 0; i < numComps; ++i) {
- for (j = 0; j < mcuHeight; ++j) {
- gfree(rowBuf[i][j]);
- }
- }
- }
}
void DCTStream::reset() {
@@ -1928,7 +1927,6 @@
numQuantTables = 0;
numDCHuffTables = 0;
numACHuffTables = 0;
- colorXform = 0;
gotJFIFMarker = gFalse;
gotAdobeMarker = gFalse;
restartInterval = 0;
@@ -1950,20 +1948,24 @@
}
if (compInfo[i].vSample > mcuHeight) {
mcuHeight = compInfo[i].vSample;
- }
+ }
}
mcuWidth *= 8;
mcuHeight *= 8;
// figure out color transform
- if (!gotAdobeMarker && numComps == 3) {
- if (gotJFIFMarker) {
- colorXform = 1;
- } else if (compInfo[0].id == 82 && compInfo[1].id == 71 &&
- compInfo[2].id == 66) { // ASCII "RGB"
- colorXform = 0;
+ if (colorXform == -1) {
+ if (numComps == 3) {
+ if (gotJFIFMarker) {
+ colorXform = 1;
+ } else if (compInfo[0].id == 82 && compInfo[1].id == 71 &&
+ compInfo[2].id == 66) { // ASCII "RGB"
+ colorXform = 0;
+ } else {
+ colorXform = 1;
+ }
} else {
- colorXform = 1;
+ colorXform = 0;
}
}
@@ -2013,6 +2015,20 @@
}
}
+void DCTStream::close() {
+ int i, j;
+
+ for (i = 0; i < 4; ++i) {
+ for (j = 0; j < 32; ++j) {
+ gfree(rowBuf[i][j]);
+ rowBuf[i][j] = NULL;
+ }
+ gfree(frameBuf[i]);
+ frameBuf[i] = NULL;
+ }
+ FilterStream::close();
+}
+
int DCTStream::getChar() {
int c;
@@ -2937,8 +2953,8 @@
width = read16();
numComps = str->getChar();
if (numComps <= 0 || numComps > 4) {
- numComps = 0;
error(getPos(), "Bad number of components in DCT stream");
+ numComps = 0;
return gFalse;
}
if (prec != 8) {
@@ -2990,8 +3006,8 @@
length = read16() - 2;
scanInfo.numComps = str->getChar();
if (scanInfo.numComps <= 0 || scanInfo.numComps > 4) {
- scanInfo.numComps = 0;
error(getPos(), "Bad number of components in DCT stream");
+ scanInfo.numComps = 0;
return gFalse;
}
--length;
@@ -3053,14 +3069,14 @@
if (prec) {
quantTables[index][dctZigZag[i]] = read16();
} else {
- quantTables[index][dctZigZag[i]] = str->getChar();
+ quantTables[index][dctZigZag[i]] = str->getChar();
}
}
if (prec) {
length -= 129;
} else {
- length -= 65;
- }
+ length -= 65;
+ }
}
return gTrue;
}
@@ -3078,12 +3094,12 @@
while (length > 0) {
index = str->getChar();
--length;
- if ((index & ~0x10) >= 4 || (index & ~0x10) < 0) {
+ if ((index & 0x0f) >= 4) {
error(getPos(), "Bad DCT Huffman table");
return gFalse;
}
if (index & 0x10) {
- index &= 0x03;
+ index &= 0x0f;
if (index >= numACHuffTables)
numACHuffTables = index+1;
tbl = &acHuffTables[index];
@@ -3887,14 +3903,15 @@
}
litCodeTab.codes = NULL;
distCodeTab.codes = NULL;
+ memset(buf, 0, flateWindow);
}
FlateStream::~FlateStream() {
if (litCodeTab.codes != fixedLitCodeTab.codes) {
- gfree(litCodeTab.codes);
+ gfree(litCodeTab.codes);
}
if (distCodeTab.codes != fixedDistCodeTab.codes) {
- gfree(distCodeTab.codes);
+ gfree(distCodeTab.codes);
}
if (pred) {
delete pred;
@@ -4073,11 +4090,11 @@
// free the code tables from the previous block
if (litCodeTab.codes != fixedLitCodeTab.codes) {
- gfree(litCodeTab.codes);
+ gfree(litCodeTab.codes);
}
litCodeTab.codes = NULL;
if (distCodeTab.codes != fixedDistCodeTab.codes) {
- gfree(distCodeTab.codes);
+ gfree(distCodeTab.codes);
}
distCodeTab.codes = NULL;
@@ -4446,35 +4463,63 @@
}
GBool ASCII85Encoder::fillBuf() {
- Gulong t;
+ Guint t;
char buf1[5];
- int c;
+ int c0, c1, c2, c3;
int n, i;
- if (eof)
+ if (eof) {
return gFalse;
- t = 0;
- for (n = 0; n < 4; ++n) {
- if ((c = str->getChar()) == EOF)
- break;
- t = (t << 8) + c;
}
+ c0 = str->getChar();
+ c1 = str->getChar();
+ c2 = str->getChar();
+ c3 = str->getChar();
bufPtr = bufEnd = buf;
- if (n > 0) {
- if (n == 4 && t == 0) {
+ if (c3 == EOF) {
+ if (c0 == EOF) {
+ n = 0;
+ t = 0;
+ } else {
+ if (c1 == EOF) {
+ n = 1;
+ t = c0 << 24;
+ } else if (c2 == EOF) {
+ n = 2;
+ t = (c0 << 24) | (c1 << 16);
+ } else {
+ n = 3;
+ t = (c0 << 24) | (c1 << 16) | (c2 << 8);
+ }
+ for (i = 4; i >= 0; --i) {
+ buf1[i] = (char)(t % 85 + 0x21);
+ t /= 85;
+ }
+ for (i = 0; i <= n; ++i) {
+ *bufEnd++ = buf1[i];
+ if (++lineLen == 65) {
+ *bufEnd++ = '\n';
+ lineLen = 0;
+ }
+ }
+ }
+ *bufEnd++ = '~';
+ *bufEnd++ = '>';
+ eof = gTrue;
+ } else {
+ t = (c0 << 24) | (c1 << 16) | (c2 << 8) | c3;
+ if (t == 0) {
*bufEnd++ = 'z';
if (++lineLen == 65) {
*bufEnd++ = '\n';
lineLen = 0;
}
} else {
- if (n < 4)
- t <<= 8 * (4 - n);
for (i = 4; i >= 0; --i) {
buf1[i] = (char)(t % 85 + 0x21);
t /= 85;
}
- for (i = 0; i <= n; ++i) {
+ for (i = 0; i <= 4; ++i) {
*bufEnd++ = buf1[i];
if (++lineLen == 65) {
*bufEnd++ = '\n';
@@ -4483,12 +4528,7 @@
}
}
}
- if (n < 4) {
- *bufEnd++ = '~';
- *bufEnd++ = '>';
- eof = gTrue;
- }
- return bufPtr < bufEnd;
+ return gTrue;
}
//------------------------------------------------------------------------
Index: Stream.h
===================================================================
RCS file: /cvs/poppler/poppler/poppler/Stream.h,v
retrieving revision 1.11
retrieving revision 1.12
diff -u -d -r1.11 -r1.12
--- Stream.h 13 Jan 2007 23:19:21 -0000 1.11
+++ Stream.h 25 Apr 2007 19:59:10 -0000 1.12
@@ -17,7 +17,6 @@
#include "goo/gtypes.h"
#include "Object.h"
-class Decrypt;
class BaseStream;
//------------------------------------------------------------------------
@@ -44,6 +43,15 @@
};
//------------------------------------------------------------------------
+
+// This is in Stream.h instead of Decrypt.h to avoid really annoying
+// include file dependency loops.
+enum CryptAlgorithm {
+ cryptRC4,
+ cryptAES
+};
+
+//------------------------------------------------------------------------
// Stream (base class)
//------------------------------------------------------------------------
@@ -99,6 +107,10 @@
// Get the BaseStream of this stream.
virtual BaseStream *getBaseStream() = 0;
+ // Get the stream after the last decoder (this may be a BaseStream
+ // or a DecryptStream).
+ virtual Stream *getUndecodedStream() = 0;
+
// Get the dictionary associated with this stream.
virtual Dict *getDict() = 0;
@@ -109,6 +121,9 @@
virtual void getImageParams(int * /*bitsPerComponent*/,
StreamColorSpaceMode * /*csMode*/) {}
+ // Return the next stream in the "stack".
+ virtual Stream *getNextStream() { return NULL; }
+
// Add filters to this stream according to the parameters in <dict>.
// Returns the new stream.
Stream *addFilters(Object *dict);
@@ -136,20 +151,14 @@
virtual void setPos(Guint pos, int dir = 0) = 0;
virtual GBool isBinary(GBool last = gTrue) { return last; }
virtual BaseStream *getBaseStream() { return this; }
+ virtual Stream *getUndecodedStream() { return this; }
virtual Dict *getDict() { return dict.getDict(); }
+ virtual GooString *getFileName() { return NULL; }
// Get/set position of first byte of stream within the file.
virtual Guint getStart() = 0;
virtual void moveStart(int delta) = 0;
- // Set decryption for this stream.
- virtual void doDecryption(Guchar *fileKey, int keyLength,
- int objNum, int objGen);
-
-protected:
-
- Decrypt *decrypt;
-
private:
Object dict;
@@ -170,7 +179,9 @@
virtual int getPos() { return str->getPos(); }
virtual void setPos(Guint pos, int dir = 0);
virtual BaseStream *getBaseStream() { return str->getBaseStream(); }
+ virtual Stream *getUndecodedStream() { return str->getUndecodedStream(); }
virtual Dict *getDict() { return str->getDict(); }
+ virtual Stream *getNextStream() { return str; }
protected:
@@ -316,8 +327,6 @@
virtual void setPos(Guint pos, int dir = 0);
virtual Guint getStart() { return start; }
virtual void moveStart(int delta);
- virtual void doDecryption(Guchar *fileKey, int keyLength,
- int objNum, int objGen);
private:
@@ -565,10 +574,11 @@
class DCTStream: public FilterStream {
public:
- DCTStream(Stream *strA);
+ DCTStream(Stream *strA, int colorXformA);
virtual ~DCTStream();
virtual StreamKind getKind() { return strDCT; }
virtual void reset();
+ virtual void close();
virtual int getChar();
virtual int lookChar();
virtual GooString *getPSFilter(int psLevel, char *indent);
@@ -585,7 +595,9 @@
DCTCompInfo compInfo[4]; // info for each component
DCTScanInfo scanInfo; // info for the current scan
int numComps; // number of components in image
- int colorXform; // need YCbCr-to-RGB transform?
+ int colorXform; // color transform: -1 = unspecified
+ // 0 = none
+ // 1 = YUV/YUVK -> RGB/CMYK
GBool gotJFIFMarker; // set if APP0 JFIF marker was present
GBool gotAdobeMarker; // set if APP14 Adobe marker was present
int restartInterval; // restart interval, in MCUs
@@ -632,6 +644,7 @@
int readMarker();
int read16();
};
+
#endif
#ifndef ENABLE_ZLIB
Index: TextOutputDev.cc
===================================================================
RCS file: /cvs/poppler/poppler/poppler/TextOutputDev.cc,v
retrieving revision 1.22
retrieving revision 1.23
diff -u -d -r1.22 -r1.23
--- TextOutputDev.cc 20 Sep 2006 20:22:19 -0000 1.22
+++ TextOutputDev.cc 25 Apr 2007 19:59:10 -0000 1.23
@@ -29,6 +29,7 @@
#include "GlobalParams.h"
#include "UnicodeMap.h"
#include "UnicodeTypeTable.h"
+#include "Link.h"
#include "TextOutputDev.h"
#include "Page.h"
@@ -106,12 +107,64 @@
// multiplied by this constant.
#define maxWideCharSpacingMul 1.3
+// Upper limit on spacing between characters in a word.
+#define maxWideCharSpacing 0.4
+
// Max difference in primary,secondary coordinates (as a fraction of
// the font size) allowed for duplicated text (fake boldface, drop
// shadows) which is to be discarded.
#define dupMaxPriDelta 0.1
#define dupMaxSecDelta 0.2
+// Max width of underlines (in points).
+#define maxUnderlineWidth 3
+
+// Min distance between baseline and underline (in points).
+//~ this should be font-size-dependent
+#define minUnderlineGap -2
+
+// Max distance between baseline and underline (in points).
+//~ this should be font-size-dependent
+#define maxUnderlineGap 4
+
+// Max horizontal distance between edge of word and start of underline
+// (in points).
+//~ this should be font-size-dependent
+#define underlineSlack 1
+
+// Max distance between edge of text and edge of link border
+#define hyperlinkSlack 2
+
+//------------------------------------------------------------------------
+// TextUnderline
+//------------------------------------------------------------------------
+
+class TextUnderline {
+public:
+
+ TextUnderline(double x0A, double y0A, double x1A, double y1A)
+ { x0 = x0A; y0 = y0A; x1 = x1A; y1 = y1A; horiz = y0 == y1; }
+ ~TextUnderline() {}
+
+ double x0, y0, x1, y1;
+ GBool horiz;
+};
+
+//------------------------------------------------------------------------
+// TextLink
+//------------------------------------------------------------------------
+
+class TextLink {
+public:
+
+ TextLink(int xMinA, int yMinA, int xMaxA, int yMaxA, Link *linkA)
+ { xMin = xMinA; yMin = yMinA; xMax = xMaxA; yMax = yMaxA; link = linkA; }
+ ~TextLink() {}
+
+ int xMin, yMin, xMax, yMax;
+ Link *link;
+};
+
//------------------------------------------------------------------------
// TextFontInfo
//------------------------------------------------------------------------
@@ -124,6 +177,7 @@
fontName = (gfxFont && gfxFont->getOrigName())
? gfxFont->getOrigName()->copy()
: (GooString *)NULL;
+ flags = gfxFont ? gfxFont->getFlags() : 0;
#endif
}
@@ -230,6 +284,9 @@
colorG = colToDbl(rgb.g);
colorB = colToDbl(rgb.b);
#endif
+
+ underlined = gFalse;
+ link = NULL;
}
TextWord::~TextWord() {
@@ -386,6 +443,39 @@
return s;
}
+void TextWord::getCharBBox(int charIdx, double *xMinA, double *yMinA,
+ double *xMaxA, double *yMaxA) {
+ if (charIdx < 0 || charIdx >= len) {
+ return;
+ }
+ switch (rot) {
+ case 0:
+ *xMinA = edge[charIdx];
+ *xMaxA = edge[charIdx + 1];
+ *yMinA = yMin;
+ *yMaxA = yMax;
+ break;
+ case 1:
+ *xMinA = xMin;
+ *xMaxA = xMax;
+ *yMinA = edge[charIdx];
+ *yMaxA = edge[charIdx + 1];
+ break;
+ case 2:
+ *xMinA = edge[charIdx + 1];
+ *xMaxA = edge[charIdx];
+ *yMinA = yMin;
+ *yMaxA = yMax;
+ break;
+ case 3:
+ *xMinA = xMin;
+ *xMaxA = xMax;
+ *yMinA = edge[charIdx + 1];
+ *yMaxA = edge[charIdx];
+ break;
+ }
+}
+
#endif // TEXTOUT_WORD_LIST
//------------------------------------------------------------------------
@@ -651,6 +741,9 @@
space = maxCharSpacing * words->fontSize;
} else {
space = maxWideCharSpacingMul * minSpace;
+ if (space > maxWideCharSpacing * words->fontSize) {
+ space = maxWideCharSpacing * words->fontSize;
+ }
}
// merge words
@@ -662,8 +755,9 @@
word0 = word1;
word1 = word1->next;
} else if (word0->font == word1->font &&
+ word0->underlined == word1->underlined &&
fabs(word0->fontSize - word1->fontSize) <
- maxWordFontSizeDelta * words->fontSize &&
+ maxWordFontSizeDelta * words->fontSize &&
word1->charPos == word0->charPos + word0->charLen) {
word0->merge(word1);
word0->next = word1->next;
@@ -740,6 +834,8 @@
static int cmpYXPrimaryRot(const void *p1, const void *p2);
static int cmpYXLineRot(const void *p1, const void *p2);
static int cmpXYLineRot(const void *p1, const void *p2);
+ static int cmpXYColumnPrimaryRot(const void *p1, const void *p2);
+ static int cmpXYColumnLineRot(const void *p1, const void *p2);
};
void TextLineFrag::init(TextLine *lineA, int startA, int lenA) {
@@ -971,6 +1067,54 @@
return cmp < 0 ? -1 : cmp > 0 ? 1 : 0;
}
+int TextLineFrag::cmpXYColumnPrimaryRot(const void *p1, const void *p2) {
+ TextLineFrag *frag1 = (TextLineFrag *)p1;
+ TextLineFrag *frag2 = (TextLineFrag *)p2;
+ double cmp;
+
+ // if columns overlap, compare y values
+ if (frag1->col < frag2->col + (frag2->line->col[frag2->start + frag2->len] -
+ frag2->line->col[frag2->start]) &&
+ frag2->col < frag1->col + (frag1->line->col[frag1->start + frag1->len] -
+ frag1->line->col[frag1->start])) {
+ cmp = 0; // make gcc happy
+ switch (frag1->line->blk->page->primaryRot) {
+ case 0: cmp = frag1->yMin - frag2->yMin; break;
+ case 1: cmp = frag2->xMax - frag1->xMax; break;
+ case 2: cmp = frag2->yMin - frag1->yMin; break;
+ case 3: cmp = frag1->xMax - frag2->xMax; break;
+ }
+ return cmp < 0 ? -1 : cmp > 0 ? 1 : 0;
+ }
+
+ // otherwise, compare starting column
+ return frag1->col - frag2->col;
+}
+
+int TextLineFrag::cmpXYColumnLineRot(const void *p1, const void *p2) {
+ TextLineFrag *frag1 = (TextLineFrag *)p1;
+ TextLineFrag *frag2 = (TextLineFrag *)p2;
+ double cmp;
+
+ // if columns overlap, compare y values
+ if (frag1->col < frag2->col + (frag2->line->col[frag2->start + frag2->len] -
+ frag2->line->col[frag2->start]) &&
+ frag2->col < frag1->col + (frag1->line->col[frag1->start + frag1->len] -
+ frag1->line->col[frag1->start])) {
+ cmp = 0; // make gcc happy
+ switch (frag1->line->rot) {
+ case 0: cmp = frag1->yMin - frag2->yMin; break;
+ case 1: cmp = frag2->xMax - frag1->xMax; break;
+ case 2: cmp = frag2->yMin - frag1->yMin; break;
+ case 3: cmp = frag1->xMax - frag2->xMax; break;
+ }
+ return cmp < 0 ? -1 : cmp > 0 ? 1 : 0;
+ }
+
+ // otherwise, compare starting column
+ return frag1->col - frag2->col;
+}
+
//------------------------------------------------------------------------
// TextBlock
//------------------------------------------------------------------------
@@ -1629,6 +1773,8 @@
fonts = new GooList();
lastFindXMin = lastFindYMin = 0;
haveLastFind = gFalse;
+ underlines = new GooList();
+ links = new GooList();
}
TextPage::~TextPage() {
@@ -1641,6 +1787,8 @@
}
}
delete fonts;
+ deleteGooList(underlines, TextUnderline);
+ deleteGooList(links, TextLink);
}
void TextPage::startPage(GfxState *state) {
@@ -1815,14 +1963,6 @@
GBool overlap;
int i;
- // throw away chars that aren't inside the page bounds
- state->transform(x, y, &x1, &y1);
- if (x1 < 0 || x1 > pageWidth ||
- y1 < 0 || y1 > pageHeight) {
- charPos += nBytes;
- return;
- }
-
// subtract char and word spacing from the dx,dy values
sp = state->getCharSpace();
if (c == (CharCode)0x20) {
@@ -1833,6 +1973,16 @@
dy -= dy2;
state->transformDelta(dx, dy, &w1, &h1);
+ // throw away chars that aren't inside the page bounds
+ // (and also do a sanity check on the character size)
+ state->transform(x, y, &x1, &y1);
+ if (x1 + w1 < 0 || x1 > pageWidth ||
+ y1 + h1 < 0 || y1 > pageHeight ||
+ w1 > pageWidth || h1 > pageHeight) {
+ charPos += nBytes;
+ return;
+ }
+
// check the tiny chars limit
if (!globalParams->getTextKeepTinyChars() &&
fabs(w1) < 3 && fabs(h1) < 3) {
@@ -1845,7 +1995,7 @@
// break words at space character
if (uLen == 1 && u[0] == (Unicode)0x20) {
if (curWord) {
- ++curWord->charLen;
+ ++curWord->charLen;
}
charPos += nBytes;
endWord();
@@ -1859,7 +2009,8 @@
// and secondary axes), or
// (2) this character overlaps the previous one (duplicated text), or
// (3) the previous character was an overlap (we want each duplicated
- // character to be in a word by itself at this stage)
+ // character to be in a word by itself at this stage),
+ // (4) the font size has changed
if (curWord && curWord->len > 0) {
base = sp = delta = 0; // make gcc happy
switch (curWord->rot) {
@@ -1889,7 +2040,8 @@
if (overlap || lastCharOverlap ||
sp < -minDupBreakOverlap * curWord->fontSize ||
sp > minWordBreakSpace * curWord->fontSize ||
- fabs(base - curWord->base) > 0.5) {
+ fabs(base - curWord->base) > 0.5 ||
+ curFontSize != curWord->fontSize) {
endWord();
}
lastCharOverlap = overlap;
@@ -1966,7 +2118,15 @@
}
}
-void TextPage::coalesce(GBool physLayout) {
+void TextPage::addUnderline(double x0, double y0, double x1, double y1) {
+ underlines->append(new TextUnderline(x0, y0, x1, y1));
+}
+
+void TextPage::addLink(int xMin, int yMin, int xMax, int yMax, Link *link) {
+ links->append(new TextLink(xMin, yMin, xMax, yMax, link));
+}
+
+void TextPage::coalesce(GBool physLayout, GBool doHTML) {
UnicodeMap *uMap;
TextPool *pool;
TextWord *word0, *word1, *word2;
@@ -1974,7 +2134,9 @@
TextBlock *blkList, *blkStack, *blk, *lastBlk, *blk0, *blk1;
TextBlock **blkArray;
TextFlow *flow, *lastFlow;
- int rot, poolMinBaseIdx, baseIdx, startBaseIdx;
+ TextUnderline *underline;
+ TextLink *link;
+ int rot, poolMinBaseIdx, baseIdx, startBaseIdx, endBaseIdx;
double minBase, maxBase, newMinBase, newMaxBase;
double fontSize, colSpace1, colSpace2, lineSpace, intraLineSpace, blkSpace;
GBool found;
@@ -2002,9 +2164,9 @@
pool = pools[rot];
for (baseIdx = pool->minBaseIdx; baseIdx <= pool->maxBaseIdx; ++baseIdx) {
for (word0 = pool->getPool(baseIdx); word0; word0 = word0->next) {
- printf(" word: x=%.2f..%.2f y=%.2f..%.2f base=%.2f fontSize=%.2f rot=%d '",
+ printf(" word: x=%.2f..%.2f y=%.2f..%.2f base=%.2f fontSize=%.2f rot=%d link=%p '",
word0->xMin, word0->xMax, word0->yMin, word0->yMax,
- word0->base, word0->fontSize, rot*90);
+ word0->base, word0->fontSize, rot*90, word0->link);
for (i = 0; i < word0->len; ++i) {
fputc(word0->text[i] & 0xff, stdout);
}
@@ -2015,6 +2177,150 @@
printf("\n");
#endif
+#if 0 //~ for debugging
+ for (i = 0; i < underlines->getLength(); ++i) {
+ underline = (TextUnderline *)underlines->get(i);
+ printf("underline: x=%g..%g y=%g..%g horiz=%d\n",
+ underline->x0, underline->x1, underline->y0, underline->y1,
+ underline->horiz);
+ }
+#endif
+
+ if (doHTML) {
+
+ //----- handle underlining
+ for (i = 0; i < underlines->getLength(); ++i) {
+ underline = (TextUnderline *)underlines->get(i);
+ if (underline->horiz) {
+ // rot = 0
+ if (pools[0]->minBaseIdx <= pools[0]->maxBaseIdx) {
+ startBaseIdx = pools[0]->getBaseIdx(underline->y0 + minUnderlineGap);
+ endBaseIdx = pools[0]->getBaseIdx(underline->y0 + maxUnderlineGap);
+ for (j = startBaseIdx; j <= endBaseIdx; ++j) {
+ for (word0 = pools[0]->getPool(j); word0; word0 = word0->next) {
+ //~ need to check the y value against the word baseline
+ if (underline->x0 < word0->xMin + underlineSlack &&
+ word0->xMax - underlineSlack < underline->x1) {
+ word0->underlined = gTrue;
+ }
+ }
+ }
+ }
+
+ // rot = 2
+ if (pools[2]->minBaseIdx <= pools[2]->maxBaseIdx) {
+ startBaseIdx = pools[2]->getBaseIdx(underline->y0 - maxUnderlineGap);
+ endBaseIdx = pools[2]->getBaseIdx(underline->y0 - minUnderlineGap);
+ for (j = startBaseIdx; j <= endBaseIdx; ++j) {
+ for (word0 = pools[2]->getPool(j); word0; word0 = word0->next) {
+ if (underline->x0 < word0->xMin + underlineSlack &&
+ word0->xMax - underlineSlack < underline->x1) {
+ word0->underlined = gTrue;
+ }
+ }
+ }
+ }
+ } else {
+ // rot = 1
+ if (pools[1]->minBaseIdx <= pools[1]->maxBaseIdx) {
+ startBaseIdx = pools[1]->getBaseIdx(underline->x0 - maxUnderlineGap);
+ endBaseIdx = pools[1]->getBaseIdx(underline->x0 - minUnderlineGap);
+ for (j = startBaseIdx; j <= endBaseIdx; ++j) {
+ for (word0 = pools[1]->getPool(j); word0; word0 = word0->next) {
+ if (underline->y0 < word0->yMin + underlineSlack &&
+ word0->yMax - underlineSlack < underline->y1) {
+ word0->underlined = gTrue;
+ }
+ }
+ }
+ }
+
+ // rot = 3
+ if (pools[3]->minBaseIdx <= pools[3]->maxBaseIdx) {
+ startBaseIdx = pools[3]->getBaseIdx(underline->x0 + minUnderlineGap);
+ endBaseIdx = pools[3]->getBaseIdx(underline->x0 + maxUnderlineGap);
+ for (j = startBaseIdx; j <= endBaseIdx; ++j) {
+ for (word0 = pools[3]->getPool(j); word0; word0 = word0->next) {
+ if (underline->y0 < word0->yMin + underlineSlack &&
+ word0->yMax - underlineSlack < underline->y1) {
+ word0->underlined = gTrue;
+ }
+ }
+ }
+ }
+ }
+ }
+
+ //----- handle links
+ for (i = 0; i < links->getLength(); ++i) {
+ link = (TextLink *)links->get(i);
+
+ // rot = 0
+ if (pools[0]->minBaseIdx <= pools[0]->maxBaseIdx) {
+ startBaseIdx = pools[0]->getBaseIdx(link->yMin);
+ endBaseIdx = pools[0]->getBaseIdx(link->yMax);
+ for (j = startBaseIdx; j <= endBaseIdx; ++j) {
+ for (word0 = pools[0]->getPool(j); word0; word0 = word0->next) {
+ if (link->xMin < word0->xMin + hyperlinkSlack &&
+ word0->xMax - hyperlinkSlack < link->xMax &&
+ link->yMin < word0->yMin + hyperlinkSlack &&
+ word0->yMax - hyperlinkSlack < link->yMax) {
+ word0->link = link->link;
+ }
+ }
+ }
+ }
+
+ // rot = 2
+ if (pools[2]->minBaseIdx <= pools[2]->maxBaseIdx) {
+ startBaseIdx = pools[2]->getBaseIdx(link->yMin);
+ endBaseIdx = pools[2]->getBaseIdx(link->yMax);
+ for (j = startBaseIdx; j <= endBaseIdx; ++j) {
+ for (word0 = pools[2]->getPool(j); word0; word0 = word0->next) {
+ if (link->xMin < word0->xMin + hyperlinkSlack &&
+ word0->xMax - hyperlinkSlack < link->xMax &&
+ link->yMin < word0->yMin + hyperlinkSlack &&
+ word0->yMax - hyperlinkSlack < link->yMax) {
+ word0->link = link->link;
+ }
+ }
+ }
+ }
+
+ // rot = 1
+ if (pools[1]->minBaseIdx <= pools[1]->maxBaseIdx) {
+ startBaseIdx = pools[1]->getBaseIdx(link->xMin);
+ endBaseIdx = pools[1]->getBaseIdx(link->xMax);
+ for (j = startBaseIdx; j <= endBaseIdx; ++j) {
+ for (word0 = pools[1]->getPool(j); word0; word0 = word0->next) {
+ if (link->yMin < word0->yMin + hyperlinkSlack &&
+ word0->yMax - hyperlinkSlack < link->yMax &&
+ link->xMin < word0->xMin + hyperlinkSlack &&
+ word0->xMax - hyperlinkSlack < link->xMax) {
+ word0->link = link->link;
+ }
+ }
+ }
+ }
+
+ // rot = 3
+ if (pools[3]->minBaseIdx <= pools[3]->maxBaseIdx) {
+ startBaseIdx = pools[3]->getBaseIdx(link->xMin);
+ endBaseIdx = pools[3]->getBaseIdx(link->xMax);
+ for (j = startBaseIdx; j <= endBaseIdx; ++j) {
+ for (word0 = pools[3]->getPool(j); word0; word0 = word0->next) {
+ if (link->yMin < word0->yMin + hyperlinkSlack &&
+ word0->yMax - hyperlinkSlack < link->yMax &&
+ link->xMin < word0->xMin + hyperlinkSlack &&
+ word0->xMax - hyperlinkSlack < link->xMax) {
+ word0->link = link->link;
+ }
+ }
+ }
+ }
+ }
+ }
+
//----- assemble the blocks
//~ add an outer loop for writing mode (vertical text)
@@ -2803,21 +3109,21 @@
}
}
} else {
- if ((startAtTop ||
- yMin1 > yStart || (yMin1 == yStart && xMin1 > xStart)) &&
- (stopAtBottom ||
+ if ((startAtTop ||
+ yMin1 > yStart || (yMin1 == yStart && xMin1 > xStart)) &&
+ (stopAtBottom ||
yMin1 < yStop || (yMin1 == yStop && xMin1 < xStop))) {
if (!found ||
yMin1 < yMin0 || (yMin1 == yMin0 && xMin1 < xMin0)) {
- xMin0 = xMin1;
- xMax0 = xMax1;
- yMin0 = yMin1;
- yMax0 = yMax1;
- found = gTrue;
+ xMin0 = xMin1;
+ xMax0 = xMax1;
+ yMin0 = yMin1;
+ yMax0 = yMax1;
+ found = gTrue;
+ }
}
}
}
- }
if (backward) {
--j;
--p;
@@ -2861,7 +3167,7 @@
char space[8], eol[16];
int spaceLen, eolLen;
int lastRot;
- double x, y;
+ double x, y, delta;
int col, idx0, idx1, i, j;
GBool multiLine, oneRot;
@@ -3028,6 +3334,17 @@
qsort(frags, nFrags, sizeof(TextLineFrag),
&TextLineFrag::cmpYXPrimaryRot);
}
+ i = 0;
+ while (i < nFrags) {
+ delta = maxIntraLineDelta * frags[i].line->words->fontSize;
+ for (j = i+1;
+ j < nFrags && fabs(frags[j].base - frags[i].base) < delta;
+ ++j) ;
+ qsort(frags + i, j - i, sizeof(TextLineFrag),
+ oneRot ? &TextLineFrag::cmpXYColumnLineRot
+ : &TextLineFrag::cmpXYColumnPrimaryRot);
+ i = j;
+ }
col = 0;
multiLine = gFalse;
@@ -3744,7 +4061,8 @@
int spaceLen, eolLen, eopLen;
GBool pageBreaks;
GooString *s;
- int col, i, d, n;
+ double delta;
+ int col, i, j, d, n;
// get the output encoding
if (!(uMap = globalParams->getTextEncoding())) {
@@ -3809,6 +4127,16 @@
}
}
qsort(frags, nFrags, sizeof(TextLineFrag), &TextLineFrag::cmpYXPrimaryRot);
+ i = 0;
+ while (i < nFrags) {
+ delta = maxIntraLineDelta * frags[i].line->words->fontSize;
+ for (j = i+1;
+ j < nFrags && fabs(frags[j].base - frags[i].base) < delta;
+ ++j) ;
+ qsort(frags + i, j - i, sizeof(TextLineFrag),
+ &TextLineFrag::cmpXYColumnPrimaryRot);
+ i = j;
+ }
#if 0 // for debugging
printf("*** line fragments ***\n");
@@ -4094,7 +4422,7 @@
// TextOutputDev
//------------------------------------------------------------------------
-static void outputToFile(void *stream, char *text, int len) {
+static void TextOutputDev_outputToFile(void *stream, char *text, int len) {
fwrite(text, 1, len, (FILE *)stream);
}
@@ -4103,6 +4431,7 @@
text = NULL;
physLayout = physLayoutA;
rawOrder = rawOrderA;
+ doHTML = gFalse;
ok = gTrue;
// open file
@@ -4121,7 +4450,7 @@
ok = gFalse;
return;
}
- outputFunc = &outputToFile;
+ outputFunc = &TextOutputDev_outputToFile;
} else {
outputStream = NULL;
}
@@ -4137,6 +4466,7 @@
needClose = gFalse;
physLayout = physLayoutA;
rawOrder = rawOrderA;
+ doHTML = gFalse;
text = new TextPage(rawOrderA);
ok = gTrue;
}
@@ -4159,7 +4489,7 @@
void TextOutputDev::endPage() {
text->endPage();
- text->coalesce(physLayout);
+ text->coalesce(physLayout, doHTML);
if (outputStream) {
text->dump(outputStream, outputFunc, physLayout);
}
@@ -4182,6 +4512,153 @@
text->addChar(state, x, y, dx, dy, c, nBytes, u, uLen);
}
+void TextOutputDev::stroke(GfxState *state) {
+ GfxPath *path;
+ GfxSubpath *subpath;
+ double x[2], y[2];
+
+ if (!doHTML) {
+ return;
+ }
+ path = state->getPath();
+ if (path->getNumSubpaths() != 1) {
+ return;
+ }
+ subpath = path->getSubpath(0);
+ if (subpath->getNumPoints() != 2) {
+ return;
+ }
+ state->transform(subpath->getX(0), subpath->getY(0), &x[0], &y[0]);
+ state->transform(subpath->getX(1), subpath->getY(1), &x[1], &y[1]);
+
+ // look for a vertical or horizontal line
+ if (x[0] == x[1] || y[0] == y[1]) {
+ text->addUnderline(x[0], y[0], x[1], y[1]);
+ }
+}
+
+void TextOutputDev::fill(GfxState *state) {
+ GfxPath *path;
+ GfxSubpath *subpath;
+ double x[5], y[5];
+ double rx0, ry0, rx1, ry1, t;
+ int i;
+
+ if (!doHTML) {
+ return;
+ }
+ path = state->getPath();
+ if (path->getNumSubpaths() != 1) {
+ return;
+ }
+ subpath = path->getSubpath(0);
+ if (subpath->getNumPoints() != 5) {
+ return;
+ }
+ for (i = 0; i < 5; ++i) {
+ if (subpath->getCurve(i)) {
+ return;
+ }
+ state->transform(subpath->getX(i), subpath->getY(i), &x[i], &y[i]);
+ }
+
+ // look for a rectangle
+ if (x[0] == x[1] && y[1] == y[2] && x[2] == x[3] && y[3] == y[4] &&
+ x[0] == x[4] && y[0] == y[4]) {
+ rx0 = x[0];
+ ry0 = y[0];
+ rx1 = x[2];
+ ry1 = y[1];
+ } else if (y[0] == y[1] && x[1] == x[2] && y[2] == y[3] && x[3] == x[4] &&
+ x[0] == x[4] && y[0] == y[4]) {
+ rx0 = x[0];
+ ry0 = y[0];
+ rx1 = x[1];
+ ry1 = y[2];
+ } else {
+ return;
+ }
+ if (rx1 < rx0) {
+ t = rx0;
+ rx0 = rx1;
+ rx1 = t;
+ }
+ if (ry1 < ry0) {
+ t = ry0;
+ ry0 = ry1;
+ ry1 = t;
+ }
+
+ // skinny horizontal rectangle
+ if (ry1 - ry0 < rx1 - rx0) {
+ if (ry1 - ry0 < maxUnderlineWidth) {
+ ry0 = 0.5 * (ry0 + ry1);
+ text->addUnderline(rx0, ry0, rx1, ry0);
+ }
+
+ // skinny vertical rectangle
+ } else {
+ if (rx1 - rx0 < maxUnderlineWidth) {
+ rx0 = 0.5 * (rx0 + rx1);
+ text->addUnderline(rx0, ry0, rx0, ry1);
+ }
+ }
+}
+
+void TextOutputDev::eoFill(GfxState *state) {
+ if (!doHTML) {
+ return;
+ }
+ fill(state);
+}
+
+void TextOutputDev::processLink(Link *link, Catalog * /*catalog*/) {
+ double x1, y1, x2, y2;
+ int xMin, yMin, xMax, yMax, x, y;
+
+ if (!doHTML) {
+ return;
+ }
+ link->getRect(&x1, &y1, &x2, &y2);
+ cvtUserToDev(x1, y1, &x, &y);
+ xMin = xMax = x;
+ yMin = yMax = y;
+ cvtUserToDev(x1, y2, &x, &y);
+ if (x < xMin) {
+ xMin = x;
+ } else if (x > xMax) {
+ xMax = x;
+ }
+ if (y < yMin) {
+ yMin = y;
+ } else if (y > yMax) {
+ yMax = y;
+ }
+ cvtUserToDev(x2, y1, &x, &y);
+ if (x < xMin) {
+ xMin = x;
+ } else if (x > xMax) {
+ xMax = x;
+ }
+ if (y < yMin) {
+ yMin = y;
+ } else if (y > yMax) {
+ yMax = y;
+ }
+ cvtUserToDev(x2, y2, &x, &y);
+ if (x < xMin) {
+ xMin = x;
+ } else if (x > xMax) {
+ xMax = x;
+ }
+ if (y < yMin) {
+ yMin = y;
+ } else if (y > yMax) {
+ yMax = y;
+ }
+ text->addLink(xMin, yMin, xMax, yMax, link);
+}
+
GBool TextOutputDev::findText(Unicode *s, int len,
GBool startAtTop, GBool stopAtBottom,
GBool startAtLast, GBool stopAtLast,
Index: TextOutputDev.h
===================================================================
RCS file: /cvs/poppler/poppler/poppler/TextOutputDev.h,v
retrieving revision 1.12
retrieving revision 1.13
diff -u -d -r1.12 -r1.13
--- TextOutputDev.h 19 May 2006 22:04:17 -0000 1.12
+++ TextOutputDev.h 25 Apr 2007 19:59:10 -0000 1.13
@@ -26,6 +26,7 @@
class GfxFont;
class GfxState;
class UnicodeMap;
+class Link;
class TextWord;
class TextPool;
@@ -53,11 +54,24 @@
GBool matches(GfxState *state);
+#if TEXTOUT_WORD_LIST
+ // Get the font name (which may be NULL).
+ GooString *getFontName() { return fontName; }
+
+ // Get font descriptor flags.
+ GBool isFixedWidth() { return flags & fontFixedWidth; }
+ GBool isSerif() { return flags & fontSerif; }
+ GBool isSymbolic() { return flags & fontSymbolic; }
+ GBool isItalic() { return flags & fontItalic; }
+ GBool isBold() { return flags & fontBold; }
+#endif
+
private:
GfxFont *gfxFont;
#if TEXTOUT_WORD_LIST
GooString *fontName;
+ int flags;
#endif
friend class TextWord;
@@ -99,6 +113,12 @@
void visitSelection(TextSelectionVisitor *visitor,
PDFRectangle *selection);
+ // Get the TextFontInfo object associated with this word.
+ TextFontInfo *getFontInfo() { return font; }
+
+ // Get the next TextWord on the linked list.
+ TextWord *getNext() { return next; }
+
#if TEXTOUT_WORD_LIST
int getLength() { return len; }
const Unicode *getChar(int idx) { return &text[idx]; }
@@ -108,11 +128,16 @@
{ *r = colorR; *g = colorG; *b = colorB; }
void getBBox(double *xMinA, double *yMinA, double *xMaxA, double *yMaxA)
{ *xMinA = xMin; *yMinA = yMin; *xMaxA = xMax; *yMaxA = yMax; }
+ void getCharBBox(int charIdx, double *xMinA, double *yMinA,
+ double *xMaxA, double *yMaxA);
double getFontSize() { return fontSize; }
int getRotation() { return rot; }
int getCharPos() { return charPos; }
int getCharLen() { return charLen; }
+ GBool getSpaceAfter() { return spaceAfter; }
#endif
+ GBool isUnderlined() { return underlined; }
+ Link *getLink() { return link; }
double getEdge(int i) { return edge[i]; }
double getBaseline () { return base; }
GBool hasSpaceAfter () { return spaceAfter; }
@@ -145,6 +170,9 @@
colorB;
#endif
+ GBool underlined;
+ Link *link;
+
friend class TextPool;
friend class TextLine;
friend class TextBlock;
@@ -222,6 +250,15 @@
void visitSelection(TextSelectionVisitor *visitor,
PDFRectangle *selection);
+ // Get the head of the linked list of TextWords.
+ TextWord *getWords() { return words; }
+
+ // Get the next TextLine on the linked list.
+ TextLine *getNext() { return next; }
+
+ // Returns true if the last char of the line is a hyphen.
+ GBool isHyphenated() { return hyphenated; }
+
private:
TextBlock *blk; // parent block
@@ -287,6 +324,12 @@
void visitSelection(TextSelectionVisitor *visitor,
PDFRectangle *selection);
+ // Get the head of the linked list of TextLines.
+ TextLine *getLines() { return lines; }
+
+ // Get the next TextBlock on the linked list.
+ TextBlock *getNext() { return next; }
+
private:
TextPage *page; // the parent page
@@ -334,6 +377,12 @@
// primary axis.
GBool blockFits(TextBlock *blk, TextBlock *prevBlk);
+ // Get the head of the linked list of TextBlocks.
+ TextBlock *getBlocks() { return blocks; }
+
+ // Get the next TextFlow on the linked list.
+ TextFlow *getNext() { return next; }
+
private:
TextPage *page; // the parent page
@@ -373,7 +422,7 @@
private:
- GooList *words;
+ GooList *words; // [TextWord]
};
#endif // TEXTOUT_WORD_LIST
@@ -414,8 +463,14 @@
// Add a word, sorting it into the list of words.
void addWord(TextWord *word);
+ // Add a (potential) underline.
+ void addUnderline(double x0, double y0, double x1, double y1);
+
+ // Add a hyperlink.
+ void addLink(int xMin, int yMin, int xMax, int yMax, Link *link);
+
// Coalesce strings that look like parts of the same line.
- void coalesce(GBool physLayout);
+ void coalesce(GBool physLayout, GBool doHTML);
// Find a string. If <startAtTop> is true, starts looking at the
// top of the page; else if <startAtLast> is true, starts looking
@@ -459,6 +514,9 @@
void dump(void *outputStream, TextOutputFunc outputFunc,
GBool physLayout);
+ // Get the head of the linked list of TextFlows.
+ TextFlow *getFlows() { return flows; }
+
#if TEXTOUT_WORD_LIST
// Build a flat word list, in content stream order (if
// this->rawOrder is true), physical layout order (if <physLayout>
@@ -504,6 +562,9 @@
lastFindYMin;
GBool haveLastFind;
+ GooList *underlines; // [TextUnderline]
+ GooList *links; // [TextLink]
+
friend class TextLine;
friend class TextLineFrag;
friend class TextBlock;
@@ -576,6 +637,14 @@
double originX, double originY,
CharCode c, int nBytes, Unicode *u, int uLen);
+ //----- path painting
+ virtual void stroke(GfxState *state);
+ virtual void fill(GfxState *state);
+ virtual void eoFill(GfxState *state);
+
+ //----- link borders
+ virtual void processLink(Link *link, Catalog *catalog);
+
//----- special access
// Find a string. If <startAtTop> is true, starts looking at the
@@ -623,6 +692,9 @@
// transferring ownership to the caller.
TextPage *takeText();
+ // Turn extra processing for HTML conversion on or off.
+ void enableHTMLExtras(GBool doHTMLA) { doHTML = doHTMLA; }
+
private:
TextOutputFunc outputFunc; // output function
@@ -633,6 +705,7 @@
GBool physLayout; // maintain original physical layout when
// dumping text
GBool rawOrder; // keep text in content stream order
+ GBool doHTML; // extra processing for HTML conversion
GBool ok; // set up ok?
};
--- UGooString.cc DELETED ---
--- UGooString.h DELETED ---
Index: XRef.cc
===================================================================
RCS file: /cvs/poppler/poppler/poppler/XRef.cc,v
retrieving revision 1.14
retrieving revision 1.15
diff -u -d -r1.14 -r1.15
--- XRef.cc 24 Feb 2007 23:32:23 -0000 1.14
+++ XRef.cc 25 Apr 2007 19:59:10 -0000 1.15
@@ -24,7 +24,6 @@
#include "Dict.h"
#include "Error.h"
#include "ErrorCodes.h"
-#include "UGooString.h"
#include "XRef.h"
//------------------------------------------------------------------------
@@ -124,7 +123,7 @@
objStr.streamReset();
obj1.initNull();
str = new EmbedStream(objStr.getStream(), &obj1, gTrue, first);
- parser = new Parser(xref, new Lexer(xref, str));
+ parser = new Parser(xref, new Lexer(xref, str), gFalse);
for (i = 0; i < nObjects; ++i) {
parser->getObj(&obj1);
parser->getObj(&obj2);
@@ -165,7 +164,7 @@
str = new EmbedStream(objStr.getStream(), &obj1, gTrue,
offsets[i+1] - offsets[i]);
}
- parser = new Parser(xref, new Lexer(xref, str));
+ parser = new Parser(xref, new Lexer(xref, str), gFalse);
parser->getObj(&objs[i]);
while (str->getChar() != EOF) ;
delete parser;
@@ -331,7 +330,8 @@
obj.initNull();
parser = new Parser(NULL,
new Lexer(NULL,
- str->makeSubStream(start + *pos, gFalse, 0, &obj)));
+ str->makeSubStream(start + *pos, gFalse, 0, &obj)),
+ gTrue);
parser->getObj(&obj);
// parse an old-style xref table
@@ -689,7 +689,7 @@
size = 0;
entries = NULL;
- error(0, "PDF file is damaged - attempting to reconstruct xref table...");
+ error(-1, "PDF file is damaged - attempting to reconstruct xref table...");
gotRoot = gFalse;
streamEndsLen = streamEndsSize = 0;
@@ -701,12 +701,16 @@
}
p = buf;
+ // skip whitespace
+ while (*p && Lexer::isSpace(*p & 0xff)) ++p;
+
// got trailer dictionary
if (!strncmp(p, "trailer", 7)) {
obj.initNull();
parser = new Parser(NULL,
new Lexer(NULL,
- str->makeSubStream(pos + 7, gFalse, 0, &obj)));
+ str->makeSubStream(pos + 7, gFalse, 0, &obj)),
+ gFalse);
parser->getObj(&newTrailerDict);
if (newTrailerDict.isDict()) {
newTrailerDict.dictLookupNF("Root", &obj);
@@ -799,7 +803,8 @@
void XRef::setEncryption(int permFlagsA, GBool ownerPasswordOkA,
Guchar *fileKeyA, int keyLengthA,
- int encVersionA, int encRevisionA) {
+ int encVersionA, int encRevisionA,
+ CryptAlgorithm encAlgorithmA) {
int i;
encrypted = gTrue;
@@ -815,6 +820,7 @@
}
encVersion = encVersionA;
encRevision = encRevisionA;
+ encAlgorithm = encAlgorithmA;
}
GBool XRef::okToPrint(GBool ignoreOwnerPW) {
@@ -883,7 +889,8 @@
obj1.initNull();
parser = new Parser(this,
new Lexer(this,
- str->makeSubStream(start + e->offset, gFalse, 0, &obj1)));
+ str->makeSubStream(start + e->offset, gFalse, 0, &obj1)),
+ gTrue);
parser->getObj(&obj1);
parser->getObj(&obj2);
parser->getObj(&obj3);
@@ -896,8 +903,8 @@
delete parser;
goto err;
}
- parser->getObj(obj, encrypted ? fileKey : (Guchar *)NULL, keyLength,
- num, gen);
+ parser->getObj(obj, encrypted ? fileKey : (Guchar *)NULL,
+ encAlgorithm, keyLength, num, gen);
obj1.free();
obj2.free();
obj3.free();
@@ -959,7 +966,7 @@
return gTrue;
}
-int XRef::getNumEntry(int offset) const
+int XRef::getNumEntry(Guint offset) const
{
if (size > 0)
{
Index: XRef.h
===================================================================
RCS file: /cvs/poppler/poppler/poppler/XRef.h,v
retrieving revision 1.7
retrieving revision 1.8
diff -u -d -r1.7 -r1.8
--- XRef.h 24 Feb 2007 23:32:23 -0000 1.7
+++ XRef.h 25 Apr 2007 19:59:10 -0000 1.8
@@ -59,7 +59,8 @@
// Set the encryption parameters.
void setEncryption(int permFlagsA, GBool ownerPasswordOkA,
Guchar *fileKeyA, int keyLengthA,
- int encVersionA, int encRevisionA);
+ int encVersionA, int encRevisionA,
+ CryptAlgorithm encAlgorithmA);
// Is the file encrypted?
GBool isEncrypted() { return encrypted; }
@@ -99,7 +100,7 @@
GBool getStreamEnd(Guint streamStart, Guint *streamEnd);
// Retuns the entry that belongs to the offset
- int getNumEntry(int offset) const;
+ int getNumEntry(Guint offset) const;
// Direct access.
int getSize() { return size; }
@@ -130,6 +131,7 @@
GBool encrypted; // true if file is encrypted
int encRevision;
int encVersion; // encryption algorithm
+ CryptAlgorithm encAlgorithm; // encryption algorithm
int keyLength; // length of key, in bytes
int permFlags; // permission bits
Guchar fileKey[16]; // file decryption key
- Previous message: [poppler] poppler/splash: Splash.cc, 1.10, 1.11 Splash.h, 1.3,
1.4 SplashBitmap.cc, 1.4, 1.5 SplashBitmap.h, 1.2,
1.3 SplashClip.cc, 1.2, 1.3 SplashClip.h, 1.2,
1.3 SplashFTFont.cc, 1.7, 1.8 SplashFTFont.h, 1.1.1.1,
1.2 SplashFTFontEngine.cc, 1.4, 1.5 SplashFTFontEngine.h, 1.3,
1.4 SplashFTFontFile.cc, 1.3, 1.4 SplashFTFontFile.h, 1.2,
1.3 SplashFont.cc, 1.3, 1.4 SplashFont.h, 1.2,
1.3 SplashFontEngine.cc, 1.4, 1.5 SplashFontEngine.h, 1.2,
1.3 SplashFontFile.cc, 1.3, 1.4 SplashFontFile.h, 1.2,
1.3 SplashMath.h, 1.2, 1.3 SplashPath.cc, 1.3,
1.4 SplashPath.h, 1.3, 1.4 SplashPattern.cc, 1.2,
1.3 SplashPattern.h, 1.2, 1.3 SplashScreen.cc, 1.3,
1.4 SplashScreen.h, 1.2, 1.3 SplashState.cc, 1.3,
1.4 SplashState.h, 1.2, 1.3 SplashT1Font.cc, 1.2,
1.3 SplashT1Font.h, 1.2, 1.3 SplashT1FontEngine.cc, 1.2,
1.3 SplashT1FontFile.cc, 1.3, 1.4 SplashT1FontFile.h, 1.2,
1.3 SplashTypes.h, 1.5, 1.6 SplashXPath.cc, 1.3,
1.4 SplashXPath.h, 1.1.1.1, 1.2 SplashXPathScanner.cc, 1.4,
1.5 SplashXPathScanner.h, 1.1.1.1, 1.2
- Next message: [poppler] 0.6 schedule
- Messages sorted by:
[ date ]
[ thread ]
[ subject ]
[ author ]
More information about the poppler
mailing list