oKular goes poppler

svn path=/trunk/playground/graphics/oKular/kpdf/; revision=520367
This commit is contained in:
Albert Astals Cid 2006-03-19 18:03:43 +00:00
parent 3e168cfd07
commit 30c2f8067d
178 changed files with 412 additions and 77993 deletions

View File

@ -2,5 +2,3 @@ Albert Astals Cid <tsdgeos@yahoo.es>
Enrico Ros <eros.kde@email.it>
Wilco Greven <greven@kde.org>
Christophe Devriese <oelewapperke@ulyssis.org>
XPdf is written by Glyph & Cog, LLC

View File

@ -1,30 +0,0 @@
if test -z "$FREETYPE_CONFIG"; then
echo ""
echo "You're missing freetype development libs."
echo "KPDF will not be build without them"
echo ""
fi
if test x$FREETYPE_VERSION != x; then
if test $FREETYPE_VERSION -lt 9008003; then
echo ""
echo "You're are using freetype older than 2.1.10, it is not mandatory"
echo "to use 2.1.10 but kpdf improves its rendering in some pdf with it"
echo ""
fi
fi
if test -z "$XFT_LIBS"; then
echo ""
echo "You're missing XFT development libs."
echo "KPDF will not be build without them"
echo ""
fi
if test "$HAVE_LIBJPEG" = "no"; then
echo ""
echo "You're missing libjpeg development libs."
echo "KPDF will not be build without them"
echo ""
fi

View File

@ -1,100 +1,3 @@
dnl ##### Check for FreeType 2.0.5+.
dnl ##### (Note: FT_Get_Name_Index was added in FT 2.0.5, and is
dnl ##### the reason that Xpdf requires 2.0.5+.)
KDE_FIND_PATH(freetype-config, FREETYPE_CONFIG, [${prefix}/bin ${exec_prefix}/bin /usr/local/bin /opt/local/bin], [
AC_MSG_WARN([Could not find libfreetype anywhere, check http://www.freetype.org/])
])
if test -n "$FREETYPE_CONFIG"; then
FREETYPE_VERSION=`$FREETYPE_CONFIG --version 2>/dev/null | sed -e 's/libfreetype //' | awk 'BEGIN { FS = "."; } { printf "%d", ($1 * 1000 + $2) * 1000 + $3;}'`
if test -n "$FREETYPE_VERSION" && test "$FREETYPE_VERSION" -ge 9000000; then
LIBFREETYPE_LIBS="`$FREETYPE_CONFIG --libs`"
LIBFREETYPE_RPATH=
for args in $LIBFREETYPE_LIBS; do
case $args in
-L*) LIBFREETYPE_RPATH="$LIBFREETYPE_RPATH $args" ;;
esac
done
LIBFREETYPE_RPATH=`echo $LIBFREETYPE_RPATH | sed -e "s/-L/-R/g"`
LIBFREETYPE_CFLAGS="`$FREETYPE_CONFIG --cflags`"
AC_DEFINE_UNQUOTED(HAVE_FREETYPE, 1, [Defines if your system has the freetype library])
else
AC_MSG_WARN([You need at least libfreetype 2.0.5])
DO_NOT_COMPILE="$DO_NOT_COMPILE kpdf"
fi
else
DO_NOT_COMPILE="$DO_NOT_COMPILE kpdf"
fi
AC_SUBST(FREETYPE_VERSION)
AC_SUBST(LIBFREETYPE_LIBS)
AC_SUBST(LIBFREETYPE_CFLAGS)
AC_SUBST(LIBFREETYPE_RPATH)
# Check for xft
KDE_FIND_PATH(xft-config, XFT_CONFIG, [${prefix}/bin ${exec_prefix}/bin /usr/local/bin /opt/local/bin],)
if test -n "$XFT_CONFIG"; then
XFT_CFLAGS="`$XFT_CONFIG --cflags`"
XFT_LIBS="`$XFT_CONFIG --libs`"
fi
AC_SUBST(XFT_CFLAGS)
AC_SUBST(XFT_LIBS)
if test -z "$XFT_LIBS"; then
DO_NOT_COMPILE="$DO_NOT_COMPILE kpdf"
fi
dnl ##### Check for libpaper (Debian).
LIBPAPER_LIBS=
KDE_CHECK_HEADER(paper.h, [
LIBPAPER_LIBS='-lpaper'
AC_DEFINE_UNQUOTED(HAVE_PAPER_H, 1, [Define to 1 if you have the <paper.h> header file.])
],
AC_DEFINE_UNQUOTED(HAVE_PAPER_H, 0, [Define to 1 if you have the <paper.h> header file.])
)
AC_SUBST(LIBPAPER_LIBS)
AC_CHECK_FUNCS(fseek64 mkstemp mkstemps popen)
AC_FIND_FILE(xpdfrc, [/etc /usr/local/etc /etc/xpdf], xpdfrc)
if test "$xpdfrc" != NO; then
AC_DEFINE_UNQUOTED(SYSTEM_XPDFRC, "$xpdfrc/xpdfrc", [Define the location your xpdfrc])
fi
dnl #### Check for FSEEK variants
KDE_CHECK_LARGEFILE
AC_FUNC_FSEEKO
AC_CHECK_FUNCS(fseek64, xpdf_cv_func_fseek64=yes, xpdf_cv_func_fseek64=no)
AC_CHECK_FUNCS(ftell64, xpdf_cv_func_ftell64=yes, xpdf_cv_func_ftell64=no)
if test "$xpdf_cv_func_fseek64" = yes -a "$xpdf_cv_func_ftell64" = yes; then
AC_DEFINE(HAVE_FSEEK64, 1)
else
AC_DEFINE(HAVE_FSEEK64, 0)
fi
dnl #### Enable the user to enable multithearind on xpdf
AC_ARG_ENABLE(multithreaded-kpdf,
AC_HELP_STRING([--enable-multithreaded-kpdf],[include support for multithreading in xpdf code inside kpdf. Has nothing to do with threaded generation of contents, this is configurable via a dialog inside the program itself]),
[
case $enableval in
yes)
AC_DEFINE(MULTITHREADED, 1, [Defines if use multithreading in xpdf code inside kpdf])
;;
no)
AC_DEFINE(MULTITHREADED, 0, [Defines if use multithreading in xpdf code inside kpdf])
;;
*)
AC_DEFINE(MULTITHREADED, 1, [Defines if use multithreading in xpdf code inside kpdf])
;;
esac
]
, AC_DEFINE(MULTITHREADED, 0, [Defines if use multithreading in xpdf code inside kpdf])
)
dnl #### Enable the user to decide if he wants to force drm or not
AC_ARG_ENABLE(force-kpdf-drm,
AC_HELP_STRING([--enable-force-kpdf-drm],[Forces kpdf to check for DRM to decide if you can copy/print protected pdf. (default=no)]),
@ -112,11 +15,4 @@ AC_ARG_ENABLE(force-kpdf-drm,
esac
]
, AC_DEFINE(KPDF_FORCE_DRM, 0, [Defines if force the use DRM in kpdf])
)
KDE_CHECK_COMPILER_FLAG([fno-regmove], SUPPORTS_NOREGMOVE=true, SUPPORTS_NOREGMOVE=false)
if test "x$SUPPORTS_NOREGMOVE" = xtrue; then
NOREGMOVE="-fno-regmove"
fi
AC_SUBST(NOREGMOVE)
)

View File

@ -20,7 +20,6 @@
#include "annotations.h"
#include "conf/settings.h"
#include "area.h"
//include "xpdf/TextOutputDev.h"
// temp includes
#include <sys/time.h>

View File

@ -6,5 +6,9 @@ if include_chm
CHMPLUGINDIR = chm
endif
if include_pdf
PDFPLUGINDIR = xpdf
endif
SUBDIRS = $(GSPLUGINDIR) xpdf fax kimgio $(CHMPLUGINDIR)

View File

@ -18,3 +18,11 @@ echo "The chm backend will not be available."
echo ""
fi
if test "x$have_poppler_051" != "xyes"; then
echo ""
echo "You're missing poppler-qt >= 0.5.1"
echo "The pdf backend won't be compiled without poppler >= 0.5.1"
echo "You can download poppler from http://poppler.freedesktop.org/"
echo ""
fi

View File

@ -21,3 +21,14 @@ AM_CONDITIONAL(include_ghostscript, test -n "$LIB_QGS")
HAVE_CHMLIB=no
KDE_CHECK_HEADER(chm_lib.h, HAVE_CHMLIB=yes)
AM_CONDITIONAL(include_chm, test "x$HAVE_CHMLIB" = "xyes")
AC_ARG_WITH([poppler],
[AS_HELP_STRING([--with-poppler],
[Enable PDF support through poppler @<:@default=check@:>@])],
[], with_poppler=check)
if test "x$with_poppler" != xno; then
PKG_CHECK_MODULES(POPPLER, poppler >= 0.5.1, have_poppler_051=yes, have_poppler_051=no)
fi
AM_CONDITIONAL(include_pdf, test "x$have_poppler_051" = xyes)

View File

@ -1,15 +1,12 @@
SUBDIRS = xpdf .
kde_module_LTLIBRARIES = \
libokularGenerator_xpdf.la
INCLUDES = -I$(srcdir)/../.. -I$(srcdir)/xpdf -I$(srcdir)/xpdf/goo -I$(srcdir)/xpdf/splash -I$(top_builddir)/kpdf $(all_includes)
INCLUDES = -I$(srcdir)/../.. -I$(top_builddir)/kpdf $(POPPLER_CFLAGS) $(all_includes)
libokularGenerator_xpdf_la_LIBADD = $(top_builddir)/kpdf/core/liboKularcore.la $(top_builddir)/kpdf/conf/liboKularconf.la \
$(top_builddir)/kpdf/generators/xpdf/xpdf/xpdf/libxpdf.la \
$(LIB_KDEPRINT) $(LIB_KDEUI) -lm
$(POPPLER_LIBS) $(LIB_KDEPRINT) $(LIB_KDEUI) -lm
libokularGenerator_xpdf_la_LDFLAGS = $(all_libraries) -module $(KDE_PLUGIN)
libokularGenerator_xpdf_la_SOURCES = generator_pdf.cpp gp_outputdev.cpp
libokularGenerator_xpdf_la_SOURCES = generator_pdf.cpp gp_outputdev.cpp pagetransition.cpp
KDE_OPTIONS = nofinal

View File

@ -25,18 +25,20 @@
#include <kmessagebox.h>
#include <kdebug.h>
// xpdf includes
#include "xpdf/PSOutputDev.h"
#include "xpdf/TextOutputDev.h"
#include "xpdf/Link.h"
#include "xpdf/ErrorCodes.h"
#include "xpdf/UnicodeMap.h"
#include "xpdf/Outline.h"
#include "xpdf/GfxState.h"
#include "xpdf/Annot.h" // for retrieving fonts only
#include "xpdf/UGString.h"
#include "xpdf/GlobalParams.h"
#include "goo/GList.h"
// poppler includes
#include "PSOutputDev.h"
#include "TextOutputDev.h"
#include "Link.h"
#include "ErrorCodes.h"
#include "UnicodeMap.h"
#include "Outline.h"
#include "GfxState.h"
#include "Annot.h" // for retrieving fonts only
#include "UGooString.h"
#include "GlobalParams.h"
#include "goo/GooList.h"
#include "pagetransition.h"
// local includes
#include "generator_pdf.h"
@ -80,7 +82,6 @@ PDFGenerator::PDFGenerator( KPDFDocument * doc )
//if ( m_count ) TODO check if we need to insert these lines..
// delete globalParams;
globalParams = new GlobalParams("");
globalParams->setupBaseFonts(NULL);
m_count++;
// generate kpdfOutputDev and cache page color
@ -123,7 +124,7 @@ bool PDFGenerator::loadDocument( const QString & filePath, QValueVector<KPDFPage
}
#endif
// create PDFDoc for the given file
pdfdoc = new PDFDoc( new GString( QFile::encodeName( filePath ) ), 0, 0 );
pdfdoc = new PDFDoc( new GooString( QFile::encodeName( filePath ) ), 0, 0 );
// if the file didn't open correctly it might be encrypted, so ask for a pass
bool firstInput = true;
@ -169,9 +170,9 @@ bool PDFGenerator::loadDocument( const QString & filePath, QValueVector<KPDFPage
}
// 2. reopen the document using the password
GString * pwd2 = new GString( password.data() );
GooString * pwd2 = new GooString( password.data() );
delete pdfdoc;
pdfdoc = new PDFDoc( new GString( QFile::encodeName( filePath ) ), pwd2, pwd2 );
pdfdoc = new PDFDoc( new GooString( QFile::encodeName( filePath ) ), pwd2, pwd2 );
delete pwd2;
// 3. if the password is correct, store it to the wallet
@ -371,7 +372,7 @@ const DocumentSynopsis * PDFGenerator::generateDocumentSynopsis()
if ( !outline )
return NULL;
GList * items = outline->getItems();
GooList * items = outline->getItems();
if ( !items || items->getLength() < 1 )
return NULL;
@ -560,27 +561,27 @@ bool PDFGenerator::print( KPrinter& printer )
}
KTempFile tf( QString::null, ".ps" );
PSOutputDev *psOut = new PSOutputDev(tf.name().latin1(), pdfdoc->getXRef(), pdfdoc->getCatalog(), 1, pdfdoc->getNumPages(), psModePS);
PSOutputDev *psOut = new PSOutputDev((char*)tf.name().latin1(), pdfdoc->getXRef(), pdfdoc->getCatalog(), 1, pdfdoc->getNumPages(), psModePS);
if (psOut->isOk())
{
std::list<int> pages;
QValueList<int> pageList;
if (!printer.previewOnly())
{
QValueList<int> pageList = printer.pageList();
QValueList<int>::const_iterator it;
for(it = pageList.begin(); it != pageList.end(); ++it) pages.push_back(*it);
pageList = printer.pageList();
}
else
{
for(int i = 1; i <= pdfdoc->getNumPages(); i++) pages.push_back(i);
for(int i = 1; i <= pdfdoc->getNumPages(); i++) pageList.push_back(i);
}
docLock.lock();
// TODO rotation
pdfdoc->displayPages(psOut, pages, 72, 72, 0, false, globalParams->getPSCrop(), gFalse);
for(int page = 0; page < pageList.count(); ++page)
{
// TODO rotation
pdfdoc->displayPage(psOut, page, 72, 72, 0, false, globalParams->getPSCrop(), gFalse);
}
docLock.unlock();
// needs to be here so that the file is flushed, do not merge with the one
@ -596,12 +597,12 @@ bool PDFGenerator::print( KPrinter& printer )
}
}
static UGString *QStringToUGString(const QString &s) {
static UGooString *QStringToUGooString(const QString &s) {
int len = s.length();
Unicode *u = (Unicode *)gmallocn(s.length(), sizeof(Unicode));
for (int i = 0; i < len; ++i)
u[i] = s.at(i).unicode();
return new UGString(u, len);
return new UGooString(u, len);
}
QString PDFGenerator::getMetaData( const QString & key, const QString & option )
@ -610,7 +611,7 @@ QString PDFGenerator::getMetaData( const QString & key, const QString & option )
if ( key == "StartFullScreen" )
{
// asking for the 'start in fullscreen mode' (pdf property)
if ( pdfdoc->getCatalog()->getPageMode() == Catalog::FullScreen )
if ( pdfdoc->getCatalog()->getPageMode() == Catalog::pageModeFullScreen )
return "yes";
}
else if ( key == "NamedViewport" && !option.isEmpty() )
@ -618,7 +619,7 @@ QString PDFGenerator::getMetaData( const QString & key, const QString & option )
// asking for the page related to a 'named link destination'. the
// option is the link name. @see addSynopsisChildren.
DocumentViewport viewport;
UGString * namedDest = QStringToUGString( option );
UGooString * namedDest = QStringToUGooString( option );
docLock.lock();
LinkDest * destination = pdfdoc->findDest( namedDest );
if ( destination )
@ -817,7 +818,7 @@ QString PDFGenerator::getDocumentInfo( const QString & data ) const
QString result;
Object obj;
GString *s1;
GooString *s1;
GBool isUnicode;
Unicode u;
int i;
@ -906,7 +907,7 @@ QString PDFGenerator::getDocumentDate( const QString & data ) const
return result;
}
void PDFGenerator::addSynopsisChildren( QDomNode * parent, GList * items )
void PDFGenerator::addSynopsisChildren( QDomNode * parent, GooList * items )
{
int numItems = items->getLength();
for ( int i = 0; i < numItems; ++i )
@ -937,7 +938,7 @@ void PDFGenerator::addSynopsisChildren( QDomNode * parent, GList * items )
// get the destination for the page now, but it's VERY time consuming,
// so better storing the reference and provide the viewport as metadata
// on demand
UGString *s = g->getNamedDest();
UGooString *s = g->getNamedDest();
QString aux = unicodeToQString( s->unicode(), s->getLength() );
item.setAttribute( "ViewportName", aux );
}
@ -956,7 +957,7 @@ void PDFGenerator::addSynopsisChildren( QDomNode * parent, GList * items )
// 3. recursively descend over children
outlineItem->open();
GList * children = outlineItem->getKids();
GooList * children = outlineItem->getKids();
if ( children )
addSynopsisChildren( &item, children );
}
@ -1005,7 +1006,7 @@ void PDFGenerator::addFonts( Dict *resDict, Ref **fonts, int &fontsLen, int &fon
docFonts.firstChild().appendChild( fontElem );
// 1. set Name
GString * name = font->getOrigName();
GooString * name = font->getOrigName();
fontElem.setAttribute( "Name", name ? name->getCString() : i18n("[none]") );
// 2. set Type
@ -1030,7 +1031,7 @@ void PDFGenerator::addFonts( Dict *resDict, Ref **fonts, int &fontsLen, int &fon
QString sPath = i18n("-");
if ( name && !emb )
{
DisplayFontParam *dfp = globalParams->getDisplayFont( name );
DisplayFontParam *dfp = globalParams->getDisplayFont( font );
if ( dfp )
{
if ( dfp -> kind == displayFontT1 ) sPath = dfp->t1.fileName->getCString();
@ -1997,12 +1998,14 @@ void PDFGenerator::fillViewportFromLink( DocumentViewport &viewport, LinkDest *d
void PDFGenerator::addTransition( Page * pdfPage, KPDFPage * page )
// called on opening when MUTEX is not used
{
PageTransition *pdfTransition = pdfPage->getTransition();
if ( !pdfTransition || pdfTransition->getType() == PageTransition::Replace )
Object o;
PageTransition *pdfTransition = new PageTransition(pdfPage->getTrans(&o));
o.free();
if ( !pdfTransition || pdfTransition->type() == PageTransition::Replace )
return;
KPDFPageTransition *transition = new KPDFPageTransition();
switch ( pdfTransition->getType() ) {
switch ( pdfTransition->type() ) {
case PageTransition::Replace:
// won't get here, added to avoid warning
break;
@ -2041,9 +2044,9 @@ void PDFGenerator::addTransition( Page * pdfPage, KPDFPage * page )
break;
}
transition->setDuration( pdfTransition->getDuration() );
transition->setDuration( pdfTransition->duration() );
switch ( pdfTransition->getAlignment() ) {
switch ( pdfTransition->alignment() ) {
case PageTransition::Horizontal:
transition->setAlignment( KPDFPageTransition::Horizontal );
break;
@ -2052,7 +2055,7 @@ void PDFGenerator::addTransition( Page * pdfPage, KPDFPage * page )
break;
}
switch ( pdfTransition->getDirection() ) {
switch ( pdfTransition->direction() ) {
case PageTransition::Inward:
transition->setDirection( KPDFPageTransition::Inward );
break;
@ -2061,8 +2064,8 @@ void PDFGenerator::addTransition( Page * pdfPage, KPDFPage * page )
break;
}
transition->setAngle( pdfTransition->getAngle() );
transition->setScale( pdfTransition->getScale() );
transition->setAngle( pdfTransition->angle() );
transition->setScale( pdfTransition->scale() );
transition->setIsRectangular( pdfTransition->isRectangular() == gTrue );
page->setTransition( transition );

View File

@ -21,7 +21,7 @@
#include "core/textpage.h"
class PDFDoc;
class GList;
class GooList;
class TextPage;
class LinkDest;
class Page;
@ -107,7 +107,7 @@ class PDFGenerator : public Generator
QString getDocumentInfo( const QString & data ) const;
QString getDocumentDate( const QString & data ) const;
// create the document synopsis hieracy
void addSynopsisChildren( QDomNode * parent, GList * items );
void addSynopsisChildren( QDomNode * parent, GooList * items );
// add fonts (in resDict) to the private 'docFonts' class
void addFonts( Dict * resDict, Ref ** fonts, int &fontsLen, int &fontsSize );
// fetch annotations from the pdf file and add they to the page

View File

@ -28,9 +28,9 @@
#include "core/document.h" // for DocumentViewport
#include "core/page.h"
#include "core/link.h"
#include "xpdf/Link.h"
#include "xpdf/GfxState.h"
#include "xpdf/TextOutputDev.h"
#include "Link.h"
#include "GfxState.h"
#include "TextOutputDev.h"
#include "splash/SplashBitmap.h"
//NOTE: XPDF/Splash *implementation dependant* code is marked with '###'
@ -263,7 +263,7 @@ KPDFLink * KPDFOutputDev::generateLink( LinkAction * a )
case actionLaunch:
{
LinkLaunch * e = (LinkLaunch *)a;
GString * p = e->getParams();
GooString * p = e->getParams();
link = new KPDFLinkExecute( e->getFileName()->getCString(), p ? p->getCString() : 0 );
}
break;
@ -328,7 +328,7 @@ KPDFLink * KPDFOutputDev::generateLink( LinkAction * a )
return link;
}
DocumentViewport KPDFOutputDev::decodeViewport( UGString * namedDest, LinkDest * dest )
DocumentViewport KPDFOutputDev::decodeViewport( UGooString * namedDest, LinkDest * dest )
// note: this function is called when processing a page, when the MUTEX is already LOCKED
{
DocumentViewport vp( -1 );

View File

@ -19,9 +19,12 @@
#pragma interface
#endif
#define USE_FIXEDPOINT 0
#define SPLASH_CMYK 0
#include <qvaluelist.h>
#include "xpdf/PDFDoc.h" // for 'Object'
#include "xpdf/SplashOutputDev.h"
#include "PDFDoc.h" // for 'Object'
#include "SplashOutputDev.h"
class QPixmap;
class KPDFLink;
@ -71,7 +74,7 @@ class KPDFOutputDev : public SplashOutputDev
// generate a valid KPDFLink subclass (or null) from a xpdf's LinkAction
KPDFLink * generateLink( LinkAction * a );
// fills up a Viewport structure out of a given LinkGoto link
DocumentViewport decodeViewport( UGString *, class LinkDest * );
DocumentViewport decodeViewport( UGooString *, class LinkDest * );
// generator switches and parameters
bool m_qtThreadSafety;

View File

@ -0,0 +1,184 @@
/* PageTransition.cc
* Copyright (C) 2005, Net Integration Technologies, Inc.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2, or (at your option)
* any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#include "Object.h"
#include "Error.h"
#include "UGooString.h"
#include "pagetransition.h"
class PageTransitionData
{
public:
PageTransition::Type type;
int duration;
PageTransition::Alignment alignment;
PageTransition::Direction direction;
int angle;
double scale;
bool rectangular;
};
PageTransition::PageTransition(Object *dictObj)
{
data = new PageTransitionData();
data->type = Replace;
data->duration = 1;
data->alignment = Horizontal;
data->direction = Inward;
data->angle = 0;
data->scale = 1.0;
data->rectangular = false;
// Paranoid safety checks
if (dictObj == 0) {
error(-1, "the method PageTransition_x::PageTransition_x(Object *params.dictObj) was called with params.dictObj==0\n");
return;
}
if (dictObj->isDict() == false) {
error(-1, "the method PageTransition_x::PageTransition_x(Object *params.dictObj) was called where params.dictObj->isDict()==false\n");
return;
}
// Obtain a pointer to the dictionary and start parsing.
Dict *transDict = dictObj->getDict();
Object obj;
if (transDict->lookup("S", &obj)->isName()) {
const char *s = obj.getName();
if (strcmp("R", s) == 0)
data->type = Replace;
else if (strcmp("Split", s) == 0)
data->type = Split;
else if (strcmp("Blinds", s) == 0)
data->type = Blinds;
else if (strcmp("Box", s) == 0)
data->type = Box;
else if (strcmp("Wipe", s) == 0)
data->type = Wipe;
else if (strcmp("Dissolve", s) == 0)
data->type = Dissolve;
else if (strcmp("Glitter", s) == 0)
data->type = Glitter;
else if (strcmp("Fly", s) == 0)
data->type = Fly;
else if (strcmp("Push", s) == 0)
data->type = Push;
else if (strcmp("Cover", s) == 0)
data->type = Cover;
else if (strcmp("Uncover", s) == 0)
data->type = Push;
else if (strcmp("Fade", s) == 0)
data->type = Cover;
}
obj.free();
if (transDict->lookup("D", &obj)->isInt()) {
data->duration = obj.getInt();
}
obj.free();
if (transDict->lookup("Dm", &obj)->isName()) {
const char *dm = obj.getName();
if ( strcmp( "H", dm ) == 0 )
data->alignment = Horizontal;
else if ( strcmp( "V", dm ) == 0 )
data->alignment = Vertical;
}
obj.free();
if (transDict->lookup("M", &obj)->isName()) {
const char *m = obj.getName();
if ( strcmp( "I", m ) == 0 )
data->direction = Inward;
else if ( strcmp( "O", m ) == 0 )
data->direction = Outward;
}
obj.free();
if (transDict->lookup("Di", &obj)->isInt()) {
data->angle = obj.getInt();
}
obj.free();
if (transDict->lookup("Di", &obj)->isName()) {
if ( strcmp( "None", obj.getName() ) == 0 )
data->angle = 0;
}
obj.free();
if (transDict->lookup("SS", &obj)->isReal()) {
data->scale = obj.getReal();
}
obj.free();
if (transDict->lookup("B", &obj)->isBool()) {
data->rectangular = obj.getBool();
}
obj.free();
}
PageTransition::PageTransition(const PageTransition &pt)
{
data = new PageTransitionData();
data->type = pt.data->type;
data->duration = pt.data->duration;
data->alignment = pt.data->alignment;
data->direction = pt.data->direction;
data->angle = pt.data->angle;
data->scale = pt.data->scale;
data->rectangular = pt.data->rectangular;
}
PageTransition::~PageTransition()
{
}
PageTransition::Type PageTransition::type() const
{
return data->type;
}
int PageTransition::duration() const
{
return data->duration;
}
PageTransition::Alignment PageTransition::alignment() const
{
return data->alignment;
}
PageTransition::Direction PageTransition::direction() const
{
return data->direction;
}
int PageTransition::angle() const
{
return data->angle;
}
double PageTransition::scale() const
{
return data->scale;
}
bool PageTransition::isRectangular() const
{
return data->rectangular;
}

View File

@ -0,0 +1,140 @@
/* PageTransition.h
* Copyright (C) 2005, Net Integration Technologies, Inc.
* Copyright (C) 2005, Brad Hards <bradh@frogmouth.net>
* Copyright (C) 2006, Albert Astals Cid <aacid@kde.org>
*
* File taken from poppler distribution, will remove asap we use the Qt4 frontend
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2, or (at your option)
* any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#ifndef __PAGETRANSITION_X_H__
#define __PAGETRANSITION_X_H__
/**
\brief Describes how a PDF file viewer shall perform the transition
from one page to another
In PDF files there is a way to specify if the viewer shall use
certain effects to perform the transition from one page to
another. This feature can be used, e.g., in a PDF-based beamer
presentation.
This utility class represents the transition effect, and can be
used to extract the information from a PDF object.
*/
class PageTransitionData;
class PageTransition {
public:
/** \brief transition effect that shall be used
*/
enum Type {
Replace,
Split,
Blinds,
Box,
Wipe,
Dissolve,
Glitter,
Fly,
Push,
Cover,
Uncover,
Fade
};
/** \brief alignment of the transition effect that shall be used
*/
enum Alignment {
Horizontal,
Vertical
};
/** \brief direction of the transition effect that shall be used
*/
enum Direction {
Inward,
Outward
};
/** \brief Construct a new PageTransition object from a page dictionary.
Users of the library will rarely need to construct a
PageTransition object themselves. Instead, the method
Poppler::Page::transition() can be used to find out if a certain
transition effect is specified.
@warning In case or error, this method will print an error message to stderr,
and construct a default object.
@param params an object whose dictionary will be read and
parsed. This must be a valid object, whose dictionaries are
accessed by the constructor. The object is only accessed by this
constructor, and may be deleted after the constructor returns.
*/
PageTransition(Object *dictObj);
/** \brief copy constructor */
PageTransition(const PageTransition &pt);
/**
Destructor
*/
~PageTransition();
/**
\brief Get type of the transition.
*/
Type type() const;
/**
\brief Get duration of the transition in seconds.
*/
int duration() const;
/**
\brief Get dimension in which the transition effect occurs.
*/
Alignment alignment() const;
/**
\brief Get direction of motion of the transition effect.
*/
Direction direction() const;
/**
\brief Get direction in which the transition effect moves.
*/
int angle() const;
/**
\brief Get starting or ending scale.
*/
double scale() const;
/**
\brief Returns true if the area to be flown is rectangular and
opaque.
*/
bool isRectangular() const;
private:
PageTransitionData *data;
};
#endif

View File

@ -1,6 +0,0 @@
SUBDIRS = fofi goo splash xpdf
# This fixes crash in Bug 109015 which i assume is a compiler bug
# as adding some correctly placed printf in SplashOutputDev::convertPath() makes this
# option unneeded
KDE_CXXFLAGS=$(NOREGMOVE)

View File

@ -1,376 +0,0 @@
Xpdf
====
version 3.00
2004-jan-22
The Xpdf software and documentation are
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-2003 Adobe Systems Inc.
What is Xpdf?
-------------
Xpdf is an open source viewer for Portable Document Format (PDF)
files. (These are also sometimes also called 'Acrobat' files, from
the name of Adobe's PDF software.) The Xpdf project also includes a
PDF text extractor, PDF-to-PostScript converter, and various other
utilities.
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 or
TrueType fonts.
Distribution
------------
Xpdf is licensed under the GNU General Public License (GPL), version
2. In my opinion, the GPL is a convoluted, confusing, ambiguous mess.
But it's also pervasive, and I'm sick of arguing. And even if it is
confusing, the basic idea is good.
In order to cut down on the confusion a little bit, here are some
informal clarifications:
- I don't mind if you redistribute Xpdf in source and/or binary form,
as long as you include all of the documentation: README, man pages
(or help files), and COPYING. (Note that the README file contains a
pointer to a web page with the source code.)
- Selling a CD-ROM that contains Xpdf is fine with me, as long as it
includes the documentation. I wouldn't mind receiving a sample
copy, but it's not necessary.
- If you make useful changes to Xpdf, please make the source code
available -- post it on a web site, email it to me, whatever.
If you're interested in commercial licensing, please see the Glyph &
Cog web site:
http://www.glyphandcog.com/
Compatibility
-------------
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,
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,
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
or on the web, I'll be happy to add a link from the Xpdf web page. I
have decided not to host any binaries I didn't compile myself (for
disk space and support reasons).
If you can't get Xpdf to compile on your system, send me email and
I'll try to help.
Xpdf has been ported to the Acorn, Amiga, BeOS, and EPOC. See the
Xpdf web page for links.
Getting Xpdf
------------
The latest version is available from:
http://www.foolabs.com/xpdf/
or:
ftp://ftp.foolabs.com/pub/xpdf/
Source code and several precompiled executables are available.
Announcements of new versions are posted to several newsgroups
(comp.text.pdf, comp.os.linux.announce, and others) and emailed to a
list of people. If you'd like to receive email notification of new
versions, just let me know.
Running Xpdf
------------
To run xpdf, simply type:
xpdf file.pdf
To generate a PostScript file, hit the "print" button in xpdf, or run
pdftops:
pdftops file.pdf
To generate a plain text file, run pdftotext:
pdftotext file.pdf
There are four additional utilities (which are fully described in
their man pages):
pdfinfo -- dumps a PDF file's Info dictionary (plus some other
useful information)
pdffonts -- lists the fonts used in a PDF file along with various
information for each font
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 2.xx
------------------------
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
--------------
See the separate file, INSTALL.
Bugs
----
If you find a bug in Xpdf, i.e., if it prints an error message,
crashes, or incorrectly displays a document, and you don't see that
bug listed here, please send me email, with a pointer (URL, ftp site,
etc.) to the PDF file.
Acknowledgments
---------------
Thanks to:
* Patrick Voigt for help with the remote server code.
* Patrick Moreau, Martin P.J. Zinser, and David Mathog for the VMS
port.
* David Boldt and Rick Rodgers for sample man pages.
* 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 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
xpdf.
* Pine Tree Systems A/S for funding the OPI and EPS support in
pdftops.
* Easy Software Products for funding the "sh" operator support.
* Tom Kacvinsky for help with FreeType and for being my interface to
the FreeType team.
* Theppitak Karoonboonyanan for help with Thai support.
* Leonard Rosenthol for help and contributions on a bunch of things.
* Alexandros Diamantidis and Maria Adaloglou for help with Greek
support.
* Lawrence Lai for help with the CJK Unicode maps.
Various people have contributed modifications made for use by the
pdftex project:
* Han The Thanh
* Martin Schröder of ArtCom GmbH
References
----------
Adobe Systems Inc., _PDF Reference: Adobe Portable Document Format
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.
[The official PostScript manual.]
Adobe Systems, Inc., _The Type 42 Font Format Specification_,
Adobe Developer Support Technical Specification #5012. 1998.
http://partners.adobe.com/asn/developer/pdfs/tn/5012.Type42_Spec.pdf
[Type 42 is the format used to embed TrueType fonts in PostScript
files.]
Adobe Systems, Inc., _Adobe CMap and CIDFont Files Specification_,
Adobe Developer Support Technical Specification #5014. 1995.
http://www.adobe.com/supportservice/devrelations/PDFS/TN/5014.CIDFont_Spec.pdf
[CMap file format needed for Japanese and Chinese font support.]
Adobe Systems, Inc., _Adobe-Japan1-4 Character Collection for
CID-Keyed Fonts_, Adobe Developer Support Technical Note #5078.
2000.
http://partners.adobe.com/asn/developer/PDFS/TN/5078.CID_Glyph.pdf
[The Adobe Japanese character set.]
Adobe Systems, Inc., _Adobe-GB1-4 Character Collection for
CID-Keyed Fonts_, Adobe Developer Support Technical Note #5079.
2000.
http://partners.adobe.com/asn/developer/pdfs/tn/5079.Adobe-GB1-4.pdf
[The Adobe Chinese GB (simplified) character set.]
Adobe Systems, Inc., _Adobe-CNS1-3 Character Collection for
CID-Keyed Fonts_, Adobe Developer Support Technical Note #5080.
2000.
http://partners.adobe.com/asn/developer/PDFS/TN/5080.CNS_CharColl.pdf
[The Adobe Chinese CNS (traditional) character set.]
Adobe Systems Inc., _Supporting the DCT Filters in PostScript Level
2_, Adobe Developer Support Technical Note #5116. 1992.
http://www.adobe.com/supportservice/devrelations/PDFS/TN/5116.PS2_DCT.PDF
[Description of the DCTDecode filter parameters.]
Adobe Systems Inc., _Open Prepress Interface (OPI) Specification -
Version 2.0_, Adobe Developer Support Technical Note #5660. 2000.
http://partners.adobe.com/asn/developer/PDFS/TN/5660.OPI_2.0.pdf
Adobe Systems Inc., CMap files.
ftp://ftp.oreilly.com/pub/examples/nutshell/cjkv/adobe/
[The actual CMap files for the 16-bit CJK encodings.]
Adobe Systems Inc., Unicode glyph lists.
http://partners.adobe.com/asn/developer/type/unicodegn.html
http://partners.adobe.com/asn/developer/type/glyphlist.txt
http://partners.adobe.com/asn/developer/type/corporateuse.txt
http://partners.adobe.com/asn/developer/type/zapfdingbats.txt
[Mappings between character names to Unicode.]
Aldus Corp., _OPI: Open Prepress Interface Specification 1.3_. 1993.
http://partners.adobe.com/asn/developer/PDFS/TN/OPI_13.pdf
Anonymous, RC4 source code.
ftp://ftp.ox.ac.uk/pub/crypto/misc/rc4.tar.gz
ftp://idea.sec.dsi.unimi.it/pub/crypt/code/rc4.tar.gz
[This is the algorithm used to encrypt PDF files.]
T. Boutell, et al., "PNG (Portable Network Graphics) Specification,
Version 1.0. RFC 2083.
[PDF uses the PNG filter algorithms.]
CCITT, "Information Technology - Digital Compression and Coding of
Continuous-tone Still Images - Requirements and Guidelines", CCITT
Recommendation T.81.
http://www.w3.org/Graphics/JPEG/
[The official JPEG spec.]
A. Chernov, "Registration of a Cyrillic Character Set". RFC 1489.
[Documentation for the KOI8-R Cyrillic encoding.]
Roman Czyborra, "The ISO 8859 Alphabet Soup".
http://czyborra.com/charsets/iso8859.html
[Documentation on the various ISO 859 encodings.]
L. Peter Deutsch, "ZLIB Compressed Data Format Specification version
3.3". RFC 1950.
[Information on the general format used in FlateDecode streams.]
L. Peter Deutsch, "DEFLATE Compressed Data Format Specification
version 1.3". RFC 1951.
[The definition of the compression algorithm used in FlateDecode
streams.]
Jim Flowers, "X Logical Font Description Conventions", Version 1.5, X
Consortium Standard, X Version 11, Release 6.1.
ftp://ftp.x.org/pub/R6.1/xc/doc/hardcopy/XLFD/xlfd.PS.Z
[The official specification of X font descriptors, including font
transformation matrices.]
Foley, van Dam, Feiner, and Hughes, _Computer Graphics: Principles and
Practice_, 2nd ed. Addison-Wesley, 1990, ISBN 0-201-12110-7.
[Colorspace conversion functions, Bezier spline math.]
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/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.
ITU, "Facsimile coding schemes and coding control functions for Group 4
facsimile apparatus", ITU-T Recommendation T.6, 1993.
http://www.itu.int/
[The official Group 3 and 4 fax standards - used by the CCITTFaxDecode
stream, as well as the JBIG2Decode stream.]
Christoph Loeffler, Adriaan Ligtenberg, George S. Moschytz, "Practical
Fast 1-D DCT Algorithms with 11 Multiplications". IEEE Intl. Conf. on
Acoustics, Speech & Signal Processing, 1989, 988-991.
[The fast IDCT algorithm used in the DCTDecode filter.]
Microsoft, _TrueType 1.0 Font Files_, rev. 1.66. 1995.
http://www.microsoft.com/typography/tt/tt.htm
[The TrueType font spec (in MS Word format, naturally).]
Thai Industrial Standard, "Standard for Thai Character Codes for
Computers", TIS-620-2533 (1990).
http://www.nectec.or.th/it-standards/std620/std620.htm
[The TIS-620 Thai encoding.]
P. Peterlin, "ISO 8859-2 (Latin 2) Resources".
http://sizif.mf.uni-lj.si/linux/cee/iso8859-2.html
[This is a web page with all sorts of useful Latin-2 character set and
font information.]
Charles Poynton, "Color FAQ".
http://www.inforamp.net/~poynton/ColorFAQ.html
[The mapping from the CIE 1931 (XYZ) color space to RGB.]
R. Rivest, "The MD5 Message-Digest Algorithm". RFC 1321.
[MD5 is used in PDF document encryption.]
Unicode Consortium, "Unicode Home Page".
http://www.unicode.org/
[Online copy of the Unicode spec.]
W3C Recommendation, "PNG (Portable Network Graphics) Specification
Version 1.0".
http://www.w3.org/Graphics/PNG/
[Defines the PNG image predictor.]
Gregory K. Wallace, "The JPEG Still Picture Compression Standard".
ftp://ftp.uu.net/graphics/jpeg/wallace.ps.gz
[Good description of the JPEG standard. Also published in CACM, April
1991, and submitted to IEEE Transactions on Consumer Electronics.]
F. Yergeau, "UTF-8, a transformation format of ISO 10646". RFC 2279.
[A commonly used Unicode encoding.]

View File

@ -1,14 +0,0 @@
/* define it to 0, if you have it, config.h will have it defined to 1 and that will be used*/
#define HAVE_FSEEK0 0
#include <config.h>
#define HAVE_T1LIB_H 0
#define HAVE_FREETYPE_H HAVE_FREETYPE
#define HAVE_FREETYPE_FREETYPE_H HAVE_FREETYPE
#define OPI_SUPPORT 0
#define TEXTOUT_WORD_LIST 1
#define SPLASH_CMYK 0
#define HAVE_XPDFCORE 0
#define HAVE_WINPDFCORE 0

View File

@ -1,156 +0,0 @@
//========================================================================
//
// 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;
}

View File

@ -1,57 +0,0 @@
//========================================================================
//
// 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, const 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

View File

@ -1,994 +0,0 @@
//========================================================================
//
// 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
//------------------------------------------------------------------------
const 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
};
const 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
//------------------------------------------------------------------------
const 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
};

View File

@ -1,36 +0,0 @@
//========================================================================
//
// 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 const char *fofiType1StandardEncoding[256];
extern const char *fofiType1ExpertEncoding[256];
//------------------------------------------------------------------------
// Type 1C font data
//------------------------------------------------------------------------
extern const char *fofiType1CStdStrings[391];
extern Gushort fofiType1CISOAdobeCharset[229];
extern Gushort fofiType1CExpertCharset[166];
extern Gushort fofiType1CExpertSubsetCharset[87];
#endif

File diff suppressed because it is too large Load Diff

View File

@ -1,141 +0,0 @@
//========================================================================
//
// 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 GString;
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, int faceIndexA=0);
// Create a FoFiTrueType object from a file on disk.
static FoFiTrueType *load(char *fileName, int faceIndexA=0);
FoFiTrueType(char *fileA, int lenA, GBool freeFileDataA, int faceIndexA=0);
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(const 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, const 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,
GBool needVerticalMetrics,
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,
GBool needVerticalMetrics,
FoFiOutputFunc outputFunc, void *outputStream);
// Write a clean TTF file, filling in missing tables and correcting
// various other errors. If <name> is non-NULL, the font is renamed
// to <name>. If <codeToGID> is non-NULL, the font is re-encoded,
// using a Windows Unicode cmap. If <name> is NULL and the font is
// complete and correct, it will be written unmodified.
void writeTTF(FoFiOutputFunc outputFunc, void *outputStream,
char *name = NULL, Gushort *codeToGID = NULL);
private:
void cvtEncoding(const char **encoding,
FoFiOutputFunc outputFunc,
void *outputStream);
void cvtCharStrings(const char **encoding,
Gushort *codeToGID,
FoFiOutputFunc outputFunc,
void *outputStream);
void cvtSfnts(FoFiOutputFunc outputFunc,
void *outputStream, GString *name,
GBool needVerticalMetrics);
void dumpString(Guchar *s, int length,
FoFiOutputFunc outputFunc,
void *outputStream);
Guint computeTableChecksum(Guchar *data, int length);
void parse();
void readPostTable();
int seekTable(const char *tag);
TrueTypeTable *tables;
int nTables;
TrueTypeCmap *cmaps;
int nCmaps;
int nGlyphs;
int locaFmt;
int bbox[4];
GHash *nameToGID;
GBool parsedOk;
int faceIndex;
};
#endif

View File

@ -1,208 +0,0 @@
//========================================================================
//
// 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((void*)name);
}
if (encoding && encoding != fofiType1StandardEncoding) {
for (i = 0; i < 256; ++i) {
gfree((void*)encoding[i]);
}
gfree(encoding);
}
}
const char *FoFiType1::getName() {
if (!parsed) {
parse();
}
return name;
}
const 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) {
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 = (const char **)gmallocn(256, sizeof(char *));
for (j = 0; j < 256; ++j) {
encoding[j] = NULL;
}
for (j = 0, line = getNextLine(line);
j < 300 && line && (line1 = getNextLine(line));
++j, line = line1) {
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;
}
}
}
//~ check for getinterval/putinterval junk
} else {
line = getNextLine(line);
}
}
parsed = gTrue;
}

