Web   ·   Wiki   ·   Activities   ·   Blog   ·   Lists   ·   Chat   ·   Meeting   ·   Bugs   ·   Git   ·   Translate   ·   Archive   ·   People   ·   Donate
summaryrefslogtreecommitdiffstats
path: root/pdf
diff options
context:
space:
mode:
Diffstat (limited to 'pdf')
-rw-r--r--pdf/xpdf/JBIG2Stream.cc383
-rw-r--r--pdf/xpdf/JBIG2Stream.h44
-rw-r--r--pdf/xpdf/Outline.h4
-rw-r--r--pdf/xpdf/XPDFApp.cc12
-rw-r--r--pdf/xpdf/XPDFApp.h3
-rw-r--r--pdf/xpdf/XPDFCore.cc118
-rw-r--r--pdf/xpdf/XPDFCore.h19
-rw-r--r--pdf/xpdf/XPDFViewer.cc73
-rw-r--r--pdf/xpdf/about-text.h2
9 files changed, 168 insertions, 490 deletions
diff --git a/pdf/xpdf/JBIG2Stream.cc b/pdf/xpdf/JBIG2Stream.cc
index f852d26..c1bf4f7 100644
--- a/pdf/xpdf/JBIG2Stream.cc
+++ b/pdf/xpdf/JBIG2Stream.cc
@@ -15,6 +15,7 @@
#include <stdlib.h>
#include "GList.h"
#include "Error.h"
+#include "JArithmeticDecoder.h"
#include "JBIG2Stream.h"
//~ share these tables
@@ -26,327 +27,6 @@ static int contextSize[4] = { 16, 13, 10, 10 };
static int refContextSize[2] = { 13, 10 };
//------------------------------------------------------------------------
-// JBIG2ArithmeticDecoderStats
-//------------------------------------------------------------------------
-
-class JBIG2ArithmeticDecoderStats {
-public:
-
- JBIG2ArithmeticDecoderStats(int contextSizeA);
- ~JBIG2ArithmeticDecoderStats();
- JBIG2ArithmeticDecoderStats *copy();
- void reset();
- int getContextSize() { return contextSize; }
- void copyFrom(JBIG2ArithmeticDecoderStats *stats);
-
-private:
-
- Guchar *cxTab; // cxTab[cx] = (i[cx] << 1) + mps[cx]
- int contextSize;
-
- friend class JBIG2ArithmeticDecoder;
-};
-
-JBIG2ArithmeticDecoderStats::JBIG2ArithmeticDecoderStats(int contextSizeA) {
- contextSize = contextSizeA;
- cxTab = (Guchar *)gmalloc((1 << contextSize) * sizeof(Guchar));
- reset();
-}
-
-JBIG2ArithmeticDecoderStats::~JBIG2ArithmeticDecoderStats() {
- gfree(cxTab);
-}
-
-JBIG2ArithmeticDecoderStats *JBIG2ArithmeticDecoderStats::copy() {
- JBIG2ArithmeticDecoderStats *stats;
-
- stats = new JBIG2ArithmeticDecoderStats(contextSize);
- memcpy(stats->cxTab, cxTab, 1 << contextSize);
- return stats;
-}
-
-void JBIG2ArithmeticDecoderStats::reset() {
- memset(cxTab, 0, 1 << contextSize);
-}
-
-void JBIG2ArithmeticDecoderStats::copyFrom(
- JBIG2ArithmeticDecoderStats *stats) {
- memcpy(cxTab, stats->cxTab, 1 << contextSize);
-}
-
-//------------------------------------------------------------------------
-// JBIG2ArithmeticDecoder
-//------------------------------------------------------------------------
-
-class JBIG2ArithmeticDecoder {
-public:
-
- JBIG2ArithmeticDecoder();
- ~JBIG2ArithmeticDecoder();
- void setStream(Stream *strA) { str = strA; }
- void start();
- int decodeBit(Guint context, JBIG2ArithmeticDecoderStats *stats);
- int decodeByte(Guint context, JBIG2ArithmeticDecoderStats *stats);
-
- // Returns false for OOB, otherwise sets *<x> and returns true.
- GBool decodeInt(int *x, JBIG2ArithmeticDecoderStats *stats);
-
- Guint decodeIAID(Guint codeLen,
- JBIG2ArithmeticDecoderStats *stats);
-
-private:
-
- int decodeIntBit(JBIG2ArithmeticDecoderStats *stats);
- void byteIn();
-
- static Guint qeTab[47];
- static int nmpsTab[47];
- static int nlpsTab[47];
- static int switchTab[47];
-
- Guint buf0, buf1;
- Guint c, a;
- int ct;
-
- Guint prev; // for the integer decoder
-
- Stream *str;
-};
-
-Guint JBIG2ArithmeticDecoder::qeTab[47] = {
- 0x56010000, 0x34010000, 0x18010000, 0x0AC10000,
- 0x05210000, 0x02210000, 0x56010000, 0x54010000,
- 0x48010000, 0x38010000, 0x30010000, 0x24010000,
- 0x1C010000, 0x16010000, 0x56010000, 0x54010000,
- 0x51010000, 0x48010000, 0x38010000, 0x34010000,
- 0x30010000, 0x28010000, 0x24010000, 0x22010000,
- 0x1C010000, 0x18010000, 0x16010000, 0x14010000,
- 0x12010000, 0x11010000, 0x0AC10000, 0x09C10000,
- 0x08A10000, 0x05210000, 0x04410000, 0x02A10000,
- 0x02210000, 0x01410000, 0x01110000, 0x00850000,
- 0x00490000, 0x00250000, 0x00150000, 0x00090000,
- 0x00050000, 0x00010000, 0x56010000
-};
-
-int JBIG2ArithmeticDecoder::nmpsTab[47] = {
- 1, 2, 3, 4, 5, 38, 7, 8, 9, 10, 11, 12, 13, 29, 15, 16,
- 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32,
- 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 45, 46
-};
-
-int JBIG2ArithmeticDecoder::nlpsTab[47] = {
- 1, 6, 9, 12, 29, 33, 6, 14, 14, 14, 17, 18, 20, 21, 14, 14,
- 15, 16, 17, 18, 19, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29,
- 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 46
-};
-
-int JBIG2ArithmeticDecoder::switchTab[47] = {
- 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
-};
-
-JBIG2ArithmeticDecoder::JBIG2ArithmeticDecoder() {
- str = NULL;
-}
-
-JBIG2ArithmeticDecoder::~JBIG2ArithmeticDecoder() {
-}
-
-void JBIG2ArithmeticDecoder::start() {
- buf0 = (Guint)str->getChar() & 0xff;
- buf1 = (Guint)str->getChar() & 0xff;
-
- // INITDEC
- c = (buf0 ^ 0xff) << 16;
- byteIn();
- c <<= 7;
- ct -= 7;
- a = 0x80000000;
-}
-
-int JBIG2ArithmeticDecoder::decodeBit(Guint context,
- JBIG2ArithmeticDecoderStats *stats) {
- int bit;
- Guint qe;
- int iCX, mpsCX;
-
- iCX = stats->cxTab[context] >> 1;
- mpsCX = stats->cxTab[context] & 1;
- qe = qeTab[iCX];
- a -= qe;
- if (c < a) {
- if (a & 0x80000000) {
- bit = mpsCX;
- } else {
- // MPS_EXCHANGE
- if (a < qe) {
- bit = 1 - mpsCX;
- if (switchTab[iCX]) {
- stats->cxTab[context] = (nlpsTab[iCX] << 1) | (1 - mpsCX);
- } else {
- stats->cxTab[context] = (nlpsTab[iCX] << 1) | mpsCX;
- }
- } else {
- bit = mpsCX;
- stats->cxTab[context] = (nmpsTab[iCX] << 1) | mpsCX;
- }
- // RENORMD
- do {
- if (ct == 0) {
- byteIn();
- }
- a <<= 1;
- c <<= 1;
- --ct;
- } while (!(a & 0x80000000));
- }
- } else {
- c -= a;
- // LPS_EXCHANGE
- if (a < qe) {
- bit = mpsCX;
- stats->cxTab[context] = (nmpsTab[iCX] << 1) | mpsCX;
- } else {
- bit = 1 - mpsCX;
- if (switchTab[iCX]) {
- stats->cxTab[context] = (nlpsTab[iCX] << 1) | (1 - mpsCX);
- } else {
- stats->cxTab[context] = (nlpsTab[iCX] << 1) | mpsCX;
- }
- }
- a = qe;
- // RENORMD
- do {
- if (ct == 0) {
- byteIn();
- }
- a <<= 1;
- c <<= 1;
- --ct;
- } while (!(a & 0x80000000));
- }
- return bit;
-}
-
-int JBIG2ArithmeticDecoder::decodeByte(Guint context,
- JBIG2ArithmeticDecoderStats *stats) {
- int byte;
- int i;
-
- byte = 0;
- for (i = 0; i < 8; ++i) {
- byte = (byte << 1) | decodeBit(context, stats);
- }
- return byte;
-}
-
-GBool JBIG2ArithmeticDecoder::decodeInt(int *x,
- JBIG2ArithmeticDecoderStats *stats) {
- int s;
- Guint v;
- int i;
-
- prev = 1;
- s = decodeIntBit(stats);
- if (decodeIntBit(stats)) {
- if (decodeIntBit(stats)) {
- if (decodeIntBit(stats)) {
- if (decodeIntBit(stats)) {
- if (decodeIntBit(stats)) {
- v = 0;
- for (i = 0; i < 32; ++i) {
- v = (v << 1) | decodeIntBit(stats);
- }
- v += 4436;
- } else {
- v = 0;
- for (i = 0; i < 12; ++i) {
- v = (v << 1) | decodeIntBit(stats);
- }
- v += 340;
- }
- } else {
- v = 0;
- for (i = 0; i < 8; ++i) {
- v = (v << 1) | decodeIntBit(stats);
- }
- v += 84;
- }
- } else {
- v = 0;
- for (i = 0; i < 6; ++i) {
- v = (v << 1) | decodeIntBit(stats);
- }
- v += 20;
- }
- } else {
- v = decodeIntBit(stats);
- v = (v << 1) | decodeIntBit(stats);
- v = (v << 1) | decodeIntBit(stats);
- v = (v << 1) | decodeIntBit(stats);
- v += 4;
- }
- } else {
- v = decodeIntBit(stats);
- v = (v << 1) | decodeIntBit(stats);
- }
-
- if (s) {
- if (v == 0) {
- return gFalse;
- }
- *x = -(int)v;
- } else {
- *x = (int)v;
- }
- return gTrue;
-}
-
-int JBIG2ArithmeticDecoder::decodeIntBit(JBIG2ArithmeticDecoderStats *stats) {
- int bit;
-
- bit = decodeBit(prev, stats);
- if (prev < 0x100) {
- prev = (prev << 1) | bit;
- } else {
- prev = (((prev << 1) | bit) & 0x1ff) | 0x100;
- }
- return bit;
-}
-
-Guint JBIG2ArithmeticDecoder::decodeIAID(Guint codeLen,
- JBIG2ArithmeticDecoderStats *stats) {
- Guint i;
- int bit;
-
- prev = 1;
- for (i = 0; i < codeLen; ++i) {
- bit = decodeBit(prev, stats);
- prev = (prev << 1) | bit;
- }
- return prev - (1 << codeLen);
-}
-
-void JBIG2ArithmeticDecoder::byteIn() {
- if (buf0 == 0xff) {
- if (buf1 > 0x8f) {
- ct = 8;
- } else {
- buf0 = buf1;
- buf1 = (Guint)str->getChar() & 0xff;
- c = c + 0xfe00 - (buf0 << 9);
- ct = 7;
- }
- } else {
- buf0 = buf1;
- buf1 = (Guint)str->getChar() & 0xff;
- c = c + 0xff00 - (buf0 << 8);
- ct = 8;
- }
-}
-
-//------------------------------------------------------------------------
// JBIG2HuffmanTable
//------------------------------------------------------------------------
@@ -1292,21 +972,21 @@ public:
Guint getSize() { return size; }
void setBitmap(Guint idx, JBIG2Bitmap *bitmap) { bitmaps[idx] = bitmap; }
JBIG2Bitmap *getBitmap(Guint idx) { return bitmaps[idx]; }
- void setGenericRegionStats(JBIG2ArithmeticDecoderStats *stats)
+ void setGenericRegionStats(JArithmeticDecoderStats *stats)
{ genericRegionStats = stats; }
- void setRefinementRegionStats(JBIG2ArithmeticDecoderStats *stats)
+ void setRefinementRegionStats(JArithmeticDecoderStats *stats)
{ refinementRegionStats = stats; }
- JBIG2ArithmeticDecoderStats *getGenericRegionStats()
+ JArithmeticDecoderStats *getGenericRegionStats()
{ return genericRegionStats; }
- JBIG2ArithmeticDecoderStats *getRefinementRegionStats()
+ JArithmeticDecoderStats *getRefinementRegionStats()
{ return refinementRegionStats; }
private:
Guint size;
JBIG2Bitmap **bitmaps;
- JBIG2ArithmeticDecoderStats *genericRegionStats;
- JBIG2ArithmeticDecoderStats *refinementRegionStats;
+ JArithmeticDecoderStats *genericRegionStats;
+ JArithmeticDecoderStats *refinementRegionStats;
};
JBIG2SymbolDict::JBIG2SymbolDict(Guint segNumA, Guint sizeA):
@@ -1405,23 +1085,23 @@ JBIG2Stream::JBIG2Stream(Stream *strA, Object *globalsStream):
{
pageBitmap = NULL;
- arithDecoder = new JBIG2ArithmeticDecoder();
- genericRegionStats = new JBIG2ArithmeticDecoderStats(1);
- refinementRegionStats = new JBIG2ArithmeticDecoderStats(1);
- iadhStats = new JBIG2ArithmeticDecoderStats(9);
- iadwStats = new JBIG2ArithmeticDecoderStats(9);
- iaexStats = new JBIG2ArithmeticDecoderStats(9);
- iaaiStats = new JBIG2ArithmeticDecoderStats(9);
- iadtStats = new JBIG2ArithmeticDecoderStats(9);
- iaitStats = new JBIG2ArithmeticDecoderStats(9);
- iafsStats = new JBIG2ArithmeticDecoderStats(9);
- iadsStats = new JBIG2ArithmeticDecoderStats(9);
- iardxStats = new JBIG2ArithmeticDecoderStats(9);
- iardyStats = new JBIG2ArithmeticDecoderStats(9);
- iardwStats = new JBIG2ArithmeticDecoderStats(9);
- iardhStats = new JBIG2ArithmeticDecoderStats(9);
- iariStats = new JBIG2ArithmeticDecoderStats(9);
- iaidStats = new JBIG2ArithmeticDecoderStats(1);
+ arithDecoder = new JArithmeticDecoder();
+ genericRegionStats = new JArithmeticDecoderStats(1 << 1);
+ refinementRegionStats = new JArithmeticDecoderStats(1 << 1);
+ iadhStats = new JArithmeticDecoderStats(1 << 9);
+ iadwStats = new JArithmeticDecoderStats(1 << 9);
+ iaexStats = new JArithmeticDecoderStats(1 << 9);
+ iaaiStats = new JArithmeticDecoderStats(1 << 9);
+ iadtStats = new JArithmeticDecoderStats(1 << 9);
+ iaitStats = new JArithmeticDecoderStats(1 << 9);
+ iafsStats = new JArithmeticDecoderStats(1 << 9);
+ iadsStats = new JArithmeticDecoderStats(1 << 9);
+ iardxStats = new JArithmeticDecoderStats(1 << 9);
+ iardyStats = new JArithmeticDecoderStats(1 << 9);
+ iardwStats = new JArithmeticDecoderStats(1 << 9);
+ iardhStats = new JArithmeticDecoderStats(1 << 9);
+ iariStats = new JArithmeticDecoderStats(1 << 9);
+ iaidStats = new JArithmeticDecoderStats(1 << 1);
huffDecoder = new JBIG2HuffmanDecoder();
mmrDecoder = new JBIG2MMRDecoder();
@@ -1511,7 +1191,7 @@ int JBIG2Stream::lookChar() {
return EOF;
}
-GString *JBIG2Stream::getPSFilter(char *indent) {
+GString *JBIG2Stream::getPSFilter(int psLevel, char *indent) {
return NULL;
}
@@ -3528,7 +3208,7 @@ void JBIG2Stream::discardSegment(Guint segNum) {
}
void JBIG2Stream::resetGenericStats(Guint templ,
- JBIG2ArithmeticDecoderStats *prevStats) {
+ JArithmeticDecoderStats *prevStats) {
int size;
size = contextSize[templ];
@@ -3544,14 +3224,13 @@ void JBIG2Stream::resetGenericStats(Guint templ,
genericRegionStats->reset();
} else {
delete genericRegionStats;
- genericRegionStats = new JBIG2ArithmeticDecoderStats(size);
+ genericRegionStats = new JArithmeticDecoderStats(1 << size);
}
}
}
-void JBIG2Stream::resetRefinementStats(
- Guint templ,
- JBIG2ArithmeticDecoderStats *prevStats) {
+void JBIG2Stream::resetRefinementStats(Guint templ,
+ JArithmeticDecoderStats *prevStats) {
int size;
size = refContextSize[templ];
@@ -3567,7 +3246,7 @@ void JBIG2Stream::resetRefinementStats(
refinementRegionStats->reset();
} else {
delete refinementRegionStats;
- refinementRegionStats = new JBIG2ArithmeticDecoderStats(size);
+ refinementRegionStats = new JArithmeticDecoderStats(1 << size);
}
}
}
@@ -3590,7 +3269,7 @@ void JBIG2Stream::resetIntStats(int symCodeLen) {
iaidStats->reset();
} else {
delete iaidStats;
- iaidStats = new JBIG2ArithmeticDecoderStats(symCodeLen + 1);
+ iaidStats = new JArithmeticDecoderStats(1 << (symCodeLen + 1));
}
}
diff --git a/pdf/xpdf/JBIG2Stream.h b/pdf/xpdf/JBIG2Stream.h
index 877dd7f..ed26d4e 100644
--- a/pdf/xpdf/JBIG2Stream.h
+++ b/pdf/xpdf/JBIG2Stream.h
@@ -22,8 +22,8 @@
class GList;
class JBIG2Segment;
class JBIG2Bitmap;
-class JBIG2ArithmeticDecoder;
-class JBIG2ArithmeticDecoderStats;
+class JArithmeticDecoder;
+class JArithmeticDecoderStats;
class JBIG2HuffmanDecoder;
struct JBIG2HuffmanTable;
class JBIG2MMRDecoder;
@@ -39,7 +39,7 @@ public:
virtual void reset();
virtual int getChar();
virtual int lookChar();
- virtual GString *getPSFilter(char *indent);
+ virtual GString *getPSFilter(int psLevel, char *indent);
virtual GBool isBinary(GBool last = gTrue);
private:
@@ -99,9 +99,9 @@ private:
JBIG2Segment *findSegment(Guint segNum);
void discardSegment(Guint segNum);
void resetGenericStats(Guint templ,
- JBIG2ArithmeticDecoderStats *prevStats);
+ JArithmeticDecoderStats *prevStats);
void resetRefinementStats(Guint templ,
- JBIG2ArithmeticDecoderStats *prevStats);
+ JArithmeticDecoderStats *prevStats);
void resetIntStats(int symCodeLen);
GBool readUByte(Guint *x);
GBool readByte(int *x);
@@ -119,23 +119,23 @@ private:
Guchar *dataPtr;
Guchar *dataEnd;
- JBIG2ArithmeticDecoder *arithDecoder;
- JBIG2ArithmeticDecoderStats *genericRegionStats;
- JBIG2ArithmeticDecoderStats *refinementRegionStats;
- JBIG2ArithmeticDecoderStats *iadhStats;
- JBIG2ArithmeticDecoderStats *iadwStats;
- JBIG2ArithmeticDecoderStats *iaexStats;
- JBIG2ArithmeticDecoderStats *iaaiStats;
- JBIG2ArithmeticDecoderStats *iadtStats;
- JBIG2ArithmeticDecoderStats *iaitStats;
- JBIG2ArithmeticDecoderStats *iafsStats;
- JBIG2ArithmeticDecoderStats *iadsStats;
- JBIG2ArithmeticDecoderStats *iardxStats;
- JBIG2ArithmeticDecoderStats *iardyStats;
- JBIG2ArithmeticDecoderStats *iardwStats;
- JBIG2ArithmeticDecoderStats *iardhStats;
- JBIG2ArithmeticDecoderStats *iariStats;
- JBIG2ArithmeticDecoderStats *iaidStats;
+ JArithmeticDecoder *arithDecoder;
+ JArithmeticDecoderStats *genericRegionStats;
+ JArithmeticDecoderStats *refinementRegionStats;
+ JArithmeticDecoderStats *iadhStats;
+ JArithmeticDecoderStats *iadwStats;
+ JArithmeticDecoderStats *iaexStats;
+ JArithmeticDecoderStats *iaaiStats;
+ JArithmeticDecoderStats *iadtStats;
+ JArithmeticDecoderStats *iaitStats;
+ JArithmeticDecoderStats *iafsStats;
+ JArithmeticDecoderStats *iadsStats;
+ JArithmeticDecoderStats *iardxStats;
+ JArithmeticDecoderStats *iardyStats;
+ JArithmeticDecoderStats *iardwStats;
+ JArithmeticDecoderStats *iardhStats;
+ JArithmeticDecoderStats *iariStats;
+ JArithmeticDecoderStats *iaidStats;
JBIG2HuffmanDecoder *huffDecoder;
JBIG2MMRDecoder *mmrDecoder;
};
diff --git a/pdf/xpdf/Outline.h b/pdf/xpdf/Outline.h
index 92a9462..f38f8d1 100644
--- a/pdf/xpdf/Outline.h
+++ b/pdf/xpdf/Outline.h
@@ -47,7 +47,8 @@ public:
OutlineItem(Dict *dict, XRef *xrefA);
~OutlineItem();
- static GList *readItemList(Object *itemRef, XRef *xrefA);
+ static GList *readItemList(Object *firstItemRef, Object *lastItemRef,
+ XRef *xrefA);
void open();
void close();
@@ -66,6 +67,7 @@ private:
int titleLen;
LinkAction *action;
Object firstRef;
+ Object lastRef;
Object nextRef;
GBool startsOpen;
GList *kids; // NULL unless this item is open [OutlineItem]
diff --git a/pdf/xpdf/XPDFApp.cc b/pdf/xpdf/XPDFApp.cc
index 5125f5f..34bde23 100644
--- a/pdf/xpdf/XPDFApp.cc
+++ b/pdf/xpdf/XPDFApp.cc
@@ -163,12 +163,20 @@ void XPDFApp::getResources() {
installCmap = (GBool)resources.installCmap;
rgbCubeSize = resources.rgbCubeSize;
reverseVideo = (GBool)resources.reverseVideo;
- paperColor = reverseVideo ? BlackPixel(display, screenNum) :
- WhitePixel(display, screenNum);
+ if (reverseVideo) {
+ paperRGB = splashMakeRGB8(0x00, 0x00, 0x00);
+ paperColor = BlackPixel(display, screenNum);
+ } else {
+ paperRGB = splashMakeRGB8(0xff, 0xff, 0xff);
+ paperColor = WhitePixel(display, screenNum);
+ }
if (resources.paperColor) {
XtVaGetValues(appShell, XmNcolormap, &colormap, NULL);
if (XAllocNamedColor(display, colormap, resources.paperColor,
&xcol, &xcol2)) {
+ paperRGB = splashMakeRGB8(xcol.red >> 8,
+ xcol.green >> 8,
+ xcol.blue >> 8);
paperColor = xcol.pixel;
} else {
error(-1, "Couldn't allocate color '%s'", resources.paperColor);
diff --git a/pdf/xpdf/XPDFApp.h b/pdf/xpdf/XPDFApp.h
index ffe0b63..4e23955 100644
--- a/pdf/xpdf/XPDFApp.h
+++ b/pdf/xpdf/XPDFApp.h
@@ -19,6 +19,7 @@
#include <Xm/XmAll.h>
#undef Object
#include "gtypes.h"
+#include "SplashTypes.h"
class GString;
class GList;
@@ -64,6 +65,7 @@ public:
GBool getInstallCmap() { return installCmap; }
int getRGBCubeSize() { return rgbCubeSize; }
GBool getReverseVideo() { return reverseVideo; }
+ SplashRGB8 getPaperRGB() { return paperRGB; }
Gulong getPaperColor() { return paperColor; }
GString *getInitialZoom() { return initialZoom; }
GBool getViKeys() { return viKeys; }
@@ -96,6 +98,7 @@ private:
GBool installCmap;
int rgbCubeSize;
GBool reverseVideo;
+ SplashRGB8 paperRGB;
Gulong paperColor;
GString *initialZoom;
GBool viKeys;
diff --git a/pdf/xpdf/XPDFCore.cc b/pdf/xpdf/XPDFCore.cc
index d4d8fa6..3b9c21e 100644
--- a/pdf/xpdf/XPDFCore.cc
+++ b/pdf/xpdf/XPDFCore.cc
@@ -25,7 +25,8 @@
#include "GfxState.h"
#include "PSOutputDev.h"
#include "TextOutputDev.h"
-#include "XPixmapOutputDev.h"
+#include "SplashPattern.h"
+#include "XSplashOutputDev.h"
#include "XPDFCore.h"
// these macro defns conflict with xpdf's Object class
@@ -101,9 +102,10 @@ Atom XPDFCore::targetsAtom;
//------------------------------------------------------------------------
XPDFCore::XPDFCore(Widget shellA, Widget parentWidgetA,
- Gulong paperColorA, GBool fullScreenA, GBool reverseVideo,
- GBool installCmap, int rgbCubeSize) {
+ SplashRGB8 paperColorA, GBool fullScreenA,
+ GBool reverseVideo, GBool installCmap, int rgbCubeSize) {
GString *initialZoom;
+ SplashColor paperColor2;
int i;
shell = shellA;
@@ -177,8 +179,9 @@ XPDFCore::XPDFCore(Widget shellA, Widget parentWidgetA,
initWindow();
// create the OutputDev
- out = new XPixmapOutputDev(display, screenNum, visual, colormap,
- reverseVideo, paperColor,
+ paperColor2.rgb8 = paperColor;
+ out = new XSplashOutputDev(display, screenNum, visual, colormap,
+ reverseVideo, paperColor2,
installCmap, rgbCubeSize, gTrue,
&outputDevRedrawCbk, this);
out->startDoc(NULL);
@@ -203,10 +206,6 @@ XPDFCore::~XPDFCore() {
delete history[i].fileName;
}
}
- if (selectGC) {
- XFreeGC(display, selectGC);
- XFreeGC(display, highlightGC);
- }
if (drawAreaGC) {
XFreeGC(display, drawAreaGC);
}
@@ -438,7 +437,6 @@ void XPDFCore::displayPage(int pageA, double zoomA, int rotateA,
int rot;
XPDFHistory *h;
GBool newZoom;
- XGCValues gcValues;
time_t newModTime;
int oldScrollX, oldScrollY;
@@ -467,12 +465,6 @@ void XPDFCore::displayPage(int pageA, double zoomA, int rotateA,
modTime = newModTime;
}
- // free the old GCs
- if (selectGC) {
- XFreeGC(display, selectGC);
- XFreeGC(display, highlightGC);
- }
-
// new page number
page = pageA;
@@ -518,8 +510,7 @@ void XPDFCore::displayPage(int pageA, double zoomA, int rotateA,
} else {
dpi = 0.01 * zoom * 72;
}
- out->setWindow(XtWindow(drawArea));
- doc->displayPage(out, page, dpi, dpi, rotate, gTrue);
+ doc->displayPage(out, page, dpi, dpi, rotate, gTrue, gTrue);
oldScrollX = scrollX;
oldScrollY = scrollY;
updateScrollBars();
@@ -527,15 +518,6 @@ void XPDFCore::displayPage(int pageA, double zoomA, int rotateA,
redrawRectangle(scrollX, scrollY, drawAreaWidth, drawAreaHeight);
}
- // allocate new GCs
- gcValues.foreground = BlackPixel(display, screenNum) ^
- WhitePixel(display, screenNum);
- gcValues.function = GXxor;
- selectGC = XCreateGC(display, out->getPixmap(),
- GCForeground | GCFunction, &gcValues);
- highlightGC = XCreateGC(display, out->getPixmap(),
- GCForeground | GCFunction, &gcValues);
-
// add to history
if (addToHist) {
@@ -651,7 +633,7 @@ void XPDFCore::gotoPrevPage(int dec, GBool top, GBool bottom) {
}
if (page > 1) {
if (!fullScreen && bottom) {
- scrollY = out->getPixmapHeight() - drawAreaHeight;
+ scrollY = out->getBitmapHeight() - drawAreaHeight;
if (scrollY < 0) {
scrollY = 0;
}
@@ -729,7 +711,7 @@ void XPDFCore::scrollPageUp() {
}
void XPDFCore::scrollPageDown() {
- if (scrollY >= out->getPixmapHeight() - drawAreaHeight) {
+ if (scrollY >= out->getBitmapHeight() - drawAreaHeight) {
gotoNextPage(1, gTrue);
} else {
scrollTo(scrollX, scrollY + drawAreaHeight);
@@ -742,7 +724,7 @@ void XPDFCore::scrollTo(int x, int y) {
needRedraw = gFalse;
- maxPos = out ? out->getPixmapWidth() : 1;
+ maxPos = out ? out->getBitmapWidth() : 1;
if (maxPos < drawAreaWidth) {
maxPos = drawAreaWidth;
}
@@ -760,7 +742,7 @@ void XPDFCore::scrollTo(int x, int y) {
needRedraw = gTrue;
}
- maxPos = out ? out->getPixmapHeight() : 1;
+ maxPos = out ? out->getBitmapHeight() : 1;
if (maxPos < drawAreaHeight) {
maxPos = drawAreaHeight;
}
@@ -789,28 +771,26 @@ void XPDFCore::scrollTo(int x, int y) {
void XPDFCore::setSelection(int newXMin, int newYMin,
int newXMax, int newYMax) {
- Pixmap pixmap;
int x, y;
GBool needRedraw, needScroll;
GBool moveLeft, moveRight, moveTop, moveBottom;
-
- pixmap = out->getPixmap();
+ SplashColor xorColor;
// erase old selection on off-screen bitmap
needRedraw = gFalse;
if (selectXMin < selectXMax && selectYMin < selectYMax) {
- XFillRectangle(display, pixmap,
- selectGC, selectXMin, selectYMin,
- selectXMax - selectXMin, selectYMax - selectYMin);
+ xorColor.rgb8 = splashMakeRGB8(0xff, 0xff, 0xff);
+ out->xorRectangle(selectXMin, selectYMin, selectXMax, selectYMax,
+ new SplashSolidColor(xorColor));
needRedraw = gTrue;
}
// draw new selection on off-screen bitmap
if (newXMin < newXMax && newYMin < newYMax) {
- XFillRectangle(display, pixmap,
- selectGC, newXMin, newYMin,
- newXMax - newXMin, newYMax - newYMin);
+ xorColor.rgb8 = splashMakeRGB8(0xff, 0xff, 0xff);
+ out->xorRectangle(newXMin, newYMin, newXMax, newYMax,
+ new SplashSolidColor(xorColor));
needRedraw = gTrue;
}
@@ -898,13 +878,13 @@ void XPDFCore::moveSelection(int mx, int my) {
// clip mouse coords
if (mx < 0) {
mx = 0;
- } else if (mx >= out->getPixmapWidth()) {
- mx = out->getPixmapWidth() - 1;
+ } else if (mx >= out->getBitmapWidth()) {
+ mx = out->getBitmapWidth() - 1;
}
if (my < 0) {
my = 0;
- } else if (my >= out->getPixmapHeight()) {
- my = out->getPixmapHeight() - 1;
+ } else if (my >= out->getBitmapHeight()) {
+ my = out->getBitmapHeight() - 1;
}
// move appropriate edges of selection
@@ -1036,7 +1016,7 @@ GString *XPDFCore::extractText(int pageNum,
delete textOut;
return NULL;
}
- doc->displayPage(textOut, pageNum, dpi, dpi, rotate, gFalse);
+ doc->displayPage(textOut, pageNum, dpi, dpi, rotate, gTrue, gFalse);
s = textOut->getText(xMin, yMin, xMax, yMax);
delete textOut;
return s;
@@ -1358,7 +1338,7 @@ void XPDFCore::find(char *s, GBool next) {
goto done;
}
for (pg = page+1; pg <= doc->getNumPages(); ++pg) {
- doc->displayPage(textOut, pg, 72, 72, 0, gFalse);
+ doc->displayPage(textOut, pg, 72, 72, 0, gTrue, gFalse);
if (textOut->findText(u, len, gTrue, gTrue, gFalse, gFalse,
&xMin1, &yMin1, &xMax1, &yMax1)) {
goto foundPage;
@@ -1367,7 +1347,7 @@ void XPDFCore::find(char *s, GBool next) {
// search previous pages
for (pg = 1; pg < page; ++pg) {
- doc->displayPage(textOut, pg, 72, 72, 0, gFalse);
+ doc->displayPage(textOut, pg, 72, 72, 0, gTrue, gFalse);
if (textOut->findText(u, len, gTrue, gTrue, gFalse, gFalse,
&xMin1, &yMin1, &xMax1, &yMax1)) {
goto foundPage;
@@ -1491,7 +1471,6 @@ void XPDFCore::initWindow() {
XtManageChild(drawAreaFrame);
n = 0;
XtSetArg(args[n], XmNresizePolicy, XmRESIZE_ANY); ++n;
- XtSetArg(args[n], XmNbackground, paperColor); ++n;
XtSetArg(args[n], XmNwidth, 700); ++n;
XtSetArg(args[n], XmNheight, 500); ++n;
drawArea = XmCreateDrawingArea(drawAreaFrame, "drawArea", args, n);
@@ -1510,8 +1489,6 @@ void XPDFCore::initWindow() {
// can't create a GC until the window gets mapped
drawAreaGC = NULL;
- selectGC = NULL;
- highlightGC = NULL;
}
void XPDFCore::hScrollChangeCbk(Widget widget, XtPointer ptr,
@@ -1641,18 +1618,18 @@ void XPDFCore::inputCbk(Widget widget, XtPointer ptr, XtPointer callData) {
} else if (data->event->xbutton.button == 5) { // mouse wheel down
if (core->fullScreen ||
core->scrollY >=
- core->out->getPixmapHeight() - core->drawAreaHeight) {
+ core->out->getBitmapHeight() - core->drawAreaHeight) {
core->gotoNextPage(1, gTrue);
} else {
core->scrollDown(1);
}
- } else if (data->event->xbutton.button == 6) { // second mouse wheel right
+ } else if (data->event->xbutton.button == 6) { // second mouse wheel left
if (!core->fullScreen) {
- core->scrollRight(1);
+ core->scrollLeft(1);
}
- } else if (data->event->xbutton.button == 7) { // second mouse wheel left
+ } else if (data->event->xbutton.button == 7) { // second mouse wheel right
if (!core->fullScreen) {
- core->scrollLeft(1);
+ core->scrollRight(1);
}
} else {
if (*core->mouseCbk) {
@@ -1776,8 +1753,8 @@ void XPDFCore::keyPress(char *s, KeySym key, Guint modifiers) {
if (modifiers & ControlMask) {
displayPage(doc->getNumPages(), zoom, rotate, gTrue, gTrue);
} else if (!fullScreen) {
- scrollTo(out->getPixmapWidth() - drawAreaWidth,
- out->getPixmapHeight() - drawAreaHeight);
+ scrollTo(out->getBitmapWidth() - drawAreaWidth,
+ out->getBitmapHeight() - drawAreaHeight);
}
return;
case XK_Page_Up:
@@ -1855,23 +1832,22 @@ void XPDFCore::redrawRectangle(int x, int y, int w, int h) {
}
// draw white background past the edges of the document
- if (x + w > out->getPixmapWidth()) {
+ if (x + w > out->getBitmapWidth()) {
XFillRectangle(display, drawAreaWin, drawAreaGC,
- out->getPixmapWidth() - scrollX, y - scrollY,
- x + w - out->getPixmapWidth(), h);
- w = out->getPixmapWidth() - x;
+ out->getBitmapWidth() - scrollX, y - scrollY,
+ x + w - out->getBitmapWidth(), h);
+ w = out->getBitmapWidth() - x;
}
- if (y + h > out->getPixmapHeight()) {
+ if (y + h > out->getBitmapHeight()) {
XFillRectangle(display, drawAreaWin, drawAreaGC,
- x - scrollX, out->getPixmapHeight() - scrollY,
- w, y + h - out->getPixmapHeight());
- h = out->getPixmapHeight() - y;
+ x - scrollX, out->getBitmapHeight() - scrollY,
+ w, y + h - out->getBitmapHeight());
+ h = out->getBitmapHeight() - y;
}
- // redraw (checking to see if pixmap has been allocated yet)
- if (out->getPixmapWidth() > 0) {
- XCopyArea(display, out->getPixmap(), drawAreaWin, drawAreaGC,
- x, y, w, h, x - scrollX, y - scrollY);
+ // redraw
+ if (w >= 0 && h >= 0) {
+ out->redraw(x, y, drawAreaWin, drawAreaGC, x - scrollX, y - scrollY, w, h);
}
}
@@ -1880,7 +1856,7 @@ void XPDFCore::updateScrollBars() {
int n;
int maxPos;
- maxPos = out ? out->getPixmapWidth() : 1;
+ maxPos = out ? out->getBitmapWidth() : 1;
if (maxPos < drawAreaWidth) {
maxPos = drawAreaWidth;
}
@@ -1895,7 +1871,7 @@ void XPDFCore::updateScrollBars() {
XtSetArg(args[n], XmNpageIncrement, drawAreaWidth); ++n;
XtSetValues(hScrollBar, args, n);
- maxPos = out ? out->getPixmapHeight() : 1;
+ maxPos = out ? out->getBitmapHeight() : 1;
if (maxPos < drawAreaHeight) {
maxPos = drawAreaHeight;
}
diff --git a/pdf/xpdf/XPDFCore.h b/pdf/xpdf/XPDFCore.h
index 4878c4f..59fc19c 100644
--- a/pdf/xpdf/XPDFCore.h
+++ b/pdf/xpdf/XPDFCore.h
@@ -21,6 +21,7 @@
#include <aconf.h>
#include "gtypes.h"
#include "gfile.h" // for time_t
+#include "SplashTypes.h"
class GString;
class GList;
@@ -28,7 +29,7 @@ class BaseStream;
class PDFDoc;
class LinkAction;
class LinkDest;
-class XPixmapOutputDev;
+class XSplashOutputDev;
//------------------------------------------------------------------------
// zoom factor
@@ -56,8 +57,8 @@ struct XPDFHistory {
struct XPDFRegion {
int page;
double xMin, yMin, xMax, yMax;
- Gulong color;
- Gulong selectColor;
+ SplashRGB8 color;
+ SplashRGB8 selectColor;
GBool selectable;
};
@@ -86,8 +87,8 @@ public:
// Create viewer core inside <parentWidgetA>.
XPDFCore(Widget shellA, Widget parentWidgetA,
- Gulong paperColorA, GBool fullScreenA, GBool reverseVideo,
- GBool installCmap, int rgbCubeSize);
+ SplashRGB8 paperColorA, GBool fullScreenA,
+ GBool reverseVideo, GBool installCmap, int rgbCubeSize);
~XPDFCore();
@@ -162,7 +163,7 @@ public:
Widget getWidget() { return scrolledWin; }
Widget getDrawAreaWidget() { return drawArea; }
PDFDoc *getDoc() { return doc; }
- XPixmapOutputDev *getOutputDev() { return out; }
+ XSplashOutputDev *getOutputDev() { return out; }
int getPageNum() { return page; }
double getZoom() { return zoom; }
double getZoomDPI() { return dpi; }
@@ -228,7 +229,7 @@ private:
static void dialogCancelCbk(Widget widget, XtPointer ptr,
XtPointer callData);
- Gulong paperColor;
+ SplashRGB8 paperColor;
GBool fullScreen;
Display *display;
@@ -245,8 +246,6 @@ private:
Cursor busyCursor, linkCursor, selectCursor;
Cursor currentCursor;
GC drawAreaGC; // GC for blitting into drawArea
- GC selectGC;
- GC highlightGC;
int drawAreaWidth, drawAreaHeight;
int scrollX, scrollY; // current upper-left corner
@@ -296,7 +295,7 @@ private:
GBool hyperlinksEnabled;
GBool selectEnabled;
- XPixmapOutputDev *out;
+ XSplashOutputDev *out;
int dialogDone;
};
diff --git a/pdf/xpdf/XPDFViewer.cc b/pdf/xpdf/XPDFViewer.cc
index 56fb7b5..b7e5532 100644
--- a/pdf/xpdf/XPDFViewer.cc
+++ b/pdf/xpdf/XPDFViewer.cc
@@ -41,7 +41,6 @@
#endif
#include "XPDFApp.h"
#include "XPDFViewer.h"
-#include "XPixmapOutputDev.h"
#include "PSOutputDev.h"
#include "config.h"
@@ -796,7 +795,7 @@ void XPDFViewer::initWindow() {
n = 0;
XtSetArg(args[n], XmNleftAttachment, XmATTACH_WIDGET); ++n;
XtSetArg(args[n], XmNleftWidget, lastBtn); ++n;
- XtSetArg(args[n], XmNrightAttachment, XmATTACH_FORM); ++n;
+ XtSetArg(args[n], XmNrightAttachment, XmATTACH_WIDGET); ++n;
XtSetArg(args[n], XmNrightWidget, quitBtn); ++n;
XtSetArg(args[n], XmNtopAttachment, XmATTACH_FORM); ++n;
XtSetArg(args[n], XmNbottomAttachment, XmATTACH_FORM); ++n;
@@ -813,7 +812,7 @@ void XPDFViewer::initWindow() {
#endif
// core
- core = new XPDFCore(win, form, app->getPaperColor(),
+ core = new XPDFCore(win, form, app->getPaperRGB(),
app->getFullScreen(), app->getReverseVideo(),
app->getInstallCmap(), app->getRGBCubeSize());
core->setUpdateCbk(&updateCbk, this);
@@ -871,7 +870,7 @@ void XPDFViewer::initWindow() {
(XtPointer)this);
// core
- core = new XPDFCore(win, panedWin, app->getPaperColor(),
+ core = new XPDFCore(win, panedWin, app->getPaperRGB(),
app->getFullScreen(), app->getReverseVideo(),
app->getInstallCmap(), app->getRGBCubeSize());
core->setUpdateCbk(&updateCbk, this);
@@ -1879,7 +1878,7 @@ void XPDFViewer::openOkCbk(Widget widget, XtPointer ptr,
//------------------------------------------------------------------------
void XPDFViewer::initFindDialog() {
- Widget row1, label, okBtn, closeBtn;
+ Widget form1, label, okBtn, closeBtn;
Arg args[20];
int n;
XmString s;
@@ -1893,31 +1892,8 @@ void XPDFViewer::initFindDialog() {
findDialog = XmCreateFormDialog(win, "findDialog", args, n);
XmStringFree(s);
- //----- top row: search string entry
- n = 0;
- XtSetArg(args[n], XmNtopAttachment, XmATTACH_FORM); ++n;
- XtSetArg(args[n], XmNtopOffset, 4); ++n;
- XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); ++n;
- XtSetArg(args[n], XmNrightAttachment, XmATTACH_FORM); ++n;
- XtSetArg(args[n], XmNorientation, XmHORIZONTAL); ++n;
- XtSetArg(args[n], XmNpacking, XmPACK_TIGHT); ++n;
- row1 = XmCreateRowColumn(findDialog, "row1", args, n);
- XtManageChild(row1);
- n = 0;
- s = XmStringCreateLocalized("Find text: ");
- XtSetArg(args[n], XmNlabelString, s); ++n;
- label = XmCreateLabel(row1, "label", args, n);
- XmStringFree(s);
- XtManageChild(label);
- n = 0;
- XtSetArg(args[n], XmNnavigationType, XmEXCLUSIVE_TAB_GROUP); ++n;
- findText = XmCreateTextField(row1, "text", args, n);
- XtManageChild(findText);
-
//----- "find" and "close" buttons
n = 0;
- XtSetArg(args[n], XmNtopAttachment, XmATTACH_WIDGET); ++n;
- XtSetArg(args[n], XmNtopWidget, row1); ++n;
XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); ++n;
XtSetArg(args[n], XmNleftOffset, 4); ++n;
XtSetArg(args[n], XmNbottomAttachment, XmATTACH_FORM); ++n;
@@ -1928,8 +1904,6 @@ void XPDFViewer::initFindDialog() {
XtAddCallback(okBtn, XmNactivateCallback,
&findFindCbk, (XtPointer)this);
n = 0;
- XtSetArg(args[n], XmNtopAttachment, XmATTACH_WIDGET); ++n;
- XtSetArg(args[n], XmNtopWidget, row1); ++n;
XtSetArg(args[n], XmNrightAttachment, XmATTACH_FORM); ++n;
XtSetArg(args[n], XmNrightOffset, 4); ++n;
XtSetArg(args[n], XmNbottomAttachment, XmATTACH_FORM); ++n;
@@ -1939,6 +1913,42 @@ void XPDFViewer::initFindDialog() {
XtManageChild(closeBtn);
XtAddCallback(closeBtn, XmNactivateCallback,
&findCloseCbk, (XtPointer)this);
+
+ //----- search string entry
+ n = 0;
+ XtSetArg(args[n], XmNtopAttachment, XmATTACH_FORM); ++n;
+ XtSetArg(args[n], XmNtopOffset, 4); ++n;
+ XtSetArg(args[n], XmNbottomAttachment, XmATTACH_WIDGET); ++n;
+ XtSetArg(args[n], XmNbottomWidget, okBtn); ++n;
+ XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); ++n;
+ XtSetArg(args[n], XmNleftOffset, 2); ++n;
+ XtSetArg(args[n], XmNrightAttachment, XmATTACH_FORM); ++n;
+ XtSetArg(args[n], XmNrightOffset, 2); ++n;
+ form1 = XmCreateForm(findDialog, "form", args, n);
+ XtManageChild(form1);
+ n = 0;
+ XtSetArg(args[n], XmNtopAttachment, XmATTACH_FORM); ++n;
+ XtSetArg(args[n], XmNbottomAttachment, XmATTACH_FORM); ++n;
+ XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); ++n;
+ s = XmStringCreateLocalized("Find text: ");
+ XtSetArg(args[n], XmNlabelString, s); ++n;
+ label = XmCreateLabel(form1, "label", args, n);
+ XmStringFree(s);
+ XtManageChild(label);
+ n = 0;
+ XtSetArg(args[n], XmNtopAttachment, XmATTACH_FORM); ++n;
+ XtSetArg(args[n], XmNbottomAttachment, XmATTACH_FORM); ++n;
+ XtSetArg(args[n], XmNleftAttachment, XmATTACH_WIDGET); ++n;
+ XtSetArg(args[n], XmNleftWidget, label); ++n;
+ XtSetArg(args[n], XmNrightAttachment, XmATTACH_FORM); ++n;
+ findText = XmCreateTextField(form1, "text", args, n);
+ XtManageChild(findText);
+#ifdef LESSTIF_VERSION
+ XtAddCallback(findText, XmNactivateCallback,
+ &findFindCbk, (XtPointer)this);
+#endif
+
+ //----- dialog parameters
n = 0;
XtSetArg(args[n], XmNdefaultButton, okBtn); ++n;
XtSetArg(args[n], XmNcancelButton, closeBtn); ++n;
@@ -2307,7 +2317,8 @@ void XPDFViewer::printPrintCbk(Widget widget, XtPointer ptr,
doc->getCatalog(), firstPage, lastPage,
psModePS);
if (psOut->isOk()) {
- doc->displayPages(psOut, firstPage, lastPage, 72, 72, 0, gFalse);
+ doc->displayPages(psOut, firstPage, lastPage, 72, 72,
+ 0, globalParams->getPSCrop(), gFalse);
}
delete psOut;
delete psFileName;
diff --git a/pdf/xpdf/about-text.h b/pdf/xpdf/about-text.h
index 172e39f..54925ce 100644
--- a/pdf/xpdf/about-text.h
+++ b/pdf/xpdf/about-text.h
@@ -16,7 +16,7 @@ static char *aboutWinText[] = {
"Supports PDF version " supportedPDFVersionStr ".",
" ",
"The PDF data structures, operators, and specification",
- "are copyright 1985-2001 Adobe Systems Inc.",
+ "are copyright 1985-2003 Adobe Systems Inc.",
" ",
"Mouse bindings:",
" button 1: select text / follow link",