From bfd0b848c8c81ab10698f74b77f9f0904c3161e1 Mon Sep 17 00:00:00 2001 From: Martin Kretzschmar Date: Tue, 01 Apr 2003 08:50:28 +0000 Subject: Import of Xpdf 2.02 for merge --- (limited to 'pdf/xpdf') diff --git a/pdf/xpdf/BuiltinFontTables.h b/pdf/xpdf/BuiltinFontTables.h index 3a8892e..eb45549 100644 --- a/pdf/xpdf/BuiltinFontTables.h +++ b/pdf/xpdf/BuiltinFontTables.h @@ -2,7 +2,7 @@ // // BuiltinFontTables.h // -// Copyright 2001-2002 Glyph & Cog, LLC +// Copyright 2001-2003 Glyph & Cog, LLC // //======================================================================== diff --git a/pdf/xpdf/CharTypes.h b/pdf/xpdf/CharTypes.h index bae2f26..d0df630 100644 --- a/pdf/xpdf/CharTypes.h +++ b/pdf/xpdf/CharTypes.h @@ -2,7 +2,7 @@ // // CharTypes.h // -// Copyright 2001-2002 Glyph & Cog, LLC +// Copyright 2001-2003 Glyph & Cog, LLC // //======================================================================== diff --git a/pdf/xpdf/CompactFontTables.h b/pdf/xpdf/CompactFontTables.h index 62d6f5a..28e16e7 100644 --- a/pdf/xpdf/CompactFontTables.h +++ b/pdf/xpdf/CompactFontTables.h @@ -2,7 +2,7 @@ // // CompactFontTables.h // -// Copyright 1999-2002 Glyph & Cog, LLC +// Copyright 1999-2003 Glyph & Cog, LLC // //======================================================================== diff --git a/pdf/xpdf/DisplayFontTable.h b/pdf/xpdf/DisplayFontTable.h index 4606031..3c2379f 100644 --- a/pdf/xpdf/DisplayFontTable.h +++ b/pdf/xpdf/DisplayFontTable.h @@ -2,7 +2,7 @@ // // DisplayFontTable.h // -// Copyright 2001-2002 Glyph & Cog, LLC +// Copyright 2001-2003 Glyph & Cog, LLC // //======================================================================== diff --git a/pdf/xpdf/ErrorCodes.h b/pdf/xpdf/ErrorCodes.h index 4e0d38a..8de2b01 100644 --- a/pdf/xpdf/ErrorCodes.h +++ b/pdf/xpdf/ErrorCodes.h @@ -2,7 +2,7 @@ // // ErrorCodes.h // -// Copyright 2002 Glyph & Cog, LLC +// Copyright 2002-2003 Glyph & Cog, LLC // //======================================================================== @@ -21,4 +21,6 @@ #define errEncrypted 4 // file was encrypted and password was // incorrect or not supplied +#define errHighlightFile 5 // nonexistent or invalid highlight file + #endif diff --git a/pdf/xpdf/FontEncodingTables.h b/pdf/xpdf/FontEncodingTables.h index deee0a8..8b0a1e7 100644 --- a/pdf/xpdf/FontEncodingTables.h +++ b/pdf/xpdf/FontEncodingTables.h @@ -2,7 +2,7 @@ // // FontEncodingTables.h // -// Copyright 2001-2002 Glyph & Cog, LLC +// Copyright 2001-2003 Glyph & Cog, LLC // //======================================================================== diff --git a/pdf/xpdf/JBIG2Stream.cc b/pdf/xpdf/JBIG2Stream.cc index 716fee1..8363362 100644 --- a/pdf/xpdf/JBIG2Stream.cc +++ b/pdf/xpdf/JBIG2Stream.cc @@ -2,7 +2,7 @@ // // JBIG2Stream.cc // -// Copyright 2002 Glyph & Cog, LLC +// Copyright 2002-2003 Glyph & Cog, LLC // //======================================================================== @@ -655,25 +655,22 @@ GBool JBIG2HuffmanDecoder::decodeInt(int *x, JBIG2HuffmanTable *table) { len = 0; prefix = 0; while (table[i].rangeLen != jbig2HuffmanEOT) { - //~ if buildTable removes the entries with prefixLen=0, this is unneeded - if (table[i].prefixLen > 0) { - while (len < table[i].prefixLen) { - prefix = (prefix << 1) | readBit(); - ++len; + while (len < table[i].prefixLen) { + prefix = (prefix << 1) | readBit(); + ++len; + } + if (prefix == table[i].prefix) { + if (table[i].rangeLen == jbig2HuffmanOOB) { + return gFalse; } - if (prefix == table[i].prefix) { - if (table[i].rangeLen == jbig2HuffmanOOB) { - return gFalse; - } - if (table[i].rangeLen == jbig2HuffmanLOW) { - *x = table[i].val - readBits(32); - } else if (table[i].rangeLen > 0) { - *x = table[i].val + readBits(table[i].rangeLen); - } else { - *x = table[i].val; - } - return gTrue; + if (table[i].rangeLen == jbig2HuffmanLOW) { + *x = table[i].val - readBits(32); + } else if (table[i].rangeLen > 0) { + *x = table[i].val + readBits(table[i].rangeLen); + } else { + *x = table[i].val; } + return gTrue; } ++i; } @@ -713,22 +710,41 @@ Guint JBIG2HuffmanDecoder::readBit() { return (buf >> bufLen) & 1; } -static int cmpHuffmanTabEntries(const void *p1, const void *p2) { - return ((JBIG2HuffmanTable *)p1)->prefixLen - - ((JBIG2HuffmanTable *)p2)->prefixLen; -} - -//~ should remove entries with prefixLen = 0 void JBIG2HuffmanDecoder::buildTable(JBIG2HuffmanTable *table, Guint len) { - Guint i, prefix; - - qsort(table, len, sizeof(JBIG2HuffmanTable), &cmpHuffmanTabEntries); - for (i = 0; i < len && table[i].prefixLen == 0; ++i) { - table[i].prefix = 0; + Guint i, j, k, prefix; + JBIG2HuffmanTable tab; + + // stable selection sort: + // - entries with prefixLen > 0, in ascending prefixLen order + // - entry with prefixLen = 0, rangeLen = EOT + // - all other entries with prefixLen = 0 + // (on entry, table[len] has prefixLen = 0, rangeLen = EOT) + for (i = 0; i < len; ++i) { + for (j = i; j < len && table[j].prefixLen == 0; ++j) ; + if (j == len) { + break; + } + for (k = j + 1; k < len; ++k) { + if (table[k].prefixLen > 0 && + table[k].prefixLen < table[j].prefixLen) { + j = k; + } + } + if (j != i) { + tab = table[j]; + for (k = j; k > i; --k) { + table[k] = table[k - 1]; + } + table[i] = tab; + } } + table[i] = table[len]; + + // assign prefixes + i = 0; prefix = 0; table[i++].prefix = prefix++; - for (; i < len; ++i) { + for (; table[i].rangeLen != jbig2HuffmanEOT; ++i) { prefix <<= table[i].prefixLen - table[i-1].prefixLen; table[i].prefix = prefix++; } @@ -810,7 +826,7 @@ int JBIG2MMRDecoder::getWhiteCode() { ++nBytesRead; } while (1) { - if (bufLen > 7 && ((buf >> (bufLen - 7)) & 0x7f) == 0) { + if (bufLen >= 7 && ((buf >> (bufLen - 7)) & 0x7f) == 0) { if (bufLen <= 12) { code = buf << (12 - bufLen); } else { @@ -825,7 +841,7 @@ int JBIG2MMRDecoder::getWhiteCode() { } p = &whiteTab2[code & 0x1ff]; } - if (p->bits > 0 && p->bits < (int)bufLen) { + if (p->bits > 0 && p->bits <= (int)bufLen) { bufLen -= p->bits; return p->n; } @@ -853,14 +869,14 @@ int JBIG2MMRDecoder::getBlackCode() { ++nBytesRead; } while (1) { - if (bufLen > 6 && ((buf >> (bufLen - 6)) & 0x3f) == 0) { + if (bufLen >= 6 && ((buf >> (bufLen - 6)) & 0x3f) == 0) { if (bufLen <= 13) { code = buf << (13 - bufLen); } else { code = buf >> (bufLen - 13); } p = &blackTab1[code & 0x7f]; - } else if (bufLen > 4 && ((buf >> (bufLen - 4)) & 0x0f) == 0) { + } else if (bufLen >= 4 && ((buf >> (bufLen - 4)) & 0x0f) == 0) { if (bufLen <= 12) { code = buf << (12 - bufLen); } else { @@ -875,7 +891,7 @@ int JBIG2MMRDecoder::getBlackCode() { } p = &blackTab3[code & 0x3f]; } - if (p->bits > 0 && p->bits < (int)bufLen) { + if (p->bits > 0 && p->bits <= (int)bufLen) { bufLen -= p->bits; return p->n; } @@ -938,6 +954,12 @@ private: // JBIG2Bitmap //------------------------------------------------------------------------ +struct JBIG2BitmapPtr { + Guchar *p; + int shift; + int x; +}; + class JBIG2Bitmap: public JBIG2Segment { public: @@ -958,6 +980,8 @@ public: { data[y * line + (x >> 3)] |= 1 << (7 - (x & 7)); } void clearPixel(int x, int y) { data[y * line + (x >> 3)] &= 0x7f7f >> (x & 7); } + void getPixelPtr(int x, int y, JBIG2BitmapPtr *ptr); + int nextPixel(JBIG2BitmapPtr *ptr); void duplicateRow(int yDest, int ySrc); void combine(JBIG2Bitmap *bitmap, int x, int y, Guint combOp); Guchar *getDataPtr() { return data; } @@ -1032,6 +1056,42 @@ void JBIG2Bitmap::clearToOne() { memset(data, 0xff, h * line); } +inline void JBIG2Bitmap::getPixelPtr(int x, int y, JBIG2BitmapPtr *ptr) { + if (y < 0 || y >= h || x >= w) { + ptr->p = NULL; + } else if (x < 0) { + ptr->p = &data[y * line]; + ptr->shift = 7; + ptr->x = x; + } else { + ptr->p = &data[y * line + (x >> 3)]; + ptr->shift = 7 - (x & 7); + ptr->x = x; + } +} + +inline int JBIG2Bitmap::nextPixel(JBIG2BitmapPtr *ptr) { + int pix; + + if (!ptr->p) { + pix = 0; + } else if (ptr->x < 0) { + ++ptr->x; + pix = 0; + } else { + pix = (*ptr->p >> ptr->shift) & 1; + if (++ptr->x == w) { + ptr->p = NULL; + } else if (ptr->shift == 0) { + ++ptr->p; + ptr->shift = 7; + } else { + --ptr->shift; + } + } + return pix; +} + void JBIG2Bitmap::duplicateRow(int yDest, int ySrc) { memcpy(data + yDest * line, data + ySrc * line, line); } @@ -1365,7 +1425,7 @@ JBIG2Stream::JBIG2Stream(Stream *strA, Object *globalsStream): huffDecoder = new JBIG2HuffmanDecoder(); mmrDecoder = new JBIG2MMRDecoder(); - segments = new GList(); + segments = globalSegments = new GList(); if (globalsStream->isStream()) { curStr = globalsStream->getStream(); curStr->reset(); @@ -1374,7 +1434,6 @@ JBIG2Stream::JBIG2Stream(Stream *strA, Object *globalsStream): mmrDecoder->setStream(curStr); readSegments(); } - globalSegments = segments; segments = NULL; curStr = NULL; @@ -1768,20 +1827,23 @@ void JBIG2Stream::readSymbolDictSeg(Guint segNum, Guint length, } else { if (contextUsed && inputSymbolDict) { resetGenericStats(sdTemplate, inputSymbolDict->getGenericRegionStats()); - if (refAgg) { - resetRefinementStats(sdrTemplate, - inputSymbolDict->getRefinementRegionStats()); - } } else { resetGenericStats(sdTemplate, NULL); - if (refAgg) { - resetRefinementStats(sdrTemplate, NULL); - } } resetIntStats(symCodeLen); arithDecoder->start(); } + // set up the arithmetic decoder for refinement/aggregation + if (refAgg) { + if (contextUsed && inputSymbolDict) { + resetRefinementStats(sdrTemplate, + inputSymbolDict->getRefinementRegionStats()); + } else { + resetRefinementStats(sdrTemplate, NULL); + } + } + // allocate symbol widths storage symWidths = NULL; if (huff && !refAgg) { @@ -1834,7 +1896,13 @@ void JBIG2Stream::readSymbolDictSeg(Guint segNum, Guint length, break; } } +#if 0 //~ This special case was added about a year before the final draft + //~ of the JBIG2 spec was released. I have encountered some old + //~ JBIG2 images that predate it. + if (0) { +#else if (refAggNum == 1) { +#endif if (huff) { symID = huffDecoder->readBits(symCodeLen); huffDecoder->decodeInt(&refDX, huffTableO); @@ -1878,15 +1946,13 @@ void JBIG2Stream::readSymbolDictSeg(Guint segNum, Guint length, // read the collective bitmap if (huff && !refAgg) { huffDecoder->decodeInt(&bmSize, huffBMSizeTable); - if (huff) { - huffDecoder->reset(); - } + huffDecoder->reset(); if (bmSize == 0) { collBitmap = new JBIG2Bitmap(0, totalWidth, symHeight); bmSize = symHeight * ((totalWidth + 7) >> 3); p = collBitmap->getDataPtr(); for (k = 0; k < (Guint)bmSize; ++k) { - *p++ = str->getChar(); + *p++ = curStr->getChar(); } } else { collBitmap = readGenericBitmap(gTrue, totalWidth, symHeight, @@ -1924,7 +1990,7 @@ void JBIG2Stream::readSymbolDictSeg(Guint segNum, Guint length, } ex = !ex; } - + for (i = 0; i < numNewSyms; ++i) { delete bitmaps[numInputSyms + i]; } @@ -1965,7 +2031,8 @@ void JBIG2Stream::readTextRegionSeg(Guint segNum, GBool imm, JBIG2Bitmap **syms; Guint w, h, x, y, segInfoFlags, extCombOp; Guint flags, huff, refine, logStrips, refCorner, transposed; - Guint combOp, defPixel, sOffset, templ; + Guint combOp, defPixel, templ; + int sOffset; Guint huffFlags, huffFS, huffDS, huffDT; Guint huffRDW, huffRDH, huffRDX, huffRDY, huffRSize; Guint numInstances, numSyms, symCodeLen; @@ -1993,6 +2060,9 @@ void JBIG2Stream::readTextRegionSeg(Guint segNum, GBool imm, combOp = (flags >> 7) & 3; defPixel = (flags >> 9) & 1; sOffset = (flags >> 10) & 0x1f; + if (sOffset & 0x10) { + sOffset |= -1 - 0x0f; + } templ = (flags >> 15) & 1; huffFS = huffDS = huffDT = 0; // make gcc happy huffRDW = huffRDH = huffRDX = huffRDY = huffRSize = 0; // make gcc happy @@ -2135,6 +2205,7 @@ void JBIG2Stream::readTextRegionSeg(Guint segNum, GBool imm, runLengthTab[34].val = 0x20b; runLengthTab[34].prefixLen = huffDecoder->readBits(4); runLengthTab[34].rangeLen = 7; + runLengthTab[35].prefixLen = 0; runLengthTab[35].rangeLen = jbig2HuffmanEOT; huffDecoder->buildTable(runLengthTab, 35); symCodeTab = (JBIG2HuffmanTable *)gmalloc((numSyms + 1) * @@ -2158,8 +2229,8 @@ void JBIG2Stream::readTextRegionSeg(Guint segNum, GBool imm, } else { symCodeTab[i++].prefixLen = j; } - } + symCodeTab[numSyms].prefixLen = 0; symCodeTab[numSyms].rangeLen = jbig2HuffmanEOT; huffDecoder->buildTable(symCodeTab, numSyms); huffDecoder->reset(); @@ -2168,11 +2239,11 @@ void JBIG2Stream::readTextRegionSeg(Guint segNum, GBool imm, } else { symCodeTab = NULL; resetIntStats(symCodeLen); - if (refine) { - resetRefinementStats(templ, NULL); - } arithDecoder->start(); } + if (refine) { + resetRefinementStats(templ, NULL); + } bitmap = readTextRegion(huff, refine, w, h, numInstances, logStrips, numSyms, symCodeTab, symCodeLen, syms, @@ -2219,7 +2290,7 @@ JBIG2Bitmap *JBIG2Stream::readTextRegion(GBool huff, GBool refine, JBIG2Bitmap **syms, Guint defPixel, Guint combOp, Guint transposed, Guint refCorner, - Guint sOffset, + int sOffset, JBIG2HuffmanTable *huffFSTable, JBIG2HuffmanTable *huffDSTable, JBIG2HuffmanTable *huffDTTable, @@ -2686,6 +2757,8 @@ JBIG2Bitmap *JBIG2Stream::readGenericBitmap(GBool mmr, int w, int h, JBIG2Bitmap *bitmap; GBool ltp; Guint ltpCX, cx, cx0, cx1, cx2; + JBIG2BitmapPtr cxPtr0, cxPtr1; + JBIG2BitmapPtr atPtr0, atPtr1, atPtr2, atPtr3; int *refLine, *codingLine; int code1, code2, code3; int x, y, a0, pix, i, refI, codingI; @@ -2880,99 +2953,151 @@ JBIG2Bitmap *JBIG2Stream::readGenericBitmap(GBool mmr, int w, int h, } } - // set up the context switch (templ) { case 0: - cx0 = (bitmap->getPixel(0, y-2) << 1) | - bitmap->getPixel(1, y-2); - cx1 = (bitmap->getPixel(0, y-1) << 2) | - (bitmap->getPixel(1, y-1) << 1) | - bitmap->getPixel(2, y-1); + + // set up the context + bitmap->getPixelPtr(0, y-2, &cxPtr0); + cx0 = bitmap->nextPixel(&cxPtr0); + cx0 = (cx0 << 1) | bitmap->nextPixel(&cxPtr0); + bitmap->getPixelPtr(0, y-1, &cxPtr1); + cx1 = bitmap->nextPixel(&cxPtr1); + cx1 = (cx1 << 1) | bitmap->nextPixel(&cxPtr1); + cx1 = (cx1 << 1) | bitmap->nextPixel(&cxPtr1); cx2 = 0; + bitmap->getPixelPtr(atx[0], y + aty[0], &atPtr0); + bitmap->getPixelPtr(atx[1], y + aty[1], &atPtr1); + bitmap->getPixelPtr(atx[2], y + aty[2], &atPtr2); + bitmap->getPixelPtr(atx[3], y + aty[3], &atPtr3); + + // decode the row + for (x = 0; x < w; ++x) { + + // build the context + cx = (cx0 << 13) | (cx1 << 8) | (cx2 << 4) | + (bitmap->nextPixel(&atPtr0) << 3) | + (bitmap->nextPixel(&atPtr1) << 2) | + (bitmap->nextPixel(&atPtr2) << 1) | + bitmap->nextPixel(&atPtr3); + + // check for a skipped pixel + if (useSkip && skip->getPixel(x, y)) { + pix = 0; + + // decode the pixel + } else if ((pix = arithDecoder->decodeBit(cx, genericRegionStats))) { + bitmap->setPixel(x, y); + } + + // update the context + cx0 = ((cx0 << 1) | bitmap->nextPixel(&cxPtr0)) & 0x07; + cx1 = ((cx1 << 1) | bitmap->nextPixel(&cxPtr1)) & 0x1f; + cx2 = ((cx2 << 1) | pix) & 0x0f; + } break; + case 1: - cx0 = (bitmap->getPixel(0, y-2) << 2) | - (bitmap->getPixel(1, y-2) << 1) | - bitmap->getPixel(2, y-2); - cx1 = (bitmap->getPixel(0, y-1) << 2) | - (bitmap->getPixel(1, y-1) << 1) | - bitmap->getPixel(2, y-1); + + // set up the context + bitmap->getPixelPtr(0, y-2, &cxPtr0); + cx0 = bitmap->nextPixel(&cxPtr0); + cx0 = (cx0 << 1) | bitmap->nextPixel(&cxPtr0); + cx0 = (cx0 << 1) | bitmap->nextPixel(&cxPtr0); + bitmap->getPixelPtr(0, y-1, &cxPtr1); + cx1 = bitmap->nextPixel(&cxPtr1); + cx1 = (cx1 << 1) | bitmap->nextPixel(&cxPtr1); + cx1 = (cx1 << 1) | bitmap->nextPixel(&cxPtr1); cx2 = 0; + bitmap->getPixelPtr(atx[0], y + aty[0], &atPtr0); + + // decode the row + for (x = 0; x < w; ++x) { + + // build the context + cx = (cx0 << 9) | (cx1 << 4) | (cx2 << 1) | + bitmap->nextPixel(&atPtr0); + + // check for a skipped pixel + if (useSkip && skip->getPixel(x, y)) { + pix = 0; + + // decode the pixel + } else if ((pix = arithDecoder->decodeBit(cx, genericRegionStats))) { + bitmap->setPixel(x, y); + } + + // update the context + cx0 = ((cx0 << 1) | bitmap->nextPixel(&cxPtr0)) & 0x07; + cx1 = ((cx1 << 1) | bitmap->nextPixel(&cxPtr1)) & 0x1f; + cx2 = ((cx2 << 1) | pix) & 0x0f; + } break; + case 2: - cx0 = (bitmap->getPixel(0, y-2) << 1) | - bitmap->getPixel(1, y-2); - cx1 = (bitmap->getPixel(0, y-1) << 1) | - bitmap->getPixel(1, y-1); + + // set up the context + bitmap->getPixelPtr(0, y-2, &cxPtr0); + cx0 = bitmap->nextPixel(&cxPtr0); + cx0 = (cx0 << 1) | bitmap->nextPixel(&cxPtr0); + bitmap->getPixelPtr(0, y-1, &cxPtr1); + cx1 = bitmap->nextPixel(&cxPtr1); + cx1 = (cx1 << 1) | bitmap->nextPixel(&cxPtr1); cx2 = 0; + bitmap->getPixelPtr(atx[0], y + aty[0], &atPtr0); + + // decode the row + for (x = 0; x < w; ++x) { + + // build the context + cx = (cx0 << 9) | (cx1 << 4) | (cx2 << 1) | + bitmap->nextPixel(&atPtr0); + + // check for a skipped pixel + if (useSkip && skip->getPixel(x, y)) { + pix = 0; + + // decode the pixel + } else if ((pix = arithDecoder->decodeBit(cx, genericRegionStats))) { + bitmap->setPixel(x, y); + } + + // update the context + cx0 = ((cx0 << 1) | bitmap->nextPixel(&cxPtr0)) & 0x0f; + cx1 = ((cx1 << 1) | bitmap->nextPixel(&cxPtr1)) & 0x1f; + cx2 = ((cx2 << 1) | pix) & 0x07; + } break; + case 3: - cx1 = (bitmap->getPixel(0, y-1) << 1) | - bitmap->getPixel(1, y-1); - cx2 = 0; - break; - } - // decode the row - for (x = 0; x < w; ++x) { + // set up the context + bitmap->getPixelPtr(0, y-1, &cxPtr1); + cx1 = bitmap->nextPixel(&cxPtr1); + cx1 = (cx1 << 1) | bitmap->nextPixel(&cxPtr1); + cx2 = 0; + bitmap->getPixelPtr(atx[0], y + aty[0], &atPtr0); - // check for a skipped pixel - if (useSkip && skip->getPixel(x, y)) { - pix = 0; - - } else { + // decode the row + for (x = 0; x < w; ++x) { // build the context - switch (templ) { - case 0: - cx = (cx0 << 13) | (cx1 << 8) | (cx2 << 4) | - (bitmap->getPixel(x + atx[0], y + aty[0]) << 3) | - (bitmap->getPixel(x + atx[1], y + aty[1]) << 2) | - (bitmap->getPixel(x + atx[2], y + aty[2]) << 1) | - bitmap->getPixel(x + atx[3], y + aty[3]); - break; - case 1: - cx = (cx0 << 9) | (cx1 << 4) | (cx2 << 1) | - bitmap->getPixel(x + atx[0], y + aty[0]); - break; - case 2: - cx = (cx0 << 7) | (cx1 << 3) | (cx2 << 1) | - bitmap->getPixel(x + atx[0], y + aty[0]); - break; - case 3: - cx = (cx1 << 5) | (cx2 << 1) | - bitmap->getPixel(x + atx[0], y + aty[0]); - break; - } + cx = (cx0 << 9) | (cx1 << 4) | (cx2 << 1) | + bitmap->nextPixel(&atPtr0); + + // check for a skipped pixel + if (useSkip && skip->getPixel(x, y)) { + pix = 0; // decode the pixel - if ((pix = arithDecoder->decodeBit(cx, genericRegionStats))) { + } else if ((pix = arithDecoder->decodeBit(cx, genericRegionStats))) { bitmap->setPixel(x, y); } - } - // update the context - switch (templ) { - case 0: - cx0 = ((cx0 << 1) | bitmap->getPixel(x+2, y-2)) & 0x07; - cx1 = ((cx1 << 1) | bitmap->getPixel(x+3, y-1)) & 0x1f; - cx2 = ((cx2 << 1) | pix) & 0x0f; - break; - case 1: - cx0 = ((cx0 << 1) | bitmap->getPixel(x+3, y-2)) & 0x0f; - cx1 = ((cx1 << 1) | bitmap->getPixel(x+3, y-1)) & 0x1f; - cx2 = ((cx2 << 1) | pix) & 0x07; - break; - case 2: - cx0 = ((cx0 << 1) | bitmap->getPixel(x+2, y-2)) & 0x07; - cx1 = ((cx1 << 1) | bitmap->getPixel(x+2, y-1)) & 0x0f; - cx2 = ((cx2 << 1) | pix) & 0x03; - break; - case 3: - cx1 = ((cx1 << 1) | bitmap->getPixel(x+2, y-1)) & 0x1f; - cx2 = ((cx2 << 1) | pix) & 0x0f; - break; + // update the context + cx1 = ((cx1 << 1) | bitmap->nextPixel(&cxPtr1)) & 0x1f; + cx2 = ((cx2 << 1) | pix) & 0x0f; } + break; } } } @@ -3076,6 +3201,8 @@ JBIG2Bitmap *JBIG2Stream::readGenericRefinementRegion(int w, int h, JBIG2Bitmap *bitmap; GBool ltp; Guint ltpCX, cx, cx0, cx2, cx3, cx4, tpgrCX0, tpgrCX1, tpgrCX2; + JBIG2BitmapPtr cxPtr0, cxPtr1, cxPtr2, cxPtr3, cxPtr4, cxPtr5, cxPtr6; + JBIG2BitmapPtr tpgrCXPtr0, tpgrCXPtr1, tpgrCXPtr2; int x, y, pix; bitmap = new JBIG2Bitmap(0, w, h); @@ -3091,87 +3218,144 @@ JBIG2Bitmap *JBIG2Stream::readGenericRefinementRegion(int w, int h, ltp = 0; for (y = 0; y < h; ++y) { - // set up the context if (templ) { - cx0 = bitmap->getPixel(0, y-1); - cx2 = 0; // unused - cx3 = (refBitmap->getPixel(-1-refDX, y-refDY) << 1) | - refBitmap->getPixel(-refDX, y-refDY); - cx4 = refBitmap->getPixel(-refDX, y+1-refDY); - } else { - cx0 = bitmap->getPixel(0, y-1); - cx2 = refBitmap->getPixel(-refDX, y-1-refDY); - cx3 = (refBitmap->getPixel(-1-refDX, y-refDY) << 1) | - refBitmap->getPixel(-refDX, y-refDY); - cx4 = (refBitmap->getPixel(-1-refDX, y+1-refDY) << 1) | - refBitmap->getPixel(-refDX, y+1-refDY); - } - - // set up the typical prediction context - tpgrCX0 = tpgrCX1 = tpgrCX2 = 0; // make gcc happy - if (tpgrOn) { - tpgrCX0 = (refBitmap->getPixel(-1-refDX, y-1-refDY) << 2) | - (refBitmap->getPixel(-refDX, y-1-refDY) << 1) | - refBitmap->getPixel(1-refDX, y-1-refDY); - tpgrCX1 = (refBitmap->getPixel(-1-refDX, y-refDY) << 2) | - (refBitmap->getPixel(-refDX, y-refDY) << 1) | - refBitmap->getPixel(1-refDX, y-refDY); - tpgrCX2 = (refBitmap->getPixel(-1-refDX, y+1-refDY) << 2) | - (refBitmap->getPixel(-refDX, y+1-refDY) << 1) | - refBitmap->getPixel(1-refDX, y+1-refDY); - } - - for (x = 0; x < w; ++x) { - - // update the context - if (templ) { - cx0 = ((cx0 << 1) | bitmap->getPixel(x+1, y-1)) & 7; - cx3 = ((cx3 << 1) | refBitmap->getPixel(x+1-refDX, y-refDY)) & 7; - cx4 = ((cx4 << 1) | refBitmap->getPixel(x+1-refDX, y+1-refDY)) & 3; - } else { - cx0 = ((cx0 << 1) | bitmap->getPixel(x+1, y-1)) & 3; - cx2 = ((cx2 << 1) | refBitmap->getPixel(x+1-refDX, y-1-refDY)) & 3; - cx3 = ((cx3 << 1) | refBitmap->getPixel(x+1-refDX, y-refDY)) & 7; - cx4 = ((cx4 << 1) | refBitmap->getPixel(x+1-refDX, y+1-refDY)) & 7; - } + // set up the context + bitmap->getPixelPtr(0, y-1, &cxPtr0); + cx0 = bitmap->nextPixel(&cxPtr0); + bitmap->getPixelPtr(-1, y, &cxPtr1); + refBitmap->getPixelPtr(-refDX, y-1-refDY, &cxPtr2); + refBitmap->getPixelPtr(-1-refDX, y-refDY, &cxPtr3); + cx3 = refBitmap->nextPixel(&cxPtr3); + cx3 = (cx3 << 1) | refBitmap->nextPixel(&cxPtr3); + refBitmap->getPixelPtr(-refDX, y+1-refDY, &cxPtr4); + cx4 = refBitmap->nextPixel(&cxPtr4); + + // set up the typical prediction context + tpgrCX0 = tpgrCX1 = tpgrCX2 = 0; // make gcc happy if (tpgrOn) { - // update the typical predictor context - tpgrCX0 = ((tpgrCX0 << 1) | - refBitmap->getPixel(x+1-refDX, y-1-refDY)) & 7; - tpgrCX1 = ((tpgrCX1 << 1) | - refBitmap->getPixel(x+1-refDX, y-refDY)) & 7; - tpgrCX2 = ((tpgrCX2 << 1) | - refBitmap->getPixel(x+1-refDX, y+1-refDY)) & 7; - - // check for a "typical" pixel - if (arithDecoder->decodeBit(ltpCX, refinementRegionStats)) { - ltp = !ltp; + refBitmap->getPixelPtr(-1-refDX, y-1-refDY, &tpgrCXPtr0); + tpgrCX0 = refBitmap->nextPixel(&tpgrCXPtr0); + tpgrCX0 = (tpgrCX0 << 1) | refBitmap->nextPixel(&tpgrCXPtr0); + tpgrCX0 = (tpgrCX0 << 1) | refBitmap->nextPixel(&tpgrCXPtr0); + refBitmap->getPixelPtr(-1-refDX, y-refDY, &tpgrCXPtr1); + tpgrCX1 = refBitmap->nextPixel(&tpgrCXPtr1); + tpgrCX1 = (tpgrCX1 << 1) | refBitmap->nextPixel(&tpgrCXPtr1); + tpgrCX1 = (tpgrCX1 << 1) | refBitmap->nextPixel(&tpgrCXPtr1); + refBitmap->getPixelPtr(-1-refDX, y+1-refDY, &tpgrCXPtr2); + tpgrCX2 = refBitmap->nextPixel(&tpgrCXPtr2); + tpgrCX2 = (tpgrCX2 << 1) | refBitmap->nextPixel(&tpgrCXPtr2); + tpgrCX2 = (tpgrCX2 << 1) | refBitmap->nextPixel(&tpgrCXPtr2); + } + + for (x = 0; x < w; ++x) { + + // update the context + cx0 = ((cx0 << 1) | bitmap->nextPixel(&cxPtr0)) & 7; + cx3 = ((cx3 << 1) | refBitmap->nextPixel(&cxPtr3)) & 7; + cx4 = ((cx4 << 1) | refBitmap->nextPixel(&cxPtr4)) & 3; + + if (tpgrOn) { + // update the typical predictor context + tpgrCX0 = ((tpgrCX0 << 1) | refBitmap->nextPixel(&tpgrCXPtr0)) & 7; + tpgrCX1 = ((tpgrCX1 << 1) | refBitmap->nextPixel(&tpgrCXPtr1)) & 7; + tpgrCX2 = ((tpgrCX2 << 1) | refBitmap->nextPixel(&tpgrCXPtr2)) & 7; + + // check for a "typical" pixel + if (arithDecoder->decodeBit(ltpCX, refinementRegionStats)) { + ltp = !ltp; + } + if (tpgrCX0 == 0 && tpgrCX1 == 0 && tpgrCX2 == 0) { + bitmap->clearPixel(x, y); + continue; + } else if (tpgrCX0 == 7 && tpgrCX1 == 7 && tpgrCX2 == 7) { + bitmap->setPixel(x, y); + continue; + } } - if (tpgrCX0 == 0 && tpgrCX1 == 0 && tpgrCX2 == 0) { - bitmap->clearPixel(x, y); - continue; - } else if (tpgrCX0 == 7 && tpgrCX1 == 7 && tpgrCX2 == 7) { + + // build the context + cx = (cx0 << 7) | (bitmap->nextPixel(&cxPtr1) << 6) | + (refBitmap->nextPixel(&cxPtr2) << 5) | + (cx3 << 2) | cx4; + + // decode the pixel + if ((pix = arithDecoder->decodeBit(cx, refinementRegionStats))) { bitmap->setPixel(x, y); - continue; } } - // build the context - if (templ) { - cx = (cx0 << 7) | (bitmap->getPixel(x-1, y) << 6) | - (refBitmap->getPixel(x-refDX, y-1-refDY) << 5) | - (cx3 << 2) | cx4; - } else { - cx = (cx0 << 11) | (bitmap->getPixel(x-1, y) << 10) | - (cx2 << 8) | (cx3 << 5) | (cx4 << 2) | - (bitmap->getPixel(x+atx[0], y+aty[0]) << 1) | - refBitmap->getPixel(x+atx[1]-refDX, y+aty[1]-refDY); + } else { + + // set up the context + bitmap->getPixelPtr(0, y-1, &cxPtr0); + cx0 = bitmap->nextPixel(&cxPtr0); + bitmap->getPixelPtr(-1, y, &cxPtr1); + refBitmap->getPixelPtr(-refDX, y-1-refDY, &cxPtr2); + cx2 = refBitmap->nextPixel(&cxPtr2); + refBitmap->getPixelPtr(-1-refDX, y-refDY, &cxPtr3); + cx3 = refBitmap->nextPixel(&cxPtr3); + cx3 = (cx3 << 1) | refBitmap->nextPixel(&cxPtr3); + refBitmap->getPixelPtr(-1-refDX, y+1-refDY, &cxPtr4); + cx4 = refBitmap->nextPixel(&cxPtr4); + cx4 = (cx4 << 1) | refBitmap->nextPixel(&cxPtr4); + bitmap->getPixelPtr(atx[0], y+aty[0], &cxPtr5); + refBitmap->getPixelPtr(atx[1]-refDX, y+aty[1]-refDY, &cxPtr6); + + // set up the typical prediction context + tpgrCX0 = tpgrCX1 = tpgrCX2 = 0; // make gcc happy + if (tpgrOn) { + refBitmap->getPixelPtr(-1-refDX, y-1-refDY, &tpgrCXPtr0); + tpgrCX0 = refBitmap->nextPixel(&tpgrCXPtr0); + tpgrCX0 = (tpgrCX0 << 1) | refBitmap->nextPixel(&tpgrCXPtr0); + tpgrCX0 = (tpgrCX0 << 1) | refBitmap->nextPixel(&tpgrCXPtr0); + refBitmap->getPixelPtr(-1-refDX, y-refDY, &tpgrCXPtr1); + tpgrCX1 = refBitmap->nextPixel(&tpgrCXPtr1); + tpgrCX1 = (tpgrCX1 << 1) | refBitmap->nextPixel(&tpgrCXPtr1); + tpgrCX1 = (tpgrCX1 << 1) | refBitmap->nextPixel(&tpgrCXPtr1); + refBitmap->getPixelPtr(-1-refDX, y+1-refDY, &tpgrCXPtr2); + tpgrCX2 = refBitmap->nextPixel(&tpgrCXPtr2); + tpgrCX2 = (tpgrCX2 << 1) | refBitmap->nextPixel(&tpgrCXPtr2); + tpgrCX2 = (tpgrCX2 << 1) | refBitmap->nextPixel(&tpgrCXPtr2); } - // decode the pixel - if ((pix = arithDecoder->decodeBit(cx, refinementRegionStats))) { - bitmap->setPixel(x, y); + for (x = 0; x < w; ++x) { + + // update the context + cx0 = ((cx0 << 1) | bitmap->nextPixel(&cxPtr0)) & 3; + cx2 = ((cx2 << 1) | refBitmap->nextPixel(&cxPtr2)) & 3; + cx3 = ((cx3 << 1) | refBitmap->nextPixel(&cxPtr3)) & 7; + cx4 = ((cx4 << 1) | refBitmap->nextPixel(&cxPtr4)) & 7; + + if (tpgrOn) { + // update the typical predictor context + tpgrCX0 = ((tpgrCX0 << 1) | refBitmap->nextPixel(&tpgrCXPtr0)) & 7; + tpgrCX1 = ((tpgrCX1 << 1) | refBitmap->nextPixel(&tpgrCXPtr1)) & 7; + tpgrCX2 = ((tpgrCX2 << 1) | refBitmap->nextPixel(&tpgrCXPtr2)) & 7; + + // check for a "typical" pixel + if (arithDecoder->decodeBit(ltpCX, refinementRegionStats)) { + ltp = !ltp; + } + if (tpgrCX0 == 0 && tpgrCX1 == 0 && tpgrCX2 == 0) { + bitmap->clearPixel(x, y); + continue; + } else if (tpgrCX0 == 7 && tpgrCX1 == 7 && tpgrCX2 == 7) { + bitmap->setPixel(x, y); + continue; + } + } + + // build the context + cx = (cx0 << 11) | (bitmap->nextPixel(&cxPtr1) << 10) | + (cx2 << 8) | (cx3 << 5) | (cx4 << 2) | + (bitmap->nextPixel(&cxPtr5) << 1) | + refBitmap->nextPixel(&cxPtr6); + + // decode the pixel + if ((pix = arithDecoder->decodeBit(cx, refinementRegionStats))) { + bitmap->setPixel(x, y); + } } } } @@ -3239,8 +3423,8 @@ void JBIG2Stream::readCodeTableSeg(Guint segNum, Guint length) { goto eofError; } oob = flags & 1; - prefixBits = (flags >> 1) & 7; - rangeBits = (flags >> 4) & 7; + prefixBits = ((flags >> 1) & 7) + 1; + rangeBits = ((flags >> 4) & 7) + 1; huffDecoder->reset(); huffTabSize = 8; @@ -3282,7 +3466,6 @@ void JBIG2Stream::readCodeTableSeg(Guint segNum, Guint length) { huffTab[i].val = 0; huffTab[i].prefixLen = 0; huffTab[i].rangeLen = jbig2HuffmanEOT; - ++i; huffDecoder->buildTable(huffTab, i); // create and store the new table segment @@ -3467,7 +3650,7 @@ GBool JBIG2Stream::readLong(int *x) { } *x = ((c0 << 24) | (c1 << 16) | (c2 << 8) | c3); if (c0 & 0x80) { - *x |= -1 - 0xffffffff; + *x |= -1 - (int)0xffffffff; } return gTrue; } diff --git a/pdf/xpdf/JBIG2Stream.h b/pdf/xpdf/JBIG2Stream.h index e15c3ac..877dd7f 100644 --- a/pdf/xpdf/JBIG2Stream.h +++ b/pdf/xpdf/JBIG2Stream.h @@ -2,7 +2,7 @@ // // JBIG2Stream.h // -// Copyright 2002 Glyph & Cog, LLC +// Copyright 2002-2003 Glyph & Cog, LLC // //======================================================================== @@ -60,7 +60,7 @@ private: JBIG2Bitmap **syms, Guint defPixel, Guint combOp, Guint transposed, Guint refCorner, - Guint sOffset, + int sOffset, JBIG2HuffmanTable *huffFSTable, JBIG2HuffmanTable *huffDSTable, JBIG2HuffmanTable *huffDTTable, diff --git a/pdf/xpdf/Outline.cc b/pdf/xpdf/Outline.cc index 267c6a0..cf9fd70 100644 --- a/pdf/xpdf/Outline.cc +++ b/pdf/xpdf/Outline.cc @@ -2,7 +2,7 @@ // // Outline.cc // -// Copyright 2002 Glyph & Cog, LLC +// Copyright 2002-2003 Glyph & Cog, LLC // //======================================================================== diff --git a/pdf/xpdf/Outline.h b/pdf/xpdf/Outline.h index dc79252..92a9462 100644 --- a/pdf/xpdf/Outline.h +++ b/pdf/xpdf/Outline.h @@ -2,7 +2,7 @@ // // Outline.h // -// Copyright 2002 Glyph & Cog, LLC +// Copyright 2002-2003 Glyph & Cog, LLC // //======================================================================== diff --git a/pdf/xpdf/PDFDocEncoding.cc b/pdf/xpdf/PDFDocEncoding.cc index 4f1e201..89dc382 100644 --- a/pdf/xpdf/PDFDocEncoding.cc +++ b/pdf/xpdf/PDFDocEncoding.cc @@ -2,7 +2,7 @@ // // PDFDocEncoding.h // -// Copyright 2002 Glyph & Cog, LLC +// Copyright 2002-2003 Glyph & Cog, LLC // //======================================================================== diff --git a/pdf/xpdf/PDFDocEncoding.h b/pdf/xpdf/PDFDocEncoding.h index 6fc157f..3259d3e 100644 --- a/pdf/xpdf/PDFDocEncoding.h +++ b/pdf/xpdf/PDFDocEncoding.h @@ -2,7 +2,7 @@ // // PDFDocEncoding.h // -// Copyright 2002 Glyph & Cog, LLC +// Copyright 2002-2003 Glyph & Cog, LLC // //======================================================================== diff --git a/pdf/xpdf/UTF8.h b/pdf/xpdf/UTF8.h index d707e2f..8536dbf 100644 --- a/pdf/xpdf/UTF8.h +++ b/pdf/xpdf/UTF8.h @@ -2,7 +2,7 @@ // // UTF8.h // -// Copyright 2001-2002 Glyph & Cog, LLC +// Copyright 2001-2003 Glyph & Cog, LLC // //======================================================================== diff --git a/pdf/xpdf/UnicodeMapTables.h b/pdf/xpdf/UnicodeMapTables.h index 51dee98..9c51034 100644 --- a/pdf/xpdf/UnicodeMapTables.h +++ b/pdf/xpdf/UnicodeMapTables.h @@ -2,7 +2,7 @@ // // UnicodeMapTables.h // -// Copyright 2001-2002 Glyph & Cog, LLC +// Copyright 2001-2003 Glyph & Cog, LLC // //======================================================================== diff --git a/pdf/xpdf/XPDFApp.cc b/pdf/xpdf/XPDFApp.cc index 864dabb..d93f2a0 100644 --- a/pdf/xpdf/XPDFApp.cc +++ b/pdf/xpdf/XPDFApp.cc @@ -2,7 +2,7 @@ // // XPDFApp.cc // -// Copyright 2002 Glyph & Cog, LLC +// Copyright 2002-2003 Glyph & Cog, LLC // //======================================================================== @@ -270,7 +270,11 @@ void XPDFApp::quit() { while (viewers->getLength() > 0) { delete (XPDFViewer *)viewers->del(0); } +#if HAVE_XTAPPSETEXITFLAG + exit(0); +#else XtAppSetExitFlag(appContext); +#endif } void XPDFApp::run() { diff --git a/pdf/xpdf/XPDFApp.h b/pdf/xpdf/XPDFApp.h index d4841e7..ffe0b63 100644 --- a/pdf/xpdf/XPDFApp.h +++ b/pdf/xpdf/XPDFApp.h @@ -2,7 +2,7 @@ // // XPDFApp.h // -// Copyright 2002 Glyph & Cog, LLC +// Copyright 2002-2003 Glyph & Cog, LLC // //======================================================================== diff --git a/pdf/xpdf/XPDFCore.cc b/pdf/xpdf/XPDFCore.cc index 554154c..9e359da 100644 --- a/pdf/xpdf/XPDFCore.cc +++ b/pdf/xpdf/XPDFCore.cc @@ -2,7 +2,7 @@ // // XPDFCore.cc // -// Copyright 2002 Glyph & Cog, LLC +// Copyright 2002-2003 Glyph & Cog, LLC // //======================================================================== @@ -101,6 +101,7 @@ static int zoomDPI[maxZoom - minZoom + 1] = { GString *XPDFCore::currentSelection = NULL; XPDFCore *XPDFCore::currentSelectionOwner = NULL; +Atom XPDFCore::targetsAtom; //------------------------------------------------------------------------ // XPDFCore @@ -116,6 +117,7 @@ XPDFCore::XPDFCore(Widget shellA, Widget parentWidgetA, parentWidget = parentWidgetA; display = XtDisplay(parentWidget); screenNum = XScreenNumberOfScreen(XtScreen(parentWidget)); + targetsAtom = XInternAtom(display, "TARGETS", False); paperColor = paperColorA; fullScreen = fullScreenA; @@ -217,18 +219,6 @@ XPDFCore::~XPDFCore() { if (drawAreaGC) { XFreeGC(display, drawAreaGC); } - if (drawArea) { - XtDestroyWidget(drawArea); - } - if (drawAreaFrame) { - XtDestroyWidget(drawAreaFrame); - } - if (vScrollBar) { - XtDestroyWidget(vScrollBar); - } - if (hScrollBar) { - XtDestroyWidget(hScrollBar); - } if (scrolledWin) { XtDestroyWidget(scrolledWin); } @@ -315,6 +305,74 @@ int XPDFCore::loadFile(GString *fileName, GString *ownerPassword, return errNone; } +int XPDFCore::loadFile(BaseStream *stream, GString *ownerPassword, + GString *userPassword) { + PDFDoc *newDoc; + GString *password; + GBool again; + int err; + + // busy cursor + setCursor(busyCursor); + + // open the PDF file + newDoc = new PDFDoc(stream, ownerPassword, userPassword); + if (!newDoc->isOk()) { + err = newDoc->getErrorCode(); + delete newDoc; + if (err != errEncrypted || !reqPasswordCbk) { + setCursor(None); + return err; + } + + // try requesting a password + again = ownerPassword != NULL || userPassword != NULL; + while (1) { + if (!(password = (*reqPasswordCbk)(reqPasswordCbkData, again))) { + setCursor(None); + return errEncrypted; + } + newDoc = new PDFDoc(stream, password, password); + if (newDoc->isOk()) { + break; + } + err = newDoc->getErrorCode(); + delete newDoc; + if (err != errEncrypted) { + setCursor(None); + return err; + } + again = gTrue; + } + } + + // replace old document + if (doc) { + delete doc; + } + doc = newDoc; + if (out) { + out->startDoc(doc->getXRef()); + } + + // nothing displayed yet + page = -99; + + // save the modification time + modTime = getModTime(doc->getFileName()->getCString()); + + // update the parent window + if (updateCbk) { + (*updateCbk)(updateCbkData, doc->getFileName(), -1, + doc->getNumPages(), NULL); + } + + // back to regular cursor + setCursor(None); + + return errNone; +} + void XPDFCore::resizeToPage(int pg) { Dimension width, height; double width1, height1; @@ -478,6 +536,15 @@ void XPDFCore::displayPage(int pageA, int 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) { @@ -488,7 +555,11 @@ void XPDFCore::displayPage(int pageA, int zoomA, int rotateA, if (h->fileName) { delete h->fileName; } - h->fileName = doc->getFileName()->copy(); + if (doc->getFileName()) { + h->fileName = doc->getFileName()->copy(); + } else { + h->fileName = NULL; + } h->page = page; if (historyBLen < xpdfHistorySize) { ++historyBLen; @@ -501,15 +572,6 @@ void XPDFCore::displayPage(int pageA, int zoomA, int rotateA, (*updateCbk)(updateCbkData, NULL, page, -1, ""); } - // 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); - // back to regular cursor setCursor(None); } @@ -925,15 +987,31 @@ Boolean XPDFCore::convertSelectionCbk(Widget widget, Atom *selection, Atom *target, Atom *type, XtPointer *value, unsigned long *length, int *format) { - if (*target != XA_STRING) { - return False; - } - //~ for multithreading: need a mutex here - *value = XtNewString(currentSelection->getCString()); - *length = currentSelection->getLength(); - *type = XA_STRING; - *format = 8; // 8-bit elements - return True; + Atom *array; + + // send back a list of supported conversion targets + if (*target == targetsAtom) { + if (!(array = (Atom *)XtMalloc(sizeof(Atom)))) { + return False; + } + array[0] = XA_STRING; + *value = (XtPointer)array; + *type = XA_ATOM; + *format = 32; + *length = 1; + return True; + + // send the selected text + } else if (*target == XA_STRING) { + //~ for multithreading: need a mutex here + *value = XtNewString(currentSelection->getCString()); + *length = currentSelection->getLength(); + *type = XA_STRING; + *format = 8; // 8-bit elements + return True; + } + + return False; } GBool XPDFCore::getSelection(int *xMin, int *yMin, int *xMax, int *yMax) { @@ -962,7 +1040,7 @@ GString *XPDFCore::extractText(int pageNum, if (!doc->okToCopy()) { return NULL; } - textOut = new TextOutputDev(NULL, gFalse, gFalse, gFalse); + textOut = new TextOutputDev(NULL, gTrue, gFalse, gFalse); if (!textOut->isOk()) { delete textOut; return NULL; @@ -1276,7 +1354,7 @@ void XPDFCore::find(char *s) { } // search following pages - textOut = new TextOutputDev(NULL, gFalse, gFalse, gFalse); + textOut = new TextOutputDev(NULL, gTrue, gFalse, gFalse); if (!textOut->isOk()) { delete textOut; goto done; @@ -1472,6 +1550,7 @@ void XPDFCore::resizeCbk(Widget widget, XtPointer ptr, XtPointer callData) { Arg args[2]; int n; Dimension w, h; + int oldScrollX, oldScrollY; n = 0; XtSetArg(args[n], XmNwidth, &w); ++n; @@ -1484,7 +1563,13 @@ void XPDFCore::resizeCbk(Widget widget, XtPointer ptr, XtPointer callData) { core->displayPage(core->page, core->zoom, core->rotate, gFalse, gFalse); } else { + oldScrollX = core->scrollX; + oldScrollY = core->scrollY; core->updateScrollBars(); + if (core->scrollX != oldScrollX || core->scrollY != oldScrollY) { + core->redrawRectangle(core->scrollX, core->scrollY, + core->drawAreaWidth, core->drawAreaHeight); + } } } diff --git a/pdf/xpdf/XPDFCore.h b/pdf/xpdf/XPDFCore.h index cf5308e..6435736 100644 --- a/pdf/xpdf/XPDFCore.h +++ b/pdf/xpdf/XPDFCore.h @@ -2,7 +2,7 @@ // // XPDFCore.h // -// Copyright 2002 Glyph & Cog, LLC +// Copyright 2002-2003 Glyph & Cog, LLC // //======================================================================== @@ -24,6 +24,7 @@ class GString; class GList; +class BaseStream; class PDFDoc; class LinkAction; class LinkDest; @@ -59,6 +60,7 @@ struct XPDFRegion { double xMin, yMin, xMax, yMax; Gulong color; Gulong selectColor; + GBool selectable; }; //------------------------------------------------------------------------ @@ -97,6 +99,11 @@ public: int loadFile(GString *fileName, GString *ownerPassword = NULL, GString *userPassword = NULL); + // Load a new file, via a Stream instead of a file name. Returns + // pdfOk or error code. + int loadFile(BaseStream *stream, GString *ownerPassword = NULL, + GString *userPassword = NULL); + // Resize the window to fit page of the current document. void resizeToPage(int pg); @@ -253,6 +260,7 @@ private: GBool lastDragTop; // last dragged selection edge was top/bottom static GString *currentSelection; // selected text static XPDFCore *currentSelectionOwner; + static Atom targetsAtom; GBool panning; int panMX, panMY; diff --git a/pdf/xpdf/XPDFTree.cc b/pdf/xpdf/XPDFTree.cc index 46e5466..720197f 100644 --- a/pdf/xpdf/XPDFTree.cc +++ b/pdf/xpdf/XPDFTree.cc @@ -2,6 +2,8 @@ // // XPDFTree.cc // +// Copyright 2002-2003 Glyph & Cog, LLC +// //======================================================================== #include diff --git a/pdf/xpdf/XPDFTree.h b/pdf/xpdf/XPDFTree.h index d569f49..432b4ff 100644 --- a/pdf/xpdf/XPDFTree.h +++ b/pdf/xpdf/XPDFTree.h @@ -2,6 +2,8 @@ // // XPDFTree.h // +// Copyright 2002-2003 Glyph & Cog, LLC +// //======================================================================== #ifndef XPDFTREE_H diff --git a/pdf/xpdf/XPDFTreeP.h b/pdf/xpdf/XPDFTreeP.h index 16ab137..1d786f4 100644 --- a/pdf/xpdf/XPDFTreeP.h +++ b/pdf/xpdf/XPDFTreeP.h @@ -2,6 +2,8 @@ // // XPDFTreeP.h // +// Copyright 2002-2003 Glyph & Cog, LLC +// //======================================================================== #ifndef XPDFTREEP_H diff --git a/pdf/xpdf/XPDFViewer.cc b/pdf/xpdf/XPDFViewer.cc index 83f8c77..f8f030b 100644 --- a/pdf/xpdf/XPDFViewer.cc +++ b/pdf/xpdf/XPDFViewer.cc @@ -2,7 +2,7 @@ // // XPDFViewer.cc // -// Copyright 2002 Glyph & Cog, LLC +// Copyright 2002-2003 Glyph & Cog, LLC // //======================================================================== @@ -19,6 +19,11 @@ #ifdef HAVE_X11_XPM_H #include #endif +#if defined(__sgi) && (XmVERSION <= 1) +#define Object XtObject +#include +#undef Object +#endif #include "gmem.h" #include "gfile.h" #include "GString.h" @@ -198,6 +203,11 @@ void XPDFViewer::clear() { XtVaSetValues(prevPageBtn, XmNsensitive, False, NULL); XtVaSetValues(nextTenPageBtn, XmNsensitive, False, NULL); XtVaSetValues(nextPageBtn, XmNsensitive, False, NULL); + + // remove the old outline +#ifndef DISABLE_OUTLINE + setupOutline(); +#endif } //------------------------------------------------------------------------ @@ -452,6 +462,11 @@ void XPDFViewer::mouseCbk(void *data, XEvent *event) { if (event->type == ButtonPress && event->xbutton.button == 3) { XmMenuPosition(viewer->popupMenu, &event->xbutton); XtManageChild(viewer->popupMenu); + + // this is magic (taken from DDD) - weird things happen if this + // call isn't made (this is done in two different places, in hopes + // of squashing this stupid bug) + XtUngrabButton(viewer->core->getDrawAreaWidget(), AnyButton, AnyModifier); } } @@ -788,7 +803,11 @@ void XPDFViewer::initWindow() { XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); ++n; XtSetArg(args[n], XmNrightAttachment, XmATTACH_FORM); ++n; XtSetArg(args[n], XmNorientation, XmHORIZONTAL); ++n; +#if defined(__sgi) && (XmVERSION <= 1) + panedWin = SgCreateHorzPanedWindow(form, "panedWin", args, n); +#else panedWin = XmCreatePanedWindow(form, "panedWin", args, n); +#endif XtManageChild(panedWin); // scrolled window for outline container @@ -797,7 +816,9 @@ void XPDFViewer::initWindow() { XtSetArg(args[n], XmNallowResize, True); ++n; XtSetArg(args[n], XmNpaneMinimum, 1); ++n; XtSetArg(args[n], XmNpaneMaximum, 10000); ++n; +#if !(defined(__sgi) && (XmVERSION <= 1)) XtSetArg(args[n], XmNwidth, 1); ++n; +#endif XtSetArg(args[n], XmNscrollingPolicy, XmAUTOMATIC); ++n; outlineScroll = XmCreateScrolledWindow(panedWin, "outlineScroll", args, n); XtManageChild(outlineScroll); @@ -950,6 +971,10 @@ void XPDFViewer::initWindow() { XtAddCallback(btn, XmNactivateCallback, &quitCbk, (XtPointer)this); + // this is magic (taken from DDD) - weird things happen if this + // call isn't made + XtUngrabButton(core->getDrawAreaWidget(), AnyButton, AnyModifier); + XmStringFree(emptyString); } @@ -958,7 +983,7 @@ void XPDFViewer::mapWindow() { Pixmap iconPixmap; #endif int depth; - Pixel bg, arm; + Pixel fg, bg, arm; // show the window XtPopup(win, XtGrabNone); @@ -974,29 +999,27 @@ void XPDFViewer::mapWindow() { // set button bitmaps (must be done after the window is mapped) XtVaGetValues(backBtn, XmNdepth, &depth, - XmNbackground, &bg, XmNarmColor, &arm, NULL); + XmNforeground, &fg, XmNbackground, &bg, + XmNarmColor, &arm, NULL); XtVaSetValues(backBtn, XmNlabelType, XmPIXMAP, XmNlabelPixmap, XCreatePixmapFromBitmapData(display, XtWindow(toolBar), (char *)backArrow_bits, backArrow_width, backArrow_height, - BlackPixel(display, screenNum), - bg, depth), + fg, bg, depth), XmNarmPixmap, XCreatePixmapFromBitmapData(display, XtWindow(toolBar), (char *)backArrow_bits, backArrow_width, backArrow_height, - BlackPixel(display, screenNum), - arm, depth), + fg, arm, depth), XmNlabelInsensitivePixmap, XCreatePixmapFromBitmapData(display, XtWindow(toolBar), (char *)backArrowDis_bits, backArrowDis_width, backArrowDis_height, - BlackPixel(display, screenNum), - bg, depth), + fg, bg, depth), NULL); XtVaSetValues(prevTenPageBtn, XmNlabelType, XmPIXMAP, XmNlabelPixmap, @@ -1004,22 +1027,19 @@ void XPDFViewer::mapWindow() { (char *)dblLeftArrow_bits, dblLeftArrow_width, dblLeftArrow_height, - BlackPixel(display, screenNum), - bg, depth), + fg, bg, depth), XmNarmPixmap, XCreatePixmapFromBitmapData(display, XtWindow(toolBar), (char *)dblLeftArrow_bits, dblLeftArrow_width, dblLeftArrow_height, - BlackPixel(display, screenNum), - arm, depth), + fg, arm, depth), XmNlabelInsensitivePixmap, XCreatePixmapFromBitmapData(display, XtWindow(toolBar), (char *)dblLeftArrowDis_bits, dblLeftArrowDis_width, dblLeftArrowDis_height, - BlackPixel(display, screenNum), - bg, depth), + fg, bg, depth), NULL); XtVaSetValues(prevPageBtn, XmNlabelType, XmPIXMAP, XmNlabelPixmap, @@ -1027,22 +1047,19 @@ void XPDFViewer::mapWindow() { (char *)leftArrow_bits, leftArrow_width, leftArrow_height, - BlackPixel(display, screenNum), - bg, depth), + fg, bg, depth), XmNarmPixmap, XCreatePixmapFromBitmapData(display, XtWindow(toolBar), (char *)leftArrow_bits, leftArrow_width, leftArrow_height, - BlackPixel(display, screenNum), - arm, depth), + fg, arm, depth), XmNlabelInsensitivePixmap, XCreatePixmapFromBitmapData(display, XtWindow(toolBar), (char *)leftArrowDis_bits, leftArrowDis_width, leftArrowDis_height, - BlackPixel(display, screenNum), - bg, depth), + fg, bg, depth), NULL); XtVaSetValues(nextPageBtn, XmNlabelType, XmPIXMAP, XmNlabelPixmap, @@ -1050,22 +1067,19 @@ void XPDFViewer::mapWindow() { (char *)rightArrow_bits, rightArrow_width, rightArrow_height, - BlackPixel(display, screenNum), - bg, depth), + fg, bg, depth), XmNarmPixmap, XCreatePixmapFromBitmapData(display, XtWindow(toolBar), (char *)rightArrow_bits, rightArrow_width, rightArrow_height, - BlackPixel(display, screenNum), - arm, depth), + fg, arm, depth), XmNlabelInsensitivePixmap, XCreatePixmapFromBitmapData(display, XtWindow(toolBar), (char *)rightArrowDis_bits, rightArrowDis_width, rightArrowDis_height, - BlackPixel(display, screenNum), - bg, depth), + fg, bg, depth), NULL); XtVaSetValues(nextTenPageBtn, XmNlabelType, XmPIXMAP, XmNlabelPixmap, @@ -1073,22 +1087,19 @@ void XPDFViewer::mapWindow() { (char *)dblRightArrow_bits, dblRightArrow_width, dblRightArrow_height, - BlackPixel(display, screenNum), - bg, depth), + fg, bg, depth), XmNarmPixmap, XCreatePixmapFromBitmapData(display, XtWindow(toolBar), (char *)dblRightArrow_bits, dblRightArrow_width, dblRightArrow_height, - BlackPixel(display, screenNum), - arm, depth), + fg, arm, depth), XmNlabelInsensitivePixmap, XCreatePixmapFromBitmapData(display, XtWindow(toolBar), (char *)dblRightArrowDis_bits, dblRightArrowDis_width, dblRightArrowDis_height, - BlackPixel(display, screenNum), - bg, depth), + fg, bg, depth), NULL); XtVaSetValues(forwardBtn, XmNlabelType, XmPIXMAP, XmNlabelPixmap, @@ -1096,22 +1107,19 @@ void XPDFViewer::mapWindow() { (char *)forwardArrow_bits, forwardArrow_width, forwardArrow_height, - BlackPixel(display, screenNum), - bg, depth), + fg, bg, depth), XmNarmPixmap, XCreatePixmapFromBitmapData(display, XtWindow(toolBar), (char *)forwardArrow_bits, forwardArrow_width, forwardArrow_height, - BlackPixel(display, screenNum), - arm, depth), + fg, arm, depth), XmNlabelInsensitivePixmap, XCreatePixmapFromBitmapData(display, XtWindow(toolBar), (char *)forwardArrowDis_bits, forwardArrowDis_width, forwardArrowDis_height, - BlackPixel(display, screenNum), - bg, depth), + fg, bg, depth), NULL); XtVaSetValues(findBtn, XmNlabelType, XmPIXMAP, XmNlabelPixmap, @@ -1119,22 +1127,19 @@ void XPDFViewer::mapWindow() { (char *)find_bits, find_width, find_height, - BlackPixel(display, screenNum), - bg, depth), + fg, bg, depth), XmNarmPixmap, XCreatePixmapFromBitmapData(display, XtWindow(toolBar), (char *)find_bits, find_width, find_height, - BlackPixel(display, screenNum), - arm, depth), + fg, arm, depth), XmNlabelInsensitivePixmap, XCreatePixmapFromBitmapData(display, XtWindow(toolBar), (char *)findDis_bits, findDis_width, findDis_height, - BlackPixel(display, screenNum), - bg, depth), + fg, bg, depth), NULL); XtVaSetValues(printBtn, XmNlabelType, XmPIXMAP, XmNlabelPixmap, @@ -1142,22 +1147,19 @@ void XPDFViewer::mapWindow() { (char *)print_bits, print_width, print_height, - BlackPixel(display, screenNum), - bg, depth), + fg, bg, depth), XmNarmPixmap, XCreatePixmapFromBitmapData(display, XtWindow(toolBar), (char *)print_bits, print_width, print_height, - BlackPixel(display, screenNum), - arm, depth), + fg, arm, depth), XmNlabelInsensitivePixmap, XCreatePixmapFromBitmapData(display, XtWindow(toolBar), (char *)printDis_bits, printDis_width, printDis_height, - BlackPixel(display, screenNum), - bg, depth), + fg, bg, depth), NULL); XtVaSetValues(aboutBtn, XmNlabelType, XmPIXMAP, XmNlabelPixmap, @@ -1165,15 +1167,13 @@ void XPDFViewer::mapWindow() { (char *)about_bits, about_width, about_height, - BlackPixel(display, screenNum), - bg, depth), + fg, bg, depth), XmNarmPixmap, XCreatePixmapFromBitmapData(display, XtWindow(toolBar), (char *)about_bits, about_width, about_height, - BlackPixel(display, screenNum), - arm, depth), + fg, arm, depth), NULL); } @@ -1470,18 +1470,21 @@ void XPDFViewer::setupOutline() { outlineLabelsLength = outlineLabelsSize = 0; } - // create the new labels - items = core->getDoc()->getOutline()->getItems(); - if (items && items->getLength() > 0) { - enc = new GString("Latin1"); - uMap = globalParams->getUnicodeMap(enc); - delete enc; - setupOutlineItems(items, NULL, uMap); - uMap->decRefCnt(); - } + if (core->getDoc()) { + + // create the new labels + items = core->getDoc()->getOutline()->getItems(); + if (items && items->getLength() > 0) { + enc = new GString("Latin1"); + uMap = globalParams->getUnicodeMap(enc); + delete enc; + setupOutlineItems(items, NULL, uMap); + uMap->decRefCnt(); + } - // manage the new labels - XtManageChildren(outlineLabels, outlineLabelsLength); + // manage the new labels + XtManageChildren(outlineLabels, outlineLabelsLength); + } } void XPDFViewer::setupOutlineItems(GList *items, Widget parent, @@ -1560,7 +1563,6 @@ void XPDFViewer::initAboutDialog() { int n, i; XmString s; char buf[20]; - XmFontListEntry entry; //----- dialog n = 0; @@ -1601,24 +1603,12 @@ void XPDFViewer::initAboutDialog() { XtManageChild(col); //----- fonts - entry = XmFontListEntryLoad( - display, - "-*-times-bold-i-normal--20-*-*-*-*-*-iso8859-1", - XmFONT_IS_FONT, XmFONTLIST_DEFAULT_TAG); - aboutBigFont = XmFontListAppendEntry(NULL, entry); - XmFontListEntryFree(&entry); - entry = XmFontListEntryLoad( - display, - "-*-times-medium-r-normal--16-*-*-*-*-*-iso8859-1", - XmFONT_IS_FONT, XmFONTLIST_DEFAULT_TAG); - aboutVersionFont = XmFontListAppendEntry(NULL, entry); - XmFontListEntryFree(&entry); - entry = XmFontListEntryLoad( - display, - "-*-courier-medium-r-normal--12-*-*-*-*-*-iso8859-1", - XmFONT_IS_FONT, XmFONTLIST_DEFAULT_TAG); - aboutFixedFont = XmFontListAppendEntry(NULL, entry); - XmFontListEntryFree(&entry); + aboutBigFont = + createFontList("-*-times-bold-i-normal--20-*-*-*-*-*-iso8859-1"); + aboutVersionFont = + createFontList("-*-times-medium-r-normal--16-*-*-*-*-*-iso8859-1"); + aboutFixedFont = + createFontList("-*-courier-medium-r-normal--12-*-*-*-*-*-iso8859-1"); //----- heading n = 0; @@ -1815,7 +1805,9 @@ void XPDFViewer::initFindDialog() { n = 0; XtSetArg(args[n], XmNdefaultButton, okBtn); ++n; XtSetArg(args[n], XmNcancelButton, closeBtn); ++n; +#if XmVersion > 1001 XtSetArg(args[n], XmNinitialFocus, findText); ++n; +#endif XtSetValues(findDialog, args, n); } @@ -1823,10 +1815,14 @@ void XPDFViewer::findFindCbk(Widget widget, XtPointer ptr, XtPointer callData) { XPDFViewer *viewer = (XPDFViewer *)ptr; - XDefineCursor(viewer->display, XtWindow(viewer->findDialog), - viewer->core->getBusyCursor()); + if (XtWindow(viewer->findDialog)) { + XDefineCursor(viewer->display, XtWindow(viewer->findDialog), + viewer->core->getBusyCursor()); + } viewer->core->find(XmTextFieldGetString(viewer->findText)); - XUndefineCursor(viewer->display, XtWindow(viewer->findDialog)); + if (XtWindow(viewer->findDialog)) { + XUndefineCursor(viewer->display, XtWindow(viewer->findDialog)); + } } void XPDFViewer::findCloseCbk(Widget widget, XtPointer ptr, @@ -2260,7 +2256,9 @@ void XPDFViewer::initPasswordDialog() { n = 0; XtSetArg(args[n], XmNdefaultButton, okBtn); ++n; XtSetArg(args[n], XmNcancelButton, cancelBtn); ++n; +#if XmVersion > 1001 XtSetArg(args[n], XmNinitialFocus, passwordText); ++n; +#endif XtSetValues(passwordDialog, args, n); } @@ -2329,3 +2327,43 @@ void XPDFViewer::getPassword(GBool again) { password = NULL; } } + +//------------------------------------------------------------------------ +// Motif support +//------------------------------------------------------------------------ + +XmFontList XPDFViewer::createFontList(char *xlfd) { + XmFontList fontList; + +#if XmVersion <= 1001 + + XFontStruct *font; + String params; + Cardinal nParams; + + font = XLoadQueryFont(display, xlfd); + if (font) { + fontList = XmFontListCreate(font, XmSTRING_DEFAULT_CHARSET); + } else { + params = (String)xlfd; + nParams = 1; + XtAppWarningMsg(app->getAppContext(), + "noSuchFont", "CvtStringToXmFontList", + "XtToolkitError", "No such font: %s", + ¶ms, &nParams); + fontList = NULL; + } + +#else + + XmFontListEntry entry; + + entry = XmFontListEntryLoad(display, xlfd, + XmFONT_IS_FONT, XmFONTLIST_DEFAULT_TAG); + fontList = XmFontListAppendEntry(NULL, entry); + XmFontListEntryFree(&entry); + +#endif + + return fontList; +} diff --git a/pdf/xpdf/XPDFViewer.h b/pdf/xpdf/XPDFViewer.h index 124650a..924042f 100644 --- a/pdf/xpdf/XPDFViewer.h +++ b/pdf/xpdf/XPDFViewer.h @@ -2,7 +2,7 @@ // // XPDFViewer.h // -// Copyright 2002 Glyph & Cog, LLC +// Copyright 2002-2003 Glyph & Cog, LLC // //======================================================================== @@ -21,7 +21,7 @@ #include "gtypes.h" #include "XPDFCore.h" -#if XmVERSION <= 1 +#if (XmVERSION <= 1) && !defined(__sgi) #define DISABLE_OUTLINE #endif @@ -173,6 +173,9 @@ private: XtPointer callData); void getPassword(GBool again); + //----- Motif support + XmFontList createFontList(char *xlfd); + XPDFApp *app; GBool ok; diff --git a/pdf/xpdf/XPixmapOutputDev.cc b/pdf/xpdf/XPixmapOutputDev.cc index ecd1498..d55b2d2 100644 --- a/pdf/xpdf/XPixmapOutputDev.cc +++ b/pdf/xpdf/XPixmapOutputDev.cc @@ -2,7 +2,7 @@ // // XPixmapOutputDev.cc // -// Copyright 2002 Glyph & Cog, LLC +// Copyright 2002-2003 Glyph & Cog, LLC // //======================================================================== diff --git a/pdf/xpdf/XPixmapOutputDev.h b/pdf/xpdf/XPixmapOutputDev.h index 1dba8af..8b83167 100644 --- a/pdf/xpdf/XPixmapOutputDev.h +++ b/pdf/xpdf/XPixmapOutputDev.h @@ -2,7 +2,7 @@ // // XPixmapOutputDev.h // -// Copyright 2002 Glyph & Cog, LLC +// Copyright 2002-2003 Glyph & Cog, LLC // //======================================================================== diff --git a/pdf/xpdf/about-text.h b/pdf/xpdf/about-text.h index e84c1ef..3b03f46 100644 --- a/pdf/xpdf/about-text.h +++ b/pdf/xpdf/about-text.h @@ -2,7 +2,7 @@ // // about-text.h // -// Copyright 2002 Glyph & Cog, LLC +// Copyright 2002-2003 Glyph & Cog, LLC // //======================================================================== -- cgit v0.9.1