View File

@ -1,59 +0,0 @@
//========================================================================
//
// 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.
const char *getName();
// Return the encoding, as an array of 256 names (any of which may
// be NULL).
const 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();
const char *name;
const char **encoding;
GBool parsed;
};
#endif

File diff suppressed because it is too large Load Diff

View File

@ -1,232 +0,0 @@
//========================================================================
//
// 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];
GBool hasFontMatrix; // CID fonts are allowed to put their
// FontMatrix in the FD instead of the
// top dict
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 {
double fontMatrix[6];
GBool hasFontMatrix;
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);
FoFiType1C(char *fileA, int lenA, GBool freeFileDataA);
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.
const 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(const 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:
void eexecCvtGlyph(Type1CEexecBuf *eb, const 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, const 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;
const 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
GBool openPath; // true if there is an unclosed path
};
#endif

View File

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

View File

@ -1,380 +0,0 @@
//========================================================================
//
// GHash.cc
//
// Copyright 2001-2003 Glyph & Cog, LLC
//
//========================================================================
#include <aconf.h>
#ifdef USE_GCC_PRAGMAS
#pragma implementation
#endif
#include "gmem.h"
#include "GString.h"
#include "GHash.h"
//------------------------------------------------------------------------
struct GHashBucket {
GString *key;
union {
void *p;
int i;
} val;
GHashBucket *next;
};
struct GHashIter {
int h;
GHashBucket *p;
};
//------------------------------------------------------------------------
GHash::GHash(GBool deleteKeysA) {
int h;
deleteKeys = deleteKeysA;
size = 7;
tab = (GHashBucket **)gmallocn(size, sizeof(GHashBucket *));
for (h = 0; h < size; ++h) {
tab[h] = NULL;
}
len = 0;
}
GHash::~GHash() {
GHashBucket *p;
int h;
for (h = 0; h < size; ++h) {
while (tab[h]) {
p = tab[h];
tab[h] = p->next;
if (deleteKeys) {
delete p->key;
}
delete p;
}
}
gfree(tab);
}
void GHash::add(GString *key, void *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.p = val;
h = hash(key);
p->next = tab[h];
tab[h] = p;
++len;
}
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::replace(GString *key, void *val) {
GHashBucket *p;
int h;
if ((p = find(key, &h))) {
p->val.p = val;
delete key;
} else {
add(key, val);
}
}
void GHash::replace(GString *key, int val) {
GHashBucket *p;
int h;
if ((p = find(key, &h))) {
p->val.i = val;
delete key;
} else {
add(key, val);
}
}
void *GHash::lookup(GString *key) {
GHashBucket *p;
int h;
if (!(p = find(key, &h))) {
return NULL;
}
return p->val.p;
}
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.p;
}
int GHash::lookupInt(const 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;
int h;
if (!(p = find(key, &h))) {
return NULL;
}
q = &tab[h];
while (*q != p) {
q = &((*q)->next);
}
*q = p->next;
if (deleteKeys) {
delete p->key;
}
val = p->val.p;
delete p;
--len;
return val;
}
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;
int h;
if (!(p = find(key, &h))) {
return NULL;
}
q = &tab[h];
while (*q != p) {
q = &((*q)->next);
}
*q = p->next;
if (deleteKeys) {
delete p->key;
}
val = p->val.p;
delete p;
--len;
return val;
}
int GHash::removeInt(const 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;
}
void GHash::startIter(GHashIter **iter) {
*iter = new GHashIter;
(*iter)->h = -1;
(*iter)->p = NULL;
}
GBool GHash::getNext(GHashIter **iter, GString **key, void **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.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;
}
void GHash::killIter(GHashIter **iter) {
delete *iter;
*iter = NULL;
}
void GHash::expand() {
GHashBucket **oldTab;
GHashBucket *p;
int oldSize, h, i;
oldSize = size;
oldTab = tab;
size = 2*size + 1;
tab = (GHashBucket **)gmallocn(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);
for (p = tab[*h]; p; p = p->next) {
if (!p->key->cmp(key)) {
return p;
}
}
return NULL;
}
GHashBucket *GHash::find(const char *key, int *h) {
GHashBucket *p;
*h = hash(key);
for (p = tab[*h]; p; p = p->next) {
if (!p->key->cmp(key)) {
return p;
}
}
return NULL;
}
int GHash::hash(GString *key) {
char *p;
unsigned int h;
int i;
h = 0;
for (p = key->getCString(), i = 0; i < key->getLength(); ++p, ++i) {
h = 17 * h + (int)(*p & 0xff);
}
return (int)(h % size);
}
int GHash::hash(const char *key) {
const char *p;
unsigned int h;
h = 0;
for (p = key; *p; ++p) {
h = 17 * h + (int)(*p & 0xff);
}
return (int)(h % size);
}

View File

@ -1,78 +0,0 @@
//========================================================================
//
// GHash.h
//
// Copyright 2001-2003 Glyph & Cog, LLC
//
//========================================================================
#ifndef GHASH_H
#define GHASH_H
#include <aconf.h>
#ifdef USE_GCC_PRAGMAS
#pragma interface
#endif
#include "gtypes.h"
class GString;
struct GHashBucket;
struct GHashIter;
//------------------------------------------------------------------------
class GHash {
public:
GHash(GBool deleteKeysA = gFalse);
~GHash();
void add(GString *key, void *val);
void add(GString *key, int val);
void replace(GString *key, void *val);
void replace(GString *key, int val);
void *lookup(GString *key);
int lookupInt(GString *key);
void *lookup(char *key);
int lookupInt(const char *key);
void *remove(GString *key);
int removeInt(GString *key);
void *remove(char *key);
int removeInt(const char *key);
int getLength() { return len; }
void startIter(GHashIter **iter);
GBool getNext(GHashIter **iter, GString **key, void **val);
GBool getNext(GHashIter **iter, GString **key, int *val);
void killIter(GHashIter **iter);
private:
void expand();
GHashBucket *find(GString *key, int *h);
GHashBucket *find(const char *key, int *h);
int hash(GString *key);
int hash(const char *key);
GBool deleteKeys; // set if key strings should be deleted
int size; // number of buckets
int len; // number of entries
GHashBucket **tab;
};
#define deleteGHash(hash, T) \
do { \
GHash *_hash = (hash); \
{ \
GHashIter *_iter; \
GString *_key; \
void *_p; \
_hash->startIter(&_iter); \
while (_hash->getNext(&_iter, &_key, &_p)) { \
delete (T*)_p; \
} \
delete _hash; \
} \
} while(0)
#endif

View File

@ -1,97 +0,0 @@
//========================================================================
//
// GList.cc
//
// Copyright 2001-2003 Glyph & Cog, LLC
//
//========================================================================
#include <aconf.h>
#ifdef USE_GCC_PRAGMAS
#pragma implementation
#endif
#include <stdlib.h>
#include <string.h>
#include "gmem.h"
#include "GList.h"
//------------------------------------------------------------------------
// GList
//------------------------------------------------------------------------
GList::GList() {
size = 8;
data = (void **)gmallocn(size, sizeof(void*));
length = 0;
inc = 0;
}
GList::GList(int sizeA) {
size = sizeA;
data = (void **)gmallocn(size, sizeof(void*));
length = 0;
inc = 0;
}
GList::~GList() {
gfree(data);
}
void GList::append(void *p) {
if (length >= size) {
expand();
}
data[length++] = p;
}
void GList::append(GList *list) {
int i;
while (length + list->length > size) {
expand();
}
for (i = 0; i < list->length; ++i) {
data[length++] = list->data[i];
}
}
void GList::insert(int i, void *p) {
if (length >= size) {
expand();
}
if (i < length) {
memmove(data+i+1, data+i, (length - i) * sizeof(void *));
}
data[i] = p;
++length;
}
void *GList::del(int i) {
void *p;
p = data[i];
if (i < length - 1) {
memmove(data+i, data+i+1, (length - i - 1) * sizeof(void *));
}
--length;
if (size - length >= ((inc > 0) ? inc : size/2)) {
shrink();
}
return p;
}
void GList::sort(int (*cmp)(const void *obj1, const void *obj2)) {
qsort(data, length, sizeof(void *), cmp);
}
void GList::expand() {
size += (inc > 0) ? inc : size;
data = (void **)greallocn(data, size, sizeof(void*));
}
void GList::shrink() {
size -= (inc > 0) ? inc : size/2;
data = (void **)greallocn(data, size, sizeof(void*));
}

View File

@ -1,96 +0,0 @@
//========================================================================
//
// GList.h
//
// Copyright 2001-2003 Glyph & Cog, LLC
//
//========================================================================
#ifndef GLIST_H
#define GLIST_H
#include <aconf.h>
#ifdef USE_GCC_PRAGMAS
#pragma interface
#endif
#include "gtypes.h"
//------------------------------------------------------------------------
// GList
//------------------------------------------------------------------------
class GList {
public:
// Create an empty list.
GList();
// Create an empty list with space for <size1> elements.
GList(int sizeA);
// Destructor - does not free pointed-to objects.
~GList();
//----- general
// Get the number of elements.
int getLength() { return length; }
//----- ordered list support
// Return the <i>th element.
// Assumes 0 <= i < length.
void *get(int i) { return data[i]; }
// Append an element to the end of the list.
void append(void *p);
// Append another list to the end of this one.
void append(GList *list);
// Insert an element at index <i>.
// Assumes 0 <= i <= length.
void insert(int i, void *p);
// Deletes and returns the element at index <i>.
// Assumes 0 <= i < length.
void *del(int i);
// Sort the list accoring to the given comparison function.
// NB: this sorts an array of pointers, so the pointer args need to
// be double-dereferenced.
void sort(int (*cmp)(const void *ptr1, const void *ptr2));
//----- control
// Set allocation increment to <inc>. If inc > 0, that many
// elements will be allocated every time the list is expanded.
// If inc <= 0, the list will be doubled in size.
void setAllocIncr(int incA) { inc = incA; }
private:
void expand();
void shrink();
void **data; // the list elements
int size; // size of data array
int length; // number of elements on list
int inc; // allocation increment
};
#define deleteGList(list, T) \
do { \
GList *_list = (list); \
{ \
int _i; \
for (_i = 0; _i < _list->getLength(); ++_i) { \
delete (T*)_list->get(_i); \
} \
delete _list; \
} \
} while (0)
#endif

View File

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

View File

@ -1,319 +0,0 @@
//========================================================================
//
// GString.cc
//
// Simple variable-length string type.
//
// Copyright 1996-2003 Glyph & Cog, LLC
//
//========================================================================
#include <aconf.h>
#ifdef USE_GCC_PRAGMAS
#pragma implementation
#endif
#include <stdlib.h>
#include <stddef.h>
#include <string.h>
#include <ctype.h>
#include "gtypes.h"
#include "GString.h"
static inline int size(int len) {
int delta;
delta = len < 256 ? 7 : 255;
return ((len + 1) + delta) & ~delta;
}
inline void GString::resize(int length1) {
char *s1;
if (!s) {
s = new char[size(length1)];
} else if (size(length1) != size(length)) {
s1 = new char[size(length1)];
if (length1 < length) {
memcpy(s1, s, length1);
s1[length1] = '\0';
} else {
memcpy(s1, s, length + 1);
}
delete[] s;
s = s1;
}
}
GString::GString() {
s = NULL;
resize(length = 0);
s[0] = '\0';
}
GString::GString(const char *sA) {
int n = strlen(sA);
s = NULL;
resize(length = n);
memcpy(s, sA, n + 1);
}
GString::GString(const char *sA, int lengthA) {
s = NULL;
resize(length = lengthA);
memcpy(s, sA, length * sizeof(char));
s[length] = '\0';
}
GString::GString(GString *str, int idx, int lengthA) {
s = NULL;
resize(length = lengthA);
memcpy(s, str->getCString() + idx, length);
s[length] = '\0';
}
GString::GString(GString *str) {
s = NULL;
resize(length = str->getLength());
memcpy(s, str->getCString(), length + 1);
}
GString::GString(GString *str1, GString *str2) {
int n1 = str1->getLength();
int n2 = str2->getLength();
s = NULL;
resize(length = n1 + n2);
memcpy(s, str1->getCString(), n1);
memcpy(s + n1, str2->getCString(), n2 + 1);
}
GString *GString::fromInt(int x) {
char buf[24]; // enough space for 64-bit ints plus a little extra
GBool neg;
Guint y;
int i;
i = 24;
if (x == 0) {
buf[--i] = '0';
} else {
if ((neg = x < 0)) {
y = (Guint)-x;
} else {
y = (Guint)x;
}
while (i > 0 && y > 0) {
buf[--i] = '0' + y % 10;
y /= 10;
}
if (neg && i > 0) {
buf[--i] = '-';
}
}
return new GString(buf + i, 24 - i);
}
GString::~GString() {
delete[] s;
}
GString *GString::clear() {
s[length = 0] = '\0';
resize(0);
return this;
}
GString *GString::append(char c) {
resize(length + 1);
s[length++] = c;
s[length] = '\0';
return this;
}
GString *GString::append(GString *str) {
int n = str->getLength();
resize(length + n);
memcpy(s + length, str->getCString(), n + 1);
length += n;
return this;
}
GString *GString::append(const char *str) {
int n = strlen(str);
resize(length + n);
memcpy(s + length, str, n + 1);
length += n;
return this;
}
GString *GString::append(const char *str, int lengthA) {
resize(length + lengthA);
memcpy(s + length, str, lengthA);
length += lengthA;
s[length] = '\0';
return this;
}
GString *GString::insert(int i, char c) {
int j;
resize(length + 1);
for (j = length + 1; j > i; --j)
s[j] = s[j-1];
s[i] = c;
++length;
return this;
}
GString *GString::insert(int i, GString *str) {
int n = str->getLength();
int j;
resize(length + n);
for (j = length; j >= i; --j)
s[j+n] = s[j];
memcpy(s+i, str->getCString(), n);
length += n;
return this;
}
GString *GString::insert(int i, const char *str) {
int n = strlen(str);
int j;
resize(length + n);
for (j = length; j >= i; --j)
s[j+n] = s[j];
memcpy(s+i, str, n);
length += n;
return this;
}
GString *GString::insert(int i, const char *str, int lengthA) {
int j;
resize(length + lengthA);
for (j = length; j >= i; --j)
s[j+lengthA] = s[j];
memcpy(s+i, str, lengthA);
length += lengthA;
return this;
}
GString *GString::del(int i, int n) {
int j;
if (n > 0) {
if (i + n > length) {
n = length - i;
}
for (j = i; j <= length - n; ++j) {
s[j] = s[j + n];
}
resize(length -= n);
}
return this;
}
GString *GString::upperCase() {
int i;
for (i = 0; i < length; ++i) {
if (islower(s[i]))
s[i] = toupper(s[i]);
}
return this;
}
GString *GString::lowerCase() {
int i;
for (i = 0; i < length; ++i) {
if (isupper(s[i]))
s[i] = tolower(s[i]);
}
return this;
}
int GString::cmp(GString *str) {
int n1, n2, i, x;
char *p1, *p2;
n1 = length;
n2 = str->length;
for (i = 0, p1 = s, p2 = str->s; i < n1 && i < n2; ++i, ++p1, ++p2) {
x = *p1 - *p2;
if (x != 0) {
return x;
}
}
return n1 - n2;
}
int GString::cmpN(GString *str, int n) {
int n1, n2, i, x;
char *p1, *p2;
n1 = length;
n2 = str->length;
for (i = 0, p1 = s, p2 = str->s;
i < n1 && i < n2 && i < n;
++i, ++p1, ++p2) {
x = *p1 - *p2;
if (x != 0) {
return x;
}
}
if (i == n) {
return 0;
}
return n1 - n2;
}
int GString::cmp(const char *sA) {
int n1, i, x;
const char *p1, *p2;
n1 = length;
for (i = 0, p1 = s, p2 = sA; i < n1 && *p2; ++i, ++p1, ++p2) {
x = *p1 - *p2;
if (x != 0) {
return x;
}
}
if (i < n1) {
return 1;
}
if (*p2) {
return -1;
}
return 0;
}
int GString::cmpN(const char *sA, int n) {
int n1, i, x;
const char *p1, *p2;
n1 = length;
for (i = 0, p1 = s, p2 = sA; i < n1 && *p2 && i < n; ++i, ++p1, ++p2) {
x = *p1 - *p2;
if (x != 0) {
return x;
}
}
if (i == n) {
return 0;
}
if (i < n1) {
return 1;
}
if (*p2) {
return -1;
}
return 0;
}

View File

@ -1,97 +0,0 @@
//========================================================================
//
// GString.h
//
// Simple variable-length string type.
//
// Copyright 1996-2003 Glyph & Cog, LLC
//
//========================================================================
#ifndef GSTRING_H
#define GSTRING_H
#include <aconf.h>
#ifdef USE_GCC_PRAGMAS
#pragma interface
#endif
class GString {
public:
// Create an empty string.
GString();
// Create a string from a C string.
GString(const char *sA);
// Create a string from <lengthA> chars at <sA>. This string
// can contain null characters.
GString(const char *sA, int lengthA);
// Create a string from <lengthA> chars at <idx> in <str>.
GString(GString *str, int idx, int lengthA);
// Copy a string.
GString(GString *str);
GString *copy() { return new GString(this); }
// Concatenate two strings.
GString(GString *str1, GString *str2);
// Convert an integer to a string.
static GString *fromInt(int x);
// Destructor.
~GString();
// Get length.
int getLength() { return length; }
// Get C string.
char *getCString() { return s; }
// Get <i>th character.
char getChar(int i) { return s[i]; }
// Change <i>th character.
void setChar(int i, char c) { s[i] = c; }
// Clear string to zero length.
GString *clear();
// Append a character or string.
GString *append(char c);
GString *append(GString *str);
GString *append(const char *str);
GString *append(const char *str, int lengthA);
// Insert a character or string.
GString *insert(int i, char c);
GString *insert(int i, GString *str);
GString *insert(int i, const char *str);
GString *insert(int i, const char *str, int lengthA);
// Delete a character or range of characters.
GString *del(int i, int n = 1);
// Convert string to all-upper/all-lower case.
GString *upperCase();
GString *lowerCase();
// Compare two strings: -1:< 0:= +1:>
int cmp(GString *str);
int cmpN(GString *str, int n);
int cmp(const char *sA);
int cmpN(const char *sA, int n);
private:
int length;
char *s;
void resize(int length1);
};
#endif

View File

@ -1,5 +0,0 @@
INCLUDES = -I$(srcdir)/..
libgoo_la_SOURCES = GHash.cc GList.cc GString.cc gfile.cc gmem.c gmempp.cc
noinst_LTLIBRARIES = libgoo.la

View File

@ -1,706 +0,0 @@
//========================================================================
//
// gfile.cc
//
// Miscellaneous file and directory name manipulation.
//
// Copyright 1996-2003 Glyph & Cog, LLC
//
//========================================================================
#include <aconf.h>
#ifndef WIN32
# if defined(MACOS)
# include <sys/stat.h>
# elif !defined(ACORN)
# include <sys/types.h>
# include <sys/stat.h>
# include <fcntl.h>
# endif
# include <limits.h>
# include <string.h>
# if !defined(VMS) && !defined(ACORN) && !defined(MACOS)
# include <pwd.h>
# endif
# if defined(VMS) && (__DECCXX_VER < 50200000)
# include <unixlib.h>
# endif
#endif // WIN32
#include "GString.h"
#include "gfile.h"
#include "config.h"
// Some systems don't define this, so just make it something reasonably
// large.
#ifndef PATH_MAX
#define PATH_MAX 1024
#endif
//------------------------------------------------------------------------
GString *getHomeDir() {
#ifdef VMS
//---------- VMS ----------
return new GString("SYS$LOGIN:");
#elif defined(__EMX__) || defined(WIN32)
//---------- OS/2+EMX and Win32 ----------
char *s;
GString *ret;
if ((s = getenv("HOME")))
ret = new GString(s);
else
ret = new GString(".");
return ret;
#elif defined(ACORN)
//---------- RISCOS ----------
return new GString("@");
#elif defined(MACOS)
//---------- MacOS ----------
return new GString(":");
#else
//---------- Unix ----------
char *s;
struct passwd *pw;
GString *ret;
if ((s = getenv("HOME"))) {
ret = new GString(s);
} else {
if ((s = getenv("USER")))
pw = getpwnam(s);
else
pw = getpwuid(getuid());
if (pw)
ret = new GString(pw->pw_dir);
else
ret = new GString(".");
}
return ret;
#endif
}
GString *getCurrentDir() {
char buf[PATH_MAX+1];
#if defined(__EMX__)
if (_getcwd2(buf, sizeof(buf)))
#elif defined(WIN32)
if (GetCurrentDirectory(sizeof(buf), buf))
#elif defined(ACORN)
if (strcpy(buf, "@"))
#elif defined(MACOS)
if (strcpy(buf, ":"))
#else
if (getcwd(buf, sizeof(buf)))
#endif
return new GString(buf);
return new GString();
}
GString *appendToPath(GString *path, const char *fileName) {
#if defined(VMS)
//---------- VMS ----------
//~ this should handle everything necessary for file
//~ requesters, but it's certainly not complete
char *p0, *p1, *p2;
char *q1;
p0 = path->getCString();
p1 = p0 + path->getLength() - 1;
if (!strcmp(fileName, "-")) {
if (*p1 == ']') {
for (p2 = p1; p2 > p0 && *p2 != '.' && *p2 != '['; --p2) ;
if (*p2 == '[')
++p2;
path->del(p2 - p0, p1 - p2);
} else if (*p1 == ':') {
path->append("[-]");
} else {
path->clear();
path->append("[-]");
}
} else if ((q1 = strrchr(fileName, '.')) && !strncmp(q1, ".DIR;", 5)) {
if (*p1 == ']') {
path->insert(p1 - p0, '.');
path->insert(p1 - p0 + 1, fileName, q1 - fileName);
} else if (*p1 == ':') {
path->append('[');
path->append(']');
path->append(fileName, q1 - fileName);
} else {
path->clear();
path->append(fileName, q1 - fileName);
}
} else {
if (*p1 != ']' && *p1 != ':')
path->clear();
path->append(fileName);
}
return path;
#elif defined(WIN32)
//---------- Win32 ----------
GString *tmp;
char buf[256];
char *fp;
tmp = new GString(path);
tmp->append('/');
tmp->append(fileName);
GetFullPathName(tmp->getCString(), sizeof(buf), buf, &fp);
delete tmp;
path->clear();
path->append(buf);
return path;
#elif defined(ACORN)
//---------- RISCOS ----------
char *p;
int i;
path->append(".");
i = path->getLength();
path->append(fileName);
for (p = path->getCString() + i; *p; ++p) {
if (*p == '/') {
*p = '.';
} else if (*p == '.') {
*p = '/';
}
}
return path;
#elif defined(MACOS)
//---------- MacOS ----------
char *p;
int i;
path->append(":");
i = path->getLength();
path->append(fileName);
for (p = path->getCString() + i; *p; ++p) {
if (*p == '/') {
*p = ':';
} else if (*p == '.') {
*p = ':';
}
}
return path;
#elif defined(__EMX__)
//---------- OS/2+EMX ----------
int i;
// appending "." does nothing
if (!strcmp(fileName, "."))
return path;
// appending ".." goes up one directory
if (!strcmp(fileName, "..")) {
for (i = path->getLength() - 2; i >= 0; --i) {
if (path->getChar(i) == '/' || path->getChar(i) == '\\' ||
path->getChar(i) == ':')
break;
}
if (i <= 0) {
if (path->getChar(0) == '/' || path->getChar(0) == '\\') {
path->del(1, path->getLength() - 1);
} else if (path->getLength() >= 2 && path->getChar(1) == ':') {
path->del(2, path->getLength() - 2);
} else {
path->clear();
path->append("..");
}
} else {
if (path->getChar(i-1) == ':')
++i;
path->del(i, path->getLength() - i);
}
return path;
}
// otherwise, append "/" and new path component
if (path->getLength() > 0 &&
path->getChar(path->getLength() - 1) != '/' &&
path->getChar(path->getLength() - 1) != '\\')
path->append('/');
path->append(fileName);
return path;
#else
//---------- Unix ----------
int i;
// appending "." does nothing
if (!strcmp(fileName, "."))
return path;
// appending ".." goes up one directory
if (!strcmp(fileName, "..")) {
for (i = path->getLength() - 2; i >= 0; --i) {
if (path->getChar(i) == '/')
break;
}
if (i <= 0) {
if (path->getChar(0) == '/') {
path->del(1, path->getLength() - 1);
} else {
path->clear();
path->append("..");
}
} else {
path->del(i, path->getLength() - i);
}
return path;
}
// otherwise, append "/" and new path component
if (path->getLength() > 0 &&
path->getChar(path->getLength() - 1) != '/')
path->append('/');
path->append(fileName);
return path;
#endif
}
GString *grabPath(char *fileName) {
#ifdef VMS
//---------- VMS ----------
char *p;
if ((p = strrchr(fileName, ']')))
return new GString(fileName, p + 1 - fileName);
if ((p = strrchr(fileName, ':')))
return new GString(fileName, p + 1 - fileName);
return new GString();
#elif defined(__EMX__) || defined(WIN32)
//---------- OS/2+EMX and Win32 ----------
char *p;
if ((p = strrchr(fileName, '/')))
return new GString(fileName, p - fileName);
if ((p = strrchr(fileName, '\\')))
return new GString(fileName, p - fileName);
if ((p = strrchr(fileName, ':')))
return new GString(fileName, p + 1 - fileName);
return new GString();
#elif defined(ACORN)
//---------- RISCOS ----------
char *p;
if ((p = strrchr(fileName, '.')))
return new GString(fileName, p - fileName);
return new GString();
#elif defined(MACOS)
//---------- MacOS ----------
char *p;
if ((p = strrchr(fileName, ':')))
return new GString(fileName, p - fileName);
return new GString();
#else
//---------- Unix ----------
char *p;
if ((p = strrchr(fileName, '/')))
return new GString(fileName, p - fileName);
return new GString();
#endif
}
GBool isAbsolutePath(char *path) {
#ifdef VMS
//---------- VMS ----------
return strchr(path, ':') ||
(path[0] == '[' && path[1] != '.' && path[1] != '-');
#elif defined(__EMX__) || defined(WIN32)
//---------- OS/2+EMX and Win32 ----------
return path[0] == '/' || path[0] == '\\' || path[1] == ':';
#elif defined(ACORN)
//---------- RISCOS ----------
return path[0] == '$';
#elif defined(MACOS)
//---------- MacOS ----------
return path[0] != ':';
#else
//---------- Unix ----------
return path[0] == '/';
#endif
}
GString *makePathAbsolute(GString *path) {
#ifdef VMS
//---------- VMS ----------
char buf[PATH_MAX+1];
if (!isAbsolutePath(path->getCString())) {
if (getcwd(buf, sizeof(buf))) {
path->insert(0, buf);
}
}
return path;
#elif defined(WIN32)
//---------- Win32 ----------
char buf[_MAX_PATH];
char *fp;
buf[0] = '\0';
if (!GetFullPathName(path->getCString(), _MAX_PATH, buf, &fp)) {
path->clear();
return path;
}
path->clear();
path->append(buf);
return path;
#elif defined(ACORN)
//---------- RISCOS ----------
path->insert(0, '@');
return path;
#elif defined(MACOS)
//---------- MacOS ----------
path->del(0, 1);
return path;
#else
//---------- Unix and OS/2+EMX ----------
struct passwd *pw;
char buf[PATH_MAX+1];
GString *s;
char *p1, *p2;
int n;
if (path->getChar(0) == '~') {
if (path->getChar(1) == '/' ||
#ifdef __EMX__
path->getChar(1) == '\\' ||
#endif
path->getLength() == 1) {
path->del(0, 1);
s = getHomeDir();
path->insert(0, s);
delete s;
} else {
p1 = path->getCString() + 1;
#ifdef __EMX__
for (p2 = p1; *p2 && *p2 != '/' && *p2 != '\\'; ++p2) ;
#else
for (p2 = p1; *p2 && *p2 != '/'; ++p2) ;
#endif
if ((n = p2 - p1) > PATH_MAX)
n = PATH_MAX;
strncpy(buf, p1, n);
buf[n] = '\0';
if ((pw = getpwnam(buf))) {
path->del(0, p2 - p1 + 1);
path->insert(0, pw->pw_dir);
}
}
} else if (!isAbsolutePath(path->getCString())) {
if (getcwd(buf, sizeof(buf))) {
#ifndef __EMX__
path->insert(0, '/');
#endif
path->insert(0, buf);
}
}
return path;
#endif
}
time_t getModTime(char *fileName) {
#ifdef WIN32
//~ should implement this, but it's (currently) only used in xpdf
return 0;
#else
struct stat statBuf;
if (stat(fileName, &statBuf)) {
return 0;
}
return statBuf.st_mtime;
#endif
}
GBool openTempFile(GString **name, FILE **f, const char *mode, char *ext) {
#if defined(WIN32)
//---------- Win32 ----------
char *s;
if (!(s = _tempnam(getenv("TEMP"), NULL))) {
return gFalse;
}
*name = new GString(s);
free(s);
if (ext) {
(*name)->append(ext);
}
if (!(*f = fopen((*name)->getCString(), mode))) {
delete (*name);
return gFalse;
}
return gTrue;
#elif defined(VMS) || defined(__EMX__) || defined(ACORN) || defined(MACOS)
//---------- non-Unix ----------
char *s;
// There is a security hole here: an attacker can create a symlink
// with this file name after the tmpnam call and before the fopen
// call. I will happily accept fixes to this function for non-Unix
// OSs.
if (!(s = tmpnam(NULL))) {
return gFalse;
}
*name = new GString(s);
if (ext) {
(*name)->append(ext);
}
if (!(*f = fopen((*name)->getCString(), mode))) {
delete (*name);
return gFalse;
}
return gTrue;
#else
//---------- Unix ----------
char *s;
int fd;
if (ext) {
#ifdef HAVE_MKSTEMPS
if ((s = getenv("TMPDIR"))) {
*name = new GString(s);
} else {
*name = new GString("/tmp");
}
(*name)->append("/XXXXXX")->append(ext);
fd = mkstemps((*name)->getCString(), strlen(ext));
#else
if (!(s = tmpnam(NULL))) {
return gFalse;
}
*name = new GString(s);
(*name)->append(ext);
fd = open((*name)->getCString(), O_WRONLY | O_CREAT | O_EXCL, 0600);
#endif
} else {
#ifdef HAVE_MKSTEMP
if ((s = getenv("TMPDIR"))) {
*name = new GString(s);
} else {
*name = new GString("/tmp");
}
(*name)->append("/XXXXXX");
fd = mkstemp((*name)->getCString());
#else // HAVE_MKSTEMP
if (!(s = tmpnam(NULL))) {
return gFalse;
}
*name = new GString(s);
fd = open((*name)->getCString(), O_WRONLY | O_CREAT | O_EXCL, 0600);
#endif // HAVE_MKSTEMP
}
if (fd < 0 || !(*f = fdopen(fd, mode))) {
delete *name;
return gFalse;
}
return gTrue;
#endif
}
GBool executeCommand(char *cmd) {
#ifdef VMS
return system(cmd) ? gTrue : gFalse;
#else
return system(cmd) ? gFalse : gTrue;
#endif
}
char *getLine(char *buf, int size, FILE *f) {
int c, i;
i = 0;
while (i < size - 1) {
if ((c = fgetc(f)) == EOF) {
break;
}
buf[i++] = (char)c;
if (c == '\x0a') {
break;
}
if (c == '\x0d') {
c = fgetc(f);
if (c == '\x0a' && i < size - 1) {
buf[i++] = (char)c;
} else if (c != EOF) {
ungetc(c, f);
}
break;
}
}
buf[i] = '\0';
if (i == 0) {
return NULL;
}
return buf;
}
//------------------------------------------------------------------------
// GDir and GDirEntry
//------------------------------------------------------------------------
GDirEntry::GDirEntry(char *dirPath, char *nameA, GBool doStat) {
#ifdef VMS
char *p;
#elif defined(WIN32)
int fa;
GString *s;
#elif defined(ACORN)
#else
struct stat st;
GString *s;
#endif
name = new GString(nameA);
dir = gFalse;
if (doStat) {
#ifdef VMS
if (!strcmp(nameA, "-") ||
((p = strrchr(nameA, '.')) && !strncmp(p, ".DIR;", 5)))
dir = gTrue;
#elif defined(ACORN)
#else
s = new GString(dirPath);
appendToPath(s, nameA);
#ifdef WIN32
fa = GetFileAttributes(s->getCString());
dir = (fa != 0xFFFFFFFF && (fa & FILE_ATTRIBUTE_DIRECTORY));
#else
if (stat(s->getCString(), &st) == 0)
dir = S_ISDIR(st.st_mode);
#endif
delete s;
#endif
}
}
GDirEntry::~GDirEntry() {
delete name;
}
GDir::GDir(char *name, GBool doStatA) {
path = new GString(name);
doStat = doStatA;
#if defined(WIN32)
GString *tmp;
tmp = path->copy();
tmp->append("/*.*");
hnd = FindFirstFile(tmp->getCString(), &ffd);
delete tmp;
#elif defined(ACORN)
#elif defined(MACOS)
#else
dir = opendir(name);
#ifdef VMS
needParent = strchr(name, '[') != NULL;
#endif
#endif
}
GDir::~GDir() {
delete path;
#if defined(WIN32)
if (hnd) {
FindClose(hnd);
hnd = NULL;
}
#elif defined(ACORN)
#elif defined(MACOS)
#else
if (dir)
closedir(dir);
#endif
}
GDirEntry *GDir::getNextEntry() {
GDirEntry *e;
#if defined(WIN32)
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)
#elif defined(VMS)
struct dirent *ent;
e = NULL;
if (dir) {
if (needParent) {
e = new GDirEntry(path->getCString(), "-", doStat);
needParent = gFalse;
return e;
}
ent = readdir(dir);
if (ent) {
e = new GDirEntry(path->getCString(), ent->d_name, doStat);
}
}
#else
struct dirent *ent;
e = NULL;
if (dir) {
ent = readdir(dir);
if (ent && !strcmp(ent->d_name, ".")) {
ent = readdir(dir);
}
if (ent) {
e = new GDirEntry(path->getCString(), ent->d_name, doStat);
}
}
#endif
return e;
}
void GDir::rewind() {
#ifdef WIN32
GString *tmp;
if (hnd)
FindClose(hnd);
tmp = path->copy();
tmp->append("/*.*");
hnd = FindFirstFile(tmp->getCString(), &ffd);
delete tmp;
#elif defined(ACORN)
#elif defined(MACOS)
#else
if (dir)
rewinddir(dir);
#ifdef VMS
needParent = strchr(path->getCString(), '[') != NULL;
#endif
#endif
}

