mirror of
https://invent.kde.org/graphics/okular
synced 2024-08-24 18:35:37 +00:00
- 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:
parent
78791f5819
commit
3abd57ea99
|
@ -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
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
SUBDIRS = . goo xpdf kpdf
|
||||
SUBDIRS = . fofi goo xpdf kpdf
|
||||
|
||||
noinst_HEADERS = aconf.h
|
||||
|
||||
|
|
149
README.xpdf
149
README.xpdf
|
@ -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.
|
||||
|
|
156
fofi/FoFiBase.cc
Normal file
156
fofi/FoFiBase.cc
Normal 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
57
fofi/FoFiBase.h
Normal 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
994
fofi/FoFiEncodings.cc
Normal 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
36
fofi/FoFiEncodings.h
Normal 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
1438
fofi/FoFiTrueType.cc
Normal file
File diff suppressed because it is too large
Load diff
133
fofi/FoFiTrueType.h
Normal file
133
fofi/FoFiTrueType.h
Normal 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
207
fofi/FoFiType1.cc
Normal 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
59
fofi/FoFiType1.h
Normal 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
2385
fofi/FoFiType1C.cc
Normal file
File diff suppressed because it is too large
Load diff
226
fofi/FoFiType1C.h
Normal file
226
fofi/FoFiType1C.h
Normal 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
10
fofi/Makefile.am
Normal 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
|
191
goo/GHash.cc
191
goo/GHash.cc
|
@ -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;
|
||||
|
|
27
goo/GHash.h
27
goo/GHash.h
|
@ -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
49
goo/GMutex.h
Normal 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
|
|
@ -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:
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
25
goo/gfile.cc
25
goo/gfile.cc
|
@ -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
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
190
goo/parseargs.c
190
goo/parseargs.c
|
@ -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;
|
||||
}
|
|
@ -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
|
|
@ -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
|
||||
|
|
|
@ -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 )
|
||||
{
|
||||
|
|
|
@ -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 );
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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 ( ));
|
||||
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
|
|
@ -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 );
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
30
xpdf/CMap.cc
30
xpdf/CMap.cc
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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
|
||||
};
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -9,7 +9,7 @@
|
|||
#ifndef COMPACTFONTINFO_H
|
||||
#define COMPACTFONTINFO_H
|
||||
|
||||
static const char *type1CStdStrings[391] = {
|
||||
static char *type1CStdStrings[391] = {
|
||||
".notdef",
|
||||
"space",
|
||||
"exclam",
|
||||
|
|
|
@ -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) {
|
||||
|
|
22
xpdf/Dict.cc
22
xpdf/Dict.cc
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
14
xpdf/Dict.h
14
xpdf/Dict.h
|
@ -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
|
||||
|
|
|
@ -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}
|
||||
};
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
783
xpdf/FTFont.cc
783
xpdf/FTFont.cc
|
@ -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)
|
139
xpdf/FTFont.h
139
xpdf/FTFont.h
|
@ -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
|
4181
xpdf/FontFile.cc
4181
xpdf/FontFile.cc
File diff suppressed because it is too large
Load diff
238
xpdf/FontFile.h
238
xpdf/FontFile.h
|
@ -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
|
|
@ -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:
|
||||
|
|
|
@ -27,8 +27,8 @@ class PSStack;
|
|||
// Function
|
||||
//------------------------------------------------------------------------
|
||||
|
||||
#define funcMaxInputs 8
|
||||
#define funcMaxOutputs 8
|
||||
#define funcMaxInputs 8
|
||||
#define funcMaxOutputs 32
|
||||
|
||||
class Function {
|
||||
public:
|
||||
|
|
591
xpdf/Gfx.cc
591
xpdf/Gfx.cc
File diff suppressed because it is too large
Load diff
27
xpdf/Gfx.h
27
xpdf/Gfx.h
|
@ -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
|
||||
|
|
431
xpdf/GfxFont.cc
431
xpdf/GfxFont.cc
|
@ -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());
|
||||
|
|
|
@ -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();
|
||||
|
|
744
xpdf/GfxState.cc
744
xpdf/GfxState.cc
|
@ -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];
|
||||
|
|
107
xpdf/GfxState.h
107
xpdf/GfxState.h
|
@ -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
|
@ -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
|
||||
};
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
|
@ -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
300
xpdf/JArithmeticDecoder.cc
Normal 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
91
xpdf/JArithmeticDecoder.h
Normal 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
|
|
@ -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));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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
2822
xpdf/JPXStream.cc
Normal file
File diff suppressed because it is too large
Load diff
340
xpdf/JPXStream.h
Normal file
340
xpdf/JPXStream.h
Normal 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
|
|
@ -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();
|
||||
}
|
|
@ -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
|
|
@ -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");
|
||||
|
|
128
xpdf/Link.cc
128
xpdf/Link.cc
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
|
|
48
xpdf/Link.h
48
xpdf/Link.h
|
@ -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?
|
||||
};
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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().
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
|
||||
static struct {
|
||||
Unicode u;
|
||||
const char *name;
|
||||
char *name;
|
||||
} nameToUnicodeTab[] = {
|
||||
{0x0021, "!"},
|
||||
{0x0023, "#"},
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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()
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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]
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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();
|
||||
}
|
|
@ -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
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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); }
|
||||
|
|
1311
xpdf/PSOutputDev.cc
1311
xpdf/PSOutputDev.cc
File diff suppressed because it is too large
Load diff
|
@ -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
|
||||
|
|
76
xpdf/Page.cc
76
xpdf/Page.cc
|
@ -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) {
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
142
xpdf/SFont.h
142
xpdf/SFont.h
|
@ -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
Loading…
Reference in a new issue