mirror of
https://invent.kde.org/graphics/okular
synced 2024-07-02 15:49:03 +00:00
oKular goes poppler
svn path=/trunk/playground/graphics/oKular/kpdf/; revision=520367
This commit is contained in:
parent
3e168cfd07
commit
30c2f8067d
2
AUTHORS
2
AUTHORS
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
106
configure.in.in
106
configure.in.in
|
@ -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)
|
||||
|
||||
)
|
|
@ -20,7 +20,6 @@
|
|||
#include "annotations.h"
|
||||
#include "conf/settings.h"
|
||||
#include "area.h"
|
||||
//include "xpdf/TextOutputDev.h"
|
||||
|
||||
// temp includes
|
||||
#include <sys/time.h>
|
||||
|
|
|
@ -6,5 +6,9 @@ if include_chm
|
|||
CHMPLUGINDIR = chm
|
||||
endif
|
||||
|
||||
if include_pdf
|
||||
PDFPLUGINDIR = xpdf
|
||||
endif
|
||||
|
||||
SUBDIRS = $(GSPLUGINDIR) xpdf fax kimgio $(CHMPLUGINDIR)
|
||||
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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)
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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 );
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 );
|
||||
|
|
|
@ -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;
|
||||
|
|
184
generators/xpdf/pagetransition.cpp
Normal file
184
generators/xpdf/pagetransition.cpp
Normal 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;
|
||||
}
|
||||
|
140
generators/xpdf/pagetransition.h
Normal file
140
generators/xpdf/pagetransition.h
Normal 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
|
|
@ -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)
|
||||
|
|
@ -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.]
|
|
@ -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
|
||||
|
|
@ -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;
|
||||
}
|
|
@ -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
|
|
@ -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
|
||||
};
|
|
@ -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
|
@ -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
|
|
@ -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;
|
||||
}
|
|
@ -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
|
@ -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
|
|
@ -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
|
|
@ -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);
|
||||
}
|
|
@ -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
|
|
@ -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*));
|
||||
}
|
|
@ -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
|
|
@ -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
|
|
@ -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;
|
||||
}
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
||||
}
|
|
@ -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
|
|
@ -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;
|
||||
}
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
@ -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
|
|
@ -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
|
||||
}
|
||||
}
|
|
@ -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
|
|
@ -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;
|
||||
}
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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;
|
||||
}
|
|
@ -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
|
|
@ -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;
|
||||
}
|
|
@ -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
|
|
@ -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;
|
||||
}
|
||||
|
|
@ -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
|
|
@ -1,23 +0,0 @@
|
|||
//========================================================================
|
||||
//
|
||||
// SplashFontFileID.cc
|
||||
//
|
||||
//========================================================================
|
||||
|
||||
#include <aconf.h>
|
||||
|
||||
#ifdef USE_GCC_PRAGMAS
|
||||
#pragma implementation
|
||||
#endif
|
||||
|
||||
#include "SplashFontFileID.h"
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
// SplashFontFileID
|
||||
//------------------------------------------------------------------------
|
||||
|
||||
SplashFontFileID::SplashFontFileID() {
|
||||
}
|
||||
|
||||
SplashFontFileID::~SplashFontFileID() {
|
||||
}
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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;
|
||||
}
|
|
@ -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
|
|
@ -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);
|
||||
}
|
|
@ -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
|
|
@ -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;
|
||||
}
|
|
@ -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
|
|
@ -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;
|
||||
}
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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);
|
||||
}
|
|
@ -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
|
|
@ -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;
|
||||
}
|
|
@ -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
|
|
@ -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);
|
||||
}
|
|
@ -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
|
|
@ -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;
|
||||
}
|
||||
}
|
|
@ -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
|
|
@ -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);
|
||||
}
|
|
@ -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
|
@ -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
|
|
@ -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;
|
||||
}
|
|
@ -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
|
|
@ -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);
|
||||
}
|
|
@ -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
|
|
@ -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();
|
||||
}
|
|
@ -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
|
|
@ -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
Loading…
Reference in New Issue
Block a user