View File

@ -1,138 +0,0 @@
//========================================================================
//
// gfile.h
//
// Miscellaneous file and directory name manipulation.
//
// Copyright 1996-2003 Glyph & Cog, LLC
//
//========================================================================
#ifndef GFILE_H
#define GFILE_H
#include <stdio.h>
#include <stdlib.h>
#include <stddef.h>
#if defined(WIN32)
# include <sys/stat.h>
# ifdef FPTEX
# include <win32lib.h>
# else
# include <windows.h>
# endif
#elif defined(ACORN)
#elif defined(MACOS)
# include <ctime.h>
#else
# include <unistd.h>
# include <sys/types.h>
# ifdef VMS
# include "vms_dirent.h"
# elif HAVE_DIRENT_H
# include <dirent.h>
# define NAMLEN(d) strlen((d)->d_name)
# else
# define dirent direct
# define NAMLEN(d) (d)->d_namlen
# if HAVE_SYS_NDIR_H
# include <sys/ndir.h>
# endif
# if HAVE_SYS_DIR_H
# include <sys/dir.h>
# endif
# if HAVE_NDIR_H
# include <ndir.h>
# endif
# endif
#endif
#include "gtypes.h"
class GString;
//------------------------------------------------------------------------
// Get home directory path.
extern GString *getHomeDir();
// Get current directory.
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);
// Grab the path from the front of the file name. If there is no
// directory component in <fileName>, returns an empty string.
extern GString *grabPath(char *fileName);
// Is this an absolute path or file name?
extern GBool isAbsolutePath(char *path);
// Make this path absolute by prepending current directory (if path is
// relative) or prepending user's directory (if path starts with '~').
extern GString *makePathAbsolute(GString *path);
// Get the modification time for <fileName>. Returns 0 if there is an
// error.
extern time_t getModTime(char *fileName);
// Create a temporary file and open it for writing. If <ext> is not
// NULL, it will be used as the file name extension. Returns both the
// name and the file pointer. For security reasons, all writing
// should be done to the returned file pointer; the file may be
// reopened later for reading, but not for writing. The <mode> string
// should be "w" or "wb". Returns true on success.
extern GBool openTempFile(GString **name, FILE **f, const char *mode, char *ext);
// Execute <command>. Returns true on success.
extern GBool executeCommand(char *cmd);
// Just like fgets, but handles Unix, Mac, and/or DOS end-of-line
// conventions.
extern char *getLine(char *buf, int size, FILE *f);
//------------------------------------------------------------------------
// GDir and GDirEntry
//------------------------------------------------------------------------
class GDirEntry {
public:
GDirEntry(char *dirPath, char *nameA, GBool doStat);
~GDirEntry();
GString *getName() { return name; }
GBool isDir() { return dir; }
private:
GString *name; // dir/file name
GBool dir; // is it a directory?
};
class GDir {
public:
GDir(char *name, GBool doStatA = gTrue);
~GDir();
GDirEntry *getNextEntry();
void rewind();
private:
GString *path; // directory path
GBool doStat; // call stat() for each entry?
#if defined(WIN32)
WIN32_FIND_DATA ffd;
HANDLE hnd;
#elif defined(ACORN)
#elif defined(MACOS)
#else
DIR *dir; // the DIR structure from opendir()
#ifdef VMS
GBool needParent; // need to return an entry for [-]
#endif
#endif
};
#endif

View File

@ -1,229 +0,0 @@
/*
* gmem.c
*
* Memory routines with out-of-memory checking.
*
* Copyright 1996-2003 Glyph & Cog, LLC
*/
#include <aconf.h>
#include <stdio.h>
#include <stdlib.h>
#include <stddef.h>
#include <string.h>
#include "gmem.h"
#ifdef DEBUG_MEM
typedef struct _GMemHdr {
int size;
int index;
struct _GMemHdr *next;
} GMemHdr;
#define gMemHdrSize ((sizeof(GMemHdr) + 7) & ~7)
#define gMemTrlSize (sizeof(long))
#if gmemTrlSize==8
#define gMemDeadVal 0xdeadbeefdeadbeefUL
#else
#define gMemDeadVal 0xdeadbeefUL
#endif
/* round data size so trailer will be aligned */
#define gMemDataSize(size) \
((((size) + gMemTrlSize - 1) / gMemTrlSize) * gMemTrlSize)
#define gMemNLists 64
#define gMemListShift 4
#define gMemListMask (gMemNLists - 1)
static GMemHdr *gMemList[gMemNLists] = {
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, 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
};
static int gMemIndex = 0;
static int gMemAlloc = 0;
static int gMemInUse = 0;
#endif /* DEBUG_MEM */
void *gmalloc(size_t size) {
#ifdef DEBUG_MEM
size_t size1;
char *mem;
GMemHdr *hdr;
void *data;
int lst;
unsigned long *trl, *p;
if (size == 0)
return NULL;
size1 = gMemDataSize(size);
if (!(mem = (char *)malloc(size1 + gMemHdrSize + gMemTrlSize))) {
fprintf(stderr, "Out of memory\n");
exit(1);
}
hdr = (GMemHdr *)mem;
data = (void *)(mem + gMemHdrSize);
trl = (unsigned long *)(mem + gMemHdrSize + size1);
hdr->size = size;
hdr->index = gMemIndex++;
lst = ((int)hdr >> gMemListShift) & gMemListMask;
hdr->next = gMemList[lst];
gMemList[lst] = hdr;
++gMemAlloc;
gMemInUse += size;
for (p = (unsigned long *)data; p <= trl; ++p)
*p = gMemDeadVal;
return data;
#else
void *p;
if (size == 0)
return NULL;
if (!(p = malloc(size))) {
fprintf(stderr, "Out of memory\n");
exit(1);
}
return p;
#endif
}
void *grealloc(void *p, size_t size) {
#ifdef DEBUG_MEM
GMemHdr *hdr;
void *q;
size_t oldSize;
if (size == 0) {
if (p)
gfree(p);
return NULL;
}
if (p) {
hdr = (GMemHdr *)((char *)p - gMemHdrSize);
oldSize = hdr->size;
q = gmalloc(size);
memcpy(q, p, size < oldSize ? size : oldSize);
gfree(p);
} else {
q = gmalloc(size);
}
return q;
#else
void *q;
if (size == 0) {
if (p)
free(p);
return NULL;
}
if (p)
q = realloc(p, size);
else
q = malloc(size);
if (!q) {
fprintf(stderr, "Out of memory\n");
exit(1);
}
return q;
#endif
}
void *gmallocn(int nObjs, int objSize) {
int n;
n = nObjs * objSize;
if (objSize == 0 || n / objSize != nObjs) {
fprintf(stderr, "Bogus memory allocation size\n");
exit(1);
}
return gmalloc(n);
}
void *greallocn(void *p, int nObjs, int objSize) {
int n;
n = nObjs * objSize;
if (objSize == 0 || n / objSize != nObjs) {
fprintf(stderr, "Bogus memory allocation size\n");
exit(1);
}
return grealloc(p, n);
}
void gfree(void *p) {
#ifdef DEBUG_MEM
size_t size;
GMemHdr *hdr;
GMemHdr *prevHdr, *q;
int lst;
unsigned long *trl, *clr;
if (p) {
hdr = (GMemHdr *)((char *)p - gMemHdrSize);
lst = ((int)hdr >> gMemListShift) & gMemListMask;
for (prevHdr = NULL, q = gMemList[lst]; q; prevHdr = q, q = q->next) {
if (q == hdr)
break;
}
if (q) {
if (prevHdr)
prevHdr->next = hdr->next;
else
gMemList[lst] = hdr->next;
--gMemAlloc;
gMemInUse -= hdr->size;
size = gMemDataSize(hdr->size);
trl = (unsigned long *)((char *)hdr + gMemHdrSize + size);
if (*trl != gMemDeadVal) {
fprintf(stderr, "Overwrite past end of block %d at address %p\n",
hdr->index, p);
}
for (clr = (unsigned long *)hdr; clr <= trl; ++clr)
*clr = gMemDeadVal;
free(hdr);
} else {
fprintf(stderr, "Attempted to free bad address %p\n", p);
}
}
#else
if (p)
free(p);
#endif
}
#ifdef DEBUG_MEM
void gMemReport(FILE *f) {
GMemHdr *p;
int lst;
fprintf(f, "%d memory allocations in all\n", gMemIndex);
if (gMemAlloc > 0) {
fprintf(f, "%d memory blocks left allocated:\n", gMemAlloc);
fprintf(f, " index size\n");
fprintf(f, "-------- --------\n");
for (lst = 0; lst < gMemNLists; ++lst) {
for (p = gMemList[lst]; p; p = p->next)
fprintf(f, "%8d %8d\n", p->index, p->size);
}
} else {
fprintf(f, "No memory blocks left allocated\n");
}
}
#endif
const char *copyString(const char *s) {
char *s1;
s1 = (char *)gmalloc(strlen(s) + 1);
strcpy(s1, s);
return s1;
}

View File

@ -1,62 +0,0 @@
/*
* gmem.h
*
* Memory routines with out-of-memory checking.
*
* Copyright 1996-2003 Glyph & Cog, LLC
*/
#ifndef GMEM_H
#define GMEM_H
#include <stdio.h>
#ifdef __cplusplus
extern "C" {
#endif
/*
* Same as malloc, but prints error message and exits if malloc()
* returns NULL.
*/
extern void *gmalloc(size_t size);
/*
* Same as realloc, but prints error message and exits if realloc()
* returns NULL. If <p> is NULL, calls malloc instead of realloc().
*/
extern void *grealloc(void *p, size_t size);
/*
* These are similar to gmalloc and grealloc, but take an object count
* and size. The result is similar to allocating nObjs * objSize
* bytes, but there is an additional error check that the total size
* doesn't overflow an int.
*/
extern void *gmallocn(int nObjs, int objSize);
extern void *greallocn(void *p, int nObjs, int objSize);
/*
* Same as free, but checks for and ignores NULL pointers.
*/
extern void gfree(void *p);
#ifdef DEBUG_MEM
/*
* Report on unfreed memory.
*/
extern void gMemReport(FILE *f);
#else
#define gMemReport(f)
#endif
/*
* Allocate memory and copy a string into it.
*/
extern const char *copyString(const char *s);
#ifdef __cplusplus
}
#endif
#endif

View File

@ -1,32 +0,0 @@
//========================================================================
//
// gmempp.cc
//
// Use gmalloc/gfree for C++ new/delete operators.
//
// Copyright 1996-2003 Glyph & Cog, LLC
//
//========================================================================
#include <aconf.h>
#include "gmem.h"
#ifdef DEBUG_MEM
void *operator new(size_t size) {
return gmalloc((int)size);
}
void *operator new[](size_t size) {
return gmalloc((int)size);
}
void operator delete(void *p) {
gfree(p);
}
void operator delete[](void *p) {
gfree(p);
}
#endif

View File

@ -1,29 +0,0 @@
/*
* gtypes.h
*
* Some useful simple types.
*
* Copyright 1996-2003 Glyph & Cog, LLC
*/
#ifndef GTYPES_H
#define GTYPES_H
/*
* These have stupid names to avoid conflicts with some (but not all)
* C++ compilers which define them.
*/
typedef int GBool;
#define gTrue 1
#define gFalse 0
/*
* These have stupid names to avoid conflicts with <sys/types.h>,
* which on various systems defines some random subset of these.
*/
typedef unsigned char Guchar;
typedef unsigned short Gushort;
typedef unsigned int Guint;
typedef unsigned long Gulong;
#endif

View File

@ -1,8 +0,0 @@
INCLUDES = -I$(srcdir)/.. -I$(srcdir)/../fofi -I$(srcdir)/../goo $(LIBFREETYPE_CFLAGS) $(USER_INCLUDES)
libsplash_la_SOURCES = Splash.cc SplashBitmap.cc SplashClip.cc SplashFTFont.cc SplashFTFontEngine.cc \
SplashFTFontFile.cc SplashFont.cc SplashFontEngine.cc SplashFontFile.cc SplashFontFileID.cc \
SplashPath.cc SplashPattern.cc SplashScreen.cc SplashState.cc SplashT1Font.cc \
SplashT1FontEngine.cc SplashT1FontFile.cc SplashXPath.cc SplashXPathScanner.cc
noinst_LTLIBRARIES = libsplash.la

File diff suppressed because it is too large Load Diff

View File

@ -1,204 +0,0 @@
//========================================================================
//
// Splash.h
//
//========================================================================
#ifndef SPLASH_H
#define SPLASH_H
#include <aconf.h>
#ifdef USE_GCC_PRAGMAS
#pragma interface
#endif
#include "SplashTypes.h"
#include "SplashClip.h"
class SplashBitmap;
struct SplashGlyphBitmap;
class SplashState;
class SplashPattern;
class SplashScreen;
class SplashPath;
class SplashXPath;
class SplashFont;
//------------------------------------------------------------------------
// Retrieves the next line of pixels in an image mask. Normally,
// fills in *<line> and returns true. If the image stream is
// exhausted, returns false.
typedef GBool (*SplashImageMaskSource)(void *data, SplashColorPtr pixel);
// Retrieves the next line of pixels in an image. Normally, fills in
// *<line> and returns true. If the image stream is exhausted,
// returns false.
typedef GBool (*SplashImageSource)(void *data, SplashColorPtr line);
//------------------------------------------------------------------------
// Splash
//------------------------------------------------------------------------
class Splash {
public:
// Create a new rasterizer object.
Splash(SplashBitmap *bitmapA);
~Splash();
//----- state read
SplashPattern *getStrokePattern();
SplashPattern *getFillPattern();
SplashScreen *getScreen();
SplashBlendFunc getBlendFunc();
SplashCoord getStrokeAlpha();
SplashCoord getFillAlpha();
SplashCoord getLineWidth();
int getLineCap();
int getLineJoin();
SplashCoord getMiterLimit();
SplashCoord getFlatness();
SplashCoord *getLineDash();
int getLineDashLength();
SplashCoord getLineDashPhase();
SplashClip *getClip();
//----- state write
void setStrokePattern(SplashPattern *strokeColor);
void setFillPattern(SplashPattern *fillColor);
void setScreen(SplashScreen *screen);
void setBlendFunc(SplashBlendFunc func);
void setStrokeAlpha(SplashCoord alpha);
void setFillAlpha(SplashCoord alpha);
void setLineWidth(SplashCoord lineWidth);
void setLineCap(int lineCap);
void setLineJoin(int lineJoin);
void setMiterLimit(SplashCoord miterLimit);
void setFlatness(SplashCoord flatness);
// the <lineDash> array will be copied
void setLineDash(SplashCoord *lineDash, int lineDashLength,
SplashCoord lineDashPhase);
void clipResetToRect(SplashCoord x0, SplashCoord y0,
SplashCoord x1, SplashCoord y1);
SplashError clipToRect(SplashCoord x0, SplashCoord y0,
SplashCoord x1, SplashCoord y1);
SplashError clipToPath(SplashPath *path, GBool eo);
//----- state save/restore
void saveState();
SplashError restoreState();
//----- soft mask
void setSoftMask(SplashBitmap *softMaskA);
//----- drawing operations
// Fill the bitmap with <color>. This is not subject to clipping.
void clear(SplashColorPtr color);
// Stroke a path using the current stroke pattern.
SplashError stroke(SplashPath *path);
// Fill a path using the current fill pattern.
SplashError fill(SplashPath *path, GBool eo);
// Fill a path, XORing with the current fill pattern.
SplashError xorFill(SplashPath *path, GBool eo);
// Draw a character, using the current fill pattern.
SplashError fillChar(SplashCoord x, SplashCoord y, int c, SplashFont *font);
// Draw a glyph, using the current fill pattern. This function does
// not free any data, i.e., it ignores glyph->freeData.
SplashError fillGlyph(SplashCoord x, SplashCoord y,
SplashGlyphBitmap *glyph);
// Draws an image mask using the fill color. This will read <h>
// lines of <w> pixels from <src>, starting with the top line. "1"
// pixels will be drawn with the current fill color; "0" pixels are
// transparent. The matrix:
// [ mat[0] mat[1] 0 ]
// [ mat[2] mat[3] 0 ]
// [ mat[4] mat[5] 1 ]
// maps a unit square to the desired destination for the image, in
// PostScript style:
// [x' y' 1] = [x y 1] * mat
// Note that the Splash y axis points downward, and the image source
// is assumed to produce pixels in raster order, starting from the
// top line.
SplashError fillImageMask(SplashImageMaskSource src, void *srcData,
int w, int h, SplashCoord *mat);
// Draw an image. This will read <h> lines of <w> pixels from
// <src>, starting with the top line. These pixels are assumed to
// be in the source mode, <srcMode>. The following combinations of
// source and target modes are supported:
// source target
// ------ ------
// Mono1 Mono1
// Mono8 Mono1 -- with dithering
// Mono8 Mono8
// RGB8 RGB8
// BGR8 BGR8
// ARGB8 RGB8 -- with source alpha (masking)
// BGRA8 BGR8 -- with source alpha (masking)
// The matrix behaves as for fillImageMask.
SplashError drawImage(SplashImageSource src, void *srcData,
SplashColorMode srcMode,
int w, int h, SplashCoord *mat);
//----- misc
// Return the associated bitmap.
SplashBitmap *getBitmap() { return bitmap; }
// Get a bounding box which includes all modifications since the
// last call to clearModRegion.
void getModRegion(int *xMin, int *yMin, int *xMax, int *yMax)
{ *xMin = modXMin; *yMin = modYMin; *xMax = modXMax; *yMax = modYMax; }
// Clear the modified region bounding box.
void clearModRegion();
// Get clipping status for the last drawing operation subject to
// clipping.
SplashClipResult getClipRes() { return opClipRes; }
// Toggle debug mode on or off.
void setDebugMode(GBool debugModeA) { debugMode = debugModeA; }
private:
void updateModX(int x);
void updateModY(int y);
void strokeNarrow(SplashXPath *xPath);
void strokeWide(SplashXPath *xPath);
SplashXPath *makeDashedPath(SplashXPath *xPath);
SplashError fillWithPattern(SplashPath *path, GBool eo,
SplashPattern *pattern, SplashCoord alpha);
void drawPixel(int x, int y, SplashColorPtr color,
SplashCoord alpha, GBool noClip);
void drawPixel(int x, int y, SplashPattern *pattern,
SplashCoord alpha, GBool noClip);
void drawSpan(int x0, int x1, int y, SplashPattern *pattern,
SplashCoord alpha, GBool noClip);
void xorSpan(int x0, int x1, int y, SplashPattern *pattern, GBool noClip);
void dumpPath(SplashPath *path);
void dumpXPath(SplashXPath *path);
SplashBitmap *bitmap;
SplashState *state;
SplashBitmap *softMask;
int modXMin, modYMin, modXMax, modYMax;
SplashClipResult opClipRes;
GBool debugMode;
};
#endif

View File

@ -1,243 +0,0 @@
//========================================================================
//
// SplashBitmap.cc
//
//========================================================================
#include <aconf.h>
#ifdef USE_GCC_PRAGMAS
#pragma implementation
#endif
#include <stdio.h>
#include "gmem.h"
#include "SplashErrorCodes.h"
#include "SplashBitmap.h"
//------------------------------------------------------------------------
// SplashBitmap
//------------------------------------------------------------------------
SplashBitmap::SplashBitmap(int widthA, int heightA, int rowPad,
SplashColorMode modeA, GBool topDown) {
width = widthA;
height = heightA;
mode = modeA;
switch (mode) {
case splashModeMono1:
rowSize = (width + 7) >> 3;
break;
case splashModeMono8:
rowSize = width;
break;
case splashModeAMono8:
rowSize = width * 2;
break;
case splashModeRGB8:
case splashModeBGR8:
rowSize = width * 3;
break;
case splashModeARGB8:
case splashModeBGRA8:
#if SPLASH_CMYK
case splashModeCMYK8:
#endif
rowSize = width * 4;
break;
#if SPLASH_CMYK
case splashModeACMYK8:
rowSize = width * 5;
break;
#endif
}
rowSize += rowPad - 1;
rowSize -= rowSize % rowPad;
data = (SplashColorPtr)gmalloc(rowSize * height);
if (!topDown) {
data += (height - 1) * rowSize;
rowSize = -rowSize;
}
}
SplashBitmap::~SplashBitmap() {
if (rowSize < 0) {
gfree(data + (height - 1) * rowSize);
} else {
gfree(data);
}
}
SplashError SplashBitmap::writePNMFile(char *fileName) {
FILE *f;
SplashColorPtr row, p;
int x, y;
if (!(f = fopen(fileName, "wb"))) {
return splashErrOpenFile;
}
switch (mode) {
case splashModeMono1:
fprintf(f, "P4\n%d %d\n", width, height);
row = data;
for (y = 0; y < height; ++y) {
p = row;
for (x = 0; x < width; x += 8) {
fputc(*p ^ 0xff, f);
++p;
}
row += rowSize;
}
break;
case splashModeMono8:
fprintf(f, "P5\n%d %d\n255\n", width, height);
row = data;
for (y = 0; y < height; ++y) {
p = row;
for (x = 0; x < width; ++x) {
fputc(*p, f);
++p;
}
row += rowSize;
}
break;
case splashModeAMono8:
fprintf(f, "P5\n%d %d\n255\n", width, height);
row = data;
for (y = 0; y < height; ++y) {
p = row;
for (x = 0; x < width; ++x) {
fputc(splashAMono8M(p), f);
p += 2;
}
row += rowSize;
}
break;
case splashModeRGB8:
fprintf(f, "P6\n%d %d\n255\n", width, height);
row = data;
for (y = 0; y < height; ++y) {
p = row;
for (x = 0; x < width; ++x) {
fputc(splashRGB8R(p), f);
fputc(splashRGB8G(p), f);
fputc(splashRGB8B(p), f);
p += 3;
}
row += rowSize;
}
break;
case splashModeBGR8:
fprintf(f, "P6\n%d %d\n255\n", width, height);
row = data;
for (y = 0; y < height; ++y) {
p = row;
for (x = 0; x < width; ++x) {
fputc(splashBGR8R(p), f);
fputc(splashBGR8G(p), f);
fputc(splashBGR8B(p), f);
p += 3;
}
row += rowSize;
}
break;
case splashModeARGB8:
fprintf(f, "P6\n%d %d\n255\n", width, height);
row = data;
for (y = 0; y < height; ++y) {
p = row;
for (x = 0; x < width; ++x) {
fputc(splashARGB8R(p), f);
fputc(splashARGB8G(p), f);
fputc(splashARGB8B(p), f);
p += 4;
}
row += rowSize;
}
break;
case splashModeBGRA8:
fprintf(f, "P6\n%d %d\n255\n", width, height);
row = data;
for (y = 0; y < height; ++y) {
p = row;
for (x = 0; x < width; ++x) {
fputc(splashBGRA8R(p), f);
fputc(splashBGRA8G(p), f);
fputc(splashBGRA8B(p), f);
p += 4;
}
row += rowSize;
}
break;
#if SPLASH_CMYK
case splashModeCMYK8:
case splashModeACMYK8:
// PNM doesn't support CMYK
break;
#endif
}
fclose(f);
return splashOk;
}
void SplashBitmap::getPixel(int x, int y, SplashColorPtr pixel) {
SplashColorPtr p;
if (y < 0 || y >= height || x < 0 || x >= width) {
return;
}
switch (mode) {
case splashModeMono1:
p = &data[y * rowSize + (x >> 3)];
pixel[0] = (p[0] >> (7 - (x & 7))) & 1;
break;
case splashModeMono8:
p = &data[y * rowSize + x];
pixel[0] = p[0];
break;
case splashModeAMono8:
p = &data[y * rowSize + 2 * x];
pixel[0] = p[0];
pixel[1] = p[1];
break;
case splashModeRGB8:
case splashModeBGR8:
p = &data[y * rowSize + 3 * x];
pixel[0] = p[0];
pixel[1] = p[1];
pixel[2] = p[2];
break;
case splashModeARGB8:
case splashModeBGRA8:
#if SPLASH_CMYK
case splashModeCMYK8:
#endif
p = &data[y * rowSize + 4 * x];
pixel[0] = p[0];
pixel[1] = p[1];
pixel[2] = p[2];
pixel[3] = p[3];
break;
#if SPLASH_CMYK
case splashModeACMYK8:
p = &data[y * rowSize + 5 * x];
pixel[0] = p[0];
pixel[1] = p[1];
pixel[2] = p[2];
pixel[3] = p[3];
pixel[4] = p[4];
break;
#endif
}
}

View File

@ -1,55 +0,0 @@
//========================================================================
//
// SplashBitmap.h
//
//========================================================================
#ifndef SPLASHBITMAP_H
#define SPLASHBITMAP_H
#include <aconf.h>
#ifdef USE_GCC_PRAGMAS
#pragma interface
#endif
#include "SplashTypes.h"
//------------------------------------------------------------------------
// SplashBitmap
//------------------------------------------------------------------------
class SplashBitmap {
public:
// Create a new bitmap. It will have <widthA> x <heightA> pixels in
// color mode <modeA>. Rows will be padded out to a multiple of
// <rowPad> bytes. If <topDown> is false, the bitmap will be stored
// upside-down, i.e., with the last row first in memory.
SplashBitmap(int widthA, int heightA, int rowPad,
SplashColorMode modeA, GBool topDown = gTrue);
~SplashBitmap();
int getWidth() { return width; }
int getHeight() { return height; }
int getRowSize() { return rowSize; }
SplashColorMode getMode() { return mode; }
SplashColorPtr getDataPtr() { return data; }
SplashError writePNMFile(char *fileName);
void getPixel(int x, int y, SplashColorPtr pixel);
private:
int width, height; // size of bitmap
int rowSize; // size of one row of data, in bytes
// - negative for bottom-up bitmaps
SplashColorMode mode; // color mode
SplashColorPtr data; // pointer to row zero of the bitmap data
friend class Splash;
};
#endif

View File

