- Put xpdf 3.00 in the xpdf, goo and fofi drawers to bring the PDF 1.5 support that version has to kpdf

- Remove not used files of xpdf (images, etc) that we don't need to distribute

Please test if your kpdf behaves equally that older versions (it should only have somewhat better support to PDF 1.5)

svn path=/trunk/kdegraphics/kpdf/; revision=339928
This commit is contained in:
Albert Astals Cid 2004-08-23 00:05:01 +00:00
parent 78791f5819
commit 3abd57ea99
137 changed files with 18738 additions and 18396 deletions

View file

@ -1,2 +1,5 @@
2004-08-23 Albert Astals Cid <tsdgeos@terra.es>
* Replace xpdf version with lastest one (3.00) that supports PDF 1.5
Tue Aug 27 13:33:19 CEST 2002 - Wilco Greven <greven@kde.org>
o Initial Creation

View file

@ -1,4 +1,4 @@
SUBDIRS = . goo xpdf kpdf
SUBDIRS = . fofi goo xpdf kpdf
noinst_HEADERS = aconf.h

View file

@ -1,17 +1,17 @@
Xpdf
====
version 2.00
2002-nov-04
version 3.00
2004-jan-22
The Xpdf software and documentation are
copyright 1996-2002 Glyph & Cog, LLC.
copyright 1996-2004 Glyph & Cog, LLC.
Email: derekn@foolabs.com
WWW: http://www.foolabs.com/xpdf/
The PDF data structures, operators, and specification are
copyright 1985-2001 Adobe Systems Inc.
copyright 1985-2003 Adobe Systems Inc.
What is Xpdf?
@ -27,8 +27,8 @@ Xpdf runs under the X Window System on UNIX, VMS, and OS/2. The non-X
components (pdftops, pdftotext, etc.) also run on Win32 systems and
should run on pretty much any system with a decent C++ compiler.
Xpdf is designed to be small and efficient. It can use Type 1,
TrueType, or standard X fonts.
Xpdf is designed to be small and efficient. It can use Type 1 or
TrueType fonts.
Distribution
@ -63,17 +63,17 @@ Cog web site:
Compatibility
-------------
Xpdf is developed and tested on a Linux 2.2 x86 system.
Xpdf is developed and tested on a Linux 2.4 x86 system.
In addition, it has been compiled by others on Solaris, AIX, HP-UX,
SCO UnixWare, Digital Unix, Irix, and numerous other Unix
implementations, as well as VMS and OS/2. It should work on pretty
much any system which runs X11 and has Unix-like libraries. You'll
need ANSI C++ and C compilers to compile it.
Digital Unix, Irix, and numerous other Unix implementations, as well
as VMS and OS/2. It should work on pretty much any system which runs
X11 and has Unix-like libraries. You'll need ANSI C++ and C compilers
to compile it.
The non-X components of Xpdf (pdftops, pdftotext, pdfinfo, pdffonts,
pdfimages) can also be compiled on Win32 systems. See the Xpdf web
page for details.
pdftoppm, and pdfimages) can also be compiled on Win32 systems. See
the Xpdf web page for details.
If you compile Xpdf for a system not listed on the web page, please
let me know. If you're willing to make your binary available by ftp
@ -130,95 +130,23 @@ their man pages):
useful information)
pdffonts -- lists the fonts used in a PDF file along with various
information for each font
pdftopbm -- converts a PDF file to a series of PBM-format bitmaps
pdftoppm -- converts a PDF file to a series of PPM/PGM/PBM-format
bitmaps
pdfimages -- extracts the images from a PDF file
Command line options and many other details are described in the man
pages (xpdf.1, etc.) and the VMS help files (xpdf.hlp, etc.).
Upgrading from Xpdf 0.9x
Upgrading from Xpdf 2.xx
------------------------
WARNING: Xpdf 1.x switched to a completely different config file setup
than Xpdf 0.9x.
Many of the configuration options that used to be X resources have
been moved into the Xpdf config file. There are also lots of new and
improved options. If you're upgrading from Xpdf 0.9x, please read
through the sample config file (doc/sample-xpdfrc) and the xpdfrc(5)
man page.
The Asian language support has been pulled out into separate packages,
loaded at run time. This is much cleaner than the 0.9x approach -- it
makes the base distribution smaller, allows the language support
packages to be upgraded separately, and lets users customize Xpdf for
other text encodings without modifying the source. See the web site
(http://www.foolabs.com/xpdf) for info on downloading the language
support packages.
All of the Xpdf tools, including the X viewer and the command line
programs, read the same config file. They first attempt to read the
user's personal config file:
$HOME/.xpdfrc
If it is not found, the Xpdf tools read a system-wide config file,
typically something like:
/usr/local/etc/xpdfrc
(this location can be customized when building Xpdf).
The Win32 command line tools look in the directory containing the
executable, e.g.:
C:/Program Files/Xpdf/xpdfrc
Xpdf comes with a "sample-xpdfrc" file in the doc directory. This is
a good starting point for constructing your own config file.
For full details, please see the xpdfrc(5) man page.
Fonts
-----
By default, Xpdf will use X server fonts. It requires the following
fonts:
* Courier: medium-r, bold-r, medium-o, and bold-o
* Helvetica: medium-r, bold-r, medium-o, and bold-o
* Times: medium-r, bold-r, medium-i, and bold-i
* Symbol: medium-r
* Zapf Dingbats: medium-r
Most X installations should already have all of these fonts (except
maybe Zapf Dingbats).
If Xpdf is built with support for t1lib (or FreeType 2), you can get
much higher quality text by using Type 1 fonts instead of X server
fonts. For example, you can use the Type 1 fonts that come with
ghostscript. To do this, add the following lines to the xpdfrc file
(e.g., /usr/local/etc/xpdfrc or $HOME/.xpdfrc):
displayFontT1 Times-Roman /usr/local/share/ghostscript/fonts/n021003l.pfb
displayFontT1 Times-Italic /usr/local/share/ghostscript/fonts/n021023l.pfb
displayFontT1 Times-Bold /usr/local/share/ghostscript/fonts/n021004l.pfb
displayFontT1 Times-BoldItalic /usr/local/share/ghostscript/fonts/n021024l.pfb
displayFontT1 Helvetica /usr/local/share/ghostscript/fonts/n019003l.pfb
displayFontT1 Helvetica-Oblique /usr/local/share/ghostscript/fonts/n019023l.pfb
displayFontT1 Helvetica-Bold /usr/local/share/ghostscript/fonts/n019004l.pfb
displayFontT1 Helvetica-BoldOblique /usr/local/share/ghostscript/fonts/n019024l.pfb
displayFontT1 Courier /usr/local/share/ghostscript/fonts/n022003l.pfb
displayFontT1 Courier-Oblique /usr/local/share/ghostscript/fonts/n022023l.pfb
displayFontT1 Courier-Bold /usr/local/share/ghostscript/fonts/n022004l.pfb
displayFontT1 Courier-BoldOblique /usr/local/share/ghostscript/fonts/n022024l.pfb
displayFontT1 Symbol /usr/local/share/ghostscript/fonts/s050000l.pfb
displayFontT1 ZapfDingbats /usr/local/share/ghostscript/fonts/d050000l.pfb
You will need to replace '/usr/local/share/ghostscript/fonts' with the
appropriate path on your system.
WARNING: Xpdf 3.00 switched to a new PDF rasterizer, which no longer
uses X fonts. You'll need a set of Base-14 fonts -- the URW fonts
distributed with ghostscript can be used for this. Xpdf will search
for the URW fonts, but if you have them installed in a non-standard
directory, you'll need to set up an xpdfrc config file to point to
them. For full details, please see the xpdfrc(5) man page.
Compiling Xpdf
@ -248,7 +176,8 @@ Thanks to:
* Brendan Miller for the icon idea.
* Olly Betts for help testing pdftotext.
* Peter Ganten for the OS/2 port.
* Michael Richmond for the Win32 port of pdftops and pdftotext.
* Michael Richmond for the Win32 port of pdftops and pdftotext and the
xpdf/cygwin/XFree86 build instructions.
* Frank M. Siegert for improvements in the PostScript code.
* Leo Smiers for the decryption patches.
* Rainer Menzner for creating t1lib, and for helping me adapt it to
@ -275,16 +204,9 @@ References
----------
Adobe Systems Inc., _PDF Reference: Adobe Portable Document Format
version 1.4_, 3nd ed.
Addison-Wesley, 2001, ISBN 0-201-75839-3.
http://partners.adobe.com/asn/developer/acrosdk/docs/filefmtspecs/PDFReference.pdf
[The printed manual for PDF version 1.4.]
Adobe Systems Inc., _Portable Document Format: Changes from Version
1.3 to 1.4_, Adobe Developer Support Technical Note #5409.
June 11, 2001.
http://partners.adobe.com/asn/developer/acrosdk/docs/filefmtspecs/PDF14Deltas.pdf
[Updates for PDF 1.4.]
Version 1.5_.
http://partners.adobe.com/asn/tech/pdf/specifications.jsp
[The manual for PDF version 1.5.]
Adobe Systems Inc., _PostScript Language Reference_, 3rd ed.
Addison-Wesley, 1999, ISBN 0-201-37922-8.
@ -387,9 +309,20 @@ Robert L. Hummel, _Programmer's Technical Reference: Data and Fax
Communications_. Ziff-Davis Press, 1993, ISBN 1-56276-077-7.
[CCITT Group 3 and 4 fax decoding.]
ISO, _Coding of Still Pictures_, IS 14492 Final Committee Draft.
http://www.jpeg.org/fcd14492.pdf
[The final draft of the JBIG2 spec.]
ISO/IEC, _Information technology -- Lossy/lossless coding of bi-level
images_. ISO/IEC 14492, First edition (2001-12-15).
http://webstore.ansi.org/
[The official JBIG2 standard. The final draft of this spec is
available from http://www.jpeg.org/jbighomepage.html.]
ISO/IEC, _Information technology -- JPEG 2000 image coding system --
Part 1: Core coding system_. ISO/IEC 15444-1, First edition
(2000-12-15).
http://webstore.ansi.org/
[The official JPEG 2000 standard. The final committee draft of this
spec is available from http://www.jpeg.org/JPEG2000.html, but there
were changes made to the bitstream format between that draft and the
published spec.]
ITU, "Standardization of Group 3 facsimile terminals for document
transmission", ITU-T Recommendation T.4, 1999.

View file

@ -1 +1 @@
KPDF v0.1
KPDF v0.4

156
fofi/FoFiBase.cc Normal file
View file

@ -0,0 +1,156 @@
//========================================================================
//
// FoFiBase.cc
//
// Copyright 1999-2003 Glyph & Cog, LLC
//
//========================================================================
#include <aconf.h>
#ifdef USE_GCC_PRAGMAS
#pragma implementation
#endif
#include <stdio.h>
#include "gmem.h"
#include "FoFiBase.h"
//------------------------------------------------------------------------
// FoFiBase
//------------------------------------------------------------------------
FoFiBase::FoFiBase(char *fileA, int lenA, GBool freeFileDataA) {
fileData = file = (Guchar *)fileA;
len = lenA;
freeFileData = freeFileDataA;
}
FoFiBase::~FoFiBase() {
if (freeFileData) {
gfree(fileData);
}
}
char *FoFiBase::readFile(char *fileName, int *fileLen) {
FILE *f;
char *buf;
int n;
if (!(f = fopen(fileName, "rb"))) {
return NULL;
}
fseek(f, 0, SEEK_END);
n = (int)ftell(f);
fseek(f, 0, SEEK_SET);
buf = (char *)gmalloc(n);
if ((int)fread(buf, 1, n, f) != n) {
gfree(buf);
fclose(f);
return NULL;
}
fclose(f);
*fileLen = n;
return buf;
}
int FoFiBase::getS8(int pos, GBool *ok) {
int x;
if (pos < 0 || pos >= len) {
*ok = gFalse;
return 0;
}
x = file[pos];
if (x & 0x80) {
x |= ~0xff;
}
return x;
}
int FoFiBase::getU8(int pos, GBool *ok) {
if (pos < 0 || pos >= len) {
*ok = gFalse;
return 0;
}
return file[pos];
}
int FoFiBase::getS16BE(int pos, GBool *ok) {
int x;
if (pos < 0 || pos+1 >= len) {
*ok = gFalse;
return 0;
}
x = file[pos];
x = (x << 8) + file[pos+1];
if (x & 0x8000) {
x |= ~0xffff;
}
return x;
}
int FoFiBase::getU16BE(int pos, GBool *ok) {
int x;
if (pos < 0 || pos+1 >= len) {
*ok = gFalse;
return 0;
}
x = file[pos];
x = (x << 8) + file[pos+1];
return x;
}
int FoFiBase::getS32BE(int pos, GBool *ok) {
int x;
if (pos < 0 || pos+3 >= len) {
*ok = gFalse;
return 0;
}
x = file[pos];
x = (x << 8) + file[pos+1];
x = (x << 8) + file[pos+2];
x = (x << 8) + file[pos+3];
if (x & 0x80000000) {
x |= ~0xffffffff;
}
return x;
}
Guint FoFiBase::getU32BE(int pos, GBool *ok) {
Guint x;
if (pos < 0 || pos+3 >= len) {
*ok = gFalse;
return 0;
}
x = file[pos];
x = (x << 8) + file[pos+1];
x = (x << 8) + file[pos+2];
x = (x << 8) + file[pos+3];
return x;
}
Guint FoFiBase::getUVarBE(int pos, int size, GBool *ok) {
Guint x;
int i;
if (pos < 0 || pos + size > len) {
*ok = gFalse;
return 0;
}
x = 0;
for (i = 0; i < size; ++i) {
x = (x << 8) + file[pos + i];
}
return x;
}
GBool FoFiBase::checkRegion(int pos, int size) {
return pos >= 0 &&
pos + size >= pos &&
pos + size <= len;
}

57
fofi/FoFiBase.h Normal file
View file

@ -0,0 +1,57 @@
//========================================================================
//
// FoFiBase.h
//
// Copyright 1999-2003 Glyph & Cog, LLC
//
//========================================================================
#ifndef FOFIBASE_H
#define FOFIBASE_H
#include <aconf.h>
#ifdef USE_GCC_PRAGMAS
#pragma interface
#endif
#include "gtypes.h"
//------------------------------------------------------------------------
typedef void (*FoFiOutputFunc)(void *stream, char *data, int len);
//------------------------------------------------------------------------
// FoFiBase
//------------------------------------------------------------------------
class FoFiBase {
public:
virtual ~FoFiBase();
protected:
FoFiBase(char *fileA, int lenA, GBool freeFileDataA);
static char *readFile(char *fileName, int *fileLen);
// S = signed / U = unsigned
// 8/16/32/Var = word length, in bytes
// BE = big endian
int getS8(int pos, GBool *ok);
int getU8(int pos, GBool *ok);
int getS16BE(int pos, GBool *ok);
int getU16BE(int pos, GBool *ok);
int getS32BE(int pos, GBool *ok);
Guint getU32BE(int pos, GBool *ok);
Guint getUVarBE(int pos, int size, GBool *ok);
GBool checkRegion(int pos, int size);
Guchar *fileData;
Guchar *file;
int len;
GBool freeFileData;
};
#endif

994
fofi/FoFiEncodings.cc Normal file
View file

@ -0,0 +1,994 @@
//========================================================================
//
// FoFiEncodings.cc
//
// Copyright 1999-2003 Glyph & Cog, LLC
//
//========================================================================
#include <aconf.h>
#ifdef USE_GCC_PRAGMAS
#pragma implementation
#endif
#include <stdlib.h>
#include "FoFiEncodings.h"
//------------------------------------------------------------------------
// Type 1 and 1C font data
//------------------------------------------------------------------------
char *fofiType1StandardEncoding[256] = {
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
"space",
"exclam",
"quotedbl",
"numbersign",
"dollar",
"percent",
"ampersand",
"quoteright",
"parenleft",
"parenright",
"asterisk",
"plus",
"comma",
"hyphen",
"period",
"slash",
"zero",
"one",
"two",
"three",
"four",
"five",
"six",
"seven",
"eight",
"nine",
"colon",
"semicolon",
"less",
"equal",
"greater",
"question",
"at",
"A",
"B",
"C",
"D",
"E",
"F",
"G",
"H",
"I",
"J",
"K",
"L",
"M",
"N",
"O",
"P",
"Q",
"R",
"S",
"T",
"U",
"V",
"W",
"X",
"Y",
"Z",
"bracketleft",
"backslash",
"bracketright",
"asciicircum",
"underscore",
"quoteleft",
"a",
"b",
"c",
"d",
"e",
"f",
"g",
"h",
"i",
"j",
"k",
"l",
"m",
"n",
"o",
"p",
"q",
"r",
"s",
"t",
"u",
"v",
"w",
"x",
"y",
"z",
"braceleft",
"bar",
"braceright",
"asciitilde",
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
"exclamdown",
"cent",
"sterling",
"fraction",
"yen",
"florin",
"section",
"currency",
"quotesingle",
"quotedblleft",
"guillemotleft",
"guilsinglleft",
"guilsinglright",
"fi",
"fl",
NULL,
"endash",
"dagger",
"daggerdbl",
"periodcentered",
NULL,
"paragraph",
"bullet",
"quotesinglbase",
"quotedblbase",
"quotedblright",
"guillemotright",
"ellipsis",
"perthousand",
NULL,
"questiondown",
NULL,
"grave",
"acute",
"circumflex",
"tilde",
"macron",
"breve",
"dotaccent",
"dieresis",
NULL,
"ring",
"cedilla",
NULL,
"hungarumlaut",
"ogonek",
"caron",
"emdash",
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
"AE",
NULL,
"ordfeminine",
NULL,
NULL,
NULL,
NULL,
"Lslash",
"Oslash",
"OE",
"ordmasculine",
NULL,
NULL,
NULL,
NULL,
NULL,
"ae",
NULL,
NULL,
NULL,
"dotlessi",
NULL,
NULL,
"lslash",
"oslash",
"oe",
"germandbls",
NULL,
NULL,
NULL,
NULL
};
char *fofiType1ExpertEncoding[256] = {
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
"space",
"exclamsmall",
"Hungarumlautsmall",
NULL,
"dollaroldstyle",
"dollarsuperior",
"ampersandsmall",
"Acutesmall",
"parenleftsuperior",
"parenrightsuperior",
"twodotenleader",
"onedotenleader",
"comma",
"hyphen",
"period",
"fraction",
"zerooldstyle",
"oneoldstyle",
"twooldstyle",
"threeoldstyle",
"fouroldstyle",
"fiveoldstyle",
"sixoldstyle",
"sevenoldstyle",
"eightoldstyle",
"nineoldstyle",
"colon",
"semicolon",
"commasuperior",
"threequartersemdash",
"periodsuperior",
"questionsmall",
NULL,
"asuperior",
"bsuperior",
"centsuperior",
"dsuperior",
"esuperior",
NULL,
NULL,
NULL,
"isuperior",
NULL,
NULL,
"lsuperior",
"msuperior",
"nsuperior",
"osuperior",
NULL,
NULL,
"rsuperior",
"ssuperior",
"tsuperior",
NULL,
"ff",
"fi",
"fl",
"ffi",
"ffl",
"parenleftinferior",
NULL,
"parenrightinferior",
"Circumflexsmall",
"hyphensuperior",
"Gravesmall",
"Asmall",
"Bsmall",
"Csmall",
"Dsmall",
"Esmall",
"Fsmall",
"Gsmall",
"Hsmall",
"Ismall",
"Jsmall",
"Ksmall",
"Lsmall",
"Msmall",
"Nsmall",
"Osmall",
"Psmall",
"Qsmall",
"Rsmall",
"Ssmall",
"Tsmall",
"Usmall",
"Vsmall",
"Wsmall",
"Xsmall",
"Ysmall",
"Zsmall",
"colonmonetary",
"onefitted",
"rupiah",
"Tildesmall",
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
"exclamdownsmall",
"centoldstyle",
"Lslashsmall",
NULL,
NULL,
"Scaronsmall",
"Zcaronsmall",
"Dieresissmall",
"Brevesmall",
"Caronsmall",
NULL,
"Dotaccentsmall",
NULL,
NULL,
"Macronsmall",
NULL,
NULL,
"figuredash",
"hypheninferior",
NULL,
NULL,
"Ogoneksmall",
"Ringsmall",
"Cedillasmall",
NULL,
NULL,
NULL,
"onequarter",
"onehalf",
"threequarters",
"questiondownsmall",
"oneeighth",
"threeeighths",
"fiveeighths",
"seveneighths",
"onethird",
"twothirds",
NULL,
NULL,
"zerosuperior",
"onesuperior",
"twosuperior",
"threesuperior",
"foursuperior",
"fivesuperior",
"sixsuperior",
"sevensuperior",
"eightsuperior",
"ninesuperior",
"zeroinferior",
"oneinferior",
"twoinferior",
"threeinferior",
"fourinferior",
"fiveinferior",
"sixinferior",
"seveninferior",
"eightinferior",
"nineinferior",
"centinferior",
"dollarinferior",
"periodinferior",
"commainferior",
"Agravesmall",
"Aacutesmall",
"Acircumflexsmall",
"Atildesmall",
"Adieresissmall",
"Aringsmall",
"AEsmall",
"Ccedillasmall",
"Egravesmall",
"Eacutesmall",
"Ecircumflexsmall",
"Edieresissmall",
"Igravesmall",
"Iacutesmall",
"Icircumflexsmall",
"Idieresissmall",
"Ethsmall",
"Ntildesmall",
"Ogravesmall",
"Oacutesmall",
"Ocircumflexsmall",
"Otildesmall",
"Odieresissmall",
"OEsmall",
"Oslashsmall",
"Ugravesmall",
"Uacutesmall",
"Ucircumflexsmall",
"Udieresissmall",
"Yacutesmall",
"Thornsmall",
"Ydieresissmall"
};
//------------------------------------------------------------------------
// Type 1C font data
//------------------------------------------------------------------------
char *fofiType1CStdStrings[391] = {
".notdef",
"space",
"exclam",
"quotedbl",
"numbersign",
"dollar",
"percent",
"ampersand",
"quoteright",
"parenleft",
"parenright",
"asterisk",
"plus",
"comma",
"hyphen",
"period",
"slash",
"zero",
"one",
"two",
"three",
"four",
"five",
"six",
"seven",
"eight",
"nine",
"colon",
"semicolon",
"less",
"equal",
"greater",
"question",
"at",
"A",
"B",
"C",
"D",
"E",
"F",
"G",
"H",
"I",
"J",
"K",
"L",
"M",
"N",
"O",
"P",
"Q",
"R",
"S",
"T",
"U",
"V",
"W",
"X",
"Y",
"Z",
"bracketleft",
"backslash",
"bracketright",
"asciicircum",
"underscore",
"quoteleft",
"a",
"b",
"c",
"d",
"e",
"f",
"g",
"h",
"i",
"j",
"k",
"l",
"m",
"n",
"o",
"p",
"q",
"r",
"s",
"t",
"u",
"v",
"w",
"x",
"y",
"z",
"braceleft",
"bar",
"braceright",
"asciitilde",
"exclamdown",
"cent",
"sterling",
"fraction",
"yen",
"florin",
"section",
"currency",
"quotesingle",
"quotedblleft",
"guillemotleft",
"guilsinglleft",
"guilsinglright",
"fi",
"fl",
"endash",
"dagger",
"daggerdbl",
"periodcentered",
"paragraph",
"bullet",
"quotesinglbase",
"quotedblbase",
"quotedblright",
"guillemotright",
"ellipsis",
"perthousand",
"questiondown",
"grave",
"acute",
"circumflex",
"tilde",
"macron",
"breve",
"dotaccent",
"dieresis",
"ring",
"cedilla",
"hungarumlaut",
"ogonek",
"caron",
"emdash",
"AE",
"ordfeminine",
"Lslash",
"Oslash",
"OE",
"ordmasculine",
"ae",
"dotlessi",
"lslash",
"oslash",
"oe",
"germandbls",
"onesuperior",
"logicalnot",
"mu",
"trademark",
"Eth",
"onehalf",
"plusminus",
"Thorn",
"onequarter",
"divide",
"brokenbar",
"degree",
"thorn",
"threequarters",
"twosuperior",
"registered",
"minus",
"eth",
"multiply",
"threesuperior",
"copyright",
"Aacute",
"Acircumflex",
"Adieresis",
"Agrave",
"Aring",
"Atilde",
"Ccedilla",
"Eacute",
"Ecircumflex",
"Edieresis",
"Egrave",
"Iacute",
"Icircumflex",
"Idieresis",
"Igrave",
"Ntilde",
"Oacute",
"Ocircumflex",
"Odieresis",
"Ograve",
"Otilde",
"Scaron",
"Uacute",
"Ucircumflex",
"Udieresis",
"Ugrave",
"Yacute",
"Ydieresis",
"Zcaron",
"aacute",
"acircumflex",
"adieresis",
"agrave",
"aring",
"atilde",
"ccedilla",
"eacute",
"ecircumflex",
"edieresis",
"egrave",
"iacute",
"icircumflex",
"idieresis",
"igrave",
"ntilde",
"oacute",
"ocircumflex",
"odieresis",
"ograve",
"otilde",
"scaron",
"uacute",
"ucircumflex",
"udieresis",
"ugrave",
"yacute",
"ydieresis",
"zcaron",
"exclamsmall",
"Hungarumlautsmall",
"dollaroldstyle",
"dollarsuperior",
"ampersandsmall",
"Acutesmall",
"parenleftsuperior",
"parenrightsuperior",
"twodotenleader",
"onedotenleader",
"zerooldstyle",
"oneoldstyle",
"twooldstyle",
"threeoldstyle",
"fouroldstyle",
"fiveoldstyle",
"sixoldstyle",
"sevenoldstyle",
"eightoldstyle",
"nineoldstyle",
"commasuperior",
"threequartersemdash",
"periodsuperior",
"questionsmall",
"asuperior",
"bsuperior",
"centsuperior",
"dsuperior",
"esuperior",
"isuperior",
"lsuperior",
"msuperior",
"nsuperior",
"osuperior",
"rsuperior",
"ssuperior",
"tsuperior",
"ff",
"ffi",
"ffl",
"parenleftinferior",
"parenrightinferior",
"Circumflexsmall",
"hyphensuperior",
"Gravesmall",
"Asmall",
"Bsmall",
"Csmall",
"Dsmall",
"Esmall",
"Fsmall",
"Gsmall",
"Hsmall",
"Ismall",
"Jsmall",
"Ksmall",
"Lsmall",
"Msmall",
"Nsmall",
"Osmall",
"Psmall",
"Qsmall",
"Rsmall",
"Ssmall",
"Tsmall",
"Usmall",
"Vsmall",
"Wsmall",
"Xsmall",
"Ysmall",
"Zsmall",
"colonmonetary",
"onefitted",
"rupiah",
"Tildesmall",
"exclamdownsmall",
"centoldstyle",
"Lslashsmall",
"Scaronsmall",
"Zcaronsmall",
"Dieresissmall",
"Brevesmall",
"Caronsmall",
"Dotaccentsmall",
"Macronsmall",
"figuredash",
"hypheninferior",
"Ogoneksmall",
"Ringsmall",
"Cedillasmall",
"questiondownsmall",
"oneeighth",
"threeeighths",
"fiveeighths",
"seveneighths",
"onethird",
"twothirds",
"zerosuperior",
"foursuperior",
"fivesuperior",
"sixsuperior",
"sevensuperior",
"eightsuperior",
"ninesuperior",
"zeroinferior",
"oneinferior",
"twoinferior",
"threeinferior",
"fourinferior",
"fiveinferior",
"sixinferior",
"seveninferior",
"eightinferior",
"nineinferior",
"centinferior",
"dollarinferior",
"periodinferior",
"commainferior",
"Agravesmall",
"Aacutesmall",
"Acircumflexsmall",
"Atildesmall",
"Adieresissmall",
"Aringsmall",
"AEsmall",
"Ccedillasmall",
"Egravesmall",
"Eacutesmall",
"Ecircumflexsmall",
"Edieresissmall",
"Igravesmall",
"Iacutesmall",
"Icircumflexsmall",
"Idieresissmall",
"Ethsmall",
"Ntildesmall",
"Ogravesmall",
"Oacutesmall",
"Ocircumflexsmall",
"Otildesmall",
"Odieresissmall",
"OEsmall",
"Oslashsmall",
"Ugravesmall",
"Uacutesmall",
"Ucircumflexsmall",
"Udieresissmall",
"Yacutesmall",
"Thornsmall",
"Ydieresissmall",
"001.000",
"001.001",
"001.002",
"001.003",
"Black",
"Bold",
"Book",
"Light",
"Medium",
"Regular",
"Roman",
"Semibold"
};
Gushort fofiType1CISOAdobeCharset[229] = {
0, 1, 2, 3, 4, 5, 6, 7, 8, 9,
10, 11, 12, 13, 14, 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, 46, 47, 48, 49,
50, 51, 52, 53, 54, 55, 56, 57, 58, 59,
60, 61, 62, 63, 64, 65, 66, 67, 68, 69,
70, 71, 72, 73, 74, 75, 76, 77, 78, 79,
80, 81, 82, 83, 84, 85, 86, 87, 88, 89,
90, 91, 92, 93, 94, 95, 96, 97, 98, 99,
100, 101, 102, 103, 104, 105, 106, 107, 108, 109,
110, 111, 112, 113, 114, 115, 116, 117, 118, 119,
120, 121, 122, 123, 124, 125, 126, 127, 128, 129,
130, 131, 132, 133, 134, 135, 136, 137, 138, 139,
140, 141, 142, 143, 144, 145, 146, 147, 148, 149,
150, 151, 152, 153, 154, 155, 156, 157, 158, 159,
160, 161, 162, 163, 164, 165, 166, 167, 168, 169,
170, 171, 172, 173, 174, 175, 176, 177, 178, 179,
180, 181, 182, 183, 184, 185, 186, 187, 188, 189,
190, 191, 192, 193, 194, 195, 196, 197, 198, 199,
200, 201, 202, 203, 204, 205, 206, 207, 208, 209,
210, 211, 212, 213, 214, 215, 216, 217, 218, 219,
220, 221, 222, 223, 224, 225, 226, 227, 228
};
Gushort fofiType1CExpertCharset[166] = {
0, 1, 229, 230, 231, 232, 233, 234, 235, 236,
237, 238, 13, 14, 15, 99, 239, 240, 241, 242,
243, 244, 245, 246, 247, 248, 27, 28, 249, 250,
251, 252, 253, 254, 255, 256, 257, 258, 259, 260,
261, 262, 263, 264, 265, 266, 109, 110, 267, 268,
269, 270, 271, 272, 273, 274, 275, 276, 277, 278,
279, 280, 281, 282, 283, 284, 285, 286, 287, 288,
289, 290, 291, 292, 293, 294, 295, 296, 297, 298,
299, 300, 301, 302, 303, 304, 305, 306, 307, 308,
309, 310, 311, 312, 313, 314, 315, 316, 317, 318,
158, 155, 163, 319, 320, 321, 322, 323, 324, 325,
326, 150, 164, 169, 327, 328, 329, 330, 331, 332,
333, 334, 335, 336, 337, 338, 339, 340, 341, 342,
343, 344, 345, 346, 347, 348, 349, 350, 351, 352,
353, 354, 355, 356, 357, 358, 359, 360, 361, 362,
363, 364, 365, 366, 367, 368, 369, 370, 371, 372,
373, 374, 375, 376, 377, 378
};
Gushort fofiType1CExpertSubsetCharset[87] = {
0, 1, 231, 232, 235, 236, 237, 238, 13, 14,
15, 99, 239, 240, 241, 242, 243, 244, 245, 246,
247, 248, 27, 28, 249, 250, 251, 253, 254, 255,
256, 257, 258, 259, 260, 261, 262, 263, 264, 265,
266, 109, 110, 267, 268, 269, 270, 272, 300, 301,
302, 305, 314, 315, 158, 155, 163, 320, 321, 322,
323, 324, 325, 326, 150, 164, 169, 327, 328, 329,
330, 331, 332, 333, 334, 335, 336, 337, 338, 339,
340, 341, 342, 343, 344, 345, 346
};

36
fofi/FoFiEncodings.h Normal file
View file

@ -0,0 +1,36 @@
//========================================================================
//
// FoFiEncodings.h
//
// Copyright 1999-2003 Glyph & Cog, LLC
//
//========================================================================
#ifndef FOFIENCODINGS_H
#define FOFIENCODINGS_H
#include <aconf.h>
#ifdef USE_GCC_PRAGMAS
#pragma interface
#endif
#include "gtypes.h"
//------------------------------------------------------------------------
// Type 1 and 1C font data
//------------------------------------------------------------------------
extern char *fofiType1StandardEncoding[256];
extern char *fofiType1ExpertEncoding[256];
//------------------------------------------------------------------------
// Type 1C font data
//------------------------------------------------------------------------
extern char *fofiType1CStdStrings[391];
extern Gushort fofiType1CISOAdobeCharset[229];
extern Gushort fofiType1CExpertCharset[166];
extern Gushort fofiType1CExpertSubsetCharset[87];
#endif

1438
fofi/FoFiTrueType.cc Normal file

File diff suppressed because it is too large Load diff

133
fofi/FoFiTrueType.h Normal file
View file

@ -0,0 +1,133 @@
//========================================================================
//
// FoFiTrueType.h
//
// Copyright 1999-2003 Glyph & Cog, LLC
//
//========================================================================
#ifndef FOFITRUETYPE_H
#define FOFITRUETYPE_H
#include <aconf.h>
#ifdef USE_GCC_PRAGMAS
#pragma interface
#endif
#include "gtypes.h"
#include "FoFiBase.h"
class GHash;
struct TrueTypeTable;
struct TrueTypeCmap;
//------------------------------------------------------------------------
// FoFiTrueType
//------------------------------------------------------------------------
class FoFiTrueType: public FoFiBase {
public:
// Create a FoFiTrueType object from a memory buffer.
static FoFiTrueType *make(char *fileA, int lenA);
// Create a FoFiTrueType object from a file on disk.
static FoFiTrueType *load(char *fileName);
virtual ~FoFiTrueType();
// Return the number of cmaps defined by this font.
int getNumCmaps();
// Return the platform ID of the <i>th cmap.
int getCmapPlatform(int i);
// Return the encoding ID of the <i>th cmap.
int getCmapEncoding(int i);
// Return the index of the cmap for <platform>, <encoding>. Returns
// -1 if there is no corresponding cmap.
int findCmap(int platform, int encoding);
// Return the GID corresponding to <c> according to the <i>th cmap.
Gushort mapCodeToGID(int i, int c);
// Returns the GID corresponding to <name> according to the post
// table. Returns 0 if there is no mapping for <name> or if the
// font does not have a post table.
int mapNameToGID(char *name);
// Returns the least restrictive embedding licensing right (as
// defined by the TrueType spec):
// * 4: OS/2 table is missing or invalid
// * 3: installable embedding
// * 2: editable embedding
// * 1: preview & print embedding
// * 0: restricted license embedding
int getEmbeddingRights();
// Convert to a Type 42 font, suitable for embedding in a PostScript
// file. <psName> will be used as the PostScript font name (so we
// don't need to depend on the 'name' table in the font). The
// <encoding> array specifies the mapping from char codes to names.
// If <encoding> is NULL, the encoding is unknown or undefined. The
// <codeToGID> array specifies the mapping from char codes to GIDs.
void convertToType42(char *psName, char **encoding,
Gushort *codeToGID,
FoFiOutputFunc outputFunc, void *outputStream);
// Convert to a Type 2 CIDFont, suitable for embedding in a
// PostScript file. <psName> will be used as the PostScript font
// name (so we don't need to depend on the 'name' table in the
// font). The <cidMap> array maps CIDs to GIDs; it has <nCIDs>
// entries.
void convertToCIDType2(char *psName, Gushort *cidMap, int nCIDs,
FoFiOutputFunc outputFunc, void *outputStream);
// Convert to a Type 0 (but non-CID) composite font, suitable for
// embedding in a PostScript file. <psName> will be used as the
// PostScript font name (so we don't need to depend on the 'name'
// table in the font). The <cidMap> array maps CIDs to GIDs; it has
// <nCIDs> entries.
void convertToType0(char *psName, Gushort *cidMap, int nCIDs,
FoFiOutputFunc outputFunc, void *outputStream);
// Write a clean TTF file, filling in missing tables and correcting
// various other errors. If the font is complete and correct, it
// will be written unmodified.
void writeTTF(FoFiOutputFunc outputFunc, void *outputStream);
private:
FoFiTrueType(char *fileA, int lenA, GBool freeFileDataA);
void cvtEncoding(char **encoding,
FoFiOutputFunc outputFunc,
void *outputStream);
void cvtCharStrings(char **encoding,
Gushort *codeToGID,
FoFiOutputFunc outputFunc,
void *outputStream);
void cvtSfnts(FoFiOutputFunc outputFunc,
void *outputStream, GString *name);
void dumpString(Guchar *s, int length,
FoFiOutputFunc outputFunc,
void *outputStream);
Guint computeTableChecksum(Guchar *data, int length);
void parse();
void readPostTable();
int seekTable(char *tag);
TrueTypeTable *tables;
int nTables;
TrueTypeCmap *cmaps;
int nCmaps;
int nGlyphs;
int locaFmt;
int bbox[4];
GHash *nameToGID;
GBool parsedOk;
};
#endif

207
fofi/FoFiType1.cc Normal file
View file

@ -0,0 +1,207 @@
//========================================================================
//
// FoFiType1.cc
//
// Copyright 1999-2003 Glyph & Cog, LLC
//
//========================================================================
#include <aconf.h>
#ifdef USE_GCC_PRAGMAS
#pragma implementation
#endif
#include <stdlib.h>
#include <string.h>
#include "gmem.h"
#include "FoFiEncodings.h"
#include "FoFiType1.h"
//------------------------------------------------------------------------
// FoFiType1
//------------------------------------------------------------------------
FoFiType1 *FoFiType1::make(char *fileA, int lenA) {
return new FoFiType1(fileA, lenA, gFalse);
}
FoFiType1 *FoFiType1::load(char *fileName) {
char *fileA;
int lenA;
if (!(fileA = FoFiBase::readFile(fileName, &lenA))) {
return NULL;
}
return new FoFiType1(fileA, lenA, gTrue);
}
FoFiType1::FoFiType1(char *fileA, int lenA, GBool freeFileDataA):
FoFiBase(fileA, lenA, freeFileDataA)
{
name = NULL;
encoding = NULL;
parsed = gFalse;
}
FoFiType1::~FoFiType1() {
int i;
if (name) {
gfree(name);
}
if (encoding && encoding != fofiType1StandardEncoding) {
for (i = 0; i < 256; ++i) {
gfree(encoding[i]);
}
gfree(encoding);
}
}
char *FoFiType1::getName() {
if (!parsed) {
parse();
}
return name;
}
char **FoFiType1::getEncoding() {
if (!parsed) {
parse();
}
return encoding;
}
void FoFiType1::writeEncoded(char **newEncoding,
FoFiOutputFunc outputFunc, void *outputStream) {
char buf[512];
char *line;
int i;
// copy everything up to the encoding
for (line = (char *)file;
line && strncmp(line, "/Encoding", 9);
line = getNextLine(line)) ;
if (!line) {
// no encoding - just copy the whole font file
(*outputFunc)(outputStream, (char *)file, len);
return;
}
(*outputFunc)(outputStream, (char *)file, line - (char *)file);
// write the new encoding
(*outputFunc)(outputStream, "/Encoding 256 array\n", 20);
(*outputFunc)(outputStream,
"0 1 255 {1 index exch /.notdef put} for\n", 40);
for (i = 0; i < 256; ++i) {
if (newEncoding[i]) {
sprintf(buf, "dup %d /%s put\n", i, newEncoding[i]);
(*outputFunc)(outputStream, buf, strlen(buf));
}
}
(*outputFunc)(outputStream, "readonly def\n", 13);
// copy everything after the encoding
if (!strncmp(line, "/Encoding StandardEncoding def", 30)) {
line = getNextLine(line);
} else {
for (line = getNextLine(line);
line && strncmp(line, "readonly def", 12);
line = getNextLine(line)) ;
}
if (line) {
(*outputFunc)(outputStream, line, ((char *)file + len) - line);
}
}
char *FoFiType1::getNextLine(char *line) {
while (line < (char *)file + len && *line != '\x0a' && *line != '\x0d') {
++line;
}
if (line < (char *)file + len && *line == '\x0d') {
++line;
}
if (line < (char *)file + len && *line == '\x0a') {
++line;
}
if (line >= (char *)file + len) {
return NULL;
}
return line;
}
void FoFiType1::parse() {
char *line, *line1, *p, *p2;
char buf[256];
char c;
int n, code, i, j;
for (i = 1, line = (char *)file;
i <= 100 && line && (!name || !encoding);
++i) {
// get font name
if (!name && !strncmp(line, "/FontName", 9)) {
strncpy(buf, line, 255);
buf[255] = '\0';
if ((p = strchr(buf+9, '/')) &&
(p = strtok(p+1, " \t\n\r"))) {
name = copyString(p);
}
line = getNextLine(line);
// get encoding
} else if (!encoding &&
!strncmp(line, "/Encoding StandardEncoding def", 30)) {
encoding = fofiType1StandardEncoding;
} else if (!encoding &&
!strncmp(line, "/Encoding 256 array", 19)) {
encoding = (char **)gmalloc(256 * sizeof(char *));
for (j = 0; j < 256; ++j) {
encoding[j] = NULL;
}
line = getNextLine(line);
for (j = 0; j < 300 && line; ++j) {
line1 = getNextLine(line);
if ((n = line1 - line) > 255) {
n = 255;
}
strncpy(buf, line, n);
buf[n] = '\0';
for (p = buf; *p == ' ' || *p == '\t'; ++p) ;
if (!strncmp(p, "dup", 3)) {
for (p += 3; *p == ' ' || *p == '\t'; ++p) ;
for (p2 = p; *p2 >= '0' && *p2 <= '9'; ++p2) ;
if (*p2) {
c = *p2;
*p2 = '\0';
if ((code = atoi(p)) < 256) {
*p2 = c;
for (p = p2; *p == ' ' || *p == '\t'; ++p) ;
if (*p == '/') {
++p;
for (p2 = p; *p2 && *p2 != ' ' && *p2 != '\t'; ++p2) ;
*p2 = '\0';
encoding[code] = copyString(p);
}
}
}
} else {
if (strtok(buf, " \t") &&
(p = strtok(NULL, " \t\n\r")) && !strcmp(p, "def")) {
break;
}
}
line = line1;
}
//~ check for getinterval/putinterval junk
} else {
line = getNextLine(line);
}
++i;
}
parsed = gTrue;
}

59
fofi/FoFiType1.h Normal file
View file

@ -0,0 +1,59 @@
//========================================================================
//
// FoFiType1.h
//
// Copyright 1999-2003 Glyph & Cog, LLC
//
//========================================================================
#ifndef FOFITYPE1_H
#define FOFITYPE1_H
#include <aconf.h>
#ifdef USE_GCC_PRAGMAS
#pragma interface
#endif
#include "gtypes.h"
#include "FoFiBase.h"
//------------------------------------------------------------------------
// FoFiType1
//------------------------------------------------------------------------
class FoFiType1: public FoFiBase {
public:
// Create a FoFiType1 object from a memory buffer.
static FoFiType1 *make(char *fileA, int lenA);
// Create a FoFiType1 object from a file on disk.
static FoFiType1 *load(char *fileName);
virtual ~FoFiType1();
// Return the font name.
char *getName();
// Return the encoding, as an array of 256 names (any of which may
// be NULL).
char **getEncoding();
// Write a version of the Type 1 font file with a new encoding.
void writeEncoded(char **newEncoding,
FoFiOutputFunc outputFunc, void *outputStream);
private:
FoFiType1(char *fileA, int lenA, GBool freeFileDataA);
char *getNextLine(char *line);
void parse();
char *name;
char **encoding;
GBool parsed;
};
#endif

2385
fofi/FoFiType1C.cc Normal file

File diff suppressed because it is too large Load diff

226
fofi/FoFiType1C.h Normal file
View file

@ -0,0 +1,226 @@
//========================================================================
//
// FoFiType1C.h
//
// Copyright 1999-2003 Glyph & Cog, LLC
//
//========================================================================
#ifndef FOFITYPE1C_H
#define FOFITYPE1C_H
#include <aconf.h>
#ifdef USE_GCC_PRAGMAS
#pragma interface
#endif
#include "gtypes.h"
#include "FoFiBase.h"
class GString;
//------------------------------------------------------------------------
struct Type1CIndex {
int pos; // absolute position in file
int len; // length (number of entries)
int offSize; // offset size
int startPos; // position of start of index data - 1
int endPos; // position one byte past end of the index
};
struct Type1CIndexVal {
int pos; // absolute position in file
int len; // length, in bytes
};
struct Type1CTopDict {
int firstOp;
int versionSID;
int noticeSID;
int copyrightSID;
int fullNameSID;
int familyNameSID;
int weightSID;
int isFixedPitch;
double italicAngle;
double underlinePosition;
double underlineThickness;
int paintType;
int charstringType;
double fontMatrix[6];
int uniqueID;
double fontBBox[4];
double strokeWidth;
int charsetOffset;
int encodingOffset;
int charStringsOffset;
int privateSize;
int privateOffset;
// CIDFont entries
int registrySID;
int orderingSID;
int supplement;
int fdArrayOffset;
int fdSelectOffset;
};
#define type1CMaxBlueValues 14
#define type1CMaxOtherBlues 10
#define type1CMaxStemSnap 12
struct Type1CPrivateDict {
int blueValues[type1CMaxBlueValues];
int nBlueValues;
int otherBlues[type1CMaxOtherBlues];
int nOtherBlues;
int familyBlues[type1CMaxBlueValues];
int nFamilyBlues;
int familyOtherBlues[type1CMaxOtherBlues];
int nFamilyOtherBlues;
double blueScale;
int blueShift;
int blueFuzz;
double stdHW;
GBool hasStdHW;
double stdVW;
GBool hasStdVW;
double stemSnapH[type1CMaxStemSnap];
int nStemSnapH;
double stemSnapV[type1CMaxStemSnap];
int nStemSnapV;
GBool forceBold;
GBool hasForceBold;
double forceBoldThreshold;
int languageGroup;
double expansionFactor;
int initialRandomSeed;
int subrsOffset;
double defaultWidthX;
GBool defaultWidthXFP;
double nominalWidthX;
GBool nominalWidthXFP;
};
struct Type1COp {
GBool isNum; // true -> number, false -> operator
GBool isFP; // true -> floating point number, false -> int
union {
double num; // if num is true
int op; // if num is false
};
};
struct Type1CEexecBuf {
FoFiOutputFunc outputFunc;
void *outputStream;
GBool ascii; // ASCII encoding?
Gushort r1; // eexec encryption key
int line; // number of eexec chars left on current line
};
//------------------------------------------------------------------------
// FoFiType1C
//------------------------------------------------------------------------
class FoFiType1C: public FoFiBase {
public:
// Create a FoFiType1C object from a memory buffer.
static FoFiType1C *make(char *fileA, int lenA);
// Create a FoFiType1C object from a file on disk.
static FoFiType1C *load(char *fileName);
virtual ~FoFiType1C();
// Return the font name.
char *getName();
// Return the encoding, as an array of 256 names (any of which may
// be NULL). This is only useful with 8-bit fonts.
char **getEncoding();
// Return the mapping from CIDs to GIDs, and return the number of
// CIDs in *<nCIDs>. This is only useful for CID fonts.
Gushort *getCIDToGIDMap(int *nCIDs);
// Convert to a Type 1 font, suitable for embedding in a PostScript
// file. This is only useful with 8-bit fonts. If <newEncoding> is
// not NULL, it will be used in place of the encoding in the Type 1C
// font. If <ascii> is true the eexec section will be hex-encoded,
// otherwise it will be left as binary data.
void convertToType1(char **newEncoding, GBool ascii,
FoFiOutputFunc outputFunc, void *outputStream);
// Convert to a Type 0 CIDFont, suitable for embedding in a
// PostScript file. <psName> will be used as the PostScript font
// name.
void convertToCIDType0(char *psName,
FoFiOutputFunc outputFunc, void *outputStream);
// Convert to a Type 0 (but non-CID) composite font, suitable for
// embedding in a PostScript file. <psName> will be used as the
// PostScript font name.
void convertToType0(char *psName,
FoFiOutputFunc outputFunc, void *outputStream);
private:
FoFiType1C(char *fileA, int lenA, GBool freeFileDataA);
void eexecCvtGlyph(Type1CEexecBuf *eb, char *glyphName,
int offset, int nBytes,
Type1CIndex *subrIdx,
Type1CPrivateDict *pDict);
void cvtGlyph(int offset, int nBytes, GString *charBuf,
Type1CIndex *subrIdx, Type1CPrivateDict *pDict,
GBool top);
void cvtGlyphWidth(GBool useOp, GString *charBuf,
Type1CPrivateDict *pDict);
void cvtNum(double x, GBool isFP, GString *charBuf);
void eexecWrite(Type1CEexecBuf *eb, char *s);
void eexecWriteCharstring(Type1CEexecBuf *eb, Guchar *s, int n);
GBool parse();
void readTopDict();
void readFD(int offset, int length, Type1CPrivateDict *pDict);
void readPrivateDict(int offset, int length, Type1CPrivateDict *pDict);
void readFDSelect();
void buildEncoding();
GBool readCharset();
int getOp(int pos, GBool charstring, GBool *ok);
int getDeltaIntArray(int *arr, int maxLen);
int getDeltaFPArray(double *arr, int maxLen);
void getIndex(int pos, Type1CIndex *idx, GBool *ok);
void getIndexVal(Type1CIndex *idx, int i, Type1CIndexVal *val, GBool *ok);
char *getString(int sid, char *buf, GBool *ok);
GString *name;
char **encoding;
Type1CIndex nameIdx;
Type1CIndex topDictIdx;
Type1CIndex stringIdx;
Type1CIndex gsubrIdx;
Type1CIndex charStringsIdx;
Type1CTopDict topDict;
Type1CPrivateDict *privateDicts;
int nGlyphs;
int nFDs;
Guchar *fdSelect;
Gushort *charset;
int gsubrBias;
GBool parsedOk;
Type1COp ops[49]; // operands and operator
int nOps; // number of operands
int nHints; // number of hints for the current glyph
GBool firstOp; // true if we haven't hit the first op yet
};
#endif

10
fofi/Makefile.am Normal file
View file

@ -0,0 +1,10 @@
INCLUDES = -I.. -I$(srcdir)/../goo $(all_includes)
libfofi_la_LDFLAGS = $(all_libraries)
libfofi_la_SOURCES = FoFiBase.cc FoFiEncodings.cc FoFiTrueType.cc \
FoFiType1.cc FoFiType1C.cc
libfofi_la_COMPILE_FIRST = ../aconf.h
METASOURCES = AUTO
noinst_LTLIBRARIES = libfofi.la

View file

@ -19,8 +19,11 @@
//------------------------------------------------------------------------
struct GHashBucket {
const GString *key;
void *val;
GString *key;
union {
void *p;
int i;
} val;
GHashBucket *next;
};
@ -61,62 +64,84 @@ GHash::~GHash() {
}
void GHash::add(GString *key, void *val) {
GHashBucket **oldTab;
GHashBucket *p;
int oldSize, i, h;
int h;
// expand the table if necessary
if (len >= size) {
oldSize = size;
oldTab = tab;
size = 2*size + 1;
tab = (GHashBucket **)gmalloc(size * sizeof(GHashBucket *));
for (h = 0; h < size; ++h) {
tab[h] = NULL;
}
for (i = 0; i < oldSize; ++i) {
while (oldTab[i]) {
p = oldTab[i];
oldTab[i] = oldTab[i]->next;
h = hash(p->key);
p->next = tab[h];
tab[h] = p;
}
}
gfree(oldTab);
expand();
}
// add the new symbol
p = new GHashBucket;
p->key = key;
p->val = val;
p->val.p = val;
h = hash(key);
p->next = tab[h];
tab[h] = p;
++len;
}
void *GHash::lookup(const GString *key) {
void GHash::add(GString *key, int val) {
GHashBucket *p;
int h;
// expand the table if necessary
if (len >= size) {
expand();
}
// add the new symbol
p = new GHashBucket;
p->key = key;
p->val.i = val;
h = hash(key);
p->next = tab[h];
tab[h] = p;
++len;
}
void *GHash::lookup(GString *key) {
GHashBucket *p;
int h;
if (!(p = find(key, &h))) {
return NULL;
}
return p->val;
return p->val.p;
}
void *GHash::lookup(const char *key) {
int GHash::lookupInt(GString *key) {
GHashBucket *p;
int h;
if (!(p = find(key, &h))) {
return 0;
}
return p->val.i;
}
void *GHash::lookup(char *key) {
GHashBucket *p;
int h;
if (!(p = find(key, &h))) {
return NULL;
}
return p->val;
return p->val.p;
}
void *GHash::remove(const GString *key) {
int GHash::lookupInt(char *key) {
GHashBucket *p;
int h;
if (!(p = find(key, &h))) {
return 0;
}
return p->val.i;
}
void *GHash::remove(GString *key) {
GHashBucket *p;
GHashBucket **q;
void *val;
@ -133,13 +158,36 @@ void *GHash::remove(const GString *key) {
if (deleteKeys) {
delete p->key;
}
val = p->val;
val = p->val.p;
delete p;
--len;
return val;
}
void *GHash::remove(const char *key) {
int GHash::removeInt(GString *key) {
GHashBucket *p;
GHashBucket **q;
int val;
int h;
if (!(p = find(key, &h))) {
return 0;
}
q = &tab[h];
while (*q != p) {
q = &((*q)->next);
}
*q = p->next;
if (deleteKeys) {
delete p->key;
}
val = p->val.i;
delete p;
--len;
return val;
}
void *GHash::remove(char *key) {
GHashBucket *p;
GHashBucket **q;
void *val;
@ -156,7 +204,30 @@ void *GHash::remove(const char *key) {
if (deleteKeys) {
delete p->key;
}
val = p->val;
val = p->val.p;
delete p;
--len;
return val;
}
int GHash::removeInt(char *key) {
GHashBucket *p;
GHashBucket **q;
int val;
int h;
if (!(p = find(key, &h))) {
return 0;
}
q = &tab[h];
while (*q != p) {
q = &((*q)->next);
}
*q = p->next;
if (deleteKeys) {
delete p->key;
}
val = p->val.i;
delete p;
--len;
return val;
@ -168,7 +239,7 @@ void GHash::startIter(GHashIter **iter) {
(*iter)->p = NULL;
}
GBool GHash::getNext(GHashIter **iter, const GString **key, void **val) {
GBool GHash::getNext(GHashIter **iter, GString **key, void **val) {
if (!*iter) {
return gFalse;
}
@ -184,7 +255,27 @@ GBool GHash::getNext(GHashIter **iter, const GString **key, void **val) {
(*iter)->p = tab[(*iter)->h];
}
*key = (*iter)->p->key;
*val = (*iter)->p->val;
*val = (*iter)->p->val.p;
return gTrue;
}
GBool GHash::getNext(GHashIter **iter, GString **key, int *val) {
if (!*iter) {
return gFalse;
}
if ((*iter)->p) {
(*iter)->p = (*iter)->p->next;
}
while (!(*iter)->p) {
if (++(*iter)->h == size) {
delete *iter;
*iter = NULL;
return gFalse;
}
(*iter)->p = tab[(*iter)->h];
}
*key = (*iter)->p->key;
*val = (*iter)->p->val.i;
return gTrue;
}
@ -193,7 +284,31 @@ void GHash::killIter(GHashIter **iter) {
*iter = NULL;
}
GHashBucket *GHash::find(const GString *key, int *h) {
void GHash::expand() {
GHashBucket **oldTab;
GHashBucket *p;
int oldSize, h, i;
oldSize = size;
oldTab = tab;
size = 2*size + 1;
tab = (GHashBucket **)gmalloc(size * sizeof(GHashBucket *));
for (h = 0; h < size; ++h) {
tab[h] = NULL;
}
for (i = 0; i < oldSize; ++i) {
while (oldTab[i]) {
p = oldTab[i];
oldTab[i] = oldTab[i]->next;
h = hash(p->key);
p->next = tab[h];
tab[h] = p;
}
}
gfree(oldTab);
}
GHashBucket *GHash::find(GString *key, int *h) {
GHashBucket *p;
*h = hash(key);
@ -205,7 +320,7 @@ GHashBucket *GHash::find(const GString *key, int *h) {
return NULL;
}
GHashBucket *GHash::find(const char *key, int *h) {
GHashBucket *GHash::find(char *key, int *h) {
GHashBucket *p;
*h = hash(key);
@ -217,8 +332,8 @@ GHashBucket *GHash::find(const char *key, int *h) {
return NULL;
}
int GHash::hash(const GString *key) {
const char *p;
int GHash::hash(GString *key) {
char *p;
unsigned int h;
int i;
@ -229,8 +344,8 @@ int GHash::hash(const GString *key) {
return (int)(h % size);
}
int GHash::hash(const char *key) {
const char *p;
int GHash::hash(char *key) {
char *p;
unsigned int h;
h = 0;

View file

@ -29,21 +29,28 @@ public:
GHash(GBool deleteKeysA = gFalse);
~GHash();
void add(GString *key, void *val);
void *lookup(const GString *key);
void *lookup(const char *key);
void *remove(const GString *key);
void *remove(const char *key);
void add(GString *key, int val);
void *lookup(GString *key);
int lookupInt(GString *key);
void *lookup(char *key);
int lookupInt(char *key);
void *remove(GString *key);
int removeInt(GString *key);
void *remove(char *key);
int removeInt(char *key);
int getLength() { return len; }
void startIter(GHashIter **iter);
GBool getNext(GHashIter **iter, const GString **key, void **val);
GBool getNext(GHashIter **iter, GString **key, void **val);
GBool getNext(GHashIter **iter, GString **key, int *val);
void killIter(GHashIter **iter);
private:
GHashBucket *find(const GString *key, int *h);
GHashBucket *find(const char *key, int *h);
int hash(const GString *key);
int hash(const char *key);
void expand();
GHashBucket *find(GString *key, int *h);
GHashBucket *find(char *key, int *h);
int hash(GString *key);
int hash(char *key);
GBool deleteKeys; // set if key strings should be deleted
int size; // number of buckets
@ -56,7 +63,7 @@ private:
GHash *_hash = (hash); \
{ \
GHashIter *_iter; \
const GString *_key; \
GString *_key; \
void *_p; \
_hash->startIter(&_iter); \
while (_hash->getNext(&_iter, &_key, &_p)) { \

49
goo/GMutex.h Normal file
View file

@ -0,0 +1,49 @@
//========================================================================
//
// GMutex.h
//
// Portable mutex macros.
//
// Copyright 2002-2003 Glyph & Cog, LLC
//
//========================================================================
#ifndef GMUTEX_H
#define GMUTEX_H
// Usage:
//
// GMutex m;
// gInitMutex(&m);
// ...
// gLockMutex(&m);
// ... critical section ...
// gUnlockMutex(&m);
// ...
// gDestroyMutex(&m);
#ifdef WIN32
#include <windows.h>
typedef CRITICAL_SECTION GMutex;
#define gInitMutex(m) InitializeCriticalSection(m)
#define gDestroyMutex(m) DeleteCriticalSection(m)
#define gLockMutex(m) EnterCriticalSection(m)
#define gUnlockMutex(m) LeaveCriticalSection(m)
#else // assume pthreads
#include <pthread.h>
typedef pthread_mutex_t GMutex;
#define gInitMutex(m) pthread_mutex_init(m, NULL)
#define gDestroyMutex(m) pthread_mutex_destroy(m)
#define gLockMutex(m) pthread_mutex_lock(m)
#define gUnlockMutex(m) pthread_mutex_unlock(m)
#endif
#endif

View file

@ -49,11 +49,10 @@ public:
~GString();
// Get length.
int getLength() const { return length; }
int getLength() { return length; }
// Get C string.
const char *getCString() const { return s; }
char *getCString() { return s; }
char *getCString() { return s; }
// Get <i>th character.
char getChar(int i) { return s[i]; }
@ -85,10 +84,10 @@ public:
// Compare two strings: -1:< 0:= +1:>
// These functions assume the strings do not contain null characters.
int cmp(const GString *str) const { return strcmp(s, str->getCString()); }
int cmpN(const GString *str, int n) const { return strncmp(s, str->getCString(), n); }
int cmp(const char *sA) const { return strcmp(s, sA); }
int cmpN(const char *sA, int n) const { return strncmp(s, sA, n); }
int cmp(GString *str) { return strcmp(s, str->getCString()); }
int cmpN(GString *str, int n) { return strncmp(s, str->getCString(), n); }
int cmp(const char *sA) { return strcmp(s, sA); }
int cmpN(const char *sA, int n) { return strncmp(s, sA, n); }
private:

View file

@ -1,12 +1,6 @@
INCLUDES = -I.. $(all_includes)
INCLUDES = -I..
libgoo_la_LDFLAGS = $(all_libraries) -no-undefined
libgoo_la_SOURCES = GHash.cc GList.cc GString.cc gfile.cc gmem.c gmempp.cc \
parseargs.c
libgoo_la_SOURCES = GHash.cc GList.cc GString.cc gfile.cc gmem.c gmempp.cc
libgoo_la_COMPILE_FIRST = ../aconf.h
noinst_LTLIBRARIES = libgoo.la
noinst_HEADERS = GHash.h GList.h GString.h gfile.h gmem.h gtypes.h \
parseargs.h
METASOURCES = AUTO

View file

@ -10,13 +10,7 @@
#include <aconf.h>
#ifdef WIN32
extern "C" {
# ifndef _MSC_VER
# include <kpathsea/win32lib.h>
# endif
}
#else // !WIN32
#ifndef WIN32
# if defined(MACOS)
# include <sys/stat.h>
# elif !defined(ACORN)
@ -108,7 +102,7 @@ GString *getCurrentDir() {
return new GString();
}
GString *appendToPath(GString *path, const char *fileName) {
GString *appendToPath(GString *path, char *fileName) {
#if defined(VMS)
//---------- VMS ----------
//~ this should handle everything necessary for file
@ -487,7 +481,7 @@ GBool openTempFile(GString **name, FILE **f, char *mode, char *ext) {
int fd;
if (ext) {
#ifdef HAVE_MKSTEMPS
#if HAVE_MKSTEMPS
if ((s = getenv("TMPDIR"))) {
*name = new GString(s);
} else {
@ -647,10 +641,14 @@ GDirEntry *GDir::getNextEntry() {
GDirEntry *e;
#if defined(WIN32)
e = new GDirEntry(path->getCString(), ffd.cFileName, doStat);
if (hnd && !FindNextFile(hnd, &ffd)) {
FindClose(hnd);
hnd = NULL;
if (hnd) {
e = new GDirEntry(path->getCString(), ffd.cFileName, doStat);
if (hnd && !FindNextFile(hnd, &ffd)) {
FindClose(hnd);
hnd = NULL;
}
} else {
e = NULL;
}
#elif defined(ACORN)
#elif defined(MACOS)
@ -694,6 +692,7 @@ void GDir::rewind() {
tmp = path->copy();
tmp->append("/*.*");
hnd = FindFirstFile(tmp->getCString(), &ffd);
delete tmp;
#elif defined(ACORN)
#elif defined(MACOS)
#else

View file

@ -60,7 +60,7 @@ extern GString *getCurrentDir();
// Append a file name to a path string. <path> may be an empty
// string, denoting the current directory). Returns <path>.
extern GString *appendToPath(GString *path, const char *fileName);
extern GString *appendToPath(GString *path, char *fileName);
// Grab the path from the front of the file name. If there is no
// directory component in <fileName>, returns an empty string.

View file

@ -195,7 +195,7 @@ void gMemReport(FILE *f) {
}
#endif
char *copyString(const char *s) {
char *copyString(char *s) {
char *s1;
s1 = (char *)gmalloc(strlen(s) + 1);

View file

@ -44,7 +44,7 @@ extern void gMemReport(FILE *f);
/*
* Allocate memory and copy a string into it.
*/
extern char *copyString(const char *s);
extern char *copyString(char *s);
#ifdef __cplusplus
}

View file

@ -1,190 +0,0 @@
/*
* parseargs.h
*
* Command line argument parser.
*
* Copyright 1996-2003 Glyph & Cog, LLC
*/
#include <stdio.h>
#include <stddef.h>
#include <string.h>
#include <stdlib.h>
#include <ctype.h>
#include "parseargs.h"
static ArgDesc *findArg(ArgDesc *args, char *arg);
static GBool grabArg(ArgDesc *arg, int i, int *argc, char *argv[]);
GBool parseArgs(ArgDesc *args, int *argc, char *argv[]) {
ArgDesc *arg;
int i, j;
GBool ok;
ok = gTrue;
i = 1;
while (i < *argc) {
if (!strcmp(argv[i], "--")) {
--*argc;
for (j = i; j < *argc; ++j)
argv[j] = argv[j+1];
break;
} else if ((arg = findArg(args, argv[i]))) {
if (!grabArg(arg, i, argc, argv))
ok = gFalse;
} else {
++i;
}
}
return ok;
}
void printUsage(char *program, char *otherArgs, ArgDesc *args) {
ArgDesc *arg;
char *typ;
int w, w1;
w = 0;
for (arg = args; arg->arg; ++arg) {
if ((w1 = strlen(arg->arg)) > w)
w = w1;
}
fprintf(stderr, "Usage: %s [options]", program);
if (otherArgs)
fprintf(stderr, " %s", otherArgs);
fprintf(stderr, "\n");
for (arg = args; arg->arg; ++arg) {
fprintf(stderr, " %s", arg->arg);
w1 = 9 + w - strlen(arg->arg);
switch (arg->kind) {
case argInt:
case argIntDummy:
typ = " <int>";
break;
case argFP:
case argFPDummy:
typ = " <fp>";
break;
case argString:
case argStringDummy:
typ = " <string>";
break;
case argFlag:
case argFlagDummy:
default:
typ = "";
break;
}
fprintf(stderr, "%-*s", w1, typ);
if (arg->usage)
fprintf(stderr, ": %s", arg->usage);
fprintf(stderr, "\n");
}
}
static ArgDesc *findArg(ArgDesc *args, char *arg) {
ArgDesc *p;
for (p = args; p->arg; ++p) {
if (p->kind < argFlagDummy && !strcmp(p->arg, arg))
return p;
}
return NULL;
}
static GBool grabArg(ArgDesc *arg, int i, int *argc, char *argv[]) {
int n;
int j;
GBool ok;
ok = gTrue;
n = 0;
switch (arg->kind) {
case argFlag:
*(GBool *)arg->val = gTrue;
n = 1;
break;
case argInt:
if (i + 1 < *argc && isInt(argv[i+1])) {
*(int *)arg->val = atoi(argv[i+1]);
n = 2;
} else {
ok = gFalse;
n = 1;
}
break;
case argFP:
if (i + 1 < *argc && isFP(argv[i+1])) {
*(double *)arg->val = atof(argv[i+1]);
n = 2;
} else {
ok = gFalse;
n = 1;
}
break;
case argString:
if (i + 1 < *argc) {
strncpy((char *)arg->val, argv[i+1], arg->size - 1);
((char *)arg->val)[arg->size - 1] = '\0';
n = 2;
} else {
ok = gFalse;
n = 1;
}
break;
default:
fprintf(stderr, "Internal error in arg table\n");
n = 1;
break;
}
if (n > 0) {
*argc -= n;
for (j = i; j < *argc; ++j)
argv[j] = argv[j+n];
}
return ok;
}
GBool isInt(char *s) {
if (*s == '-' || *s == '+')
++s;
while (isdigit(*s))
++s;
if (*s)
return gFalse;
return gTrue;
}
GBool isFP(char *s) {
int n;
if (*s == '-' || *s == '+')
++s;
n = 0;
while (isdigit(*s)) {
++s;
++n;
}
if (*s == '.')
++s;
while (isdigit(*s)) {
++s;
++n;
}
if (n > 0 && (*s == 'e' || *s == 'E')) {
++s;
if (*s == '-' || *s == '+')
++s;
n = 0;
if (!isdigit(*s))
return gFalse;
do {
++s;
} while (isdigit(*s));
}
if (*s)
return gFalse;
return gTrue;
}

View file

@ -1,71 +0,0 @@
/*
* parseargs.h
*
* Command line argument parser.
*
* Copyright 1996-2003 Glyph & Cog, LLC
*/
#ifndef PARSEARGS_H
#define PARSEARGS_H
#ifdef __cplusplus
extern "C" {
#endif
#include "gtypes.h"
/*
* Argument kinds.
*/
typedef enum {
argFlag, /* flag (present / not-present) */
/* [val: GBool *] */
argInt, /* integer arg */
/* [val: int *] */
argFP, /* floating point arg */
/* [val: double *] */
argString, /* string arg */
/* [val: char *] */
/* dummy entries -- these show up in the usage listing only; */
/* useful for X args, for example */
argFlagDummy,
argIntDummy,
argFPDummy,
argStringDummy
} ArgKind;
/*
* Argument descriptor.
*/
typedef struct {
char *arg; /* the command line switch */
ArgKind kind; /* kind of arg */
void *val; /* place to store value */
int size; /* for argString: size of string */
char *usage; /* usage string */
} ArgDesc;
/*
* Parse command line. Removes all args which are found in the arg
* descriptor list <args>. Stops parsing if "--" is found (and removes
* it). Returns gFalse if there was an error.
*/
extern GBool parseArgs(ArgDesc *args, int *argc, char *argv[]);
/*
* Print usage message, based on arg descriptor list.
*/
extern void printUsage(char *program, char *otherArgs, ArgDesc *args);
/*
* Check if a string is a valid integer or floating point number.
*/
extern GBool isInt(char *s);
extern GBool isFP(char *s);
#ifdef __cplusplus
}
#endif
#endif

View file

@ -1,5 +1,5 @@
# set the include path for X, qt and KDE
INCLUDES = -I.. -I$(top_srcdir)/kpdf/goo -I$(top_srcdir)/kpdf/xpdf $(all_includes)
INCLUDES = -I.. -I$(srcdir)/../goo -I$(srcdir)/../xpdf $(all_includes)
# these are the headers for your project
noinst_HEADERS = kpdf_shell.h kpdf_part.h kpdf_canvas.h kpdf_pagewidget.h QOutputDevPixmap.h QOutputDev.h

View file

@ -40,7 +40,6 @@
#include <GfxFont.h>
#include <UnicodeMap.h>
#include <CharCodeToUnicode.h>
#include <FontFile.h>
#include <Error.h>
#include <TextOutputDev.h>
#include <Catalog.h>
@ -186,7 +185,7 @@ QOutputDev::~QOutputDev ( )
void QOutputDev::startPage ( int /*pageNum*/, GfxState *state )
{
m_text->clear();
m_text->startPage(state);
}
void QOutputDev::endPage ( )
@ -196,19 +195,59 @@ void QOutputDev::endPage ( )
void QOutputDev::drawLink ( Link *link, Catalog * /* catalog */ )
{
fp_t x1, y1, x2, y2, w;
link-> getBorder ( &x1, &y1, &x2, &y2, &w );
if ( w > 0 ) {
int x, y, dx, dy;
cvtUserToDev ( x1, y1, &x, &y );
cvtUserToDev ( x2, y2, &dx, &dy );
QPen oldpen = m_painter-> pen ( );
m_painter-> setPen ( Qt::blue );
m_painter-> drawRect ( x, y, dx, dy );
double x1, y1, x2, y2;
LinkBorderStyle *borderStyle;
GfxRGB rgb;
double *dash;
int dashLength;
double dashList[20];
QPointArray path;
int x, y, i;
QPen oldpen, newpen;
link->getRect(&x1, &y1, &x2, &y2);
borderStyle = link->getBorderStyle();
if (borderStyle->getWidth() > 0)
{
oldpen = m_painter->pen();
borderStyle->getColor(&rgb.r, &rgb.g, &rgb.b);
newpen.setColor(q_col(rgb));
newpen.setWidth(qRound(borderStyle->getWidth()));
m_painter-> setPen ( newpen );
/* as said below on updateLineAttrs we don't support dashes right now
borderStyle->getDash(&dash, &dashLength);
if (borderStyle->getType() == linkBorderDashed && dashLength > 0)
{
if (dashLength > 20) dashLength = 20;
for (i = 0; i < dashLength; ++i)
{
dashList[i] = dash[i];
}
// ORIGINAL XPDF HAS THIS LINE, we must remove it and
// create something on variable path using that variables
// splash->setLineDash(dashList, dashLength, 0);
}
*/
if (borderStyle->getType() == linkBorderUnderlined)
{
cvtUserToDev(x1, y1, &x, &y);
path.setPoint(0, x, y);
cvtUserToDev(x2, y1, &x, &y);
path.setPoint(1, x, y);
}
else
{
cvtUserToDev(x1, y1, &x, &y);
path.setPoint(0, x, y);
cvtUserToDev(x2, y1, &x, &y);
path.setPoint(1, x, y);
cvtUserToDev(x2, y2, &x, &y);
path.setPoint(2, x, y);
cvtUserToDev(x1, y2, &x, &y);
path.setPoint(3, x, y);
}
m_painter-> drawPolygon( path );
m_painter-> setPen ( oldpen );
}
}
@ -876,7 +915,7 @@ void QOutputDev::drawImage(GfxState *state, Object */*ref*/, Stream *str, int wi
bool QOutputDev::findText ( const QString &str, QRect &r, bool top, bool bottom )
/*bool QOutputDev::findText ( const QString &str, QRect &r, bool top, bool bottom )
{
int l, t, w, h;
r. rect ( &l, &t, &w, &h );
@ -929,7 +968,7 @@ GBool QOutputDev::findText ( Unicode *s, int len, GBool top, GBool bottom, int *
found = true;
}
return found;
}
}*/
QString QOutputDev::getText ( int l, int t, int w, int h )
{

View file

@ -157,12 +157,12 @@ public:
// stops looking at <l+w-1>,<t+h-1>; otherwise stops looking at bottom
// of page. If found, sets the text bounding rectange and returns
// true; otherwise returns false.
GBool findText ( Unicode *s, int len, GBool top, GBool bottom, int *xMin, int *yMin, int *xMax, int *yMax );
// GBool findText ( Unicode *s, int len, GBool top, GBool bottom, int *xMin, int *yMin, int *xMax, int *yMax );
//----- special QT access
bool findText ( const QString &str, int &l, int &t, int &w, int &h, bool top = 0, bool bottom = 0 );
bool findText ( const QString &str, QRect &r, bool top = 0, bool bottom = 0 );
// bool findText ( const QString &str, int &l, int &t, int &w, int &h, bool top = 0, bool bottom = 0 );
// bool findText ( const QString &str, QRect &r, bool top = 0, bool bottom = 0 );
// Get the text which is inside the specified rectangle.
QString getText ( int left, int top, int width, int height );

View file

@ -29,7 +29,6 @@
#include <GfxFont.h>
#include <UnicodeMap.h>
#include <CharCodeToUnicode.h>
#include <FontFile.h>
#include <Error.h>
#include <TextOutputDev.h>
#include <Catalog.h>

View file

@ -278,7 +278,7 @@ namespace KPDF
const float ppp = basePpp * m_zoomFactor; // pixels per point
m_doc->displayPage(m_outputdev, m_currentPage, int(ppp * 72.0), 0, true);
m_doc->displayPage(m_outputdev, m_currentPage, ppp * 72.0, ppp * 72.0, 0, true, true);
resizeContents ( m_outputdev->getPixmap()->width ( ), m_outputdev->getPixmap()->height ( ));

View file

@ -24,7 +24,6 @@
#include "GlobalParams.h"
#include "PDFDoc.h"
#include "XOutputDev.h"
#include "QOutputDevKPrinter.h"
#include "QOutputDevPixmap.h"
@ -379,11 +378,11 @@ void Part::nextThumbnail()
// does not exist
if (m_nextThumbnail > m_doc->getNumPages()) return;
// Pixels per point when the zoomFactor is 1.
const float basePpp = QPaintDevice::x11AppDpiX() / 72.0;
const float ppp = basePpp * m_zoomFactor; // pixels per point
const double basePpp = QPaintDevice::x11AppDpiX() / 72.0;
const double ppp = basePpp * m_zoomFactor; // pixels per point
QOutputDevPixmap odev;
m_doc->displayPage(&odev, m_nextThumbnail, int(ppp * 72.0), 0, true);
m_doc->displayPage(&odev, m_nextThumbnail, ppp * 72.0, ppp * 72.0, 0, true, true);
pdfpartview->setThumbnail(m_nextThumbnail, odev.getPixmap());
m_nextThumbnail++;
@ -682,7 +681,7 @@ void Part::printPreview()
int max = m_doc->getNumPages();
for ( int i = 1; i <= max; ++i )
{
m_doc->displayPage( &printdev, i, printer.resolution(), 0, true );
m_doc->displayPage(&printdev, i, printer.resolution(), printer.resolution(), 0, true, true);
if ( i != max )
printer.newPage();
}
@ -695,7 +694,7 @@ void Part::doPrint( KPrinter& printer )
QValueList<int> pages = printer.pageList();
for ( QValueList<int>::ConstIterator i = pages.begin(); i != pages.end();)
{
m_doc->displayPage( &printdev, *i, printer.resolution(), 0, true );
m_doc->displayPage(&printdev, *i, printer.resolution(), printer.resolution(), 0, true, true);
if ( ++i != pages.end() )
printer.newPage();
}

View file

@ -7,7 +7,7 @@
static const char description[] =
I18N_NOOP("kpdf, a kde pdf viewer based on xpdf");
static const char version[] = "v0.3";
static const char version[] = "v0.4";
static KCmdLineOptions options[] =
{
@ -28,7 +28,7 @@ int main(int argc, char** argv)
about.addAuthor("Wilco Greven", 0, "greven@kde.org");
about.addAuthor("Christophe Devriese", 0, "oelewapperke@oelewapperke.org");
about.addAuthor("Laurent Montel", 0, "montel@kde.org");
about.addAuthor("Albert Astals Cid", I18N_NOOP("Added thumbnails"), "astals11@terra.es");
about.addAuthor("Albert Astals Cid", I18N_NOOP("xpdf 3.0 integration, thumbnails"), "astals11@terra.es");
KCmdLineArgs::init(argc, argv, &about);
KCmdLineArgs::addCmdLineOptions( options );

View file

@ -97,7 +97,7 @@ void Annot::draw(Gfx *gfx) {
Annots::Annots(XRef *xref, Object *annotsObj) {
Annot *annot;
Object obj1, obj2;
Object obj1;
int size;
int i;
@ -108,21 +108,16 @@ Annots::Annots(XRef *xref, Object *annotsObj) {
if (annotsObj->isArray()) {
for (i = 0; i < annotsObj->arrayGetLength(); ++i) {
if (annotsObj->arrayGet(i, &obj1)->isDict()) {
obj1.dictLookup("Subtype", &obj2);
if (obj2.isName("Widget") ||
obj2.isName("Stamp")) {
annot = new Annot(xref, obj1.getDict());
if (annot->isOk()) {
if (nAnnots >= size) {
size += 16;
annots = (Annot **)grealloc(annots, size * sizeof(Annot *));
}
annots[nAnnots++] = annot;
} else {
delete annot;
annot = new Annot(xref, obj1.getDict());
if (annot->isOk()) {
if (nAnnots >= size) {
size += 16;
annots = (Annot **)grealloc(annots, size * sizeof(Annot *));
}
annots[nAnnots++] = annot;
} else {
delete annot;
}
obj2.free();
}
obj1.free();
}

View file

@ -38,8 +38,12 @@ Array::~Array() {
}
void Array::add(Object *elem) {
if (length + 1 > size) {
size += 8;
if (length == size) {
if (length == 0) {
size = 8;
} else {
size *= 2;
}
elems = (Object *)grealloc(elems, size * sizeof(Object));
}
elems[length] = *elem;

View file

@ -39,7 +39,7 @@ BuiltinFontWidths::~BuiltinFontWidths() {
gfree(tab);
}
GBool BuiltinFontWidths::getWidth(const char *name, Gushort *width) {
GBool BuiltinFontWidths::getWidth(char *name, Gushort *width) {
int h;
BuiltinFontWidth *p;
@ -53,8 +53,8 @@ GBool BuiltinFontWidths::getWidth(const char *name, Gushort *width) {
return gFalse;
}
int BuiltinFontWidths::hash(const char *name) {
const char *p;
int BuiltinFontWidths::hash(char *name) {
char *p;
unsigned int h;
h = 0;

View file

@ -23,7 +23,7 @@ class BuiltinFontWidths;
//------------------------------------------------------------------------
struct BuiltinFont {
const char *name;
char *name;
char **defaultBaseEnc;
short ascent;
short descent;
@ -34,7 +34,7 @@ struct BuiltinFont {
//------------------------------------------------------------------------
struct BuiltinFontWidth {
const char *name;
char *name;
Gushort width;
BuiltinFontWidth *next;
};
@ -44,11 +44,11 @@ public:
BuiltinFontWidths(BuiltinFontWidth *widths, int sizeA);
~BuiltinFontWidths();
GBool getWidth(const char *name, Gushort *width);
GBool getWidth(char *name, Gushort *width);
private:
int hash(const char *name);
int hash(char *name);
BuiltinFontWidth **tab;
int size;

File diff suppressed because it is too large Load diff

View file

@ -36,7 +36,7 @@ struct CMapVectorEntry {
//------------------------------------------------------------------------
static int CMapgetCharFromFile(void *data) {
static int getCharFromFile(void *data) {
return fgetc((FILE *)data);
}
@ -68,7 +68,7 @@ CMap *CMap::parse(CMapCache *cache, GString *collectionA,
cmap = new CMap(collectionA->copy(), cMapNameA->copy());
pst = new PSTokenizer(&CMapgetCharFromFile, f);
pst = new PSTokenizer(&getCharFromFile, f);
pst->getToken(tok1, sizeof(tok1), &n1);
while (pst->getToken(tok2, sizeof(tok2), &n2)) {
if (!strcmp(tok2, "usecmap")) {
@ -144,6 +144,9 @@ CMap::CMap(GString *collectionA, GString *cMapNameA) {
vector[i].cid = 0;
}
refCnt = 1;
#if MULTITHREADED
gInitMutex(&mutex);
#endif
}
CMap::CMap(GString *collectionA, GString *cMapNameA, int wModeA) {
@ -152,6 +155,9 @@ CMap::CMap(GString *collectionA, GString *cMapNameA, int wModeA) {
wMode = wModeA;
vector = NULL;
refCnt = 1;
#if MULTITHREADED
gInitMutex(&mutex);
#endif
}
void CMap::useCMap(CMapCache *cache, char *useName) {
@ -252,6 +258,9 @@ CMap::~CMap() {
if (vector) {
freeCMapVector(vector);
}
#if MULTITHREADED
gDestroyMutex(&mutex);
#endif
}
void CMap::freeCMapVector(CMapVectorEntry *vec) {
@ -266,11 +275,26 @@ void CMap::freeCMapVector(CMapVectorEntry *vec) {
}
void CMap::incRefCnt() {
#if MULTITHREADED
gLockMutex(&mutex);
#endif
++refCnt;
#if MULTITHREADED
gUnlockMutex(&mutex);
#endif
}
void CMap::decRefCnt() {
if (--refCnt == 0) {
GBool done;
#if MULTITHREADED
gLockMutex(&mutex);
#endif
done = --refCnt == 0;
#if MULTITHREADED
gUnlockMutex(&mutex);
#endif
if (done) {
delete this;
}
}

View file

@ -18,6 +18,10 @@
#include "gtypes.h"
#include "CharTypes.h"
#if MULTITHREADED
#include "GMutex.h"
#endif
class GString;
struct CMapVectorEntry;
class CMapCache;
@ -69,6 +73,9 @@ private:
CMapVectorEntry *vector; // vector for first byte (NULL for
// identity CMap)
int refCnt;
#ifdef MULTITHREADED
GMutex mutex;
#endif
};
//------------------------------------------------------------------------

View file

@ -56,12 +56,13 @@ Catalog::Catalog(XRef *xrefA) {
goto err2;
}
pagesDict.dictLookup("Count", &obj);
if (!obj.isInt()) {
// some PDF files actually use real numbers here ("/Count 9.0")
if (!obj.isNum()) {
error(-1, "Page count in top-level pages object is wrong type (%s)",
obj.getTypeName());
goto err3;
}
pagesSize = numPages0 = obj.getInt();
pagesSize = numPages0 = (int)obj.getNum();
obj.free();
pages = (Page **)gmalloc(pagesSize * sizeof(Page *));
pageRefs = (Ref *)gmalloc(pagesSize * sizeof(Ref));
@ -307,8 +308,8 @@ Object *Catalog::findDestInTree(Object *tree, GString *name, Object *obj) {
} else if (cmp < 0) {
done = gTrue;
}
name1.free();
}
name1.free();
}
names.free();
if (!found)

View file

@ -54,7 +54,8 @@ static int getCharFromFile(void *data) {
//------------------------------------------------------------------------
CharCodeToUnicode *CharCodeToUnicode::parseCIDToUnicode(GString *collectionA) {
CharCodeToUnicode *CharCodeToUnicode::parseCIDToUnicode(GString *fileName,
GString *collection) {
FILE *f;
Unicode *mapA;
CharCode size, mapLenA;
@ -62,9 +63,9 @@ CharCodeToUnicode *CharCodeToUnicode::parseCIDToUnicode(GString *collectionA) {
Unicode u;
CharCodeToUnicode *ctu;
if (!(f = globalParams->getCIDToUnicodeFile(collectionA))) {
error(-1, "Couldn't find cidToUnicode file for the '%s' collection",
collectionA->getCString());
if (!(f = fopen(fileName->getCString(), "r"))) {
error(-1, "Couldn't open cidToUnicode file '%s'",
fileName->getCString());
return NULL;
}
@ -80,22 +81,110 @@ CharCodeToUnicode *CharCodeToUnicode::parseCIDToUnicode(GString *collectionA) {
if (sscanf(buf, "%x", &u) == 1) {
mapA[mapLenA] = u;
} else {
error(-1, "Bad line (%d) in cidToUnicode file for the '%s' collection",
(int)(mapLenA + 1), collectionA->getCString());
error(-1, "Bad line (%d) in cidToUnicode file '%s'",
(int)(mapLenA + 1), fileName->getCString());
mapA[mapLenA] = 0;
}
++mapLenA;
}
fclose(f);
ctu = new CharCodeToUnicode(collectionA->copy(), mapA, mapLenA, gTrue,
NULL, 0);
ctu = new CharCodeToUnicode(collection->copy(), mapA, mapLenA, gTrue,
NULL, 0, 0);
gfree(mapA);
return ctu;
}
CharCodeToUnicode *CharCodeToUnicode::parseUnicodeToUnicode(
GString *fileName) {
FILE *f;
Unicode *mapA;
CharCodeToUnicodeString *sMapA;
CharCode size, oldSize, len, sMapSizeA, sMapLenA;
char buf[256];
char *tok;
Unicode u0;
Unicode uBuf[maxUnicodeString];
CharCodeToUnicode *ctu;
int line, n, i;
if (!(f = fopen(fileName->getCString(), "r"))) {
error(-1, "Couldn't open unicodeToUnicode file '%s'",
fileName->getCString());
return NULL;
}
size = 4096;
mapA = (Unicode *)gmalloc(size * sizeof(Unicode));
memset(mapA, 0, size * sizeof(Unicode));
len = 0;
sMapA = NULL;
sMapSizeA = sMapLenA = 0;
line = 0;
while (getLine(buf, sizeof(buf), f)) {
++line;
if (!(tok = strtok(buf, " \t\r\n")) ||
sscanf(tok, "%x", &u0) != 1) {
error(-1, "Bad line (%d) in unicodeToUnicode file '%s'",
line, fileName->getCString());
continue;
}
n = 0;
while (n < maxUnicodeString) {
if (!(tok = strtok(NULL, " \t\r\n"))) {
break;
}
if (sscanf(tok, "%x", &uBuf[n]) != 1) {
error(-1, "Bad line (%d) in unicodeToUnicode file '%s'",
line, fileName->getCString());
break;
}
++n;
}
if (n < 1) {
error(-1, "Bad line (%d) in unicodeToUnicode file '%s'",
line, fileName->getCString());
continue;
}
if (u0 >= size) {
oldSize = size;
while (u0 >= size) {
size *= 2;
}
mapA = (Unicode *)grealloc(mapA, size * sizeof(Unicode));
memset(mapA + oldSize, 0, (size - oldSize) * sizeof(Unicode));
}
if (n == 1) {
mapA[u0] = uBuf[0];
} else {
mapA[u0] = 0;
if (sMapLenA == sMapSizeA) {
sMapSizeA += 16;
sMapA = (CharCodeToUnicodeString *)
grealloc(sMapA, sMapSizeA * sizeof(CharCodeToUnicodeString));
}
sMapA[sMapLenA].c = u0;
for (i = 0; i < n; ++i) {
sMapA[sMapLenA].u[i] = uBuf[i];
}
sMapA[sMapLenA].len = n;
++sMapLenA;
}
if (u0 >= len) {
len = u0 + 1;
}
}
fclose(f);
ctu = new CharCodeToUnicode(fileName->copy(), mapA, len, gTrue,
sMapA, sMapLenA, sMapSizeA);
gfree(mapA);
return ctu;
}
CharCodeToUnicode *CharCodeToUnicode::make8BitToUnicode(Unicode *toUnicode) {
return new CharCodeToUnicode(NULL, toUnicode, 256, gTrue, NULL, 0);
return new CharCodeToUnicode(NULL, toUnicode, 256, gTrue, NULL, 0, 0);
}
CharCodeToUnicode *CharCodeToUnicode::parseCMap(GString *buf, int nBits) {
@ -108,16 +197,20 @@ CharCodeToUnicode *CharCodeToUnicode::parseCMap(GString *buf, int nBits) {
return ctu;
}
void CharCodeToUnicode::mergeCMap(GString *buf, int nBits) {
char *p;
p = buf->getCString();
parseCMap1(&getCharFromString, &p, nBits);
}
void CharCodeToUnicode::parseCMap1(int (*getCharFunc)(void *), void *data,
int nBits) {
PSTokenizer *pst;
char tok1[256], tok2[256], tok3[256];
int nDigits, n1, n2, n3;
CharCode oldLen, i;
CharCode i;
CharCode code1, code2;
Unicode u;
char uHex[5];
int j;
GString *name;
FILE *f;
@ -158,38 +251,7 @@ void CharCodeToUnicode::parseCMap1(int (*getCharFunc)(void *), void *data,
error(-1, "Illegal entry in bfchar block in ToUnicode CMap");
continue;
}
if (code1 >= mapLen) {
oldLen = mapLen;
mapLen = (code1 + 256) & ~255;
map = (Unicode *)grealloc(map, mapLen * sizeof(Unicode));
for (i = oldLen; i < mapLen; ++i) {
map[i] = 0;
}
}
if (n2 == 6) {
if (sscanf(tok2 + 1, "%x", &u) != 1) {
error(-1, "Illegal entry in bfchar block in ToUnicode CMap");
continue;
}
map[code1] = u;
} else {
map[code1] = 0;
if (sMapLen == sMapSize) {
sMapSize += 8;
sMap = (CharCodeToUnicodeString *)
grealloc(sMap, sMapSize * sizeof(CharCodeToUnicodeString));
}
sMap[sMapLen].c = code1;
sMap[sMapLen].len = (n2 - 2) / 4;
for (j = 0; j < sMap[sMapLen].len && j < maxUnicodeString; ++j) {
strncpy(uHex, tok2 + 1 + j*4, 4);
uHex[4] = '\0';
if (sscanf(uHex, "%x", &sMap[sMapLen].u[j]) != 1) {
error(-1, "Illegal entry in bfchar block in ToUnicode CMap");
}
}
++sMapLen;
}
addMapping(code1, tok2 + 1, n2 - 1, 0);
}
pst->getToken(tok1, sizeof(tok1), &n1);
} else if (!strcmp(tok2, "beginbfrange")) {
@ -205,53 +267,39 @@ void CharCodeToUnicode::parseCMap1(int (*getCharFunc)(void *), void *data,
break;
}
if (!(n1 == 2 + nDigits && tok1[0] == '<' && tok1[n1 - 1] == '>' &&
n2 == 2 + nDigits && tok2[0] == '<' && tok2[n2 - 1] == '>' &&
tok3[0] == '<' && tok3[n3 - 1] == '>')) {
n2 == 2 + nDigits && tok2[0] == '<' && tok2[n2 - 1] == '>')) {
error(-1, "Illegal entry in bfrange block in ToUnicode CMap");
continue;
}
tok1[n1 - 1] = tok2[n2 - 1] = tok3[n3 - 1] = '\0';
tok1[n1 - 1] = tok2[n2 - 1] = '\0';
if (sscanf(tok1 + 1, "%x", &code1) != 1 ||
sscanf(tok2 + 1, "%x", &code2) != 1) {
error(-1, "Illegal entry in bfrange block in ToUnicode CMap");
continue;
}
if (code2 >= mapLen) {
oldLen = mapLen;
mapLen = (code2 + 256) & ~255;
map = (Unicode *)grealloc(map, mapLen * sizeof(Unicode));
for (i = oldLen; i < mapLen; ++i) {
map[i] = 0;
}
}
if (n3 <= 6) {
if (sscanf(tok3 + 1, "%x", &u) != 1) {
error(-1, "Illegal entry in bfrange block in ToUnicode CMap");
continue;
}
for (; code1 <= code2; ++code1) {
map[code1] = u++;
}
} else {
if (sMapLen + (int)(code2 - code1 + 1) > sMapSize) {
sMapSize = (sMapSize + (code2 - code1 + 1) + 7) & ~7;
sMap = (CharCodeToUnicodeString *)
grealloc(sMap, sMapSize * sizeof(CharCodeToUnicodeString));
}
for (i = 0; code1 <= code2; ++code1, ++i) {
map[code1] = 0;
sMap[sMapLen].c = code1;
sMap[sMapLen].len = (n3 - 2) / 4;
for (j = 0; j < sMap[sMapLen].len && j < maxUnicodeString; ++j) {
strncpy(uHex, tok3 + 1 + j*4, 4);
uHex[4] = '\0';
if (sscanf(uHex, "%x", &sMap[sMapLen].u[j]) != 1) {
error(-1, "Illegal entry in bfrange block in ToUnicode CMap");
}
if (!strcmp(tok3, "[")) {
i = 0;
while (pst->getToken(tok1, sizeof(tok1), &n1) &&
code1 + i <= code2) {
if (!strcmp(tok1, "]")) {
break;
}
sMap[sMapLen].u[sMap[sMapLen].len - 1] += i;
++sMapLen;
if (tok1[0] == '<' && tok1[n1 - 1] == '>') {
tok1[n1 - 1] = '\0';
addMapping(code1 + i, tok1 + 1, n1 - 2, 0);
} else {
error(-1, "Illegal entry in bfrange block in ToUnicode CMap");
}
++i;
}
} else if (tok3[0] == '<' && tok3[n3 - 1] == '>') {
tok3[n3 - 1] = '\0';
for (i = 0; code1 <= code2; ++code1, ++i) {
addMapping(code1, tok3 + 1, n3 - 2, i);
}
} else {
error(-1, "Illegal entry in bfrange block in ToUnicode CMap");
}
}
pst->getToken(tok1, sizeof(tok1), &n1);
@ -262,10 +310,52 @@ void CharCodeToUnicode::parseCMap1(int (*getCharFunc)(void *), void *data,
delete pst;
}
CharCodeToUnicode::CharCodeToUnicode(GString *collectionA) {
void CharCodeToUnicode::addMapping(CharCode code, char *uStr, int n,
int offset) {
CharCode oldLen, i;
Unicode u;
char uHex[5];
int j;
if (code >= mapLen) {
oldLen = mapLen;
mapLen = (code + 256) & ~255;
map = (Unicode *)grealloc(map, mapLen * sizeof(Unicode));
for (i = oldLen; i < mapLen; ++i) {
map[i] = 0;
}
}
if (n <= 4) {
if (sscanf(uStr, "%x", &u) != 1) {
error(-1, "Illegal entry in ToUnicode CMap");
return;
}
map[code] = u + offset;
} else {
if (sMapLen >= sMapSize) {
sMapSize = sMapSize + 16;
sMap = (CharCodeToUnicodeString *)
grealloc(sMap, sMapSize * sizeof(CharCodeToUnicodeString));
}
map[code] = 0;
sMap[sMapLen].c = code;
sMap[sMapLen].len = n / 4;
for (j = 0; j < sMap[sMapLen].len && j < maxUnicodeString; ++j) {
strncpy(uHex, uStr + j*4, 4);
uHex[4] = '\0';
if (sscanf(uHex, "%x", &sMap[sMapLen].u[j]) != 1) {
error(-1, "Illegal entry in ToUnicode CMap");
}
}
sMap[sMapLen].u[sMap[sMapLen].len - 1] += offset;
++sMapLen;
}
}
CharCodeToUnicode::CharCodeToUnicode(GString *tagA) {
CharCode i;
collection = collectionA;
tag = tagA;
mapLen = 256;
map = (Unicode *)gmalloc(mapLen * sizeof(Unicode));
for (i = 0; i < mapLen; ++i) {
@ -274,13 +364,16 @@ CharCodeToUnicode::CharCodeToUnicode(GString *collectionA) {
sMap = NULL;
sMapLen = sMapSize = 0;
refCnt = 1;
#if MULTITHREADED
gInitMutex(&mutex);
#endif
}
CharCodeToUnicode::CharCodeToUnicode(GString *collectionA, Unicode *mapA,
CharCodeToUnicode::CharCodeToUnicode(GString *tagA, Unicode *mapA,
CharCode mapLenA, GBool copyMap,
CharCodeToUnicodeString *sMapA,
int sMapLenA) {
collection = collectionA;
int sMapLenA, int sMapSizeA) {
tag = tagA;
mapLen = mapLenA;
if (copyMap) {
map = (Unicode *)gmalloc(mapLen * sizeof(Unicode));
@ -289,32 +382,75 @@ CharCodeToUnicode::CharCodeToUnicode(GString *collectionA, Unicode *mapA,
map = mapA;
}
sMap = sMapA;
sMapLen = sMapSize = sMapLenA;
sMapLen = sMapLenA;
sMapSize = sMapSizeA;
refCnt = 1;
#if MULTITHREADED
gInitMutex(&mutex);
#endif
}
CharCodeToUnicode::~CharCodeToUnicode() {
if (collection) {
delete collection;
if (tag) {
delete tag;
}
gfree(map);
if (sMap) {
gfree(sMap);
}
#if MULTITHREADED
gDestroyMutex(&mutex);
#endif
}
void CharCodeToUnicode::incRefCnt() {
#if MULTITHREADED
gLockMutex(&mutex);
#endif
++refCnt;
#if MULTITHREADED
gUnlockMutex(&mutex);
#endif
}
void CharCodeToUnicode::decRefCnt() {
if (--refCnt == 0) {
GBool done;
#if MULTITHREADED
gLockMutex(&mutex);
#endif
done = --refCnt == 0;
#if MULTITHREADED
gUnlockMutex(&mutex);
#endif
if (done) {
delete this;
}
}
GBool CharCodeToUnicode::match(GString *collectionA) {
return collection && !collection->cmp(collectionA);
GBool CharCodeToUnicode::match(GString *tagA) {
return tag && !tag->cmp(tagA);
}
void CharCodeToUnicode::setMapping(CharCode c, Unicode *u, int len) {
int i;
if (len == 1) {
map[c] = u[0];
} else {
map[c] = 0;
if (sMapLen == sMapSize) {
sMapSize += 8;
sMap = (CharCodeToUnicodeString *)
grealloc(sMap, sMapSize * sizeof(CharCodeToUnicodeString));
}
sMap[sMapLen].c = c;
sMap[sMapLen].len = len;
for (i = 0; i < len && i < maxUnicodeString; ++i) {
sMap[sMapLen].u[i] = u[i];
}
++sMapLen;
}
}
int CharCodeToUnicode::mapToUnicode(CharCode c, Unicode *u, int size) {
@ -340,34 +476,37 @@ int CharCodeToUnicode::mapToUnicode(CharCode c, Unicode *u, int size) {
//------------------------------------------------------------------------
CIDToUnicodeCache::CIDToUnicodeCache() {
CharCodeToUnicodeCache::CharCodeToUnicodeCache(int sizeA) {
int i;
for (i = 0; i < cidToUnicodeCacheSize; ++i) {
size = sizeA;
cache = (CharCodeToUnicode **)gmalloc(size * sizeof(CharCodeToUnicode *));
for (i = 0; i < size; ++i) {
cache[i] = NULL;
}
}
CIDToUnicodeCache::~CIDToUnicodeCache() {
CharCodeToUnicodeCache::~CharCodeToUnicodeCache() {
int i;
for (i = 0; i < cidToUnicodeCacheSize; ++i) {
for (i = 0; i < size; ++i) {
if (cache[i]) {
cache[i]->decRefCnt();
}
}
gfree(cache);
}
CharCodeToUnicode *CIDToUnicodeCache::getCIDToUnicode(GString *collection) {
CharCodeToUnicode *CharCodeToUnicodeCache::getCharCodeToUnicode(GString *tag) {
CharCodeToUnicode *ctu;
int i, j;
if (cache[0] && cache[0]->match(collection)) {
if (cache[0] && cache[0]->match(tag)) {
cache[0]->incRefCnt();
return cache[0];
}
for (i = 1; i < cidToUnicodeCacheSize; ++i) {
if (cache[i] && cache[i]->match(collection)) {
for (i = 1; i < size; ++i) {
if (cache[i] && cache[i]->match(tag)) {
ctu = cache[i];
for (j = i; j >= 1; --j) {
cache[j] = cache[j - 1];
@ -377,16 +516,18 @@ CharCodeToUnicode *CIDToUnicodeCache::getCIDToUnicode(GString *collection) {
return ctu;
}
}
if ((ctu = CharCodeToUnicode::parseCIDToUnicode(collection))) {
if (cache[cidToUnicodeCacheSize - 1]) {
cache[cidToUnicodeCacheSize - 1]->decRefCnt();
}
for (j = cidToUnicodeCacheSize - 1; j >= 1; --j) {
cache[j] = cache[j - 1];
}
cache[0] = ctu;
ctu->incRefCnt();
return ctu;
}
return NULL;
}
void CharCodeToUnicodeCache::add(CharCodeToUnicode *ctu) {
int i;
if (cache[size - 1]) {
cache[size - 1]->decRefCnt();
}
for (i = size - 1; i >= 1; --i) {
cache[i] = cache[i - 1];
}
cache[0] = ctu;
ctu->incRefCnt();
}

View file

@ -19,6 +19,10 @@
#include "CharTypes.h"
#if MULTITHREADED
#include "GMutex.h"
#endif
struct CharCodeToUnicodeString;
//------------------------------------------------------------------------
@ -26,10 +30,16 @@ struct CharCodeToUnicodeString;
class CharCodeToUnicode {
public:
// Create the CID-to-Unicode mapping specified by <collection>.
// This reads a .cidToUnicode file from disk. Sets the initial
// reference count to 1. Returns NULL on failure.
static CharCodeToUnicode *parseCIDToUnicode(GString *collectionA);
// Read the CID-to-Unicode mapping for <collection> from the file
// specified by <fileName>. Sets the initial reference count to 1.
// Returns NULL on failure.
static CharCodeToUnicode *parseCIDToUnicode(GString *fileName,
GString *collection);
// Create a Unicode-to-Unicode mapping from the file specified by
// <fileName>. Sets the initial reference count to 1. Returns NULL
// on failure.
static CharCodeToUnicode *parseUnicodeToUnicode(GString *fileName);
// Create the CharCode-to-Unicode mapping for an 8-bit font.
// <toUnicode> is an array of 256 Unicode indexes. Sets the initial
@ -39,13 +49,20 @@ public:
// Parse a ToUnicode CMap for an 8- or 16-bit font.
static CharCodeToUnicode *parseCMap(GString *buf, int nBits);
// Parse a ToUnicode CMap for an 8- or 16-bit font, merging it into
// <this>.
void mergeCMap(GString *buf, int nBits);
~CharCodeToUnicode();
void incRefCnt();
void decRefCnt();
// Return true if this mapping matches the specified <collectionA>.
GBool match(GString *collectionA);
// Return true if this mapping matches the specified <tagA>.
GBool match(GString *tagA);
// Set the mapping for <c>.
void setMapping(CharCode c, Unicode *u, int len);
// Map a CharCode to Unicode.
int mapToUnicode(CharCode c, Unicode *u, int size);
@ -53,38 +70,44 @@ public:
private:
void parseCMap1(int (*getCharFunc)(void *), void *data, int nBits);
CharCodeToUnicode(GString *collectionA);
CharCodeToUnicode(GString *collectionA, Unicode *mapA,
void addMapping(CharCode code, char *uStr, int n, int offset);
CharCodeToUnicode(GString *tagA);
CharCodeToUnicode(GString *tagA, Unicode *mapA,
CharCode mapLenA, GBool copyMap,
CharCodeToUnicodeString *sMapA, int sMapLenA);
CharCodeToUnicodeString *sMapA,
int sMapLenA, int sMapSizeA);
GString *collection;
GString *tag;
Unicode *map;
CharCode mapLen;
CharCodeToUnicodeString *sMap;
int sMapLen, sMapSize;
int refCnt;
#ifdef MULTITHREADED
GMutex mutex;
#endif
};
//------------------------------------------------------------------------
#define cidToUnicodeCacheSize 4
class CIDToUnicodeCache {
class CharCodeToUnicodeCache {
public:
CIDToUnicodeCache();
~CIDToUnicodeCache();
CharCodeToUnicodeCache(int sizeA);
~CharCodeToUnicodeCache();
// Get the CharCodeToUnicode object for <collection>. Increments
// its reference count; there will be one reference for the cache
// plus one for the caller of this function. Returns NULL on
// failure.
CharCodeToUnicode *getCIDToUnicode(GString *collection);
// Get the CharCodeToUnicode object for <tag>. Increments its
// reference count; there will be one reference for the cache plus
// one for the caller of this function. Returns NULL on failure.
CharCodeToUnicode *getCharCodeToUnicode(GString *tag);
// Insert <ctu> into the cache, in the most-recently-used position.
void add(CharCodeToUnicode *ctu);
private:
CharCodeToUnicode *cache[cidToUnicodeCacheSize];
CharCodeToUnicode **cache;
int size;
};
#endif

View file

@ -9,7 +9,7 @@
#ifndef COMPACTFONTINFO_H
#define COMPACTFONTINFO_H
static const char *type1CStdStrings[391] = {
static char *type1CStdStrings[391] = {
".notdef",
"space",
"exclam",

View file

@ -21,8 +21,8 @@ static void md5(Guchar *msg, int msgLen, Guchar *digest);
static Guchar passwordPad[32] = {
0x28, 0xbf, 0x4e, 0x5e, 0x4e, 0x75, 0x8a, 0x41,
0x64, 0x00, 0x4e, 0x56, 0xff, 0xfa, 0x01, 0x08,
0x2e, 0x2e, 0x00, 0xb6, 0xd0, 0x68, 0x3e, 0x80,
0x64, 0x00, 0x4e, 0x56, 0xff, 0xfa, 0x01, 0x08,
0x2e, 0x2e, 0x00, 0xb6, 0xd0, 0x68, 0x3e, 0x80,
0x2f, 0x0c, 0xa9, 0xfe, 0x64, 0x53, 0x69, 0x7a
};
@ -74,6 +74,7 @@ GBool Decrypt::makeFileKey(int encVersion, int encRevision, int keyLength,
int len, i, j;
// try using the supplied owner password to generate the user password
*ownerPasswordOk = gFalse;
if (ownerPassword) {
len = ownerPassword->getLength();
if (len < 32) {
@ -82,50 +83,47 @@ GBool Decrypt::makeFileKey(int encVersion, int encRevision, int keyLength,
} else {
memcpy(test, ownerPassword->getCString(), 32);
}
} else {
memcpy(test, passwordPad, 32);
}
md5(test, 32, test);
if (encRevision == 3) {
for (i = 0; i < 50; ++i) {
md5(test, 16, test);
}
}
if (encRevision == 2) {
rc4InitKey(test, keyLength, fState);
fx = fy = 0;
for (i = 0; i < 32; ++i) {
test2[i] = rc4DecryptByte(fState, &fx, &fy, ownerKey->getChar(i));
}
} else {
memcpy(test2, ownerKey->getCString(), 32);
for (i = 19; i >= 0; --i) {
for (j = 0; j < keyLength; ++j) {
tmpKey[j] = test[j] ^ i;
md5(test, 32, test);
if (encRevision == 3) {
for (i = 0; i < 50; ++i) {
md5(test, 16, test);
}
rc4InitKey(tmpKey, keyLength, fState);
}
if (encRevision == 2) {
rc4InitKey(test, keyLength, fState);
fx = fy = 0;
for (j = 0; j < 32; ++j) {
test2[j] = rc4DecryptByte(fState, &fx, &fy, test2[j]);
for (i = 0; i < 32; ++i) {
test2[i] = rc4DecryptByte(fState, &fx, &fy, ownerKey->getChar(i));
}
} else {
memcpy(test2, ownerKey->getCString(), 32);
for (i = 19; i >= 0; --i) {
for (j = 0; j < keyLength; ++j) {
tmpKey[j] = test[j] ^ i;
}
rc4InitKey(tmpKey, keyLength, fState);
fx = fy = 0;
for (j = 0; j < 32; ++j) {
test2[j] = rc4DecryptByte(fState, &fx, &fy, test2[j]);
}
}
}
}
userPassword2 = new GString((char *)test2, 32);
if (makeFileKey2(encVersion, encRevision, keyLength, ownerKey, userKey,
permissions, fileID, userPassword2, fileKey)) {
*ownerPasswordOk = gTrue;
userPassword2 = new GString((char *)test2, 32);
if (makeFileKey2(encVersion, encRevision, keyLength, ownerKey, userKey,
permissions, fileID, userPassword2, fileKey)) {
*ownerPasswordOk = gTrue;
delete userPassword2;
return gTrue;
}
delete userPassword2;
return gTrue;
}
*ownerPasswordOk = gFalse;
delete userPassword2;
// try using the supplied user password
return makeFileKey2(encVersion, encRevision, keyLength, ownerKey, userKey,
permissions, fileID, userPassword, fileKey);
}
GBool Decrypt::makeFileKey2(int /* encVersion */, int encRevision, int keyLength,
GBool Decrypt::makeFileKey2(int encVersion, int encRevision, int keyLength,
GString *ownerKey, GString *userKey,
int permissions, GString *fileID,
GString *userPassword, Guchar *fileKey) {

View file

@ -34,15 +34,19 @@ Dict::~Dict() {
int i;
for (i = 0; i < length; ++i) {
gfree((void *) entries[i].key);
gfree(entries[i].key);
entries[i].val.free();
}
gfree(entries);
}
void Dict::add(const char *key, Object *val) {
if (length + 1 > size) {
size += 8;
void Dict::add(char *key, Object *val) {
if (length == size) {
if (length == 0) {
size = 8;
} else {
size *= 2;
}
entries = (DictEntry *)grealloc(entries, size * sizeof(DictEntry));
}
entries[length].key = key;
@ -50,7 +54,7 @@ void Dict::add(const char *key, Object *val) {
++length;
}
inline DictEntry *Dict::find(const char *key) {
inline DictEntry *Dict::find(char *key) {
int i;
for (i = 0; i < length; ++i) {
@ -60,25 +64,25 @@ inline DictEntry *Dict::find(const char *key) {
return NULL;
}
GBool Dict::is(const char *type) {
GBool Dict::is(char *type) {
DictEntry *e;
return (e = find("Type")) && e->val.isName(type);
}
Object *Dict::lookup(const char *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 char *key, Object *obj) {
Object *Dict::lookupNF(char *key, Object *obj) {
DictEntry *e;
return (e = find(key)) ? e->val.copy(obj) : obj->initNull();
}
const char *Dict::getKey(int i) {
char *Dict::getKey(int i) {
return entries[i].key;
}

View file

@ -22,7 +22,7 @@
//------------------------------------------------------------------------
struct DictEntry {
const char *key;
char *key;
Object val;
};
@ -43,18 +43,18 @@ public:
int getLength() { return length; }
// Add an entry. NB: does not copy key.
void add(const char *key, Object *val);
void add(char *key, Object *val);
// Check if dictionary is of specified type.
GBool is(const char *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 char *key, Object *obj);
Object *lookupNF(const char *key, Object *obj);
Object *lookup(char *key, Object *obj);
Object *lookupNF(char *key, Object *obj);
// Iterative accessors.
const char *getKey(int i);
char *getKey(int i);
Object *getVal(int i, Object *obj);
Object *getValNF(int i, Object *obj);
@ -71,7 +71,7 @@ private:
int length; // number of entries in dictionary
int ref; // reference count
DictEntry *find(const char *key);
DictEntry *find(char *key);
};
#endif

View file

@ -1,29 +0,0 @@
//========================================================================
//
// DisplayFontTable.h
//
// Copyright 2001-2003 Glyph & Cog, LLC
//
//========================================================================
static struct {
const char *name;
const char *xlfd;
const char *encoding;
} displayFontTab[] = {
{"Courier", "-*-courier-medium-r-normal-*-%s-*-*-*-*-*-iso8859-1", "Latin1"},
{"Courier-Bold", "-*-courier-bold-r-normal-*-%s-*-*-*-*-*-iso8859-1", "Latin1"},
{"Courier-BoldOblique", "-*-courier-bold-o-normal-*-%s-*-*-*-*-*-iso8859-1", "Latin1"},
{"Courier-Oblique", "-*-courier-medium-o-normal-*-%s-*-*-*-*-*-iso8859-1", "Latin1"},
{"Helvetica", "-*-helvetica-medium-r-normal-*-%s-*-*-*-*-*-iso8859-1", "Latin1"},
{"Helvetica-Bold", "-*-helvetica-bold-r-normal-*-%s-*-*-*-*-*-iso8859-1", "Latin1"},
{"Helvetica-BoldOblique", "-*-helvetica-bold-o-normal-*-%s-*-*-*-*-*-iso8859-1", "Latin1"},
{"Helvetica-Oblique", "-*-helvetica-medium-o-normal-*-%s-*-*-*-*-*-iso8859-1", "Latin1"},
{"Symbol", "-*-symbol-medium-r-normal-*-%s-*-*-*-*-*-adobe-fontspecific", "Symbol"},
{"Times-Bold", "-*-times-bold-r-normal-*-%s-*-*-*-*-*-iso8859-1", "Latin1"},
{"Times-BoldItalic", "-*-times-bold-i-normal-*-%s-*-*-*-*-*-iso8859-1", "Latin1"},
{"Times-Italic", "-*-times-medium-i-normal-*-%s-*-*-*-*-*-iso8859-1", "Latin1"},
{"Times-Roman", "-*-times-medium-r-normal-*-%s-*-*-*-*-*-iso8859-1", "Latin1"},
{"ZapfDingbats", "-*-zapfdingbats-medium-r-normal-*-%s-*-*-*-*-*-*-*", "ZapfDingbats"},
{NULL, NULL, NULL}
};

View file

@ -18,7 +18,7 @@
#include "GlobalParams.h"
#include "Error.h"
void CDECL error(int pos, const char *msg, ...) {
void CDECL error(int pos, char *msg, ...) {
va_list args;
// NB: this can be called before the globalParams object is created

View file

@ -18,6 +18,6 @@
#include <stdio.h>
#include "config.h"
extern void CDECL error(int pos, const char *msg, ...);
extern void CDECL error(int pos, char *msg, ...);
#endif

View file

@ -23,4 +23,14 @@
#define errHighlightFile 5 // nonexistent or invalid highlight file
#define errBadPrinter 6 // invalid printer
#define errPrinting 7 // error during printing
#define errPermission 8 // PDF file doesn't allow that operation
#define errBadPageNum 9 // invalid page number
#define errFileIO 10 // file I/O error
#endif

View file

@ -1,783 +0,0 @@
//========================================================================
//
// FTFont.cc
//
// Copyright 2001-2003 Glyph & Cog, LLC
//
//========================================================================
#include <aconf.h>
#if FREETYPE2 && (HAVE_FREETYPE_FREETYPE_H || HAVE_FREETYPE_H)
#ifdef USE_GCC_PRAGMAS
#pragma implementation
#endif
#include <math.h>
#include <string.h>
#include "gmem.h"
#include "freetype/ftoutln.h"
#include "freetype/internal/ftobjs.h"
#if 1 //~ cff cid->gid map
#include "freetype/internal/cfftypes.h"
#include "freetype/internal/tttypes.h"
#endif
#include "GlobalParams.h"
#include "GfxState.h"
#include "FTFont.h"
//------------------------------------------------------------------------
FTFontEngine::FTFontEngine(Display *displayA, Visual *visualA, int depthA,
Colormap colormapA, GBool aaA):
SFontEngine(displayA, visualA, depthA, colormapA) {
ok = gFalse;
if (FT_Init_FreeType(&lib)) {
return;
}
aa = aaA;
ok = gTrue;
}
FTFontEngine::~FTFontEngine() {
FT_Done_FreeType(lib);
}
//------------------------------------------------------------------------
FTFontFile::FTFontFile(FTFontEngine *engineA, char *fontFileName,
char **fontEnc, GBool pdfFontHasEncoding,
GBool pdfFontIsSymbolic) {
char *name;
int unicodeCmap, macRomanCmap, msSymbolCmap;
int i, j;
ok = gFalse;
engine = engineA;
codeMap = NULL;
cidToGID = NULL;
cidToGIDLen = 0;
if (FT_New_Face(engine->lib, fontFileName, 0, &face)) {
return;
}
if (!strcmp(face->driver->root.clazz->module_name, "type1") ||
!strcmp(face->driver->root.clazz->module_name, "cff")) {
mode = ftFontModeCodeMapDirect;
codeMap = (Guint *)gmalloc(256 * sizeof(Guint));
for (i = 0; i < 256; ++i) {
codeMap[i] = 0;
if ((name = fontEnc[i])) {
codeMap[i] = FT_Get_Name_Index(face, name);
}
}
} else {
// To match up with the Adobe-defined behaviour, we choose a cmap
// like this:
// 1. If the PDF font has an encoding:
// 1a. If the TrueType font has a Microsoft Unicode cmap, use it,
// and use the Unicode indexes, not the char codes.
// 1b. If the PDF font is symbolic and the TrueType font has a
// Microsoft Symbol cmap, use it, and use (0xf000 + char code).
// 1c. If the TrueType font has a Macintosh Roman cmap, use it,
// and reverse map the char names through MacRomanEncoding to
// get char codes.
// 2. If the PDF font does not have an encoding:
// 2a. If the TrueType font has a Macintosh Roman cmap, use it,
// and use char codes directly.
// 2b. If the TrueType font has a Microsoft Symbol cmap, use it,
// and use (0xf000 + char code).
// 3. If none of these rules apply, use the first cmap and hope for
// the best (this shouldn't happen).
unicodeCmap = macRomanCmap = msSymbolCmap = 0xffff;
for (i = 0; i < face->num_charmaps; ++i) {
if ((face->charmaps[i]->platform_id == 3 &&
face->charmaps[i]->encoding_id == 1) ||
face->charmaps[i]->platform_id == 0) {
unicodeCmap = i;
} else if (face->charmaps[i]->platform_id == 1 &&
face->charmaps[i]->encoding_id == 0) {
macRomanCmap = i;
} else if (face->charmaps[i]->platform_id == 3 &&
face->charmaps[i]->encoding_id == 0) {
msSymbolCmap = i;
}
}
i = 0;
mode = ftFontModeCharCode;
charMapOffset = 0;
if (pdfFontHasEncoding) {
if (unicodeCmap != 0xffff) {
i = unicodeCmap;
mode = ftFontModeUnicode;
} else if (pdfFontIsSymbolic && msSymbolCmap != 0xffff) {
i = msSymbolCmap;
mode = ftFontModeCharCodeOffset;
charMapOffset = 0xf000;
} else if (macRomanCmap != 0xffff) {
i = macRomanCmap;
mode = ftFontModeCodeMap;
codeMap = (Guint *)gmalloc(256 * sizeof(Guint));
for (j = 0; j < 256; ++j) {
if (fontEnc[j]) {
codeMap[j] = globalParams->getMacRomanCharCode(fontEnc[j]);
} else {
codeMap[j] = 0;
}
}
}
} else {
if (macRomanCmap != 0xffff) {
i = macRomanCmap;
mode = ftFontModeCharCode;
} else if (msSymbolCmap != 0xffff) {
i = msSymbolCmap;
mode = ftFontModeCharCodeOffset;
charMapOffset = 0xf000;
}
}
if (FT_Set_Charmap(face, face->charmaps[i])) {
return;
}
}
ok = gTrue;
}
FTFontFile::FTFontFile(FTFontEngine *engineA, char *fontFileName,
Gushort *cidToGIDA, int cidToGIDLenA, GBool embedded) {
int i;
ok = gFalse;
engine = engineA;
codeMap = NULL;
cidToGID = NULL;
cidToGIDLen = 0;
if (FT_New_Face(engine->lib, fontFileName, 0, &face)) {
return;
}
cidToGIDLen = cidToGIDLenA;
cidToGID = (Gushort *)gmalloc(cidToGIDLen * sizeof(Gushort));
memcpy(cidToGID, cidToGIDA, cidToGIDLen * sizeof(Gushort));
if (!strcmp(face->driver->root.clazz->module_name, "t1cid")) {
mode = ftFontModeCID;
} else if (!strcmp(face->driver->root.clazz->module_name, "cff")) {
mode = ftFontModeCFFCharset;
} else if (embedded) {
mode = ftFontModeCIDToGIDMap;
} else {
mode = ftFontModeUnicode;
for (i = 0; i < face->num_charmaps; ++i) {
if ((face->charmaps[i]->platform_id == 3 &&
face->charmaps[i]->encoding_id == 1) ||
face->charmaps[i]->platform_id == 0) {
break;
}
}
if (i == face->num_charmaps) {
i = 0;
}
FT_Set_Charmap(face, face->charmaps[i]);
}
ok = gTrue;
}
FTFontFile::FTFontFile(FTFontEngine *engineA, char *fontFileName,
GBool embedded) {
int i;
ok = gFalse;
engine = engineA;
codeMap = NULL;
cidToGID = NULL;
cidToGIDLen = 0;
if (FT_New_Face(engine->lib, fontFileName, 0, &face)) {
return;
}
if (!strcmp(face->driver->root.clazz->module_name, "t1cid")) {
mode = ftFontModeCID;
} else if (embedded) {
mode = ftFontModeCFFCharset;
} else {
mode = ftFontModeUnicode;
for (i = 0; i < face->num_charmaps; ++i) {
if ((face->charmaps[i]->platform_id == 3 &&
face->charmaps[i]->encoding_id == 1) ||
face->charmaps[i]->platform_id == 0) {
break;
}
}
if (i == face->num_charmaps) {
i = 0;
}
FT_Set_Charmap(face, face->charmaps[i]);
}
ok = gTrue;
}
FTFontFile::~FTFontFile() {
if (face) {
FT_Done_Face(face);
}
if (codeMap) {
gfree(codeMap);
}
if (cidToGID) {
gfree(cidToGID);
}
}
//------------------------------------------------------------------------
FTFont::FTFont(FTFontFile *fontFileA, double *m) {
FTFontEngine *engine;
FT_Face face;
double size, div;
int x, xMin, xMax;
int y, yMin, yMax;
int i;
ok = gFalse;
fontFile = fontFileA;
engine = fontFile->engine;
face = fontFile->face;
if (FT_New_Size(face, &sizeObj)) {
return;
}
face->size = sizeObj;
size = sqrt(m[2]*m[2] + m[3]*m[3]);
if (FT_Set_Pixel_Sizes(face, 0, (int)size)) {
return;
}
div = face->bbox.xMax > 20000 ? 65536 : 1;
// transform the four corners of the font bounding box -- the min
// and max values form the bounding box of the transformed font
x = (int)((m[0] * face->bbox.xMin + m[2] * face->bbox.yMin) /
(div * face->units_per_EM));
xMin = xMax = x;
y = (int)((m[1] * face->bbox.xMin + m[3] * face->bbox.yMin) /
(div * face->units_per_EM));
yMin = yMax = y;
x = (int)((m[0] * face->bbox.xMin + m[2] * face->bbox.yMax) /
(div * face->units_per_EM));
if (x < xMin) {
xMin = x;
} else if (x > xMax) {
xMax = x;
}
y = (int)((m[1] * face->bbox.xMin + m[3] * face->bbox.yMax) /
(div * face->units_per_EM));
if (y < yMin) {
yMin = y;
} else if (y > yMax) {
yMax = y;
}
x = (int)((m[0] * face->bbox.xMax + m[2] * face->bbox.yMin) /
(div * face->units_per_EM));
if (x < xMin) {
xMin = x;
} else if (x > xMax) {
xMax = x;
}
y = (int)((m[1] * face->bbox.xMax + m[3] * face->bbox.yMin) /
(div * face->units_per_EM));
if (y < yMin) {
yMin = y;
} else if (y > yMax) {
yMax = y;
}
x = (int)((m[0] * face->bbox.xMax + m[2] * face->bbox.yMax) /
(div * face->units_per_EM));
if (x < xMin) {
xMin = x;
} else if (x > xMax) {
xMax = x;
}
y = (int)((m[1] * face->bbox.xMax + m[3] * face->bbox.yMax) /
(div * face->units_per_EM));
if (y < yMin) {
yMin = y;
} else if (y > yMax) {
yMax = y;
}
// This is a kludge: some buggy PDF generators embed fonts with
// zero bounding boxes.
if (xMax == xMin) {
xMin = 0;
xMax = (int)size;
}
if (yMax == yMin) {
yMin = 0;
yMax = (int)(1.2 * size);
}
// this should be (max - min + 1), but we add some padding to
// deal with rounding errors, bogus bboxes, etc.
glyphW = xMax - xMin + 3;
glyphW += glyphW >> 1;
glyphH = yMax - yMin + 3;
glyphH += glyphH >> 1;
if (engine->aa) {
glyphSize = glyphW * glyphH;
} else {
glyphSize = ((glyphW + 7) >> 3) * glyphH;
}
// set up the glyph pixmap cache
cacheAssoc = 8;
if (glyphSize <= 256) {
cacheSets = 8;
} else if (glyphSize <= 512) {
cacheSets = 4;
} else if (glyphSize <= 1024) {
cacheSets = 2;
} else {
cacheSets = 1;
}
cache = (Guchar *)gmalloc(cacheSets * cacheAssoc * glyphSize);
cacheTags = (FTFontCacheTag *)gmalloc(cacheSets * cacheAssoc *
sizeof(FTFontCacheTag));
for (i = 0; i < cacheSets * cacheAssoc; ++i) {
cacheTags[i].mru = i & (cacheAssoc - 1);
}
// create the XImage
if (!(image = XCreateImage(engine->display, engine->visual, engine->depth,
ZPixmap, 0, NULL, glyphW, glyphH, 8, 0))) {
return;
}
image->data = (char *)gmalloc(glyphH * image->bytes_per_line);
// compute the transform matrix
matrix.xx = (FT_Fixed)((m[0] / size) * 65536);
matrix.yx = (FT_Fixed)((m[1] / size) * 65536);
matrix.xy = (FT_Fixed)((m[2] / size) * 65536);
matrix.yy = (FT_Fixed)((m[3] / size) * 65536);
ok = gTrue;
}
FTFont::~FTFont() {
gfree(cacheTags);
gfree(cache);
gfree(image->data);
image->data = NULL;
XDestroyImage(image);
}
GBool FTFont::drawChar(Drawable d, int w, int h, GC gc,
int x, int y, int r, int g, int b,
CharCode c, Unicode u) {
FTFontEngine *engine;
XColor xcolor;
int bgR, bgG, bgB;
Gulong colors[5];
Guchar *bitmap, *p;
GBool tempBitmap;
XImage *img;
int pix;
int xOffset, yOffset, x0, y0, x1, y1, gw, gh, w0, h0;
int xx, yy, xx1;
engine = fontFile->engine;
// no Unicode index for this char - don't draw anything
if (fontFile->mode == ftFontModeUnicode && u == 0) {
return gFalse;
}
// generate the glyph pixmap
if (!(bitmap = getGlyphPixmap(c, u, &xOffset, &yOffset, &gw, &gh,
&tempBitmap))) {
return gFalse;
}
// compute: (x0,y0) = position in destination drawable
// (x1,y1) = position in glyph image
// (w0,h0) = size of image transfer
x0 = x - xOffset;
y0 = y - yOffset;
x1 = 0;
y1 = 0;
w0 = gw;
h0 = gh;
if (x0 < 0) {
x1 = -x0;
w0 += x0;
x0 = 0;
}
if (x0 + w0 > w) {
w0 = w - x0;
}
if (w0 < 0) {
goto done;
}
if (y0 < 0) {
y1 = -y0;
h0 += y0;
y0 = 0;
}
if (y0 + h0 > h) {
h0 = h - y0;
}
if (h0 < 0) {
goto done;
}
// getGlyphPixmap may have returned a larger-than-cache-entry
// bitmap, in which case we need to allocate a temporary XImage here
if (tempBitmap) {
if (!(img = XCreateImage(engine->display, engine->visual, engine->depth,
ZPixmap, 0, NULL, gw, gh, 8, 0))) {
goto done;
}
img->data = (char *)gmalloc(gh * img->bytes_per_line);
} else {
img = image;
}
// read the X image
XGetSubImage(engine->display, d, x0, y0, w0, h0, (1 << engine->depth) - 1,
ZPixmap, img, x1, y1);
if (engine->aa) {
// compute the colors
xcolor.pixel = XGetPixel(img, x1 + w0/2, y1 + h0/2);
XQueryColor(engine->display, engine->colormap, &xcolor);
bgR = xcolor.red;
bgG = xcolor.green;
bgB = xcolor.blue;
colors[1] = engine->findColor((r + 3*bgR) / 4,
(g + 3*bgG) / 4,
(b + 3*bgB) / 4);
colors[2] = engine->findColor((r + bgR) / 2,
(g + bgG) / 2,
(b + bgB) / 2);
colors[3] = engine->findColor((3*r + bgR) / 4,
(3*g + bgG) / 4,
(3*b + bgB) / 4);
colors[4] = engine->findColor(r, g, b);
// stuff the glyph pixmap into the X image
p = bitmap;
for (yy = 0; yy < gh; ++yy) {
for (xx = 0; xx < gw; ++xx) {
pix = *p++ & 0xff;
// this is a heuristic which seems to produce decent
// results -- the linear mapping would be:
// pix = (pix * 5) / 256;
pix = ((pix + 10) * 5) / 256;
if (pix > 4) {
pix = 4;
}
if (pix > 0) {
XPutPixel(img, xx, yy, colors[pix]);
}
}
}
} else {
// one color
colors[1] = engine->findColor(r, g, b);
// stuff the glyph bitmap into the X image
p = bitmap;
for (yy = 0; yy < gh; ++yy) {
for (xx = 0; xx < gw; xx += 8) {
pix = *p++;
for (xx1 = xx; xx1 < xx + 8 && xx1 < gw; ++xx1) {
if (pix & 0x80) {
XPutPixel(img, xx1, yy, colors[1]);
}
pix <<= 1;
}
}
}
}
// draw the X image
XPutImage(engine->display, d, gc, img, x1, y1, x0, y0, w0, h0);
if (tempBitmap) {
gfree(img->data);
img->data = NULL;
XDestroyImage(img);
}
done:
if (tempBitmap) {
gfree(bitmap);
}
return gTrue;
}
Guchar *FTFont::getGlyphPixmap(CharCode c, Unicode u,
int *x, int *y, int *w, int *h,
GBool *tempBitmap) {
FT_GlyphSlot slot;
FT_UInt idx;
int rowSize;
int i, j, k;
Guchar *ret, *p, *q;
// check the cache
i = (c & (cacheSets - 1)) * cacheAssoc;
for (j = 0; j < cacheAssoc; ++j) {
if ((cacheTags[i+j].mru & 0x8000) && cacheTags[i+j].code == c) {
*x = cacheTags[i+j].x;
*y = cacheTags[i+j].y;
*w = cacheTags[i+j].w;
*h = cacheTags[i+j].h;
for (k = 0; k < cacheAssoc; ++k) {
if (k != j &&
(cacheTags[i+k].mru & 0x7fff) < (cacheTags[i+j].mru & 0x7fff)) {
++cacheTags[i+k].mru;
}
}
cacheTags[i+j].mru = 0x8000;
*tempBitmap = gFalse;
return cache + (i+j) * glyphSize;
}
}
// generate the glyph pixmap or bitmap
fontFile->face->size = sizeObj;
FT_Set_Transform(fontFile->face, &matrix, NULL);
slot = fontFile->face->glyph;
idx = getGlyphIndex(c, u);
// if we have the FT2 bytecode interpreter, autohinting won't be used
#ifdef TT_CONFIG_OPTION_BYTECODE_INTERPRETER
if (FT_Load_Glyph(fontFile->face, idx, FT_LOAD_DEFAULT)) {
return gFalse;
}
#else
// FT2's autohinting doesn't always work very well (especially with
// font subsets), so turn it off if anti-aliasing is enabled; if
// anti-aliasing is disabled, this seems to be a tossup - some fonts
// look better with hinting, some without, so leave hinting on
if (FT_Load_Glyph(fontFile->face, idx,
fontFile->engine->aa ? FT_LOAD_NO_HINTING
: FT_LOAD_DEFAULT)) {
return gFalse;
}
#endif
if (FT_Render_Glyph(slot,
fontFile->engine->aa ? ft_render_mode_normal :
ft_render_mode_mono)) {
return gFalse;
}
// copy the glyph into the cache or a temporary bitmap
*x = -slot->bitmap_left;
*y = slot->bitmap_top;
*w = slot->bitmap.width;
*h = slot->bitmap.rows;
if (fontFile->engine->aa) {
rowSize = *w;
} else {
rowSize = (*w + 7) >> 3;
}
if (*w > glyphW || *h > glyphH) {
// the glyph doesn't fit in the bounding box -- return a
// temporary, uncached bitmap (this shouldn't happen but some
// fonts have incorrect bboxes)
ret = (Guchar *)gmalloc(*h * rowSize);
*tempBitmap = gTrue;
} else {
// store glyph pixmap in cache
ret = NULL; // make gcc happy
for (j = 0; j < cacheAssoc; ++j) {
if ((cacheTags[i+j].mru & 0x7fff) == cacheAssoc - 1) {
cacheTags[i+j].mru = 0x8000;
cacheTags[i+j].code = c;
cacheTags[i+j].x = *x;
cacheTags[i+j].y = *y;
cacheTags[i+j].w = *w;
cacheTags[i+j].h = *h;
ret = cache + (i+j) * glyphSize;
} else {
++cacheTags[i+j].mru;
}
}
*tempBitmap = gFalse;
}
for (k = 0, p = ret, q = slot->bitmap.buffer;
k < slot->bitmap.rows;
++k, p += rowSize, q += slot->bitmap.pitch) {
memcpy(p, q, rowSize);
}
return ret;
}
GBool FTFont::getCharPath(CharCode c, Unicode u, GfxState *state) {
static FT_Outline_Funcs outlineFuncs = {
&charPathMoveTo,
&charPathLineTo,
&charPathConicTo,
&charPathCubicTo,
0, 0
};
FT_GlyphSlot slot;
FT_UInt idx;
FT_Glyph glyph;
fontFile->face->size = sizeObj;
FT_Set_Transform(fontFile->face, &matrix, NULL);
slot = fontFile->face->glyph;
idx = getGlyphIndex(c, u);
#ifdef TT_CONFIG_OPTION_BYTECODE_INTERPRETER
if (FT_Load_Glyph(fontFile->face, idx, FT_LOAD_DEFAULT)) {
return gFalse;
}
#else
// FT2's autohinting doesn't always work very well (especially with
// font subsets), so turn it off if anti-aliasing is enabled; if
// anti-aliasing is disabled, this seems to be a tossup - some fonts
// look better with hinting, some without, so leave hinting on
if (FT_Load_Glyph(fontFile->face, idx,
fontFile->engine->aa ? FT_LOAD_NO_HINTING
: FT_LOAD_DEFAULT)) {
return gFalse;
}
#endif
if (FT_Get_Glyph(slot, &glyph)) {
return gFalse;
}
FT_Outline_Decompose(&((FT_OutlineGlyph)glyph)->outline,
&outlineFuncs, state);
return gTrue;
}
int FTFont::charPathMoveTo(FT_Vector *pt, void *state) {
((GfxState *)state)->moveTo(pt->x / 64.0, -pt->y / 64.0);
return 0;
}
int FTFont::charPathLineTo(FT_Vector *pt, void *state) {
((GfxState *)state)->lineTo(pt->x / 64.0, -pt->y / 64.0);
return 0;
}
int FTFont::charPathConicTo(FT_Vector *ctrl, FT_Vector *pt, void *state) {
double x0, y0, x1, y1, x2, y2, x3, y3, xc, yc;
x0 = ((GfxState *)state)->getCurX();
y0 = ((GfxState *)state)->getCurY();
xc = ctrl->x / 64.0;
yc = -ctrl->y / 64.0;
x3 = pt->x / 64.0;
y3 = -pt->y / 64.0;
// A second-order Bezier curve is defined by two endpoints, p0 and
// p3, and one control point, pc:
//
// p(t) = (1-t)^2*p0 + t*(1-t)*pc + t^2*p3
//
// A third-order Bezier curve is defined by the same two endpoints,
// p0 and p3, and two control points, p1 and p2:
//
// p(t) = (1-t)^3*p0 + 3t*(1-t)^2*p1 + 3t^2*(1-t)*p2 + t^3*p3
//
// Applying some algebra, we can convert a second-order curve to a
// third-order curve:
//
// p1 = (1/3) * (p0 + 2pc)
// p2 = (1/3) * (2pc + p3)
x1 = (1.0 / 3.0) * (x0 + 2 * xc);
y1 = (1.0 / 3.0) * (y0 + 2 * yc);
x2 = (1.0 / 3.0) * (2 * xc + x3);
y2 = (1.0 / 3.0) * (2 * yc + y3);
((GfxState *)state)->curveTo(x1, y1, x2, y2, x3, y3);
return 0;
}
int FTFont::charPathCubicTo(FT_Vector *ctrl1, FT_Vector *ctrl2,
FT_Vector *pt, void *state) {
((GfxState *)state)->curveTo(ctrl1->x / 64.0, -ctrl1->y / 64.0,
ctrl2->x / 64.0, -ctrl2->y / 64.0,
pt->x / 64.0, -pt->y / 64.0);
return 0;
}
FT_UInt FTFont::getGlyphIndex(CharCode c, Unicode u) {
FT_UInt idx;
int j;
idx = 0; // make gcc happy
switch (fontFile->mode) {
case ftFontModeUnicode:
idx = FT_Get_Char_Index(fontFile->face, (FT_ULong)u);
break;
case ftFontModeCharCode:
idx = FT_Get_Char_Index(fontFile->face, (FT_ULong)c);
break;
case ftFontModeCharCodeOffset:
if ((idx = FT_Get_Char_Index(fontFile->face, (FT_ULong)c)) == 0) {
idx = FT_Get_Char_Index(fontFile->face,
(FT_ULong)(c + fontFile->charMapOffset));
}
break;
case ftFontModeCodeMap:
if (c <= 0xff) {
idx = FT_Get_Char_Index(fontFile->face, (FT_ULong)fontFile->codeMap[c]);
} else {
idx = 0;
}
break;
case ftFontModeCodeMapDirect:
if (c <= 0xff) {
idx = (FT_UInt)fontFile->codeMap[c];
} else {
idx = 0;
}
break;
case ftFontModeCIDToGIDMap:
if (fontFile->cidToGIDLen) {
if ((int)c < fontFile->cidToGIDLen) {
idx = (FT_UInt)fontFile->cidToGID[c];
} else {
idx = (FT_UInt)0;
}
} else {
idx = (FT_UInt)c;
}
break;
case ftFontModeCFFCharset:
#if 1 //~ cff cid->gid map
{
#if FREETYPE_MAJOR == 2 && FREETYPE_MINOR == 0
CFF_Font *cff = (CFF_Font *)((TT_Face)fontFile->face)->extra.data;
#else
CFF_Font cff = (CFF_Font)((TT_Face)fontFile->face)->extra.data;
#endif
idx = 0;
for (j = 0; j < (int)cff->num_glyphs; ++j) {
if (cff->charset.sids[j] == c) {
idx = j;
break;
}
}
}
#endif
break;
case ftFontModeCID:
idx = c;
break;
}
return idx;
}
#endif // FREETYPE2 && (HAVE_FREETYPE_FREETYPE_H || HAVE_FREETYPE_H)

View file

@ -1,139 +0,0 @@
//========================================================================
//
// FTFont.h
//
// An X wrapper for the FreeType font rasterizer.
//
// Copyright 2001-2003 Glyph & Cog, LLC
//
//========================================================================
#ifndef FTFONT_H
#define FTFONT_H
#include <aconf.h>
#if FREETYPE2 && (HAVE_FREETYPE_FREETYPE_H || HAVE_FREETYPE_H)
#ifdef USE_GCC_PRAGMAS
#pragma interface
#endif
#include <freetype/freetype.h>
#include "CharTypes.h"
#include "SFont.h"
//------------------------------------------------------------------------
class FTFontEngine: public SFontEngine {
public:
FTFontEngine(Display *displayA, Visual *visualA, int depthA,
Colormap colormapA, GBool aaA);
GBool isOk() { return ok; }
virtual ~FTFontEngine();
private:
FT_Library lib;
GBool aa;
Gulong palette[5];
GBool ok;
friend class FTFontFile;
friend class FTFont;
};
//------------------------------------------------------------------------
enum FTFontIndexMode {
ftFontModeUnicode,
ftFontModeCharCode,
ftFontModeCharCodeOffset,
ftFontModeCodeMap,
ftFontModeCodeMapDirect,
ftFontModeCIDToGIDMap,
ftFontModeCFFCharset,
ftFontModeCID
};
class FTFontFile: public SFontFile {
public:
// 8-bit font, TrueType or Type 1/1C
FTFontFile(FTFontEngine *engineA, char *fontFileName,
char **fontEnc, GBool pdfFontHasEncoding,
GBool pdfFontIsSymbolic);
// CID font, TrueType
FTFontFile(FTFontEngine *engineA, char *fontFileName,
Gushort *cidToGIDA, int cidToGIDLenA, GBool embedded);
// CID font, Type 0C (CFF)
FTFontFile(FTFontEngine *engineA, char *fontFileName,
GBool embedded);
GBool isOk() { return ok; }
virtual ~FTFontFile();
private:
FTFontEngine *engine;
FT_Face face;
FTFontIndexMode mode;
int charMapOffset;
Guint *codeMap;
Gushort *cidToGID;
int cidToGIDLen;
GBool ok;
friend class FTFont;
};
//------------------------------------------------------------------------
struct FTFontCacheTag {
Gushort code;
Gushort mru; // valid bit (0x8000) and MRU index
int x, y, w, h; // offset and size of glyph
};
class FTFont: public SFont {
public:
FTFont(FTFontFile *fontFileA, double *m);
GBool isOk() { return ok; }
virtual ~FTFont();
virtual GBool drawChar(Drawable d, int w, int h, GC gc,
int x, int y, int r, int g, int b,
CharCode c, Unicode u);
virtual GBool getCharPath(CharCode c, Unicode u, GfxState *state);
private:
Guchar *getGlyphPixmap(CharCode c, Unicode u,
int *x, int *y, int *w, int *h,
GBool *tempBitmap);
static int charPathMoveTo(FT_Vector *pt, void *state);
static int charPathLineTo(FT_Vector *pt, void *state);
static int charPathConicTo(FT_Vector *ctrl, FT_Vector *pt, void *state);
static int charPathCubicTo(FT_Vector *ctrl1, FT_Vector *ctrl2,
FT_Vector *pt, void *state);
FT_UInt getGlyphIndex(CharCode c, Unicode u);
FTFontFile *fontFile;
FT_Size sizeObj;
XImage *image;
FT_Matrix matrix;
int glyphW, glyphH; // size of glyph pixmaps
int glyphSize; // size of glyph pixmaps, in bytes
Guchar *cache; // glyph pixmap cache
FTFontCacheTag *cacheTags; // cache tags, i.e., char codes
int cacheSets; // number of sets in cache
int cacheAssoc; // cache associativity (glyphs per set)
GBool ok;
};
#endif // FREETYPE2 && (HAVE_FREETYPE_FREETYPE_H || HAVE_FREETYPE_H)
#endif

File diff suppressed because it is too large Load diff

View file

@ -1,238 +0,0 @@
//========================================================================
//
// FontFile.h
//
// Copyright 1999-2003 Glyph & Cog, LLC
//
//========================================================================
#ifndef FONTFILE_H
#define FONTFILE_H
#include <aconf.h>
#ifdef USE_GCC_PRAGMAS
#pragma interface
#endif
#include <stdio.h>
#include "gtypes.h"
#include "GString.h"
#include "CharTypes.h"
class CharCodeToUnicode;
//------------------------------------------------------------------------
typedef void (*FontFileOutputFunc)(void *stream, const char *data, int len);
//------------------------------------------------------------------------
// FontFile
//------------------------------------------------------------------------
class FontFile {
public:
FontFile();
virtual ~FontFile();
// Returns the font name, as specified internally by the font file.
// Returns NULL if no name is available.
virtual char *getName() = 0;
// Returns the custom font encoding, or NULL if the encoding is not
// available.
virtual char **getEncoding() = 0;
};
//------------------------------------------------------------------------
// Type1FontFile
//------------------------------------------------------------------------
class Type1FontFile: public FontFile {
public:
Type1FontFile(char *file, int len);
virtual ~Type1FontFile();
virtual char *getName() { return name; }
virtual char **getEncoding() { return encoding; }
private:
char *name;
char **encoding;
};
//------------------------------------------------------------------------
// Type1CFontFile
//------------------------------------------------------------------------
struct Type1CTopDict;
struct Type1CPrivateDict;
class Type1CFontFile: public FontFile {
public:
Type1CFontFile(char *fileA, int lenA);
virtual ~Type1CFontFile();
GBool isOk() { return ok; }
virtual char *getName();
virtual char **getEncoding();
// Convert to a Type 1 font, suitable for embedding in a PostScript
// file. The name will be used as the PostScript font name.
void convertToType1(FontFileOutputFunc outputFuncA, void *outputStreamA);
// Convert to a Type 0 CIDFont, suitable for embedding in a
// PostScript file. The name will be used as the PostScript font
// name.
void convertToCIDType0(const char *psName,
FontFileOutputFunc outputFuncA, void *outputStreamA);
// Convert to a Type 0 (but non-CID) composite font, suitable for
// embedding in a PostScript file. The name will be used as the
// PostScript font name.
void convertToType0(const char *psName,
FontFileOutputFunc outputFuncA, void *outputStreamA);
private:
void readEncoding();
void readTopDict(Type1CTopDict *dict);
void readPrivateDict(Type1CPrivateDict *privateDict,
int offset, int size);
Gushort *readCharset(int charset, int nGlyphs);
void eexecWrite(const char *s);
void eexecCvtGlyph(const char *glyphName, int pos, int n);
void cvtGlyph(int pos, int n, GBool top);
void cvtGlyphWidth(GBool useOp);
void eexecDumpNum(double x, GBool fpA);
void eexecDumpOp1(int opA);
void eexecDumpOp2(int opA);
void eexecWriteCharstring(Guchar *s, int n);
void getDeltaInt(char *buf, const char *key, double *opA, int n);
void getDeltaReal(char *buf, const char *key, double *opA, int n);
int getIndexLen(int indexPos);
int getIndexValPos(int indexPos, int i, int *valLen);
int getIndexEnd(int indexPos);
Guint getWord(int pos, int size);
double getNum(int *pos, GBool *fp);
char *getString(int sid, char *buf);
Guchar *file;
int len;
GString *name;
char **encoding;
int topDictIdxPos;
int stringIdxPos;
int gsubrIdxPos;
int subrIdxPos;
int gsubrBias;
int subrBias;
FontFileOutputFunc outputFunc;
void *outputStream;
double op[48]; // operands
GBool fp[48]; // true if operand is fixed point
int nOps; // number of operands
int nHints; // number of hints for the current glyph
GBool firstOp; // true if we haven't hit the first op yet
double defaultWidthX; // default glyph width
double nominalWidthX; // nominal glyph width
GBool defaultWidthXFP; // true if defaultWidthX is fixed point
GBool nominalWidthXFP; // true if nominalWidthX is fixed point
Gushort r1; // eexec encryption key
GString *charBuf; // charstring output buffer
int line; // number of eexec chars on current line
GBool ok;
};
//------------------------------------------------------------------------
// TrueTypeFontFile
//------------------------------------------------------------------------
struct TTFontTableHdr;
class TrueTypeFontFile: public FontFile {
public:
TrueTypeFontFile(char *fileA, int lenA);
~TrueTypeFontFile();
// This always returns NULL, since it's probably better to trust the
// font name in the PDF file rather than the one in the TrueType
// font file.
virtual char *getName();
virtual char **getEncoding();
// Convert to a Type 42 font, suitable for embedding in a PostScript
// file. The name will be used as the PostScript font name (so we
// don't need to depend on the 'name' table in the font). The
// encoding is needed because the PDF Font object can modify the
// encoding.
void convertToType42(const char *name, char **encodingA,
CharCodeToUnicode *toUnicode,
GBool pdfFontHasEncoding,
GBool pdfFontIsSymbolic,
FontFileOutputFunc outputFunc, void *outputStream);
// Convert to a Type 2 CIDFont, suitable for embedding in a
// PostScript file. The name will be used as the PostScript font
// name (so we don't need to depend on the 'name' table in the
// font).
void convertToCIDType2(const char *name, Gushort *cidMap, int nCIDs,
FontFileOutputFunc outputFunc, void *outputStream);
// Convert to a Type 0 (but non-CID) composite font, suitable for
// embedding in a PostScript file. The name will be used as the
// PostScript font name (so we don't need to depend on the 'name'
// table in the font).
void convertToType0(const char *name, Gushort *cidMap, int nCIDs,
FontFileOutputFunc outputFunc, void *outputStream);
// Write a TTF file, filling in any missing tables that are required
// by the TrueType spec. If the font already has all the required
// tables, it will be written unmodified.
void writeTTF(FILE *out);
private:
char *file;
int len;
char **encoding;
TTFontTableHdr *tableHdrs;
int nTables;
int bbox[4];
int locaFmt;
int nGlyphs;
GBool mungedCmapSize;
int getByte(int pos);
int getChar(int pos);
int getUShort(int pos);
int getShort(int pos);
Guint getULong(int pos);
double getFixed(int pos);
int seekTable(const char *tag);
int seekTableIdx(const char *tag);
void cvtEncoding(char **encodingA, GBool pdfFontHasEncoding,
FontFileOutputFunc outputFunc, void *outputStream);
void cvtCharStrings(char **encodingA, CharCodeToUnicode *toUnicode,
GBool pdfFontHasEncoding, GBool pdfFontIsSymbolic,
FontFileOutputFunc outputFunc, void *outputStream);
int getCmapEntry(int cmapFmt, int pos, int code);
void cvtSfnts(FontFileOutputFunc outputFunc, void *outputStream,
GString *name);
void dumpString(char *s, int length,
FontFileOutputFunc outputFunc, void *outputStream);
Guint computeTableChecksum(char *data, int length);
};
#endif

View file

@ -380,8 +380,8 @@ void SampledFunction::transform(double *in, double *out) {
// pull 2^m values out of the sample array
for (j = 0; j < (1<<m); ++j) {
idx = e[j & 1][m - 1];
for (k = m - 2; k >= 0; --k) {
idx = 0;
for (k = m - 1; k >= 0; --k) {
idx = idx * sampleSize[k] + e[(j >> k) & 1][k];
}
idx = idx * n + i;
@ -410,7 +410,7 @@ void SampledFunction::transform(double *in, double *out) {
// ExponentialFunction
//------------------------------------------------------------------------
ExponentialFunction::ExponentialFunction(Object * /* funcObj */, Dict *dict) {
ExponentialFunction::ExponentialFunction(Object *funcObj, Dict *dict) {
Object obj1, obj2;
int i;
@ -529,7 +529,7 @@ void ExponentialFunction::transform(double *in, double *out) {
// StitchingFunction
//------------------------------------------------------------------------
StitchingFunction::StitchingFunction(Object * /* funcObj */, Dict *dict) {
StitchingFunction::StitchingFunction(Object *funcObj, Dict *dict) {
Object obj1, obj2;
int i;
@ -616,9 +616,13 @@ StitchingFunction::StitchingFunction(Object * /* funcObj */, Dict *dict) {
}
StitchingFunction::StitchingFunction(StitchingFunction *func) {
int i;
k = func->k;
funcs = (Function **)gmalloc(k * sizeof(Function *));
memcpy(funcs, func->funcs, k * sizeof(Function *));
for (i = 0; i < k; ++i) {
funcs[i] = func->funcs[i]->copy();
}
bounds = (double *)gmalloc((k + 1) * sizeof(double));
memcpy(bounds, func->bounds, (k + 1) * sizeof(double));
encode = (double *)gmalloc(2 * k * sizeof(double));
@ -629,9 +633,11 @@ StitchingFunction::StitchingFunction(StitchingFunction *func) {
StitchingFunction::~StitchingFunction() {
int i;
for (i = 0; i < k; ++i) {
if (funcs[i]) {
delete funcs[i];
if (funcs) {
for (i = 0; i < k; ++i) {
if (funcs[i]) {
delete funcs[i];
}
}
}
gfree(funcs);
@ -1241,7 +1247,7 @@ void PostScriptFunction::exec(PSStack *stack, int codePtr) {
} else {
b2 = stack->popBool();
b1 = stack->popBool();
stack->pushReal(b1 && b2);
stack->pushBool(b1 && b2);
}
break;
case psOpAtan:
@ -1308,8 +1314,8 @@ void PostScriptFunction::exec(PSStack *stack, int codePtr) {
stack->roll(2, 1);
break;
case psOpExp:
r2 = stack->popInt();
r1 = stack->popInt();
r2 = stack->popNum();
r1 = stack->popNum();
stack->pushReal(pow(r1, r2));
break;
case psOpFalse:
@ -1421,7 +1427,7 @@ void PostScriptFunction::exec(PSStack *stack, int codePtr) {
if (stack->topIsInt()) {
stack->pushInt(~stack->popInt());
} else {
stack->pushReal(!stack->popBool());
stack->pushBool(!stack->popBool());
}
break;
case psOpOr:
@ -1432,7 +1438,7 @@ void PostScriptFunction::exec(PSStack *stack, int codePtr) {
} else {
b2 = stack->popBool();
b1 = stack->popBool();
stack->pushReal(b1 || b2);
stack->pushBool(b1 || b2);
}
break;
case psOpPop:
@ -1450,7 +1456,7 @@ void PostScriptFunction::exec(PSStack *stack, int codePtr) {
}
break;
case psOpSin:
stack->pushReal(cos(stack->popNum()));
stack->pushReal(sin(stack->popNum()));
break;
case psOpSqrt:
stack->pushReal(sqrt(stack->popNum()));
@ -1483,7 +1489,7 @@ void PostScriptFunction::exec(PSStack *stack, int codePtr) {
} else {
b2 = stack->popBool();
b1 = stack->popBool();
stack->pushReal(b1 ^ b2);
stack->pushBool(b1 ^ b2);
}
break;
case psOpIf:

View file

@ -27,8 +27,8 @@ class PSStack;
// Function
//------------------------------------------------------------------------
#define funcMaxInputs 8
#define funcMaxOutputs 8
#define funcMaxInputs 8
#define funcMaxOutputs 32
class Function {
public:

File diff suppressed because it is too large Load diff

View file

@ -27,10 +27,14 @@ class OutputDev;
class GfxFontDict;
class GfxFont;
class GfxPattern;
class GfxTilingPattern;
class GfxShadingPattern;
class GfxShading;
class GfxFunctionShading;
class GfxAxialShading;
class GfxRadialShading;
class GfxState;
struct GfxColor;
class Gfx;
class PDFRectangle;
@ -96,8 +100,9 @@ class Gfx {
public:
// Constructor for regular output.
Gfx(XRef *xrefA, OutputDev *outA, int pageNum, Dict *resDict, double dpi,
PDFRectangle *box, GBool crop, PDFRectangle *cropBox, int rotate,
Gfx(XRef *xrefA, OutputDev *outA, int pageNum, Dict *resDict,
double hDPI, double vDPI, PDFRectangle *box, GBool crop,
PDFRectangle *cropBox, int rotate,
GBool (*abortCheckCbkA)(void *data) = NULL,
void *abortCheckCbkDataA = NULL);
@ -117,8 +122,11 @@ public:
void doAnnot(Object *str, double xMin, double yMin,
double xMax, double yMax);
void pushResources(Dict *resDict);
void popResources();
// Save graphics state.
void saveState();
// Restore graphics state.
void restoreState();
private:
@ -135,6 +143,7 @@ private:
int ignoreUndef; // current BX/EX nesting level
double baseMatrix[6]; // default matrix for most recent
// page/form/pattern
int formDepth;
Parser *parser; // parser for page content stream(s)
@ -197,7 +206,14 @@ private:
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 opShFill(Object args[], int numArgs);
void doFunctionShFill(GfxFunctionShading *shading);
void doFunctionShFill1(GfxFunctionShading *shading,
double x0, double y0,
double x1, double y1,
GfxColor *colors, int depth);
void doAxialShFill(GfxAxialShading *shading);
void doRadialShFill(GfxRadialShading *shading);
void doEndPath();
@ -256,6 +272,9 @@ private:
void opBeginMarkedContent(Object args[], int numArgs);
void opEndMarkedContent(Object args[], int numArgs);
void opMarkPoint(Object args[], int numArgs);
void pushResources(Dict *resDict);
void popResources();
};
#endif

View file

@ -25,14 +25,16 @@
#include "CharCodeToUnicode.h"
#include "FontEncodingTables.h"
#include "BuiltinFontTables.h"
#include "FontFile.h"
#include "FoFiType1.h"
#include "FoFiType1C.h"
#include "FoFiTrueType.h"
#include "GfxFont.h"
//------------------------------------------------------------------------
struct StdFontMapEntry {
const char *altName;
const char *properName;
char *altName;
char *properName;
};
// Acrobat 4.0 and earlier substituted Base14-compatible fonts without
@ -88,14 +90,17 @@ static StdFontMapEntry stdFontMap[] = {
{ "TimesNewRomanPS-BoldMT", "Times-Bold" },
{ "TimesNewRomanPS-Italic", "Times-Italic" },
{ "TimesNewRomanPS-ItalicMT", "Times-Italic" },
{ "TimesNewRomanPSMT", "Times-Roman" }
{ "TimesNewRomanPSMT", "Times-Roman" },
{ "TimesNewRomanPSMT,Bold", "Times-Bold" },
{ "TimesNewRomanPSMT,BoldItalic", "Times-BoldItalic" },
{ "TimesNewRomanPSMT,Italic", "Times-Italic" }
};
//------------------------------------------------------------------------
// GfxFont
//------------------------------------------------------------------------
GfxFont *GfxFont::makeFont(XRef *xref, const char *tagA, Ref idA, Dict *fontDict) {
GfxFont *GfxFont::makeFont(XRef *xref, char *tagA, Ref idA, Dict *fontDict) {
GString *nameA;
GfxFont *font;
Object obj1;
@ -131,17 +136,21 @@ GfxFont *GfxFont::makeFont(XRef *xref, const char *tagA, Ref idA, Dict *fontDict
return font;
}
GfxFont::GfxFont(const char *tagA, Ref idA, GString *nameA) {
GfxFont::GfxFont(char *tagA, Ref idA, GString *nameA) {
ok = gFalse;
tag = new GString(tagA);
id = idA;
name = nameA;
origName = nameA;
embFontName = NULL;
extFontFile = NULL;
}
GfxFont::~GfxFont() {
delete tag;
if (origName && origName != name) {
delete origName;
}
if (name) {
delete name;
}
@ -286,8 +295,8 @@ void GfxFont::readFontDescriptor(XRef *xref, Dict *fontDict) {
obj1.free();
}
CharCodeToUnicode *GfxFont::readToUnicodeCMap(Dict *fontDict, int nBits) {
CharCodeToUnicode *ctu;
CharCodeToUnicode *GfxFont::readToUnicodeCMap(Dict *fontDict, int nBits,
CharCodeToUnicode *ctu) {
GString *buf;
Object obj1;
int c;
@ -303,14 +312,18 @@ CharCodeToUnicode *GfxFont::readToUnicodeCMap(Dict *fontDict, int nBits) {
}
obj1.streamClose();
obj1.free();
ctu = CharCodeToUnicode::parseCMap(buf, nBits);
if (ctu) {
ctu->mergeCMap(buf, nBits);
} else {
ctu = CharCodeToUnicode::parseCMap(buf, nBits);
}
delete buf;
return ctu;
}
void GfxFont::findExtFontFile() {
static const char *type1Exts[] = { ".pfa", ".pfb", ".ps", "", NULL };
static const char *ttExts[] = { ".ttf", NULL };
static char *type1Exts[] = { ".pfa", ".pfb", ".ps", "", NULL };
static char *ttExts[] = { ".ttf", NULL };
if (name) {
if (type == fontType1) {
@ -334,7 +347,8 @@ char *GfxFont::readExtFontFile(int *len) {
fseek(f, 0, SEEK_SET);
buf = (char *)gmalloc(*len);
if ((int)fread(buf, 1, *len, f) != *len) {
error(-1, "Error reading external font file '%s'", extFontFile);
error(-1, "Error reading external font file '%s'",
extFontFile->getCString());
}
fclose(f);
return buf;
@ -381,7 +395,7 @@ char *GfxFont::readEmbFontFile(XRef *xref, int *len) {
// Gfx8BitFont
//------------------------------------------------------------------------
Gfx8BitFont::Gfx8BitFont(XRef *xref, const char *tagA, Ref idA, GString *nameA,
Gfx8BitFont::Gfx8BitFont(XRef *xref, char *tagA, Ref idA, GString *nameA,
GfxFontType typeA, Dict *fontDict):
GfxFont(tagA, idA, nameA)
{
@ -390,11 +404,14 @@ Gfx8BitFont::Gfx8BitFont(XRef *xref, const char *tagA, Ref idA, GString *nameA,
GBool baseEncFromFontFile;
char *buf;
int len;
FontFile *fontFile;
FoFiType1 *ffT1;
FoFiType1C *ffT1C;
int code, code2;
char *charName;
GBool missing, hex;
Unicode toUnicode[256];
CharCodeToUnicode *utu, *ctu2;
Unicode uBuf[8];
double mul;
int firstChar, lastChar;
Gushort w;
@ -419,7 +436,6 @@ Gfx8BitFont::Gfx8BitFont(XRef *xref, const char *tagA, Ref idA, GString *nameA,
}
}
if (!name->cmp(stdFontMap[a].altName)) {
delete name;
name = new GString(stdFontMap[a].properName);
}
}
@ -504,6 +520,7 @@ Gfx8BitFont::Gfx8BitFont(XRef *xref, const char *tagA, Ref idA, GString *nameA,
// check FontDict for base encoding
hasEncoding = gFalse;
usesMacRomanEnc = gFalse;
baseEnc = NULL;
baseEncFromFontFile = gFalse;
fontDict->lookup("Encoding", &obj1);
@ -511,6 +528,7 @@ Gfx8BitFont::Gfx8BitFont(XRef *xref, const char *tagA, Ref idA, GString *nameA,
obj1.dictLookup("BaseEncoding", &obj2);
if (obj2.isName("MacRomanEncoding")) {
hasEncoding = gTrue;
usesMacRomanEnc = gTrue;
baseEnc = macRomanEncoding;
} else if (obj2.isName("MacExpertEncoding")) {
hasEncoding = gTrue;
@ -525,6 +543,7 @@ Gfx8BitFont::Gfx8BitFont(XRef *xref, const char *tagA, Ref idA, GString *nameA,
obj2.free();
} else if (obj1.isName("MacRomanEncoding")) {
hasEncoding = gTrue;
usesMacRomanEnc = gTrue;
baseEnc = macRomanEncoding;
} else if (obj1.isName("MacExpertEncoding")) {
hasEncoding = gTrue;
@ -540,42 +559,50 @@ Gfx8BitFont::Gfx8BitFont(XRef *xref, const char *tagA, Ref idA, GString *nameA,
// check embedded or external font file for base encoding
// (only for Type 1 fonts - trying to get an encoding out of a
// TrueType font is a losing proposition)
fontFile = NULL;
ffT1 = NULL;
ffT1C = NULL;
buf = NULL;
if ((type == fontType1 || type == fontType1C) &&
(extFontFile || embFontID.num >= 0)) {
if (type == fontType1 && (extFontFile || embFontID.num >= 0)) {
if (extFontFile) {
buf = readExtFontFile(&len);
ffT1 = FoFiType1::load(extFontFile->getCString());
} else {
buf = readEmbFontFile(xref, &len);
ffT1 = FoFiType1::make(buf, len);
}
if (buf) {
if (type == fontType1C && !strncmp(buf, "%!", 2)) {
// various tools (including Adobe's) occasionally embed Type 1
// fonts but label them Type 1C
type = fontType1;
}
if (type == fontType1) {
fontFile = new Type1FontFile(buf, len);
} else {
fontFile = new Type1CFontFile(buf, len);
if (!((Type1CFontFile *)fontFile)->isOk()) {
delete fontFile;
fontFile = NULL;
}
}
if (fontFile && fontFile->getName()) {
if (ffT1) {
if (ffT1->getName()) {
if (embFontName) {
delete embFontName;
}
embFontName = new GString(fontFile->getName());
embFontName = new GString(ffT1->getName());
}
if (fontFile && !baseEnc) {
baseEnc = fontFile->getEncoding();
if (!baseEnc) {
baseEnc = ffT1->getEncoding();
baseEncFromFontFile = gTrue;
}
gfree(buf);
}
} else if (type == fontType1C && (extFontFile || embFontID.num >= 0)) {
if (extFontFile) {
ffT1C = FoFiType1C::load(extFontFile->getCString());
} else {
buf = readEmbFontFile(xref, &len);
ffT1C = FoFiType1C::make(buf, len);
}
if (ffT1C) {
if (ffT1C->getName()) {
if (embFontName) {
delete embFontName;
}
embFontName = new GString(ffT1C->getName());
}
if (!baseEnc) {
baseEnc = ffT1C->getEncoding();
baseEncFromFontFile = gTrue;
}
}
}
if (buf) {
gfree(buf);
}
// get default base encoding
@ -598,6 +625,20 @@ Gfx8BitFont::Gfx8BitFont(XRef *xref, const char *tagA, Ref idA, GString *nameA,
}
}
// some Type 1C font files have empty encodings, which can break the
// T1C->T1 conversion (since the 'seac' operator depends on having
// the accents in the encoding), so we fill in any gaps from
// StandardEncoding
if (type == fontType1C && (extFontFile || embFontID.num >= 0) &&
baseEncFromFontFile) {
for (i = 0; i < 256; ++i) {
if (!enc[i] && standardEncoding[i]) {
enc[i] = standardEncoding[i];
encFree[i] = gFalse;
}
}
}
// merge differences into encoding
if (obj1.isDict()) {
obj1.dictLookup("Differences", &obj2);
@ -609,7 +650,7 @@ Gfx8BitFont::Gfx8BitFont(XRef *xref, const char *tagA, Ref idA, GString *nameA,
if (obj3.isInt()) {
code = obj3.getInt();
} else if (obj3.isName()) {
if (code < 256) {
if (code >= 0 && code < 256) {
if (encFree[code]) {
gfree(enc[code]);
}
@ -627,82 +668,106 @@ Gfx8BitFont::Gfx8BitFont(XRef *xref, const char *tagA, Ref idA, GString *nameA,
obj2.free();
}
obj1.free();
if (fontFile) {
delete fontFile;
if (ffT1) {
delete ffT1;
}
if (ffT1C) {
delete ffT1C;
}
//----- build the mapping to Unicode -----
// look for a ToUnicode CMap
if (!(ctu = readToUnicodeCMap(fontDict, 8))) {
// pass 1: use the name-to-Unicode mapping table
missing = hex = gFalse;
for (code = 0; code < 256; ++code) {
if ((charName = enc[code])) {
if (!(toUnicode[code] = globalParams->mapNameToUnicode(charName)) &&
strcmp(charName, ".notdef")) {
// if it wasn't in the name-to-Unicode table, check for a
// name that looks like 'Axx' or 'xx', where 'A' is any letter
// and 'xx' is two hex digits
if ((strlen(charName) == 3 &&
isalpha(charName[0]) &&
isxdigit(charName[1]) && isxdigit(charName[2]) &&
((charName[1] >= 'a' && charName[1] <= 'f') ||
(charName[1] >= 'A' && charName[1] <= 'F') ||
(charName[2] >= 'a' && charName[2] <= 'f') ||
(charName[2] >= 'A' && charName[2] <= 'F'))) ||
(strlen(charName) == 2 &&
isxdigit(charName[0]) && isxdigit(charName[1]) &&
((charName[0] >= 'a' && charName[0] <= 'f') ||
(charName[0] >= 'A' && charName[0] <= 'F') ||
(charName[1] >= 'a' && charName[1] <= 'f') ||
(charName[1] >= 'A' && charName[1] <= 'F')))) {
hex = gTrue;
}
missing = gTrue;
}
} else {
toUnicode[code] = 0;
}
}
// no ToUnicode CMap, so use the char names
// pass 1: use the name-to-Unicode mapping table
missing = hex = gFalse;
// pass 2: try to fill in the missing chars, looking for names of
// the form 'Axx', 'xx', 'Ann', 'ABnn', or 'nn', where 'A' and 'B'
// are any letters, 'xx' is two hex digits, and 'nn' is 2-4
// decimal digits
if (missing && globalParams->getMapNumericCharNames()) {
for (code = 0; code < 256; ++code) {
if ((charName = enc[code])) {
if (!(toUnicode[code] = globalParams->mapNameToUnicode(charName)) &&
strcmp(charName, ".notdef")) {
// if it wasn't in the name-to-Unicode table, check for a
// name that looks like 'Axx' or 'xx', where 'A' is any letter
// and 'xx' is two hex digits
if ((strlen(charName) == 3 &&
isalpha(charName[0]) &&
isxdigit(charName[1]) && isxdigit(charName[2]) &&
((charName[1] >= 'a' && charName[1] <= 'f') ||
(charName[1] >= 'A' && charName[1] <= 'F') ||
(charName[2] >= 'a' && charName[2] <= 'f') ||
(charName[2] >= 'A' && charName[2] <= 'F'))) ||
(strlen(charName) == 2 &&
isxdigit(charName[0]) && isxdigit(charName[1]) &&
((charName[0] >= 'a' && charName[0] <= 'f') ||
(charName[0] >= 'A' && charName[0] <= 'F') ||
(charName[1] >= 'a' && charName[1] <= 'f') ||
(charName[1] >= 'A' && charName[1] <= 'F')))) {
hex = gTrue;
}
missing = gTrue;
if ((charName = enc[code]) && !toUnicode[code] &&
strcmp(charName, ".notdef")) {
n = strlen(charName);
code2 = -1;
if (hex && n == 3 && isalpha(charName[0]) &&
isxdigit(charName[1]) && isxdigit(charName[2])) {
sscanf(charName+1, "%x", &code2);
} else if (hex && n == 2 &&
isxdigit(charName[0]) && isxdigit(charName[1])) {
sscanf(charName, "%x", &code2);
} else if (!hex && n >= 2 && n <= 4 &&
isdigit(charName[0]) && isdigit(charName[1])) {
code2 = atoi(charName);
} else if (n >= 3 && n <= 5 &&
isdigit(charName[1]) && isdigit(charName[2])) {
code2 = atoi(charName+1);
} else if (n >= 4 && n <= 6 &&
isdigit(charName[2]) && isdigit(charName[3])) {
code2 = atoi(charName+2);
}
} else {
toUnicode[code] = 0;
}
}
// pass 2: try to fill in the missing chars, looking for names of
// the form 'Axx', 'xx', 'Ann', 'ABnn', or 'nn', where 'A' and 'B'
// are any letters, 'xx' is two hex digits, and 'nn' is 2-4
// decimal digits
if (missing && globalParams->getMapNumericCharNames()) {
for (code = 0; code < 256; ++code) {
if ((charName = enc[code]) && !toUnicode[code] &&
strcmp(charName, ".notdef")) {
n = strlen(charName);
code2 = -1;
if (hex && n == 3 && isalpha(charName[0]) &&
isxdigit(charName[1]) && isxdigit(charName[2])) {
sscanf(charName+1, "%x", &code2);
} else if (hex && n == 2 &&
isxdigit(charName[0]) && isxdigit(charName[1])) {
sscanf(charName, "%x", &code2);
} else if (!hex && n >= 2 && n <= 4 &&
isdigit(charName[0]) && isdigit(charName[1])) {
code2 = atoi(charName);
} else if (n >= 3 && n <= 5 &&
isdigit(charName[1]) && isdigit(charName[2])) {
code2 = atoi(charName+1);
} else if (n >= 4 && n <= 6 &&
isdigit(charName[2]) && isdigit(charName[3])) {
code2 = atoi(charName+2);
}
if (code2 >= 0 && code2 <= 0xff) {
toUnicode[code] = (Unicode)code2;
}
if (code2 >= 0 && code2 <= 0xff) {
toUnicode[code] = (Unicode)code2;
}
}
}
}
ctu = CharCodeToUnicode::make8BitToUnicode(toUnicode);
// construct the char code -> Unicode mapping object
ctu = CharCodeToUnicode::make8BitToUnicode(toUnicode);
// merge in a ToUnicode CMap, if there is one -- this overwrites
// existing entries in ctu, i.e., the ToUnicode CMap takes
// precedence, but the other encoding info is allowed to fill in any
// holes
readToUnicodeCMap(fontDict, 8, ctu);
// look for a Unicode-to-Unicode mapping
if (name && (utu = globalParams->getUnicodeToUnicode(name))) {
for (i = 0; i < 256; ++i) {
toUnicode[i] = 0;
}
ctu2 = CharCodeToUnicode::make8BitToUnicode(toUnicode);
for (i = 0; i < 256; ++i) {
n = ctu->mapToUnicode((CharCode)i, uBuf, 8);
if (n >= 1) {
n = utu->mapToUnicode((CharCode)uBuf[0], uBuf, 8);
if (n >= 1) {
ctu2->setMapping((CharCode)i, uBuf, n);
}
}
}
utu->decRefCnt();
delete ctu;
ctu = ctu2;
}
//----- get the character widths -----
@ -716,9 +781,15 @@ Gfx8BitFont::Gfx8BitFont(XRef *xref, const char *tagA, Ref idA, GString *nameA,
fontDict->lookup("FirstChar", &obj1);
firstChar = obj1.isInt() ? obj1.getInt() : 0;
obj1.free();
if (firstChar < 0 || firstChar > 255) {
firstChar = 0;
}
fontDict->lookup("LastChar", &obj1);
lastChar = obj1.isInt() ? obj1.getInt() : 255;
obj1.free();
if (lastChar < 0 || lastChar > 255) {
lastChar = 255;
}
mul = (type == fontType3) ? fontMat[0] : 0.001;
fontDict->lookup("Widths", &obj1);
if (obj1.isArray()) {
@ -750,7 +821,7 @@ Gfx8BitFont::Gfx8BitFont(XRef *xref, const char *tagA, Ref idA, GString *nameA,
}
}
// couldn't find widths -- use defaults
// couldn't find widths -- use defaults
} else {
// this is technically an error -- the Widths entry is required
// for all but the Base-14 fonts -- but certain PDF generators
@ -802,7 +873,7 @@ Gfx8BitFont::~Gfx8BitFont() {
}
}
int Gfx8BitFont::getNextChar(char *s, int /* len */, CharCode *code,
int Gfx8BitFont::getNextChar(char *s, int len, CharCode *code,
Unicode *u, int uSize, int *uLen,
double *dx, double *dy, double *ox, double *oy) {
CharCode c;
@ -819,12 +890,126 @@ CharCodeToUnicode *Gfx8BitFont::getToUnicode() {
return ctu;
}
Gushort *Gfx8BitFont::getCodeToGIDMap(FoFiTrueType *ff) {
Gushort *map;
int cmapPlatform, cmapEncoding;
int unicodeCmap, macRomanCmap, msSymbolCmap, cmap;
GBool useMacRoman, useUnicode;
char *charName;
Unicode u;
int code, i, n;
map = (Gushort *)gmalloc(256 * sizeof(Gushort));
for (i = 0; i < 256; ++i) {
map[i] = 0;
}
// To match up with the Adobe-defined behaviour, we choose a cmap
// like this:
// 1. If the PDF font has an encoding:
// 1a. If the PDF font specified MacRomanEncoding and the
// TrueType font has a Macintosh Roman cmap, use it, and
// reverse map the char names through MacRomanEncoding to
// get char codes.
// 1b. If the TrueType font has a Microsoft Unicode cmap or a
// non-Microsoft Unicode cmap, use it, and use the Unicode
// indexes, not the char codes.
// 1c. If the PDF font is symbolic and the TrueType font has a
// Microsoft Symbol cmap, use it, and use char codes
// directly (possibly with an offset of 0xf000).
// 1d. If the TrueType font has a Macintosh Roman cmap, use it,
// as in case 1a.
// 2. If the PDF font does not have an encoding:
// 2a. If the TrueType font has a Macintosh Roman cmap, use it,
// and use char codes directly (possibly with an offset of
// 0xf000).
// 2b. If the TrueType font has a Microsoft Symbol cmap, use it,
// and use char codes directly (possible with an offset of
// 0xf000).
// 3. If none of these rules apply, use the first cmap and hope for
// the best (this shouldn't happen).
unicodeCmap = macRomanCmap = msSymbolCmap = -1;
for (i = 0; i < ff->getNumCmaps(); ++i) {
cmapPlatform = ff->getCmapPlatform(i);
cmapEncoding = ff->getCmapEncoding(i);
if ((cmapPlatform == 3 && cmapEncoding == 1) ||
cmapPlatform == 0) {
unicodeCmap = i;
} else if (cmapPlatform == 1 && cmapEncoding == 0) {
macRomanCmap = i;
} else if (cmapPlatform == 3 && cmapEncoding == 0) {
msSymbolCmap = i;
}
}
cmap = 0;
useMacRoman = gFalse;
useUnicode = gFalse;
if (hasEncoding) {
if (usesMacRomanEnc && macRomanCmap >= 0) {
cmap = macRomanCmap;
useMacRoman = gTrue;
} else if (unicodeCmap >= 0) {
cmap = unicodeCmap;
useUnicode = gTrue;
} else if ((flags & fontSymbolic) && msSymbolCmap >= 0) {
cmap = msSymbolCmap;
} else if (macRomanCmap >= 0) {
cmap = macRomanCmap;
useMacRoman = gTrue;
}
} else {
if (macRomanCmap >= 0) {
cmap = macRomanCmap;
} else if (msSymbolCmap >= 0) {
cmap = msSymbolCmap;
}
}
// reverse map the char names through MacRomanEncoding, then map the
// char codes through the cmap
if (useMacRoman) {
for (i = 0; i < 256; ++i) {
if ((charName = enc[i])) {
if ((code = globalParams->getMacRomanCharCode(charName))) {
map[i] = ff->mapCodeToGID(cmap, code);
}
}
}
// map Unicode through the cmap
} else if (useUnicode) {
for (i = 0; i < 256; ++i) {
if ((n = ctu->mapToUnicode((CharCode)i, &u, 1))) {
map[i] = ff->mapCodeToGID(cmap, u);
}
}
// map the char codes through the cmap, possibly with an offset of
// 0xf000
} else {
for (i = 0; i < 256; ++i) {
if (!(map[i] = ff->mapCodeToGID(cmap, i))) {
map[i] = ff->mapCodeToGID(cmap, 0xf000 + i);
}
}
}
// try the TrueType 'post' table to handle any unmapped characters
for (i = 0; i < 256; ++i) {
if (!map[i] && (charName = enc[i])) {
map[i] = (Gushort)(int)ff->mapNameToGID(charName);
}
}
return map;
}
Dict *Gfx8BitFont::getCharProcs() {
return charProcs.isDict() ? charProcs.getDict() : (Dict *)NULL;
}
Object *Gfx8BitFont::getCharProc(int code, Object *proc) {
if (charProcs.isDict()) {
if (enc[code] && charProcs.isDict()) {
charProcs.dictLookup(enc[code], proc);
} else {
proc->initNull();
@ -850,7 +1035,7 @@ static int CDECL cmpWidthExcepV(const void *w1, const void *w2) {
((GfxFontCIDWidthExcepV *)w2)->first;
}
GfxCIDFont::GfxCIDFont(XRef *xref, const char *tagA, Ref idA, GString *nameA,
GfxCIDFont::GfxCIDFont(XRef *xref, char *tagA, Ref idA, GString *nameA,
Dict *fontDict):
GfxFont(tagA, idA, nameA)
{
@ -930,7 +1115,7 @@ GfxCIDFont::GfxCIDFont(XRef *xref, const char *tagA, Ref idA, GString *nameA,
obj1.free();
// look for a ToUnicode CMap
if (!(ctu = readToUnicodeCMap(fontDict, 16))) {
if (!(ctu = readToUnicodeCMap(fontDict, 16, NULL))) {
// the "Adobe-Identity" and "Adobe-UCS" collections don't have
// cidToUnicode files
@ -1058,11 +1243,11 @@ GfxCIDFont::GfxCIDFont(XRef *xref, const char *tagA, Ref idA, GString *nameA,
if (desFontDict->lookup("DW2", &obj1)->isArray() &&
obj1.arrayGetLength() == 2) {
if (obj1.arrayGet(0, &obj2)->isNum()) {
widths.defVY = obj1.getNum() * 0.001;
widths.defVY = obj2.getNum() * 0.001;
}
obj2.free();
if (obj1.arrayGet(1, &obj2)->isNum()) {
widths.defHeight = obj1.getNum() * 0.001;
widths.defHeight = obj2.getNum() * 0.001;
}
obj2.free();
}
@ -1073,8 +1258,8 @@ GfxCIDFont::GfxCIDFont(XRef *xref, const char *tagA, Ref idA, GString *nameA,
excepsSize = 0;
i = 0;
while (i + 1 < obj1.arrayGetLength()) {
obj1.arrayGet(0, &obj2);
obj2.arrayGet(0, &obj3);
obj1.arrayGet(i, &obj2);
obj1.arrayGet(i+ 1, &obj3);
if (obj2.isInt() && obj3.isInt() && i + 4 < obj1.arrayGetLength()) {
if (obj1.arrayGet(i + 2, &obj4)->isNum() &&
obj1.arrayGet(i + 3, &obj5)->isNum() &&
@ -1107,10 +1292,10 @@ GfxCIDFont::GfxCIDFont(XRef *xref, const char *tagA, Ref idA, GString *nameA,
excepsSize * sizeof(GfxFontCIDWidthExcepV));
}
j = obj2.getInt();
for (k = 0; k < obj3.arrayGetLength(); ++k) {
for (k = 0; k < obj3.arrayGetLength(); k += 3) {
if (obj3.arrayGet(k, &obj4)->isNum() &&
obj3.arrayGet(k, &obj5)->isNum() &&
obj3.arrayGet(k, &obj6)->isNum()) {
obj3.arrayGet(k+1, &obj5)->isNum() &&
obj3.arrayGet(k+2, &obj6)->isNum()) {
widths.excepsV[widths.nExceps].first = j;
widths.excepsV[widths.nExceps].last = j;
widths.excepsV[widths.nExceps].height = obj4.getNum() * 0.001;
@ -1247,7 +1432,9 @@ int GfxCIDFont::getWMode() {
}
CharCodeToUnicode *GfxCIDFont::getToUnicode() {
ctu->incRefCnt();
if (ctu) {
ctu->incRefCnt();
}
return ctu;
}
@ -1259,7 +1446,7 @@ GString *GfxCIDFont::getCollection() {
// GfxFontDict
//------------------------------------------------------------------------
GfxFontDict::GfxFontDict(XRef *xref, Dict *fontDict) {
GfxFontDict::GfxFontDict(XRef *xref, Ref *fontDictRef, Dict *fontDict) {
int i;
Object obj1, obj2;
Ref r;
@ -1277,7 +1464,11 @@ GfxFontDict::GfxFontDict(XRef *xref, Dict *fontDict) {
// (legal generation numbers are five digits, so any 6-digit
// number would be safe)
r.num = i;
r.gen = 999999;
if (fontDictRef) {
r.gen = 100000 + fontDictRef->num;
} else {
r.gen = 999999;
}
}
fonts[i] = GfxFont::makeFont(xref, fontDict->getKey(i),
r, obj2.getDict());

View file

@ -23,6 +23,7 @@
class Dict;
class CMap;
class CharCodeToUnicode;
class FoFiTrueType;
struct GfxFontCIDWidths;
//------------------------------------------------------------------------
@ -84,9 +85,9 @@ class GfxFont {
public:
// Build a GfxFont object.
static GfxFont *makeFont(XRef *xref, const char *tagA, Ref idA, Dict *fontDict);
static GfxFont *makeFont(XRef *xref, char *tagA, Ref idA, Dict *fontDict);
GfxFont(const char *tagA, Ref idA, GString *nameA);
GfxFont(char *tagA, Ref idA, GString *nameA);
virtual ~GfxFont();
@ -104,6 +105,10 @@ public:
// Get base font name.
GString *getName() { return name; }
// Get the original font name (ignornig any munging that might have
// been done to map to a canonical Base-14 font name).
GString *getOrigName() { return origName; }
// Get font type.
GfxFontType getType() { return type; }
virtual GBool isCIDFont() { return gFalse; }
@ -158,12 +163,14 @@ public:
protected:
void readFontDescriptor(XRef *xref, Dict *fontDict);
CharCodeToUnicode *readToUnicodeCMap(Dict *fontDict, int nBits);
CharCodeToUnicode *readToUnicodeCMap(Dict *fontDict, int nBits,
CharCodeToUnicode *ctu);
void findExtFontFile();
GString *tag; // PDF font tag
Ref id; // reference (used as unique ID)
GString *name; // font name
GString *origName; // original font name
GfxFontType type; // type of font
int flags; // font descriptor flags
GString *embFontName; // name of embedded font
@ -184,7 +191,7 @@ protected:
class Gfx8BitFont: public GfxFont {
public:
Gfx8BitFont(XRef *xref, const char *tagA, Ref idA, GString *nameA,
Gfx8BitFont(XRef *xref, char *tagA, Ref idA, GString *nameA,
GfxFontType typeA, Dict *fontDict);
virtual ~Gfx8BitFont();
@ -205,9 +212,16 @@ public:
// Returns true if the PDF font specified an encoding.
GBool getHasEncoding() { return hasEncoding; }
// Get width of a character or string.
// Returns true if the PDF font specified MacRomanEncoding.
GBool getUsesMacRomanEnc() { return usesMacRomanEnc; }
// Get width of a character.
double getWidth(Guchar c) { return widths[c]; }
// Return a char code-to-GID mapping for the provided font file.
// (This is only useful for TrueType fonts.)
Gushort *getCodeToGIDMap(FoFiTrueType *ff);
// Return the Type 3 CharProc dictionary, or NULL if none.
Dict *getCharProcs();
@ -224,6 +238,7 @@ private:
// the string is malloc'ed
CharCodeToUnicode *ctu; // char code --> Unicode
GBool hasEncoding;
GBool usesMacRomanEnc;
double widths[256]; // character widths
Object charProcs; // Type 3 CharProcs dictionary
Object resources; // Type 3 Resources dictionary
@ -236,7 +251,7 @@ private:
class GfxCIDFont: public GfxFont {
public:
GfxCIDFont(XRef *xref, const char *tagA, Ref idA, GString *nameA,
GfxCIDFont(XRef *xref, char *tagA, Ref idA, GString *nameA,
Dict *fontDict);
virtual ~GfxCIDFont();
@ -279,7 +294,7 @@ class GfxFontDict {
public:
// Build the font dictionary, given the PDF font dictionary.
GfxFontDict(XRef *xref, Dict *fontDict);
GfxFontDict(XRef *xref, Ref *fontDictRef, Dict *fontDict);
// Destructor.
~GfxFontDict();

View file

@ -98,7 +98,7 @@ GfxColorSpace *GfxColorSpace::parse(Object *csObj) {
} else if (obj1.isName("Pattern")) {
cs = GfxPatternColorSpace::parse(csObj->getArray());
} else {
error(-1, "Bad color space '%s'", csObj->getName());
error(-1, "Bad color space");
}
obj1.free();
} else {
@ -760,12 +760,18 @@ void GfxICCBasedColorSpace::getCMYK(GfxColor *color, GfxCMYK *cmyk) {
void GfxICCBasedColorSpace::getDefaultRanges(double *decodeLow,
double *decodeRange,
int maxImgPixel) {
alt->getDefaultRanges(decodeLow, decodeRange, maxImgPixel);
#if 0
// this is nominally correct, but some PDF files don't set the
// correct ranges in the ICCBased dict
int i;
for (i = 0; i < nComps; ++i) {
decodeLow[i] = rangeMin[i];
decodeRange[i] = rangeMax[i] - rangeMin[i];
}
#endif
}
//------------------------------------------------------------------------
@ -1047,6 +1053,11 @@ GfxColorSpace *GfxDeviceNColorSpace::parse(Array *arr) {
goto err2;
}
nCompsA = obj1.arrayGetLength();
if (nCompsA > gfxColorMaxComps) {
error(-1, "DeviceN color space with more than %d > %d components",
nCompsA, gfxColorMaxComps);
nCompsA = gfxColorMaxComps;
}
for (i = 0; i < nCompsA; ++i) {
if (!obj1.arrayGet(i, &obj2)->isName()) {
error(-1, "Bad DeviceN color space (names)");
@ -1175,18 +1186,22 @@ GfxPattern::~GfxPattern() {
GfxPattern *GfxPattern::parse(Object *obj) {
GfxPattern *pattern;
Dict *dict;
Object obj1;
pattern = NULL;
if (obj->isStream()) {
dict = obj->streamGetDict();
dict->lookup("PatternType", &obj1);
if (obj1.isInt() && obj1.getInt() == 1) {
pattern = new GfxTilingPattern(dict, obj);
}
obj1.free();
if (obj->isDict()) {
obj->dictLookup("PatternType", &obj1);
} else if (obj->isStream()) {
obj->streamGetDict()->lookup("PatternType", &obj1);
} else {
return NULL;
}
pattern = NULL;
if (obj1.isInt() && obj1.getInt() == 1) {
pattern = GfxTilingPattern::parse(obj);
} else if (obj1.isInt() && obj1.getInt() == 2) {
pattern = GfxShadingPattern::parse(obj);
}
obj1.free();
return pattern;
}
@ -1194,33 +1209,42 @@ GfxPattern *GfxPattern::parse(Object *obj) {
// GfxTilingPattern
//------------------------------------------------------------------------
GfxTilingPattern::GfxTilingPattern(Dict *streamDict, Object *stream):
GfxPattern(1)
{
GfxTilingPattern *GfxTilingPattern::parse(Object *patObj) {
GfxTilingPattern *pat;
Dict *dict;
int paintTypeA, tilingTypeA;
double bboxA[4], matrixA[6];
double xStepA, yStepA;
Object resDictA;
Object obj1, obj2;
int i;
if (streamDict->lookup("PaintType", &obj1)->isInt()) {
paintType = obj1.getInt();
if (!patObj->isStream()) {
return NULL;
}
dict = patObj->streamGetDict();
if (dict->lookup("PaintType", &obj1)->isInt()) {
paintTypeA = obj1.getInt();
} else {
paintType = 1;
paintTypeA = 1;
error(-1, "Invalid or missing PaintType in pattern");
}
obj1.free();
if (streamDict->lookup("TilingType", &obj1)->isInt()) {
tilingType = obj1.getInt();
if (dict->lookup("TilingType", &obj1)->isInt()) {
tilingTypeA = obj1.getInt();
} else {
tilingType = 1;
tilingTypeA = 1;
error(-1, "Invalid or missing TilingType in pattern");
}
obj1.free();
bbox[0] = bbox[1] = 0;
bbox[2] = bbox[3] = 1;
if (streamDict->lookup("BBox", &obj1)->isArray() &&
bboxA[0] = bboxA[1] = 0;
bboxA[2] = bboxA[3] = 1;
if (dict->lookup("BBox", &obj1)->isArray() &&
obj1.arrayGetLength() == 4) {
for (i = 0; i < 4; ++i) {
if (obj1.arrayGet(i, &obj2)->isNum()) {
bbox[i] = obj2.getNum();
bboxA[i] = obj2.getNum();
}
obj2.free();
}
@ -1228,39 +1252,65 @@ GfxTilingPattern::GfxTilingPattern(Dict *streamDict, Object *stream):
error(-1, "Invalid or missing BBox in pattern");
}
obj1.free();
if (streamDict->lookup("XStep", &obj1)->isNum()) {
xStep = obj1.getNum();
if (dict->lookup("XStep", &obj1)->isNum()) {
xStepA = obj1.getNum();
} else {
xStep = 1;
xStepA = 1;
error(-1, "Invalid or missing XStep in pattern");
}
obj1.free();
if (streamDict->lookup("YStep", &obj1)->isNum()) {
yStep = obj1.getNum();
if (dict->lookup("YStep", &obj1)->isNum()) {
yStepA = obj1.getNum();
} else {
yStep = 1;
yStepA = 1;
error(-1, "Invalid or missing YStep in pattern");
}
obj1.free();
if (!streamDict->lookup("Resources", &resDict)->isDict()) {
resDict.free();
resDict.initNull();
if (!dict->lookup("Resources", &resDictA)->isDict()) {
resDictA.free();
resDictA.initNull();
error(-1, "Invalid or missing Resources in pattern");
}
matrix[0] = 1; matrix[1] = 0;
matrix[2] = 0; matrix[3] = 1;
matrix[4] = 0; matrix[5] = 0;
if (streamDict->lookup("Matrix", &obj1)->isArray() &&
matrixA[0] = 1; matrixA[1] = 0;
matrixA[2] = 0; matrixA[3] = 1;
matrixA[4] = 0; matrixA[5] = 0;
if (dict->lookup("Matrix", &obj1)->isArray() &&
obj1.arrayGetLength() == 6) {
for (i = 0; i < 6; ++i) {
if (obj1.arrayGet(i, &obj2)->isNum()) {
matrix[i] = obj2.getNum();
matrixA[i] = obj2.getNum();
}
obj2.free();
}
}
obj1.free();
stream->copy(&contentStream);
pat = new GfxTilingPattern(paintTypeA, tilingTypeA, bboxA, xStepA, yStepA,
&resDictA, matrixA, patObj);
resDictA.free();
return pat;
}
GfxTilingPattern::GfxTilingPattern(int paintTypeA, int tilingTypeA,
double *bboxA, double xStepA, double yStepA,
Object *resDictA, double *matrixA,
Object *contentStreamA):
GfxPattern(1)
{
int i;
paintType = paintTypeA;
tilingType = tilingTypeA;
for (i = 0; i < 4; ++i) {
bbox[i] = bboxA[i];
}
xStep = xStepA;
yStep = yStepA;
resDictA->copy(&resDict);
for (i = 0; i < 6; ++i) {
matrix[i] = matrixA[i];
}
contentStreamA->copy(&contentStream);
}
GfxTilingPattern::~GfxTilingPattern() {
@ -1269,119 +1319,135 @@ GfxTilingPattern::~GfxTilingPattern() {
}
GfxPattern *GfxTilingPattern::copy() {
return new GfxTilingPattern(this);
return new GfxTilingPattern(paintType, tilingType, bbox, xStep, yStep,
&resDict, matrix, &contentStream);
}
GfxTilingPattern::GfxTilingPattern(GfxTilingPattern *pat):
GfxPattern(1)
//------------------------------------------------------------------------
// GfxShadingPattern
//------------------------------------------------------------------------
GfxShadingPattern *GfxShadingPattern::parse(Object *patObj) {
Dict *dict;
GfxShading *shadingA;
double matrixA[6];
Object obj1, obj2;
int i;
if (!patObj->isDict()) {
return NULL;
}
dict = patObj->getDict();
dict->lookup("Shading", &obj1);
shadingA = GfxShading::parse(&obj1);
obj1.free();
if (!shadingA) {
return NULL;
}
matrixA[0] = 1; matrixA[1] = 0;
matrixA[2] = 0; matrixA[3] = 1;
matrixA[4] = 0; matrixA[5] = 0;
if (dict->lookup("Matrix", &obj1)->isArray() &&
obj1.arrayGetLength() == 6) {
for (i = 0; i < 6; ++i) {
if (obj1.arrayGet(i, &obj2)->isNum()) {
matrixA[i] = obj2.getNum();
}
obj2.free();
}
}
obj1.free();
return new GfxShadingPattern(shadingA, matrixA);
}
GfxShadingPattern::GfxShadingPattern(GfxShading *shadingA, double *matrixA):
GfxPattern(2)
{
memcpy(this, pat, sizeof(GfxTilingPattern));
pat->resDict.copy(&resDict);
pat->contentStream.copy(&contentStream);
int i;
shading = shadingA;
for (i = 0; i < 6; ++i) {
matrix[i] = matrixA[i];
}
}
GfxShadingPattern::~GfxShadingPattern() {
delete shading;
}
GfxPattern *GfxShadingPattern::copy() {
return new GfxShadingPattern(shading->copy(), matrix);
}
//------------------------------------------------------------------------
// GfxShading
//------------------------------------------------------------------------
GfxShading::GfxShading() {
GfxShading::GfxShading(int typeA) {
type = typeA;
colorSpace = NULL;
}
GfxShading::GfxShading(GfxShading *shading) {
int i;
type = shading->type;
colorSpace = shading->colorSpace->copy();
for (i = 0; i < gfxColorMaxComps; ++i) {
background.c[i] = shading->background.c[i];
}
hasBackground = shading->hasBackground;
xMin = shading->xMin;
yMin = shading->yMin;
xMax = shading->xMax;
yMax = shading->yMax;
hasBBox = shading->hasBBox;
}
GfxShading::~GfxShading() {
delete colorSpace;
if (colorSpace) {
delete colorSpace;
}
}
GfxShading *GfxShading::parse(Object *obj) {
GfxShading *shading;
Dict *dict;
int typeA;
GfxColorSpace *colorSpaceA;
GfxColor backgroundA;
GBool hasBackgroundA;
double xMinA, yMinA, xMaxA, yMaxA;
GBool hasBBoxA;
Object obj1, obj2;
int i;
Object obj1;
shading = NULL;
if (obj->isDict()) {
dict = obj->getDict();
} else if (obj->isStream()) {
dict = obj->streamGetDict();
} else {
return NULL;
}
if (!obj->dictLookup("ShadingType", &obj1)->isInt()) {
error(-1, "Invalid ShadingType in shading dictionary");
obj1.free();
goto err1;
}
typeA = obj1.getInt();
if (!dict->lookup("ShadingType", &obj1)->isInt()) {
error(-1, "Invalid ShadingType in shading dictionary");
obj1.free();
return NULL;
}
typeA = obj1.getInt();
obj1.free();
obj->dictLookup("ColorSpace", &obj1);
if (!(colorSpaceA = GfxColorSpace::parse(&obj1))) {
error(-1, "Bad color space in shading dictionary");
obj1.free();
goto err1;
}
obj1.free();
for (i = 0; i < gfxColorMaxComps; ++i) {
backgroundA.c[i] = 0;
}
hasBackgroundA = gFalse;
if (obj->dictLookup("Background", &obj1)->isArray()) {
if (obj1.arrayGetLength() == colorSpaceA->getNComps()) {
hasBackgroundA = gTrue;
for (i = 0; i < colorSpaceA->getNComps(); ++i) {
backgroundA.c[i] = obj1.arrayGet(i, &obj2)->getNum();
obj2.free();
}
} else {
error(-1, "Bad Background in shading dictionary");
}
}
obj1.free();
xMinA = yMinA = xMaxA = yMaxA = 0;
hasBBoxA = gFalse;
if (obj->dictLookup("BBox", &obj1)->isArray()) {
if (obj1.arrayGetLength() == 4) {
hasBBoxA = gTrue;
xMinA = obj1.arrayGet(0, &obj2)->getNum();
obj2.free();
yMinA = obj1.arrayGet(1, &obj2)->getNum();
obj2.free();
xMaxA = obj1.arrayGet(2, &obj2)->getNum();
obj2.free();
yMaxA = obj1.arrayGet(3, &obj2)->getNum();
obj2.free();
} else {
error(-1, "Bad BBox in shading dictionary");
}
}
obj1.free();
switch (typeA) {
case 2:
shading = GfxAxialShading::parse(obj->getDict());
break;
case 3:
shading = GfxRadialShading::parse(obj->getDict());
break;
default:
error(-1, "Unimplemented shading type %d", typeA);
goto err1;
}
if (shading) {
shading->type = typeA;
shading->colorSpace = colorSpaceA;
shading->background = backgroundA;
shading->hasBackground = hasBackgroundA;
shading->xMin = xMinA;
shading->yMin = yMinA;
shading->xMax = xMaxA;
shading->yMax = yMaxA;
shading->hasBBox = hasBBoxA;
} else {
delete colorSpaceA;
}
switch (typeA) {
case 1:
shading = GfxFunctionShading::parse(dict);
break;
case 2:
shading = GfxAxialShading::parse(dict);
break;
case 3:
shading = GfxRadialShading::parse(dict);
break;
default:
error(-1, "Unimplemented shading type %d", typeA);
goto err1;
}
return shading;
@ -1390,6 +1456,204 @@ GfxShading *GfxShading::parse(Object *obj) {
return NULL;
}
GBool GfxShading::init(Dict *dict) {
Object obj1, obj2;
int i;
dict->lookup("ColorSpace", &obj1);
if (!(colorSpace = GfxColorSpace::parse(&obj1))) {
error(-1, "Bad color space in shading dictionary");
obj1.free();
return gFalse;
}
obj1.free();
for (i = 0; i < gfxColorMaxComps; ++i) {
background.c[i] = 0;
}
hasBackground = gFalse;
if (dict->lookup("Background", &obj1)->isArray()) {
if (obj1.arrayGetLength() == colorSpace->getNComps()) {
hasBackground = gTrue;
for (i = 0; i < colorSpace->getNComps(); ++i) {
background.c[i] = obj1.arrayGet(i, &obj2)->getNum();
obj2.free();
}
} else {
error(-1, "Bad Background in shading dictionary");
}
}
obj1.free();
xMin = yMin = xMax = yMax = 0;
hasBBox = gFalse;
if (dict->lookup("BBox", &obj1)->isArray()) {
if (obj1.arrayGetLength() == 4) {
hasBBox = gTrue;
xMin = obj1.arrayGet(0, &obj2)->getNum();
obj2.free();
yMin = obj1.arrayGet(1, &obj2)->getNum();
obj2.free();
xMax = obj1.arrayGet(2, &obj2)->getNum();
obj2.free();
yMax = obj1.arrayGet(3, &obj2)->getNum();
obj2.free();
} else {
error(-1, "Bad BBox in shading dictionary");
}
}
obj1.free();
return gTrue;
}
//------------------------------------------------------------------------
// GfxFunctionShading
//------------------------------------------------------------------------
GfxFunctionShading::GfxFunctionShading(double x0A, double y0A,
double x1A, double y1A,
double *matrixA,
Function **funcsA, int nFuncsA):
GfxShading(1)
{
int i;
x0 = x0A;
y0 = y0A;
x1 = x1A;
y1 = y1A;
for (i = 0; i < 6; ++i) {
matrix[i] = matrixA[i];
}
nFuncs = nFuncsA;
for (i = 0; i < nFuncs; ++i) {
funcs[i] = funcsA[i];
}
}
GfxFunctionShading::GfxFunctionShading(GfxFunctionShading *shading):
GfxShading(shading)
{
int i;
x0 = shading->x0;
y0 = shading->y0;
x1 = shading->x1;
y1 = shading->y1;
for (i = 0; i < 6; ++i) {
matrix[i] = shading->matrix[i];
}
nFuncs = shading->nFuncs;
for (i = 0; i < nFuncs; ++i) {
funcs[i] = shading->funcs[i]->copy();
}
}
GfxFunctionShading::~GfxFunctionShading() {
int i;
for (i = 0; i < nFuncs; ++i) {
delete funcs[i];
}
}
GfxFunctionShading *GfxFunctionShading::parse(Dict *dict) {
GfxFunctionShading *shading;
double x0A, y0A, x1A, y1A;
double matrixA[6];
Function *funcsA[gfxColorMaxComps];
int nFuncsA;
Object obj1, obj2;
int i;
x0A = y0A = 0;
x1A = y1A = 1;
if (dict->lookup("Domain", &obj1)->isArray() &&
obj1.arrayGetLength() == 4) {
x0A = obj1.arrayGet(0, &obj2)->getNum();
obj2.free();
y0A = obj1.arrayGet(1, &obj2)->getNum();
obj2.free();
x1A = obj1.arrayGet(2, &obj2)->getNum();
obj2.free();
y1A = obj1.arrayGet(3, &obj2)->getNum();
obj2.free();
}
obj1.free();
matrixA[0] = 1; matrixA[1] = 0;
matrixA[2] = 0; matrixA[3] = 1;
matrixA[4] = 0; matrixA[5] = 0;
if (dict->lookup("Matrix", &obj1)->isArray() &&
obj1.arrayGetLength() == 6) {
matrixA[0] = obj1.arrayGet(0, &obj2)->getNum();
obj2.free();
matrixA[1] = obj1.arrayGet(1, &obj2)->getNum();
obj2.free();
matrixA[2] = obj1.arrayGet(2, &obj2)->getNum();
obj2.free();
matrixA[3] = obj1.arrayGet(3, &obj2)->getNum();
obj2.free();
matrixA[4] = obj1.arrayGet(4, &obj2)->getNum();
obj2.free();
matrixA[5] = obj1.arrayGet(5, &obj2)->getNum();
obj2.free();
}
obj1.free();
dict->lookup("Function", &obj1);
if (obj1.isArray()) {
nFuncsA = obj1.arrayGetLength();
if (nFuncsA > gfxColorMaxComps) {
error(-1, "Invalid Function array in shading dictionary");
goto err1;
}
for (i = 0; i < nFuncsA; ++i) {
obj1.arrayGet(i, &obj2);
if (!(funcsA[i] = Function::parse(&obj2))) {
goto err2;
}
obj2.free();
}
} else {
nFuncsA = 1;
if (!(funcsA[0] = Function::parse(&obj1))) {
goto err1;
}
}
obj1.free();
shading = new GfxFunctionShading(x0A, y0A, x1A, y1A, matrixA,
funcsA, nFuncsA);
if (!shading->init(dict)) {
delete shading;
return NULL;
}
return shading;
err2:
obj2.free();
err1:
obj1.free();
return NULL;
}
GfxShading *GfxFunctionShading::copy() {
return new GfxFunctionShading(this);
}
void GfxFunctionShading::getColor(double x, double y, GfxColor *color) {
double in[2];
int i;
in[0] = x;
in[1] = y;
for (i = 0; i < nFuncs; ++i) {
funcs[i]->transform(in, &color->c[i]);
}
}
//------------------------------------------------------------------------
// GfxAxialShading
//------------------------------------------------------------------------
@ -1398,7 +1662,9 @@ GfxAxialShading::GfxAxialShading(double x0A, double y0A,
double x1A, double y1A,
double t0A, double t1A,
Function **funcsA, int nFuncsA,
GBool extend0A, GBool extend1A) {
GBool extend0A, GBool extend1A):
GfxShading(2)
{
int i;
x0 = x0A;
@ -1415,6 +1681,25 @@ GfxAxialShading::GfxAxialShading(double x0A, double y0A,
extend1 = extend1A;
}
GfxAxialShading::GfxAxialShading(GfxAxialShading *shading):
GfxShading(shading)
{
int i;
x0 = shading->x0;
y0 = shading->y0;
x1 = shading->x1;
y1 = shading->y1;
t0 = shading->t0;
y1 = shading->t1;
nFuncs = shading->nFuncs;
for (i = 0; i < nFuncs; ++i) {
funcs[i] = shading->funcs[i]->copy();
}
extend0 = shading->extend0;
extend1 = shading->extend1;
}
GfxAxialShading::~GfxAxialShading() {
int i;
@ -1424,6 +1709,7 @@ GfxAxialShading::~GfxAxialShading() {
}
GfxAxialShading *GfxAxialShading::parse(Dict *dict) {
GfxAxialShading *shading;
double x0A, y0A, x1A, y1A;
double t0A, t1A;
Function *funcsA[gfxColorMaxComps];
@ -1463,6 +1749,10 @@ GfxAxialShading *GfxAxialShading::parse(Dict *dict) {
dict->lookup("Function", &obj1);
if (obj1.isArray()) {
nFuncsA = obj1.arrayGetLength();
if (nFuncsA > gfxColorMaxComps) {
error(-1, "Invalid Function array in shading dictionary");
goto err1;
}
for (i = 0; i < nFuncsA; ++i) {
obj1.arrayGet(i, &obj2);
if (!(funcsA[i] = Function::parse(&obj2))) {
@ -1491,16 +1781,27 @@ GfxAxialShading *GfxAxialShading::parse(Dict *dict) {
}
obj1.free();
return new GfxAxialShading(x0A, y0A, x1A, y1A, t0A, t1A,
funcsA, nFuncsA, extend0A, extend1A);
shading = new GfxAxialShading(x0A, y0A, x1A, y1A, t0A, t1A,
funcsA, nFuncsA, extend0A, extend1A);
if (!shading->init(dict)) {
delete shading;
return NULL;
}
return shading;
err1:
return NULL;
}
GfxShading *GfxAxialShading::copy() {
return new GfxAxialShading(this);
}
void GfxAxialShading::getColor(double t, GfxColor *color) {
int i;
// NB: there can be one function with n outputs or n functions with
// one output each (where n = number of color components)
for (i = 0; i < nFuncs; ++i) {
funcs[i]->transform(&t, &color->c[i]);
}
@ -1514,7 +1815,9 @@ GfxRadialShading::GfxRadialShading(double x0A, double y0A, double r0A,
double x1A, double y1A, double r1A,
double t0A, double t1A,
Function **funcsA, int nFuncsA,
GBool extend0A, GBool extend1A) {
GBool extend0A, GBool extend1A):
GfxShading(3)
{
int i;
x0 = x0A;
@ -1533,6 +1836,27 @@ GfxRadialShading::GfxRadialShading(double x0A, double y0A, double r0A,
extend1 = extend1A;
}
GfxRadialShading::GfxRadialShading(GfxRadialShading *shading):
GfxShading(shading)
{
int i;
x0 = shading->x0;
y0 = shading->y0;
r0 = shading->r0;
x1 = shading->x1;
y1 = shading->y1;
r1 = shading->r1;
t0 = shading->t0;
y1 = shading->t1;
nFuncs = shading->nFuncs;
for (i = 0; i < nFuncs; ++i) {
funcs[i] = shading->funcs[i]->copy();
}
extend0 = shading->extend0;
extend1 = shading->extend1;
}
GfxRadialShading::~GfxRadialShading() {
int i;
@ -1542,6 +1866,7 @@ GfxRadialShading::~GfxRadialShading() {
}
GfxRadialShading *GfxRadialShading::parse(Dict *dict) {
GfxRadialShading *shading;
double x0A, y0A, r0A, x1A, y1A, r1A;
double t0A, t1A;
Function *funcsA[gfxColorMaxComps];
@ -1585,6 +1910,10 @@ GfxRadialShading *GfxRadialShading::parse(Dict *dict) {
dict->lookup("Function", &obj1);
if (obj1.isArray()) {
nFuncsA = obj1.arrayGetLength();
if (nFuncsA > gfxColorMaxComps) {
error(-1, "Invalid Function array in shading dictionary");
goto err1;
}
for (i = 0; i < nFuncsA; ++i) {
obj1.arrayGet(i, &obj2);
if (!(funcsA[i] = Function::parse(&obj2))) {
@ -1613,16 +1942,27 @@ GfxRadialShading *GfxRadialShading::parse(Dict *dict) {
}
obj1.free();
return new GfxRadialShading(x0A, y0A, r0A, x1A, y1A, r1A, t0A, t1A,
funcsA, nFuncsA, extend0A, extend1A);
shading = new GfxRadialShading(x0A, y0A, r0A, x1A, y1A, r1A, t0A, t1A,
funcsA, nFuncsA, extend0A, extend1A);
if (!shading->init(dict)) {
delete shading;
return NULL;
}
return shading;
err1:
return NULL;
}
GfxShading *GfxRadialShading::copy() {
return new GfxRadialShading(this);
}
void GfxRadialShading::getColor(double t, GfxColor *color) {
int i;
// NB: there can be one function with n outputs or n functions with
// one output each (where n = number of color components)
for (i = 0; i < nFuncs; ++i) {
funcs[i]->transform(&t, &color->c[i]);
}
@ -1695,13 +2035,18 @@ GfxImageColorMap::GfxImageColorMap(int bitsA, Object *decode,
colorSpace2 = indexedCS->getBase();
indexHigh = indexedCS->getIndexHigh();
nComps2 = colorSpace2->getNComps();
lookup = (double *)gmalloc((indexHigh + 1) * nComps2 * sizeof(double));
lookup = (double *)gmalloc((maxPixel + 1) * nComps2 * sizeof(double));
lookup2 = indexedCS->getLookup();
colorSpace2->getDefaultRanges(x, y, indexHigh);
for (i = 0; i <= indexHigh; ++i) {
for (i = 0; i <= maxPixel; ++i) {
j = (int)(decodeLow[0] + (i * decodeRange[0]) / maxPixel + 0.5);
if (j < 0) {
j = 0;
} else if (j > indexHigh) {
j = indexHigh;
}
for (k = 0; k < nComps2; ++k) {
lookup[j*nComps2 + k] = x[k] + (lookup2[i*nComps2 + k] / 255.0) * y[k];
lookup[i*nComps2 + k] = x[k] + (lookup2[j*nComps2 + k] / 255.0) * y[k];
}
}
} else if (colorSpace->getMode() == csSeparation) {
@ -1735,6 +2080,34 @@ GfxImageColorMap::GfxImageColorMap(int bitsA, Object *decode,
ok = gFalse;
}
GfxImageColorMap::GfxImageColorMap(GfxImageColorMap *colorMap) {
int n, i;
colorSpace = colorMap->colorSpace->copy();
bits = colorMap->bits;
nComps = colorMap->nComps;
nComps2 = colorMap->nComps2;
colorSpace2 = NULL;
lookup = NULL;
n = 1 << bits;
if (colorSpace->getMode() == csIndexed) {
colorSpace2 = ((GfxIndexedColorSpace *)colorSpace)->getBase();
n = n * nComps2 * sizeof(double);
} else if (colorSpace->getMode() == csSeparation) {
colorSpace2 = ((GfxSeparationColorSpace *)colorSpace)->getAlt();
n = n * nComps2 * sizeof(double);
} else {
n = n * nComps * sizeof(double);
}
lookup = (double *)gmalloc(n);
memcpy(lookup, colorMap->lookup, n);
for (i = 0; i < nComps; ++i) {
decodeLow[i] = colorMap->decodeLow[i];
decodeRange[i] = colorMap->decodeRange[i];
}
ok = gTrue;
}
GfxImageColorMap::~GfxImageColorMap() {
delete colorSpace;
gfree(lookup);
@ -1880,6 +2253,15 @@ void GfxSubpath::close() {
closed = gTrue;
}
void GfxSubpath::offset(double dx, double dy) {
int i;
for (i = 0; i < n; ++i) {
x[i] += dx;
y[i] += dy;
}
}
GfxPath::GfxPath() {
justMoved = gFalse;
size = 16;
@ -1962,55 +2344,78 @@ void GfxPath::close() {
subpaths[n-1]->close();
}
void GfxPath::append(GfxPath *path) {
int i;
if (n + path->n > size) {
size = n + path->n;
subpaths = (GfxSubpath **)
grealloc(subpaths, size * sizeof(GfxSubpath *));
}
for (i = 0; i < path->n; ++i) {
subpaths[n++] = path->subpaths[i]->copy();
}
justMoved = gFalse;
}
void GfxPath::offset(double dx, double dy) {
int i;
for (i = 0; i < n; ++i) {
subpaths[i]->offset(dx, dy);
}
}
//------------------------------------------------------------------------
// GfxState
//------------------------------------------------------------------------
GfxState::GfxState(double dpi, PDFRectangle *pageBox, int rotate,
GBool upsideDown) {
double k;
GfxState::GfxState(double hDPI, double vDPI, PDFRectangle *pageBox,
int rotate, GBool upsideDown) {
double kx, ky;
px1 = pageBox->x1;
py1 = pageBox->y1;
px2 = pageBox->x2;
py2 = pageBox->y2;
k = dpi / 72.0;
kx = hDPI / 72.0;
ky = vDPI / 72.0;
if (rotate == 90) {
ctm[0] = 0;
ctm[1] = upsideDown ? k : -k;
ctm[2] = k;
ctm[1] = upsideDown ? ky : -ky;
ctm[2] = kx;
ctm[3] = 0;
ctm[4] = -k * py1;
ctm[5] = k * (upsideDown ? -px1 : px2);
pageWidth = k * (py2 - py1);
pageHeight = k * (px2 - px1);
ctm[4] = -kx * py1;
ctm[5] = ky * (upsideDown ? -px1 : px2);
pageWidth = kx * (py2 - py1);
pageHeight = ky * (px2 - px1);
} else if (rotate == 180) {
ctm[0] = -k;
ctm[0] = -kx;
ctm[1] = 0;
ctm[2] = 0;
ctm[3] = upsideDown ? k : -k;
ctm[4] = k * px2;
ctm[5] = k * (upsideDown ? -py1 : py2);
pageWidth = k * (px2 - px1);
pageHeight = k * (py2 - py1);
ctm[3] = upsideDown ? ky : -ky;
ctm[4] = kx * px2;
ctm[5] = ky * (upsideDown ? -py1 : py2);
pageWidth = kx * (px2 - px1);
pageHeight = ky * (py2 - py1);
} else if (rotate == 270) {
ctm[0] = 0;
ctm[1] = upsideDown ? -k : k;
ctm[2] = -k;
ctm[1] = upsideDown ? -ky : ky;
ctm[2] = -kx;
ctm[3] = 0;
ctm[4] = k * py2;
ctm[5] = k * (upsideDown ? px2 : -px1);
pageWidth = k * (py2 - py1);
pageHeight = k * (px2 - px1);
ctm[4] = kx * py2;
ctm[5] = ky * (upsideDown ? px2 : -px1);
pageWidth = kx * (py2 - py1);
pageHeight = ky * (px2 - px1);
} else {
ctm[0] = k;
ctm[0] = kx;
ctm[1] = 0;
ctm[2] = 0;
ctm[3] = upsideDown ? -k : k;
ctm[4] = -k * px1;
ctm[5] = k * (upsideDown ? py2 : -py1);
pageWidth = k * (px2 - px1);
pageHeight = k * (py2 - py1);
ctm[3] = upsideDown ? -ky : ky;
ctm[4] = -kx * px1;
ctm[5] = ky * (upsideDown ? py2 : -py1);
pageWidth = kx * (px2 - px1);
pageHeight = ky * (py2 - py1);
}
fillColorSpace = new GfxDeviceGrayColorSpace();
@ -2026,7 +2431,7 @@ GfxState::GfxState(double dpi, PDFRectangle *pageBox, int rotate,
lineDash = NULL;
lineDashLength = 0;
lineDashStart = 0;
flatness = 0;
flatness = 1;
lineJoin = 0;
lineCap = 0;
miterLimit = 10;
@ -2100,6 +2505,11 @@ GfxState::GfxState(GfxState *state) {
saved = NULL;
}
void GfxState::setPath(GfxPath *pathA) {
delete path;
path = pathA;
}
void GfxState::getUserClipBBox(double *xMin, double *yMin,
double *xMax, double *yMax) {
double ictm[6];

View file

@ -22,6 +22,7 @@
class Array;
class GfxFont;
class PDFRectangle;
class GfxShading;
//------------------------------------------------------------------------
// GfxColor
@ -402,7 +403,7 @@ private:
class GfxDeviceNColorSpace: public GfxColorSpace {
public:
GfxDeviceNColorSpace(int nComps, GfxColorSpace *alt, Function *func);
GfxDeviceNColorSpace(int nCompsA, GfxColorSpace *alt, Function *func);
virtual ~GfxDeviceNColorSpace();
virtual GfxColorSpace *copy();
virtual GfxColorSpaceMode getMode() { return csDeviceN; }
@ -428,7 +429,6 @@ private:
*names[gfxColorMaxComps];
GfxColorSpace *alt; // alternate color space
Function *func; // tint transform (into alternate color space)
};
//------------------------------------------------------------------------
@ -489,7 +489,7 @@ private:
class GfxTilingPattern: public GfxPattern {
public:
GfxTilingPattern(Dict *streamDict, Object *stream);
static GfxTilingPattern *parse(Object *patObj);
virtual ~GfxTilingPattern();
virtual GfxPattern *copy();
@ -506,7 +506,10 @@ public:
private:
GfxTilingPattern(GfxTilingPattern *pat);
GfxTilingPattern(int paintTypeA, int tilingTypeA,
double *bboxA, double xStepA, double yStepA,
Object *resDictA, double *matrixA,
Object *contentStreamA);
int paintType;
int tilingType;
@ -517,6 +520,29 @@ private:
Object contentStream;
};
//------------------------------------------------------------------------
// GfxShadingPattern
//------------------------------------------------------------------------
class GfxShadingPattern: public GfxPattern {
public:
static GfxShadingPattern *parse(Object *patObj);
virtual ~GfxShadingPattern();
virtual GfxPattern *copy();
GfxShading *getShading() { return shading; }
double *getMatrix() { return matrix; }
private:
GfxShadingPattern(GfxShading *shadingA, double *matrixA);
GfxShading *shading;
double matrix[6];
};
//------------------------------------------------------------------------
// GfxShading
//------------------------------------------------------------------------
@ -524,11 +550,14 @@ private:
class GfxShading {
public:
GfxShading();
GfxShading(int typeA);
GfxShading(GfxShading *shading);
virtual ~GfxShading();
static GfxShading *parse(Object *obj);
virtual GfxShading *copy() = 0;
int getType() { return type; }
GfxColorSpace *getColorSpace() { return colorSpace; }
GfxColor *getBackground() { return &background; }
@ -537,7 +566,9 @@ public:
{ *xMinA = xMin; *yMinA = yMin; *xMaxA = xMax; *yMaxA = yMax; }
GBool getHasBBox() { return hasBBox; }
private:
protected:
GBool init(Dict *dict);
int type;
GfxColorSpace *colorSpace;
@ -547,6 +578,37 @@ private:
GBool hasBBox;
};
//------------------------------------------------------------------------
// GfxFunctionShading
//------------------------------------------------------------------------
class GfxFunctionShading: public GfxShading {
public:
GfxFunctionShading(double x0A, double y0A,
double x1A, double y1A,
double *matrixA,
Function **funcsA, int nFuncsA);
GfxFunctionShading(GfxFunctionShading *shading);
virtual ~GfxFunctionShading();
static GfxFunctionShading *parse(Dict *dict);
virtual GfxShading *copy();
void getDomain(double *x0A, double *y0A, double *x1A, double *y1A)
{ *x0A = x0; *y0A = y0; *x1A = x1; *y1A = y1; }
double *getMatrix() { return matrix; }
void getColor(double x, double y, GfxColor *color);
private:
double x0, y0, x1, y1;
double matrix[6];
Function *funcs[gfxColorMaxComps];
int nFuncs;
};
//------------------------------------------------------------------------
// GfxAxialShading
//------------------------------------------------------------------------
@ -559,10 +621,13 @@ public:
double t0A, double t1A,
Function **funcsA, int nFuncsA,
GBool extend0A, GBool extend1A);
GfxAxialShading(GfxAxialShading *shading);
virtual ~GfxAxialShading();
static GfxAxialShading *parse(Dict *dict);
virtual GfxShading *copy();
void getCoords(double *x0A, double *y0A, double *x1A, double *y1A)
{ *x0A = x0; *y0A = y0; *x1A = x1; *y1A = y1; }
double getDomain0() { return t0; }
@ -592,10 +657,13 @@ public:
double t0A, double t1A,
Function **funcsA, int nFuncsA,
GBool extend0A, GBool extend1A);
GfxRadialShading(GfxRadialShading *shading);
virtual ~GfxRadialShading();
static GfxRadialShading *parse(Dict *dict);
virtual GfxShading *copy();
void getCoords(double *x0A, double *y0A, double *r0A,
double *x1A, double *y1A, double *r1A)
{ *x0A = x0; *y0A = y0; *r0A = r0; *x1A = x1; *y1A = y1; *r1A = r1; }
@ -627,6 +695,9 @@ public:
// Destructor.
~GfxImageColorMap();
// Return a copy of this color map.
GfxImageColorMap *copy() { return new GfxImageColorMap(this); }
// Is color map valid?
GBool isOk() { return ok; }
@ -649,6 +720,8 @@ public:
private:
GfxImageColorMap(GfxImageColorMap *colorMap);
GfxColorSpace *colorSpace; // the image color space
int bits; // bits per component
int nComps; // number of components in a pixel
@ -699,6 +772,9 @@ public:
void close();
GBool isClosed() { return closed; }
// Add (<dx>, <dy>) to each point in the subpath.
void offset(double dx, double dy);
private:
double *x, *y; // points
@ -751,6 +827,12 @@ public:
// Close the last subpath.
void close();
// Append <path> to <this>.
void append(GfxPath *path);
// Add (<dx>, <dy>) to each point in the path.
void offset(double dx, double dy);
private:
GBool justMoved; // set if a new subpath was just started
@ -770,11 +852,11 @@ private:
class GfxState {
public:
// Construct a default GfxState, for a device with resolution <dpi>,
// page box <pageBox>, page rotation <rotate>, and coordinate system
// specified by <upsideDown>.
GfxState(double dpi, PDFRectangle *pageBox, int rotate,
GBool upsideDown);
// Construct a default GfxState, for a device with resolution <hDPI>
// x <vDPI>, page box <pageBox>, page rotation <rotate>, and
// coordinate system specified by <upsideDown>.
GfxState(double hDPI, double vDPI, PDFRectangle *pageBox,
int rotate, GBool upsideDown);
// Destructor.
~GfxState();
@ -795,7 +877,7 @@ public:
void getFillGray(double *gray)
{ fillColorSpace->getGray(&fillColor, gray); }
void getStrokeGray(double *gray)
{ strokeColorSpace->getGray(&fillColor, gray); }
{ strokeColorSpace->getGray(&strokeColor, gray); }
void getFillRGB(GfxRGB *rgb)
{ fillColorSpace->getRGB(&fillColor, rgb); }
void getStrokeRGB(GfxRGB *rgb)
@ -827,6 +909,7 @@ public:
double getRise() { return rise; }
int getRender() { return render; }
GfxPath *getPath() { return path; }
void setPath(GfxPath *pathA);
double getCurX() { return curX; }
double getCurY() { return curY; }
void getClipBBox(double *xMin, double *yMin, double *xMax, double *yMax)

File diff suppressed because it is too large Load diff

View file

@ -19,7 +19,7 @@
#include "gtypes.h"
#include "CharTypes.h"
#ifdef MULTITHREADED
#if MULTITHREADED
#include "GMutex.h"
#endif
@ -28,7 +28,7 @@ class GList;
class GHash;
class NameToCharCode;
class CharCodeToUnicode;
class CIDToUnicodeCache;
class CharCodeToUnicodeCache;
class UnicodeMap;
class UnicodeMapCache;
class CMap;
@ -43,7 +43,6 @@ extern GlobalParams *globalParams;
//------------------------------------------------------------------------
enum DisplayFontParamKind {
displayFontX,
displayFontT1,
displayFontTT
};
@ -56,10 +55,6 @@ public:
// generic CID fonts
DisplayFontParamKind kind;
union {
struct {
GString *xlfd;
GString *encoding;
} x;
struct {
GString *fileName;
} t1;
@ -69,18 +64,9 @@ public:
};
DisplayFontParam(GString *nameA, DisplayFontParamKind kindA);
DisplayFontParam(const char *nameA, const char *xlfdA, const char *encodingA);
~DisplayFontParam();
};
// Font rasterizer control.
enum FontRastControl {
fontRastNone, // don't use this rasterizer
fontRastPlain, // use it, without anti-aliasing
fontRastAALow, // use it, with low-level anti-aliasing
fontRastAAHigh // use it, with high-level anti-aliasing
};
//------------------------------------------------------------------------
class PSFontParam {
@ -129,12 +115,13 @@ public:
~GlobalParams();
void setupBaseFonts(char *dir);
//----- accessors
CharCode getMacRomanCharCode(char *charName);
Unicode mapNameToUnicode(char *charName);
FILE *getCIDToUnicodeFile(GString *collection);
UnicodeMap *getResidentUnicodeMap(GString *encodingName);
FILE *getUnicodeMapFile(GString *encodingName);
FILE *findCMapFile(GString *collection, GString *cMapName);
@ -144,7 +131,12 @@ public:
GString *getPSFile();
int getPSPaperWidth();
int getPSPaperHeight();
void getPSImageableArea(int *llx, int *lly, int *urx, int *ury);
GBool getPSDuplex();
GBool getPSCrop();
GBool getPSExpandSmaller();
GBool getPSShrinkLarger();
GBool getPSCenter();
PSLevel getPSLevel();
PSFontParam *getPSFont(GString *fontName);
PSFontParam *getPSFont16(GString *fontName, GString *collection, int wMode);
@ -154,12 +146,15 @@ public:
GBool getPSEmbedCIDTrueType();
GBool getPSOPI();
GBool getPSASCIIHex();
GString *getTextEncodingName();
EndOfLineKind getTextEOL();
GBool getTextPageBreaks();
GBool getTextKeepTinyChars();
GString *findFontFile(const GString *fontName, const char **exts);
GString *findFontFile(GString *fontName, char **exts);
GString *getInitialZoom();
FontRastControl getT1libControl();
FontRastControl getFreeTypeControl();
GBool getEnableT1lib();
GBool getEnableFreeType();
GBool getAntialias();
GString *getURLCommand() { return urlCommand; }
GString *getMovieCommand() { return movieCommand; }
GBool getMapNumericCharNames();
@ -167,6 +162,7 @@ public:
GBool getErrQuiet();
CharCodeToUnicode *getCIDToUnicode(GString *collection);
CharCodeToUnicode *getUnicodeToUnicode(GString *fontName);
UnicodeMap *getUnicodeMap(GString *encodingName);
CMap *getCMap(GString *collection, GString *cMapName);
UnicodeMap *getTextEncoding();
@ -178,7 +174,12 @@ public:
GBool setPSPaperSize(char *size);
void setPSPaperWidth(int width);
void setPSPaperHeight(int height);
void setPSImageableArea(int llx, int lly, int urx, int ury);
void setPSDuplex(GBool duplex);
void setPSCrop(GBool crop);
void setPSExpandSmaller(GBool expand);
void setPSShrinkLarger(GBool shrink);
void setPSCenter(GBool center);
void setPSLevel(PSLevel level);
void setPSEmbedType1(GBool embed);
void setPSEmbedTrueType(GBool embed);
@ -188,10 +189,12 @@ public:
void setPSASCIIHex(GBool hex);
void setTextEncoding(char *encodingName);
GBool setTextEOL(char *s);
void setTextPageBreaks(GBool pageBreaks);
void setTextKeepTinyChars(GBool keep);
void setInitialZoom(char *s);
GBool setT1libControl(char *s);
GBool setFreeTypeControl(char *s);
GBool setEnableT1lib(char *s);
GBool setEnableFreeType(char *s);
GBool setAntialias(char *s);
void setMapNumericCharNames(GBool map);
void setPrintCommands(GBool printCommandsA);
void setErrQuiet(GBool errQuietA);
@ -201,6 +204,7 @@ private:
void parseFile(GString *fileName, FILE *f);
void parseNameToUnicode(GList *tokens, GString *fileName, int line);
void parseCIDToUnicode(GList *tokens, GString *fileName, int line);
void parseUnicodeToUnicode(GList *tokens, GString *fileName, int line);
void parseUnicodeMap(GList *tokens, GString *fileName, int line);
void parseCMapDir(GList *tokens, GString *fileName, int line);
void parseToUnicodeDir(GList *tokens, GString *fileName, int line);
@ -209,6 +213,7 @@ private:
GString *fileName, int line);
void parsePSFile(GList *tokens, GString *fileName, int line);
void parsePSPaperSize(GList *tokens, GString *fileName, int line);
void parsePSImageableArea(GList *tokens, GString *fileName, int line);
void parsePSLevel(GList *tokens, GString *fileName, int line);
void parsePSFont(GList *tokens, GString *fileName, int line);
void parsePSFont16(char *cmdName, GList *fontList,
@ -217,14 +222,12 @@ private:
void parseTextEOL(GList *tokens, GString *fileName, int line);
void parseFontDir(GList *tokens, GString *fileName, int line);
void parseInitialZoom(GList *tokens, GString *fileName, int line);
void parseFontRastControl(char *cmdName, FontRastControl *val,
GList *tokens, GString *fileName, int line);
void parseCommand(char *cmdName, GString **val,
GList *tokens, GString *fileName, int line);
void parseYesNo(char *cmdName, GBool *flag,
GList *tokens, GString *fileName, int line);
GBool parseYesNo2(char *token, GBool *flag);
UnicodeMap *getUnicodeMap2(GString *encodingName);
GBool setFontRastControl(FontRastControl *val, char *s);
//----- static tables
@ -238,6 +241,8 @@ private:
GHash *cidToUnicodes; // files for mappings from char collections
// to Unicode, indexed by collection name
// [GString]
GHash *unicodeToUnicodes; // files for Unicode-to-Unicode mappings,
// indexed by font name pattern [GString]
GHash *residentUnicodeMaps; // mappings from Unicode to char codes,
// indexed by encoding name [UnicodeMap]
GHash *unicodeMaps; // files for mappings from Unicode to char
@ -254,6 +259,14 @@ private:
GString *psFile; // PostScript file or command (for xpdf)
int psPaperWidth; // paper size, in PostScript points, for
int psPaperHeight; // PostScript output
int psImageableLLX, // imageable area, in PostScript points,
psImageableLLY, // for PostScript output
psImageableURX,
psImageableURY;
GBool psCrop; // crop PS output to CropBox
GBool psExpandSmaller; // expand smaller pages to fill paper
GBool psShrinkLarger; // shrink larger pages to fit paper
GBool psCenter; // center pages on the paper
GBool psDuplex; // enable duplexing in PostScript?
PSLevel psLevel; // PostScript level to generate
GHash *psFonts; // PostScript font info, indexed by PDF
@ -270,24 +283,28 @@ private:
// output
EndOfLineKind textEOL; // type of EOL marker to use for text
// output
GBool textPageBreaks; // insert end-of-page markers?
GBool textKeepTinyChars; // keep all characters in text output
GList *fontDirs; // list of font dirs [GString]
GString *initialZoom; // initial zoom level
FontRastControl t1libControl; // t1lib rasterization mode
FontRastControl // FreeType rasterization mode
freetypeControl;
GBool enableT1lib; // t1lib enable flag
GBool enableFreeType; // FreeType enable flag
GBool antialias; // anti-aliasing enable flag
GString *urlCommand; // command executed for URL links
GString *movieCommand; // command executed for movie annotations
GBool mapNumericCharNames; // map numeric char names (from font subsets)?
GBool printCommands; // print the drawing commands
GBool errQuiet; // suppress error messages?
CIDToUnicodeCache *cidToUnicodeCache;
CharCodeToUnicodeCache *cidToUnicodeCache;
CharCodeToUnicodeCache *unicodeToUnicodeCache;
UnicodeMapCache *unicodeMapCache;
CMapCache *cMapCache;
#ifdef MULTITHREADED
#if MULTITHREADED
GMutex mutex;
GMutex unicodeMapCacheMutex;
GMutex cMapCacheMutex;
#endif
};

View file

@ -1,194 +0,0 @@
//========================================================================
//
// ImageOutputDev.cc
//
// Copyright 1998-2003 Glyph & Cog, LLC
//
//========================================================================
#include <aconf.h>
#ifdef USE_GCC_PRAGMAS
#pragma implementation
#endif
#include <stdio.h>
#include <stdlib.h>
#include <stddef.h>
#include <ctype.h>
#include "gmem.h"
#include "config.h"
#include "Error.h"
#include "GfxState.h"
#include "Object.h"
#include "Stream.h"
#include "ImageOutputDev.h"
ImageOutputDev::ImageOutputDev(char *fileRootA, GBool dumpJPEGA) {
fileRoot = copyString(fileRootA);
fileName = (char *)gmalloc(strlen(fileRoot) + 20);
dumpJPEG = dumpJPEGA;
imgNum = 0;
ok = gTrue;
}
ImageOutputDev::~ImageOutputDev() {
gfree(fileName);
gfree(fileRoot);
}
void ImageOutputDev::drawImageMask(GfxState *state, Object *ref, Stream *str,
int width, int height, GBool invert,
GBool inlineImg) {
FILE *f;
int c;
int size, i;
// dump JPEG file
if (dumpJPEG && str->getKind() == strDCT && !inlineImg) {
// open the image file
sprintf(fileName, "%s-%03d.jpg", fileRoot, imgNum);
++imgNum;
if (!(f = fopen(fileName, "wb"))) {
error(-1, "Couldn't open image file '%s'", fileName);
return;
}
// initialize stream
str = ((DCTStream *)str)->getRawStream();
str->reset();
// copy the stream
while ((c = str->getChar()) != EOF)
fputc(c, f);
str->close();
fclose(f);
// dump PBM file
} else {
// open the image file and write the PBM header
sprintf(fileName, "%s-%03d.pbm", fileRoot, imgNum);
++imgNum;
if (!(f = fopen(fileName, "wb"))) {
error(-1, "Couldn't open image file '%s'", fileName);
return;
}
fprintf(f, "P4\n");
fprintf(f, "%d %d\n", width, height);
// initialize stream
str->reset();
// copy the stream
size = height * ((width + 7) / 8);
for (i = 0; i < size; ++i) {
fputc(str->getChar(), f);
}
str->close();
fclose(f);
}
}
void ImageOutputDev::drawImage(GfxState *state, Object *ref, Stream *str,
int width, int height,
GfxImageColorMap *colorMap,
int *maskColors, GBool inlineImg) {
FILE *f;
ImageStream *imgStr;
Guchar *p;
GfxRGB rgb;
int x, y;
int c;
int size, i;
// dump JPEG file
if (dumpJPEG && str->getKind() == strDCT &&
colorMap->getNumPixelComps() == 3 &&
!inlineImg) {
// open the image file
sprintf(fileName, "%s-%03d.jpg", fileRoot, imgNum);
++imgNum;
if (!(f = fopen(fileName, "wb"))) {
error(-1, "Couldn't open image file '%s'", fileName);
return;
}
// initialize stream
str = ((DCTStream *)str)->getRawStream();
str->reset();
// copy the stream
while ((c = str->getChar()) != EOF)
fputc(c, f);
str->close();
fclose(f);
// dump PBM file
} else if (colorMap->getNumPixelComps() == 1 &&
colorMap->getBits() == 1) {
// open the image file and write the PBM header
sprintf(fileName, "%s-%03d.pbm", fileRoot, imgNum);
++imgNum;
if (!(f = fopen(fileName, "wb"))) {
error(-1, "Couldn't open image file '%s'", fileName);
return;
}
fprintf(f, "P4\n");
fprintf(f, "%d %d\n", width, height);
// initialize stream
str->reset();
// copy the stream
size = height * ((width + 7) / 8);
for (i = 0; i < size; ++i) {
fputc(str->getChar() ^ 0xff, f);
}
str->close();
fclose(f);
// dump PPM file
} else {
// open the image file and write the PPM header
sprintf(fileName, "%s-%03d.ppm", fileRoot, imgNum);
++imgNum;
if (!(f = fopen(fileName, "wb"))) {
error(-1, "Couldn't open image file '%s'", fileName);
return;
}
fprintf(f, "P6\n");
fprintf(f, "%d %d\n", width, height);
fprintf(f, "255\n");
// initialize stream
imgStr = new ImageStream(str, width, colorMap->getNumPixelComps(),
colorMap->getBits());
imgStr->reset();
// for each line...
for (y = 0; y < height; ++y) {
// write the line
p = imgStr->getLine();
for (x = 0; x < width; ++x) {
colorMap->getRGB(p, &rgb);
fputc((int)(rgb.r * 255 + 0.5), f);
fputc((int)(rgb.g * 255 + 0.5), f);
fputc((int)(rgb.b * 255 + 0.5), f);
p += colorMap->getNumPixelComps();
}
}
delete imgStr;
fclose(f);
}
}

View file

@ -1,76 +0,0 @@
//========================================================================
//
// ImageOutputDev.h
//
// Copyright 1998-2003 Glyph & Cog, LLC
//
//========================================================================
#ifndef IMAGEOUTPUTDEV_H
#define IMAGEOUTPUTDEV_H
#include <aconf.h>
#ifdef USE_GCC_PRAGMAS
#pragma interface
#endif
#include <stdio.h>
#include "gtypes.h"
#include "OutputDev.h"
class GfxState;
//------------------------------------------------------------------------
// ImageOutputDev
//------------------------------------------------------------------------
class ImageOutputDev: public OutputDev {
public:
// Create an OutputDev which will write images to files named
// <fileRoot>-NNN.<type>. Normally, all images are written as PBM
// (.pbm) or PPM (.ppm) files. If <dumpJPEG> is set, JPEG images are
// written as JPEG (.jpg) files.
ImageOutputDev(char *fileRootA, GBool dumpJPEGA);
// Destructor.
virtual ~ImageOutputDev();
// Check if file was successfully created.
virtual GBool isOk() { return ok; }
// Does this device use beginType3Char/endType3Char? Otherwise,
// text in Type 3 fonts will be drawn with drawChar/drawString.
virtual GBool interpretType3Chars() { return gFalse; }
// Does this device need non-text content?
virtual GBool needNonText() { return gFalse; }
//---- get info about output device
// Does this device use upside-down coordinates?
// (Upside-down means (0,0) is the top left corner of the page.)
virtual GBool upsideDown() { return gTrue; }
// Does this device use drawChar() or drawString()?
virtual GBool useDrawChar() { return gFalse; }
//----- image drawing
virtual void drawImageMask(GfxState *state, Object *ref, Stream *str,
int width, int height, GBool invert,
GBool inlineImg);
virtual void drawImage(GfxState *state, Object *ref, Stream *str,
int width, int height, GfxImageColorMap *colorMap,
int *maskColors, GBool inlineImg);
private:
char *fileRoot; // root of output file names
char *fileName; // buffer for output file names
GBool dumpJPEG; // set to dump native JPEG files
int imgNum; // current image number
GBool ok; // set up ok?
};
#endif

300
xpdf/JArithmeticDecoder.cc Normal file
View file

@ -0,0 +1,300 @@
//========================================================================
//
// JArithmeticDecoder.cc
//
// Copyright 2002-2004 Glyph & Cog, LLC
//
//========================================================================
#include <aconf.h>
#ifdef USE_GCC_PRAGMAS
#pragma implementation
#endif
#include "Object.h"
#include "Stream.h"
#include "JArithmeticDecoder.h"
//------------------------------------------------------------------------
// JArithmeticDecoderStates
//------------------------------------------------------------------------
JArithmeticDecoderStats::JArithmeticDecoderStats(int contextSizeA) {
contextSize = contextSizeA;
cxTab = (Guchar *)gmalloc(contextSize * sizeof(Guchar));
reset();
}
JArithmeticDecoderStats::~JArithmeticDecoderStats() {
gfree(cxTab);
}
JArithmeticDecoderStats *JArithmeticDecoderStats::copy() {
JArithmeticDecoderStats *stats;
stats = new JArithmeticDecoderStats(contextSize);
memcpy(stats->cxTab, cxTab, contextSize);
return stats;
}
void JArithmeticDecoderStats::reset() {
memset(cxTab, 0, contextSize);
}
void JArithmeticDecoderStats::copyFrom(JArithmeticDecoderStats *stats) {
memcpy(cxTab, stats->cxTab, contextSize);
}
void JArithmeticDecoderStats::setEntry(Guint cx, int i, int mps) {
cxTab[cx] = (i << 1) + mps;
}
//------------------------------------------------------------------------
// JArithmeticDecoder
//------------------------------------------------------------------------
Guint JArithmeticDecoder::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 JArithmeticDecoder::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 JArithmeticDecoder::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 JArithmeticDecoder::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
};
JArithmeticDecoder::JArithmeticDecoder() {
str = NULL;
}
JArithmeticDecoder::~JArithmeticDecoder() {
while (dataLen > 0) {
readByte();
}
}
inline Guint JArithmeticDecoder::readByte() {
if (dataLen == 0) {
return 0xff;
}
if (dataLen > 0) {
--dataLen;
}
return (Guint)str->getChar() & 0xff;
}
void JArithmeticDecoder::start() {
buf0 = readByte();
buf1 = readByte();
// INITDEC
c = (buf0 ^ 0xff) << 16;
byteIn();
c <<= 7;
ct -= 7;
a = 0x80000000;
}
int JArithmeticDecoder::decodeBit(Guint context,
JArithmeticDecoderStats *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 JArithmeticDecoder::decodeByte(Guint context,
JArithmeticDecoderStats *stats) {
int byte;
int i;
byte = 0;
for (i = 0; i < 8; ++i) {
byte = (byte << 1) | decodeBit(context, stats);
}
return byte;
}
GBool JArithmeticDecoder::decodeInt(int *x, JArithmeticDecoderStats *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 JArithmeticDecoder::decodeIntBit(JArithmeticDecoderStats *stats) {
int bit;
bit = decodeBit(prev, stats);
if (prev < 0x100) {
prev = (prev << 1) | bit;
} else {
prev = (((prev << 1) | bit) & 0x1ff) | 0x100;
}
return bit;
}
Guint JArithmeticDecoder::decodeIAID(Guint codeLen,
JArithmeticDecoderStats *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 JArithmeticDecoder::byteIn() {
if (buf0 == 0xff) {
if (buf1 > 0x8f) {
ct = 8;
} else {
buf0 = buf1;
buf1 = readByte();
c = c + 0xfe00 - (buf0 << 9);
ct = 7;
}
} else {
buf0 = buf1;
buf1 = readByte();
c = c + 0xff00 - (buf0 << 8);
ct = 8;
}
}

91
xpdf/JArithmeticDecoder.h Normal file
View file

@ -0,0 +1,91 @@
//========================================================================
//
// JArithmeticDecoder.h
//
// Arithmetic decoder used by the JBIG2 and JPEG2000 decoders.
//
// Copyright 2002-2004 Glyph & Cog, LLC
//
//========================================================================
#ifndef JARITHMETICDECODER_H
#define JARITHMETICDECODER_H
#include <aconf.h>
#ifdef USE_GCC_PRAGMAS
#pragma interface
#endif
#include "gtypes.h"
class Stream;
//------------------------------------------------------------------------
// JArithmeticDecoderStats
//------------------------------------------------------------------------
class JArithmeticDecoderStats {
public:
JArithmeticDecoderStats(int contextSizeA);
~JArithmeticDecoderStats();
JArithmeticDecoderStats *copy();
void reset();
int getContextSize() { return contextSize; }
void copyFrom(JArithmeticDecoderStats *stats);
void setEntry(Guint cx, int i, int mps);
private:
Guchar *cxTab; // cxTab[cx] = (i[cx] << 1) + mps[cx]
int contextSize;
friend class JArithmeticDecoder;
};
//------------------------------------------------------------------------
// JArithmeticDecoder
//------------------------------------------------------------------------
class JArithmeticDecoder {
public:
JArithmeticDecoder();
~JArithmeticDecoder();
void setStream(Stream *strA)
{ str = strA; dataLen = -1; }
void setStream(Stream *strA, int dataLenA)
{ str = strA; dataLen = dataLenA; }
void start();
int decodeBit(Guint context, JArithmeticDecoderStats *stats);
int decodeByte(Guint context, JArithmeticDecoderStats *stats);
// Returns false for OOB, otherwise sets *<x> and returns true.
GBool decodeInt(int *x, JArithmeticDecoderStats *stats);
Guint decodeIAID(Guint codeLen,
JArithmeticDecoderStats *stats);
private:
Guint readByte();
int decodeIntBit(JArithmeticDecoderStats *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;
int dataLen;
};
#endif

View file

@ -15,6 +15,7 @@
#include <stdlib.h>
#include "GList.h"
#include "Error.h"
#include "JArithmeticDecoder.h"
#include "JBIG2Stream.h"
//~ share these tables
@ -25,327 +26,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;
}
@ -2324,7 +2004,7 @@ JBIG2Bitmap *JBIG2Stream::readTextRegion(GBool huff, GBool refine,
} else {
arithDecoder->decodeInt(&t, iadtStats);
}
t *= -strips;
t *= -(int)strips;
inst = 0;
sFirst = 0;
@ -2497,10 +2177,10 @@ void JBIG2Stream::readPatternDictSeg(Guint segNum, Guint length) {
}
// read the bitmap
atx[0] = -patternW; aty[0] = 0;
atx[1] = -3; aty[1] = -1;
atx[2] = 2; aty[2] = -2;
atx[3] = -2; aty[3] = -2;
atx[0] = -(int)patternW; aty[0] = 0;
atx[1] = -3; aty[1] = -1;
atx[2] = 2; aty[2] = -2;
atx[3] = -2; aty[3] = -2;
bitmap = readGenericBitmap(mmr, (grayMax + 1) * patternW, patternH,
templ, gFalse, gFalse, NULL,
atx, aty, length - 7);
@ -2816,10 +2496,12 @@ JBIG2Bitmap *JBIG2Stream::readGenericBitmap(GBool mmr, int w, int h,
code2 += code3 = mmrDecoder->getBlackCode();
} while (code3 >= 64);
}
a0 = codingLine[codingI++] = a0 + code1;
a0 = codingLine[codingI++] = a0 + code2;
while (refLine[refI] <= a0 && refLine[refI] < w) {
refI += 2;
if (code1 > 0 || code2 > 0) {
a0 = codingLine[codingI++] = a0 + code1;
a0 = codingLine[codingI++] = a0 + code2;
while (refLine[refI] <= a0 && refLine[refI] < w) {
refI += 2;
}
}
break;
case twoDimVert0:
@ -3027,9 +2709,9 @@ JBIG2Bitmap *JBIG2Stream::readGenericBitmap(GBool mmr, int w, int h,
}
// update the context
cx0 = ((cx0 << 1) | bitmap->nextPixel(&cxPtr0)) & 0x07;
cx0 = ((cx0 << 1) | bitmap->nextPixel(&cxPtr0)) & 0x0f;
cx1 = ((cx1 << 1) | bitmap->nextPixel(&cxPtr1)) & 0x1f;
cx2 = ((cx2 << 1) | pix) & 0x0f;
cx2 = ((cx2 << 1) | pix) & 0x07;
}
break;
@ -3049,7 +2731,7 @@ JBIG2Bitmap *JBIG2Stream::readGenericBitmap(GBool mmr, int w, int h,
for (x = 0; x < w; ++x) {
// build the context
cx = (cx0 << 9) | (cx1 << 4) | (cx2 << 1) |
cx = (cx0 << 7) | (cx1 << 3) | (cx2 << 1) |
bitmap->nextPixel(&atPtr0);
// check for a skipped pixel
@ -3062,9 +2744,9 @@ JBIG2Bitmap *JBIG2Stream::readGenericBitmap(GBool mmr, int w, int h,
}
// update the context
cx0 = ((cx0 << 1) | bitmap->nextPixel(&cxPtr0)) & 0x0f;
cx1 = ((cx1 << 1) | bitmap->nextPixel(&cxPtr1)) & 0x1f;
cx2 = ((cx2 << 1) | pix) & 0x07;
cx0 = ((cx0 << 1) | bitmap->nextPixel(&cxPtr0)) & 0x07;
cx1 = ((cx1 << 1) | bitmap->nextPixel(&cxPtr1)) & 0x0f;
cx2 = ((cx2 << 1) | pix) & 0x03;
}
break;
@ -3081,7 +2763,7 @@ JBIG2Bitmap *JBIG2Stream::readGenericBitmap(GBool mmr, int w, int h,
for (x = 0; x < w; ++x) {
// build the context
cx = (cx0 << 9) | (cx1 << 4) | (cx2 << 1) |
cx = (cx1 << 5) | (cx2 << 1) |
bitmap->nextPixel(&atPtr0);
// check for a skipped pixel
@ -3519,14 +3201,14 @@ void JBIG2Stream::discardSegment(Guint segNum) {
for (i = 0; i < segments->getLength(); ++i) {
seg = (JBIG2Segment *)segments->get(i);
if (seg->getSegNum() == segNum) {
globalSegments->del(i);
segments->del(i);
return;
}
}
}
void JBIG2Stream::resetGenericStats(Guint templ,
JBIG2ArithmeticDecoderStats *prevStats) {
JArithmeticDecoderStats *prevStats) {
int size;
size = contextSize[templ];
@ -3542,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];
@ -3565,7 +3246,7 @@ void JBIG2Stream::resetRefinementStats(
refinementRegionStats->reset();
} else {
delete refinementRegionStats;
refinementRegionStats = new JBIG2ArithmeticDecoderStats(size);
refinementRegionStats = new JArithmeticDecoderStats(1 << size);
}
}
}
@ -3588,7 +3269,7 @@ void JBIG2Stream::resetIntStats(int symCodeLen) {
iaidStats->reset();
} else {
delete iaidStats;
iaidStats = new JBIG2ArithmeticDecoderStats(symCodeLen + 1);
iaidStats = new JArithmeticDecoderStats(1 << (symCodeLen + 1));
}
}

View file

@ -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;
};

2822
xpdf/JPXStream.cc Normal file

File diff suppressed because it is too large Load diff

340
xpdf/JPXStream.h Normal file
View file

@ -0,0 +1,340 @@
//========================================================================
//
// JPXStream.h
//
// Copyright 2002-2003 Glyph & Cog, LLC
//
//========================================================================
#ifndef JPXSTREAM_H
#define JPXSTREAM_H
#include <aconf.h>
#ifdef USE_GCC_PRAGMAS
#pragma interface
#endif
#include "gtypes.h"
#include "Object.h"
#include "Stream.h"
class JArithmeticDecoderStats;
//------------------------------------------------------------------------
enum JPXColorSpaceType {
jpxCSBiLevel = 0,
jpxCSYCbCr1 = 1,
jpxCSYCbCr2 = 3,
jpxCSYCBCr3 = 4,
jpxCSPhotoYCC = 9,
jpxCSCMY = 11,
jpxCSCMYK = 12,
jpxCSYCCK = 13,
jpxCSCIELab = 14,
jpxCSsRGB = 16,
jpxCSGrayscale = 17,
jpxCSBiLevel2 = 18,
jpxCSCIEJab = 19,
jpxCSCISesRGB = 20,
jpxCSROMMRGB = 21,
jpxCSsRGBYCbCr = 22,
jpxCSYPbPr1125 = 23,
jpxCSYPbPr1250 = 24
};
struct JPXColorSpec {
Guint meth; // method
int prec; // precedence
union {
struct {
JPXColorSpaceType type; // color space type
union {
struct {
Guint rl, ol, ra, oa, rb, ob, il;
} cieLab;
};
} enumerated;
};
};
//------------------------------------------------------------------------
struct JPXPalette {
Guint nEntries; // number of entries in the palette
Guint nComps; // number of components in each entry
Guint *bpc; // bits per component, for each component
int *c; // color data:
// c[i*nComps+j] = entry i, component j
};
//------------------------------------------------------------------------
struct JPXCompMap {
Guint nChannels; // number of channels
Guint *comp; // codestream components mapped to each channel
Guint *type; // 0 for direct use, 1 for palette mapping
Guint *pComp; // palette components to use
};
//------------------------------------------------------------------------
struct JPXChannelDefn {
Guint nChannels; // number of channels
Guint *idx; // channel indexes
Guint *type; // channel types
Guint *assoc; // channel associations
};
//------------------------------------------------------------------------
struct JPXTagTreeNode {
GBool finished; // true if this node is finished
Guint val; // current value
};
//------------------------------------------------------------------------
struct JPXCoeff {
Gushort flags; // flag bits
Gushort len; // number of significant bits in mag
Guint mag; // magnitude value
};
// coefficient flags
#define jpxCoeffSignificantB 0
#define jpxCoeffTouchedB 1
#define jpxCoeffFirstMagRefB 2
#define jpxCoeffSignB 7
#define jpxCoeffSignificant (1 << jpxCoeffSignificantB)
#define jpxCoeffTouched (1 << jpxCoeffTouchedB)
#define jpxCoeffFirstMagRef (1 << jpxCoeffFirstMagRefB)
#define jpxCoeffSign (1 << jpxCoeffSignB)
//------------------------------------------------------------------------
struct JPXCodeBlock {
//----- size
Guint x0, y0, x1, y1; // bounds
//----- persistent state
GBool seen; // true if this code-block has already
// been seen
Guint lBlock; // base number of bits used for pkt data length
Guint nextPass; // next coding pass
//---- info from first packet
Guint nZeroBitPlanes; // number of zero bit planes
//----- info for the current packet
Guint included; // code-block inclusion in this packet:
// 0=not included, 1=included
Guint nCodingPasses; // number of coding passes in this pkt
Guint dataLen; // pkt data length
//----- coefficient data
JPXCoeff *coeffs; // the coefficients
JArithmeticDecoderStats // arithmetic decoder stats
*stats;
};
//------------------------------------------------------------------------
struct JPXSubband {
//----- computed
Guint x0, y0, x1, y1; // bounds
Guint nXCBs, nYCBs; // number of code-blocks in the x and y
// directions
//----- tag trees
Guint maxTTLevel; // max tag tree level
JPXTagTreeNode *inclusion; // inclusion tag tree for each subband
JPXTagTreeNode *zeroBitPlane; // zero-bit plane tag tree for each
// subband
//----- children
JPXCodeBlock *cbs; // the code-blocks (len = nXCBs * nYCBs)
};
//------------------------------------------------------------------------
struct JPXPrecinct {
//----- computed
Guint x0, y0, x1, y1; // bounds of the precinct
//----- children
JPXSubband *subbands; // the subbands
};
//------------------------------------------------------------------------
struct JPXResLevel {
//----- from the COD and COC segments (main and tile)
Guint precinctWidth; // log2(precinct width)
Guint precinctHeight; // log2(precinct height)
//----- computed
Guint x0, y0, x1, y1; // bounds of the tile-comp (for this res level)
Guint bx0[3], by0[3], // subband bounds
bx1[3], by1[3];
//---- children
JPXPrecinct *precincts; // the precincts
};
//------------------------------------------------------------------------
struct JPXTileComp {
//----- from the SIZ segment
GBool sgned; // 1 for signed, 0 for unsigned
Guint prec; // precision, in bits
Guint hSep; // horizontal separation of samples
Guint vSep; // vertical separation of samples
//----- from the COD and COC segments (main and tile)
Guint style; // coding style parameter (Scod / Scoc)
Guint nDecompLevels; // number of decomposition levels
Guint codeBlockW; // log2(code-block width)
Guint codeBlockH; // log2(code-block height)
Guint codeBlockStyle; // code-block style
Guint transform; // wavelet transformation
//----- from the QCD and QCC segments (main and tile)
Guint quantStyle; // quantization style
Guint *quantSteps; // quantization step size for each subband
Guint nQuantSteps; // number of entries in quantSteps
//----- computed
Guint x0, y0, x1, y1; // bounds of the tile-comp, in ref coords
Guint cbW; // code-block width
Guint cbH; // code-block height
//----- image data
int *data; // the decoded image data
int *buf; // intermediate buffer for the inverse
// transform
//----- children
JPXResLevel *resLevels; // the resolution levels
// (len = nDecompLevels + 1)
};
//------------------------------------------------------------------------
struct JPXTile {
//----- from the COD segments (main and tile)
Guint progOrder; // progression order
Guint nLayers; // number of layers
Guint multiComp; // multiple component transformation
//----- computed
Guint x0, y0, x1, y1; // bounds of the tile, in ref coords
Guint maxNDecompLevels; // max number of decomposition levels used
// in any component in this tile
//----- progression order loop counters
Guint comp; // component
Guint res; // resolution level
Guint precinct; // precinct
Guint layer; // layer
//----- children
JPXTileComp *tileComps; // the tile-components (len = JPXImage.nComps)
};
//------------------------------------------------------------------------
struct JPXImage {
//----- from the SIZ segment
Guint xSize, ySize; // size of reference grid
Guint xOffset, yOffset; // image offset
Guint xTileSize, yTileSize; // size of tiles
Guint xTileOffset, // offset of first tile
yTileOffset;
Guint nComps; // number of components
//----- computed
Guint nXTiles; // number of tiles in x direction
Guint nYTiles; // number of tiles in y direction
//----- children
JPXTile *tiles; // the tiles (len = nXTiles * nYTiles)
};
//------------------------------------------------------------------------
class JPXStream: public FilterStream {
public:
JPXStream(Stream *strA);
virtual ~JPXStream();
virtual StreamKind getKind() { return strJPX; }
virtual void reset();
virtual int getChar();
virtual int lookChar();
virtual GString *getPSFilter(int psLevel, char *indent);
virtual GBool isBinary(GBool last = gTrue);
private:
void fillReadBuf();
GBool readBoxes();
GBool readColorSpecBox(Guint dataLen);
GBool readCodestream(Guint len);
GBool readTilePart();
GBool readTilePartData(Guint tileIdx,
Guint tilePartLen, GBool tilePartToEOC);
GBool readCodeBlockData(JPXTileComp *tileComp,
JPXResLevel *resLevel,
JPXPrecinct *precinct,
JPXSubband *subband,
Guint res, Guint sb,
JPXCodeBlock *cb);
void inverseTransform(JPXTileComp *tileComp);
void inverseTransformLevel(JPXTileComp *tileComp,
Guint r, JPXResLevel *resLevel,
Guint nx0, Guint ny0,
Guint nx1, Guint ny1);
void inverseTransform1D(JPXTileComp *tileComp,
int *data, Guint stride,
Guint i0, Guint i1);
GBool inverseMultiCompAndDC(JPXTile *tile);
GBool readBoxHdr(Guint *boxType, Guint *boxLen, Guint *dataLen);
int readMarkerHdr(int *segType, Guint *segLen);
GBool readUByte(Guint *x);
GBool readByte(int *x);
GBool readUWord(Guint *x);
GBool readULong(Guint *x);
GBool readNBytes(int nBytes, GBool signd, int *x);
GBool readBits(int nBits, Guint *x);
void clearBitBuf();
Guint nComps; // number of components
Guint *bpc; // bits per component, for each component
Guint width, height; // image size
GBool haveImgHdr; // set if a JP2/JPX image header has been
// found
JPXColorSpec cs; // color specification
GBool haveCS; // set if a color spec has been found
JPXPalette palette; // the palette
GBool havePalette; // set if a palette has been found
JPXCompMap compMap; // the component mapping
GBool haveCompMap; // set if a component mapping has been found
JPXChannelDefn channelDefn; // channel definition
GBool haveChannelDefn; // set if a channel defn has been found
JPXImage img; // JPEG2000 decoder data
Guint bitBuf; // buffer for bit reads
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 curX, curY, curComp; // current position for lookChar/getChar
Guint readBuf; // read buffer
Guint readBufLen; // number of valid bits in readBuf
};
#endif

View file

@ -1,72 +0,0 @@
//========================================================================
//
// LTKOutputDev.cc
//
// Copyright 1998-2002 Glyph & Cog, LLC
//
//========================================================================
#ifdef __GNUC__
#pragma implementation
#endif
#include <aconf.h>
#include <stdio.h>
#include <stdlib.h>
#include <stddef.h>
#include <string.h>
#include "gmem.h"
#include "GString.h"
#include "LTKWindow.h"
#include "LTKScrollingCanvas.h"
#include "Object.h"
#include "Stream.h"
#include "GfxState.h"
#include "GfxFont.h"
#include "Error.h"
#include "LTKOutputDev.h"
//------------------------------------------------------------------------
LTKOutputDev::LTKOutputDev(LTKWindow *winA, GBool reverseVideoA,
unsigned long paperColor, GBool installCmap,
GBool rgbCubeSize, GBool incrementalUpdateA):
XOutputDev(winA->getDisplay(),
((LTKScrollingCanvas *)winA->findWidget("canvas"))->getPixmap(),
0, winA->getColormap(), reverseVideoA, paperColor,
installCmap, rgbCubeSize)
{
win = winA;
canvas = (LTKScrollingCanvas *)win->findWidget("canvas");
setPixmap(canvas->getPixmap(),
canvas->getRealWidth(), canvas->getRealHeight());
incrementalUpdate = incrementalUpdateA;
}
LTKOutputDev::~LTKOutputDev() {
}
void LTKOutputDev::startPage(int pageNum, GfxState *state) {
canvas->resize((int)(state->getPageWidth() + 0.5),
(int)(state->getPageHeight() + 0.5));
setPixmap(canvas->getPixmap(),
canvas->getRealWidth(), canvas->getRealHeight());
XOutputDev::startPage(pageNum, state);
if (incrementalUpdate) {
canvas->redraw();
}
}
void LTKOutputDev::endPage() {
if (!incrementalUpdate) {
canvas->redraw();
}
XOutputDev::endPage();
}
void LTKOutputDev::dump() {
if (incrementalUpdate) {
canvas->redraw();
}
XOutputDev::dump();
}

View file

@ -1,52 +0,0 @@
//========================================================================
//
// LTKOutputDev.h
//
// Copyright 1998-2002 Glyph & Cog, LLC
//
//========================================================================
#ifndef LTKOUTPUTDEV_H
#define LTKOUTPUTDEV_H
#ifdef __GNUC__
#pragma interface
#endif
#include <stddef.h>
#include "config.h"
#include "XOutputDev.h"
class LTKApp;
class LTKWindow;
//------------------------------------------------------------------------
class LTKOutputDev: public XOutputDev {
public:
LTKOutputDev(LTKWindow *winA, GBool reverseVideoA,
unsigned long paperColor, GBool installCmap,
GBool rgbCubeSize, GBool incrementalUpdateA);
~LTKOutputDev();
//----- initialization and control
// Start a page.
virtual void startPage(int pageNum, GfxState *state);
// End a page.
virtual void endPage();
// Dump page contents to display.
virtual void dump();
private:
LTKWindow *win; // window
LTKScrollingCanvas *canvas; // drawing canvas
GBool incrementalUpdate; // incrementally update the display?
};
#endif

View file

@ -23,7 +23,7 @@
// A '1' in this array means the character is white space. A '1' or
// '2' means the character ends a name or command.
static char LexerSpecialChars[256] = {
static char specialChars[256] = {
1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 1, 1, 0, 0, // 0x
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 1x
1, 0, 0, 0, 0, 2, 0, 0, 2, 2, 0, 0, 0, 0, 0, 2, // 2x
@ -129,7 +129,7 @@ Object *Lexer::getObj(Object *obj) {
comment = gFalse;
} else if (c == '%') {
comment = gTrue;
} else if (LexerSpecialChars[c] != 1) {
} else if (specialChars[c] != 1) {
break;
}
}
@ -300,7 +300,7 @@ Object *Lexer::getObj(Object *obj) {
case '/':
p = tokBuf;
n = 0;
while ((c = lookChar()) != EOF && !LexerSpecialChars[c]) {
while ((c = lookChar()) != EOF && !specialChars[c]) {
getChar();
if (c == '#') {
c2 = lookChar();
@ -369,7 +369,7 @@ Object *Lexer::getObj(Object *obj) {
} else if (c == EOF) {
error(getPos(), "Unterminated hex string");
break;
} else if (LexerSpecialChars[c] != 1) {
} else if (specialChars[c] != 1) {
c2 = c2 << 4;
if (c >= '0' && c <= '9')
c2 += c - '0';
@ -432,7 +432,7 @@ Object *Lexer::getObj(Object *obj) {
p = tokBuf;
*p++ = c;
n = 1;
while ((c = lookChar()) != EOF && !LexerSpecialChars[c]) {
while ((c = lookChar()) != EOF && !specialChars[c]) {
getChar();
if (++n == tokBufSize) {
error(getPos(), "Command token too long");

View file

@ -580,14 +580,43 @@ LinkUnknown::~LinkUnknown() {
delete action;
}
//------------------------------------------------------------------------
// 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, GString *baseURI) {
Object obj1, obj2;
Object obj1, obj2, obj3;
LinkBorderType borderType;
double borderWidth;
double *borderDash;
int borderDashLength;
double borderR, borderG, borderB;
double t;
int i;
borderStyle = NULL;
action = NULL;
ok = gFalse;
@ -632,19 +661,92 @@ Link::Link(Dict *dict, GString *baseURI) {
y2 = t;
}
// get border
borderW = 1;
if (!dict->lookup("Border", &obj1)->isNull()) {
if (obj1.isArray() && obj1.arrayGetLength() >= 3) {
if (obj1.arrayGet(2, &obj2)->isNum()) {
borderW = obj2.getNum();
} else {
error(-1, "Bad annotation border");
// 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 *)gmalloc(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 *)gmalloc(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();
}
}
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()) {
@ -673,8 +775,12 @@ Link::Link(Dict *dict, GString *baseURI) {
}
Link::~Link() {
if (action)
if (borderStyle) {
delete borderStyle;
}
if (action) {
delete action;
}
}
//------------------------------------------------------------------------

View file

@ -301,6 +301,42 @@ private:
GString *action; // action subtype
};
//------------------------------------------------------------------------
// 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
//------------------------------------------------------------------------
@ -324,16 +360,18 @@ public:
// Get action.
LinkAction *getAction() { return action; }
// Get border corners and width.
void getBorder(double *xa1, double *ya1, double *xa2, double *ya2,
double *wa)
{ *xa1 = x1; *ya1 = y1; *xa2 = x2; *ya2 = y2; *wa = borderW; }
// Get the link rectangle.
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
double borderW; // border width
LinkBorderStyle *borderStyle; // border style
LinkAction *action; // action
GBool ok; // is link valid?
};

View file

@ -1,26 +1,15 @@
INCLUDES = -I.. -I$(top_srcdir)/kpdf/goo $(all_includes) $(LIBFREETYPE_CFLAGS)
INCLUDES = -I.. -I$(srcdir)/../fofi -I$(srcdir)/../goo $(all_includes) $(LIBFREETYPE_CFLAGS)
libxpdf_la_LDFLAGS = $(all_libraries) -no-undefined
libxpdf_la_LIBADD = $(LIB_X11) $(LIBFREETYPE_LIBS) $(LIBPAPER_LIBS) ../goo/libgoo.la
libxpdf_la_LDFLAGS = $(all_libraries)
libxpdf_la_LIBADD = $(LIB_X11) $(LIBFREETYPE_LIBS) $(LIBPAPER_LIBS) ../goo/libgoo.la ../fofi/libfofi.la
libxpdf_la_SOURCES = Annot.cc Array.cc BuiltinFont.cc BuiltinFontTables.cc \
CMap.cc Catalog.cc CharCodeToUnicode.cc Decrypt.cc Dict.cc Error.cc \
FTFont.cc FontEncodingTables.cc FontFile.cc Function.cc Gfx.cc \
GfxFont.cc GfxState.cc GlobalParams.cc ImageOutputDev.cc \
Catalog.cc CharCodeToUnicode.cc CMap.cc Decrypt.cc Dict.cc Error.cc \
FontEncodingTables.cc Function.cc Gfx.cc \
GfxFont.cc GfxState.cc GlobalParams.cc JArithmeticDecoder.cc \
JBIG2Stream.cc Lexer.cc Link.cc NameToCharCode.cc Object.cc Outline.cc \
OutputDev.cc PDFDoc.cc PDFDocEncoding.cc PSOutputDev.cc PSTokenizer.cc \
Page.cc Parser.cc SFont.cc Stream.cc \
TextOutputDev.cc UnicodeMap.cc XOutputDev.cc XRef.cc
Page.cc Parser.cc Stream.cc JPXStream.cc \
TextOutputDev.cc UnicodeMap.cc UnicodeTypeTable.cc XRef.cc
libxpdf_la_COMPILE_FIRST = ../aconf.h
noinst_LTLIBRARIES = libxpdf.la
noinst_HEADERS = Annot.h Array.h BuiltinFont.h BuiltinFontTables.h \
CMap.h Catalog.h CharCodeToUnicode.h CharTypes.h CompactFontTables.h \
Decrypt.h Dict.h DisplayFontTable.h Error.h ErrorCodes.h FTFont.h \
FontEncodingTables.h FontFile.h Function.h Gfx.h GfxFont.h \
GfxState.h GlobalParams.h ImageOutputDev.h JBIG2Stream.h LTKOutputDev.h \
Lexer.h Link.h NameToCharCode.h NameToUnicodeTable.h Object.h Outline.h \
OutputDev.h PBMOutputDev.h PDFDoc.h PDFDocEncoding.cc PSOutputDev.h \
PSTokenizer.h Page.h Parser.h SFont.h Stream-CCITT.h Stream.h \
TextOutputDev.h UTF8.h UnicodeMap.h UnicodeMapTables.h \
XOutputDev.h XRef.h config.h xpdf-ltk.h

View file

@ -1,3 +0,0 @@
- The XOutputDev constructor should have pixmapWA and pixmapHA arguments.
Without them pixmapW and pixmapH won't be initialized, and one is forced to
use setPixmap().

View file

@ -47,7 +47,7 @@ NameToCharCode::~NameToCharCode() {
gfree(tab);
}
void NameToCharCode::add(const char *name, CharCode c) {
void NameToCharCode::add(char *name, CharCode c) {
NameToCharCodeEntry *oldTab;
int h, i, oldSize;
@ -89,7 +89,7 @@ void NameToCharCode::add(const char *name, CharCode c) {
++len;
}
CharCode NameToCharCode::lookup(const char *name) {
CharCode NameToCharCode::lookup(char *name) {
int h;
h = hash(name);
@ -104,8 +104,8 @@ CharCode NameToCharCode::lookup(const char *name) {
return 0;
}
int NameToCharCode::hash(const char *name) {
const char *p;
int NameToCharCode::hash(char *name) {
char *p;
unsigned int h;
h = 0;

View file

@ -27,12 +27,12 @@ public:
NameToCharCode();
~NameToCharCode();
void add(const char *name, CharCode c);
CharCode lookup(const char *name);
void add(char *name, CharCode c);
CharCode lookup(char *name);
private:
int hash(const char *name);
int hash(char *name);
NameToCharCodeEntry *tab;
int size;

View file

@ -8,7 +8,7 @@
static struct {
Unicode u;
const char *name;
char *name;
} nameToUnicodeTab[] = {
{0x0021, "!"},
{0x0023, "#"},

View file

@ -24,7 +24,7 @@
// Object
//------------------------------------------------------------------------
const char *objTypeNames[numObjTypes] = {
char *objTypeNames[numObjTypes] = {
"boolean",
"integer",
"real",
@ -58,6 +58,13 @@ Object *Object::initDict(XRef *xref) {
return this;
}
Object *Object::initDict(Dict *dictA) {
initObj(objDict);
dict = dictA;
dict->incRef();
return this;
}
Object *Object::initStream(Stream *streamA) {
initObj(objStream);
stream = streamA;
@ -134,7 +141,7 @@ void Object::free() {
type = objNone;
}
const char *Object::getTypeName() const {
char *Object::getTypeName() {
return objTypeNames[type];
}
@ -205,7 +212,7 @@ void Object::print(FILE *f) {
}
}
void Object::memCheck(FILE * f) {
void Object::memCheck(FILE *f) {
#ifdef DEBUG_MEM
int i;
int t;

View file

@ -95,6 +95,7 @@ public:
{ initObj(objNull); return this; }
Object *initArray(XRef *xref);
Object *initDict(XRef *xref);
Object *initDict(Dict *dictA);
Object *initStream(Stream *streamA);
Object *initRef(int numA, int genA)
{ initObj(objRef); ref.num = numA; ref.gen = genA; return this; }
@ -116,29 +117,29 @@ public:
void free();
// Type checking.
ObjType getType() const { return type; }
GBool isBool() const { return type == objBool; }
GBool isInt() const { return type == objInt; }
GBool isReal() const { return type == objReal; }
GBool isNum() const { return type == objInt || type == objReal; }
GBool isString() const { return type == objString; }
GBool isName() const { return type == objName; }
GBool isNull() const { return type == objNull; }
GBool isArray() const { return type == objArray; }
GBool isDict() const { return type == objDict; }
GBool isStream() const { return type == objStream; }
GBool isRef() const { return type == objRef; }
GBool isCmd() const { return type == objCmd; }
GBool isError() const { return type == objError; }
GBool isEOF() const { return type == objEOF; }
GBool isNone() const { return type == objNone; }
ObjType getType() { return type; }
GBool isBool() { return type == objBool; }
GBool isInt() { return type == objInt; }
GBool isReal() { return type == objReal; }
GBool isNum() { return type == objInt || type == objReal; }
GBool isString() { return type == objString; }
GBool isName() { return type == objName; }
GBool isNull() { return type == objNull; }
GBool isArray() { return type == objArray; }
GBool isDict() { return type == objDict; }
GBool isStream() { return type == objStream; }
GBool isRef() { return type == objRef; }
GBool isCmd() { return type == objCmd; }
GBool isError() { return type == objError; }
GBool isEOF() { return type == objEOF; }
GBool isNone() { return type == objNone; }
// Special type checking.
GBool isName(const char *nameA) const
GBool isName(char *nameA)
{ return type == objName && !strcmp(name, nameA); }
GBool isDict(const char *dictType);
GBool isStream(const char *dictType);
GBool isCmd(const char *cmdA)
GBool isDict(char *dictType);
GBool isStream(char *dictType);
GBool isCmd(char *cmdA)
{ return type == objCmd && !strcmp(cmd, cmdA); }
// Accessors. NB: these assume object is of correct type.
@ -164,16 +165,16 @@ public:
// Dict accessors.
int dictGetLength();
void dictAdd(const char *key, Object *val);
GBool dictIs(const char *dictType);
Object *dictLookup(const char *key, Object *obj);
Object *dictLookupNF(const char *key, Object *obj);
const char *dictGetKey(int i);
void dictAdd(char *key, Object *val);
GBool dictIs(char *dictType);
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);
// Stream accessors.
GBool streamIs(const char *dictType);
GBool streamIs(char *dictType);
void streamReset();
void streamClose();
int streamGetChar();
@ -184,7 +185,7 @@ public:
Dict *streamGetDict();
// Output.
const char *getTypeName() const;
char *getTypeName();
void print(FILE *f = stdout);
// Memory testing.
@ -239,22 +240,22 @@ inline Object *Object::arrayGetNF(int i, Object *obj)
inline int Object::dictGetLength()
{ return dict->getLength(); }
inline void Object::dictAdd(const char *key, Object *val)
inline void Object::dictAdd(char *key, Object *val)
{ dict->add(key, val); }
inline GBool Object::dictIs(const char *dictType)
inline GBool Object::dictIs(char *dictType)
{ return dict->is(dictType); }
inline GBool Object::isDict(const char *dictType)
inline GBool Object::isDict(char *dictType)
{ return type == objDict && dictIs(dictType); }
inline Object *Object::dictLookup(const char *key, Object *obj)
inline Object *Object::dictLookup(char *key, Object *obj)
{ return dict->lookup(key, obj); }
inline Object *Object::dictLookupNF(const char *key, Object *obj)
inline Object *Object::dictLookupNF(char *key, Object *obj)
{ return dict->lookupNF(key, obj); }
inline const char *Object::dictGetKey(int i)
inline char *Object::dictGetKey(int i)
{ return dict->getKey(i); }
inline Object *Object::dictGetVal(int i, Object *obj)
@ -269,10 +270,10 @@ inline Object *Object::dictGetValNF(int i, Object *obj)
#include "Stream.h"
inline GBool Object::streamIs(const char *dictType)
inline GBool Object::streamIs(char *dictType)
{ return stream->getDict()->is(dictType); }
inline GBool Object::isStream(const char *dictType)
inline GBool Object::isStream(char *dictType)
{ return type == objStream && streamIs(dictType); }
inline void Object::streamReset()

View file

@ -22,15 +22,17 @@
//------------------------------------------------------------------------
Outline::Outline(Object *outlineObj, XRef *xref) {
Object first;
Object first, last;
items = NULL;
if (!outlineObj->isDict()) {
return;
}
items = OutlineItem::readItemList(outlineObj->dictLookupNF("First", &first),
outlineObj->dictLookupNF("Last", &last),
xref);
first.free();
last.free();
}
Outline::~Outline() {
@ -68,6 +70,8 @@ OutlineItem::OutlineItem(Dict *dict, XRef *xrefA) {
title[i] = pdfDocEncoding[s->getChar(i) & 0xff];
}
}
} else {
titleLen = 0;
}
obj1.free();
@ -82,6 +86,7 @@ OutlineItem::OutlineItem(Dict *dict, XRef *xrefA) {
obj1.free();
dict->lookupNF("First", &firstRef);
dict->lookupNF("Last", &lastRef);
dict->lookupNF("Next", &nextRef);
startsOpen = gFalse;
@ -102,17 +107,19 @@ OutlineItem::~OutlineItem() {
delete action;
}
firstRef.free();
lastRef.free();
nextRef.free();
}
GList *OutlineItem::readItemList(Object *itemRef, XRef *xrefA) {
GList *OutlineItem::readItemList(Object *firstItemRef, Object *lastItemRef,
XRef *xrefA) {
GList *items;
OutlineItem *item;
Object obj;
Object *p;
items = new GList();
p = itemRef;
p = firstItemRef;
while (p->isRef()) {
if (!p->fetch(xrefA, &obj)->isDict()) {
obj.free();
@ -121,6 +128,10 @@ GList *OutlineItem::readItemList(Object *itemRef, XRef *xrefA) {
item = new OutlineItem(obj.getDict(), xrefA);
obj.free();
items->append(item);
if (p->getRef().num == lastItemRef->getRef().num &&
p->getRef().gen == lastItemRef->getRef().gen) {
break;
}
p = &item->nextRef;
}
return items;
@ -128,7 +139,7 @@ GList *OutlineItem::readItemList(Object *itemRef, XRef *xrefA) {
void OutlineItem::open() {
if (!kids) {
kids = readItemList(&firstRef, xref);
kids = readItemList(&firstRef, &lastRef, xref);
}
}

View file

@ -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]

View file

@ -60,7 +60,8 @@ void OutputDev::updateAll(GfxState *state) {
updateFont(state);
}
GBool OutputDev::beginType3Char(GfxState *state,
GBool OutputDev::beginType3Char(GfxState *state, double x, double y,
double dx, double dy,
CharCode code, Unicode *u, int uLen) {
return gFalse;
}

View file

@ -125,9 +125,11 @@ public:
double originX, double originY,
CharCode code, Unicode *u, int uLen) {}
virtual void drawString(GfxState *state, GString *s) {}
virtual GBool beginType3Char(GfxState *state,
virtual GBool beginType3Char(GfxState *state, double x, double y,
double dx, double dy,
CharCode code, Unicode *u, int uLen);
virtual void endType3Char(GfxState *state) {}
virtual void endTextObject(GfxState *state) {}
//----- image drawing
virtual void drawImageMask(GfxState *state, Object *ref, Stream *str,
@ -137,6 +139,12 @@ public:
int width, int height, GfxImageColorMap *colorMap,
int *maskColors, GBool inlineImg);
#if OPI_SUPPORT
//----- OPI functions
virtual void opiBegin(GfxState *state, Dict *opiDict);
virtual void opiEnd(GfxState *state, Dict *opiDict);
#endif
//----- Type 3 font operators
virtual void type3D0(GfxState *state, double wx, double wy) {}
virtual void type3D1(GfxState *state, double wx, double wy,

View file

@ -1,162 +0,0 @@
//========================================================================
//
// PBMOutputDev.cc
//
// Copyright 1998-2003 Glyph & Cog, LLC
//
//========================================================================
#include <aconf.h>
#ifdef USE_GCC_PRAGMAS
#pragma implementation
#endif
#include <stdio.h>
#include <stdlib.h>
#include <stddef.h>
#include <string.h>
#include "gmem.h"
#include "GString.h"
#include "Object.h"
#include "Stream.h"
#include "GfxState.h"
#include "GfxFont.h"
#include "Error.h"
#include "PBMOutputDev.h"
//------------------------------------------------------------------------
PBMOutputDev *PBMOutputDev::makePBMOutputDev(char *displayName,
char *fileRootA) {
Display *displayA;
Pixmap pixmapA;
Window dummyWinA;
int screenA;
int invertA;
unsigned long black, white;
PBMOutputDev *out;
if (!(displayA = XOpenDisplay(displayName))) {
fprintf(stderr, "Couldn't open display '%s'\n", displayName);
exit(1);
}
screenA = DefaultScreen(displayA);
black = BlackPixel(displayA, screenA);
white = WhitePixel(displayA, screenA);
if ((black & 1) == (white & 1)) {
fprintf(stderr, "Weird black/white pixel colors\n");
XCloseDisplay(displayA);
return NULL;
}
invertA = (white & 1) == 1 ? 0xff : 0x00;
dummyWinA = XCreateSimpleWindow(displayA, RootWindow(displayA, screenA),
0, 0, 1, 1, 0,
black, white);
pixmapA = XCreatePixmap(displayA, dummyWinA, 1, 1, 1);
out = new PBMOutputDev(displayA, screenA, pixmapA, dummyWinA,
invertA, fileRootA);
return out;
}
void PBMOutputDev::killPBMOutputDev(PBMOutputDev *out) {
Display *displayA;
Pixmap pixmapA;
Window dummyWinA;
displayA = out->display;
pixmapA = out->pixmap;
dummyWinA = out->dummyWin;
delete out;
// these have to be done *after* the XOutputDev (parent of the
// PBMOutputDev) is deleted, since XOutputDev::~XOutputDev() needs
// them
XFreePixmap(displayA, pixmapA);
XDestroyWindow(displayA, dummyWinA);
XCloseDisplay(displayA);
}
PBMOutputDev::PBMOutputDev(Display *displayA, int screenA,
Pixmap pixmapA, Window dummyWinA,
int invertA, char *fileRootA):
XOutputDev(displayA, screenA,
DefaultVisual(displayA, screenA),
DefaultColormap(displayA, screenA),
gFalse,
WhitePixel(displayA, DefaultScreen(displayA)),
gFalse, 1, 1)
{
display = displayA;
screen = screenA;
pixmap = pixmapA;
dummyWin = dummyWinA;
invert = invertA;
fileRoot = fileRootA;
fileName = (char *)gmalloc(strlen(fileRoot) + 20);
}
PBMOutputDev::~PBMOutputDev() {
gfree(fileName);
}
void PBMOutputDev::startPage(int pageNum, GfxState *state) {
curPage = pageNum;
width = (int)(state->getPageWidth() + 0.5);
height = (int)(state->getPageHeight() + 0.5);
XFreePixmap(display, pixmap);
pixmap = XCreatePixmap(display, dummyWin, width, height, 1);
setPixmap(pixmap, width, height);
XOutputDev::startPage(pageNum, state);
}
void PBMOutputDev::endPage() {
XImage *image;
FILE *f;
int p;
int x, y, i;
image = XCreateImage(display, DefaultVisual(display, screen),
1, ZPixmap, 0, NULL, width, height, 8, 0);
image->data = (char *)gmalloc(height * image->bytes_per_line);
XGetSubImage(display, pixmap, 0, 0, width, height, 1, ZPixmap,
image, 0, 0);
sprintf(fileName, "%s-%06d.pbm", fileRoot, curPage);
if (!(f = fopen(fileName, "wb"))) {
fprintf(stderr, "Couldn't open output file '%s'\n", fileName);
goto err;
}
fprintf(f, "P4\n");
fprintf(f, "%d %d\n", width, height);
for (y = 0; y < height; ++y) {
for (x = 0; x+8 <= width; x += 8) {
p = 0;
for (i = 0; i < 8; ++i)
p = (p << 1) + (XGetPixel(image, x+i, y) & 1);
p ^= invert;
fputc((char)p, f);
}
if (width & 7) {
p = 0;
for (i = 0; i < (width & 7); ++i)
p = (p << 1) + (XGetPixel(image, x+i, y) & 1);
p <<= 8 - (width & 7);
p ^= invert;
fputc((char)p, f);
}
}
fclose(f);
err:
gfree(image->data);
image->data = NULL;
XDestroyImage(image);
XOutputDev::endPage();
}

View file

@ -1,64 +0,0 @@
//========================================================================
//
// PBMOutputDev.h
//
// Copyright 1998-2003 Glyph & Cog, LLC
//
//========================================================================
#ifndef PBMOUTPUTDEV_H
#define PBMOUTPUTDEV_H
#include <aconf.h>
#ifdef USE_GCC_PRAGMAS
#pragma interface
#endif
#include <stddef.h>
#include "config.h"
#include "XOutputDev.h"
//------------------------------------------------------------------------
class PBMOutputDev: public XOutputDev {
public:
// NB: Users must use makePBMOutputDev and killPBMOutputDev rather
// than the constructor and destructor. (This is due to some
// constraints in the underlying XOutputDev object.)
static PBMOutputDev *makePBMOutputDev(char *displayName,
char *fileRootA);
static void killPBMOutputDev(PBMOutputDev *out);
virtual ~PBMOutputDev();
//----- initialization and control
// Start a page.
virtual void startPage(int pageNum, GfxState *state);
// End a page.
virtual void endPage();
private:
PBMOutputDev(Display *displayA, int screenA,
Pixmap pixmapA, Window dummyWinA,
int invertA, char *fileRootA);
char *fileRoot;
char *fileName;
int curPage;
Display *display;
int screen;
Pixmap pixmap;
Window dummyWin;
int width, height;
int invert;
};
#endif

View file

@ -113,6 +113,8 @@ PDFDoc::PDFDoc(BaseStream *strA, GString *ownerPassword,
}
GBool PDFDoc::setup(GString *ownerPassword, GString *userPassword) {
str->reset();
// check header
checkHeader();
@ -198,8 +200,8 @@ void PDFDoc::checkHeader() {
}
}
void PDFDoc::displayPage(OutputDev *out, int page, double zoom,
int rotate, GBool doLinks,
void PDFDoc::displayPage(OutputDev *out, int page, double hDPI, double vDPI,
int rotate, GBool crop, GBool doLinks,
GBool (*abortCheckCbk)(void *data),
void *abortCheckCbkData) {
Page *p;
@ -213,35 +215,38 @@ void PDFDoc::displayPage(OutputDev *out, int page, double zoom,
delete links;
}
getLinks(p);
p->display(out, zoom, rotate, links, catalog,
p->display(out, hDPI, vDPI, rotate, crop, links, catalog,
abortCheckCbk, abortCheckCbkData);
} else {
p->display(out, zoom, rotate, NULL, catalog,
p->display(out, hDPI, vDPI, rotate, crop, NULL, catalog,
abortCheckCbk, abortCheckCbkData);
}
}
void PDFDoc::displayPages(OutputDev *out, int firstPage, int lastPage,
int zoom, int rotate, GBool doLinks,
double hDPI, double vDPI, int rotate,
GBool crop, GBool doLinks,
GBool (*abortCheckCbk)(void *data),
void *abortCheckCbkData) {
int page;
for (page = firstPage; page <= lastPage; ++page) {
displayPage(out, page, zoom, rotate, doLinks,
displayPage(out, page, hDPI, vDPI, rotate, crop, doLinks,
abortCheckCbk, abortCheckCbkData);
}
}
void PDFDoc::displayPageSlice(OutputDev *out, int page, double zoom,
int rotate, int sliceX, int sliceY,
int sliceW, int sliceH,
void PDFDoc::displayPageSlice(OutputDev *out, int page,
double hDPI, double vDPI,
int rotate, GBool crop,
int sliceX, int sliceY, int sliceW, int sliceH,
GBool (*abortCheckCbk)(void *data),
void *abortCheckCbkData) {
Page *p;
p = catalog->getPage(page);
p->displaySlice(out, zoom, rotate, sliceX, sliceY, sliceW, sliceH,
p->displaySlice(out, hDPI, vDPI, rotate, crop,
sliceX, sliceY, sliceW, sliceH,
NULL, catalog, abortCheckCbk, abortCheckCbkData);
}

View file

@ -79,21 +79,23 @@ public:
Object *getStructTreeRoot() { return catalog->getStructTreeRoot(); }
// Display a page.
void displayPage(OutputDev *out, int page, double zoom,
int rotate, GBool doLinks,
void displayPage(OutputDev *out, int page, double hDPI, double vDPI,
int rotate, GBool crop, GBool doLinks,
GBool (*abortCheckCbk)(void *data) = NULL,
void *abortCheckCbkData = NULL);
// Display a range of pages.
void displayPages(OutputDev *out, int firstPage, int lastPage,
int zoom, int rotate, GBool doLinks,
double hDPI, double vDPI, int rotate,
GBool crop, GBool doLinks,
GBool (*abortCheckCbk)(void *data) = NULL,
void *abortCheckCbkData = NULL);
// Display part of a page.
void displayPageSlice(OutputDev *out, int page, double zoom,
int rotate, int sliceX, int sliceY,
int sliceW, int sliceH,
void displayPageSlice(OutputDev *out, int page,
double hDPI, double vDPI,
int rotate, GBool crop,
int sliceX, int sliceY, int sliceW, int sliceH,
GBool (*abortCheckCbk)(void *data) = NULL,
void *abortCheckCbkData = NULL);
@ -103,7 +105,8 @@ public:
// If point <x>,<y> is in a link, return the associated action;
// else return NULL.
LinkAction *findLink(double x, double y) { return links->find(x, y); }
LinkAction *findLink(double x, double y)
{ return links ? links->find(x, y) : (LinkAction *)NULL; }
// Return true if <x>,<y> is in a link.
GBool onLink(double x, double y) { return links->onLink(x, y); }

File diff suppressed because it is too large Load diff

View file

@ -25,6 +25,7 @@ class GfxPath;
class GfxFont;
class GfxColorSpace;
class GfxSeparationColorSpace;
class PDFRectangle;
struct PSFont16Enc;
class PSOutCustomColor;
@ -45,19 +46,25 @@ enum PSFileType {
psGeneric // write to a generic stream
};
typedef void (*PSOutputFunc)(void *stream, const char *data, int len);
typedef void (*PSOutputFunc)(void *stream, char *data, int len);
class PSOutputDev: public OutputDev {
public:
// Open a PostScript output file, and write the prolog.
PSOutputDev(char *fileName, XRef *xrefA, Catalog *catalog,
int firstPage, int lastPage, PSOutMode modeA);
int firstPage, int lastPage, PSOutMode modeA,
int imgLLXA = 0, int imgLLYA = 0,
int imgURXA = 0, int imgURYA = 0,
GBool manualCtrlA = gFalse);
// Open a PSOutputDev that will write to a generic stream.
PSOutputDev(PSOutputFunc outputFuncA, void *outputStreamA,
XRef *xrefA, Catalog *catalog,
int firstPage, int lastPage, PSOutMode modeA);
int firstPage, int lastPage, PSOutMode modeA,
int imgLLXA = 0, int imgLLYA = 0,
int imgURXA = 0, int imgURYA = 0,
GBool manualCtrlA = gFalse);
// Destructor -- writes the trailer and closes the file.
virtual ~PSOutputDev();
@ -78,6 +85,27 @@ public:
// text in Type 3 fonts will be drawn with drawChar/drawString.
virtual GBool interpretType3Chars() { return gFalse; }
//----- header/trailer (used only if manualCtrl is true)
// Write the document-level header.
void writeHeader(int firstPage, int lastPage,
PDFRectangle *mediaBox, PDFRectangle *cropBox);
// Write the Xpdf procset.
void writeXpdfProcset();
// Write the document-level setup.
void writeDocSetup(Catalog *catalog, int firstPage, int lastPage);
// Write the setup for the current page.
void writePageSetup();
// Write the trailer for the current page.
void writePageTrailer();
// Write the document trailer.
void writeTrailer();
//----- initialization and control
// Start a page.
@ -124,6 +152,7 @@ public:
//----- text drawing
virtual void drawString(GfxState *state, GString *s);
virtual void endTextObject(GfxState *state);
//----- image drawing
virtual void drawImageMask(GfxState *state, Object *ref, Stream *str,
@ -133,7 +162,7 @@ public:
int width, int height, GfxImageColorMap *colorMap,
int *maskColors, GBool inlineImg);
#ifdef OPI_SUPPORT
#if OPI_SUPPORT
//----- OPI functions
virtual void opiBegin(GfxState *state, Dict *opiDict);
virtual void opiEnd(GfxState *state, Dict *opiDict);
@ -147,29 +176,46 @@ public:
//----- PostScript XObjects
virtual void psXObject(Stream *psStream, Stream *level1Stream);
//----- miscellaneous
void setOffset(double x, double y)
{ tx0 = x; ty0 = y; }
void setScale(double x, double y)
{ xScale0 = x; yScale0 = y; }
void setRotate(int rotateA)
{ rotate0 = rotateA; }
void setClip(double llx, double lly, double urx, double ury)
{ clipLLX0 = llx; clipLLY0 = lly; clipURX0 = urx; clipURY0 = ury; }
void setUnderlayCbk(void (*cbk)(PSOutputDev *psOut, void *data),
void *data)
{ underlayCbk = cbk; underlayCbkData = data; }
void setOverlayCbk(void (*cbk)(PSOutputDev *psOut, void *data),
void *data)
{ overlayCbk = cbk; overlayCbkData = data; }
private:
void init(PSOutputFunc outputFuncA, void *outputStreamA,
PSFileType fileTypeA, XRef *xrefA, Catalog *catalog,
int firstPage, int lastPage, PSOutMode modeA);
int firstPage, int lastPage, PSOutMode modeA,
int imgLLXA, int imgLLYA, int imgURXA, int imgURYA,
GBool manualCtrlA);
void setupResources(Dict *resDict);
void setupFonts(Dict *resDict);
void setupFont(GfxFont *font, Dict *parentResDict);
void setupEmbeddedType1Font(Ref *id, const char *psName);
void setupExternalType1Font(GString *fileName, const char *psName);
void setupEmbeddedType1CFont(GfxFont *font, Ref *id, const char *psName);
void setupEmbeddedTrueTypeFont(GfxFont *font, Ref *id, const char *psName);
void setupExternalTrueTypeFont(GfxFont *font, const char *psName);
void setupEmbeddedCIDType0Font(GfxFont *font, Ref *id, const char *psName);
void setupEmbeddedCIDTrueTypeFont(GfxFont *font, Ref *id, const char *psName);
void setupType3Font(GfxFont *font, const char *psName, Dict *parentResDict);
void setupEmbeddedType1Font(Ref *id, GString *psName);
void setupExternalType1Font(GString *fileName, GString *psName);
void setupEmbeddedType1CFont(GfxFont *font, Ref *id, GString *psName);
void setupEmbeddedTrueTypeFont(GfxFont *font, Ref *id, GString *psName);
void setupExternalTrueTypeFont(GfxFont *font, GString *psName);
void setupEmbeddedCIDType0Font(GfxFont *font, Ref *id, GString *psName);
void setupEmbeddedCIDTrueTypeFont(GfxFont *font, Ref *id, GString *psName);
void setupType3Font(GfxFont *font, GString *psName, Dict *parentResDict);
void setupImages(Dict *resDict);
void setupImage(Ref id, Stream *str);
void addProcessColor(double c, double m, double y, double k);
void addCustomColor(GfxSeparationColorSpace *sepCS);
void doPath(GfxPath *path);
void doImageL1(GfxImageColorMap *colorMap,
void doImageL1(Object *ref, GfxImageColorMap *colorMap,
GBool invert, GBool inlineImg,
Stream *str, int width, int height, int len);
void doImageL1Sep(GfxImageColorMap *colorMap,
@ -179,7 +225,7 @@ private:
GBool invert, GBool inlineImg,
Stream *str, int width, int height, int len);
void dumpColorSpaceL2(GfxColorSpace *colorSpace);
#ifdef OPI_SUPPORT
#if OPI_SUPPORT
void opiBegin20(GfxState *state, Dict *dict);
void opiBegin13(GfxState *state, Dict *dict);
void opiTransform(GfxState *state, double x0, double y0,
@ -190,18 +236,25 @@ private:
void writePS(char *s);
void writePSFmt(const char *fmt, ...);
void writePSString(GString *s);
void writePSName(const char *s);
void writePSName(char *s);
GString *filterPSName(GString *name);
PSLevel level; // PostScript level (1, 2, separation)
PSOutMode mode; // PostScript mode (PS, EPS, form)
int paperWidth; // width of paper, in pts
int paperHeight; // height of paper, in pts
int imgLLX, imgLLY, // imageable area, in pts
imgURX, imgURY;
PSOutputFunc outputFunc;
void *outputStream;
PSFileType fileType; // file / pipe / stdout
GBool manualCtrl;
int seqPage; // current sequential page number
void (*underlayCbk)(PSOutputDev *psOut, void *data);
void *underlayCbkData;
void (*overlayCbk)(PSOutputDev *psOut, void *data);
void *overlayCbkData;
XRef *xref; // the xref table for this PDF file
@ -214,15 +267,23 @@ private:
GString **fontFileNames; // list of names of all embedded external fonts
int fontFileNameLen; // number of entries in fontFileNames array
int fontFileNameSize; // size of fontFileNames array
int nextTrueTypeNum; // next unique number to append to a TrueType
// font name
PSFont16Enc *font16Enc; // encodings for substitute 16-bit fonts
int font16EncLen; // number of entries in font16Enc array
int font16EncSize; // size of font16Enc array
GList *xobjStack; // stack of XObject dicts currently being
// processed
int numSaves; // current number of gsaves
double tx, ty; // global translation
double xScale, yScale; // global scaling
GBool landscape; // true for landscape, false for portrait
double tx0, ty0; // global translation
double xScale0, yScale0; // global scaling
int rotate0; // rotation angle (0, 90, 180, 270)
double clipLLX0, clipLLY0,
clipURX0, clipURY0;
double tx, ty; // global translation for current page
double xScale, yScale; // global scaling for current page
int rotate; // rotation angle for current page
GString *embFontList; // resource comments for embedded fonts
@ -230,19 +291,24 @@ private:
PSOutCustomColor // used custom colors
*customColors;
GBool haveTextClip; // set if text has been drawn with a
// clipping render mode
GBool inType3Char; // inside a Type 3 CharProc
GString *t3String; // Type 3 content string
double t3WX, t3WY, // Type 3 character parameters
t3LLX, t3LLY, t3URX, t3URY;
GBool t3Cacheable; // cleared if char is not cacheable
#ifdef OPI_SUPPORT
#if OPI_SUPPORT
int opi13Nest; // nesting level of OPI 1.3 objects
int opi20Nest; // nesting level of OPI 2.0 objects
#endif
GBool ok; // set up ok?
friend class WinPDFPrinter;
};
#endif

View file

@ -59,8 +59,12 @@ PageAttrs::PageAttrs(PageAttrs *attrs, Dict *dict) {
readBox(dict, "MediaBox", &mediaBox);
// crop box
cropBox = mediaBox;
haveCropBox = readBox(dict, "CropBox", &cropBox);
if (readBox(dict, "CropBox", &cropBox)) {
haveCropBox = gTrue;
}
if (!haveCropBox) {
cropBox = mediaBox;
}
// if the MediaBox is excessively larger than the CropBox,
// just use the CropBox
@ -214,15 +218,17 @@ Page::~Page() {
contents.free();
}
void Page::display(OutputDev *out, double dpi, int rotate,
void Page::display(OutputDev *out, double hDPI, double vDPI,
int rotate, GBool crop,
Links *links, Catalog *catalog,
GBool (*abortCheckCbk)(void *data),
void *abortCheckCbkData) {
displaySlice(out, dpi, rotate, -1, -1, -1, -1, links, catalog,
displaySlice(out, hDPI, vDPI, rotate, crop, -1, -1, -1, -1, links, catalog,
abortCheckCbk, abortCheckCbkData);
}
void Page::displaySlice(OutputDev *out, double dpi, int rotate,
void Page::displaySlice(OutputDev *out, double hDPI, double vDPI,
int rotate, GBool crop,
int sliceX, int sliceY, int sliceW, int sliceH,
Links *links, Catalog *catalog,
GBool (*abortCheckCbk)(void *data),
@ -234,7 +240,7 @@ void Page::displaySlice(OutputDev *out, double dpi, int rotate,
Object obj;
Link *link;
Annots *annotList;
double k;
double kx, ky;
int i;
rotate += getRotate();
@ -246,46 +252,47 @@ void Page::displaySlice(OutputDev *out, double dpi, int rotate,
mediaBox = getBox();
if (sliceW >= 0 && sliceH >= 0) {
k = 72.0 / dpi;
kx = 72.0 / hDPI;
ky = 72.0 / vDPI;
if (rotate == 90) {
if (out->upsideDown()) {
box.x1 = mediaBox->x1 + k * sliceY;
box.x2 = mediaBox->x1 + k * (sliceY + sliceH);
box.x1 = mediaBox->x1 + ky * sliceY;
box.x2 = mediaBox->x1 + ky * (sliceY + sliceH);
} else {
box.x1 = mediaBox->x2 - k * (sliceY + sliceH);
box.x2 = mediaBox->x2 - k * sliceY;
box.x1 = mediaBox->x2 - ky * (sliceY + sliceH);
box.x2 = mediaBox->x2 - ky * sliceY;
}
box.y1 = mediaBox->y1 + k * sliceX;
box.y2 = mediaBox->y1 + k * (sliceX + sliceW);
box.y1 = mediaBox->y1 + kx * sliceX;
box.y2 = mediaBox->y1 + kx * (sliceX + sliceW);
} else if (rotate == 180) {
box.x1 = mediaBox->x2 - k * (sliceX + sliceW);
box.x2 = mediaBox->x2 - k * sliceX;
box.x1 = mediaBox->x2 - kx * (sliceX + sliceW);
box.x2 = mediaBox->x2 - kx * sliceX;
if (out->upsideDown()) {
box.y1 = mediaBox->y1 + k * sliceY;
box.y2 = mediaBox->y1 + k * (sliceY + sliceH);
box.y1 = mediaBox->y1 + ky * sliceY;
box.y2 = mediaBox->y1 + ky * (sliceY + sliceH);
} else {
box.y1 = mediaBox->y2 - k * (sliceY + sliceH);
box.y2 = mediaBox->y2 - k * sliceY;
box.y1 = mediaBox->y2 - ky * (sliceY + sliceH);
box.y2 = mediaBox->y2 - ky * sliceY;
}
} else if (rotate == 270) {
if (out->upsideDown()) {
box.x1 = mediaBox->x2 - k * (sliceY + sliceH);
box.x2 = mediaBox->x2 - k * sliceY;
box.x1 = mediaBox->x2 - ky * (sliceY + sliceH);
box.x2 = mediaBox->x2 - ky * sliceY;
} else {
box.x1 = mediaBox->x1 + k * sliceY;
box.x2 = mediaBox->x1 + k * (sliceY + sliceH);
box.x1 = mediaBox->x1 + ky * sliceY;
box.x2 = mediaBox->x1 + ky * (sliceY + sliceH);
}
box.y1 = mediaBox->y2 - k * (sliceX + sliceW);
box.y2 = mediaBox->y2 - k * sliceX;
box.y1 = mediaBox->y2 - kx * (sliceX + sliceW);
box.y2 = mediaBox->y2 - kx * sliceX;
} else {
box.x1 = mediaBox->x1 + k * sliceX;
box.x2 = mediaBox->x1 + k * (sliceX + sliceW);
box.x1 = mediaBox->x1 + kx * sliceX;
box.x2 = mediaBox->x1 + kx * (sliceX + sliceW);
if (out->upsideDown()) {
box.y1 = mediaBox->y2 - k * (sliceY + sliceH);
box.y2 = mediaBox->y2 - k * sliceY;
box.y1 = mediaBox->y2 - ky * (sliceY + sliceH);
box.y2 = mediaBox->y2 - ky * sliceY;
} else {
box.y1 = mediaBox->y1 + k * sliceY;
box.y2 = mediaBox->y1 + k * (sliceY + sliceH);
box.y1 = mediaBox->y1 + ky * sliceY;
box.y2 = mediaBox->y1 + ky * (sliceY + sliceH);
}
}
} else {
@ -304,25 +311,28 @@ void Page::displaySlice(OutputDev *out, double dpi, int rotate,
}
gfx = new Gfx(xref, out, num, attrs->getResourceDict(),
dpi, &box, isCropped(), cropBox, rotate,
hDPI, vDPI, &box, crop && isCropped(), cropBox, rotate,
abortCheckCbk, abortCheckCbkData);
contents.fetch(xref, &obj);
if (!obj.isNull()) {
gfx->saveState();
gfx->display(&obj);
gfx->restoreState();
}
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
//~ need to reset CTM ???
annotList = new Annots(xref, annots.fetch(xref, &obj));
obj.free();
if (annotList->getNumAnnots() > 0) {

View file

@ -141,13 +141,15 @@ public:
Object *getContents(Object *obj) { return contents.fetch(xref, obj); }
// Display a page.
void display(OutputDev *out, double dpi, int rotate,
void display(OutputDev *out, double hDPI, double vDPI,
int rotate, GBool crop,
Links *links, Catalog *catalog,
GBool (*abortCheckCbk)(void *data) = NULL,
void *abortCheckCbkData = NULL);
// Display part of a page.
void displaySlice(OutputDev *out, double dpi, int rotate,
void displaySlice(OutputDev *out, double hDPI, double vDPI,
int rotate, GBool crop,
int sliceX, int sliceY, int sliceW, int sliceH,
Links *links, Catalog *catalog,
GBool (*abortCheckCbk)(void *data) = NULL,

View file

@ -176,10 +176,16 @@ Stream *Parser::makeStream(Object *dict) {
}
// check for length in damaged file
if (xref->getStreamEnd(pos, &endPos)) {
if (xref && xref->getStreamEnd(pos, &endPos)) {
length = endPos - pos;
}
// in badly damaged PDF files, we can run off the end of the input
// stream immediately after the "stream" token
if (!lexer->getStream()) {
return NULL;
}
// make base stream
str = lexer->getStream()->getBaseStream()->makeSubStream(pos, gTrue,
length, dict);
@ -193,10 +199,12 @@ Stream *Parser::makeStream(Object *dict) {
// refill token buffers and check for 'endstream'
shift(); // kill '>>'
shift(); // kill 'stream'
if (buf1.isCmd("endstream"))
if (buf1.isCmd("endstream")) {
shift();
else
} else {
error(getPos(), "Missing 'endstream'");
str->ignoreLength();
}
return str;
}

View file

@ -1,81 +0,0 @@
//========================================================================
//
// SFont.cc
//
// Copyright 2001-2003 Glyph & Cog, LLC
//
//========================================================================
#include <aconf.h>
#ifdef USE_GCC_PRAGMAS
#pragma implementation
#endif
#include "SFont.h"
//------------------------------------------------------------------------
SFontEngine::SFontEngine(Display *displayA, Visual *visualA, int depthA,
Colormap colormapA) {
display = displayA;
visual = visualA;
depth = depthA;
colormap = colormapA;
}
SFontEngine::~SFontEngine() {
}
void SFontEngine::useTrueColor(int rMaxA, int rShiftA, int gMaxA, int gShiftA,
int bMaxA, int bShiftA) {
trueColor = gTrue;
rMax = rMaxA;
rShift = rShiftA;
gMax = gMaxA;
gShift = gShiftA;
bMax = bMaxA;
bShift = bShiftA;
}
void SFontEngine::useColorCube(Gulong *colorsA, int nRGBA) {
trueColor = gFalse;
colors = colorsA;
nRGB = nRGBA;
rMax = gMax = bMax = nRGB - 1;
}
Gulong SFontEngine::findColor(int r, int g, int b) {
int r1, g1, b1;
Gulong pix;
r1 = ((r & 0xffff) * rMax) / 0xffff;
g1 = ((g & 0xffff) * gMax) / 0xffff;
b1 = ((b & 0xffff) * bMax) / 0xffff;
if (trueColor) {
pix = (r1 << rShift) + (g1 << gShift) + (b1 << bShift);
} else {
pix = colors[(r1 * nRGB + g1) * nRGB + b1];
}
return pix;
}
//------------------------------------------------------------------------
SFontFile::SFontFile() {
}
SFontFile::~SFontFile() {
}
//------------------------------------------------------------------------
SFont::SFont() {
}
SFont::~SFont() {
}
GBool SFont::getCharPath(CharCode c, Unicode u, GfxState *state) {
return gFalse;
}

View file

@ -1,142 +0,0 @@
//========================================================================
//
// SFont.h
//
// Base class for font rasterizers.
//
// Copyright 2001-2003 Glyph & Cog, LLC
//
//========================================================================
#ifndef SFONT_H
#define SFONT_H
#include <aconf.h>
#ifdef USE_GCC_PRAGMAS
#pragma interface
#endif
#include <X11/Xlib.h>
#include <X11/Xutil.h>
#include "gtypes.h"
#include "CharTypes.h"
class GfxState;
//------------------------------------------------------------------------
class SFontEngine {
public:
SFontEngine(Display *displayA, Visual *visualA, int depthA,
Colormap colormapA);
virtual ~SFontEngine();
// Use a TrueColor visual. Pixel values are computed as:
//
// (r << rShift) + (g << gShift) + (b << bShift)
//
// where r, g, and b are scaled to the ranges [0,rMax], [0,gMax],
// and [0,bMax], respectively.
virtual void useTrueColor(int rMaxA, int rShiftA, int gMaxA, int gShiftA,
int bMaxA, int bShiftA);
// Use an RGB color cube. <colors> is an array containing
// <nRGB>*<nRGB>*<nRGB> pixel values in red,green,blue order, e.g.,
// for <nRGB>=2, there will be 8 entries:
//
// |--- colors[i] ---|
// i red green blue
// - ----- ----- -----
// 0 0000 0000 0000
// 1 0000 0000 ffff
// 2 0000 ffff 0000
// 3 0000 ffff ffff
// 4 ffff 0000 0000
// 5 ffff 0000 ffff
// 6 ffff ffff 0000
// 7 ffff ffff ffff
//
// The <colors> array is not copied and must remain valid for the
// lifetime of this SFont object.
virtual void useColorCube(Gulong *colorsA, int nRGBA);
protected:
// Find the closest match to (<r>,<g>,<b>).
Gulong findColor(int r, int g, int b);
//----- X parameters
Display *display;
Visual *visual;
int depth;
Colormap colormap;
GBool trueColor; // true for TrueColor, false for RGB cube
//----- TrueColor parameters
int rMax, gMax, bMax;
int rShift, gShift, bShift;
//----- RGB color cube parameters
Gulong *colors;
int nRGB;
};
//------------------------------------------------------------------------
class SFontFile {
public:
// A typical subclass will provide a constructor along the lines of:
//
// SomeFontFile(SomeFontEngine *engine, char *fontFileName);
SFontFile();
virtual ~SFontFile();
private:
};
//------------------------------------------------------------------------
class SFont {
public:
// A typical subclass will provide a constructor along the lines of:
//
// SomeFont(SomeFontFile *fontFile, double *m);
//
// where <m> is a transform matrix consisting of four elements,
// using the PostScript ordering conventions (without any
// translation):
//
// [x' y'] = [x y] * [m0 m1]
// [m2 m3]
//
// This is the level at which fonts are cached, and so the font
// cannot be transformed after it is created.
SFont();
virtual ~SFont();
// Draw a character <c>/<u> at <x>,<y> in color (<r>,<g>,<b>). The
// RGB values should each be in the range [0,65535]. Draws into
// <d>, clipped to the rectangle (0,0)-(<w>-1,<h>-1). Returns true
// if the character was drawn successfully.
virtual GBool drawChar(Drawable d, int w, int h, GC gc,
int x, int y, int r, int g, int b,
CharCode c, Unicode u) = 0;
// Add the outline of the specified character to the current path by
// calling state->moveTo, lineTo, and curveTo. Returns true if
// successful. If this SFont subclass doesn't implement character
// paths, returns false immediately without modifying the current
// path.
virtual GBool getCharPath(CharCode c, Unicode u, GfxState *state);
protected:
};
#endif

Some files were not shown because too many files have changed in this diff Show more