@ -1,270 +0,0 @@
//========================================================================
//
// SplashClip.cc
//
//========================================================================
#include <aconf.h>
#ifdef USE_GCC_PRAGMAS
#pragma implementation
#endif
#include <stdlib.h>
#include <string.h>
#include "gmem.h"
#include "SplashErrorCodes.h"
#include "SplashMath.h"
#include "SplashPath.h"
#include "SplashXPath.h"
#include "SplashXPathScanner.h"
#include "SplashClip.h"
//------------------------------------------------------------------------
// SplashClip.flags
//------------------------------------------------------------------------
#define splashClipEO 0x01 // use even-odd rule
//------------------------------------------------------------------------
// SplashClip
//------------------------------------------------------------------------
SplashClip::SplashClip(SplashCoord x0, SplashCoord y0,
SplashCoord x1, SplashCoord y1) {
if (x0 < x1) {
xMin = splashFloor(x0);
xMax = splashFloor(x1);
} else {
xMin = splashFloor(x1);
xMax = splashFloor(x0);
}
if (y0 < y1) {
yMin = splashFloor(y0);
yMax = splashFloor(y1);
} else {
yMin = splashFloor(y1);
yMax = splashFloor(y0);
}
paths = NULL;
flags = NULL;
scanners = NULL;
length = size = 0;
}
SplashClip::SplashClip(SplashClip *clip) {
int i;
xMin = clip->xMin;
yMin = clip->yMin;
xMax = clip->xMax;
yMax = clip->yMax;
length = clip->length;
size = clip->size;
paths = (SplashXPath **)gmallocn(size, sizeof(SplashXPath *));
flags = (Guchar *)gmallocn(size, sizeof(Guchar));
scanners = (SplashXPathScanner **)
gmallocn(size, sizeof(SplashXPathScanner *));
for (i = 0; i < length; ++i) {
paths[i] = clip->paths[i]->copy();
flags[i] = clip->flags[i];
scanners[i] = new SplashXPathScanner(paths[i], flags[i] & splashClipEO);
}
}
SplashClip::~SplashClip() {
int i;
for (i = 0; i < length; ++i) {
delete paths[i];
delete scanners[i];
}
gfree(paths);
gfree(flags);
gfree(scanners);
}
void SplashClip::grow(int nPaths) {
if (length + nPaths > size) {
if (size == 0) {
size = 32;
}
while (size < length + nPaths) {
size *= 2;
}
paths = (SplashXPath **)greallocn(paths, size, sizeof(SplashXPath *));
flags = (Guchar *)greallocn(flags, size, sizeof(Guchar));
scanners = (SplashXPathScanner **)
greallocn(scanners, size, sizeof(SplashXPathScanner *));
}
}
void SplashClip::resetToRect(SplashCoord x0, SplashCoord y0,
SplashCoord x1, SplashCoord y1) {
int i;
for (i = 0; i < length; ++i) {
delete paths[i];
delete scanners[i];
}
gfree(paths);
gfree(flags);
gfree(scanners);
paths = NULL;
flags = NULL;
scanners = NULL;
length = size = 0;
if (x0 < x1) {
xMin = splashFloor(x0);
xMax = splashFloor(x1);
} else {
xMin = splashFloor(x1);
xMax = splashFloor(x0);
}
if (y0 < y1) {
yMin = splashFloor(y0);
yMax = splashFloor(y1);
} else {
yMin = splashFloor(y1);
yMax = splashFloor(y0);
}
}
SplashError SplashClip::clipToRect(SplashCoord x0, SplashCoord y0,
SplashCoord x1, SplashCoord y1) {
int x0I, y0I, x1I, y1I;
if (x0 < x1) {
x0I = splashFloor(x0);
x1I = splashFloor(x1);
} else {
x0I = splashFloor(x1);
x1I = splashFloor(x0);
}
if (x0I > xMin) {
xMin = x0I;
}
if (x1I < xMax) {
xMax = x1I;
}
if (y0 < y1) {
y0I = splashFloor(y0);
y1I = splashFloor(y1);
} else {
y0I = splashFloor(y1);
y1I = splashFloor(y0);
}
if (y0I > yMin) {
yMin = y0I;
}
if (y1I < yMax) {
yMax = y1I;
}
return splashOk;
}
SplashError SplashClip::clipToPath(SplashPath *path, SplashCoord flatness,
GBool eo) {
SplashXPath *xPath;
xPath = new SplashXPath(path, flatness, gTrue);
// check for an empty path
if (xPath->length == 0) {
xMax = xMin - 1;
yMax = yMin - 1;
delete xPath;
// check for a rectangle
} else if (xPath->length == 4 &&
((xPath->segs[0].x0 == xPath->segs[0].x1 &&
xPath->segs[0].x0 == xPath->segs[1].x0 &&
xPath->segs[0].x0 == xPath->segs[3].x1 &&
xPath->segs[2].x0 == xPath->segs[2].x1 &&
xPath->segs[2].x0 == xPath->segs[1].x1 &&
xPath->segs[2].x0 == xPath->segs[3].x0 &&
xPath->segs[1].y0 == xPath->segs[1].y1 &&
xPath->segs[1].y0 == xPath->segs[0].y1 &&
xPath->segs[1].y0 == xPath->segs[2].y0 &&
xPath->segs[3].y0 == xPath->segs[3].y1 &&
xPath->segs[3].y0 == xPath->segs[0].y0 &&
xPath->segs[3].y0 == xPath->segs[2].y1) ||
(xPath->segs[0].y0 == xPath->segs[0].y1 &&
xPath->segs[0].y0 == xPath->segs[1].y0 &&
xPath->segs[0].y0 == xPath->segs[3].y1 &&
xPath->segs[2].y0 == xPath->segs[2].y1 &&
xPath->segs[2].y0 == xPath->segs[1].y1 &&
xPath->segs[2].y0 == xPath->segs[3].y0 &&
xPath->segs[1].x0 == xPath->segs[1].x1 &&
xPath->segs[1].x0 == xPath->segs[0].x1 &&
xPath->segs[1].x0 == xPath->segs[2].x0 &&
xPath->segs[3].x0 == xPath->segs[3].x1 &&
xPath->segs[3].x0 == xPath->segs[0].x0 &&
xPath->segs[3].x0 == xPath->segs[2].x1))) {
clipToRect(xPath->segs[0].x0, xPath->segs[0].y0,
xPath->segs[2].x0, xPath->segs[2].y0);
delete xPath;
} else {
grow(1);
xPath->sort();
paths[length] = xPath;
flags[length] = eo ? splashClipEO : 0;
scanners[length] = new SplashXPathScanner(xPath, eo);
++length;
}
return splashOk;
}
GBool SplashClip::test(int x, int y) {
int i;
// check the rectangle
if (x < xMin || x > xMax || y < yMin || y > yMax) {
return gFalse;
}
// check the paths
for (i = 0; i < length; ++i) {
if (!scanners[i]->test(x, y)) {
return gFalse;
}
}
return gTrue;
}
SplashClipResult SplashClip::testRect(int rectXMin, int rectYMin,
int rectXMax, int rectYMax) {
if (rectXMax < xMin || rectXMin > xMax ||
rectYMax < yMin || rectYMin > yMax) {
return splashClipAllOutside;
}
if (rectXMin >= xMin && rectXMax <= xMax &&
rectYMin >= yMin && rectYMax <= yMax &&
length == 0) {
return splashClipAllInside;
}
return splashClipPartial;
}
SplashClipResult SplashClip::testSpan(int spanXMin, int spanXMax, int spanY) {
int i;
if (spanXMax < xMin || spanXMin > xMax ||
spanY < yMin || spanY > yMax) {
return splashClipAllOutside;
}
if (!(spanXMin >= xMin && spanXMax <= xMax &&
spanY >= yMin && spanY <= yMax)) {
return splashClipPartial;
}
for (i = 0; i < length; ++i) {
if (!scanners[i]->testSpan(xMin, xMax, spanY)) {
return splashClipPartial;
}
}
return splashClipAllInside;
}

View File

@ -1,97 +0,0 @@
//========================================================================
//
// SplashClip.h
//
//========================================================================
#ifndef SPLASHCLIP_H
#define SPLASHCLIP_H
#include <aconf.h>
#ifdef USE_GCC_PRAGMAS
#pragma interface
#endif
#include "SplashTypes.h"
class SplashPath;
class SplashXPath;
class SplashXPathScanner;
//------------------------------------------------------------------------
enum SplashClipResult {
splashClipAllInside,
splashClipAllOutside,
splashClipPartial
};
//------------------------------------------------------------------------
// SplashClip
//------------------------------------------------------------------------
class SplashClip {
public:
// Create a clip, for the given rectangle.
SplashClip(SplashCoord x0, SplashCoord y0,
SplashCoord x1, SplashCoord y1);
// Copy a clip.
SplashClip *copy() { return new SplashClip(this); }
~SplashClip();
// Reset the clip to a rectangle.
void resetToRect(SplashCoord x0, SplashCoord y0,
SplashCoord x1, SplashCoord y1);
// Intersect the clip with a rectangle.
SplashError clipToRect(SplashCoord x0, SplashCoord y0,
SplashCoord x1, SplashCoord y1);
// Interesect the clip with <path>.
SplashError clipToPath(SplashPath *path, SplashCoord flatness,
GBool eo);
// Returns true if (<x>,<y>) is inside the clip.
GBool test(int x, int y);
// Tests a rectangle against the clipping region. Returns one of:
// - splashClipAllInside if the entire rectangle is inside the
// clipping region, i.e., all pixels in the rectangle are
// visible
// - splashClipAllOutside if the entire rectangle is outside the
// clipping region, i.e., all the pixels in the rectangle are
// clipped
// - splashClipPartial if the rectangle is part inside and part
// outside the clipping region
SplashClipResult testRect(int rectXMin, int rectYMin,
int rectXMax, int rectYMax);
// Similar to testRect, but tests a horizontal span.
SplashClipResult testSpan(int spanXMin, int spanXMax, int spanY);
// Get the rectangle part of the clip region.
int getXMin() { return xMin; }
int getXMax() { return xMax; }
int getYMin() { return yMin; }
int getYMax() { return yMax; }
// Get the number of arbitrary paths used by the clip region.
int getNumPaths() { return length; }
private:
SplashClip(SplashClip *clip);
void grow(int nPaths);
int xMin, yMin, xMax, yMax;
SplashXPath **paths;
Guchar *flags;
SplashXPathScanner **scanners;
int length, size;
};
#endif

View File

@ -1,32 +0,0 @@
//========================================================================
//
// SplashErrorCodes.h
//
//========================================================================
#ifndef SPLASHERRORCODES_H
#define SPLASHERRORCODES_H
#include <aconf.h>
//------------------------------------------------------------------------
#define splashOk 0 // no error
#define splashErrNoCurPt 1 // no current point
#define splashErrEmptyPath 2 // zero points in path
#define splashErrBogusPath 3 // only one point in subpath
#define splashErrNoSave 4 // state stack is empty
#define splashErrOpenFile 5 // couldn't open file
#define splashErrNoGlyph 6 // couldn't get the requested glyph
#define splashErrModeMismatch 7 // invalid combination of color modes
#define splashErrSingularMatrix 8 // matrix is singular
#endif

View File

@ -1,346 +0,0 @@
//========================================================================
//
// SplashFTFont.cc
//
//========================================================================
#include <aconf.h>
#if HAVE_FREETYPE_FREETYPE_H || HAVE_FREETYPE_H
#ifdef USE_GCC_PRAGMAS
#pragma implementation
#endif
#define MAKE_VERSION( a,b,c ) (((a) << 16) | ((b) << 8) | (c))
#define FREETYPE_VERSION \
MAKE_VERSION(FREETYPE_MAJOR,FREETYPE_MINOR,FREETYPE_PATCH)
#include <ft2build.h>
#include FT_OUTLINE_H
#include FT_SIZES_H
#include FT_GLYPH_H
#include "gmem.h"
#include "SplashMath.h"
#include "SplashGlyphBitmap.h"
#include "SplashPath.h"
#include "SplashFTFontEngine.h"
#include "SplashFTFontFile.h"
#include "SplashFTFont.h"
//------------------------------------------------------------------------
#if ( FREETYPE_VERSION >= MAKE_VERSION(2,2,0) )
static int glyphPathMoveTo(const FT_Vector *pt, void *path);
static int glyphPathLineTo(const FT_Vector *pt, void *path);
static int glyphPathConicTo(const FT_Vector *ctrl, const FT_Vector *pt, void *path);
static int glyphPathCubicTo(const FT_Vector *ctrl1, const FT_Vector *ctrl2,
const FT_Vector *pt, void *path);
#else
static int glyphPathMoveTo(FT_Vector *pt, void *path);
static int glyphPathLineTo(FT_Vector *pt, void *path);
static int glyphPathConicTo(FT_Vector *ctrl, FT_Vector *pt, void *path);
static int glyphPathCubicTo(FT_Vector *ctrl1, FT_Vector *ctrl2,
FT_Vector *pt, void *path);
#endif
//------------------------------------------------------------------------
// SplashFTFont
//------------------------------------------------------------------------
SplashFTFont::SplashFTFont(SplashFTFontFile *fontFileA, SplashCoord *matA):
SplashFont(fontFileA, matA, fontFileA->engine->aa)
{
FT_Face face;
SplashCoord size, div;
int x, y;
face = fontFileA->face;
if (FT_New_Size(face, &sizeObj)) {
return;
}
face->size = sizeObj;
size = splashSqrt(mat[2]*mat[2] + mat[3]*mat[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)((mat[0] * face->bbox.xMin + mat[2] * face->bbox.yMin) /
(div * face->units_per_EM));
xMin = xMax = x;
y = (int)((mat[1] * face->bbox.xMin + mat[3] * face->bbox.yMin) /
(div * face->units_per_EM));
yMin = yMax = y;
x = (int)((mat[0] * face->bbox.xMin + mat[2] * face->bbox.yMax) /
(div * face->units_per_EM));
if (x < xMin) {
xMin = x;
} else if (x > xMax) {
xMax = x;
}
y = (int)((mat[1] * face->bbox.xMin + mat[3] * face->bbox.yMax) /
(div * face->units_per_EM));
if (y < yMin) {
yMin = y;
} else if (y > yMax) {
yMax = y;
}
x = (int)((mat[0] * face->bbox.xMax + mat[2] * face->bbox.yMin) /
(div * face->units_per_EM));
if (x < xMin) {
xMin = x;
} else if (x > xMax) {
xMax = x;
}
y = (int)((mat[1] * face->bbox.xMax + mat[3] * face->bbox.yMin) /
(div * face->units_per_EM));
if (y < yMin) {
yMin = y;
} else if (y > yMax) {
yMax = y;
}
x = (int)((mat[0] * face->bbox.xMax + mat[2] * face->bbox.yMax) /
(div * face->units_per_EM));
if (x < xMin) {
xMin = x;
} else if (x > xMax) {
xMax = x;
}
y = (int)((mat[1] * face->bbox.xMax + mat[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)((SplashCoord)1.2 * size);
}
// compute the transform matrix
matrix.xx = (FT_Fixed)((mat[0] / size) * 65536);
matrix.yx = (FT_Fixed)((mat[1] / size) * 65536);
matrix.xy = (FT_Fixed)((mat[2] / size) * 65536);
matrix.yy = (FT_Fixed)((mat[3] / size) * 65536);
}
SplashFTFont::~SplashFTFont() {
}
GBool SplashFTFont::getGlyph(int c, int xFrac, int /*yFrac*/,
SplashGlyphBitmap *bitmap) {
return SplashFont::getGlyph(c, xFrac, 0, bitmap);
}
GBool SplashFTFont::makeGlyph(int c, int xFrac, int /*yFrac*/,
SplashGlyphBitmap *bitmap) {
SplashFTFontFile *ff;
FT_Vector offset;
FT_GlyphSlot slot;
FT_UInt gid;
int rowSize;
Guchar *p, *q;
int i;
ff = (SplashFTFontFile *)fontFile;
ff->face->size = sizeObj;
offset.x = (FT_Pos)(int)((SplashCoord)xFrac * splashFontFractionMul * 64);
offset.y = 0;
FT_Set_Transform(ff->face, &matrix, &offset);
slot = ff->face->glyph;
if (ff->codeToGID && c < ff->codeToGIDLen) {
gid = (FT_UInt)ff->codeToGID[c];
} else {
gid = (FT_UInt)c;
}
// if we have the FT2 bytecode interpreter, autohinting won't be used
#ifdef TT_CONFIG_OPTION_BYTECODE_INTERPRETER
if (FT_Load_Glyph(ff->face, gid,
aa ? FT_LOAD_NO_BITMAP : 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(ff->face, gid,
aa ? FT_LOAD_NO_HINTING | FT_LOAD_NO_BITMAP
: FT_LOAD_DEFAULT)) {
return gFalse;
}
#endif
if (FT_Render_Glyph(slot, aa ? ft_render_mode_normal
: ft_render_mode_mono)) {
return gFalse;
}
bitmap->x = -slot->bitmap_left;
bitmap->y = slot->bitmap_top;
bitmap->w = slot->bitmap.width;
bitmap->h = slot->bitmap.rows;
bitmap->aa = aa;
if (aa) {
rowSize = bitmap->w;
} else {
rowSize = (bitmap->w + 7) >> 3;
}
bitmap->data = (Guchar *)gmalloc(rowSize * bitmap->h);
bitmap->freeData = gTrue;
for (i = 0, p = bitmap->data, q = slot->bitmap.buffer;
i < bitmap->h;
++i, p += rowSize, q += slot->bitmap.pitch) {
memcpy(p, q, rowSize);
}
return gTrue;
}
struct SplashFTFontPath {
SplashPath *path;
GBool needClose;
};
SplashPath *SplashFTFont::getGlyphPath(int c) {
static FT_Outline_Funcs outlineFuncs = {
&glyphPathMoveTo,
&glyphPathLineTo,
&glyphPathConicTo,
&glyphPathCubicTo,
0, 0
};
SplashFTFontFile *ff;
SplashFTFontPath path;
FT_GlyphSlot slot;
FT_UInt gid;
FT_Glyph glyph;
ff = (SplashFTFontFile *)fontFile;
ff->face->size = sizeObj;
FT_Set_Transform(ff->face, &matrix, NULL);
slot = ff->face->glyph;
if (ff->codeToGID && c < ff->codeToGIDLen) {
gid = ff->codeToGID[c];
} else {
gid = (FT_UInt)c;
}
if (FT_Load_Glyph(ff->face, gid, FT_LOAD_NO_BITMAP)) {
return NULL;
}
if (FT_Get_Glyph(slot, &glyph)) {
return NULL;
}
path.path = new SplashPath();
path.needClose = gFalse;
FT_Outline_Decompose(&((FT_OutlineGlyph)glyph)->outline,
&outlineFuncs, &path);
if (path.needClose) {
path.path->close();
}
FT_Done_Glyph(glyph);
return path.path;
}
#if ( FREETYPE_VERSION >= MAKE_VERSION(2,2,0) )
static int glyphPathMoveTo(const FT_Vector *pt, void *path)
#else
static int glyphPathMoveTo(FT_Vector *pt, void *path)
#endif
{
SplashFTFontPath *p = (SplashFTFontPath *)path;
if (p->needClose) {
p->path->close();
p->needClose = gFalse;
}
p->path->moveTo(pt->x / 64.0, -pt->y / 64.0);
return 0;
}
#if ( FREETYPE_VERSION >= MAKE_VERSION(2,2,0) )
static int glyphPathLineTo(const FT_Vector *pt, void *path)
#else
static int glyphPathLineTo(FT_Vector *pt, void *path)
#endif
{
SplashFTFontPath *p = (SplashFTFontPath *)path;
p->path->lineTo(pt->x / 64.0, -pt->y / 64.0);
p->needClose = gTrue;
return 0;
}
#if ( FREETYPE_VERSION >= MAKE_VERSION(2,2,0) )
static int glyphPathConicTo(const FT_Vector *ctrl, const FT_Vector *pt, void *path)
#else
static int glyphPathConicTo(FT_Vector *ctrl, FT_Vector *pt, void *path)
#endif
{
SplashFTFontPath *p = (SplashFTFontPath *)path;
SplashCoord x0, y0, x1, y1, x2, y2, x3, y3, xc, yc;
if (!p->path->getCurPt(&x0, &y0)) {
return 0;
}
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 = (SplashCoord)(1.0 / 3.0) * (x0 + (SplashCoord)2 * xc);
y1 = (SplashCoord)(1.0 / 3.0) * (y0 + (SplashCoord)2 * yc);
x2 = (SplashCoord)(1.0 / 3.0) * ((SplashCoord)2 * xc + x3);
y2 = (SplashCoord)(1.0 / 3.0) * ((SplashCoord)2 * yc + y3);
p->path->curveTo(x1, y1, x2, y2, x3, y3);
p->needClose = gTrue;
return 0;
}
#if ( FREETYPE_VERSION >= MAKE_VERSION(2,2,0) )
static int glyphPathCubicTo(const FT_Vector *ctrl1, const FT_Vector *ctrl2, const FT_Vector *pt, void *path)
#else
static int glyphPathCubicTo(FT_Vector *ctrl1, FT_Vector *ctrl2, FT_Vector *pt, void *path)
#endif
{
SplashFTFontPath *p = (SplashFTFontPath *)path;
p->path->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);
p->needClose = gTrue;
return 0;
}
#endif // HAVE_FREETYPE_FREETYPE_H || HAVE_FREETYPE_H

View File

@ -1,55 +0,0 @@
//========================================================================
//
// SplashFTFont.h
//
//========================================================================
#ifndef SPLASHFTFONT_H
#define SPLASHFTFONT_H
#include <aconf.h>
#if HAVE_FREETYPE_FREETYPE_H || HAVE_FREETYPE_H
#ifdef USE_GCC_PRAGMAS
#pragma interface
#endif
#include <ft2build.h>
#include FT_FREETYPE_H
#include "SplashFont.h"
class SplashFTFontFile;
//------------------------------------------------------------------------
// SplashFTFont
//------------------------------------------------------------------------
class SplashFTFont: public SplashFont {
public:
SplashFTFont(SplashFTFontFile *fontFileA, SplashCoord *matA);
virtual ~SplashFTFont();
// Munge xFrac and yFrac before calling SplashFont::getGlyph.
virtual GBool getGlyph(int c, int xFrac, int yFrac,
SplashGlyphBitmap *bitmap);
// Rasterize a glyph. The <xFrac> and <yFrac> values are the same
// as described for getGlyph.
virtual GBool makeGlyph(int c, int xFrac, int yFrac,
SplashGlyphBitmap *bitmap);
// Return the path for a glyph.
virtual SplashPath *getGlyphPath(int c);
private:
FT_Size sizeObj;
FT_Matrix matrix;
};
#endif // HAVE_FREETYPE_FREETYPE_H || HAVE_FREETYPE_H
#endif

View File

@ -1,161 +0,0 @@
//========================================================================
//
// SplashFTFontEngine.cc
//
//========================================================================
#include <aconf.h>
#if HAVE_FREETYPE_FREETYPE_H || HAVE_FREETYPE_H
#ifdef USE_GCC_PRAGMAS
#pragma implementation
#endif
#include <stdio.h>
#ifndef WIN32
# include <unistd.h>
#endif
#include "gmem.h"
#include "GString.h"
#include "gfile.h"
#include "FoFiTrueType.h"
#include "FoFiType1C.h"
#include "SplashFTFontFile.h"
#include "SplashFTFontEngine.h"
#ifdef VMS
#if (__VMS_VER < 70000000)
extern "C" int unlink(char *filename);
#endif
#endif
//------------------------------------------------------------------------
#if 0
static void FT_fileWrite(void *stream, const char *data, int len) {
fwrite(data, 1, len, (FILE *)stream);
}
#endif
//------------------------------------------------------------------------
// SplashFTFontEngine
//------------------------------------------------------------------------
SplashFTFontEngine::SplashFTFontEngine(GBool aaA, FT_Library libA) {
FT_Int major, minor, patch;
aa = aaA;
lib = libA;
// as of FT 2.1.8, CID fonts are indexed by CID instead of GID
FT_Library_Version(lib, &major, &minor, &patch);
useCIDs = major > 2 ||
(major == 2 && (minor > 1 || (minor == 1 && patch > 7)));
}
SplashFTFontEngine *SplashFTFontEngine::init(GBool aaA) {
FT_Library libA;
if (FT_Init_FreeType(&libA)) {
return NULL;
}
return new SplashFTFontEngine(aaA, libA);
}
SplashFTFontEngine::~SplashFTFontEngine() {
FT_Done_FreeType(lib);
}
SplashFontFile *SplashFTFontEngine::loadType1Font(SplashFontFileID *idA,
SplashFontSrc *src,
const char **enc) {
return SplashFTFontFile::loadType1Font(this, idA, src, enc);
}
SplashFontFile *SplashFTFontEngine::loadType1CFont(SplashFontFileID *idA,
SplashFontSrc *src,
const char **enc) {
return SplashFTFontFile::loadType1Font(this, idA, src, enc);
}
SplashFontFile *SplashFTFontEngine::loadCIDFont(SplashFontFileID *idA,
SplashFontSrc *src) {
Gushort *cidToGIDMap;
int nCIDs;
SplashFontFile *ret;
// check for a CFF font
if (!useCIDs)
{
FoFiType1C *ff;
if (src->isFile) {
ff = FoFiType1C::load(src->fileName->getCString());
} else {
ff = new FoFiType1C(src->buf, src->bufLen, gFalse);
}
if (ff) {
cidToGIDMap = ff->getCIDToGIDMap(&nCIDs);
delete ff;
} else {
cidToGIDMap = NULL;
nCIDs = 0;
}
}
else
{
// Freetype 2.1.8 and up treats all CID fonts the same way
cidToGIDMap = NULL;
nCIDs = 0;
}
ret = SplashFTFontFile::loadCIDFont(this, idA, src, cidToGIDMap, nCIDs);
if (!ret) {
gfree(cidToGIDMap);
}
return ret;
}
SplashFontFile *SplashFTFontEngine::loadTrueTypeFont(SplashFontFileID *idA,
SplashFontSrc *src,
Gushort *codeToGID,
int codeToGIDLen,
int faceIndex) {
#if 0
FoFiTrueType *ff;
GString *tmpFileName;
FILE *tmpFile;
SplashFontFile *ret;
if (!(ff = FoFiTrueType::load(fileName, faceIndex))) {
return NULL;
}
tmpFileName = NULL;
if (!openTempFile(&tmpFileName, &tmpFile, "wb", NULL)) {
delete ff;
return NULL;
}
ff->writeTTF(&FT_fileWrite, tmpFile);
delete ff;
fclose(tmpFile);
ret = SplashFTFontFile::loadTrueTypeFont(this, idA,
tmpFileName->getCString(),
gTrue, codeToGID, codeToGIDLen,
faceIndex);
if (ret) {
if (deleteFile) {
unlink(fileName);
}
} else {
unlink(tmpFileName->getCString());
}
delete tmpFileName;
return ret;
#else
SplashFontFile *ret;
ret = SplashFTFontFile::loadTrueTypeFont(this, idA, src,
codeToGID, codeToGIDLen,
faceIndex);
return ret;
#endif
}
#endif // HAVE_FREETYPE_FREETYPE_H || HAVE_FREETYPE_H

View File

@ -1,59 +0,0 @@
//========================================================================
//
// SplashFTFontEngine.h
//
//========================================================================
#ifndef SPLASHFTFONTENGINE_H
#define SPLASHFTFONTENGINE_H
#include <aconf.h>
#if HAVE_FREETYPE_FREETYPE_H || HAVE_FREETYPE_H
#ifdef USE_GCC_PRAGMAS
#pragma interface
#endif
#include <ft2build.h>
#include FT_FREETYPE_H
#include "gtypes.h"
class SplashFontFile;
class SplashFontFileID;
class SplashFontSrc;
//------------------------------------------------------------------------
// SplashFTFontEngine
//------------------------------------------------------------------------
class SplashFTFontEngine {
public:
static SplashFTFontEngine *init(GBool aaA);
~SplashFTFontEngine();
// Load fonts.
SplashFontFile *loadType1Font(SplashFontFileID *idA, SplashFontSrc *src, const char **enc);
SplashFontFile *loadType1CFont(SplashFontFileID *idA, SplashFontSrc *src, const char **enc);
SplashFontFile *loadCIDFont(SplashFontFileID *idA, SplashFontSrc *src);
SplashFontFile *loadTrueTypeFont(SplashFontFileID *idA, SplashFontSrc *src,
Gushort *codeToGID, int codeToGIDLen,
int faceIndex=0);
private:
SplashFTFontEngine(GBool aaA, FT_Library libA);
GBool aa;
FT_Library lib;
GBool useCIDs;
friend class SplashFTFontFile;
friend class SplashFTFont;
};
#endif // HAVE_FREETYPE_FREETYPE_H || HAVE_FREETYPE_H
#endif

View File

@ -1,122 +0,0 @@
//========================================================================
//
// SplashFTFontFile.cc
//
//========================================================================
#include <aconf.h>
#if HAVE_FREETYPE_FREETYPE_H || HAVE_FREETYPE_H
#ifdef USE_GCC_PRAGMAS
#pragma implementation
#endif
#include "gmem.h"
#include "SplashFTFontEngine.h"
#include "SplashFTFont.h"
#include "SplashFTFontFile.h"
#include "GString.h"
//------------------------------------------------------------------------
// SplashFTFontFile
//------------------------------------------------------------------------
SplashFontFile *SplashFTFontFile::loadType1Font(SplashFTFontEngine *engineA,
SplashFontFileID *idA,
SplashFontSrc *src,
const char **encA) {
FT_Face faceA;
Gushort *codeToGIDA;
const char *name;
int i;
if (src->isFile) {
if (FT_New_Face(engineA->lib, src->fileName->getCString(), 0, &faceA))
return NULL;
} else {
if (FT_New_Memory_Face(engineA->lib, (const FT_Byte *)src->buf, src->bufLen, 0, &faceA))
return NULL;
}
codeToGIDA = (Gushort *)gmallocn(256, sizeof(int));
for (i = 0; i < 256; ++i) {
codeToGIDA[i] = 0;
if ((name = encA[i])) {
codeToGIDA[i] = (Gushort)FT_Get_Name_Index(faceA, (char*)name);
}
}
return new SplashFTFontFile(engineA, idA, src,
faceA, codeToGIDA, 256);
}
SplashFontFile *SplashFTFontFile::loadCIDFont(SplashFTFontEngine *engineA,
SplashFontFileID *idA,
SplashFontSrc *src,
Gushort *codeToGIDA,
int codeToGIDLenA) {
FT_Face faceA;
if (src->isFile) {
if (FT_New_Face(engineA->lib, src->fileName->getCString(), 0, &faceA))
return NULL;
} else {
if (FT_New_Memory_Face(engineA->lib, (const FT_Byte *)src->buf, src->bufLen, 0, &faceA))
return NULL;
}
return new SplashFTFontFile(engineA, idA, src,
faceA, codeToGIDA, codeToGIDLenA);
}
SplashFontFile *SplashFTFontFile::loadTrueTypeFont(SplashFTFontEngine *engineA,
SplashFontFileID *idA,
SplashFontSrc *src,
Gushort *codeToGIDA,
int codeToGIDLenA,
int faceIndexA) {
FT_Face faceA;
if (src->isFile) {
if (FT_New_Face(engineA->lib, src->fileName->getCString(), faceIndexA, &faceA))
return NULL;
} else {
if (FT_New_Memory_Face(engineA->lib, (const FT_Byte *)src->buf, src->bufLen, faceIndexA, &faceA))
return NULL;
}
return new SplashFTFontFile(engineA, idA, src,
faceA, codeToGIDA, codeToGIDLenA);
}
SplashFTFontFile::SplashFTFontFile(SplashFTFontEngine *engineA,
SplashFontFileID *idA,
SplashFontSrc *srcA,
FT_Face faceA,
Gushort *codeToGIDA, int codeToGIDLenA):
SplashFontFile(idA, srcA)
{
engine = engineA;
face = faceA;
codeToGID = codeToGIDA;
codeToGIDLen = codeToGIDLenA;
}
SplashFTFontFile::~SplashFTFontFile() {
if (face) {
FT_Done_Face(face);
}
if (codeToGID) {
gfree(codeToGID);
}
}
SplashFont *SplashFTFontFile::makeFont(SplashCoord *mat) {
SplashFont *font;
font = new SplashFTFont(this, mat);
font->initCache();
return font;
}
#endif // HAVE_FREETYPE_FREETYPE_H || HAVE_FREETYPE_H

View File

@ -1,70 +0,0 @@
//========================================================================
//
// SplashFTFontFile.h
//
//========================================================================
#ifndef SPLASHFTFONTFILE_H
#define SPLASHFTFONTFILE_H
#include <aconf.h>
#if HAVE_FREETYPE_FREETYPE_H || HAVE_FREETYPE_H
#ifdef USE_GCC_PRAGMAS
#pragma interface
#endif
#include <ft2build.h>
#include FT_FREETYPE_H
#include "SplashFontFile.h"
class SplashFontFileID;
class SplashFTFontEngine;
//------------------------------------------------------------------------
// SplashFTFontFile
//------------------------------------------------------------------------
class SplashFTFontFile: public SplashFontFile {
public:
static SplashFontFile *loadType1Font(SplashFTFontEngine *engineA,
SplashFontFileID *idA,
SplashFontSrc *src, const char **encA);
static SplashFontFile *loadCIDFont(SplashFTFontEngine *engineA,
SplashFontFileID *idA,
SplashFontSrc *src,
Gushort *codeToCIDA, int codeToGIDLenA);
static SplashFontFile *loadTrueTypeFont(SplashFTFontEngine *engineA,
SplashFontFileID *idA,
SplashFontSrc *src,
Gushort *codeToGIDA,
int codeToGIDLenA,
int faceIndexA=0);
virtual ~SplashFTFontFile();
// Create a new SplashFTFont, i.e., a scaled instance of this font
// file.
virtual SplashFont *makeFont(SplashCoord *mat);
private:
SplashFTFontFile(SplashFTFontEngine *engineA,
SplashFontFileID *idA,
SplashFontSrc *srcA,
FT_Face faceA,
Gushort *codeToGIDA, int codeToGIDLenA);
SplashFTFontEngine *engine;
FT_Face face;
Gushort *codeToGID;
int codeToGIDLen;
friend class SplashFTFont;
};
#endif // HAVE_FREETYPE_FREETYPE_H || HAVE_FREETYPE_H
#endif

View File

@ -1,172 +0,0 @@
//========================================================================
//
// SplashFont.cc
//
//========================================================================
#include <aconf.h>
#ifdef USE_GCC_PRAGMAS
#pragma implementation
#endif
#include <string.h>
#include "gmem.h"
#include "SplashMath.h"
#include "SplashGlyphBitmap.h"
#include "SplashFontFile.h"
#include "SplashFont.h"
//------------------------------------------------------------------------
struct SplashFontCacheTag {
int c;
short xFrac, yFrac; // x and y fractions
int mru; // valid bit (0x80000000) and MRU index
int x, y, w, h; // offset and size of glyph
};
//------------------------------------------------------------------------
// SplashFont
//------------------------------------------------------------------------
SplashFont::SplashFont(SplashFontFile *fontFileA, SplashCoord *matA,
GBool aaA) {
fontFile = fontFileA;
fontFile->incRefCnt();
mat[0] = matA[0];
mat[1] = matA[1];
mat[2] = matA[2];
mat[3] = matA[3];
aa = aaA;
cache = NULL;
cacheTags = NULL;
xMin = yMin = xMax = yMax = 0;
}
void SplashFont::initCache() {
int i;
// this should be (max - min + 1), but we add some padding to
// deal with rounding errors
glyphW = xMax - xMin + 3;
glyphH = yMax - yMin + 3;
if (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 *)gmallocn(cacheSets* cacheAssoc, glyphSize);
cacheTags = (SplashFontCacheTag *)gmallocn(cacheSets * cacheAssoc,
sizeof(SplashFontCacheTag));
for (i = 0; i < cacheSets * cacheAssoc; ++i) {
cacheTags[i].mru = i & (cacheAssoc - 1);
}
}
SplashFont::~SplashFont() {
fontFile->decRefCnt();
if (cache) {
gfree(cache);
}
if (cacheTags) {
gfree(cacheTags);
}
}
GBool SplashFont::getGlyph(int c, int xFrac, int yFrac,
SplashGlyphBitmap *bitmap) {
SplashGlyphBitmap bitmap2;
int size;
Guchar *p;
int i, j, k;
// no fractional coordinates for large glyphs or non-anti-aliased
// glyphs
if (!aa || glyphH > 50) {
xFrac = yFrac = 0;
}
// check the cache
i = (c & (cacheSets - 1)) * cacheAssoc;
for (j = 0; j < cacheAssoc; ++j) {
if ((cacheTags[i+j].mru & 0x80000000) &&
cacheTags[i+j].c == c &&
(int)cacheTags[i+j].xFrac == xFrac &&
(int)cacheTags[i+j].yFrac == yFrac) {
bitmap->x = cacheTags[i+j].x;
bitmap->y = cacheTags[i+j].y;
bitmap->w = cacheTags[i+j].w;
bitmap->h = cacheTags[i+j].h;
for (k = 0; k < cacheAssoc; ++k) {
if (k != j &&
(cacheTags[i+k].mru & 0x7fffffff) <
(cacheTags[i+j].mru & 0x7fffffff)) {
++cacheTags[i+k].mru;
}
}
cacheTags[i+j].mru = 0x80000000;
bitmap->aa = aa;
bitmap->data = cache + (i+j) * glyphSize;
bitmap->freeData = gFalse;
return gTrue;
}
}
// generate the glyph bitmap
if (!makeGlyph(c, xFrac, yFrac, &bitmap2)) {
return gFalse;
}
// if the glyph doesn't fit in the bounding box, return a temporary
// uncached bitmap
if (bitmap2.w > glyphW || bitmap2.h > glyphH) {
*bitmap = bitmap2;
return gTrue;
}
// insert glyph pixmap in cache
if (aa) {
size = bitmap2.w * bitmap2.h;
} else {
size = ((bitmap2.w + 7) >> 3) * bitmap2.h;
}
p = NULL; // make gcc happy
for (j = 0; j < cacheAssoc; ++j) {
if ((cacheTags[i+j].mru & 0x7fffffff) == cacheAssoc - 1) {
cacheTags[i+j].mru = 0x80000000;
cacheTags[i+j].c = c;
cacheTags[i+j].xFrac = (short)xFrac;
cacheTags[i+j].yFrac = (short)yFrac;
cacheTags[i+j].x = bitmap2.x;
cacheTags[i+j].y = bitmap2.y;
cacheTags[i+j].w = bitmap2.w;
cacheTags[i+j].h = bitmap2.h;
p = cache + (i+j) * glyphSize;
memcpy(p, bitmap2.data, size);
} else {
++cacheTags[i+j].mru;
}
}
*bitmap = bitmap2;
bitmap->data = p;
bitmap->freeData = gFalse;
if (bitmap2.freeData) {
gfree(bitmap2.data);
}
return gTrue;
}

View File

@ -1,97 +0,0 @@
//========================================================================
//
// SplashFont.h
//
//========================================================================
#ifndef SPLASHFONT_H
#define SPLASHFONT_H
#include <aconf.h>
#ifdef USE_GCC_PRAGMAS
#pragma interface
#endif
#include "gtypes.h"
#include "SplashTypes.h"
struct SplashGlyphBitmap;
struct SplashFontCacheTag;
class SplashFontFile;
class SplashPath;
//------------------------------------------------------------------------
// Fractional positioning uses this many bits to the right of the
// decimal points.
#define splashFontFractionBits 2
#define splashFontFraction (1 << splashFontFractionBits)
#define splashFontFractionMul \
((SplashCoord)1 / (SplashCoord)splashFontFraction)
//------------------------------------------------------------------------
// SplashFont
//------------------------------------------------------------------------
class SplashFont {
public:
SplashFont(SplashFontFile *fontFileA, SplashCoord *matA, GBool aaA);
// This must be called after the constructor, so that the subclass
// constructor has a chance to compute the bbox.
void initCache();
virtual ~SplashFont();
SplashFontFile *getFontFile() { return fontFile; }
// Return true if <this> matches the specified font file and matrix.
GBool matches(SplashFontFile *fontFileA, SplashCoord *matA) {
return fontFileA == fontFile &&
matA[0] == mat[0] && matA[1] == mat[1] &&
matA[2] == mat[2] && matA[3] == mat[3];
}
// Get a glyph - this does a cache lookup first, and if not found,
// creates a new bitmap and adds it to the cache. The <xFrac> and
// <yFrac> values are splashFontFractionBits bits each, representing
// the numerators of fractions in [0, 1), where the denominator is
// splashFontFraction = 1 << splashFontFractionBits. Subclasses
// should override this to zero out xFrac and/or yFrac if they don't
// support fractional coordinates.
virtual GBool getGlyph(int c, int xFrac, int yFrac,
SplashGlyphBitmap *bitmap);
// Rasterize a glyph. The <xFrac> and <yFrac> values are the same
// as described for getGlyph.
virtual GBool makeGlyph(int c, int xFrac, int yFrac,
SplashGlyphBitmap *bitmap) = 0;
// Return the path for a glyph.
virtual SplashPath *getGlyphPath(int c) = 0;
// Return the font transform matrix.
SplashCoord *getMatrix() { return mat; }
// Return the glyph bounding box.
void getBBox(int *xMinA, int *yMinA, int *xMaxA, int *yMaxA)
{ *xMinA = xMin; *yMinA = yMin; *xMaxA = xMax; *yMaxA = yMax; }
protected:
SplashFontFile *fontFile;
SplashCoord mat[4]; // font transform matrix
GBool aa; // anti-aliasing
int xMin, yMin, xMax, yMax; // glyph bounding box
Guchar *cache; // glyph bitmap cache
SplashFontCacheTag * // cache tags
cacheTags;
int glyphW, glyphH; // size of glyph bitmaps
int glyphSize; // size of glyph bitmaps, in bytes
int cacheSets; // number of sets in cache
int cacheAssoc; // cache associativity (glyphs per set)
};
#endif

View File

@ -1,229 +0,0 @@
//========================================================================
//
// SplashFontEngine.cc
//
//========================================================================
#include <aconf.h>
#ifdef USE_GCC_PRAGMAS
#pragma implementation
#endif
#if HAVE_T1LIB_H
#include <t1lib.h>
#endif
#include <stdlib.h>
#include <stdio.h>
#ifndef WIN32
# include <unistd.h>
#endif
#include "gmem.h"
#include "GString.h"
#include "SplashT1FontEngine.h"
#include "SplashFTFontEngine.h"
#include "SplashFontFile.h"
#include "SplashFontFileID.h"
#include "SplashFont.h"
#include "SplashFontEngine.h"
//------------------------------------------------------------------------
// SplashFontEngine
//------------------------------------------------------------------------
SplashFontEngine::SplashFontEngine(
#if HAVE_T1LIB_H
GBool enableT1lib,
#endif
#if HAVE_FREETYPE_FREETYPE_H || HAVE_FREETYPE_H
GBool enableFreeType,
#endif
GBool aa) {
int i;
for (i = 0; i < splashFontCacheSize; ++i) {
fontCache[i] = NULL;
}
#if HAVE_T1LIB_H
if (enableT1lib) {
t1Engine = SplashT1FontEngine::init(aa);
} else {
t1Engine = NULL;
}
#endif
#if HAVE_FREETYPE_FREETYPE_H || HAVE_FREETYPE_H
if (enableFreeType) {
ftEngine = SplashFTFontEngine::init(aa);
} else {
ftEngine = NULL;
}
#endif
}
SplashFontEngine::~SplashFontEngine() {
int i;
for (i = 0; i < splashFontCacheSize; ++i) {
if (fontCache[i]) {
delete fontCache[i];
}
}
#if HAVE_T1LIB_H
if (t1Engine) {
delete t1Engine;
}
#endif
#if HAVE_FREETYPE_FREETYPE_H || HAVE_FREETYPE_H
if (ftEngine) {
delete ftEngine;
}
#endif
}
SplashFontFile *SplashFontEngine::getFontFile(SplashFontFileID *id) {
SplashFontFile *fontFile;
int i;
for (i = 0; i < splashFontCacheSize; ++i) {
if (fontCache[i]) {
fontFile = fontCache[i]->getFontFile();
if (fontFile && fontFile->getID()->matches(id)) {
return fontFile;
}
}
}
return NULL;
}
SplashFontFile *SplashFontEngine::loadType1Font(SplashFontFileID *idA,
SplashFontSrc *src,
const char **enc) {
SplashFontFile *fontFile;
fontFile = NULL;
#if HAVE_T1LIB_H
if (!fontFile && t1Engine) {
fontFile = t1Engine->loadType1Font(idA, src, enc);
}
#endif
#if HAVE_FREETYPE_FREETYPE_H || HAVE_FREETYPE_H
if (!fontFile && ftEngine) {
fontFile = ftEngine->loadType1Font(idA, src, enc);
}
#endif
// delete the (temporary) font file -- with Unix hard link
// semantics, this will remove the last link; otherwise it will
// return an error, leaving the file to be deleted later (if
// loadXYZFont failed, the file will always be deleted)
src->unref();
return fontFile;
}
SplashFontFile *SplashFontEngine::loadType1CFont(SplashFontFileID *idA,
SplashFontSrc *src,
const char **enc) {
SplashFontFile *fontFile;
fontFile = NULL;
#if HAVE_T1LIB_H
if (!fontFile && t1Engine) {
fontFile = t1Engine->loadType1CFont(idA, src, enc);
}
#endif
#if HAVE_FREETYPE_FREETYPE_H || HAVE_FREETYPE_H
if (!fontFile && ftEngine) {
fontFile = ftEngine->loadType1CFont(idA, src, enc);
}
#endif
// delete the (temporary) font file -- with Unix hard link
// semantics, this will remove the last link; otherwise it will
// return an error, leaving the file to be deleted later (if
// loadXYZFont failed, the file will always be deleted)
src->unref();
return fontFile;
}
SplashFontFile *SplashFontEngine::loadCIDFont(SplashFontFileID *idA,
SplashFontSrc *src) {
SplashFontFile *fontFile;
fontFile = NULL;
#if HAVE_FREETYPE_FREETYPE_H || HAVE_FREETYPE_H
if (!fontFile && ftEngine) {
fontFile = ftEngine->loadCIDFont(idA, src);
}
#endif
// delete the (temporary) font file -- with Unix hard link
// semantics, this will remove the last link; otherwise it will
// return an error, leaving the file to be deleted later (if
// loadXYZFont failed, the file will always be deleted)
src->unref();
return fontFile;
}
SplashFontFile *SplashFontEngine::loadTrueTypeFont(SplashFontFileID *idA,
SplashFontSrc *src,
Gushort *codeToGID,
int codeToGIDLen,
int faceIndex) {
SplashFontFile *fontFile;
fontFile = NULL;
#if HAVE_FREETYPE_FREETYPE_H || HAVE_FREETYPE_H
if (!fontFile && ftEngine) {
fontFile = ftEngine->loadTrueTypeFont(idA, src,
codeToGID, codeToGIDLen, faceIndex);
}
#endif
if (!fontFile) {
gfree(codeToGID);
}
// delete the (temporary) font file -- with Unix hard link
// semantics, this will remove the last link; otherwise it will
// return an error, leaving the file to be deleted later (if
// loadXYZFont failed, the file will always be deleted)
src->unref();
return fontFile;
}
SplashFont *SplashFontEngine::getFont(SplashFontFile *fontFile,
SplashCoord *mat) {
SplashFont *font;
int i, j;
font = fontCache[0];
if (font && font->matches(fontFile, mat)) {
return font;
}
for (i = 1; i < splashFontCacheSize; ++i) {
font = fontCache[i];
if (font && font->matches(fontFile, mat)) {
for (j = i; j > 0; --j) {
fontCache[j] = fontCache[j-1];
}
fontCache[0] = font;
return font;
}
}
font = fontFile->makeFont(mat);
if (fontCache[splashFontCacheSize - 1]) {
delete fontCache[splashFontCacheSize - 1];
}
for (j = splashFontCacheSize - 1; j > 0; --j) {
fontCache[j] = fontCache[j-1];
}
fontCache[0] = font;
return font;
}

View File

@ -1,83 +0,0 @@
//========================================================================
//
// SplashFontEngine.h
//
//========================================================================
#ifndef SPLASHFONTENGINE_H
#define SPLASHFONTENGINE_H
#include <aconf.h>
#ifdef USE_GCC_PRAGMAS
#pragma interface
#endif
#include "gtypes.h"
class SplashT1FontEngine;
class SplashFTFontEngine;
class SplashDTFontEngine;
class SplashFontFile;
class SplashFontFileID;
class SplashFont;
class SplashFontSrc;
//------------------------------------------------------------------------
#define splashFontCacheSize 16
//------------------------------------------------------------------------
// SplashFontEngine
//------------------------------------------------------------------------
class SplashFontEngine {
public:
// Create a font engine.
SplashFontEngine(
#if HAVE_T1LIB_H
GBool enableT1lib,
#endif
#if HAVE_FREETYPE_FREETYPE_H || HAVE_FREETYPE_H
GBool enableFreeType,
#endif
GBool aa);
~SplashFontEngine();
// Get a font file from the cache. Returns NULL if there is no
// matching entry in the cache.
SplashFontFile *getFontFile(SplashFontFileID *id);
// Load fonts - these create new SplashFontFile objects.
SplashFontFile *loadType1Font(SplashFontFileID *idA, SplashFontSrc *src, const char **enc);
SplashFontFile *loadType1CFont(SplashFontFileID *idA, SplashFontSrc *src, const char **enc);
SplashFontFile *loadCIDFont(SplashFontFileID *idA, SplashFontSrc *src);
SplashFontFile *loadTrueTypeFont(SplashFontFileID *idA, SplashFontSrc *src,
Gushort *codeToGID, int codeToGIDLen,
int faceIndex=0);
// Get a font - this does a cache lookup first, and if not found,
// creates a new SplashFont object and adds it to the cache. The
// matrix:
// [ mat[0] mat[1] ]
// [ mat[2] mat[3] ]
// specifies the font transform in PostScript style:
// [x' y'] = [x y] * mat
// Note that the Splash y axis points downward.
SplashFont *getFont(SplashFontFile *fontFile, SplashCoord *mat);
private:
SplashFont *fontCache[splashFontCacheSize];
#if HAVE_T1LIB_H
SplashT1FontEngine *t1Engine;
#endif
#if HAVE_FREETYPE_FREETYPE_H || HAVE_FREETYPE_H
SplashFTFontEngine *ftEngine;
#endif
};
#endif

View File

@ -1,109 +0,0 @@
//========================================================================
//
// SplashFontFile.cc
//
//========================================================================
#include <aconf.h>
#ifdef USE_GCC_PRAGMAS
#pragma implementation
#endif
#include <stdio.h>
#ifndef WIN32
# include <unistd.h>
#endif
#include "GString.h"
#include "SplashFontFile.h"
#include "SplashFontFileID.h"
#include "gmem.h"
#ifdef VMS
#if (__VMS_VER < 70000000)
extern "C" int unlink(char *filename);
#endif
#endif
//------------------------------------------------------------------------
// SplashFontFile
//------------------------------------------------------------------------
SplashFontFile::SplashFontFile(SplashFontFileID *idA, SplashFontSrc *srcA) {
id = idA;
src = srcA;
src->ref();
refCnt = 0;
}
SplashFontFile::~SplashFontFile() {
src->unref();
delete id;
}
void SplashFontFile::incRefCnt() {
++refCnt;
}
void SplashFontFile::decRefCnt() {
if (!--refCnt) {
delete this;
}
}
//
SplashFontSrc::SplashFontSrc() {
isFile = gFalse;
deleteSrc = gFalse;
fileName = NULL;
buf = NULL;
refcnt = 1;
}
SplashFontSrc::~SplashFontSrc() {
if (deleteSrc) {
if (isFile) {
if (fileName)
unlink(fileName->getCString());
} else {
if (buf)
gfree(buf);
}
}
if (isFile && fileName)
delete fileName;
}
void SplashFontSrc::ref() {
refcnt++;
}
void SplashFontSrc::unref() {
if (! --refcnt)
delete this;
}
void SplashFontSrc::setFile(GString *file, GBool del)
{
isFile = gTrue;
fileName = file->copy();
deleteSrc = del;
}
void SplashFontSrc::setFile(const char *file, GBool del)
{
isFile = gTrue;
fileName = new GString(file);
deleteSrc = del;
}
void SplashFontSrc::setBuf(char *bufA, int bufLenA, GBool del)
{
isFile = gFalse;
buf = bufA;
bufLen = bufLenA;
deleteSrc = del;
}

View File

@ -1,77 +0,0 @@
//========================================================================
//
// SplashFontFile.h
//
//========================================================================
#ifndef SPLASHFONTFILE_H
#define SPLASHFONTFILE_H
#include <aconf.h>
#ifdef USE_GCC_PRAGMAS
#pragma interface
#endif
#include "gtypes.h"
#include "SplashTypes.h"
class GString;
class SplashFontEngine;
class SplashFont;
class SplashFontFileID;
//------------------------------------------------------------------------
// SplashFontFile
//------------------------------------------------------------------------
struct SplashFontSrc {
SplashFontSrc();
~SplashFontSrc();
void setFile(GString *file, GBool del);
void setFile(const char *file, GBool del);
void setBuf(char *bufA, int buflenA, GBool del);
void ref();
void unref();
GBool isFile;
GString *fileName;
char *buf;
int bufLen;
GBool deleteSrc;
int refcnt;
};
class SplashFontFile {
public:
virtual ~SplashFontFile();
// Create a new SplashFont, i.e., a scaled instance of this font
// file.
virtual SplashFont *makeFont(SplashCoord *mat) = 0;
// Get the font file ID.
SplashFontFileID *getID() { return id; }
// Increment the reference count.
void incRefCnt();
// Decrement the reference count. If the new value is zero, delete
// the SplashFontFile object.
void decRefCnt();
protected:
SplashFontFile(SplashFontFileID *idA, SplashFontSrc *srcA);
SplashFontFileID *id;
SplashFontSrc *src;
int refCnt;
friend class SplashFontEngine;
};
#endif

View File

@ -1,23 +0,0 @@
//========================================================================
//
// SplashFontFileID.cc
//
//========================================================================
#include <aconf.h>
#ifdef USE_GCC_PRAGMAS
#pragma implementation
#endif
#include "SplashFontFileID.h"
//------------------------------------------------------------------------
// SplashFontFileID
//------------------------------------------------------------------------
SplashFontFileID::SplashFontFileID() {
}
SplashFontFileID::~SplashFontFileID() {
}

View File

@ -1,30 +0,0 @@
//========================================================================
//
// SplashFontFileID.h
//
//========================================================================
#ifndef SPLASHFONTFILEID_H
#define SPLASHFONTFILEID_H
#include <aconf.h>
#ifdef USE_GCC_PRAGMAS
#pragma interface
#endif
#include "gtypes.h"
//------------------------------------------------------------------------
// SplashFontFileID
//------------------------------------------------------------------------
class SplashFontFileID {
public:
SplashFontFileID();
virtual ~SplashFontFileID();
virtual GBool matches(SplashFontFileID *id) = 0;
};
#endif

View File

@ -1,26 +0,0 @@
//========================================================================
//
// SplashGlyphBitmap.h
//
//========================================================================
#ifndef SPLASHGLYPHBITMAP_H
#define SPLASHGLYPHBITMAP_H
#include <aconf.h>
#include "gtypes.h"
//------------------------------------------------------------------------
// SplashGlyphBitmap
//------------------------------------------------------------------------
struct SplashGlyphBitmap {
int x, y, w, h; // offset and size of glyph
GBool aa; // anti-aliased: true means 8-bit alpha
// bitmap; false means 1-bit
Guchar *data; // bitmap data
GBool freeData; // true if data memory should be freed
};
#endif

View File

@ -1,46 +0,0 @@
//========================================================================
//
// SplashMath.h
//
//========================================================================
#ifndef SPLASHMATH_H
#define SPLASHMATH_H
#include <aconf.h>
#include <math.h>
#include "SplashTypes.h"
static inline SplashCoord splashAbs(SplashCoord x) {
return fabs(x);
}
static inline int splashFloor(SplashCoord x) {
return (int)floor(x);
}
static inline int splashCeil(SplashCoord x) {
return (int)ceil(x);
}
static inline int splashRound(SplashCoord x) {
return (int)floor(x + 0.5);
}
static inline SplashCoord splashSqrt(SplashCoord x) {
return sqrt(x);
}
static inline SplashCoord splashPow(SplashCoord x, SplashCoord y) {
return pow(x, y);
}
static inline SplashCoord splashDist(SplashCoord x0, SplashCoord y0,
SplashCoord x1, SplashCoord y1) {
SplashCoord dx, dy;
dx = x1 - x0;
dy = y1 - y0;
return sqrt(dx * dx + dy * dy);
}
#endif

View File

@ -1,178 +0,0 @@
//========================================================================
//
// SplashPath.cc
//
//========================================================================
#include <aconf.h>
#ifdef USE_GCC_PRAGMAS
#pragma implementation
#endif
#include <string.h>
#include "gmem.h"
#include "SplashErrorCodes.h"
#include "SplashPath.h"
//------------------------------------------------------------------------
// SplashPath
//------------------------------------------------------------------------
// A path can be in three possible states:
//
// 1. no current point -- zero or more finished subpaths
// [curSubpath == length]
//
// 2. one point in subpath
// [curSubpath == length - 1]
//
// 3. open subpath with two or more points
// [curSubpath < length - 1]
SplashPath::SplashPath() {
pts = NULL;
flags = NULL;
length = size = 0;
curSubpath = 0;
}
SplashPath::SplashPath(SplashPath *path) {
length = path->length;
size = path->size;
pts = (SplashPathPoint *)gmallocn(size, sizeof(SplashPathPoint));
flags = (Guchar *)gmallocn(size, sizeof(Guchar));
memcpy(pts, path->pts, length * sizeof(SplashPathPoint));
memcpy(flags, path->flags, length * sizeof(Guchar));
curSubpath = path->curSubpath;
}
SplashPath::~SplashPath() {
gfree(pts);
gfree(flags);
}
// Add space for <nPts> more points.
void SplashPath::grow(int nPts) {
if (length + nPts > size) {
if (size == 0) {
size = 32;
}
while (size < length + nPts) {
size *= 2;
}
pts = (SplashPathPoint *)greallocn(pts, size, sizeof(SplashPathPoint));
flags = (Guchar *)greallocn(flags, size, sizeof(Guchar));
}
}
void SplashPath::append(SplashPath *path) {
int i;
curSubpath = length + path->curSubpath;
grow(path->length);
for (i = 0; i < path->length; ++i) {
pts[length] = path->pts[i];
flags[length] = path->flags[i];
++length;
}
}
SplashError SplashPath::moveTo(SplashCoord x, SplashCoord y) {
if (onePointSubpath()) {
return splashErrBogusPath;
}
grow(1);
pts[length].x = x;
pts[length].y = y;
flags[length] = splashPathFirst | splashPathLast;
curSubpath = length++;
return splashOk;
}
SplashError SplashPath::lineTo(SplashCoord x, SplashCoord y) {
if (noCurrentPoint()) {
return splashErrNoCurPt;
}
flags[length-1] &= ~splashPathLast;
grow(1);
pts[length].x = x;
pts[length].y = y;
flags[length] = splashPathLast;
++length;
return splashOk;
}
SplashError SplashPath::curveTo(SplashCoord x1, SplashCoord y1,
SplashCoord x2, SplashCoord y2,
SplashCoord x3, SplashCoord y3) {
if (noCurrentPoint()) {
return splashErrNoCurPt;
}
flags[length-1] &= ~splashPathLast;
grow(3);
pts[length].x = x1;
pts[length].y = y1;
flags[length] = splashPathCurve;
++length;
pts[length].x = x2;
pts[length].y = y2;
flags[length] = splashPathCurve;
++length;
pts[length].x = x3;
pts[length].y = y3;
flags[length] = splashPathLast;
++length;
return splashOk;
}
SplashError SplashPath::arcCWTo(SplashCoord x1, SplashCoord y1,
SplashCoord xc, SplashCoord yc) {
if (noCurrentPoint()) {
return splashErrNoCurPt;
}
flags[length-1] &= ~splashPathLast;
grow(2);
pts[length].x = xc;
pts[length].y = yc;
flags[length] = splashPathArcCW;
++length;
pts[length].x = x1;
pts[length].y = y1;
flags[length] = splashPathLast;
++length;
return splashOk;
}
SplashError SplashPath::close() {
if (noCurrentPoint()) {
return splashErrNoCurPt;
}
if (curSubpath == length - 1 ||
pts[length - 1].x != pts[curSubpath].x ||
pts[length - 1].y != pts[curSubpath].y) {
lineTo(pts[curSubpath].x, pts[curSubpath].y);
}
flags[curSubpath] |= splashPathClosed;
flags[length - 1] |= splashPathClosed;
curSubpath = length;
return splashOk;
}
void SplashPath::offset(SplashCoord dx, SplashCoord dy) {
int i;
for (i = 0; i < length; ++i) {
pts[i].x += dx;
pts[i].y += dy;
}
}
GBool SplashPath::getCurPt(SplashCoord *x, SplashCoord *y) {
if (noCurrentPoint()) {
return gFalse;
}
*x = pts[length - 1].x;
*y = pts[length - 1].y;
return gTrue;
}

View File

@ -1,112 +0,0 @@
//========================================================================
//
// SplashPath.h
//
//========================================================================
#ifndef SPLASHPATH_H
#define SPLASHPATH_H
#include <aconf.h>
#ifdef USE_GCC_PRAGMAS
#pragma interface
#endif
#include "SplashTypes.h"
//------------------------------------------------------------------------
// SplashPathPoint
//------------------------------------------------------------------------
struct SplashPathPoint {
SplashCoord x, y;
};
//------------------------------------------------------------------------
// SplashPath.flags
//------------------------------------------------------------------------
// first point on each subpath sets this flag
#define splashPathFirst 0x01
// last point on each subpath sets this flag
#define splashPathLast 0x02
// if the subpath is closed, its first and last points must be
// identical, and must set this flag
#define splashPathClosed 0x04
// curve control points set this flag
#define splashPathCurve 0x08
// clockwise arc center points set this flag
#define splashPathArcCW 0x10
//------------------------------------------------------------------------
// SplashPath
//------------------------------------------------------------------------
class SplashPath {
public:
// Create an empty path.
SplashPath();
// Copy a path.
SplashPath *copy() { return new SplashPath(this); }
~SplashPath();
// Append <path> to <this>.
void append(SplashPath *path);
// Start a new subpath.
SplashError moveTo(SplashCoord x, SplashCoord y);
// Add a line segment to the last subpath.
SplashError lineTo(SplashCoord x, SplashCoord y);
// Add a third-order (cubic) Bezier curve segment to the last
// subpath.
SplashError curveTo(SplashCoord x1, SplashCoord y1,
SplashCoord x2, SplashCoord y2,
SplashCoord x3, SplashCoord y3);
// Add a clockwise circular arc with center (xc, yc) and endpoint
// (x1, y1).
SplashError arcCWTo(SplashCoord x1, SplashCoord y1,
SplashCoord xc, SplashCoord yc);
// Close the last subpath, adding a line segment if necessary.
SplashError close();
// Add (<dx>, <dy>) to every point on this path.
void offset(SplashCoord dx, SplashCoord dy);
// Get the points on the path.
int getLength() { return length; }
void getPoint(int i, double *x, double *y, Guchar *f)
{ *x = pts[i].x; *y = pts[i].y; *f = flags[i]; }
// Get the current point.
GBool getCurPt(SplashCoord *x, SplashCoord *y);
private:
SplashPath(SplashPath *path);
void grow(int nPts);
GBool noCurrentPoint() { return curSubpath == length; }
GBool onePointSubpath() { return curSubpath == length - 1; }
GBool openSubpath() { return curSubpath < length - 1; }
SplashPathPoint *pts; // array of points
Guchar *flags; // array of flags
int length, size; // length/size of the pts and flags arrays
int curSubpath; // index of first point in last subpath
friend class SplashXPath;
friend class Splash;
};
#endif

View File

@ -1,68 +0,0 @@
//========================================================================
//
// SplashPattern.cc
//
//========================================================================
#include <aconf.h>
#ifdef USE_GCC_PRAGMAS
#pragma implementation
#endif
#include "SplashMath.h"
#include "SplashScreen.h"
#include "SplashPattern.h"
//------------------------------------------------------------------------
// SplashPattern
//------------------------------------------------------------------------
SplashPattern::SplashPattern() {
}
SplashPattern::~SplashPattern() {
}
//------------------------------------------------------------------------
// SplashSolidColor
//------------------------------------------------------------------------
SplashSolidColor::SplashSolidColor(SplashColorPtr colorA) {
splashColorCopy(color, colorA);
}
SplashSolidColor::~SplashSolidColor() {
}
void SplashSolidColor::getColor(int /*x*/, int /*y*/, SplashColorPtr c) {
splashColorCopy(c, color);
}
//------------------------------------------------------------------------
// SplashHalftone
//------------------------------------------------------------------------
SplashHalftone::SplashHalftone(SplashColorPtr color0A, SplashColorPtr color1A,
SplashScreen *screenA, SplashCoord valueA) {
splashColorCopy(color0, color0A);
splashColorCopy(color1, color1A);
screen = screenA;
value = valueA;
}
SplashPattern *SplashHalftone::copy() {
return new SplashHalftone(color0, color1, screen->copy(), value);
}
SplashHalftone::~SplashHalftone() {
delete screen;
}
void SplashHalftone::getColor(int x, int y, SplashColorPtr c) {
splashColorCopy(c, screen->test(x, y, value) ? color1 : color0);
}
GBool SplashHalftone::isStatic() {
return screen->isStatic(value);
}

View File

@ -1,90 +0,0 @@
//========================================================================
//
// SplashPattern.h
//
//========================================================================
#ifndef SPLASHPATTERN_H
#define SPLASHPATTERN_H
#include <aconf.h>
#ifdef USE_GCC_PRAGMAS
#pragma interface
#endif
#include "SplashTypes.h"
class SplashScreen;
//------------------------------------------------------------------------
// SplashPattern
//------------------------------------------------------------------------
class SplashPattern {
public:
SplashPattern();
virtual SplashPattern *copy() = 0;
virtual ~SplashPattern();
// Return the color value for a specific pixel.
virtual void getColor(int x, int y, SplashColorPtr c) = 0;
// Returns true if this pattern object will return the same color
// value for all pixels.
virtual GBool isStatic() = 0;
private:
};
//------------------------------------------------------------------------
// SplashSolidColor
//------------------------------------------------------------------------
class SplashSolidColor: public SplashPattern {
public:
SplashSolidColor(SplashColorPtr colorA);
virtual SplashPattern *copy() { return new SplashSolidColor(color); }
virtual ~SplashSolidColor();
virtual void getColor(int x, int y, SplashColorPtr c);
virtual GBool isStatic() { return gTrue; }
private:
SplashColor color;
};
//------------------------------------------------------------------------
// SplashHalftone
//------------------------------------------------------------------------
class SplashHalftone: public SplashPattern {
public:
SplashHalftone(SplashColorPtr color0A, SplashColorPtr color1A,
SplashScreen *screenA, SplashCoord valueA);
virtual SplashPattern *copy();
virtual ~SplashHalftone();
virtual void getColor(int x, int y, SplashColorPtr c);
virtual GBool isStatic();
private:
SplashColor color0, color1;
SplashScreen *screen;
SplashCoord value;
};
#endif

View File

@ -1,141 +0,0 @@
//========================================================================
//
// SplashScreen.cc
//
//========================================================================
#include <aconf.h>
#ifdef USE_GCC_PRAGMAS
#pragma implementation
#endif
#include <string.h>
#include "gmem.h"
#include "SplashMath.h"
#include "SplashScreen.h"
//------------------------------------------------------------------------
// SplashScreen
//------------------------------------------------------------------------
// This generates a 45 degree screen using a circular dot spot
// function. DPI = resolution / ((size / 2) * sqrt(2)).
// Gamma correction (gamma = 1 / 1.33) is also computed here.
SplashScreen::SplashScreen(int sizeA) {
SplashCoord *dist;
SplashCoord u, v, d, val;
int size2, x, y, x1, y1, i;
size2 = sizeA >> 1;
if (size2 < 1) {
size2 = 1;
}
size = size2 << 1;
// initialize the threshold matrix
mat = (SplashCoord *)gmallocn(size * size, sizeof(SplashCoord));
for (y = 0; y < size; ++y) {
for (x = 0; x < size; ++x) {
mat[y * size + x] = -1;
}
}
// build the distance matrix
dist = (SplashCoord *)gmallocn(size * size2, sizeof(SplashCoord));
for (y = 0; y < size2; ++y) {
for (x = 0; x < size2; ++x) {
if (x + y < size2 - 1) {
u = (SplashCoord)x + 0.5 - 0;
v = (SplashCoord)y + 0.5 - 0;
} else {
u = (SplashCoord)x + 0.5 - (SplashCoord)size2;
v = (SplashCoord)y + 0.5 - (SplashCoord)size2;
}
dist[y * size2 + x] = u*u + v*v;
}
}
for (y = 0; y < size2; ++y) {
for (x = 0; x < size2; ++x) {
if (x < y) {
u = (SplashCoord)x + 0.5 - 0;
v = (SplashCoord)y + 0.5 - (SplashCoord)size2;
} else {
u = (SplashCoord)x + 0.5 - (SplashCoord)size2;
v = (SplashCoord)y + 0.5 - 0;
}
dist[(size2 + y) * size2 + x] = u*u + v*v;
}
}
// build the threshold matrix
minVal = 1;
maxVal = 0;
x1 = y1 = 0; // make gcc happy
for (i = 1; i <= size * size2; ++i) {
d = size * size2;
for (y = 0; y < size; ++y) {
for (x = 0; x < size2; ++x) {
if (mat[y * size + x] < 0 &&
dist[y * size2 + x] < d) {
x1 = x;
y1 = y;
d = dist[y1 * size2 + x1];
}
}
}
u = (SplashCoord)1 - (SplashCoord)i / (SplashCoord)(size * size2 + 1);
val = splashPow(u, 1.33);
if (val < minVal) {
minVal = val;
}
if (val > maxVal) {
maxVal = val;
}
mat[y1 * size + x1] = val;
if (y1 < size2) {
mat[(y1 + size2) * size + x1 + size2] = val;
} else {
mat[(y1 - size2) * size + x1 + size2] = val;
}
}
gfree(dist);
}
SplashScreen::SplashScreen(SplashScreen *screen) {
int n;
size = screen->size;
n = size * size * sizeof(SplashCoord);
mat = (SplashCoord *)gmalloc(n);
memcpy(mat, screen->mat, n);
minVal = screen->minVal;
maxVal = screen->maxVal;
}
SplashScreen::~SplashScreen() {
gfree(mat);
}
int SplashScreen::test(int x, int y, SplashCoord value) {
int xx, yy;
if (value < minVal) {
return 0;
}
if (value >= maxVal) {
return 1;
}
if ((xx = x % size) < 0) {
xx = -xx;
}
if ((yy = y % size) < 0) {
yy = -yy;
}
return value < mat[yy * size + xx] ? 0 : 1;
}
GBool SplashScreen::isStatic(SplashCoord value) {
return value < minVal || value >= maxVal;
}

View File

@ -1,50 +0,0 @@
//========================================================================
//
// SplashScreen.h
//
//========================================================================
#ifndef SPLASHSCREEN_H
#define SPLASHSCREEN_H
#include <aconf.h>
#ifdef USE_GCC_PRAGMAS
#pragma interface
#endif
#include "SplashTypes.h"
//------------------------------------------------------------------------
// SplashScreen
//------------------------------------------------------------------------
class SplashScreen {
public:
SplashScreen(int sizeA);
SplashScreen(SplashScreen *screen);
~SplashScreen();
SplashScreen *copy() { return new SplashScreen(this); }
// Return the computed pixel value (0=black, 1=white) for the gray
// level <value> at (<x>, <y>).
int test(int x, int y, SplashCoord value);
// Returns true if value is above the white threshold or below the
// black threshold, i.e., if the corresponding halftone will be
// solid white or black.
GBool isStatic(SplashCoord value);
private:
SplashCoord *mat; // threshold matrix
int size; // size of the threshold matrix
SplashCoord minVal; // any pixel value below minVal generates
// solid black
SplashCoord maxVal; // any pixel value above maxVal generates
// solid white
};
#endif

View File

@ -1,110 +0,0 @@
//========================================================================
//
// SplashState.cc
//
//========================================================================
#include <aconf.h>
#ifdef USE_GCC_PRAGMAS
#pragma implementation
#endif
#include <string.h>
#include "gmem.h"
#include "SplashPattern.h"
#include "SplashScreen.h"
#include "SplashClip.h"
#include "SplashState.h"
//------------------------------------------------------------------------
// SplashState
//------------------------------------------------------------------------
// number of components in each color mode
int splashColorModeNComps[] = {
1, 1, 2, 3, 3, 4, 4
};
SplashState::SplashState(int width, int height) {
SplashColor color;
memset(&color, 0, sizeof(SplashColor));
strokePattern = new SplashSolidColor(color);
fillPattern = new SplashSolidColor(color);
screen = new SplashScreen(10);
blendFunc = NULL;
strokeAlpha = 1;
fillAlpha = 1;
lineWidth = 0;
lineCap = splashLineCapButt;
lineJoin = splashLineJoinMiter;
miterLimit = 10;
flatness = 1;
lineDash = NULL;
lineDashLength = 0;
lineDashPhase = 0;
clip = new SplashClip(0, 0, width - 1, height - 1);
next = NULL;
}
SplashState::SplashState(SplashState *state) {
strokePattern = state->strokePattern->copy();
fillPattern = state->fillPattern->copy();
screen = state->screen->copy();
blendFunc = state->blendFunc;
strokeAlpha = state->strokeAlpha;
fillAlpha = state->fillAlpha;
lineWidth = state->lineWidth;
lineCap = state->lineCap;
lineJoin = state->lineJoin;
miterLimit = state->miterLimit;
flatness = state->flatness;
if (state->lineDash) {
lineDashLength = state->lineDashLength;
lineDash = (SplashCoord *)gmallocn(lineDashLength, sizeof(SplashCoord));
memcpy(lineDash, state->lineDash, lineDashLength * sizeof(SplashCoord));
} else {
lineDash = NULL;
lineDashLength = 0;
}
lineDashPhase = state->lineDashPhase;
clip = state->clip->copy();
next = NULL;
}
SplashState::~SplashState() {
delete strokePattern;
delete fillPattern;
delete screen;
gfree(lineDash);
delete clip;
}
void SplashState::setStrokePattern(SplashPattern *strokePatternA) {
delete strokePattern;
strokePattern = strokePatternA;
}
void SplashState::setFillPattern(SplashPattern *fillPatternA) {
delete fillPattern;
fillPattern = fillPatternA;
}
void SplashState::setScreen(SplashScreen *screenA) {
delete screen;
screen = screenA;
}
void SplashState::setLineDash(SplashCoord *lineDashA, int lineDashLengthA,
SplashCoord lineDashPhaseA) {
gfree(lineDash);
lineDashLength = lineDashLengthA;
if (lineDashLength > 0) {
lineDash = (SplashCoord *)gmallocn(lineDashLength, sizeof(SplashCoord));
memcpy(lineDash, lineDashA, lineDashLength * sizeof(SplashCoord));
} else {
lineDash = NULL;
}
lineDashPhase = lineDashPhaseA;
}

View File

@ -1,91 +0,0 @@
//========================================================================
//
// SplashState.h
//
//========================================================================
#ifndef SPLASHSTATE_H
#define SPLASHSTATE_H
#include <aconf.h>
#ifdef USE_GCC_PRAGMAS
#pragma interface
#endif
#include "SplashTypes.h"
class SplashPattern;
class SplashScreen;
class SplashClip;
//------------------------------------------------------------------------
// line cap values
//------------------------------------------------------------------------
#define splashLineCapButt 0
#define splashLineCapRound 1
#define splashLineCapProjecting 2
//------------------------------------------------------------------------
// line join values
//------------------------------------------------------------------------
#define splashLineJoinMiter 0
#define splashLineJoinRound 1
#define splashLineJoinBevel 2
//------------------------------------------------------------------------
// SplashState
//------------------------------------------------------------------------
class SplashState {
public:
// Create a new state object, initialized with default settings.
SplashState(int width, int height);
// Copy a state object.
SplashState *copy() { return new SplashState(this); }
~SplashState();
// Set the stroke pattern. This does not copy <strokePatternA>.
void setStrokePattern(SplashPattern *strokePatternA);
// Set the fill pattern. This does not copy <fillPatternA>.
void setFillPattern(SplashPattern *fillPatternA);
// Set the screen. This does not copy <screenA>.
void setScreen(SplashScreen *screenA);
// Set the line dash pattern. This copies the <lineDashA> array.
void setLineDash(SplashCoord *lineDashA, int lineDashLengthA,
SplashCoord lineDashPhaseA);
private:
SplashState(SplashState *state);
SplashPattern *strokePattern;
SplashPattern *fillPattern;
SplashScreen *screen;
SplashBlendFunc blendFunc;
SplashCoord strokeAlpha;
SplashCoord fillAlpha;
SplashCoord lineWidth;
int lineCap;
int lineJoin;
SplashCoord miterLimit;
SplashCoord flatness;
SplashCoord *lineDash;
int lineDashLength;
SplashCoord lineDashPhase;
SplashClip *clip;
SplashState *next; // used by Splash class
friend class Splash;
};
#endif

View File

@ -1,264 +0,0 @@
//========================================================================
//
// SplashT1Font.cc
//
//========================================================================
#include <aconf.h>
#if HAVE_T1LIB_H
#ifdef USE_GCC_PRAGMAS
#pragma implementation
#endif
#include <stdlib.h>
#include <t1lib.h>
#include "gmem.h"
#include "SplashMath.h"
#include "SplashGlyphBitmap.h"
#include "SplashPath.h"
#include "SplashT1FontEngine.h"
#include "SplashT1FontFile.h"
#include "SplashT1Font.h"
//------------------------------------------------------------------------
static Guchar bitReverse[256] = {
0x00, 0x80, 0x40, 0xc0, 0x20, 0xa0, 0x60, 0xe0,
0x10, 0x90, 0x50, 0xd0, 0x30, 0xb0, 0x70, 0xf0,
0x08, 0x88, 0x48, 0xc8, 0x28, 0xa8, 0x68, 0xe8,
0x18, 0x98, 0x58, 0xd8, 0x38, 0xb8, 0x78, 0xf8,
0x04, 0x84, 0x44, 0xc4, 0x24, 0xa4, 0x64, 0xe4,
0x14, 0x94, 0x54, 0xd4, 0x34, 0xb4, 0x74, 0xf4,
0x0c, 0x8c, 0x4c, 0xcc, 0x2c, 0xac, 0x6c, 0xec,
0x1c, 0x9c, 0x5c, 0xdc, 0x3c, 0xbc, 0x7c, 0xfc,
0x02, 0x82, 0x42, 0xc2, 0x22, 0xa2, 0x62, 0xe2,
0x12, 0x92, 0x52, 0xd2, 0x32, 0xb2, 0x72, 0xf2,
0x0a, 0x8a, 0x4a, 0xca, 0x2a, 0xaa, 0x6a, 0xea,
0x1a, 0x9a, 0x5a, 0xda, 0x3a, 0xba, 0x7a, 0xfa,
0x06, 0x86, 0x46, 0xc6, 0x26, 0xa6, 0x66, 0xe6,
0x16, 0x96, 0x56, 0xd6, 0x36, 0xb6, 0x76, 0xf6,
0x0e, 0x8e, 0x4e, 0xce, 0x2e, 0xae, 0x6e, 0xee,
0x1e, 0x9e, 0x5e, 0xde, 0x3e, 0xbe, 0x7e, 0xfe,
0x01, 0x81, 0x41, 0xc1, 0x21, 0xa1, 0x61, 0xe1,
0x11, 0x91, 0x51, 0xd1, 0x31, 0xb1, 0x71, 0xf1,
0x09, 0x89, 0x49, 0xc9, 0x29, 0xa9, 0x69, 0xe9,
0x19, 0x99, 0x59, 0xd9, 0x39, 0xb9, 0x79, 0xf9,
0x05, 0x85, 0x45, 0xc5, 0x25, 0xa5, 0x65, 0xe5,
0x15, 0x95, 0x55, 0xd5, 0x35, 0xb5, 0x75, 0xf5,
0x0d, 0x8d, 0x4d, 0xcd, 0x2d, 0xad, 0x6d, 0xed,
0x1d, 0x9d, 0x5d, 0xdd, 0x3d, 0xbd, 0x7d, 0xfd,
0x03, 0x83, 0x43, 0xc3, 0x23, 0xa3, 0x63, 0xe3,
0x13, 0x93, 0x53, 0xd3, 0x33, 0xb3, 0x73, 0xf3,
0x0b, 0x8b, 0x4b, 0xcb, 0x2b, 0xab, 0x6b, 0xeb,
0x1b, 0x9b, 0x5b, 0xdb, 0x3b, 0xbb, 0x7b, 0xfb,
0x07, 0x87, 0x47, 0xc7, 0x27, 0xa7, 0x67, 0xe7,
0x17, 0x97, 0x57, 0xd7, 0x37, 0xb7, 0x77, 0xf7,
0x0f, 0x8f, 0x4f, 0xcf, 0x2f, 0xaf, 0x6f, 0xef,
0x1f, 0x9f, 0x5f, 0xdf, 0x3f, 0xbf, 0x7f, 0xff
};
//------------------------------------------------------------------------
// SplashT1Font
//------------------------------------------------------------------------
SplashT1Font::SplashT1Font(SplashT1FontFile *fontFileA, SplashCoord *matA):
SplashFont(fontFileA, matA, ((SplashT1FontFile *)fontFileA)->engine->aa)
{
T1_TMATRIX matrix;
BBox bbox;
SplashCoord bbx0, bby0, bbx1, bby1;
int x, y;
t1libID = T1_CopyFont(fontFileA->t1libID);
// compute font size
size = (float)splashSqrt(mat[2]*mat[2] + mat[3]*mat[3]);
// transform the four corners of the font bounding box -- the min
// and max values form the bounding box of the transformed font
bbox = T1_GetFontBBox(t1libID);
bbx0 = 0.001 * bbox.llx;
bby0 = 0.001 * bbox.lly;
bbx1 = 0.001 * bbox.urx;
bby1 = 0.001 * bbox.ury;
// some fonts are completely broken, so we fake it (with values
// large enough that most glyphs should fit)
if (bbx0 == 0 && bby0 == 0 && bbx1 == 0 && bby1 == 0) {
bbx0 = bby0 = -0.5;
bbx1 = bby1 = 1.5;
}
x = (int)(mat[0] * bbx0 + mat[2] * bby0);
xMin = xMax = x;
y = (int)(mat[1] * bbx0 + mat[3] * bby0);
yMin = yMax = y;
x = (int)(mat[0] * bbx0 + mat[2] * bby1);
if (x < xMin) {
xMin = x;
} else if (x > xMax) {
xMax = x;
}
y = (int)(mat[1] * bbx0 + mat[3] * bby1);
if (y < yMin) {
yMin = y;
} else if (y > yMax) {
yMax = y;
}
x = (int)(mat[0] * bbx1 + mat[2] * bby0);
if (x < xMin) {
xMin = x;
} else if (x > xMax) {
xMax = x;
}
y = (int)(mat[1] * bbx1 + mat[3] * bby0);
if (y < yMin) {
yMin = y;
} else if (y > yMax) {
yMax = y;
}
x = (int)(mat[0] * bbx1 + mat[2] * bby1);
if (x < xMin) {
xMin = x;
} else if (x > xMax) {
xMax = x;
}
y = (int)(mat[1] * bbx1 + mat[3] * bby1);
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);
}
// Another kludge: an unusually large xMin or yMin coordinate is
// probably wrong.
if (xMin > 0) {
xMin = 0;
}
if (yMin > 0) {
yMin = 0;
}
// Another kludge: t1lib doesn't correctly handle fonts with
// real (non-integer) bounding box coordinates.
if (xMax - xMin > 5000) {
xMin = 0;
xMax = (int)size;
}
if (yMax - yMin > 5000) {
yMin = 0;
yMax = (int)(1.2 * size);
}
// transform the font
matrix.cxx = (double)mat[0] / size;
matrix.cxy = (double)mat[1] / size;
matrix.cyx = (double)mat[2] / size;
matrix.cyy = (double)mat[3] / size;
T1_TransformFont(t1libID, &matrix);
}
SplashT1Font::~SplashT1Font() {
T1_DeleteFont(t1libID);
}
GBool SplashT1Font::getGlyph(int c, int /*xFrac*/, int /*yFrac*/,
SplashGlyphBitmap *bitmap) {
return SplashFont::getGlyph(c, 0, 0, bitmap);
}
GBool SplashT1Font::makeGlyph(int c, int /*xFrac*/, int /*yFrac*/,
SplashGlyphBitmap *bitmap) {
GLYPH *glyph;
int n, i;
if (aa) {
glyph = T1_AASetChar(t1libID, c, size, NULL);
} else {
glyph = T1_SetChar(t1libID, c, size, NULL);
}
if (!glyph) {
return gFalse;
}
bitmap->x = -glyph->metrics.leftSideBearing;
bitmap->y = glyph->metrics.ascent;
bitmap->w = glyph->metrics.rightSideBearing - glyph->metrics.leftSideBearing;
bitmap->h = glyph->metrics.ascent - glyph->metrics.descent;
bitmap->aa = aa;
if (aa) {
bitmap->data = (Guchar *)glyph->bits;
bitmap->freeData = gFalse;
} else {
n = bitmap->h * ((bitmap->w + 7) >> 3);
bitmap->data = (Guchar *)gmalloc(n);
for (i = 0; i < n; ++i) {
bitmap->data[i] = bitReverse[glyph->bits[i] & 0xff];
}
bitmap->freeData = gTrue;
}
return gTrue;
}
SplashPath *SplashT1Font::getGlyphPath(int c) {
SplashPath *path;
T1_OUTLINE *outline;
T1_PATHSEGMENT *seg;
T1_BEZIERSEGMENT *bez;
SplashCoord x, y, x1, y1;
GBool needClose;
path = new SplashPath();
if (!(outline = T1_GetCharOutline(t1libID, c, size, NULL))) {
return path;
}
x = 0;
y = 0;
needClose = gFalse;
for (seg = outline; seg; seg = seg->link) {
switch (seg->type) {
case T1_PATHTYPE_MOVE:
if (needClose) {
path->close();
needClose = gFalse;
}
x += seg->dest.x / 65536.0;
y += seg->dest.y / 65536.0;
path->moveTo(x, y);
break;
case T1_PATHTYPE_LINE:
x += seg->dest.x / 65536.0;
y += seg->dest.y / 65536.0;
path->lineTo(x, y);
needClose = gTrue;
break;
case T1_PATHTYPE_BEZIER:
bez = (T1_BEZIERSEGMENT *)seg;
x1 = x + bez->dest.x / 65536.0;
y1 = y + bez->dest.y / 65536.0;
path->curveTo(x + bez->B.x / 65536.0, y + bez->B.y / 65536.0,
x + bez->C.x / 65536.0, y + bez->C.y / 65536.0,
x1, y1);
x = x1;
y = y1;
needClose = gTrue;
break;
}
}
if (needClose) {
path->close();
}
T1_FreeOutline(outline);
return path;
}
#endif // HAVE_T1LIB_H

View File

@ -1,53 +0,0 @@
//========================================================================
//
// SplashT1Font.h
//
//========================================================================
#ifndef SPLASHT1FONT_H
#define SPLASHT1FONT_H
#include <aconf.h>
#if HAVE_T1LIB_H
#ifdef USE_GCC_PRAGMAS
#pragma interface
#endif
#include "SplashFont.h"
class SplashT1FontFile;
//------------------------------------------------------------------------
// SplashT1Font
//------------------------------------------------------------------------
class SplashT1Font: public SplashFont {
public:
SplashT1Font(SplashT1FontFile *fontFileA, SplashCoord *matA);
virtual ~SplashT1Font();
// Munge xFrac and yFrac before calling SplashFont::getGlyph.
virtual GBool getGlyph(int c, int xFrac, int yFrac,
SplashGlyphBitmap *bitmap);
// Rasterize a glyph. The <xFrac> and <yFrac> values are the same
// as described for getGlyph.
virtual GBool makeGlyph(int c, int xFrac, int yFrac,
SplashGlyphBitmap *bitmap);
// Return the path for a glyph.
virtual SplashPath *getGlyphPath(int c);
private:
int t1libID; // t1lib font ID
float size;
};
#endif // HAVE_T1LIB_H
#endif

View File

@ -1,122 +0,0 @@
//========================================================================
//
// SplashT1FontEngine.cc
//
//========================================================================
#include <aconf.h>
#if HAVE_T1LIB_H
#ifdef USE_GCC_PRAGMAS
#pragma implementation
#endif
#include <stdlib.h>
#include <stdio.h>
#ifndef WIN32
# include <unistd.h>
#endif
#include <t1lib.h>
#include "GString.h"
#include "gfile.h"
#include "FoFiType1C.h"
#include "SplashT1FontFile.h"
#include "SplashT1FontEngine.h"
#ifdef VMS
#if (__VMS_VER < 70000000)
extern "C" int unlink(char *filename);
#endif
#endif
//------------------------------------------------------------------------
int SplashT1FontEngine::t1libInitCount = 0;
//------------------------------------------------------------------------
static void T1_fileWrite(void *stream, const char *data, int len) {
fwrite(data, 1, len, (FILE *)stream);
}
//------------------------------------------------------------------------
// SplashT1FontEngine
//------------------------------------------------------------------------
SplashT1FontEngine::SplashT1FontEngine(GBool aaA) {
aa = aaA;
}
SplashT1FontEngine *SplashT1FontEngine::init(GBool aaA) {
// grayVals[i] = round(i * 255 / 16)
static unsigned long grayVals[17] = {
0, 16, 32, 48, 64, 80, 96, 112, 128, 143, 159, 175, 191, 207, 223, 239, 255
};
//~ for multithreading: need a mutex here
if (t1libInitCount == 0) {
T1_SetBitmapPad(8);
if (!T1_InitLib(NO_LOGFILE | IGNORE_CONFIGFILE | IGNORE_FONTDATABASE |
T1_NO_AFM)) {
return NULL;
}
if (aaA) {
T1_AASetBitsPerPixel(8);
T1_AASetLevel(T1_AA_HIGH);
T1_AAHSetGrayValues(grayVals);
} else {
T1_AANSetGrayValues(0, 1);
}
}
++t1libInitCount;
return new SplashT1FontEngine(aaA);
}
SplashT1FontEngine::~SplashT1FontEngine() {
//~ for multithreading: need a mutex here
if (--t1libInitCount == 0) {
T1_CloseLib();
}
}
SplashFontFile *SplashT1FontEngine::loadType1Font(SplashFontFileID *idA,
SplashFontSrc *src,
const char **enc) {
return SplashT1FontFile::loadType1Font(this, idA, src, enc);
}
SplashFontFile *SplashT1FontEngine::loadType1CFont(SplashFontFileID *idA,
SplashFontSrc *src,
const char **enc) {
FoFiType1C *ff;
GString *tmpFileName;
FILE *tmpFile;
SplashFontFile *ret;
SplashFontSrc *newsrc;
if (src->isFile)
ff = FoFiType1C::load(src->fileName);
else
ff = new FoFiType1C(src->buf, src->bufLen, gFalse);
if (! ff)
return NULL;
}
tmpFileName = NULL;
if (!openTempFile(&tmpFileName, &tmpFile, "wb", NULL)) {
delete ff;
return NULL;
}
ff->convertToType1(NULL, gTrue, &T1_fileWrite, tmpFile);
delete ff;
fclose(tmpFile);
newsrc = new SplashFontSrc;
newsrc->setFile(tmpFileName, gTrue);
delete tmpFileName;
ret = SplashT1FontFile::loadType1Font(this, idA, newsrc, enc);
newsrc->unref();
return ret;
}
#endif // HAVE_T1LIB_H

View File

@ -1,53 +0,0 @@
//========================================================================
//
// SplashT1FontEngine.h
//
//========================================================================
#ifndef SPLASHT1FONTENGINE_H
#define SPLASHT1FONTENGINE_H
#include <aconf.h>
#if HAVE_T1LIB_H
#ifdef USE_GCC_PRAGMAS
#pragma interface
#endif
#include "gtypes.h"
class SplashFontFile;
class SplashFontFileID;
//------------------------------------------------------------------------
// SplashT1FontEngine
//------------------------------------------------------------------------
class SplashT1FontEngine {
public:
static SplashT1FontEngine *init(GBool aaA);
~SplashT1FontEngine();
// Load fonts.
SplashFontFile *loadType1Font(SplashFontFileID *idA, char *fileName,
GBool deleteFile, const char **enc);
SplashFontFile *loadType1CFont(SplashFontFileID *idA, char *fileName,
GBool deleteFile, const char **enc);
private:
SplashT1FontEngine(GBool aaA);
static int t1libInitCount;
GBool aa;
friend class SplashT1FontFile;
friend class SplashT1Font;
};
#endif // HAVE_T1LIB_H
#endif

View File

@ -1,116 +0,0 @@
//========================================================================
//
// SplashT1FontFile.cc
//
//========================================================================
#include <aconf.h>
#if HAVE_T1LIB_H
#ifdef USE_GCC_PRAGMAS
#pragma implementation
#endif
#include <string.h>
#include <t1lib.h>
#include "gmem.h"
#include "SplashT1FontEngine.h"
#include "SplashT1Font.h"
#include "SplashT1FontFile.h"
//------------------------------------------------------------------------
// SplashT1FontFile
//------------------------------------------------------------------------
SplashFontFile *SplashT1FontFile::loadType1Font(SplashT1FontEngine *engineA,
SplashFontFileID *idA,
SplashFontSrc *src,
const char **encA) {
int t1libIDA;
const char **encTmp;
char *encStrTmp;
int encStrSize;
char *encPtr;
int i;
GString *fileNameA;
SplashFontSrc *newsrc = NULL;
SplashFontFile *ff;
if (! src->isFile) {
GString *tmpFileName;
FILE *tmpFile;
if (!openTempFile(&tmpFileName, &tmpFile, "wb", NULL))
return NULL;
fwrite(src->buf, 1, src->bufLen, tmpFile);
fclose(tmpFile);
newsrc = new SplashFontSrc;
newsrc->setFile(tmpFileName, gTrue);
src = newsrc;
delete tmpFileName;
}
fileNameA = src->fileName;
// load the font file
if ((t1libIDA = T1_AddFont(fileNameA)) < 0) {
if (newsrc)
delete newsrc;
return NULL;
}
T1_LoadFont(t1libIDA);
// reencode it
encStrSize = 0;
for (i = 0; i < 256; ++i) {
if (encA[i]) {
encStrSize += strlen(encA[i]) + 1;
}
}
encTmp = (const char **)gmallocn(257, sizeof(char *));
encStrTmp = (char *)gmallocn(encStrSize, sizeof(char));
encPtr = encStrTmp;
for (i = 0; i < 256; ++i) {
if (encA[i]) {
strcpy(encPtr, encA[i]);
encTmp[i] = encPtr;
encPtr += strlen(encPtr) + 1;
} else {
encTmp[i] = ".notdef";
}
}
encTmp[256] = "custom";
T1_ReencodeFont(t1libIDA, (char**)encTmp);
ff = new SplashT1FontFile(engineA, idA, src,
t1libIDA, encTmp, encStrTmp);
if (newsrc)
newsrc->unref();
return ff;
}
SplashT1FontFile::SplashT1FontFile(SplashT1FontEngine *engineA,
SplashFontFileID *idA,
SplashFontSrc *srcA,
int t1libIDA, const char **encA, char *encStrA):
SplashFontFile(idA, srcA)
{
engine = engineA;
t1libID = t1libIDA;
enc = encA;
encStr = encStrA;
}
SplashT1FontFile::~SplashT1FontFile() {
gfree(encStr);
gfree(enc);
T1_DeleteFont(t1libID);
}
SplashFont *SplashT1FontFile::makeFont(SplashCoord *mat) {
SplashFont *font;
font = new SplashT1Font(this, mat);
font->initCache();
return font;
}
#endif // HAVE_T1LIB_H

View File

@ -1,57 +0,0 @@
//========================================================================
//
// SplashT1FontFile.h
//
//========================================================================
#ifndef SPLASHT1FONTFILE_H
#define SPLASHT1FONTFILE_H
#include <aconf.h>
#if HAVE_T1LIB_H
#ifdef USE_GCC_PRAGMAS
#pragma interface
#endif
#include "SplashFontFile.h"
class SplashT1FontEngine;
//------------------------------------------------------------------------
// SplashT1FontFile
//------------------------------------------------------------------------
class SplashT1FontFile: public SplashFontFile {
public:
static SplashFontFile *loadType1Font(SplashT1FontEngine *engineA,
SplashFontFileID *idA,
SplashFontSrc *src,
const char **encA);
virtual ~SplashT1FontFile();
// Create a new SplashT1Font, i.e., a scaled instance of this font
// file.
virtual SplashFont *makeFont(SplashCoord *mat);
private:
SplashT1FontFile(SplashT1FontEngine *engineA,
SplashFontFileID *idA,
SplashFontSrc *src,
int t1libIDA, const char **encA, char *encStrA);
SplashT1FontEngine *engine;
int t1libID; // t1lib font ID
const char **enc;
char *encStr;
friend class SplashT1Font;
};
#endif // HAVE_T1LIB_H
#endif

View File

@ -1,134 +0,0 @@
//========================================================================
//
// SplashTypes.h
//
//========================================================================
#ifndef SPLASHTYPES_H
#define SPLASHTYPES_H
#include <aconf.h>
#include "gtypes.h"
//------------------------------------------------------------------------
// coordinates
//------------------------------------------------------------------------
typedef double SplashCoord;
//------------------------------------------------------------------------
// colors
//------------------------------------------------------------------------
enum SplashColorMode {
splashModeMono1, // 1 bit per component, 8 pixels per byte,
// MSbit is on the left
splashModeMono8, // 1 byte per component, 1 byte per pixel
splashModeAMono8, // 1 byte per component, 2 bytes per pixel:
// AMAM...
splashModeRGB8, // 1 byte per component, 3 bytes per pixel:
// RGBRGB...
splashModeBGR8, // 1 byte per component, 3 bytes per pixel:
// BGRBGR...
splashModeARGB8, // 1 byte per component, 4 bytes per pixel:
// ARGBARGB...
splashModeBGRA8 // 1 byte per component, 4 bytes per pixel:
// BGRABGRA...
#if SPLASH_CMYK
,
splashModeCMYK8, // 1 byte per component, 4 bytes per pixel:
// CMYKCMYK...
splashModeACMYK8 // 1 byte per component, 5 bytes per pixel:
// ACMYKACMYK
#endif
};
// number of components in each color mode
// (defined in SplashState.cc)
extern int splashColorModeNComps[];
// max number of components in any SplashColor
#if SPLASH_CMYK
# define splashMaxColorComps 5
#else
# define splashMaxColorComps 4
#endif
typedef Guchar SplashColor[splashMaxColorComps];
typedef Guchar *SplashColorPtr;
// AMono8
static inline Guchar splashAMono8A(SplashColorPtr am8) { return am8[0]; }
static inline Guchar splashAMono8M(SplashColorPtr am8) { return am8[1]; }
// RGB8
static inline Guchar splashRGB8R(SplashColorPtr rgb8) { return rgb8[0]; }
static inline Guchar splashRGB8G(SplashColorPtr rgb8) { return rgb8[1]; }
static inline Guchar splashRGB8B(SplashColorPtr rgb8) { return rgb8[2]; }
// BGR8
static inline Guchar splashBGR8R(SplashColorPtr bgr8) { return bgr8[2]; }
static inline Guchar splashBGR8G(SplashColorPtr bgr8) { return bgr8[1]; }
static inline Guchar splashBGR8B(SplashColorPtr bgr8) { return bgr8[0]; }
// ARGB8
static inline Guchar splashARGB8A(SplashColorPtr argb8) { return argb8[0]; }
static inline Guchar splashARGB8R(SplashColorPtr argb8) { return argb8[1]; }
static inline Guchar splashARGB8G(SplashColorPtr argb8) { return argb8[2]; }
static inline Guchar splashARGB8B(SplashColorPtr argb8) { return argb8[3]; }
// ARGB8
static inline Guchar splashBGRA8A(SplashColorPtr bgra8) { return bgra8[3]; }
static inline Guchar splashBGRA8R(SplashColorPtr bgra8) { return bgra8[2]; }
static inline Guchar splashBGRA8G(SplashColorPtr bgra8) { return bgra8[1]; }
static inline Guchar splashBGRA8B(SplashColorPtr bgra8) { return bgra8[0]; }
#if SPLASH_CMYK
// CMYK8
static inline Guchar splashCMYK8C(SplashColorPtr cmyk8) { return cmyk8[0]; }
static inline Guchar splashCMYK8M(SplashColorPtr cmyk8) { return cmyk8[1]; }
static inline Guchar splashCMYK8Y(SplashColorPtr cmyk8) { return cmyk8[2]; }
static inline Guchar splashCMYK8K(SplashColorPtr cmyk8) { return cmyk8[3]; }
// ACMYK8
static inline Guchar splashACMYK8A(SplashColorPtr acmyk8) { return acmyk8[0]; }
static inline Guchar splashACMYK8C(SplashColorPtr acmyk8) { return acmyk8[1]; }
static inline Guchar splashACMYK8M(SplashColorPtr acmyk8) { return acmyk8[2]; }
static inline Guchar splashACMYK8Y(SplashColorPtr acmyk8) { return acmyk8[3]; }
static inline Guchar splashACMYK8K(SplashColorPtr acmyk8) { return acmyk8[4]; }
#endif
static inline void splashColorCopy(SplashColorPtr dest, SplashColorPtr src) {
dest[0] = src[0];
dest[1] = src[1];
dest[2] = src[2];
dest[3] = src[3];
#if SPLASH_CMYK
dest[4] = src[4];
#endif
}
static inline void splashColorXor(SplashColorPtr dest, SplashColorPtr src) {
dest[0] ^= src[0];
dest[1] ^= src[1];
dest[2] ^= src[2];
dest[3] ^= src[3];
#if SPLASH_CMYK
dest[4] ^= src[4];
#endif
}
//------------------------------------------------------------------------
// blend functions
//------------------------------------------------------------------------
typedef void (*SplashBlendFunc)(SplashColorPtr src, SplashColorPtr dest,
SplashColorPtr blend, SplashColorMode cm);
//------------------------------------------------------------------------
// error results
//------------------------------------------------------------------------
typedef int SplashError;
#endif

View File

@ -1,414 +0,0 @@
//========================================================================
//
// SplashXPath.cc
//
//========================================================================
#include <aconf.h>
#ifdef USE_GCC_PRAGMAS
#pragma implementation
#endif
#include <stdlib.h>
#include <string.h>
#include "gmem.h"
#include "SplashMath.h"
#include "SplashPath.h"
#include "SplashXPath.h"
//------------------------------------------------------------------------
#define maxCurveSplits (1 << 10)
//------------------------------------------------------------------------
// SplashXPath
//------------------------------------------------------------------------
SplashXPath::SplashXPath() {
segs = NULL;
length = size = 0;
}
SplashXPath::SplashXPath(SplashPath *path, SplashCoord flatness,
GBool closeSubpaths) {
SplashCoord xc, yc, dx, dy, r, x0, y0, x1, y1;
int quad0, quad1, quad;
int curSubpath, n, i, j;
segs = NULL;
length = size = 0;
i = 0;
curSubpath = 0;
while (i < path->length) {
// first point in subpath - skip it
if (path->flags[i] & splashPathFirst) {
curSubpath = i;
++i;
} else {
// curve segment
if (path->flags[i] & splashPathCurve) {
addCurve(path->pts[i-1].x, path->pts[i-1].y,
path->pts[i ].x, path->pts[i ].y,
path->pts[i+1].x, path->pts[i+1].y,
path->pts[i+2].x, path->pts[i+2].y,
flatness,
(path->flags[i-1] & splashPathFirst),
(path->flags[i+2] & splashPathLast),
!closeSubpaths &&
(path->flags[i-1] & splashPathFirst) &&
!(path->flags[i-1] & splashPathClosed),
!closeSubpaths &&
(path->flags[i+2] & splashPathLast) &&
!(path->flags[i+2] & splashPathClosed));
i += 3;
// clockwise circular arc
} else if (path->flags[i] & splashPathArcCW) {
xc = path->pts[i].x;
yc = path->pts[i].y;
dx = path->pts[i+1].x - xc;
dy = path->pts[i+1].y - yc;
r = splashSqrt(dx * dx + dy * dy);
if (path->pts[i-1].x < xc && path->pts[i-1].y <= yc) {
quad0 = 0;
} else if (path->pts[i-1].x >= xc && path->pts[i-1].y < yc) {
quad0 = 1;
} else if (path->pts[i-1].x > xc && path->pts[i-1].y >= yc) {
quad0 = 2;
} else {
quad0 = 3;
}
if (path->pts[i+1].x <= xc && path->pts[i+1].y < yc) {
quad1 = 0;
} else if (path->pts[i+1].x > xc && path->pts[i+1].y <= yc) {
quad1 = 1;
} else if (path->pts[i+1].x >= xc && path->pts[i+1].y > yc) {
quad1 = 2;
} else {
quad1 = 3;
}
n = 0; // make gcc happy
if (quad0 == quad1) {
switch (quad0) {
case 0:
case 1: n = path->pts[i-1].x < path->pts[i+1].x ? 0 : 4; break;
case 2:
case 3: n = path->pts[i-1].x > path->pts[i+1].x ? 0 : 4; break;
}
} else {
n = (quad1 - quad0) & 3;
}
x0 = path->pts[i-1].x;
y0 = path->pts[i-1].y;
x1 = y1 = 0; // make gcc happy
quad = quad0;
for (j = 0; j < n; ++j) {
switch (quad) {
case 0: x1 = xc; y1 = yc - r; break;
case 1: x1 = xc + r; y1 = yc; break;
case 2: x1 = xc; y1 = yc + r; break;
case 3: x1 = xc - r; y1 = yc; break;
}
addArc(x0, y0, x1, y1,
xc, yc, r, quad, flatness,
quad == quad0 && (path->flags[i-1] & splashPathFirst),
gFalse,
quad == quad0 && !closeSubpaths &&
(path->flags[i-1] & splashPathFirst) &&
!(path->flags[i-1] & splashPathClosed),
gFalse);
x0 = x1;
y0 = y1;
quad = (quad + 1) & 3;
}
addArc(x0, y0, path->pts[i+1].x, path->pts[i+1].y,
xc, yc, r, quad, flatness,
quad == quad0 && (path->flags[i-1] & splashPathFirst),
(path->flags[i+1] & splashPathLast),
quad == quad0 && !closeSubpaths &&
(path->flags[i-1] & splashPathFirst) &&
!(path->flags[i-1] & splashPathClosed),
!closeSubpaths &&
(path->flags[i+1] & splashPathLast) &&
!(path->flags[i+1] & splashPathClosed));
i += 2;
// line segment
} else {
addSegment(path->pts[i-1].x, path->pts[i-1].y,
path->pts[i].x, path->pts[i].y,
path->flags[i-1] & splashPathFirst,
path->flags[i] & splashPathLast,
!closeSubpaths &&
(path->flags[i-1] & splashPathFirst) &&
!(path->flags[i-1] & splashPathClosed),
!closeSubpaths &&
(path->flags[i] & splashPathLast) &&
!(path->flags[i] & splashPathClosed));
++i;
}
// close a subpath
if (closeSubpaths &&
(path->flags[i-1] & splashPathLast) &&
(path->pts[i-1].x != path->pts[curSubpath].x ||
path->pts[i-1].y != path->pts[curSubpath]. y)) {
addSegment(path->pts[i-1].x, path->pts[i-1].y,
path->pts[curSubpath].x, path->pts[curSubpath].y,
gFalse, gTrue, gFalse, gFalse);
}
}
}
}
SplashXPath::SplashXPath(SplashXPath *xPath) {
length = xPath->length;
size = xPath->size;
segs = (SplashXPathSeg *)gmallocn(size, sizeof(SplashXPathSeg));
memcpy(segs, xPath->segs, length * sizeof(SplashXPathSeg));
}
SplashXPath::~SplashXPath() {
gfree(segs);
}
// Add space for <nSegs> more segments
void SplashXPath::grow(int nSegs) {
if (length + nSegs > size) {
if (size == 0) {
size = 32;
}
while (size < length + nSegs) {
size *= 2;
}
segs = (SplashXPathSeg *)greallocn(segs, size, sizeof(SplashXPathSeg));
}
}
void SplashXPath::addCurve(SplashCoord x0, SplashCoord y0,
SplashCoord x1, SplashCoord y1,
SplashCoord x2, SplashCoord y2,
SplashCoord x3, SplashCoord y3,
SplashCoord flatness,
GBool first, GBool last, GBool end0, GBool end1) {
SplashCoord cx[maxCurveSplits + 1][3];
SplashCoord cy[maxCurveSplits + 1][3];
int cNext[maxCurveSplits + 1];
SplashCoord xl0, xl1, xl2, xr0, xr1, xr2, xr3, xx1, xx2, xh;
SplashCoord yl0, yl1, yl2, yr0, yr1, yr2, yr3, yy1, yy2, yh;
SplashCoord dx, dy, mx, my, d1, d2, flatness2;
int p1, p2, p3;
flatness2 = flatness * flatness;
// initial segment
p1 = 0;
p2 = maxCurveSplits;
cx[p1][0] = x0; cy[p1][0] = y0;
cx[p1][1] = x1; cy[p1][1] = y1;
cx[p1][2] = x2; cy[p1][2] = y2;
cx[p2][0] = x3; cy[p2][0] = y3;
cNext[p1] = p2;
while (p1 < maxCurveSplits) {
// get the next segment
xl0 = cx[p1][0]; yl0 = cy[p1][0];
xx1 = cx[p1][1]; yy1 = cy[p1][1];
xx2 = cx[p1][2]; yy2 = cy[p1][2];
p2 = cNext[p1];
xr3 = cx[p2][0]; yr3 = cy[p2][0];
// compute the distances from the control points to the
// midpoint of the straight line (this is a bit of a hack, but
// it's much faster than computing the actual distances to the
// line)
mx = (xl0 + xr3) * 0.5;
my = (yl0 + yr3) * 0.5;
dx = xx1 - mx;
dy = yy1 - my;
d1 = dx*dx + dy*dy;
dx = xx2 - mx;
dy = yy2 - my;
d2 = dx*dx + dy*dy;
// if the curve is flat enough, or no more subdivisions are
// allowed, add the straight line segment
if (p2 - p1 == 1 || (d1 <= flatness2 && d2 <= flatness2)) {
addSegment(xl0, yl0, xr3, yr3,
p1 == 0 && first,
p2 == maxCurveSplits && last,
p1 == 0 && end0,
p2 == maxCurveSplits && end1);
p1 = p2;
// otherwise, subdivide the curve
} else {
xl1 = (xl0 + xx1) * 0.5;
yl1 = (yl0 + yy1) * 0.5;
xh = (xx1 + xx2) * 0.5;
yh = (yy1 + yy2) * 0.5;
xl2 = (xl1 + xh) * 0.5;
yl2 = (yl1 + yh) * 0.5;
xr2 = (xx2 + xr3) * 0.5;
yr2 = (yy2 + yr3) * 0.5;
xr1 = (xh + xr2) * 0.5;
yr1 = (yh + yr2) * 0.5;
xr0 = (xl2 + xr1) * 0.5;
yr0 = (yl2 + yr1) * 0.5;
// add the new subdivision points
p3 = (p1 + p2) / 2;
cx[p1][1] = xl1; cy[p1][1] = yl1;
cx[p1][2] = xl2; cy[p1][2] = yl2;
cNext[p1] = p3;
cx[p3][0] = xr0; cy[p3][0] = yr0;
cx[p3][1] = xr1; cy[p3][1] = yr1;
cx[p3][2] = xr2; cy[p3][2] = yr2;
cNext[p3] = p2;
}
}
}
void SplashXPath::addArc(SplashCoord x0, SplashCoord y0,
SplashCoord x1, SplashCoord y1,
SplashCoord xc, SplashCoord yc,
SplashCoord r, int quad,
SplashCoord flatness,
GBool first, GBool last, GBool end0, GBool end1) {
SplashCoord px[maxCurveSplits + 1];
SplashCoord py[maxCurveSplits + 1];
int pNext[maxCurveSplits + 1];
SplashCoord r2, flatness2;
SplashCoord xx0, yy0, xx1, yy1, xm, ym, t, dx, dy;
int p1, p2, p3;
r2 = r * r;
flatness2 = flatness * flatness;
// initial segment
p1 = 0;
p2 = maxCurveSplits;
px[p1] = x0; py[p1] = y0;
px[p2] = x1; py[p2] = y1;
pNext[p1] = p2;
while (p1 < maxCurveSplits) {
// get the next segment
xx0 = px[p1]; yy0 = py[p1];
p2 = pNext[p1];
xx1 = px[p2]; yy1 = py[p2];
// compute the arc midpoint
t = (xx0 - xc) * (xx1 - xc) - (yy0 - yc) * (yy1 - yc);
xm = splashSqrt((SplashCoord)0.5 * (r2 + t));
ym = splashSqrt((SplashCoord)0.5 * (r2 - t));
switch (quad) {
case 0: xm = xc - xm; ym = yc - ym; break;
case 1: xm = xc + xm; ym = yc - ym; break;
case 2: xm = xc + xm; ym = yc + ym; break;
case 3: xm = xc - xm; ym = yc + ym; break;
}
// compute distance from midpoint of straight segment to midpoint
// of arc
dx = (SplashCoord)0.5 * (xx0 + xx1) - xm;
dy = (SplashCoord)0.5 * (yy0 + yy1) - ym;
// if the arc is flat enough, or no more subdivisions are allowed,
// add the straight line segment
if (p2 - p1 == 1 || dx * dx + dy * dy <= flatness2) {
addSegment(xx0, yy0, xx1, yy1,
p1 == 0 && first,
p2 == maxCurveSplits && last,
p1 == 0 && end0,
p2 == maxCurveSplits && end1);
p1 = p2;
// otherwise, subdivide the arc
} else {
p3 = (p1 + p2) / 2;
px[p3] = xm;
py[p3] = ym;
pNext[p1] = p3;
pNext[p3] = p2;
}
}
}
void SplashXPath::addSegment(SplashCoord x0, SplashCoord y0,
SplashCoord x1, SplashCoord y1,
GBool first, GBool last, GBool end0, GBool end1) {
grow(1);
segs[length].x0 = x0;
segs[length].y0 = y0;
segs[length].x1 = x1;
segs[length].y1 = y1;
segs[length].flags = 0;
if (first) {
segs[length].flags |= splashXPathFirst;
}
if (last) {
segs[length].flags |= splashXPathLast;
}
if (end0) {
segs[length].flags |= splashXPathEnd0;
}
if (end1) {
segs[length].flags |= splashXPathEnd1;
}
if (y1 == y0) {
segs[length].dxdy = segs[length].dydx = 0;
segs[length].flags |= splashXPathHoriz;
if (x1 == x0) {
segs[length].flags |= splashXPathVert;
}
} else if (x1 == x0) {
segs[length].dxdy = segs[length].dydx = 0;
segs[length].flags |= splashXPathVert;
} else {
segs[length].dxdy = (x1 - x0) / (y1 - y0);
segs[length].dydx = (SplashCoord)1 / segs[length].dxdy;
}
if (y0 > y1) {
segs[length].flags |= splashXPathFlip;
}
++length;
}
static int cmpXPathSegs(const void *arg0, const void *arg1) {
SplashXPathSeg *seg0 = (SplashXPathSeg *)arg0;
SplashXPathSeg *seg1 = (SplashXPathSeg *)arg1;
SplashCoord x0, y0, x1, y1;
if (seg0->flags & splashXPathFlip) {
x0 = seg0->x1;
y0 = seg0->y1;
} else {
x0 = seg0->x0;
y0 = seg0->y0;
}
if (seg1->flags & splashXPathFlip) {
x1 = seg1->x1;
y1 = seg1->y1;
} else {
x1 = seg1->x0;
y1 = seg1->y0;
}
if (y0 != y1) {
return (y0 > y1) ? 1 : -1;
}
if (x0 != x1) {
return (x0 > x1) ? 1 : -1;
}
return 0;
}
void SplashXPath::sort() {
qsort(segs, length, sizeof(SplashXPathSeg), &cmpXPathSegs);
}

View File

@ -1,92 +0,0 @@
//========================================================================
//
// SplashXPath.h
//
//========================================================================
#ifndef SPLASHXPATH_H
#define SPLASHXPATH_H
#include <aconf.h>
#ifdef USE_GCC_PRAGMAS
#pragma interface
#endif
#include "SplashTypes.h"
class SplashPath;
//------------------------------------------------------------------------
// SplashXPathSeg
//------------------------------------------------------------------------
struct SplashXPathSeg {
SplashCoord x0, y0; // first endpoint
SplashCoord x1, y1; // second endpoint
SplashCoord dxdy; // slope: delta-x / delta-y
SplashCoord dydx; // slope: delta-y / delta-x
Guint flags;
};
#define splashXPathFirst 0x01 // first segment of a subpath
#define splashXPathLast 0x02 // last segment of a subpath
#define splashXPathEnd0 0x04 // first endpoint is end of an open subpath
#define splashXPathEnd1 0x08 // second endpoint is end of an open subpath
#define splashXPathHoriz 0x10 // segment is vertical (y0 == y1)
// (dxdy is undef)
#define splashXPathVert 0x20 // segment is horizontal (x0 == x1)
// (dydx is undef)
#define splashXPathFlip 0x40 // y0 > y1
//------------------------------------------------------------------------
// SplashXPath
//------------------------------------------------------------------------
class SplashXPath {
public:
// Expands (converts to segments) and flattens (converts curves to
// lines) <path>. If <closeSubpaths> is true, closes all open
// subpaths.
SplashXPath(SplashPath *path, SplashCoord flatness,
GBool closeSubpaths);
// Copy an expanded path.
SplashXPath *copy() { return new SplashXPath(this); }
~SplashXPath();
// Sort by upper coordinate (lower y), in y-major order.
void sort();
private:
SplashXPath();
SplashXPath(SplashXPath *xPath);
void grow(int nSegs);
void addCurve(SplashCoord x0, SplashCoord y0,
SplashCoord x1, SplashCoord y1,
SplashCoord x2, SplashCoord y2,
SplashCoord x3, SplashCoord y3,
SplashCoord flatness,
GBool first, GBool last, GBool end0, GBool end1);
void addArc(SplashCoord x0, SplashCoord y0,
SplashCoord x1, SplashCoord y1,
SplashCoord xc, SplashCoord yc,
SplashCoord r, int quad,
SplashCoord flatness,
GBool first, GBool last, GBool end0, GBool end1);
void addSegment(SplashCoord x0, SplashCoord y0,
SplashCoord x1, SplashCoord y1,
GBool first, GBool last, GBool end0, GBool end1);
SplashXPathSeg *segs;
int length, size; // length and size of segs array
friend class SplashXPathScanner;
friend class SplashClip;
friend class Splash;
};
#endif

View File

@ -1,277 +0,0 @@
//========================================================================
//
// SplashXPathScanner.cc
//
//========================================================================
#include <aconf.h>
#ifdef USE_GCC_PRAGMAS
#pragma implementation
#endif
#include <stdlib.h>
#include "gmem.h"
#include "SplashMath.h"
#include "SplashXPath.h"
#include "SplashXPathScanner.h"
//------------------------------------------------------------------------
struct SplashIntersect {
int x0, x1; // intersection of segment with [y, y+1)
int count; // EO/NZWN counter increment
};
static int cmpIntersect(const void *p0, const void *p1) {
return ((SplashIntersect *)p0)->x0 - ((SplashIntersect *)p1)->x0;
}
//------------------------------------------------------------------------
// SplashXPathScanner
//------------------------------------------------------------------------
SplashXPathScanner::SplashXPathScanner(SplashXPath *xPathA, GBool eoA) {
SplashXPathSeg *seg;
SplashCoord xMinFP, yMinFP, xMaxFP, yMaxFP;
int i;
xPath = xPathA;
eo = eoA;
// compute the bbox
if (xPath->length == 0) {
xMin = yMin = 1;
xMax = yMax = 0;
} else {
seg = &xPath->segs[0];
if (seg->x0 <= seg->x1) {
xMinFP = seg->x0;
xMaxFP = seg->x1;
} else {
xMinFP = seg->x1;
xMaxFP = seg->x0;
}
if (seg->flags & splashXPathFlip) {
yMinFP = seg->y1;
yMaxFP = seg->y0;
} else {
yMinFP = seg->y0;
yMaxFP = seg->y1;
}
for (i = 1; i < xPath->length; ++i) {
seg = &xPath->segs[i];
if (seg->x0 < xMinFP) {
xMinFP = seg->x0;
} else if (seg->x0 > xMaxFP) {
xMaxFP = seg->x0;
}
if (seg->x1 < xMinFP) {
xMinFP = seg->x1;
} else if (seg->x1 > xMaxFP) {
xMaxFP = seg->x1;
}
if (seg->flags & splashXPathFlip) {
if (seg->y0 > yMaxFP) {
yMaxFP = seg->y0;
}
} else {
if (seg->y1 > yMaxFP) {
yMaxFP = seg->y1;
}
}
}
xMin = splashFloor(xMinFP);
xMax = splashFloor(xMaxFP);
yMin = splashFloor(yMinFP);
yMax = splashFloor(yMaxFP);
}
interY = yMin - 1;
xPathIdx = 0;
inter = NULL;
interLen = interSize = 0;
}
SplashXPathScanner::~SplashXPathScanner() {
gfree(inter);
}
void SplashXPathScanner::getSpanBounds(int y, int *spanXMin, int *spanXMax) {
if (interY != y) {
computeIntersections(y);
}
if (interLen > 0) {
*spanXMin = inter[0].x0;
*spanXMax = inter[interLen - 1].x1;
} else {
*spanXMin = xMax + 1;
*spanXMax = xMax;
}
}
GBool SplashXPathScanner::test(int x, int y) {
int count, i;
if (interY != y) {
computeIntersections(y);
}
count = 0;
for (i = 0; i < interLen && inter[i].x0 <= x; ++i) {
if (x <= inter[i].x1) {
return gTrue;
}
count += inter[i].count;
}
return eo ? (count & 1) : (count != 0);
}
GBool SplashXPathScanner::testSpan(int x0, int x1, int y) {
int count, xx1, i;
if (interY != y) {
computeIntersections(y);
}
count = 0;
for (i = 0; i < interLen && inter[i].x1 < x0; ++i) {
count += inter[i].count;
}
// invariant: the subspan [x0,xx1] is inside the path
xx1 = x0 - 1;
while (xx1 < x1) {
if (i >= interLen) {
return gFalse;
}
if (inter[i].x0 > xx1 + 1 &&
!(eo ? (count & 1) : (count != 0))) {
return gFalse;
}
if (inter[i].x1 > xx1) {
xx1 = inter[i].x1;
}
count += inter[i].count;
++i;
}
return gTrue;
}
GBool SplashXPathScanner::getNextSpan(int y, int *x0, int *x1) {
int xx0, xx1;
if (interY != y) {
computeIntersections(y);
}
if (interIdx >= interLen) {
return gFalse;
}
xx0 = inter[interIdx].x0;
xx1 = inter[interIdx].x1;
interCount += inter[interIdx].count;
++interIdx;
while (interIdx < interLen &&
(inter[interIdx].x0 <= xx1 ||
(eo ? (interCount & 1) : (interCount != 0)))) {
if (inter[interIdx].x1 > xx1) {
xx1 = inter[interIdx].x1;
}
interCount += inter[interIdx].count;
++interIdx;
}
*x0 = xx0;
*x1 = xx1;
return gTrue;
}
void SplashXPathScanner::computeIntersections(int y) {
SplashCoord ySegMin, ySegMax, xx0, xx1;
SplashXPathSeg *seg;
int i, j;
// find the first segment that intersects [y, y+1)
i = (y >= interY) ? xPathIdx : 0;
while (i < xPath->length &&
xPath->segs[i].y0 < y && xPath->segs[i].y1 < y) {
++i;
}
xPathIdx = i;
// find all of the segments that intersect [y, y+1) and create an
// Intersect element for each one
interLen = 0;
for (j = i; j < xPath->length; ++j) {
seg = &xPath->segs[j];
if (seg->flags & splashXPathFlip) {
ySegMin = seg->y1;
ySegMax = seg->y0;
} else {
ySegMin = seg->y0;
ySegMax = seg->y1;
}
// ensure that: ySegMin < y+1
// y <= ySegMax
if (ySegMin >= y + 1) {
break;
}
if (ySegMax < y) {
continue;
}
if (interLen == interSize) {
if (interSize == 0) {
interSize = 16;
} else {
interSize *= 2;
}
inter = (SplashIntersect *)greallocn(inter, interSize,
sizeof(SplashIntersect));
}
if (seg->flags & splashXPathHoriz) {
xx0 = seg->x0;
xx1 = seg->x1;
} else if (seg->flags & splashXPathVert) {
xx0 = xx1 = seg->x0;
} else {
if (ySegMin <= y) {
// intersection with top edge
xx0 = seg->x0 + ((SplashCoord)y - seg->y0) * seg->dxdy;
} else {
// x coord of segment endpoint with min y coord
xx0 = (seg->flags & splashXPathFlip) ? seg->x1 : seg->x0;
}
if (ySegMax >= y + 1) {
// intersection with bottom edge
xx1 = seg->x0 + ((SplashCoord)y + 1 - seg->y0) * seg->dxdy;
} else {
// x coord of segment endpoint with max y coord
xx1 = (seg->flags & splashXPathFlip) ? seg->x0 : seg->x1;
}
}
if (xx0 < xx1) {
inter[interLen].x0 = splashFloor(xx0);
inter[interLen].x1 = splashFloor(xx1);
} else {
inter[interLen].x0 = splashFloor(xx1);
inter[interLen].x1 = splashFloor(xx0);
}
if (ySegMin <= y &&
(SplashCoord)y < ySegMax &&
!(seg->flags & splashXPathHoriz)) {
inter[interLen].count = eo ? 1
: (seg->flags & splashXPathFlip) ? 1 : -1;
} else {
inter[interLen].count = 0;
}
++interLen;
}
qsort(inter, interLen, sizeof(SplashIntersect), &cmpIntersect);
interY = y;
interIdx = 0;
interCount = 0;
}

View File

@ -1,74 +0,0 @@
//========================================================================
//
// SplashXPathScanner.h
//
//========================================================================
#ifndef SPLASHXPATHSCANNER_H
#define SPLASHXPATHSCANNER_H
#include <aconf.h>
#ifdef USE_GCC_PRAGMAS
#pragma interface
#endif
#include "SplashTypes.h"
class SplashXPath;
struct SplashIntersect;
//------------------------------------------------------------------------
// SplashXPathScanner
//------------------------------------------------------------------------
class SplashXPathScanner {
public:
// Create a new SplashXPathScanner object. <xPathA> must be sorted.
SplashXPathScanner(SplashXPath *xPathA, GBool eoA);
~SplashXPathScanner();
// Return the path's bounding box.
void getBBox(int *xMinA, int *yMinA, int *xMaxA, int *yMaxA)
{ *xMinA = xMin; *yMinA = yMin; *xMaxA = xMax; *yMaxA = yMax; }
// Return the min/max x values for the span at <y>.
void getSpanBounds(int y, int *spanXMin, int *spanXMax);
// Returns true if (<x>,<y>) is inside the path.
GBool test(int x, int y);
// Returns true if the entire span ([<x0>,<x1>], <y>) is inside the
// path.
GBool testSpan(int x0, int x1, int y);
// Returns the next span inside the path at <y>. If <y> is
// different than the previous call to getNextSpan, this returns the
// first span at <y>; otherwise it returns the next span (relative
// to the previous call to getNextSpan). Returns false if there are
// no more spans at <y>.
GBool getNextSpan(int y, int *x0, int *x1);
private:
void computeIntersections(int y);
SplashXPath *xPath;
GBool eo;
int xMin, yMin, xMax, yMax;
int interY; // current y value
int interIdx; // current index into <inter> - used by
// getNextSpan
int interCount; // current EO/NZWN counter - used by
// getNextSpan
int xPathIdx; // current index into <xPath> - used by
// computeIntersections
SplashIntersect *inter; // intersections array for <interY>
int interLen; // number of intersections in <inter>
int interSize; // size of the <inter> array
};
#endif

View File

@ -1,316 +0,0 @@
//========================================================================
//
// Annot.cc
//
// Copyright 2000-2003 Glyph & Cog, LLC
//
//========================================================================
#include <aconf.h>
#ifdef USE_GCC_PRAGMAS
#pragma implementation
#endif
#include <stdlib.h>
#include "gmem.h"
#include "Object.h"
#include "Catalog.h"
#include "Gfx.h"
#include "Lexer.h"
#include "Annot.h"
#include "UGString.h"
//------------------------------------------------------------------------
// Annot
//------------------------------------------------------------------------
Annot::Annot(XRef *xrefA, Dict *acroForm, Dict *dict) {
Object apObj, asObj, obj1, obj2;
GBool regen, isTextField;
double t;
ok = gFalse;
xref = xrefA;
appearBuf = NULL;
if (dict->lookup("Rect", &obj1)->isArray() &&
obj1.arrayGetLength() == 4) {
//~ should check object types here
obj1.arrayGet(0, &obj2);
xMin = obj2.getNum();
obj2.free();
obj1.arrayGet(1, &obj2);
yMin = obj2.getNum();
obj2.free();
obj1.arrayGet(2, &obj2);
xMax = obj2.getNum();
obj2.free();
obj1.arrayGet(3, &obj2);
yMax = obj2.getNum();
obj2.free();
if (xMin > xMax) {
t = xMin; xMin = xMax; xMax = t;
}
if (yMin > yMax) {
t = yMin; yMin = yMax; yMax = t;
}
} else {
//~ this should return an error
xMin = yMin = 0;
xMax = yMax = 1;
}
obj1.free();
// check if field apperances need to be regenerated
regen = gFalse;
if (acroForm) {
acroForm->lookup("NeedAppearances", &obj1);
if (obj1.isBool() && obj1.getBool()) {
regen = gTrue;
}
obj1.free();
}
// check for a text-type field
isTextField = dict->lookup("FT", &obj1)->isName("Tx");
obj1.free();
#if 0 //~ appearance stream generation is not finished yet
if (regen && isTextField) {
generateAppearance(acroForm, dict);
} else {
#endif
if (dict->lookup("AP", &apObj)->isDict()) {
if (dict->lookup("AS", &asObj)->isName()) {
if (apObj.dictLookup("N", &obj1)->isDict()) {
if (obj1.dictLookupNF(asObj.getName(), &obj2)->isRef()) {
obj2.copy(&appearance);
ok = gTrue;
} else {
obj2.free();
if (obj1.dictLookupNF("Off", &obj2)->isRef()) {
obj2.copy(&appearance);
ok = gTrue;
}
}
obj2.free();
}
obj1.free();
} else {
if (apObj.dictLookupNF("N", &obj1)->isRef()) {
obj1.copy(&appearance);
ok = gTrue;
}
obj1.free();
}
asObj.free();
}
apObj.free();
#if 0 //~ appearance stream generation is not finished yet
}
#endif
}
Annot::~Annot() {
appearance.free();
if (appearBuf) {
delete appearBuf;
}
}
void Annot::generateAppearance(Dict *acroForm, Dict *dict) {
MemStream *appearStream;
Object daObj, vObj, drObj, appearDict, obj1, obj2;
GString *daStr, *daStr1, *vStr, *s;
char buf[256];
double fontSize;
int c;
int i0, i1;
//~ DA can be inherited
if (dict->lookup("DA", &daObj)->isString()) {
daStr = daObj.getString();
// look for a font size
//~ may want to parse the DS entry in place of this (if it exists)
daStr1 = NULL;
fontSize = 10;
for (i1 = daStr->getLength() - 2; i1 >= 0; --i1) {
if (daStr->getChar(i1) == 'T' && daStr->getChar(i1+1) == 'f') {
for (--i1; i1 >= 0 && Lexer::isSpace(daStr->getChar(i1)); --i1) ;
for (i0 = i1; i0 >= 0 && !Lexer::isSpace(daStr->getChar(i0)); --i0) ;
if (i0 >= 0) {
++i0;
++i1;
s = new GString(daStr, i0, i1 - i0);
fontSize = atof(s->getCString());
delete s;
// autosize the font
if (fontSize == 0) {
fontSize = 0.67 * (yMax - yMin);
daStr1 = new GString(daStr, 0, i0);
sprintf(buf, "%.2f", fontSize);
daStr1->append(buf);
daStr1->append(daStr->getCString() + i1,
daStr->getLength() - i1);
}
}
break;
}
}
// build the appearance stream contents
appearBuf = new GString();
appearBuf->append("/Tx BMC\n");
appearBuf->append("q BT\n");
appearBuf->append(daStr1 ? daStr1 : daStr)->append("\n");
if (dict->lookup("V", &vObj)->isString()) {
//~ handle quadding -- this requires finding the font and using
//~ the encoding and char widths
sprintf(buf, "1 0 0 1 %.2f %.2f Tm\n", 2.0, yMax - yMin - fontSize);
appearBuf->append(buf);
sprintf(buf, "%g TL\n", fontSize);
appearBuf->append(buf);
vStr = vObj.getString();
i0 = 0;
while (i0 < vStr->getLength()) {
for (i1 = i0;
i1 < vStr->getLength() &&
vStr->getChar(i1) != '\n' && vStr->getChar(i1) != '\r';
++i1) ;
if (i0 > 0) {
appearBuf->append("T*\n");
}
appearBuf->append('(');
for (; i0 < i1; ++i0) {
c = vStr->getChar(i0);
if (c == '(' || c == ')' || c == '\\') {
appearBuf->append('\\');
appearBuf->append(c);
} else if (c < 0x20 || c >= 0x80) {
sprintf(buf, "\\%03o", c);
appearBuf->append(buf);
} else {
appearBuf->append(c);
}
}
appearBuf->append(") Tj\n");
if (i1 + 1 < vStr->getLength() &&
vStr->getChar(i1) == '\r' && vStr->getChar(i1 + 1) == '\n') {
i0 = i1 + 2;
} else {
i0 = i1 + 1;
}
}
}
vObj.free();
appearBuf->append("ET Q\n");
appearBuf->append("EMC\n");
// build the appearance stream dictionary
appearDict.initDict(xref);
appearDict.dictAdd("Length",
obj1.initInt(appearBuf->getLength()));
appearDict.dictAdd("Subtype", obj1.initName("Form"));
obj1.initArray(xref);
obj1.arrayAdd(obj2.initReal(0));
obj1.arrayAdd(obj2.initReal(0));
obj1.arrayAdd(obj2.initReal(xMax - xMin));
obj1.arrayAdd(obj2.initReal(yMax - yMin));
appearDict.dictAdd("BBox", &obj1);
// find the resource dictionary
dict->lookup("DR", &drObj);
if (!drObj.isDict()) {
dict->lookup("Parent", &obj1);
while (obj1.isDict()) {
drObj.free();
obj1.dictLookup("DR", &drObj);
if (drObj.isDict()) {
break;
}
obj1.dictLookup("Parent", &obj2);
obj1.free();
obj1 = obj2;
}
obj1.free();
if (!drObj.isDict()) {
if (acroForm) {
drObj.free();
acroForm->lookup("DR", &drObj);
}
}
}
if (drObj.isDict()) {
appearDict.dictAdd("Resources", drObj.copy(&obj1));
}
drObj.free();
// build the appearance stream
appearStream = new MemStream(appearBuf->getCString(), 0,
appearBuf->getLength(), &appearDict);
appearance.initStream(appearStream);
ok = gTrue;
if (daStr1) {
delete daStr1;
}
}
daObj.free();
}
void Annot::draw(Gfx *gfx) {
Object obj;
if (appearance.fetch(xref, &obj)->isStream()) {
gfx->doAnnot(&obj, xMin, yMin, xMax, yMax);
}
obj.free();
}
//------------------------------------------------------------------------
// Annots
//------------------------------------------------------------------------
Annots::Annots(XRef *xref, Catalog *catalog, Object *annotsObj) {
Dict *acroForm;
Annot *annot;
Object obj1;
int size;
int i;
annots = NULL;
size = 0;
nAnnots = 0;
acroForm = catalog->getAcroForm()->isDict() ?
catalog->getAcroForm()->getDict() : NULL;
if (annotsObj->isArray()) {
for (i = 0; i < annotsObj->arrayGetLength(); ++i) {
if (annotsObj->arrayGet(i, &obj1)->isDict()) {
annot = new Annot(xref, acroForm, obj1.getDict());
if (annot->isOk()) {
if (nAnnots >= size) {
size += 16;
annots = (Annot **)greallocn(annots, size, sizeof(Annot *));
}
annots[nAnnots++] = annot;
} else {
delete annot;
}
}
obj1.free();
}
}
}
Annots::~Annots() {
int i;
for (i = 0; i < nAnnots; ++i) {
delete annots[i];
}
gfree(annots);
}

View File

@ -1,73 +0,0 @@
//========================================================================
//
// Annot.h
//
// Copyright 2000-2003 Glyph & Cog, LLC
//
//========================================================================
#ifndef ANNOT_H
#define ANNOT_H
#include <aconf.h>
#ifdef USE_GCC_PRAGMAS
#pragma interface
#endif
class XRef;
class Catalog;
class Gfx;
//------------------------------------------------------------------------
// Annot
//------------------------------------------------------------------------
class Annot {
public:
Annot(XRef *xrefA, Dict *acroForm, Dict *dict);
~Annot();
GBool isOk() { return ok; }
void draw(Gfx *gfx);
// Get appearance object.
Object *getAppearance(Object *obj) { return appearance.fetch(xref, obj); }
private:
void generateAppearance(Dict *acroForm, Dict *dict);
XRef *xref; // the xref table for this PDF file
Object appearance; // a reference to the Form XObject stream
// for the normal appearance
GString *appearBuf;
double xMin, yMin, // annotation rectangle
xMax, yMax;
GBool ok;
};
//------------------------------------------------------------------------
// Annots
//------------------------------------------------------------------------
class Annots {
public:
// Extract non-link annotations from array of annotations.
Annots(XRef *xref, Catalog *catalog, Object *annotsObj);
~Annots();
// Iterate through list of annotations.
int getNumAnnots() { return nAnnots; }
Annot *getAnnot(int i) { return annots[i]; }
private:
Annot **annots;
int nAnnots;
};
#endif

View File

@ -1,88 +0,0 @@
//========================================================================
//
// Array.cc
//
// Copyright 1996-2003 Glyph & Cog, LLC
//
//========================================================================
#include <aconf.h>
#ifdef USE_GCC_PRAGMAS
#pragma implementation
#endif
#include <stdlib.h>
#include <stddef.h>
#include "gmem.h"
#include "Object.h"
#include "Array.h"
//------------------------------------------------------------------------
// Array
//------------------------------------------------------------------------
Array::Array(XRef *xrefA) {
xref = xrefA;
elems = NULL;
size = length = 0;
ref = 1;
}
Array::~Array() {
int i;
for (i = 0; i < length; ++i)
elems[i].free();
gfree(elems);
}
void Array::add(Object *elem) {
if (length == size) {
if (length == 0) {
size = 8;
} else {
size *= 2;
}
elems = (Object *)greallocn(elems, size, sizeof(Object));
}
elems[length] = *elem;
++length;
}
Object *Array::get(int i, Object *obj) {
if (i < 0 || i >= length) {
#ifdef DEBUG_MEM
abort();
#else
return obj->initNull();
#endif
}
return elems[i].fetch(xref, obj);
}
Object *Array::getNF(int i, Object *obj) {
if (i < 0 || i >= length) {
#ifdef DEBUG_MEM
abort();
#else
return obj->initNull();
#endif
}
return elems[i].copy(obj);
}
GBool Array::getString(int i, GString *string)
{
Object obj;
if (getNF(i, &obj)->isString()) {
string->clear();
string->append(obj.getString());
obj.free();
return gTrue;
} else {
obj.free();
return gFalse;
}
}

View File

@ -1,59 +0,0 @@
//========================================================================
//
// Array.h
//
// Copyright 1996-2003 Glyph & Cog, LLC
//
//========================================================================
#ifndef ARRAY_H
#define ARRAY_H
#include <aconf.h>
#ifdef USE_GCC_PRAGMAS
#pragma interface
#endif
#include "Object.h"
class XRef;
//------------------------------------------------------------------------
// Array
//------------------------------------------------------------------------
class Array {
public:
// Constructor.
Array(XRef *xrefA);
// Destructor.
~Array();
// Reference counting.
int incRef() { return ++ref; }
int decRef() { return --ref; }
// Get number of elements.
int getLength() { return length; }
// Add an element.
void add(Object *elem);
// Accessors.
Object *get(int i, Object *obj);
Object *getNF(int i, Object *obj);
GBool getString(int i, GString *string);
private:
XRef *xref; // the xref table for this PDF file
Object *elems; // array of elements
int size; // size of <elems> array
int length; // number of elements in array
int ref; // reference count
};
#endif

View File

@ -1,65 +0,0 @@
//========================================================================
//
// BuiltinFont.cc
//
// Copyright 2001-2003 Glyph & Cog, LLC
//
//========================================================================
#include <aconf.h>
#ifdef USE_GCC_PRAGMAS
#pragma implementation
#endif
#include <stdlib.h>
#include <string.h>
#include "gmem.h"
#include "FontEncodingTables.h"
#include "BuiltinFont.h"
//------------------------------------------------------------------------
BuiltinFontWidths::BuiltinFontWidths(BuiltinFontWidth *widths, int sizeA) {
int i, h;
size = sizeA;
tab = (BuiltinFontWidth **)gmallocn(size, sizeof(BuiltinFontWidth *));
for (i = 0; i < size; ++i) {
tab[i] = NULL;
}
for (i = 0; i < sizeA; ++i) {
h = hash(widths[i].name);
widths[i].next = tab[h];
tab[h] = &widths[i];
}
}
BuiltinFontWidths::~BuiltinFontWidths() {
gfree(tab);
}
GBool BuiltinFontWidths::getWidth(const char *name, Gushort *width) {
int h;
BuiltinFontWidth *p;
h = hash(name);
for (p = tab[h]; p; p = p->next) {
if (!strcmp(p->name, name)) {
*width = p->width;
return gTrue;
}
}
return gFalse;
}
int BuiltinFontWidths::hash(const char *name) {
const char *p;
unsigned int h;
h = 0;
for (p = name; *p; ++p) {
h = 17 * h + (int)(*p & 0xff);
}
return (int)(h % size);
}

View File

@ -1,57 +0,0 @@
//========================================================================
//
// BuiltinFont.h
//
// Copyright 2001-2003 Glyph & Cog, LLC
//
//========================================================================
#ifndef BUILTINFONT_H
#define BUILTINFONT_H
#include <aconf.h>
#ifdef USE_GCC_PRAGMAS
#pragma interface
#endif
#include "gtypes.h"
struct BuiltinFont;
class BuiltinFontWidths;
//------------------------------------------------------------------------
struct BuiltinFont {
const char *name;
const char **defaultBaseEnc;
short ascent;
short descent;
short bbox[4];
BuiltinFontWidths *widths;
};
//------------------------------------------------------------------------
struct BuiltinFontWidth {
const char *name;
Gushort width;
BuiltinFontWidth *next;
};
class BuiltinFontWidths {
public:
BuiltinFontWidths(BuiltinFontWidth *widths, int sizeA);
~BuiltinFontWidths();
GBool getWidth(const char *name, Gushort *width);
private:
int hash(const char *name);
BuiltinFontWidth **tab;
int size;
};
#endif

File diff suppressed because it is too large Load Diff

View File

@ -1,23 +0,0 @@
//========================================================================
//
// BuiltinFontTables.h
//
// Copyright 2001-2003 Glyph & Cog, LLC
//
//========================================================================
#ifndef BUILTINFONTTABLES_H
#define BUILTINFONTTABLES_H
#include "BuiltinFont.h"
#define nBuiltinFonts 14
#define nBuiltinFontSubsts 12
extern BuiltinFont builtinFonts[nBuiltinFonts];
extern BuiltinFont *builtinFontSubst[nBuiltinFontSubsts];
extern void initBuiltinFontTables();
extern void freeBuiltinFontTables();
#endif

View File

@ -1,408 +0,0 @@
//========================================================================
//
// CMap.cc
//
// Copyright 2001-2003 Glyph & Cog, LLC
//
//========================================================================
#include <aconf.h>
#ifdef USE_GCC_PRAGMAS
#pragma implementation
#endif
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include "gmem.h"
#include "gfile.h"
#include "GString.h"
#include "Error.h"
#include "GlobalParams.h"
#include "PSTokenizer.h"
#include "CMap.h"
//------------------------------------------------------------------------
struct CMapVectorEntry {
GBool isVector;
union {
CMapVectorEntry *vector;
CID cid;
};
};
//------------------------------------------------------------------------
static int CMap_getCharFromFile(void *data) {
return fgetc((FILE *)data);
}
//------------------------------------------------------------------------
CMap *CMap::parse(CMapCache *cache, GString *collectionA,
GString *cMapNameA) {
FILE *f;
CMap *cmap;
PSTokenizer *pst;
char tok1[256], tok2[256], tok3[256];
int n1, n2, n3;
Guint start, end, code;
if (!(f = globalParams->findCMapFile(collectionA, cMapNameA))) {
// Check for an identity CMap.
if (!cMapNameA->cmp("Identity") || !cMapNameA->cmp("Identity-H")) {
return new CMap(collectionA->copy(), cMapNameA->copy(), 0);
}
if (!cMapNameA->cmp("Identity-V")) {
return new CMap(collectionA->copy(), cMapNameA->copy(), 1);
}
error(-1, "Couldn't find '%s' CMap file for '%s' collection",
cMapNameA->getCString(), collectionA->getCString());
return NULL;
}
cmap = new CMap(collectionA->copy(), cMapNameA->copy());
pst = new PSTokenizer(&CMap_getCharFromFile, f);
pst->getToken(tok1, sizeof(tok1), &n1);
while (pst->getToken(tok2, sizeof(tok2), &n2)) {
if (!strcmp(tok2, "usecmap")) {
if (tok1[0] == '/') {
cmap->useCMap(cache, tok1 + 1);
}
pst->getToken(tok1, sizeof(tok1), &n1);
} else if (!strcmp(tok1, "/WMode")) {
cmap->wMode = atoi(tok2);
pst->getToken(tok1, sizeof(tok1), &n1);
} else if (!strcmp(tok2, "begincodespacerange")) {
while (pst->getToken(tok1, sizeof(tok1), &n1)) {
if (!strcmp(tok1, "endcodespacerange")) {
break;
}
if (!pst->getToken(tok2, sizeof(tok2), &n2) ||
!strcmp(tok2, "endcodespacerange")) {
error(-1, "Illegal entry in codespacerange block in CMap");
break;
}
if (tok1[0] == '<' && tok2[0] == '<' &&
n1 == n2 && n1 >= 4 && (n1 & 1) == 0) {
tok1[n1 - 1] = tok2[n1 - 1] = '\0';
sscanf(tok1 + 1, "%x", &start);
sscanf(tok2 + 1, "%x", &end);
n1 = (n1 - 2) / 2;
cmap->addCodeSpace(cmap->vector, start, end, n1);
}
}
pst->getToken(tok1, sizeof(tok1), &n1);
} else if (!strcmp(tok2, "begincidchar")) {
while (pst->getToken(tok1, sizeof(tok1), &n1)) {
if (!strcmp(tok1, "endcidchar")) {
break;
}
if (!pst->getToken(tok2, sizeof(tok2), &n2) ||
!strcmp(tok2, "endcidchar")) {
error(-1, "Illegal entry in cidchar block in CMap");
break;
}
if (!(tok1[0] == '<' && tok1[n1 - 1] == '>' &&
n1 >= 4 && (n1 & 1) == 0)) {
error(-1, "Illegal entry in cidchar block in CMap");
continue;
}
tok1[n1 - 1] = '\0';
if (sscanf(tok1 + 1, "%x", &code) != 1) {
error(-1, "Illegal entry in cidchar block in CMap");
continue;
}
n1 = (n1 - 2) / 2;
cmap->addCIDs(code, code, n1, (CID)atoi(tok2));
}
pst->getToken(tok1, sizeof(tok1), &n1);
} else if (!strcmp(tok2, "begincidrange")) {
while (pst->getToken(tok1, sizeof(tok1), &n1)) {
if (!strcmp(tok1, "endcidrange")) {
break;
}
if (!pst->getToken(tok2, sizeof(tok2), &n2) ||
!strcmp(tok2, "endcidrange") ||
!pst->getToken(tok3, sizeof(tok3), &n3) ||
!strcmp(tok3, "endcidrange")) {
error(-1, "Illegal entry in cidrange block in CMap");
break;
}
if (tok1[0] == '<' && tok2[0] == '<' &&
n1 == n2 && n1 >= 4 && (n1 & 1) == 0) {
tok1[n1 - 1] = tok2[n1 - 1] = '\0';
sscanf(tok1 + 1, "%x", &start);
sscanf(tok2 + 1, "%x", &end);
n1 = (n1 - 2) / 2;
cmap->addCIDs(start, end, n1, (CID)atoi(tok3));
}
}
pst->getToken(tok1, sizeof(tok1), &n1);
} else {
strcpy(tok1, tok2);
}
}
delete pst;
fclose(f);
return cmap;
}
CMap::CMap(GString *collectionA, GString *cMapNameA) {
int i;
collection = collectionA;
cMapName = cMapNameA;
wMode = 0;
vector = (CMapVectorEntry *)gmallocn(256, sizeof(CMapVectorEntry));
for (i = 0; i < 256; ++i) {
vector[i].isVector = gFalse;
vector[i].cid = 0;
}
refCnt = 1;
#if MULTITHREADED
gInitMutex(&mutex);
#endif
}
CMap::CMap(GString *collectionA, GString *cMapNameA, int wModeA) {
collection = collectionA;
cMapName = cMapNameA;
wMode = wModeA;
vector = NULL;
refCnt = 1;
#if MULTITHREADED
gInitMutex(&mutex);
#endif
}
void CMap::useCMap(CMapCache *cache, char *useName) {
GString *useNameStr;
CMap *subCMap;
useNameStr = new GString(useName);
subCMap = cache->getCMap(collection, useNameStr);
delete useNameStr;
if (!subCMap) {
return;
}
copyVector(vector, subCMap->vector);
subCMap->decRefCnt();
}
void CMap::copyVector(CMapVectorEntry *dest, CMapVectorEntry *src) {
int i, j;
for (i = 0; i < 256; ++i) {
if (src[i].isVector) {
if (!dest[i].isVector) {
dest[i].isVector = gTrue;
dest[i].vector =
(CMapVectorEntry *)gmallocn(256, sizeof(CMapVectorEntry));
for (j = 0; j < 256; ++j) {
dest[i].vector[j].isVector = gFalse;
dest[i].vector[j].cid = 0;
}
}
copyVector(dest[i].vector, src[i].vector);
} else {
if (dest[i].isVector) {
error(-1, "Collision in usecmap");
} else {
dest[i].cid = src[i].cid;
}
}
}
}
void CMap::addCodeSpace(CMapVectorEntry *vec, Guint start, Guint end,
Guint nBytes) {
Guint start2, end2;
int startByte, endByte, i, j;
if (nBytes > 1) {
startByte = (start >> (8 * (nBytes - 1))) & 0xff;
endByte = (end >> (8 * (nBytes - 1))) & 0xff;
start2 = start & ((1 << (8 * (nBytes - 1))) - 1);
end2 = end & ((1 << (8 * (nBytes - 1))) - 1);
for (i = startByte; i <= endByte; ++i) {
if (!vec[i].isVector) {
vec[i].isVector = gTrue;
vec[i].vector =
(CMapVectorEntry *)gmallocn(256, sizeof(CMapVectorEntry));
for (j = 0; j < 256; ++j) {
vec[i].vector[j].isVector = gFalse;
vec[i].vector[j].cid = 0;
}
}
addCodeSpace(vec[i].vector, start2, end2, nBytes - 1);
}
}
}
void CMap::addCIDs(Guint start, Guint end, Guint nBytes, CID firstCID) {
CMapVectorEntry *vec;
CID cid;
int byte;
Guint i;
vec = vector;
for (i = nBytes - 1; i >= 1; --i) {
byte = (start >> (8 * i)) & 0xff;
if (!vec[byte].isVector) {
error(-1, "Invalid CID (%0*x - %0*x) in CMap",
2*nBytes, start, 2*nBytes, end);
return;
}
vec = vec[byte].vector;
}
cid = firstCID;
for (byte = (int)(start & 0xff); byte <= (int)(end & 0xff); ++byte) {
if (vec[byte].isVector) {
error(-1, "Invalid CID (%0*x - %0*x) in CMap",
2*nBytes, start, 2*nBytes, end);
} else {
vec[byte].cid = cid;
}
++cid;
}
}
CMap::~CMap() {
delete collection;
delete cMapName;
if (vector) {
freeCMapVector(vector);
}
#if MULTITHREADED
gDestroyMutex(&mutex);
#endif
}
void CMap::freeCMapVector(CMapVectorEntry *vec) {
int i;
for (i = 0; i < 256; ++i) {
if (vec[i].isVector) {
freeCMapVector(vec[i].vector);
}
}
gfree(vec);
}
void CMap::incRefCnt() {
#if MULTITHREADED
gLockMutex(&mutex);
#endif
++refCnt;
#if MULTITHREADED
gUnlockMutex(&mutex);
#endif
}
void CMap::decRefCnt() {
GBool done;
#if MULTITHREADED
gLockMutex(&mutex);
#endif
done = --refCnt == 0;
#if MULTITHREADED
gUnlockMutex(&mutex);
#endif
if (done) {
delete this;
}
}
GBool CMap::match(GString *collectionA, GString *cMapNameA) {
return !collection->cmp(collectionA) && !cMapName->cmp(cMapNameA);
}
CID CMap::getCID(char *s, int len, int *nUsed) {
CMapVectorEntry *vec;
int n, i;
if (!(vec = vector)) {
// identity CMap
*nUsed = 2;
if (len < 2) {
return 0;
}
return ((s[0] & 0xff) << 8) + (s[1] & 0xff);
}
n = 0;
while (1) {
if (n >= len) {
*nUsed = n;
return 0;
}
i = s[n++] & 0xff;
if (!vec[i].isVector) {
*nUsed = n;
return vec[i].cid;
}
vec = vec[i].vector;
}
}
//------------------------------------------------------------------------
CMapCache::CMapCache() {
int i;
for (i = 0; i < cMapCacheSize; ++i) {
cache[i] = NULL;
}
}
CMapCache::~CMapCache() {
int i;
for (i = 0; i < cMapCacheSize; ++i) {
if (cache[i]) {
cache[i]->decRefCnt();
}
}
}
CMap *CMapCache::getCMap(GString *collection, GString *cMapName) {
CMap *cmap;
int i, j;
if (cache[0] && cache[0]->match(collection, cMapName)) {
cache[0]->incRefCnt();
return cache[0];
}
for (i = 1; i < cMapCacheSize; ++i) {
if (cache[i] && cache[i]->match(collection, cMapName)) {
cmap = cache[i];
for (j = i; j >= 1; --j) {
cache[j] = cache[j - 1];
}
cache[0] = cmap;
cmap->incRefCnt();
return cmap;
}
}
if ((cmap = CMap::parse(this, collection, cMapName))) {
if (cache[cMapCacheSize - 1]) {
cache[cMapCacheSize - 1]->decRefCnt();
}
for (j = cMapCacheSize - 1; j >= 1; --j) {
cache[j] = cache[j - 1];
}
cache[0] = cmap;
cmap->incRefCnt();
return cmap;
}
return NULL;
}

View File

@ -1,102 +0,0 @@
//========================================================================
//
// CMap.h
//
// Copyright 2001-2003 Glyph & Cog, LLC
//
//========================================================================
#ifndef CMAP_H
#define CMAP_H
#include <aconf.h>
#ifdef USE_GCC_PRAGMAS
#pragma interface
#endif
#include "gtypes.h"
#include "CharTypes.h"
#if MULTITHREADED
#include "GMutex.h"
#endif
class GString;
struct CMapVectorEntry;
class CMapCache;
//------------------------------------------------------------------------
class CMap {
public:
// Create the CMap specified by <collection> and <cMapName>. Sets
// the initial reference count to 1. Returns NULL on failure.
static CMap *parse(CMapCache *cache, GString *collectionA,
GString *cMapNameA);
~CMap();
void incRefCnt();
void decRefCnt();
// Return collection name (<registry>-<ordering>).
GString *getCollection() { return collection; }
// Return true if this CMap matches the specified <collectionA>, and
// <cMapNameA>.
GBool match(GString *collectionA, GString *cMapNameA);
// Return the CID corresponding to the character code starting at
// <s>, which contains <len> bytes. Sets *<nUsed> to the number of
// bytes used by the char code.
CID getCID(char *s, int len, int *nUsed);
// Return the writing mode (0=horizontal, 1=vertical).
int getWMode() { return wMode; }
private:
CMap(GString *collectionA, GString *cMapNameA);
CMap(GString *collectionA, GString *cMapNameA, int wModeA);
void useCMap(CMapCache *cache, char *useName);
void copyVector(CMapVectorEntry *dest, CMapVectorEntry *src);
void addCodeSpace(CMapVectorEntry *vec, Guint start, Guint end,
Guint nBytes);
void addCIDs(Guint start, Guint end, Guint nBytes, CID firstCID);
void freeCMapVector(CMapVectorEntry *vec);
GString *collection;
GString *cMapName;
int wMode; // writing mode (0=horizontal, 1=vertical)
CMapVectorEntry *vector; // vector for first byte (NULL for
// identity CMap)
int refCnt;
#if MULTITHREADED
GMutex mutex;
#endif
};
//------------------------------------------------------------------------
#define cMapCacheSize 4
class CMapCache {
public:
CMapCache();
~CMapCache();
// Get the <cMapName> CMap for the specified character 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.
CMap *getCMap(GString *collection, GString *cMapName);
private:
CMap *cache[cMapCacheSize];
};
#endif

View File

@ -1,426 +0,0 @@
//========================================================================
//
// Catalog.cc
//
// Copyright 1996-2003 Glyph & Cog, LLC
//
//========================================================================
#include <aconf.h>
#ifdef USE_GCC_PRAGMAS
#pragma implementation
#endif
#include <limits.h>
#include <stddef.h>
#include <stdlib.h>
#include "gmem.h"
#include "Object.h"
#include "XRef.h"
#include "Array.h"
#include "Dict.h"
#include "Page.h"
#include "Error.h"
#include "Link.h"
#include "UGString.h"
#include "Catalog.h"
//------------------------------------------------------------------------
// Catalog
//------------------------------------------------------------------------
Catalog::Catalog(XRef *xrefA) {
Object catDict, pagesDict;
Object obj, obj2;
int numPages0;
int i;
ok = gTrue;
xref = xrefA;
pages = NULL;
pageRefs = NULL;
numPages = pagesSize = 0;
baseURI = NULL;
pageMode = UseNone;
xref->getCatalog(&catDict);
if (!catDict.isDict()) {
error(-1, "Catalog object is wrong type (%s)", catDict.getTypeName());
goto err1;
}
// read page tree
catDict.dictLookup("Pages", &pagesDict);
// This should really be isDict("Pages"), but I've seen at least one
// PDF file where the /Type entry is missing.
if (!pagesDict.isDict()) {
error(-1, "Top-level pages object is wrong type (%s)",
pagesDict.getTypeName());
goto err2;
}
pagesDict.dictLookup("Count", &obj);
// 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 = (int)obj.getNum();
obj.free();
pages = (Page **)gmallocn(pagesSize, sizeof(Page *));
pageRefs = (Ref *)gmallocn(pagesSize, sizeof(Ref));
for (i = 0; i < pagesSize; ++i) {
pages[i] = NULL;
pageRefs[i].num = -1;
pageRefs[i].gen = -1;
}
numPages = readPageTree(pagesDict.getDict(), NULL, 0);
if (numPages != numPages0) {
error(-1, "Page count in top-level pages object is incorrect");
}
pagesDict.free();
// read named destination dictionary
catDict.dictLookup("Dests", &dests);
// read root of named destination tree
if (catDict.dictLookup("Names", &obj)->isDict()) {
obj.dictLookup("Dests", &obj2);
destNameTree.init(xref, &obj2);
obj2.free();
}
obj.free();
// read base URI
if (catDict.dictLookup("URI", &obj)->isDict()) {
if (obj.dictLookup("Base", &obj2)->isString()) {
baseURI = obj2.getString()->copy();
}
obj2.free();
}
obj.free();
// read page mode
if (catDict.dictLookup("PageMode", &obj)->isName()) {
if (strcmp(obj.getName(), "UseNone") == 0)
pageMode = UseNone;
else if (strcmp(obj.getName(), "UseOutlines") == 0)
pageMode = UseOutlines;
else if (strcmp(obj.getName(), "UseThumbs") == 0)
pageMode = UseThumbs;
else if (strcmp(obj.getName(), "FullScreen") == 0)
pageMode = FullScreen;
else if (strcmp(obj.getName(), "UseOC") == 0)
pageMode = UseOC;
} else {
pageMode = UseNone;
}
obj.free();
// get the metadata stream
catDict.dictLookup("Metadata", &metadata);
// get the structure tree root
catDict.dictLookup("StructTreeRoot", &structTreeRoot);
// get the outline dictionary
catDict.dictLookup("Outlines", &outline);
// get the AcroForm dictionary
catDict.dictLookup("AcroForm", &acroForm);
catDict.free();
return;
err3:
obj.free();
err2:
pagesDict.free();
err1:
catDict.free();
dests.initNull();
ok = gFalse;
}
Catalog::~Catalog() {
int i;
if (pages) {
for (i = 0; i < pagesSize; ++i) {
if (pages[i]) {
delete pages[i];
}
}
gfree(pages);
gfree(pageRefs);
}
dests.free();
destNameTree.free();
if (baseURI) {
delete baseURI;
}
metadata.free();
structTreeRoot.free();
outline.free();
acroForm.free();
}
GString *Catalog::readMetadata() {
GString *s;
Dict *dict;
Object obj;
int c;
if (!metadata.isStream()) {
return NULL;
}
dict = metadata.streamGetDict();
if (!dict->lookup("Subtype", &obj)->isName("XML")) {
error(-1, "Unknown Metadata type: '%s'",
obj.isName() ? obj.getName() : "???");
}
obj.free();
s = new GString();
metadata.streamReset();
while ((c = metadata.streamGetChar()) != EOF) {
s->append(c);
}
metadata.streamClose();
return s;
}
int Catalog::readPageTree(Dict *pagesDict, PageAttrs *attrs, int start) {
Object kids;
Object kid;
Object kidRef;
PageAttrs *attrs1, *attrs2;
Page *page;
int i, j;
attrs1 = new PageAttrs(attrs, pagesDict);
pagesDict->lookup("Kids", &kids);
if (!kids.isArray()) {
error(-1, "Kids object (page %d) is wrong type (%s)",
start+1, kids.getTypeName());
goto err1;
}
for (i = 0; i < kids.arrayGetLength(); ++i) {
kids.arrayGet(i, &kid);
if (kid.isDict("Page")) {
attrs2 = new PageAttrs(attrs1, kid.getDict());
page = new Page(xref, start+1, kid.getDict(), attrs2);
if (!page->isOk()) {
++start;
goto err3;
}
if (start >= pagesSize) {
pagesSize += 32;
pages = (Page **)greallocn(pages, pagesSize, sizeof(Page *));
pageRefs = (Ref *)greallocn(pageRefs, pagesSize, sizeof(Ref));
for (j = pagesSize - 32; j < pagesSize; ++j) {
pages[j] = NULL;
pageRefs[j].num = -1;
pageRefs[j].gen = -1;
}
}
pages[start] = page;
kids.arrayGetNF(i, &kidRef);
if (kidRef.isRef()) {
pageRefs[start].num = kidRef.getRefNum();
pageRefs[start].gen = kidRef.getRefGen();
}
kidRef.free();
++start;
// This should really be isDict("Pages"), but I've seen at least one
// PDF file where the /Type entry is missing.
} else if (kid.isDict()) {
if ((start = readPageTree(kid.getDict(), attrs1, start))
< 0)
goto err2;
} else {
error(-1, "Kid object (page %d) is wrong type (%s)",
start+1, kid.getTypeName());
}
kid.free();
}
delete attrs1;
kids.free();
return start;
err3:
delete page;
err2:
kid.free();
err1:
kids.free();
delete attrs1;
ok = gFalse;
return -1;
}
int Catalog::findPage(int num, int gen) {
int i;
for (i = 0; i < numPages; ++i) {
if (pageRefs[i].num == num && pageRefs[i].gen == gen)
return i + 1;
}
return 0;
}
LinkDest *Catalog::findDest(UGString *name) {
LinkDest *dest;
Object obj1, obj2;
GBool found;
// try named destination dictionary then name tree
found = gFalse;
if (dests.isDict()) {
if (!dests.dictLookup(*name, &obj1)->isNull())
found = gTrue;
else
obj1.free();
}
if (!found) {
if (destNameTree.lookup(name, &obj1))
found = gTrue;
else
obj1.free();
}
if (!found)
return NULL;
// construct LinkDest
dest = NULL;
if (obj1.isArray()) {
dest = new LinkDest(obj1.getArray());
} else if (obj1.isDict()) {
if (obj1.dictLookup("D", &obj2)->isArray())
dest = new LinkDest(obj2.getArray());
else
error(-1, "Bad named destination value");
obj2.free();
} else {
error(-1, "Bad named destination value");
}
obj1.free();
if (dest && !dest->isOk()) {
delete dest;
dest = NULL;
}
return dest;
}
NameTree::NameTree(void)
{
size = 0;
length = 0;
entries = NULL;
}
NameTree::Entry::Entry(Array *array, int index) {
GString n;
if (!array->getString(index, &n) || !array->getNF(index + 1, &value))
error(-1, "Invalid page tree");
name = new UGString(n);
}
NameTree::Entry::~Entry() {
value.free();
delete name;
}
void NameTree::addEntry(Entry *entry)
{
if (length == size) {
if (length == 0) {
size = 8;
} else {
size *= 2;
}
entries = (Entry **) grealloc (entries, sizeof (Entry *) * size);
}
entries[length] = entry;
++length;
}
void NameTree::init(XRef *xrefA, Object *tree) {
xref = xrefA;
parse(tree);
}
void NameTree::parse(Object *tree) {
Object names;
Object kids, kid;
int i;
if (!tree->isDict())
return;
// leaf node
if (tree->dictLookup("Names", &names)->isArray()) {
for (i = 0; i < names.arrayGetLength(); i += 2) {
NameTree::Entry *entry;
entry = new Entry(names.getArray(), i);
addEntry(entry);
}
}
// root or intermediate node
if (tree->dictLookup("Kids", &kids)->isArray()) {
for (i = 0; i < kids.arrayGetLength(); ++i) {
if (kids.arrayGet(i, &kid)->isDict())
parse(&kid);
kid.free();
}
}
kids.free();
}
int NameTree::Entry::cmp(const void *voidKey, const void *voidEntry)
{
UGString *key = (UGString *) voidKey;
Entry *entry = *(NameTree::Entry **) voidEntry;
return key->cmp(entry->name);
}
GBool NameTree::lookup(UGString *name, Object *obj)
{
Entry *entry;
Entry **e = (Entry **) bsearch(name, entries,
length, sizeof(Entry *), Entry::cmp);
if (e) entry = *e;
else
{
error(-1, "failed to look up %s\n", name->getCString());
obj->initNull();
return gFalse;
}
if (entry != NULL) {
entry->value.fetch(xref, obj);
return gTrue;
} else {
error(-1, "failed to look up %s\n", name->getCString());
obj->initNull();
return gFalse;
}
}
void NameTree::free()
{
int i;
for (i = 0; i < length; i++)
delete entries[i];
gfree(entries);
}

View File

@ -1,135 +0,0 @@
//========================================================================
//
// Catalog.h
//
// Copyright 1996-2003 Glyph & Cog, LLC
//
//========================================================================
#ifndef CATALOG_H
#define CATALOG_H
#include <aconf.h>
#ifdef USE_GCC_PRAGMAS
#pragma interface
#endif
class XRef;
class Object;
class Page;
class PageAttrs;
struct Ref;
class LinkDest;
class UGString;
//------------------------------------------------------------------------
// NameTree
//------------------------------------------------------------------------
class NameTree {
public:
NameTree();
void init(XRef *xref, Object *tree);
void parse(Object *tree);
GBool lookup(UGString *name, Object *obj);
void free();
private:
struct Entry {
Entry(Array *array, int index);
~Entry();
UGString *name;
Object value;
void free();
static int cmp(const void *key, const void *entry);
};
void addEntry(Entry *entry);
XRef *xref;
Object *root;
Entry **entries;
int size, length;
};
//------------------------------------------------------------------------
// Catalog
//------------------------------------------------------------------------
class Catalog {
public:
enum PageMode {
UseNone,
UseOutlines,
UseThumbs,
FullScreen,
UseOC
};
// Constructor.
Catalog(XRef *xrefA);
// Destructor.
~Catalog();
// Is catalog valid?
GBool isOk() { return ok; }
// Get number of pages.
int getNumPages() { return numPages; }
// Get a page.
Page *getPage(int i) { return pages[i-1]; }
// Get the reference for a page object.
Ref *getPageRef(int i) { return &pageRefs[i-1]; }
// Return base URI, or NULL if none.
GString *getBaseURI() { return baseURI; }
// Returns the page mode.
PageMode getPageMode() { return pageMode; }
// Return the contents of the metadata stream, or NULL if there is
// no metadata.
GString *readMetadata();
// Return the structure tree root object.
Object *getStructTreeRoot() { return &structTreeRoot; }
// Find a page, given its object ID. Returns page number, or 0 if
// not found.
int findPage(int num, int gen);
// Find a named destination. Returns the link destination, or
// NULL if <name> is not a destination.
LinkDest *findDest(UGString *name);
Object *getOutline() { return &outline; }
Object *getAcroForm() { return &acroForm; }
private:
XRef *xref; // the xref table for this PDF file
Page **pages; // array of pages
Ref *pageRefs; // object ID for each page
int numPages; // number of pages
int pagesSize; // size of pages array
Object dests; // named destination dictionary
NameTree destNameTree; // name tree
GString *baseURI; // base URI for URI-type links
PageMode pageMode; // page mode
Object metadata; // metadata stream
Object structTreeRoot; // structure tree root dictionary
Object outline; // outline dictionary
Object acroForm; // AcroForm dictionary
GBool ok; // true if catalog is valid
int readPageTree(Dict *pages, PageAttrs *attrs, int start);
Object *findDestInTree(Object *tree, GString *name, Object *obj);
};
#endif

View File

@ -1,563 +0,0 @@
//========================================================================
//
// CharCodeToUnicode.cc
//
// Copyright 2001-2003 Glyph & Cog, LLC
//
//========================================================================
#include <aconf.h>
#ifdef USE_GCC_PRAGMAS
#pragma implementation
#endif
#include <stdio.h>
#include <string.h>
#include "gmem.h"
#include "gfile.h"
#include "GString.h"
#include "Error.h"
#include "GlobalParams.h"
#include "PSTokenizer.h"
#include "CharCodeToUnicode.h"
//------------------------------------------------------------------------
#define maxUnicodeString 8
struct CharCodeToUnicodeString {
CharCode c;
Unicode u[maxUnicodeString];
int len;
};
//------------------------------------------------------------------------
static int getCharFromString(void *data) {
char *p;
int c;
p = *(char **)data;
if (*p) {
c = *p++;
*(char **)data = p;
} else {
c = EOF;
}
return c;
}
static int CharCodeToUnicode_getCharFromFile(void *data) {
return fgetc((FILE *)data);
}
//------------------------------------------------------------------------
CharCodeToUnicode *CharCodeToUnicode::parseCIDToUnicode(GString *fileName,
GString *collection) {
FILE *f;
Unicode *mapA;
CharCode size, mapLenA;
char buf[64];
Unicode u;
CharCodeToUnicode *ctu;
if (!(f = fopen(fileName->getCString(), "r"))) {
error(-1, "Couldn't open cidToUnicode file '%s'",
fileName->getCString());
return NULL;
}
size = 32768;
mapA = (Unicode *)gmallocn(size, sizeof(Unicode));
mapLenA = 0;
while (getLine(buf, sizeof(buf), f)) {
if (mapLenA == size) {
size *= 2;
mapA = (Unicode *)greallocn(mapA, size, sizeof(Unicode));
}
if (sscanf(buf, "%x", &u) == 1) {
mapA[mapLenA] = u;
} else {
error(-1, "Bad line (%d) in cidToUnicode file '%s'",
(int)(mapLenA + 1), fileName->getCString());
mapA[mapLenA] = 0;
}
++mapLenA;
}
fclose(f);
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 *)gmallocn(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 *)greallocn(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 *)
greallocn(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, 0);
}
CharCodeToUnicode *CharCodeToUnicode::parseCMap(GString *buf, int nBits) {
CharCodeToUnicode *ctu;
char *p;
ctu = new CharCodeToUnicode(NULL);
p = buf->getCString();
ctu->parseCMap1(&getCharFromString, &p, 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 i;
CharCode code1, code2;
GString *name;
FILE *f;
nDigits = nBits / 4;
pst = new PSTokenizer(getCharFunc, data);
pst->getToken(tok1, sizeof(tok1), &n1);
while (pst->getToken(tok2, sizeof(tok2), &n2)) {
if (!strcmp(tok2, "usecmap")) {
if (tok1[0] == '/') {
name = new GString(tok1 + 1);
if ((f = globalParams->findToUnicodeFile(name))) {
parseCMap1(&CharCodeToUnicode_getCharFromFile, f, nBits);
fclose(f);
} else {
error(-1, "Couldn't find ToUnicode CMap file for '%s'",
name->getCString());
}
delete name;
}
pst->getToken(tok1, sizeof(tok1), &n1);
} else if (!strcmp(tok2, "beginbfchar")) {
while (pst->getToken(tok1, sizeof(tok1), &n1)) {
if (!strcmp(tok1, "endbfchar")) {
break;
}
if (!pst->getToken(tok2, sizeof(tok2), &n2) ||
!strcmp(tok2, "endbfchar")) {
error(-1, "Illegal entry in bfchar block in ToUnicode CMap");
break;
}
if (!(n1 == 2 + nDigits && tok1[0] == '<' && tok1[n1 - 1] == '>' &&
tok2[0] == '<' && tok2[n2 - 1] == '>')) {
// check there was no line jump inside the token and so the length is
// longer than it should be
int countAux = 0;
for (int k = 0; k < n1; k++)
if (tok1[k] != '\n' && tok1[k] != '\r') countAux++;
if (!(countAux == 2 + nDigits && tok1[0] == '<' && tok1[n1 - 1] == '>' &&
tok2[0] == '<' && tok2[n2 - 1] == '>')) {
error(-1, "Illegal entry in bfchar block in ToUnicode CMap");
continue;
}
}
tok1[n1 - 1] = tok2[n2 - 1] = '\0';
if (sscanf(tok1 + 1, "%x", &code1) != 1) {
error(-1, "Illegal entry in bfchar block in ToUnicode CMap");
continue;
}
addMapping(code1, tok2 + 1, n2 - 2, 0);
}
pst->getToken(tok1, sizeof(tok1), &n1);
} else if (!strcmp(tok2, "beginbfrange")) {
while (pst->getToken(tok1, sizeof(tok1), &n1)) {
if (!strcmp(tok1, "endbfrange")) {
break;
}
if (!pst->getToken(tok2, sizeof(tok2), &n2) ||
!strcmp(tok2, "endbfrange") ||
!pst->getToken(tok3, sizeof(tok3), &n3) ||
!strcmp(tok3, "endbfrange")) {
error(-1, "Illegal entry in bfrange block in ToUnicode CMap");
break;
}
if (!(n1 == 2 + nDigits && tok1[0] == '<' && tok1[n1 - 1] == '>' &&
n2 == 2 + nDigits && tok2[0] == '<' && tok2[n2 - 1] == '>')) {
// check there was no line jump inside the token and so the length is
// longer than it should be
int countAux = 0;
for (int k = 0; k < n1; k++)
if (tok1[k] != '\n' && tok1[k] != '\r') countAux++;
int countAux2 = 0;
for (int k = 0; k < n1; k++)
if (tok2[k] != '\n' && tok2[k] != '\r') countAux++;
if (!(countAux == 2 + nDigits && tok1[0] == '<' && tok1[n1 - 1] == '>' &&
countAux2 == 2 + nDigits && tok2[0] == '<' && tok2[n2 - 1] == '>')) {
error(-1, "Illegal entry in bfrange block in ToUnicode CMap");
continue;
}
}
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 (!strcmp(tok3, "[")) {
i = 0;
while (pst->getToken(tok1, sizeof(tok1), &n1) &&
code1 + i <= code2) {
if (!strcmp(tok1, "]")) {
break;
}
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);
} else {
strcpy(tok1, tok2);
}
}
delete pst;
}
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 *)greallocn(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 *)
greallocn(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;
tag = tagA;
mapLen = 256;
map = (Unicode *)gmallocn(mapLen, sizeof(Unicode));
for (i = 0; i < mapLen; ++i) {
map[i] = 0;
}
sMap = NULL;
sMapLen = sMapSize = 0;
refCnt = 1;
#if MULTITHREADED
gInitMutex(&mutex);
#endif
}
CharCodeToUnicode::CharCodeToUnicode(GString *tagA, Unicode *mapA,
CharCode mapLenA, GBool copyMap,
CharCodeToUnicodeString *sMapA,
int sMapLenA, int sMapSizeA) {
tag = tagA;
mapLen = mapLenA;
if (copyMap) {
map = (Unicode *)gmallocn(mapLen, sizeof(Unicode));
memcpy(map, mapA, mapLen * sizeof(Unicode));
} else {
map = mapA;
}
sMap = sMapA;
sMapLen = sMapLenA;
sMapSize = sMapSizeA;
refCnt = 1;
#if MULTITHREADED
gInitMutex(&mutex);
#endif
}
CharCodeToUnicode::~CharCodeToUnicode() {
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() {
GBool done;
#if MULTITHREADED
gLockMutex(&mutex);
#endif
done = --refCnt == 0;
#if MULTITHREADED
gUnlockMutex(&mutex);
#endif
if (done) {
delete this;
}
}
GBool CharCodeToUnicode::match(GString *tagA) {
return tag && !tag->cmp(tagA);
}
void CharCodeToUnicode::setMapping(CharCode c, Unicode *u, int len) {
int i, j;
if (len == 1) {
map[c] = u[0];
} else {
for (i = 0; i < sMapLen; ++i) {
if (sMap[i].c == c) {
break;
}
}
if (i == sMapLen) {
if (sMapLen == sMapSize) {
sMapSize += 8;
sMap = (CharCodeToUnicodeString *)
greallocn(sMap, sMapSize, sizeof(CharCodeToUnicodeString));
}
++sMapLen;
}
map[c] = 0;
sMap[i].c = c;
sMap[i].len = len;
for (j = 0; j < len && j < maxUnicodeString; ++j) {
sMap[i].u[j] = u[j];
}
}
}
int CharCodeToUnicode::mapToUnicode(CharCode c, Unicode *u, int size) {
int i, j;
if (c >= mapLen) {
return 0;
}
if (map[c]) {
u[0] = map[c];
return 1;
}
for (i = 0; i < sMapLen; ++i) {
if (sMap[i].c == c) {
for (j = 0; j < sMap[i].len && j < size; ++j) {
u[j] = sMap[i].u[j];
}
return j;
}
}
return 0;
}
//------------------------------------------------------------------------
CharCodeToUnicodeCache::CharCodeToUnicodeCache(int sizeA) {
int i;
size = sizeA;
cache = (CharCodeToUnicode **)gmallocn(size, sizeof(CharCodeToUnicode *));
for (i = 0; i < size; ++i) {
cache[i] = NULL;
}
}
CharCodeToUnicodeCache::~CharCodeToUnicodeCache() {
int i;
for (i = 0; i < size; ++i) {
if (cache[i]) {
cache[i]->decRefCnt();
}
}
gfree(cache);
}
CharCodeToUnicode *CharCodeToUnicodeCache::getCharCodeToUnicode(GString *tag) {
CharCodeToUnicode *ctu;
int i, j;
if (cache[0] && cache[0]->match(tag)) {
cache[0]->incRefCnt();
return cache[0];
}
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];
}
cache[0] = ctu;
ctu->incRefCnt();
return ctu;
}
}
return NULL;
}
void CharCodeToUnicodeCache::add(CharCodeToUnicode *ctu) {
int i;
if (cache[size - 1]) {
cache[size - 1]->decRefCnt();
}
for (i = size - 1; i >= 1; --i) {
cache[i] = cache[i - 1];
}
cache[0] = ctu;
ctu->incRefCnt();
}

View File

@ -1,117 +0,0 @@
//========================================================================
//
// CharCodeToUnicode.h
//
// Mapping from character codes to Unicode.
//
// Copyright 2001-2003 Glyph & Cog, LLC
//
//========================================================================
#ifndef CHARCODETOUNICODE_H
#define CHARCODETOUNICODE_H
#include <aconf.h>
#ifdef USE_GCC_PRAGMAS
#pragma interface
#endif
#include "CharTypes.h"
#if MULTITHREADED
#include "GMutex.h"
#endif
struct CharCodeToUnicodeString;
//------------------------------------------------------------------------
class CharCodeToUnicode {
public:
// 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
// reference count to 1.
static CharCodeToUnicode *make8BitToUnicode(Unicode *toUnicode);
// 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 <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);
// Return the mapping's length, i.e., one more than the max char
// code supported by the mapping.
CharCode getLength() { return mapLen; }
private:
void parseCMap1(int (*getCharFunc)(void *), void *data, int nBits);
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, int sMapSizeA);
GString *tag;
Unicode *map;
CharCode mapLen;
CharCodeToUnicodeString *sMap;
int sMapLen, sMapSize;
int refCnt;
#if MULTITHREADED
GMutex mutex;
#endif
};
//------------------------------------------------------------------------
class CharCodeToUnicodeCache {
public:
CharCodeToUnicodeCache(int sizeA);
~CharCodeToUnicodeCache();
// 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;
int size;
};
#endif

View File

@ -1,24 +0,0 @@
//========================================================================
//
// CharTypes.h
//
// Copyright 2001-2003 Glyph & Cog, LLC
//
//========================================================================
#ifndef CHARTYPES_H
#define CHARTYPES_H
// Unicode character.
typedef unsigned int Unicode;
// Character ID for CID character collections.
typedef unsigned int CID;
// This is large enough to hold any of the following:
// - 8-bit char code
// - 16-bit CID
// - Unicode
typedef unsigned int CharCode;
#endif

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