summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChris Liddell <chris.liddell@artifex.com>2012-06-01 15:44:11 +0100
committerChris Liddell <chris.liddell@artifex.com>2012-11-13 08:45:46 +0000
commit58937f6debfbed7675a0ce5cb8d0aa629e3fa7b8 (patch)
tree33e7aaa4c7bea89d51b66c5a5990363a1292a51c
parenta971121e9e50c672908f1b3185f42d497adf0b02 (diff)
downloadghostpdl-58937f6debfbed7675a0ce5cb8d0aa629e3fa7b8.tar.gz
Extend/modify FAPI for use by PDLs other than PS/PDF.
All languages take a -dDisableFAPI option which reverts to the AFS code. On Unuix type systems ./configure --disable-fapi and on Windows, adding "FT_BRIDGE=0" create builds without the FAPI font handling. Both of these will be removed as the FAPI code matures. Move Font API from psi into base. Split the FAPI functions into the interpreter dependent ones, and the "core" functions. Move the core functions into the graphics library. Change fapi.dev to fapi_ps.dev Since the old fapi.dev is now split into core and PS dependent parts, the old fapi.dev gets renamed as fapi_ps.dev Basic TrueType support thru FAPI for pcl and pxl. Doesn't include artificial boldening. Basic FAPI functions working with XPS interpreter. (Mostly) Make PCL/UFST work through gs_fapi API Bug 693188: don't skip glyphs with degenerate matrices In commit 752397ab, the fix for Bug 692263 was to skip over glyphs when the matrix in force for the glyph had a zero scale in either dimension. It seems that this approach had potentially unfavourable side effects in the glyph cache. So, when we encounter a degenerate matrix rendering a glyph, we now force a minimal, non-zero scale before attempting to render the glyph. This placates the glyph cache. Cluster testing shows (tiny) progressions in Bug689006.pdf, Bug690179.pdf, and Bug692634.ps, and pixel differences, not identifiable as progressions or regressions in Bug690497.pdf and 12-07C.PS. Conflicts: gs/psi/fapiufst.c gs/psi/ifapi.h gs/psi/zfapi.c Revise gs_fapi_available and zFAPIavailable so they can check for a specific fapi server being available (as well as just fapi itself being available. Tidy up header includes, and header dependencies. Typos, warnings and dependency mistakes. Handle FAPI having no servers gracefully in PCL and XPS Use existing API to retrieve glyph metrics. Fix some PCL/PXL spacing problems. Improve handling of notdefs in PCL/PXL Some reformatting. Update fapi call in xps and fix some merge mistakes. Change gs_fapi_do_char() parameters to gs_glyph and gs_char types. Handle GS_NO_CHAR value better. Remove deprecated char_code entry Provide method for client to request ttf cmap in fapi. Skip "unencodable" glyphs (that is character codes whose "decoding" results in a gs_no_glyph glyph value). Fix (finally, I think) the PCL notdef problems, and PCL text orientation. Also, a GL spacing problem. Amend the Postscript size to work with these changes. FAPI API and warnings clean up. Identify glyph index or otherwise.... ...in the FAPI PS world. fix a missing dependency Include stdint_.h in gxfapi.h.... so int64_t is available. Add dependency. Fix typo in dependency. Changes to build gs_fapi on Windows. Fix a typo <sigh> another "notdef" handling revision Add PCL/XL glyph boldening (bitmap smearing) to FAPI. Remove some debug code accidentally left in. Provide a "-dDisableFAPI" command line option for pcl/pxl/xps. It's added in a very noddy way for two reasons: it needs acted upon before the interpreter is initialised, and second to make it more obvious to remove when we've gained confidence in the new fapi code. Split fapi server builds out of lib.mak and into separate makefiles. Add one commercial server build to the Ghostscript/GhostPDL build system, so it no longer needs built separately. Also fix a couple of dependency typos/errors. Some tweaks to get the build changes working on Windows Delete makefile.... Revise build changes. Cluster differences in every PCL/PXL/XPS file with text display in a Truetype/Opentype font (including CFF).
-rw-r--r--common/msvc_top.mak2
-rw-r--r--common/ugcc_top.mak1
-rw-r--r--config.mak.in26
-rw-r--r--configure.ac67
-rw-r--r--gs/Resource/Init/gs_fapi.ps44
-rw-r--r--gs/base/Makefile.in3
-rw-r--r--gs/base/configure.ac81
-rw-r--r--gs/base/fapi_bs.mak97
-rw-r--r--gs/base/fapi_ft.c (renamed from gs/psi/fapi_ft.c)1025
-rw-r--r--gs/base/fapibstm.c (renamed from gs/psi/fapibstm.c)190
-rw-r--r--gs/base/fapiufst.c2093
-rw-r--r--gs/base/gconf.c21
-rw-r--r--gs/base/genconf.c2
-rw-r--r--gs/base/gscdefs.h3
-rw-r--r--gs/base/gsinit.c3
-rw-r--r--gs/base/gslibctx.h6
-rw-r--r--gs/base/gxfapi.c1951
-rw-r--r--gs/base/gxfapi.h434
-rw-r--r--gs/base/gxfapiu.c242
-rw-r--r--gs/base/gxfapiu.h43
-rw-r--r--gs/base/gxfont.h8
-rw-r--r--gs/base/lib.mak105
-rw-r--r--gs/base/stub.mak18
-rw-r--r--gs/base/winlib.mak3
-rw-r--r--gs/base/wrfont.c86
-rw-r--r--gs/base/wrfont.h (renamed from gs/psi/wrfont.h)30
-rw-r--r--gs/base/write_t1.c450
-rw-r--r--gs/base/write_t1.h (renamed from gs/psi/write_t1.h)12
-rw-r--r--gs/base/write_t2.c515
-rw-r--r--gs/base/write_t2.h (renamed from gs/psi/write_t2.h)6
-rw-r--r--gs/psi/fapiufst.c1781
-rw-r--r--gs/psi/ifapi.h221
-rw-r--r--gs/psi/int.mak186
-rw-r--r--gs/psi/msvc.mak2
-rw-r--r--gs/psi/wrfont.c80
-rw-r--r--gs/psi/write_t1.c372
-rw-r--r--gs/psi/write_t2.c469
-rw-r--r--gs/psi/zfapi.c3178
-rw-r--r--language_switch/pspcl6_gcc.mak3
-rw-r--r--main/pcl6_msvc.mak85
-rw-r--r--pcl/pcfontpg.c4
-rw-r--r--pcl/pcfsel.c39
-rw-r--r--pcl/pcl.mak3
-rw-r--r--pcl/pcsfont.c13
-rw-r--r--pl/pl.mak33
-rw-r--r--pl/plchar.c4
-rw-r--r--pl/plchar.h9
-rw-r--r--pl/plfapi.c572
-rw-r--r--pl/plfapi.h34
-rw-r--r--pl/plfont.c91
-rw-r--r--pl/plfont.h3
-rw-r--r--pl/plftable.c648
-rw-r--r--pl/plftable.h650
-rw-r--r--pl/pllfont.c392
-rw-r--r--pl/pllfont.h4
-rw-r--r--pl/plmain.c24
-rw-r--r--pl/pluchar.c23
-rw-r--r--pl/plufont.c9
-rw-r--r--pl/plufstlp.c27
-rw-r--r--pl/plufstlp.h16
-rw-r--r--pl/plufstlp1.c27
-rw-r--r--pl/plulfont.c12
-rw-r--r--pxl/pxfont.c24
-rw-r--r--pxl/pxl.mak2
-rw-r--r--xps/ghostxps.h2
-rw-r--r--xps/xps.mak4
-rw-r--r--xps/xps_msvc.mak33
-rw-r--r--xps/xpscff.c7
-rw-r--r--xps/xpsfapi.c213
-rw-r--r--xps/xpsfapi.h21
-rw-r--r--xps/xpsttf.c10
71 files changed, 10436 insertions, 6461 deletions
diff --git a/common/msvc_top.mak b/common/msvc_top.mak
index 46c06aef6..004c7fc07 100644
--- a/common/msvc_top.mak
+++ b/common/msvc_top.mak
@@ -36,7 +36,7 @@ AK=$(GLGENDIR)\ccf32.tr
clean_gs:
nmake /f $(GLSRCDIR)\msvclib.mak \
GLSRCDIR=$(GLSRCDIR) GLGENDIR=$(GLGENDIR) \
- GLOBJDIR=$(GLOBJDIR) clean
+ GLOBJDIR=$(GLOBJDIR) CONTRIBDIR=$(CONTRIBDIR) clean
-erase $(TARGET_XE).ilk
-erase $(TARGET_XE).pdb
-erase $(TARGET_XE).exp
diff --git a/common/ugcc_top.mak b/common/ugcc_top.mak
index 97a184d57..6d91b7926 100644
--- a/common/ugcc_top.mak
+++ b/common/ugcc_top.mak
@@ -65,6 +65,7 @@ include $(GLSRCDIR)/unix-aux.mak
include $(GLSRCDIR)/unix-end.mak
include $(GLSRCDIR)/version.mak
include $(GLSRCDIR)/freetype.mak
+include $(FAPIUFST_MAK)
UGCC_TOP_DIR:
@if test ! -d $(GLGENDIR); then mkdir $(GLGENDIR); fi
diff --git a/config.mak.in b/config.mak.in
index 1556a33e2..444a3b1a7 100644
--- a/config.mak.in
+++ b/config.mak.in
@@ -29,3 +29,29 @@ X11DEVS?=@X11DEVS@
LCMS_CFLAGS=@LCMS_ENDIAN@
LCMS2_CFLAGS=@LCMS2_ENDIAN@
+
+FT_BRIDGE?=@FT_BRIDGE@
+SHARE_FT=0
+FTSRCDIR?=$(GLSRCDIR)/../freetype
+FT_CFLAGS=-I$(GLSRCDIR)/../freetype/include
+FT_LIBS=
+FT_CONFIG_SYSTEM_ZLIB=
+
+
+# Define whether to compile in UFST.
+# UFST_BRIDGE must be either "1", or empty (*never* "0")
+UFST_BRIDGE?=@UFST_BRIDGE@
+UFST_ROOT=@UFST_ROOT@
+UFST_LIB_EXT=@UFST_LIB_EXT@
+FAPIUFST_MAK=@FAPIUFST_MAK@
+
+UFST_ROMFS_ARGS?=-b \
+ -P $(UFST_ROOT)/fontdata/mtfonts/pcl45/mt3/ -d fontdata/mtfonts/pcl45/mt3/ pcl___xj.fco plug__xi.fco wd____xh.fco \
+ -P $(UFST_ROOT)/fontdata/mtfonts/pclps2/mt3/ -d fontdata/mtfonts/pclps2/mt3/ pclp2_xj.fco \
+ -c -P $(PSSRCDIR)/../lib/ -d Resource/Init/ FAPIconfig-FCO
+
+UFSTROMFONTDIR=\"%rom%fontdata/\"
+UFSTDISCFONTDIR?=\"$(UFST_ROOT)/fontdata/\"
+
+
+UFST_CFLAGS=@UFST_CFLAGS@
diff --git a/configure.ac b/configure.ac
index 1bc7ca870..5f7289c06 100644
--- a/configure.ac
+++ b/configure.ac
@@ -116,6 +116,73 @@ cd $olddir
echo
echo "Continuing with GhostPDL configuration..."
+
+dnl --------------------------------------------------
+dnl Should we use FAPI, and which server(s)
+dnl --------------------------------------------------
+
+FT_BRIDGE=0
+UFST_BRIDGE=
+UFST_ROOT=
+UFST_CFLAGS=
+UFST_LIB_EXT=
+FAPIUFST_MAK="\$(GLSRCDIR)/stub.mak"
+
+AC_ARG_ENABLE([fapi], AC_HELP_STRING([--disable-fapi],
+ [Force use of the (deprecated) Artifex font scaler/renderer]))
+
+if test x"$enable_fapi" != xno; then
+ FT_BRIDGE=1
+ AC_ARG_ENABLE([freetype], AC_HELP_STRING([--disable-freetype],
+ [Disable freetype for font rasterization]))
+
+ if test x"$enable_freetype" != xno; then
+ if ! test -f gs/freetype/src/base/ftbbox.c; then
+ FT_BRIDGE=0
+ fi
+ else
+ FT_BRIDGE=0
+ fi
+
+ dnl UFST detection
+ AC_ARG_WITH([ufst], AC_HELP_STRING([--with-ufst=UFST_ROOT_DIR],
+ [Use UFST]), [], [with_ufst=no])
+
+ if test -d $with_ufst; then
+ UFST_BRIDGE=1
+ case $with_ufst in
+ /*) UFST_ROOT=$with_ufst ;;
+ *) UFST_ROOT=`pwd`/$with_ufst ;;
+ esac
+
+ FAPIUFST_MAK="\$(UFST_ROOT)/fapiufst.mak"
+
+ # Check pointer size
+ AC_CHECK_SIZEOF(char*)
+
+ if test "x$ac_cv_sizeof_charp" = "x8"; then
+ UFST_CFLAGS="-DGCCx86_64 -DO_BINARY=0"
+ else
+ if test "x$ac_cv_sizeof_charp" = "x4"; then
+ UFST_CFLAGS="-DGCCx86 -DO_BINARY=0"
+ fi
+ fi
+
+ UFST_LIB_EXT=.a
+ fi
+fi
+
+
+AC_SUBST(UFST_BRIDGE)
+AC_SUBST(UFST_ROOT)
+AC_SUBST(UFST_CFLAGS)
+AC_SUBST(UFST_LIB_EXT)
+AC_SUBST(FAPIUFST_MAK)
+
+AC_SUBST(FT_BRIDGE)
+
+
+
dnl --------------------------------------------------
dnl check for big/little endian for LCMS
dnl --------------------------------------------------
diff --git a/gs/Resource/Init/gs_fapi.ps b/gs/Resource/Init/gs_fapi.ps
index 8c30751c9..44a9c66e7 100644
--- a/gs/Resource/Init/gs_fapi.ps
+++ b/gs/Resource/Init/gs_fapi.ps
@@ -15,7 +15,7 @@
% Redefine Font and CIDFont categories with FAPI-handeled fonts.
-systemdict /.FAPIavailable known { .FAPIavailable } { //false } ifelse not {
+systemdict /.FAPIavailable known { //null .FAPIavailable } { //false } ifelse not {
(%END FAPI) .skipeof
} if
@@ -95,6 +95,48 @@ languagelevel 2 .setlanguagelevel
>> def
systemdict /.FAPIconfig //Config put
+/UFST .FAPIavailable
+{
+ systemdict /UFST_SSdir known
+ {
+ /UFSTFONTDIR UFST_SSdir def
+ systemdict /UFST_SSdir undef
+ }
+ {
+ /UFSTROMFONTDIR (%rom%fontdata/) def
+
+ UFSTROMFONTDIR (mtfonts/pcl45/mt3/plug__xi.fco)
+ concatstrings status
+ {
+ pop pop pop pop
+ /UFSTFONTDIR UFSTROMFONTDIR def
+ }
+ {
+ /UFSTFONTDIR () def
+ } ifelse
+ } ifelse
+
+ systemdict /UFST_PlugIn known not
+ {
+ systemdict /UFST_PlugIn UFSTFONTDIR (mtfonts/pcl45/mt3/plug__xi.fco) concatstrings put
+ } if
+
+ systemdict /FCOfontfile known not
+ {
+ systemdict /FCOfontfile UFSTFONTDIR (mtfonts/pclps2/mt3/pclp2_xj.fco) concatstrings put
+ } if
+
+ systemdict /FCOfontfile2 known not
+ {
+ systemdict /FCOfontfile2 UFSTFONTDIR (mtfonts/pcl45/mt3/wd____xh.fco) concatstrings put
+ } if
+
+ systemdict /FAPIfontmap known not
+ {
+ systemdict /FAPIfontmap (FCOfontmap-PCLPS2) put
+ } if
+} if
+
()
systemdict /UFST_SSdir .knownget {
(UFST_SSdir=) exch concatstrings concatstrings
diff --git a/gs/base/Makefile.in b/gs/base/Makefile.in
index e629988ec..617c2ca86 100644
--- a/gs/base/Makefile.in
+++ b/gs/base/Makefile.in
@@ -445,7 +445,7 @@ DYNANIC_LIB_EXT = @DYNANIC_LIB_EXT@
# Choose the language feature(s) to include. See gs.mak for details.
-FEATURE_DEVS=$(PSD)psl3.dev $(PSD)pdf.dev $(PSD)dpsnext.dev $(PSD)ttfont.dev $(PSD)epsf.dev $(GLD)pipe.dev $(GLD)gsnogc.dev $(GLD)htxlib.dev $(PSD)fapi.dev @JBIG2DEVS@ @JPXDEVS@ @UTF8DEVS@
+FEATURE_DEVS=$(PSD)psl3.dev $(PSD)pdf.dev $(PSD)dpsnext.dev $(PSD)ttfont.dev $(PSD)epsf.dev $(GLD)pipe.dev $(GLD)gsnogc.dev $(GLD)htxlib.dev @JBIG2DEVS@ @JPXDEVS@ @UTF8DEVS@
#FEATURE_DEVS=$(PSD)psl3.dev $(PSD)pdf.dev
#FEATURE_DEVS=$(PSD)psl3.dev $(PSD)pdf.dev $(PSD)dpsnext.dev $(PSD)ttfont.dev $(PSD)rasterop.dev $(GLD)pipe.dev
# The following is strictly for testing.
@@ -587,6 +587,7 @@ include $(PSSRCDIR)/psromfs.mak
include $(GLSRCDIR)/lib.mak
include $(PSSRCDIR)/int.mak
include $(GLSRCDIR)/freetype.mak
+include @FAPIUFST_MAK@
include $(GLSRCDIR)/jpeg.mak
# zlib.mak must precede png.mak
include $(GLSRCDIR)/zlib.mak
diff --git a/gs/base/configure.ac b/gs/base/configure.ac
index f6d28c147..16f20bbdf 100644
--- a/gs/base/configure.ac
+++ b/gs/base/configure.ac
@@ -588,48 +588,69 @@ AC_CHECK_LIB(dl, dlopen)
AC_ARG_ENABLE([freetype], AC_HELP_STRING([--disable-freetype],
[Disable freetype for font rasterization]))
+
FT_BRIDGE=0
SHARE_FT=0
FTSRCDIR=
FT_CFLAGS=
FT_LIBS=
-dnl UFST detection
-AC_ARG_WITH([ufst], AC_HELP_STRING([--with-ufst=UFST_ROOT_DIR],
- [Use UFST]),
- [], [with_ufst=no])
INSERT_UFST_BRIDGE_EQUAL_ONE=
UFST_ROOT=
UFST_CFLAGS=
UFST_LIB_EXT=
-if test -d $with_ufst; then
-INSERT_UFST_BRIDGE_EQUAL_ONE="UFST_BRIDGE=1"
-UFST_ROOT=$with_ufst
-UFST_CFLAGS=-DGCCx86
-UFST_LIB_EXT=.a
-fi
-AC_SUBST(INSERT_UFST_BRIDGE_EQUAL_ONE)
-AC_SUBST(UFST_ROOT)
-AC_SUBST(UFST_CFLAGS)
-AC_SUBST(UFST_LIB_EXT)
+FAPIUFST_MAK="\$(GLSRCDIR)/stub.mak"
+
+AC_ARG_ENABLE([fapi], AC_HELP_STRING([--disable-fapi],
+ [Force use of the (deprecated) Artifex font scaler/renderer]))
+
+if test x"$enable_fapi" != xno; then
+
+ dnl UFST detection
+ AC_ARG_WITH([ufst], AC_HELP_STRING([--with-ufst=UFST_ROOT_DIR],
+ [Use UFST]),
+ [], [with_ufst=no])
+ if test -d $with_ufst; then
+ INSERT_UFST_BRIDGE_EQUAL_ONE="UFST_BRIDGE=1"
+ case $with_ufst in
+ /*) UFST_ROOT=$with_ufst ;;
+ *) UFST_ROOT=`pwd`/$with_ufst ;;
+ esac
+
+ FAPIUFST_MAK="\$(UFST_ROOT)/fapiufst.mak"
+
+ # Check pointer size
+ AC_CHECK_SIZEOF(char*)
+
+ if test "x$ac_cv_sizeof_charp" = "x8"; then
+ UFST_CFLAGS="-DGCCx86_64 -DO_BINARY=0"
+ else
+ if test "x$ac_cv_sizeof_charp" = "x4"; then
+ UFST_CFLAGS="-DGCCx86 -DO_BINARY=0"
+ fi
+ fi
+
+ UFST_LIB_EXT=.a
+ fi
-if test x"$enable_freetype" != xno; then
- AC_MSG_CHECKING([for local freetype library source])
- dnl We prefer freetype2 over freetype, so it is easy to override
- dnl the included freetype source with a checkout from upstream.
- for dir in freetype2 freetype; do
- if test -f $dir/src/base/ftbbox.c; then
+ if test x"$enable_freetype" != xno; then
+ AC_MSG_CHECKING([for local freetype library source])
+ dnl We prefer freetype2 over freetype, so it is easy to override
+ dnl the included freetype source with a checkout from upstream.
+ for dir in freetype2 freetype; do
+ if test -f $dir/src/base/ftbbox.c; then
AC_MSG_RESULT(yes)
SHARE_FT=0
FTSRCDIR="$dir"
FT_CFLAGS="-I$dir/include"
FT_BRIDGE=1
break;
- fi
- done
- if test -z $FTSRCDIR; then
- AC_MSG_RESULT([no])
- if test "x$PKGCONFIG" != x; then
+ fi
+ done
+
+ if test -z $FTSRCDIR; then
+ AC_MSG_RESULT([no])
+ if test "x$PKGCONFIG" != x; then
AC_MSG_CHECKING(for system freetype2 >= 2.4.2 with pkg-config)
# pkg-config needs the libtool version, which != the freetype2 version <sigh!>
# There is a table of corresponding ft2<->libtool numbers in freetype/docs/VERSION.DLL
@@ -644,7 +665,7 @@ if test x"$enable_freetype" != xno; then
AC_MSG_WARN([freetype library source not found...using native rasterizer])
AFS=1
fi
- else
+ else
AC_CHECK_HEADER([ft2build.h], [FT_BRIDGE=1], [AFS=1])
if test "x$FT_BRIDGE" = x1; then
@@ -671,9 +692,17 @@ if test x"$enable_freetype" != xno; then
fi
fi
+ fi
fi
fi
fi
+
+AC_SUBST(INSERT_UFST_BRIDGE_EQUAL_ONE)
+AC_SUBST(UFST_ROOT)
+AC_SUBST(UFST_CFLAGS)
+AC_SUBST(UFST_LIB_EXT)
+AC_SUBST(FAPIUFST_MAK)
+
AC_SUBST(FT_BRIDGE)
AC_SUBST(SHARE_FT)
AC_SUBST(FTSRCDIR)
diff --git a/gs/base/fapi_bs.mak b/gs/base/fapi_bs.mak
new file mode 100644
index 000000000..20f88ad1a
--- /dev/null
+++ b/gs/base/fapi_bs.mak
@@ -0,0 +1,97 @@
+# Copyright (C) 2001-2012 Artifex Software, Inc.
+# All Rights Reserved.
+#
+# This software is provided AS-IS with no warranty, either express or
+# implied.
+#
+# This software is distributed under license and may not be copied,
+# modified or distributed except as expressly authorized under the terms
+# of the license contained in the file LICENSE in this distribution.
+#
+# Refer to licensing information at http://www.artifex.com or contact
+# Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael,
+# CA 94903, U.S.A., +1(415)492-9861, for further information.
+#
+#
+# makefile for Bitstream as part of the monolithic gs build.
+#
+# WARNING: the FAPI/Bitstream interface is incomplete.
+#
+# Users of this makefile must define the following:
+# BITSTREAM_ROOT - the source directory
+# GLGEN - the generated intermediate file directory
+# GLOBJ - the object file directory
+# BITSTREAM_CFLAGS - The include options for the Bitstream library
+
+# Define the name of this makefile.
+FAPI_BS_MAK=$(GLSRC)fapi_bs.mak
+
+# Bitstream bridge :
+
+BITSTREAM_LIB=$(BITSTREAM_ROOT)$(D)core$(D)
+BITSTREAM_INC=$(I_)"$(BITSTREAM_ROOT)$(D)core"
+
+$(GLD)fapib1.dev : $(FAPI_BS_MAK) $(ECHOGS_XE) \
+ $(GLOBJ)fapibstm.$(OBJ) $(GLOBJ)t2k.$(OBJ) $(GLOBJ)t2kextra.$(OBJ) $(GLOBJ)tsimem.$(OBJ)\
+ $(GLOBJ)t2ktt.$(OBJ) $(GLOBJ)cstream.$(OBJ) $(GLOBJ)fft1hint.$(OBJ) $(GLOBJ)ghints.$(OBJ)\
+ $(GLOBJ)glyph.$(OBJ) $(GLOBJ)t1.$(OBJ) $(GLOBJ)t2kstrm.$(OBJ) $(GLOBJ)truetype.$(OBJ)\
+ $(GLOBJ)util.$(OBJ) $(GLOBJ)fnt.$(OBJ) $(GLOBJ)pclread.$(OBJ) $(GLOBJ)t2ksc.$(OBJ)\
+ $(GLOBJ)write_t1.$(OBJ) $(GLOBJ)write_t2.$(OBJ) $(GLOBJ)wrfont.$(OBJ)
+ $(SETMOD) $(GLD)fapib1 $(GLOBJ)fapibstm.$(OBJ)
+ $(ADDMOD) $(GLD)fapib1 $(GLOBJ)t2k.$(OBJ) $(GLOBJ)t2kextra.$(OBJ) $(GLOBJ)fnt.$(OBJ)
+ $(ADDMOD) $(GLD)fapib1 $(GLOBJ)tsimem.$(OBJ) $(GLOBJ)t2ktt.$(OBJ) $(GLOBJ)util.$(OBJ)
+ $(ADDMOD) $(GLD)fapib1 $(GLOBJ)t2kstrm.$(OBJ) $(GLOBJ)truetype.$(OBJ) $(GLOBJ)cstream.$(OBJ)
+ $(ADDMOD) $(GLD)fapib1 $(GLOBJ)fft1hint.$(OBJ) $(GLOBJ)ghints.$(OBJ) $(GLOBJ)glyph.$(OBJ)
+ $(ADDMOD) $(GLD)fapib1 $(GLOBJ)t1.$(OBJ) $(GLOBJ)pclread.$(OBJ) $(GLOBJ)t2ksc.$(OBJ)
+ $(ADDMOD) $(GLD)fapib1 $(GLOBJ)write_t1.$(OBJ) $(GLOBJ)write_t2.$(OBJ) $(GLOBJ)wrfont.$(OBJ)
+ $(ADDMOD) $(GLD)fapib1 -plugin fapibstm
+
+$(GLOBJ)fapibstm.$(OBJ) : $(FAPI_BS_MAK) $(GLSRC)fapibstm.c $(AK)\
+ $(stdio__h) $(memory__h) $(math__h) $(strmio_h)\
+ $(ierrors_h) $(iplugin_h) $(gxfapi_h) $(gxfapi_h) $(gp_h)
+ $(GLCC) $(BITSTREAM_CFLAGS) $(BITSTREAM_INC) $(GLO_)fapibstm.$(OBJ) $(C_) $(GLSRC)fapibstm.c
+
+$(GLOBJ)t2k.$(OBJ) : $(FAPI_BS_MAK) "$(BITSTREAM_LIB)t2k.c" $(AK)
+ $(GLCC) $(BITSTREAM_CFLAGS) $(BITSTREAM_INC) $(GLO_)t2k.$(OBJ) $(C_) "$(BITSTREAM_LIB)t2k.c"
+
+$(GLOBJ)t2kextra.$(OBJ) : $(FAPI_BS_MAK) "$(BITSTREAM_LIB)t2kextra.c" $(AK)
+ $(GLCC) $(BITSTREAM_CFLAGS) $(BITSTREAM_INC) $(GLO_)t2kextra.$(OBJ) $(C_) "$(BITSTREAM_LIB)t2kextra.c"
+
+$(GLOBJ)tsimem.$(OBJ) : $(FAPI_BS_MAK) "$(BITSTREAM_LIB)tsimem.c" $(AK)
+ $(GLCC) $(BITSTREAM_CFLAGS) $(BITSTREAM_INC) $(GLO_)tsimem.$(OBJ) $(C_) "$(BITSTREAM_LIB)tsimem.c"
+
+$(GLOBJ)t2ktt.$(OBJ) : $(FAPI_BS_MAK) "$(BITSTREAM_LIB)t2ktt.c" $(AK)
+ $(GLCC) $(BITSTREAM_CFLAGS) $(BITSTREAM_INC) $(GLO_)t2ktt.$(OBJ) $(C_) "$(BITSTREAM_LIB)t2ktt.c"
+
+$(GLOBJ)cstream.$(OBJ) : $(FAPI_BS_MAK) "$(BITSTREAM_LIB)cstream.c" $(AK)
+ $(GLCC) $(BITSTREAM_CFLAGS) $(BITSTREAM_INC) $(GLO_)cstream.$(OBJ) $(C_) "$(BITSTREAM_LIB)cstream.c"
+
+$(GLOBJ)fft1hint.$(OBJ) : $(FAPI_BS_MAK) "$(BITSTREAM_LIB)fft1hint.c" $(AK)
+ $(GLCC) $(BITSTREAM_CFLAGS) $(BITSTREAM_INC) $(GLO_)fft1hint.$(OBJ) $(C_) "$(BITSTREAM_LIB)fft1hint.c"
+
+$(GLOBJ)ghints.$(OBJ) : $(FAPI_BS_MAK) "$(BITSTREAM_LIB)ghints.c" $(AK)
+ $(GLCC) $(BITSTREAM_CFLAGS) $(BITSTREAM_INC) $(GLO_)ghints.$(OBJ) $(C_) "$(BITSTREAM_LIB)ghints.c"
+
+$(GLOBJ)glyph.$(OBJ) : $(FAPI_BS_MAK) "$(BITSTREAM_LIB)glyph.c" $(AK)
+ $(GLCC) $(BITSTREAM_CFLAGS) $(BITSTREAM_INC) $(GLO_)glyph.$(OBJ) $(C_) "$(BITSTREAM_LIB)glyph.c"
+
+$(GLOBJ)t1.$(OBJ) : $(FAPI_BS_MAK) "$(BITSTREAM_LIB)t1.c" $(AK)
+ $(GLCC) $(BITSTREAM_CFLAGS) $(BITSTREAM_INC) $(GLO_)t1.$(OBJ) $(C_) "$(BITSTREAM_LIB)t1.c"
+
+$(GLOBJ)t2kstrm.$(OBJ) : $(FAPI_BS_MAK) "$(BITSTREAM_LIB)t2kstrm.c" $(AK)
+ $(GLCC) $(BITSTREAM_CFLAGS) $(BITSTREAM_INC) $(GLO_)t2kstrm.$(OBJ) $(C_) "$(BITSTREAM_LIB)t2kstrm.c"
+
+$(GLOBJ)truetype.$(OBJ) : $(FAPI_BS_MAK) "$(BITSTREAM_LIB)truetype.c" $(AK)
+ $(GLCC) $(BITSTREAM_CFLAGS) $(BITSTREAM_INC) $(GLO_)truetype.$(OBJ) $(C_) "$(BITSTREAM_LIB)truetype.c"
+
+$(GLOBJ)util.$(OBJ) : $(FAPI_BS_MAK) "$(BITSTREAM_LIB)util.c" $(AK)
+ $(GLCC) $(BITSTREAM_CFLAGS) $(BITSTREAM_INC) $(GLO_)util.$(OBJ) $(C_) "$(BITSTREAM_LIB)util.c"
+
+$(GLOBJ)fnt.$(OBJ) : $(FAPI_BS_MAK) "$(BITSTREAM_LIB)fnt.c" $(AK)
+ $(GLCC) $(BITSTREAM_CFLAGS) $(BITSTREAM_INC) $(GLO_)fnt.$(OBJ) $(C_) "$(BITSTREAM_LIB)fnt.c"
+
+$(GLOBJ)pclread.$(OBJ) : $(FAPI_BS_MAK) "$(BITSTREAM_LIB)pclread.c" $(AK)
+ $(GLCC) $(BITSTREAM_CFLAGS) $(BITSTREAM_INC) $(GLO_)pclread.$(OBJ) $(C_) "$(BITSTREAM_LIB)pclread.c"
+
+$(GLOBJ)t2ksc.$(OBJ) : $(FAPI_BS_MAK) "$(BITSTREAM_LIB)t2ksc.c" $(AK)
+ $(GLCC) $(BITSTREAM_CFLAGS) $(BITSTREAM_INC) $(GLO_)t2ksc.$(OBJ) $(C_) "$(BITSTREAM_LIB)t2ksc.c"
diff --git a/gs/psi/fapi_ft.c b/gs/base/fapi_ft.c
index dd1a4cf65..6db05cc8c 100644
--- a/gs/psi/fapi_ft.c
+++ b/gs/base/fapi_ft.c
@@ -22,8 +22,6 @@
/* GhostScript headers. */
#include "stdio_.h"
#include "malloc_.h"
-#include "ierrors.h"
-#include "ifapi.h"
#include "write_t1.h"
#include "write_t2.h"
#include "math_.h"
@@ -40,6 +38,9 @@
#include "gsfname.h"
+#include "gxfapi.h"
+
+
/* FreeType headers */
#include <ft2build.h>
#include FT_FREETYPE_H
@@ -55,18 +56,20 @@
/* Note: structure definitions here start with FF_, which stands for 'FAPI FreeType". */
-typedef struct FF_server_s
+typedef struct ff_server_s
{
- FAPI_server fapi_server;
+ gs_fapi_server fapi_server;
FT_Library freetype_library;
FT_OutlineGlyph outline_glyph;
FT_BitmapGlyph bitmap_glyph;
gs_memory_t *mem;
FT_Memory ftmemory;
- struct FT_MemoryRec_ ftmemory_rec;
-} FF_server;
+ struct FT_MemoryRec_ ftmemory_rec;
+} ff_server;
+
-typedef struct FF_face_s
+
+typedef struct ff_face_s
{
FT_Face ft_face;
@@ -82,7 +85,8 @@ typedef struct FF_face_s
FT_Stream ftstrm;
/* Non-null if font data is owned by this object. */
unsigned char *font_data;
-} FF_face;
+ int font_data_len;
+} ff_face;
/* Here we define the struct FT_Incremental that is used as an opaque type
* inside FreeType. This structure has to have the tag FT_IncrementalRec_
@@ -90,51 +94,52 @@ typedef struct FF_face_s
*/
typedef struct FT_IncrementalRec_
{
- FAPI_font *fapi_font; /* The font. */
+ gs_fapi_font *fapi_font; /* The font. */
/* If it is already in use glyph data is allocated on the heap. */
- unsigned char *glyph_data; /* A one-shot buffer for glyph data. */
- size_t glyph_data_length; /* Length in bytes of glyph_data. */
- bool glyph_data_in_use; /* True if glyph_data is already in use. */
+ unsigned char *glyph_data; /* A one-shot buffer for glyph data. */
+ size_t glyph_data_length; /* Length in bytes of glyph_data. */
+ bool glyph_data_in_use; /* True if glyph_data is already in use. */
- FT_Incremental_MetricsRec glyph_metrics; /* Incremental glyph metrics supplied by Ghostscript. */
- unsigned long glyph_metrics_index; /* contains data for this glyph index unless it is 0xFFFFFFFF. */
- FAPI_metrics_type metrics_type; /* determines whether metrics are replaced, added, etc. */
+ FT_Incremental_MetricsRec glyph_metrics; /* Incremental glyph metrics supplied by Ghostscript. */
+ unsigned long glyph_metrics_index; /* contains data for this glyph index unless it is 0xFFFFFFFF. */
+ gs_fapi_metrics_type metrics_type; /* determines whether metrics are replaced, added, etc. */
} FT_IncrementalRec;
-FT_CALLBACK_DEF( void* )
-FF_alloc( FT_Memory memory, long size)
+FT_CALLBACK_DEF(void *)
+FF_alloc(FT_Memory memory, long size)
{
- gs_memory_t *mem = (gs_memory_t *)memory->user;
+ gs_memory_t *mem = (gs_memory_t *) memory->user;
- return(gs_malloc (mem, size, 1, "FF_alloc"));
+ return (gs_malloc(mem, size, 1, "FF_alloc"));
}
-FT_CALLBACK_DEF( void* )
-FF_realloc(FT_Memory memory, long cur_size, long new_size, void* block)
+FT_CALLBACK_DEF(void *)
+ FF_realloc(FT_Memory memory, long cur_size, long new_size, void *block)
{
- gs_memory_t *mem = (gs_memory_t *)memory->user;
+ gs_memory_t *mem = (gs_memory_t *) memory->user;
void *tmp;
if (cur_size == new_size) {
return (block);
}
- tmp = gs_malloc (mem, new_size, 1, "FF_realloc");
+ tmp = gs_malloc(mem, new_size, 1, "FF_realloc");
if (tmp && block) {
- memcpy (tmp, block, min(cur_size, new_size));
+ memcpy(tmp, block, min(cur_size, new_size));
- gs_free (mem, block, 0, 0, "FF_realloc");
+ gs_free(mem, block, 0, 0, "FF_realloc");
}
- return(tmp);
+ return (tmp);
}
-FT_CALLBACK_DEF( void )
-FF_free(FT_Memory memory, void* block)
+FT_CALLBACK_DEF(void)
+ FF_free(FT_Memory memory, void *block)
{
- gs_memory_t *mem = (gs_memory_t *)memory->user;
- gs_free (mem, block, 0, 0, "FF_free");
+ gs_memory_t *mem = (gs_memory_t *) memory->user;
+
+ gs_free(mem, block, 0, 0, "FF_free");
}
/* The following three functions are used in providing a custom stream
@@ -142,9 +147,11 @@ FF_free(FT_Memory memory, void* block)
* file i/o. Most importantly, this gives Freetype direct access to
* files in the romfs
*/
-static FT_ULong FF_stream_read (FT_Stream str, unsigned long offset, unsigned char* buffer, unsigned long count)
+static FT_ULong
+FF_stream_read(FT_Stream str, unsigned long offset, unsigned char *buffer,
+ unsigned long count)
{
- stream *ps = (stream *)str->descriptor.pointer;
+ stream *ps = (stream *) str->descriptor.pointer;
unsigned int rlen = 0;
int status = 0;
@@ -155,21 +162,23 @@ static FT_ULong FF_stream_read (FT_Stream str, unsigned long offset, unsigned ch
status = sgets(ps, buffer, count, &rlen);
if (status < 0 && status != EOFC)
- return(-1);
+ return (-1);
}
- return(rlen);
+ return (rlen);
}
-static void FF_stream_close (FT_Stream str)
+static void
+FF_stream_close(FT_Stream str)
{
- stream *ps = (stream *)str->descriptor.pointer;
+ stream *ps = (stream *) str->descriptor.pointer;
(void)sclose(ps);
}
extern const uint file_default_buffer_size;
-static int FF_open_read_stream (gs_memory_t *mem, char *fname, FT_Stream *fts)
+static int
+FF_open_read_stream(gs_memory_t * mem, char *fname, FT_Stream * fts)
{
int code = 0;
gs_parsed_file_name_t pfn;
@@ -178,21 +187,22 @@ static int FF_open_read_stream (gs_memory_t *mem, char *fname, FT_Stream *fts)
FT_Stream ftstrm = NULL;
code = gs_parse_file_name(&pfn, (const char *)fname, strlen(fname), mem);
- if (code < 0){
+ if (code < 0) {
goto error_out;
}
-
+
if (!pfn.fname) {
- code = e_undefinedfilename;
+ code = gs_error_undefinedfilename;
goto error_out;
}
-
+
if (pfn.iodev == NULL) {
pfn.iodev = iodev_default(mem);
}
-
+
if (pfn.iodev) {
gx_io_device *const iodev = pfn.iodev;
+
iodev_proc_open_file((*open_file)) = iodev->procs.open_file;
if (open_file) {
@@ -202,21 +212,23 @@ static int FF_open_read_stream (gs_memory_t *mem, char *fname, FT_Stream *fts)
}
}
else {
- code = file_open_stream(pfn.fname, pfn.len, "r", file_default_buffer_size,
- &ps, pfn.iodev, pfn.iodev->procs.fopen, mem);
+ code =
+ file_open_stream(pfn.fname, pfn.len, "r",
+ file_default_buffer_size, &ps, pfn.iodev,
+ pfn.iodev->procs.fopen, mem);
if (code < 0) {
goto error_out;
}
}
}
- if ((code = savailable(ps, &length)) < 0){
+ if ((code = savailable(ps, &length)) < 0) {
goto error_out;
}
ftstrm = gs_malloc(mem, sizeof(FT_StreamRec), 1, "FF_open_read_stream");
- if (!ftstrm){
- code = e_VMerror;
+ if (!ftstrm) {
+ code = gs_error_VMerror;
goto error_out;
}
memset(ftstrm, 0x00, sizeof(FT_StreamRec));
@@ -227,37 +239,41 @@ static int FF_open_read_stream (gs_memory_t *mem, char *fname, FT_Stream *fts)
ftstrm->size = (long)length;
*fts = ftstrm;
-error_out:
+ error_out:
if (code < 0) {
- if (ps) (void)sclose(ps);
- if (ftstrm) gs_free(mem, ftstrm, 0, 0, "FF_open_read_stream");
+ if (ps)
+ (void)sclose(ps);
+ if (ftstrm)
+ gs_free(mem, ftstrm, 0, 0, "FF_open_read_stream");
}
- return(code);
+ return (code);
}
-static FF_face *
-new_face(FAPI_server *a_server, FT_Face a_ft_face, FT_Incremental_InterfaceRec *a_ft_inc_int, FT_Stream ftstrm, unsigned char *a_font_data)
+static ff_face *
+new_face(gs_fapi_server * a_server, FT_Face a_ft_face,
+ FT_Incremental_InterfaceRec * a_ft_inc_int, FT_Stream ftstrm,
+ unsigned char *a_font_data, int a_font_data_len)
{
- FF_server *s = (FF_server*)a_server;
+ ff_server *s = (ff_server *) a_server;
+
+ ff_face *face = (ff_face *) FF_alloc(s->ftmemory, sizeof(ff_face));
- FF_face *face = (FF_face *)FF_alloc(s->ftmemory, sizeof(FF_face));
- if (face)
- {
+ if (face) {
face->ft_face = a_ft_face;
face->ft_inc_int = a_ft_inc_int;
face->font_data = a_font_data;
+ face->font_data_len = a_font_data_len;
face->ftstrm = ftstrm;
}
return face;
}
static void
-delete_face(FAPI_server *a_server, FF_face *a_face)
+delete_face(gs_fapi_server * a_server, ff_face * a_face)
{
- if (a_face)
- {
- FF_server *s = (FF_server*)a_server;
+ if (a_face) {
+ ff_server *s = (ff_server *) a_server;
FT_Done_Face(a_face->ft_face);
FF_free(s->ftmemory, a_face->ft_inc_int);
@@ -270,38 +286,40 @@ delete_face(FAPI_server *a_server, FF_face *a_face)
}
static FT_IncrementalRec *
-new_inc_int_info(FAPI_server *a_server, FAPI_font *a_fapi_font)
+new_inc_int_info(gs_fapi_server * a_server, gs_fapi_font * a_fapi_font)
{
- FF_server *s = (FF_server*)a_server;
+ ff_server *s = (ff_server *) a_server;
- FT_IncrementalRec *info = (FT_IncrementalRec*)FF_alloc(s->ftmemory, sizeof(FT_IncrementalRec));
- if (info)
- {
+ FT_IncrementalRec *info =
+ (FT_IncrementalRec *) FF_alloc(s->ftmemory,
+ sizeof(FT_IncrementalRec));
+ if (info) {
info->fapi_font = a_fapi_font;
info->glyph_data = NULL;
info->glyph_data_length = 0;
info->glyph_data_in_use = false;
info->glyph_metrics_index = 0xFFFFFFFF;
- info->metrics_type = FAPI_METRICS_NOTDEF;
+ info->metrics_type = gs_fapi_metrics_notdef;
}
return info;
}
static void
-delete_inc_int_info(FAPI_server *a_server, FT_IncrementalRec *a_inc_int_info)
+delete_inc_int_info(gs_fapi_server * a_server,
+ FT_IncrementalRec * a_inc_int_info)
{
- FF_server *s = (FF_server*)a_server;
- if (a_inc_int_info)
- {
+ ff_server *s = (ff_server *) a_server;
+
+ if (a_inc_int_info) {
FF_free(s->ftmemory, a_inc_int_info->glyph_data);
FF_free(s->ftmemory, a_inc_int_info);
}
}
static FT_Error
-get_fapi_glyph_data(FT_Incremental a_info, FT_UInt a_index, FT_Data *a_data)
+get_fapi_glyph_data(FT_Incremental a_info, FT_UInt a_index, FT_Data * a_data)
{
- FAPI_font *ff = a_info->fapi_font;
+ gs_fapi_font *ff = a_info->fapi_font;
int length = 0;
/* Tell the FAPI interface that we need to decrypt the glyph data. */
@@ -310,45 +328,52 @@ get_fapi_glyph_data(FT_Incremental a_info, FT_UInt a_index, FT_Data *a_data)
/* If glyph_data is already in use (as will happen for composite glyphs)
* create a new buffer on the heap.
*/
- if (a_info->glyph_data_in_use)
- {
+ if (a_info->glyph_data_in_use) {
unsigned char *buffer = NULL;
+
length = ff->get_glyph(ff, a_index, NULL, 0);
if (length == 65535)
return FT_Err_Invalid_Glyph_Index;
- buffer = gs_malloc ((gs_memory_t *)a_info->fapi_font->memory, length, 1, "get_fapi_glyph_data");
+ buffer =
+ gs_malloc((gs_memory_t *) a_info->fapi_font->memory, length, 1,
+ "get_fapi_glyph_data");
if (!buffer)
return FT_Err_Out_Of_Memory;
length = ff->get_glyph(ff, a_index, buffer, length);
if (length == 65535) {
- gs_free ((gs_memory_t *)a_info->fapi_font->memory, buffer, 0, 0, "get_fapi_glyph_data");
+ gs_free((gs_memory_t *) a_info->fapi_font->memory, buffer, 0, 0,
+ "get_fapi_glyph_data");
return FT_Err_Invalid_Glyph_Index;
}
a_data->pointer = buffer;
}
- else
- {
+ else {
/* Save ff->char_data, which is set to null by FAPI_FF_get_glyph as part of a hack to
* make the deprecated Type 2 endchar ('seac') work, so that it can be restored
* if we need to try again with a longer buffer.
*/
const void *saved_char_data = ff->char_data;
- /* Get as much of the glyph data as possible into the buffer */
- length = ff->get_glyph(ff, a_index, a_info->glyph_data, (ushort)a_info->glyph_data_length);
- if (length == -1) {
- ff->char_data = saved_char_data;
- return FT_Err_Unknown_File_Format;
- }
+ /* Get as much of the glyph data as possible into the buffer */
+ length =
+ ff->get_glyph(ff, a_index, a_info->glyph_data,
+ (ushort) a_info->glyph_data_length);
+ if (length == -1) {
+ ff->char_data = saved_char_data;
+ return FT_Err_Unknown_File_Format;
+ }
- /* If the buffer was too small enlarge it and try again. */
- if (length > a_info->glyph_data_length) {
+ /* If the buffer was too small enlarge it and try again. */
+ if (length > a_info->glyph_data_length) {
if (a_info->glyph_data) {
- gs_free ((gs_memory_t *)a_info->fapi_font->memory, a_info->glyph_data, 0, 0, "get_fapi_glyph_data");
+ gs_free((gs_memory_t *) a_info->fapi_font->memory,
+ a_info->glyph_data, 0, 0, "get_fapi_glyph_data");
}
- a_info->glyph_data = gs_malloc ((gs_memory_t *)a_info->fapi_font->memory, length, 1, "get_fapi_glyph_data");
+ a_info->glyph_data =
+ gs_malloc((gs_memory_t *) a_info->fapi_font->memory, length,
+ 1, "get_fapi_glyph_data");
if (!a_info->glyph_data) {
a_info->glyph_data_length = 0;
@@ -372,17 +397,19 @@ get_fapi_glyph_data(FT_Incremental a_info, FT_UInt a_index, FT_Data *a_data)
}
static void
-free_fapi_glyph_data(FT_Incremental a_info, FT_Data *a_data)
+free_fapi_glyph_data(FT_Incremental a_info, FT_Data * a_data)
{
- if (a_data->pointer == (const FT_Byte*)a_info->glyph_data)
+ if (a_data->pointer == (const FT_Byte *)a_info->glyph_data)
a_info->glyph_data_in_use = false;
else
- gs_free((gs_memory_t *)a_info->fapi_font->memory, (FT_Byte*)a_data->pointer, 0, 0, "free_fapi_glyph_data");
+ gs_free((gs_memory_t *) a_info->fapi_font->memory,
+ (FT_Byte *) a_data->pointer, 0, 0, "free_fapi_glyph_data");
}
static FT_Error
get_fapi_glyph_metrics(FT_Incremental a_info, FT_UInt a_glyph_index,
- FT_Bool bVertical, FT_Incremental_MetricsRec *a_metrics)
+ FT_Bool bVertical,
+ FT_Incremental_MetricsRec * a_metrics)
{
/* FreeType will create synthetic vertical metrics, including a vertical
* advance, if none is present. We don't want this, so if the font uses Truetype outlines
@@ -391,17 +418,15 @@ get_fapi_glyph_metrics(FT_Incremental a_info, FT_UInt a_glyph_index,
if (bVertical && !a_info->fapi_font->is_type1)
a_metrics->advance = 0;
- if (a_info->glyph_metrics_index == a_glyph_index)
- {
- switch (a_info->metrics_type)
- {
- case FAPI_METRICS_ADD:
+ if (a_info->glyph_metrics_index == a_glyph_index) {
+ switch (a_info->metrics_type) {
+ case gs_fapi_metrics_add:
a_metrics->advance += a_info->glyph_metrics.advance;
break;
- case FAPI_METRICS_REPLACE_WIDTH:
+ case gs_fapi_metrics_replace_width:
a_metrics->advance = a_info->glyph_metrics.advance;
break;
- case FAPI_METRICS_REPLACE:
+ case gs_fapi_metrics_replace:
*a_metrics = a_info->glyph_metrics;
/* We are replacing the horizontal metrics, so the vertical must be 0 */
a_metrics->advance_v = 0;
@@ -414,28 +439,26 @@ get_fapi_glyph_metrics(FT_Incremental a_info, FT_UInt a_glyph_index,
return 0;
}
-static const
-FT_Incremental_FuncsRec TheFAPIIncrementalInterfaceFuncs =
-{
+static const FT_Incremental_FuncsRec TheFAPIIncrementalInterfaceFuncs = {
get_fapi_glyph_data,
free_fapi_glyph_data,
get_fapi_glyph_metrics
};
static FT_Incremental_InterfaceRec *
-new_inc_int(FAPI_server *a_server, FAPI_font *a_fapi_font)
+new_inc_int(gs_fapi_server * a_server, gs_fapi_font * a_fapi_font)
{
- FF_server *s = (FF_server*)a_server;
+ ff_server *s = (ff_server *) a_server;
FT_Incremental_InterfaceRec *i =
- (FT_Incremental_InterfaceRec*) FF_alloc(s->ftmemory, sizeof(FT_Incremental_InterfaceRec));
- if (i)
- {
- i->object = (FT_Incremental)new_inc_int_info(a_server, a_fapi_font);
+ (FT_Incremental_InterfaceRec *) FF_alloc(s->ftmemory,
+ sizeof
+ (FT_Incremental_InterfaceRec));
+ if (i) {
+ i->object = (FT_Incremental) new_inc_int_info(a_server, a_fapi_font);
i->funcs = &TheFAPIIncrementalInterfaceFuncs;
}
- if (!i->object)
- {
+ if (!i->object) {
FF_free(s->ftmemory, i);
i = NULL;
}
@@ -443,11 +466,12 @@ new_inc_int(FAPI_server *a_server, FAPI_font *a_fapi_font)
}
static void
-delete_inc_int(FAPI_server *a_server, FT_Incremental_InterfaceRec *a_inc_int)
+delete_inc_int(gs_fapi_server * a_server,
+ FT_Incremental_InterfaceRec * a_inc_int)
{
- FF_server *s = (FF_server*)a_server;
- if (a_inc_int)
- {
+ ff_server *s = (ff_server *) a_server;
+
+ if (a_inc_int) {
delete_inc_int_info(a_server, a_inc_int->object);
FF_free(s->ftmemory, a_inc_int);
}
@@ -459,12 +483,11 @@ delete_inc_int(FAPI_server *a_server, FT_Incremental_InterfaceRec *a_inc_int)
static int
ft_to_gs_error(FT_Error a_error)
{
- if (a_error)
- {
+ if (a_error) {
if (a_error == FT_Err_Out_Of_Memory)
- return e_VMerror;
+ return gs_error_VMerror;
else
- return e_unknownerror;
+ return gs_error_unknownerror;
}
return 0;
}
@@ -472,16 +495,17 @@ ft_to_gs_error(FT_Error a_error)
/* Load a glyph and optionally rasterize it. Return its metrics in a_metrics.
* If a_bitmap is true convert the glyph to a bitmap.
*/
-static FAPI_retcode
-load_glyph(FAPI_server *a_server, FAPI_font *a_fapi_font, const FAPI_char_ref *a_char_ref,
- FAPI_metrics *a_metrics, FT_Glyph *a_glyph, bool a_bitmap, int max_bitmap)
+static gs_fapi_retcode
+load_glyph(gs_fapi_server * a_server, gs_fapi_font * a_fapi_font,
+ const gs_fapi_char_ref * a_char_ref, gs_fapi_metrics * a_metrics,
+ FT_Glyph * a_glyph, bool a_bitmap, int max_bitmap)
{
- FF_server *s = (FF_server*)a_server;
+ ff_server *s = (ff_server *) a_server;
FT_Error ft_error = 0;
FT_Error ft_error_fb = 1;
- FF_face *face = (FF_face*)a_fapi_font->server_font_data;
+ ff_face *face = (ff_face *) a_fapi_font->server_font_data;
FT_Face ft_face = face->ft_face;
- int index = a_char_ref->char_code;
+ int index = a_char_ref->char_codes[0];
FT_Long w;
FT_Long h;
FT_Long fflags;
@@ -494,22 +518,20 @@ load_glyph(FAPI_server *a_server, FAPI_font *a_fapi_font, const FAPI_char_ref *a
const int saved_char_data_len = a_fapi_font->char_data_len;
if (s->bitmap_glyph) {
- FT_Bitmap_Done (s->freetype_library, &s->bitmap_glyph->bitmap);
+ FT_Bitmap_Done(s->freetype_library, &s->bitmap_glyph->bitmap);
FF_free(s->ftmemory, s->bitmap_glyph);
s->bitmap_glyph = NULL;
}
if (s->outline_glyph) {
- FT_Outline_Done (s->freetype_library, &s->outline_glyph->outline);
+ FT_Outline_Done(s->freetype_library, &s->outline_glyph->outline);
FF_free(s->ftmemory, s->outline_glyph);
s->outline_glyph = NULL;
}
- if (!a_char_ref->is_glyph_index)
- {
+ if (!a_char_ref->is_glyph_index) {
if (ft_face->num_charmaps)
index = FT_Get_Char_Index(ft_face, index);
- else
- {
+ else {
/* If there are no character maps and no glyph index, loading the glyph will still work
* properly if both glyph data and metrics are supplied by the incremental interface.
* In that case we use a dummy glyph index which will be passed
@@ -524,73 +546,107 @@ load_glyph(FAPI_server *a_server, FAPI_font *a_fapi_font, const FAPI_char_ref *a
if (a_fapi_font->is_type1)
index = 0;
else
- index = a_char_ref->char_code;
+ index = a_char_ref->char_codes[0];
}
}
+ else {
+ /* This is a heuristic to try to avoid using the TTF notdef (empty rectangle), and replace it
+ with a non-marking glyph instead. This is only required for fonts where we don't use the
+ FT incremental interface - when we are using the incremental interface, we handle it in
+ our own glyph lookup code.
+ */
+ if (!face->ft_inc_int && (index == 0 ||
+ (a_char_ref->client_char_code != gs_no_char &&
+ FT_Get_Char_Index(ft_face, a_char_ref->client_char_code) <= 0))) {
+ int tmp_ind;
+ if ((tmp_ind = FT_Get_Char_Index(ft_face, 32)) > 0) {
+ index = tmp_ind;
+ }
+ }
+ }
/* Refresh the pointer to the FAPI_font held by the incremental interface. */
if (face->ft_inc_int)
face->ft_inc_int->object->fapi_font = a_fapi_font;
/* Store the overriding metrics if they have been supplied. */
- if (face->ft_inc_int && a_char_ref->metrics_type != FAPI_METRICS_NOTDEF)
- {
- FT_Incremental_MetricsRec *m = &face->ft_inc_int->object->glyph_metrics;
+ if (face->ft_inc_int
+ && a_char_ref->metrics_type != gs_fapi_metrics_notdef) {
+ FT_Incremental_MetricsRec *m =
+ &face->ft_inc_int->object->glyph_metrics;
m->bearing_x = a_char_ref->sb_x >> 16;
m->bearing_y = a_char_ref->sb_y >> 16;
m->advance = a_char_ref->aw_x >> 16;
face->ft_inc_int->object->glyph_metrics_index = index;
face->ft_inc_int->object->metrics_type = a_char_ref->metrics_type;
}
- else
- if (face->ft_inc_int)
- /* Make sure we don't leave this set to the last value, as we may then use inappropriate metrics values */
- face->ft_inc_int->object->glyph_metrics_index = 0xFFFFFFFF;
+ else if (face->ft_inc_int)
+ /* Make sure we don't leave this set to the last value, as we may then use inappropriate metrics values */
+ face->ft_inc_int->object->glyph_metrics_index = 0xFFFFFFFF;
/* We have to load the glyph, scale it correctly, and render it if we need a bitmap. */
- if (!ft_error)
- {
+ if (!ft_error) {
/* We disable loading bitmaps because if we allow it then FreeType invents metrics for them, which messes up our glyph positioning */
/* Also the bitmaps tend to look somewhat different (though more readable) than FreeType's rendering. By disabling them we */
/* maintain consistency better. (FT_LOAD_NO_BITMAP) */
a_fapi_font->char_data = saved_char_data;
if (!a_fapi_font->is_type1)
- ft_error = FT_Load_Glyph(ft_face, index, FT_LOAD_MONOCHROME | FT_LOAD_NO_BITMAP | FT_LOAD_LINEAR_DESIGN);
+ ft_error =
+ FT_Load_Glyph(ft_face, index,
+ FT_LOAD_MONOCHROME | FT_LOAD_NO_BITMAP |
+ FT_LOAD_LINEAR_DESIGN);
else {
/* Current FreeType hinting for type 1 fonts is so poor we are actually better off without it (fewer files render incorrectly) (FT_LOAD_NO_HINTING) */
- ft_error = FT_Load_Glyph(ft_face, index, FT_LOAD_MONOCHROME | FT_LOAD_NO_HINTING | FT_LOAD_NO_BITMAP | FT_LOAD_LINEAR_DESIGN);
+ ft_error =
+ FT_Load_Glyph(ft_face, index,
+ FT_LOAD_MONOCHROME | FT_LOAD_NO_HINTING |
+ FT_LOAD_NO_BITMAP | FT_LOAD_LINEAR_DESIGN);
if (ft_error == FT_Err_Unknown_File_Format)
- return index+1;
+ return index + 1;
}
}
- if (ft_error == FT_Err_Invalid_Argument || ft_error == FT_Err_Invalid_Glyph_Index
- || (ft_error >= FT_Err_Invalid_Opcode && ft_error <= FT_Err_Too_Many_Instruction_Defs)) {
+ if (ft_error == FT_Err_Invalid_Argument
+ || ft_error == FT_Err_Invalid_Glyph_Index
+ || (ft_error >= FT_Err_Invalid_Opcode
+ && ft_error <= FT_Err_Too_Many_Instruction_Defs)) {
a_fapi_font->char_data = saved_char_data;
/* We want to prevent hinting, even for a "tricky" font - it shouldn't matter for the notdef */
fflags = ft_face->face_flags;
ft_face->face_flags &= ~FT_FACE_FLAG_TRICKY;
- ft_error = FT_Load_Glyph(ft_face, index, FT_LOAD_MONOCHROME | FT_LOAD_NO_HINTING | FT_LOAD_NO_BITMAP | FT_LOAD_LINEAR_DESIGN);
+ ft_error =
+ FT_Load_Glyph(ft_face, index,
+ FT_LOAD_MONOCHROME | FT_LOAD_NO_HINTING |
+ FT_LOAD_NO_BITMAP | FT_LOAD_LINEAR_DESIGN);
ft_face->face_flags = fflags;
}
- if (ft_error == FT_Err_Out_Of_Memory || ft_error == FT_Err_Array_Too_Large) {
- return(e_VMerror);
+ if (ft_error == FT_Err_Out_Of_Memory
+ || ft_error == FT_Err_Array_Too_Large) {
+ return (gs_error_VMerror);
}
/* If FT gives us an error, try to fall back to the notdef - if that doesn't work, we'll throw an error over to Ghostscript */
if (ft_error) {
- a_fapi_font->char_data = (void *)".notdef";
- a_fapi_font->char_data_len = 7;
+ gs_string notdef_str;
+
+ notdef_str.data = (byte *)".notdef";
+ notdef_str.size = 7;
+
+ a_fapi_font->char_data = (void *)(&notdef_str);
+ a_fapi_font->char_data_len = 0;
/* We want to prevent hinting, even for a "tricky" font - it shouldn't matter for the notdef */
fflags = ft_face->face_flags;
ft_face->face_flags &= ~FT_FACE_FLAG_TRICKY;
- ft_error_fb = FT_Load_Glyph(ft_face, 0, FT_LOAD_MONOCHROME | FT_LOAD_NO_HINTING | FT_LOAD_NO_BITMAP | FT_LOAD_LINEAR_DESIGN);
+ ft_error_fb =
+ FT_Load_Glyph(ft_face, 0,
+ FT_LOAD_MONOCHROME | FT_LOAD_NO_HINTING |
+ FT_LOAD_NO_BITMAP | FT_LOAD_LINEAR_DESIGN);
ft_face->face_flags = fflags;
@@ -601,8 +657,7 @@ load_glyph(FAPI_server *a_server, FAPI_font *a_fapi_font, const FAPI_char_ref *a
/* Previously we interpreted the glyph unscaled, and derived the metrics from that. Now we only interpret it
* once, and work out the metrics from the scaled/hinted outline.
*/
- if ((!ft_error || !ft_error_fb) && a_metrics)
- {
+ if ((!ft_error || !ft_error_fb) && a_metrics) {
FT_Long hx;
FT_Long hy;
FT_Long vadv;
@@ -610,21 +665,30 @@ load_glyph(FAPI_server *a_server, FAPI_font *a_fapi_font, const FAPI_char_ref *a
/* In order to get the metrics in the form we need them, we have to remove the size scaling
* the resolution scaling, and convert to points.
*/
- hx = (FT_Long)(((double)ft_face->glyph->metrics.horiBearingX * ft_face->units_per_EM * 72.0) / ((double)face->width * face->horz_res));
- hy = (FT_Long)(((double)ft_face->glyph->metrics.horiBearingY * ft_face->units_per_EM * 72.0) / ((double)face->height * face->vert_res));
-
- w = (FT_Long)(((double)ft_face->glyph->metrics.width * ft_face->units_per_EM * 72.0) / ((double)face->width * face->horz_res));
- h = (FT_Long)(((double)ft_face->glyph->metrics.height * ft_face->units_per_EM * 72.0) / ((double)face->height * face->vert_res));
+ hx = (FT_Long) (((double)ft_face->glyph->metrics.horiBearingX *
+ ft_face->units_per_EM * 72.0) /
+ ((double)face->width * face->horz_res));
+ hy = (FT_Long) (((double)ft_face->glyph->metrics.horiBearingY *
+ ft_face->units_per_EM * 72.0) /
+ ((double)face->height * face->vert_res));
+
+ w = (FT_Long) (((double)ft_face->glyph->metrics.width *
+ ft_face->units_per_EM * 72.0) / ((double)face->width *
+ face->horz_res));
+ h = (FT_Long) (((double)ft_face->glyph->metrics.height *
+ ft_face->units_per_EM * 72.0) /
+ ((double)face->height * face->vert_res));
/* Ugly. FreeType creates verticla metrics for TT fonts, normally we override them in the
* metrics callbacks, but those only work for incremental interface fonts, and TrueType fonts
* loaded as CIDFont replacements are not incrementally handled. So here, if its a CIDFont, and
* its not type 1 outlines, and its not a vertical mode fotn, ignore the advance.
*/
- if(!a_fapi_font->is_type1 && a_fapi_font->is_cid && !a_fapi_font->is_vertical)
- vadv = 0;
- else
- vadv = ft_face->glyph->linearVertAdvance;
+ if (!a_fapi_font->is_type1 && a_fapi_font->is_cid
+ && !a_fapi_font->is_vertical)
+ vadv = 0;
+ else
+ vadv = ft_face->glyph->linearVertAdvance;
a_metrics->bbox_x0 = hx;
a_metrics->bbox_y0 = hy - h;
@@ -638,31 +702,33 @@ load_glyph(FAPI_server *a_server, FAPI_font *a_fapi_font, const FAPI_char_ref *a
if ((!ft_error || !ft_error_fb) && a_bitmap == true) {
- FT_BBox cbox;
+ FT_BBox cbox;
+
/* compute the control box, and grid fit it - lifted from ft_raster1_render() */
- FT_Outline_Get_CBox(&ft_face->glyph->outline,&cbox);
+ FT_Outline_Get_CBox(&ft_face->glyph->outline, &cbox);
/* These round operations are only to preserve behaviour compared to the 9.00 release
which used the bitmap dimensions as calculated by Freetype.
But FT_PIX_FLOOR/FT_PIX_CEIL aren't public.
- */
- cbox.xMin = ((cbox.xMin) & ~63); /* FT_PIX_FLOOR( cbox.xMin ) */
+ */
+ cbox.xMin = ((cbox.xMin) & ~63); /* FT_PIX_FLOOR( cbox.xMin ) */
cbox.yMin = ((cbox.yMin) & ~63);
cbox.xMax = (((cbox.xMax) + 63) & ~63);
cbox.yMax = (((cbox.yMax) + 63) & ~63); /* FT_PIX_CEIL( cbox.yMax ) */
- w = (FT_UInt)(( cbox.xMax - cbox.xMin ) >> 6 );
- h = (FT_UInt)(( cbox.yMax - cbox.yMin ) >> 6 );
+ w = (FT_UInt) ((cbox.xMax - cbox.xMin) >> 6);
+ h = (FT_UInt) ((cbox.yMax - cbox.yMin) >> 6);
- if (ft_face->glyph->format != FT_GLYPH_FORMAT_BITMAP && ft_face->glyph->format != FT_GLYPH_FORMAT_COMPOSITE) {
+ if (ft_face->glyph->format != FT_GLYPH_FORMAT_BITMAP
+ && ft_face->glyph->format != FT_GLYPH_FORMAT_COMPOSITE) {
if ((bitmap_raster(w) * h) < max_bitmap) {
- FT_Render_Mode mode = FT_RENDER_MODE_MONO;
+ FT_Render_Mode mode = FT_RENDER_MODE_MONO;
- ft_error = FT_Render_Glyph(ft_face->glyph, mode);
+ ft_error = FT_Render_Glyph(ft_face->glyph, mode);
}
else {
(*a_glyph) = NULL;
- return(e_VMerror);
+ return (gs_error_VMerror);
}
}
}
@@ -673,17 +739,19 @@ load_glyph(FAPI_server *a_server, FAPI_font *a_fapi_font, const FAPI_char_ref *a
else {
if (ft_face->glyph->format == FT_GLYPH_FORMAT_BITMAP) {
FT_BitmapGlyph bmg;
- ft_error = FT_Get_Glyph(ft_face->glyph, (FT_Glyph *)&bmg);
+
+ ft_error = FT_Get_Glyph(ft_face->glyph, (FT_Glyph *) & bmg);
if (!ft_error) {
- FT_Bitmap_Done (s->freetype_library, &bmg->bitmap);
+ FT_Bitmap_Done(s->freetype_library, &bmg->bitmap);
FF_free(s->ftmemory, bmg);
}
}
else {
FT_OutlineGlyph olg;
- ft_error = FT_Get_Glyph(ft_face->glyph, (FT_Glyph *)&olg);
+
+ ft_error = FT_Get_Glyph(ft_face->glyph, (FT_Glyph *) & olg);
if (!ft_error) {
- FT_Outline_Done (s->freetype_library, &olg->outline);
+ FT_Outline_Done(s->freetype_library, &olg->outline);
FF_free(s->ftmemory, olg);
}
}
@@ -693,57 +761,65 @@ load_glyph(FAPI_server *a_server, FAPI_font *a_fapi_font, const FAPI_char_ref *a
#ifdef DEBUG
if (gs_debug_c('1')) {
emprintf1(a_fapi_font->memory,
- "TrueType glyph %d uses more instructions than the declared maximum in the font.",
- a_char_ref->char_code);
+ "TrueType glyph %"PRId64" uses more instructions than the declared maximum in the font.",
+ a_char_ref->char_codes[0]);
if (!ft_error_fb) {
- emprintf(a_fapi_font->memory, " Continuing, falling back to notdef\n\n");
+ emprintf(a_fapi_font->memory,
+ " Continuing, falling back to notdef\n\n");
}
}
#endif
- if (!ft_error_fb) ft_error = 0;
+ if (!ft_error_fb)
+ ft_error = 0;
}
if (ft_error == FT_Err_Invalid_Argument) {
#ifdef DEBUG
if (gs_debug_c('1')) {
emprintf1(a_fapi_font->memory,
- "TrueType parsing error in glyph %d in the font.",
- a_char_ref->char_code);
+ "TrueType parsing error in glyph %"PRId64" in the font.",
+ a_char_ref->char_codes[0]);
if (!ft_error_fb) {
- emprintf(a_fapi_font->memory, " Continuing, falling back to notdef\n\n");
+ emprintf(a_fapi_font->memory,
+ " Continuing, falling back to notdef\n\n");
}
}
#endif
- if (!ft_error_fb) ft_error = 0;
+ if (!ft_error_fb)
+ ft_error = 0;
}
if (ft_error == FT_Err_Too_Many_Function_Defs) {
#ifdef DEBUG
if (gs_debug_c('1')) {
emprintf1(a_fapi_font->memory,
- "TrueType instruction error in glyph %d in the font.",
- a_char_ref->char_code);
+ "TrueType instruction error in glyph %"PRId64" in the font.",
+ a_char_ref->char_codes[0]);
if (!ft_error_fb) {
- emprintf(a_fapi_font->memory, " Continuing, falling back to notdef\n\n");
+ emprintf(a_fapi_font->memory,
+ " Continuing, falling back to notdef\n\n");
}
}
#endif
- if (!ft_error_fb) ft_error = 0;
+ if (!ft_error_fb)
+ ft_error = 0;
}
if (ft_error == FT_Err_Invalid_Glyph_Index) {
#ifdef DEBUG
if (gs_debug_c('1')) {
emprintf1(a_fapi_font->memory,
- "FreeType is unable to find the glyph %d in the font.",
- a_char_ref->char_code);
+ "FreeType is unable to find the glyph %"PRId64" in the font.",
+ a_char_ref->char_codes[0]);
if (!ft_error_fb) {
- emprintf(a_fapi_font->memory, " Continuing, falling back to notdef\n\n");
+ emprintf(a_fapi_font->memory,
+ " Continuing, falling back to notdef\n\n");
}
}
#endif
- if (!ft_error_fb) ft_error = 0;
+ if (!ft_error_fb)
+ ft_error = 0;
}
return ft_to_gs_error(ft_error);
}
@@ -753,12 +829,13 @@ load_glyph(FAPI_server *a_server, FAPI_font *a_fapi_font, const FAPI_char_ref *a
*
* In the case of FreeType this means creating the FreeType library object.
*/
-static FAPI_retcode
-ensure_open(FAPI_server *a_server, const byte *server_param, int server_param_size)
+static gs_fapi_retcode
+ensure_open(gs_fapi_server * a_server, const char * server_param,
+ int server_param_size)
{
- FF_server *s = (FF_server*)a_server;
- if (!s->freetype_library)
- {
+ ff_server *s = (ff_server *) a_server;
+
+ if (!s->freetype_library) {
FT_Error ft_error;
/* As we want FT to use our memory management, we cannot use the convenience of
@@ -771,7 +848,7 @@ ensure_open(FAPI_server *a_server, const byte *server_param, int server_param_si
ft_error = FT_New_Library(s->ftmemory, &s->freetype_library);
if (ft_error) {
- gs_free (s->mem, s->ftmemory, 0, 0, "ensure_open");
+ gs_free(s->mem, s->ftmemory, 0, 0, "ensure_open");
}
else {
FT_Add_Default_Modules(s->freetype_library);
@@ -783,28 +860,29 @@ ensure_open(FAPI_server *a_server, const byte *server_param, int server_param_si
return 0;
}
-#if 0 /* Not currently used */
+#if 0 /* Not currently used */
static void
-transform_concat(FT_Matrix *a_A, const FT_Matrix *a_B)
+transform_concat(FT_Matrix * a_A, const FT_Matrix * a_B)
{
FT_Matrix result = *a_B;
+
FT_Matrix_Multiply(a_A, &result);
*a_A = result;
}
/* Create a transform representing an angle defined as a vector. */
static void
-make_rotation(FT_Matrix *a_transform, const FT_Vector *a_vector)
+make_rotation(FT_Matrix * a_transform, const FT_Vector * a_vector)
{
FT_Fixed length, cos, sin;
- if (a_vector->x >= 0 && a_vector->y == 0)
- {
+
+ if (a_vector->x >= 0 && a_vector->y == 0) {
a_transform->xx = a_transform->yy = 65536;
a_transform->xy = a_transform->yx = 0;
return;
}
- length = FT_Vector_Length((FT_Vector*)a_vector);
+ length = FT_Vector_Length((FT_Vector *) a_vector);
cos = FT_DivFix(a_vector->x, length);
sin = FT_DivFix(a_vector->y, length);
a_transform->xx = a_transform->yy = cos;
@@ -817,8 +895,8 @@ make_rotation(FT_Matrix *a_transform, const FT_Vector *a_vector)
* The scaling part is used for setting the pixel size for hinting.
*/
static void
-transform_decompose(FT_Matrix *a_transform, FT_UInt *xresp, FT_UInt *yresp,
- FT_Fixed *a_x_scale, FT_Fixed *a_y_scale)
+transform_decompose(FT_Matrix * a_transform, FT_UInt * xresp, FT_UInt * yresp,
+ FT_Fixed * a_x_scale, FT_Fixed * a_y_scale)
{
double scalex, scaley, fact = 1.0;
double factx = 1.0, facty = 1.0;
@@ -827,8 +905,8 @@ transform_decompose(FT_Matrix *a_transform, FT_UInt *xresp, FT_UInt *yresp,
FT_UInt yres;
bool indep_scale;
- scalex = hypot ((double)a_transform->xx, (double)a_transform->xy);
- scaley = hypot ((double)a_transform->yx, (double)a_transform->yy);
+ scalex = hypot((double)a_transform->xx, (double)a_transform->xy);
+ scaley = hypot((double)a_transform->yx, (double)a_transform->yy);
if (*xresp != *yresp) {
/* To get good results, we have to pull the implicit scaling from
@@ -838,16 +916,20 @@ transform_decompose(FT_Matrix *a_transform, FT_UInt *xresp, FT_UInt *yresp,
* axes were coincident with the axes of the page.
*/
bool use_x = true;
-
+
if (*xresp < *yresp) {
use_x = false;
}
- ftscale_mat.xx = (int)(((double)(*xresp) / ((double)(use_x ? (*xresp) : (*yresp)))) * 65536);
+ ftscale_mat.xx =
+ (int)(((double)(*xresp) /
+ ((double)(use_x ? (*xresp) : (*yresp)))) * 65536);
ftscale_mat.xy = ftscale_mat.yx = 0;
- ftscale_mat.yy = (int)(((double)(*yresp) / ((double)(use_x ? (*xresp) : (*yresp)))) * 65536);
+ ftscale_mat.yy =
+ (int)(((double)(*yresp) /
+ ((double)(use_x ? (*xresp) : (*yresp)))) * 65536);
- FT_Matrix_Multiply (&ftscale_mat, a_transform);
+ FT_Matrix_Multiply(&ftscale_mat, a_transform);
xres = yres = (use_x ? (*xresp) : (*yresp));
}
@@ -865,10 +947,11 @@ transform_decompose(FT_Matrix *a_transform, FT_UInt *xresp, FT_UInt *yresp,
* As these are scaled fixed point values, we should be safe forcing
* them into integer operations.
*/
- indep_scale = (((((int)scalex) / ((int)scaley)) > 512) || ((((int)scaley) / ((int)scalex)) > 512));
+ indep_scale = (((((int)scalex) / ((int)scaley)) > 512)
+ || ((((int)scaley) / ((int)scalex)) > 512));
- scalex *= 1.0/65536.0;
- scaley *= 1.0/65536.0;
+ scalex *= 1.0 / 65536.0;
+ scaley *= 1.0 / 65536.0;
/* FT clamps the width and height to a lower limit of 1.0 units
* (note: as FT stores it in 64ths of a unit, that is 64)
* So if either the width or the height are <1.0 here, we scale
@@ -878,15 +961,15 @@ transform_decompose(FT_Matrix *a_transform, FT_UInt *xresp, FT_UInt *yresp,
/* We use 1 1/64th to calculate the scale, so that we *guarantee* the
* scalex/y we calculate will be >64 after rounding.
*/
- /* It turns out that pdfwrite uses a unit matrix for some/many/all of
- * its nefarious needs, this causes small values to round to zero in
- * some of Freetype's code, which can result in glyph metrics (height,
- * width etc) being falsely recorded as zero.
- * Raise the scale factor of what we consider a "small" glyph by an
- * order of magnitude to keep pdfwrite happy - note this doesn't
- * affect the ultimate size of the glyph since we recalculate the
- * final scale matrix to suit below.
- */
+ /* It turns out that pdfwrite uses a unit matrix for some/many/all of
+ * its nefarious needs, this causes small values to round to zero in
+ * some of Freetype's code, which can result in glyph metrics (height,
+ * width etc) being falsely recorded as zero.
+ * Raise the scale factor of what we consider a "small" glyph by an
+ * order of magnitude to keep pdfwrite happy - note this doesn't
+ * affect the ultimate size of the glyph since we recalculate the
+ * final scale matrix to suit below.
+ */
if (indep_scale) {
if (scaley < 10.0) {
facty = 10.016 / scaley;
@@ -901,8 +984,8 @@ transform_decompose(FT_Matrix *a_transform, FT_UInt *xresp, FT_UInt *yresp,
The calculation has been rearranged to reduce (in particular) the
number of floating point divisions.
*/
- if (scaley * yres < 2268.0/64.0) {
- facty = (2400.0/64.0) / (yres * scaley);
+ if (scaley * yres < 2268.0 / 64.0) {
+ facty = (2400.0 / 64.0) / (yres * scaley);
scaley *= facty;
}
@@ -930,8 +1013,8 @@ transform_decompose(FT_Matrix *a_transform, FT_UInt *xresp, FT_UInt *yresp,
}
/* see above */
- if (scalex * xres < 2268.0/64.0) {
- factx = (2400.0/64.0) / (xres * scalex);
+ if (scalex * xres < 2268.0 / 64.0) {
+ factx = (2400.0 / 64.0) / (xres * scalex);
scalex *= factx;
}
@@ -967,8 +1050,8 @@ transform_decompose(FT_Matrix *a_transform, FT_UInt *xresp, FT_UInt *yresp,
The calculation has been rearranged to reduce (in particular) the
number of floating point divisions.
*/
- if (scaley * yres < 2268.0/64.0) {
- fact = (2400.0/64.0) / (yres * scaley);
+ if (scaley * yres < 2268.0 / 64.0) {
+ fact = (2400.0 / 64.0) / (yres * scaley);
scaley *= fact;
scalex *= fact;
}
@@ -986,8 +1069,8 @@ transform_decompose(FT_Matrix *a_transform, FT_UInt *xresp, FT_UInt *yresp,
fact *= 2.0;
}
else {
- scalex /= 1.25;
- scaley /= 1.25;
+ scalex /= 1.25;
+ scaley /= 1.25;
}
}
}
@@ -999,8 +1082,8 @@ transform_decompose(FT_Matrix *a_transform, FT_UInt *xresp, FT_UInt *yresp,
}
/* see above */
- if (scalex * xres < 2268.0/64.0) {
- fact = (2400.0/64.0) / (xres * scalex);
+ if (scalex * xres < 2268.0 / 64.0) {
+ fact = (2400.0 / 64.0) / (xres * scalex);
scaley *= fact;
scalex *= fact;
}
@@ -1015,48 +1098,49 @@ transform_decompose(FT_Matrix *a_transform, FT_UInt *xresp, FT_UInt *yresp,
fact *= 2.0;
}
else {
- scalex /= 1.25;
- scaley /= 1.25;
+ scalex /= 1.25;
+ scaley /= 1.25;
}
}
}
factx = facty = fact;
}
- ftscale_mat.xx = (FT_Fixed)((65536.0 / scalex) * factx);
+ ftscale_mat.xx = (FT_Fixed) ((65536.0 / scalex) * factx);
ftscale_mat.xy = 0;
ftscale_mat.yx = 0;
- ftscale_mat.yy = (FT_Fixed)((65536.0 / scaley) * facty);
+ ftscale_mat.yy = (FT_Fixed) ((65536.0 / scaley) * facty);
- FT_Matrix_Multiply (a_transform, &ftscale_mat);
+ FT_Matrix_Multiply(a_transform, &ftscale_mat);
memcpy(a_transform, &ftscale_mat, sizeof(FT_Matrix));
*xresp = xres;
*yresp = yres;
/* Return values ready scaled for FT */
- *a_x_scale = (FT_Fixed)(scalex * 64);
- *a_y_scale = (FT_Fixed)(scaley * 64);
+ *a_x_scale = (FT_Fixed) (scalex * 64);
+ *a_y_scale = (FT_Fixed) (scaley * 64);
}
/*
* Open a font and set its size.
*/
-static FAPI_retcode
-get_scaled_font(FAPI_server *a_server, FAPI_font *a_font,
- const FAPI_font_scale *a_font_scale,
- const char *a_map,
- FAPI_descendant_code a_descendant_code)
+static gs_fapi_retcode
+get_scaled_font(gs_fapi_server * a_server, gs_fapi_font * a_font,
+ const gs_fapi_font_scale * a_font_scale,
+ const char *a_map, gs_fapi_descendant_code a_descendant_code)
{
- FF_server *s = (FF_server*)a_server;
- FF_face *face = (FF_face*)a_font->server_font_data;
+ ff_server *s = (ff_server *) a_server;
+ ff_face *face = (ff_face *) a_font->server_font_data;
FT_Error ft_error = 0;
+ int i, j;
+ FT_CharMap cmap = NULL;
if (s->bitmap_glyph) {
- FT_Bitmap_Done (s->freetype_library, &s->bitmap_glyph->bitmap);
+ FT_Bitmap_Done(s->freetype_library, &s->bitmap_glyph->bitmap);
FF_free(s->ftmemory, s->bitmap_glyph);
s->bitmap_glyph = NULL;
}
if (s->outline_glyph) {
- FT_Outline_Done (s->freetype_library, &s->outline_glyph->outline);
+ FT_Outline_Done(s->freetype_library, &s->outline_glyph->outline);
FF_free(s->ftmemory, s->outline_glyph);
s->outline_glyph = NULL;
}
@@ -1068,57 +1152,84 @@ get_scaled_font(FAPI_server *a_server, FAPI_font *a_font,
* do nothing. See the comment in FAPI_prepare_font. The descendant fonts are
* passed in individually.
*/
- if (a_font->is_cid && a_font->is_type1 && a_font->font_file_path == NULL &&
- (a_descendant_code == FAPI_TOPLEVEL_BEGIN ||
- a_descendant_code == FAPI_TOPLEVEL_COMPLETE))
- {
+ if (a_font->is_cid && a_font->is_type1 && a_font->font_file_path == NULL
+ && (a_descendant_code == gs_fapi_toplevel_begin
+ || a_descendant_code == gs_fapi_toplevel_complete)) {
/* dpf("get_scaled_font return 0\n"); */
return 0;
}
/* Create the face if it doesn't already exist. */
- if (!face)
- {
+ if (!face) {
FT_Face ft_face = NULL;
FT_Parameter ft_param;
FT_Incremental_InterfaceRec *ft_inc_int = NULL;
unsigned char *own_font_data = NULL;
+ int own_font_data_len = -1;
FT_Stream ft_strm = NULL;
/* dpf("get_scaled_font creating face\n"); */
+ if (a_font->full_font_buf) {
+
+ own_font_data =
+ gs_malloc(((gs_memory_t *) (s->ftmemory->user)),
+ a_font->full_font_buf_len, 1,
+ "get_scaled_font - full font buf");
+ if (!own_font_data) {
+ return_error(gs_error_VMerror);
+ }
+
+ own_font_data_len = a_font->full_font_buf_len;
+ memcpy(own_font_data, a_font->full_font_buf,
+ a_font->full_font_buf_len);
+
+ ft_error =
+ FT_New_Memory_Face(s->freetype_library,
+ (const FT_Byte *)own_font_data,
+ own_font_data_len, a_font->subfont,
+ &ft_face);
+
+ if (!ft_error && ft_face)
+ ft_error = FT_Select_Charmap(ft_face, ft_encoding_unicode);
+
+ }
/* Load a typeface from a file. */
- if (a_font->font_file_path)
- {
+ else if (a_font->font_file_path) {
FT_Open_Args args;
int code;
memset(&args, 0x00, sizeof(args));
- if ((code = FF_open_read_stream ((gs_memory_t *)(s->ftmemory->user),
- (char *)a_font->font_file_path, &ft_strm)) < 0){
- return(code);
+ if ((code =
+ FF_open_read_stream((gs_memory_t *) (s->ftmemory->user),
+ (char *)a_font->font_file_path,
+ &ft_strm)) < 0) {
+ return (code);
}
args.flags = FT_OPEN_STREAM;
args.stream = ft_strm;
- ft_error = FT_Open_Face(s->freetype_library, &args, a_font->subfont, &ft_face);
+ ft_error =
+ FT_Open_Face(s->freetype_library, &args, a_font->subfont,
+ &ft_face);
if (!ft_error && ft_face)
ft_error = FT_Select_Charmap(ft_face, ft_encoding_unicode);
}
/* Load a typeface from a representation in GhostScript's memory. */
- else
- {
+ else {
FT_Open_Args open_args;
+
open_args.flags = FT_OPEN_MEMORY;
- if (a_font->is_type1)
- {
+ if (a_font->is_type1) {
long length;
- int type = a_font->get_word(a_font, FAPI_FONT_FEATURE_FontType, 0);
+ int type =
+ a_font->get_word(a_font, gs_fapi_font_feature_FontType,
+ 0);
/* Tell the FAPI interface that we need to decrypt the /Subrs data. */
a_font->need_decrypt = true;
@@ -1128,70 +1239,82 @@ get_scaled_font(FAPI_server *a_server, FAPI_font *a_font,
a Type 2 font in binary form, so that FreeType can read it.
*/
if (type == 1)
- length = FF_serialize_type1_font(a_font, NULL, 0);
+ length = gs_fapi_serialize_type1_font(a_font, NULL, 0);
else
- length = FF_serialize_type2_font(a_font, NULL, 0);
- open_args.memory_base = own_font_data = FF_alloc(s->ftmemory, length);
+ length = gs_fapi_serialize_type2_font(a_font, NULL, 0);
+ open_args.memory_base = own_font_data =
+ FF_alloc(s->ftmemory, length);
if (!open_args.memory_base)
- return e_VMerror;
+ return gs_error_VMerror;
+ own_font_data_len = length;
if (type == 1)
- open_args.memory_size = FF_serialize_type1_font(a_font, own_font_data, length);
+ open_args.memory_size =
+ gs_fapi_serialize_type1_font(a_font, own_font_data,
+ length);
else
- open_args.memory_size = FF_serialize_type2_font(a_font, own_font_data, length);
+ open_args.memory_size =
+ gs_fapi_serialize_type2_font(a_font, own_font_data,
+ length);
if (open_args.memory_size != length)
- return_error(e_unregistered); /* Must not happen. */
+ return_error(gs_error_unregistered); /* Must not happen. */
ft_inc_int = new_inc_int(a_server, a_font);
- if (!ft_inc_int)
- {
- FF_free (s->ftmemory, own_font_data);
- return e_VMerror;
+ if (!ft_inc_int) {
+ FF_free(s->ftmemory, own_font_data);
+ return gs_error_VMerror;
}
}
/* It must be type 42 (see code in FAPI_FF_get_glyph in zfapi.c). */
- else
- {
+ else {
/* Get the length of the TrueType data. */
- open_args.memory_size = a_font->get_long(a_font, FAPI_FONT_FEATURE_TT_size, 0);
+ open_args.memory_size =
+ a_font->get_long(a_font, gs_fapi_font_feature_TT_size, 0);
if (open_args.memory_size == 0)
- return e_invalidfont;
+ return gs_error_invalidfont;
/* Load the TrueType data into a single buffer. */
- open_args.memory_base = own_font_data = FF_alloc(s->ftmemory, open_args.memory_size);
+ open_args.memory_base = own_font_data =
+ FF_alloc(s->ftmemory, open_args.memory_size);
if (!own_font_data)
- return e_VMerror;
- if (a_font->serialize_tt_font(a_font, own_font_data, open_args.memory_size))
- return e_invalidfont;
+ return gs_error_VMerror;
+
+ own_font_data_len = open_args.memory_size;
+
+ if (a_font->
+ serialize_tt_font(a_font, own_font_data,
+ open_args.memory_size))
+ return gs_error_invalidfont;
/* We always load incrementally. */
ft_inc_int = new_inc_int(a_server, a_font);
- if (!ft_inc_int)
- {
+ if (!ft_inc_int) {
FF_free(s->ftmemory, own_font_data);
- return e_VMerror;
+ return gs_error_VMerror;
}
}
- if (ft_inc_int)
- {
- open_args.flags = (FT_UInt)(open_args.flags | FT_OPEN_PARAMS);
+ if (ft_inc_int) {
+ open_args.flags =
+ (FT_UInt) (open_args.flags | FT_OPEN_PARAMS);
ft_param.tag = FT_PARAM_TAG_INCREMENTAL;
ft_param.data = ft_inc_int;
open_args.num_params = 1;
open_args.params = &ft_param;
}
- ft_error = FT_Open_Face(s->freetype_library, &open_args, a_font->subfont, &ft_face);
+ ft_error =
+ FT_Open_Face(s->freetype_library, &open_args, a_font->subfont,
+ &ft_face);
}
- if (ft_face)
- {
- face = new_face(a_server, ft_face, ft_inc_int, ft_strm, own_font_data);
- if (!face)
- {
+ if (ft_face) {
+ face =
+ new_face(a_server, ft_face, ft_inc_int, ft_strm,
+ own_font_data, own_font_data_len);
+ if (!face) {
FF_free(s->ftmemory, own_font_data);
FT_Done_Face(ft_face);
delete_inc_int(a_server, ft_inc_int);
- return e_VMerror;
+ return gs_error_VMerror;
}
a_font->server_font_data = face;
}
@@ -1203,8 +1326,7 @@ get_scaled_font(FAPI_server *a_server, FAPI_font *a_font,
* The matrix is scaled by the shift specified in the server, 16,
* so we divide by 65536 when converting to a gs_matrix.
*/
- if (face)
- {
+ if (face) {
/* Convert the GS transform into an FT transform.
* Ignore the translation elements because they contain very large values
* derived from the current transformation matrix and so are of no use.
@@ -1220,13 +1342,13 @@ get_scaled_font(FAPI_server *a_server, FAPI_font *a_font,
/* Split the transform into scale factors and a rotation-and-shear
* transform.
*/
- transform_decompose(&face->ft_transform, &face->horz_res, &face->vert_res, &face->width, &face->height);
+ transform_decompose(&face->ft_transform, &face->horz_res,
+ &face->vert_res, &face->width, &face->height);
ft_error = FT_Set_Char_Size(face->ft_face, face->width, face->height,
- face->horz_res, face->vert_res);
+ face->horz_res, face->vert_res);
- if (ft_error)
- {
+ if (ft_error) {
/* The code originally cleaned up the face data here, but the "top level"
font object still has references to the face data, and we've no way
to tell it it's gone. So we defer releasing the data until the garbage
@@ -1242,6 +1364,25 @@ get_scaled_font(FAPI_server *a_server, FAPI_font *a_font,
*/
FT_Set_Transform(face->ft_face, &face->ft_transform, NULL);
+
+ for (i = 0; i < GS_FAPI_NUM_TTF_CMAP_REQ && !cmap; i++) {
+ if (a_font->ttf_cmap_req[i].platform_id > 0) {
+ for (j = 0; j < face->ft_face->num_charmaps; j++) {
+ if (face->ft_face->charmaps[j]->platform_id == a_font->ttf_cmap_req[i].platform_id
+ && face->ft_face->charmaps[j]->encoding_id == a_font->ttf_cmap_req[i].encoding_id) {
+
+ cmap = face->ft_face->charmaps[j];
+ break;
+ }
+ }
+ }
+ else {
+ break;
+ }
+ }
+ if (cmap) {
+ (void)FT_Set_Charmap(face->ft_face, cmap);
+ }
}
/* dpf("get_scaled_font return %d\n", a_font->server_font_data ? 0 : -1); */
@@ -1254,8 +1395,9 @@ get_scaled_font(FAPI_server *a_server, FAPI_font *a_font,
* is in the 'decoding' directory in the directory named by /GenericResourceDir
* in lib/gs_res.ps.
*/
-static FAPI_retcode
-get_decodingID(FAPI_server *a_server, FAPI_font *a_font, const char** a_decoding_id)
+static gs_fapi_retcode
+get_decodingID(gs_fapi_server * a_server, gs_fapi_font * a_font,
+ const char **a_decoding_id)
{
*a_decoding_id = "Unicode";
return 0;
@@ -1264,10 +1406,11 @@ get_decodingID(FAPI_server *a_server, FAPI_font *a_font, const char** a_decoding
/*
* Get the font bounding box in font units.
*/
-static FAPI_retcode
-get_font_bbox(FAPI_server *a_server, FAPI_font *a_font, int a_box[4])
+static gs_fapi_retcode
+get_font_bbox(gs_fapi_server * a_server, gs_fapi_font * a_font, int a_box[4])
{
- FF_face *face = (FF_face*)a_font->server_font_data;
+ ff_face *face = (ff_face *) a_font->server_font_data;
+
a_box[0] = face->ft_face->bbox.xMin;
a_box[1] = face->ft_face->bbox.yMin;
a_box[2] = face->ft_face->bbox.xMax;
@@ -1279,8 +1422,9 @@ get_font_bbox(FAPI_server *a_server, FAPI_font *a_font, int a_box[4])
* Return a boolean value in a_proportional stating whether the font is proportional
* or fixed-width.
*/
-static FAPI_retcode
-get_font_proportional_feature(FAPI_server *a_server, FAPI_font *a_font, bool *a_proportional)
+static gs_fapi_retcode
+get_font_proportional_feature(gs_fapi_server * a_server,
+ gs_fapi_font * a_font, bool * a_proportional)
{
*a_proportional = true;
return 0;
@@ -1292,17 +1436,19 @@ get_font_proportional_feature(FAPI_server *a_server, FAPI_font *a_font, bool *a_
* to true, otherwise set it to false. The return value is a standard error
* return code.
*/
-static FAPI_retcode
-can_retrieve_char_by_name(FAPI_server *a_server, FAPI_font *a_font, FAPI_char_ref *a_char_ref, bool *a_result)
+static gs_fapi_retcode
+can_retrieve_char_by_name(gs_fapi_server * a_server, gs_fapi_font * a_font,
+ gs_fapi_char_ref * a_char_ref, bool * a_result)
{
- FF_face *face = (FF_face*)a_font->server_font_data;
+ ff_face *face = (ff_face *) a_font->server_font_data;
char name[128];
- if (FT_HAS_GLYPH_NAMES(face->ft_face) && a_char_ref->char_name_length < sizeof(name))
- {
+
+ if (FT_HAS_GLYPH_NAMES(face->ft_face)
+ && a_char_ref->char_name_length < sizeof(name)) {
memcpy(name, a_char_ref->char_name, a_char_ref->char_name_length);
name[a_char_ref->char_name_length] = 0;
- a_char_ref->char_code = FT_Get_Name_Index(face->ft_face, name);
- *a_result = a_char_ref->char_code != 0;
+ a_char_ref->char_codes[0] = FT_Get_Name_Index(face->ft_face, name);
+ *a_result = a_char_ref->char_codes[0] != 0;
if (*a_result)
a_char_ref->is_glyph_index = true;
}
@@ -1314,8 +1460,9 @@ can_retrieve_char_by_name(FAPI_server *a_server, FAPI_font *a_font, FAPI_char_re
/*
* Return non-zero if the metrics can be replaced.
*/
-static FAPI_retcode
-can_replace_metrics(FAPI_server *a_server, FAPI_font *a_font, FAPI_char_ref *a_char_ref, int *a_result)
+static gs_fapi_retcode
+can_replace_metrics(gs_fapi_server * a_server, gs_fapi_font * a_font,
+ gs_fapi_char_ref * a_char_ref, int *a_result)
{
/* Replace metrics only if the metrics are supplied in font units. */
*a_result = 1;
@@ -1325,16 +1472,19 @@ can_replace_metrics(FAPI_server *a_server, FAPI_font *a_font, FAPI_char_ref *a_c
/*
* Retrieve the metrics of a_char_ref and put them in a_metrics.
*/
-static FAPI_retcode
-get_char_width(FAPI_server *a_server, FAPI_font *a_font, FAPI_char_ref *a_char_ref, FAPI_metrics *a_metrics)
+static gs_fapi_retcode
+get_char_width(gs_fapi_server * a_server, gs_fapi_font * a_font,
+ gs_fapi_char_ref * a_char_ref, gs_fapi_metrics * a_metrics)
{
- FF_server *s = (FF_server*)a_server;
+ ff_server *s = (ff_server *) a_server;
+
return load_glyph(a_server, a_font, a_char_ref, a_metrics,
- (FT_Glyph*)&s->outline_glyph,
+ (FT_Glyph *) & s->outline_glyph,
false, a_server->max_bitmap);
}
-static FAPI_retcode get_fontmatrix(FAPI_server *server, gs_matrix *m)
+static gs_fapi_retcode
+get_fontmatrix(gs_fapi_server * server, gs_matrix * m)
{
m->xx = 1.0;
m->xy = 0.0;
@@ -1350,32 +1500,37 @@ static FAPI_retcode get_fontmatrix(FAPI_server *server, gs_matrix *m)
* bitmap but store this. It can be retrieved by a subsequent call to
* get_char_raster.
*/
-static FAPI_retcode
-get_char_raster_metrics(FAPI_server *a_server, FAPI_font *a_font,
- FAPI_char_ref *a_char_ref, FAPI_metrics *a_metrics)
+static gs_fapi_retcode
+get_char_raster_metrics(gs_fapi_server * a_server, gs_fapi_font * a_font,
+ gs_fapi_char_ref * a_char_ref,
+ gs_fapi_metrics * a_metrics)
{
- FF_server *s = (FF_server*)a_server;
- FAPI_retcode error = load_glyph(a_server, a_font, a_char_ref, a_metrics,
- (FT_Glyph*)&s->bitmap_glyph, true, a_server->max_bitmap);
+ ff_server *s = (ff_server *) a_server;
+ gs_fapi_retcode error =
+ load_glyph(a_server, a_font, a_char_ref, a_metrics,
+ (FT_Glyph *) & s->bitmap_glyph, true,
+ a_server->max_bitmap);
return error;
}
/*
* Return the bitmap created by the last call to get_char_raster_metrics.
*/
-static FAPI_retcode
-get_char_raster(FAPI_server *a_server, FAPI_raster *a_raster)
+static gs_fapi_retcode
+get_char_raster(gs_fapi_server * a_server, gs_fapi_raster * a_raster)
{
- FF_server *s = (FF_server*)a_server;
+ ff_server *s = (ff_server *) a_server;
+
if (!s->bitmap_glyph)
- return_error(e_unregistered); /* Must not happen. */
+ return_error(gs_error_unregistered); /* Must not happen. */
a_raster->p = s->bitmap_glyph->bitmap.buffer;
a_raster->width = s->bitmap_glyph->bitmap.width;
a_raster->height = s->bitmap_glyph->bitmap.rows;
a_raster->line_step = s->bitmap_glyph->bitmap.pitch;
a_raster->orig_x = s->bitmap_glyph->left * 16;
a_raster->orig_y = s->bitmap_glyph->top * 16;
- a_raster->left_indent = a_raster->top_indent = a_raster->black_height = a_raster->black_width = 0;
+ a_raster->left_indent = a_raster->top_indent = a_raster->black_height =
+ a_raster->black_width = 0;
return 0;
}
@@ -1384,25 +1539,29 @@ get_char_raster(FAPI_server *a_server, FAPI_raster *a_raster)
* return the outline but store this.
* It can be retrieved by a subsequent call to get_char_outline.
*/
-static FAPI_retcode
-get_char_outline_metrics(FAPI_server *a_server, FAPI_font *a_font,
- FAPI_char_ref *a_char_ref, FAPI_metrics *a_metrics)
+static gs_fapi_retcode
+get_char_outline_metrics(gs_fapi_server * a_server, gs_fapi_font * a_font,
+ gs_fapi_char_ref * a_char_ref,
+ gs_fapi_metrics * a_metrics)
{
- FF_server *s = (FF_server*)a_server;
+ ff_server *s = (ff_server *) a_server;
+
return load_glyph(a_server, a_font, a_char_ref, a_metrics,
- (FT_Glyph*)&s->outline_glyph, false, a_server->max_bitmap);
+ (FT_Glyph *) & s->outline_glyph, false,
+ a_server->max_bitmap);
}
typedef struct FF_path_info_s
{
- FAPI_path *path;
+ gs_fapi_path *path;
int64_t x;
int64_t y;
} FF_path_info;
-static int move_to(const FT_Vector *aTo, void *aObject)
+static int
+move_to(const FT_Vector * aTo, void *aObject)
{
- FF_path_info *p = (FF_path_info*)aObject;
+ FF_path_info *p = (FF_path_info *) aObject;
/* FAPI expects that co-ordinates will be as implied by frac_shift
* in our case 16.16 fixed precision. True for 'low level' FT
@@ -1410,27 +1569,29 @@ static int move_to(const FT_Vector *aTo, void *aObject)
* FT returns a 26.6 format. Rescale to 16.16 so that FAPI will
* be able to convert to GS co-ordinates properly.
*/
- /* FAPI now expects these coordinates in 32.32 */
- p->x = ((int64_t)aTo->x) << 26;
- p->y = ((int64_t)aTo->y) << 26;
+ /* FAPI now expects these coordinates in 32.32 */
+ p->x = ((int64_t) aTo->x) << 26;
+ p->y = ((int64_t) aTo->y) << 26;
return p->path->moveto(p->path, p->x, p->y) ? -1 : 0;
}
-static int line_to(const FT_Vector *aTo, void *aObject)
+static int
+line_to(const FT_Vector * aTo, void *aObject)
{
- FF_path_info *p = (FF_path_info*)aObject;
+ FF_path_info *p = (FF_path_info *) aObject;
/* See move_to() above */
- p->x = ((int64_t)aTo->x) << 26;
- p->y = ((int64_t)aTo->y) << 26;
+ p->x = ((int64_t) aTo->x) << 26;
+ p->y = ((int64_t) aTo->y) << 26;
return p->path->lineto(p->path, p->x, p->y) ? -1 : 0;
}
-static int conic_to(const FT_Vector *aControl, const FT_Vector *aTo, void *aObject)
+static int
+conic_to(const FT_Vector * aControl, const FT_Vector * aTo, void *aObject)
{
- FF_path_info *p = (FF_path_info*)aObject;
+ FF_path_info *p = (FF_path_info *) aObject;
floatp x, y, Controlx, Controly;
int64_t Control1x, Control1y, Control2x, Control2y;
floatp sx, sy;
@@ -1451,50 +1612,51 @@ static int conic_to(const FT_Vector *aControl, const FT_Vector *aTo, void *aObje
* gives the same curve as the original quadratic.
*/
- sx = (floatp)(p->x >> 32);
- sy = (floatp)(p->y >> 32);
+ sx = (floatp) (p->x >> 32);
+ sy = (floatp) (p->y >> 32);
x = aTo->x / 64.0;
- p->x = ((int64_t)float2fixed(x)) << 24;
+ p->x = ((int64_t) float2fixed(x)) << 24;
y = aTo->y / 64.0;
- p->y = ((int64_t)float2fixed(y)) << 24;
+ p->y = ((int64_t) float2fixed(y)) << 24;
Controlx = aControl->x / 64.0;
Controly = aControl->y / 64.0;
- Control1x = ((int64_t)float2fixed((sx + Controlx * 2) / 3)) << 24;
- Control1y = ((int64_t)float2fixed((sy + Controly * 2) / 3)) << 24;
- Control2x = ((int64_t)float2fixed((x + Controlx * 2) / 3)) << 24;
- Control2y = ((int64_t)float2fixed((y + Controly * 2) / 3)) << 24;
+ Control1x = ((int64_t) float2fixed((sx + Controlx * 2) / 3)) << 24;
+ Control1y = ((int64_t) float2fixed((sy + Controly * 2) / 3)) << 24;
+ Control2x = ((int64_t) float2fixed((x + Controlx * 2) / 3)) << 24;
+ Control2y = ((int64_t) float2fixed((y + Controly * 2) / 3)) << 24;
return p->path->curveto(p->path, Control1x,
- Control1y,
- Control2x,
- Control2y,
- p->x, p->y) ? -1 : 0;
+ Control1y,
+ Control2x, Control2y, p->x, p->y) ? -1 : 0;
}
-static int cubic_to(const FT_Vector *aControl1, const FT_Vector *aControl2, const FT_Vector *aTo, void *aObject)
+static int
+cubic_to(const FT_Vector * aControl1, const FT_Vector * aControl2,
+ const FT_Vector * aTo, void *aObject)
{
- FF_path_info *p = (FF_path_info*)aObject;
+ FF_path_info *p = (FF_path_info *) aObject;
int64_t Control1x, Control1y, Control2x, Control2y;
/* See move_to() above */
- p->x = ((int64_t)aTo->x) << 26;
- p->y = ((int64_t)aTo->y) << 26;
+ p->x = ((int64_t) aTo->x) << 26;
+ p->y = ((int64_t) aTo->y) << 26;
- Control1x = ((int64_t)aControl1->x) << 26;
- Control1y = ((int64_t)aControl1->y) << 26;
- Control2x = ((int64_t)aControl2->x) << 26;
- Control2y = ((int64_t)aControl2->y) << 26;
- return p->path->curveto(p->path, Control1x, Control1y, Control2x, Control2y, p->x, p->y) ? -1 : 0;
+ Control1x = ((int64_t) aControl1->x) << 26;
+ Control1y = ((int64_t) aControl1->y) << 26;
+ Control2x = ((int64_t) aControl2->x) << 26;
+ Control2y = ((int64_t) aControl2->y) << 26;
+ return p->path->curveto(p->path, Control1x, Control1y, Control2x,
+ Control2y, p->x, p->y) ? -1 : 0;
p->x = aTo->x;
p->y = aTo->y;
- return p->path->curveto(p->path, aControl1->x, aControl1->y, aControl2->x, aControl2->y, aTo->x, aTo->y) ? -1 : 0;
+ return p->path->curveto(p->path, aControl1->x, aControl1->y, aControl2->x,
+ aControl2->y, aTo->x, aTo->y) ? -1 : 0;
}
-static const FT_Outline_Funcs TheFtOutlineFuncs =
-{
+static const FT_Outline_Funcs TheFtOutlineFuncs = {
move_to,
line_to,
conic_to,
@@ -1506,32 +1668,36 @@ static const FT_Outline_Funcs TheFtOutlineFuncs =
/*
* Return the outline created by the last call to get_char_outline_metrics.
*/
-static FAPI_retcode
-get_char_outline(FAPI_server *a_server, FAPI_path *a_path)
+static gs_fapi_retcode
+get_char_outline(gs_fapi_server * a_server, gs_fapi_path * a_path)
{
- FF_server *s = (FF_server*)a_server;
+ ff_server *s = (ff_server *) a_server;
FF_path_info p;
FT_Error ft_error = 0;
+
p.path = a_path;
p.x = 0;
p.y = 0;
- ft_error = FT_Outline_Decompose(&s->outline_glyph->outline, &TheFtOutlineFuncs, &p);
+ ft_error =
+ FT_Outline_Decompose(&s->outline_glyph->outline, &TheFtOutlineFuncs,
+ &p);
if (a_path->gs_error == 0)
a_path->closepath(a_path);
return ft_to_gs_error(ft_error);
}
-static FAPI_retcode release_char_data(FAPI_server *a_server)
+static gs_fapi_retcode
+release_char_data(gs_fapi_server * a_server)
{
- FF_server *s = (FF_server*)a_server;
+ ff_server *s = (ff_server *) a_server;
if (s->outline_glyph) {
- FT_Outline_Done (s->freetype_library, &s->outline_glyph->outline);
+ FT_Outline_Done(s->freetype_library, &s->outline_glyph->outline);
FF_free(s->ftmemory, s->outline_glyph);
}
if (s->bitmap_glyph) {
- FT_Bitmap_Done (s->freetype_library, &s->bitmap_glyph->bitmap);
+ FT_Bitmap_Done(s->freetype_library, &s->bitmap_glyph->bitmap);
FF_free(s->ftmemory, s->bitmap_glyph);
}
@@ -1540,37 +1706,37 @@ static FAPI_retcode release_char_data(FAPI_server *a_server)
return 0;
}
-static FAPI_retcode
-release_typeface(FAPI_server *a_server, void *a_server_font_data)
+static gs_fapi_retcode
+release_typeface(gs_fapi_server * a_server, void *a_server_font_data)
{
- FF_face *face = (FF_face*)a_server_font_data;
+ ff_face *face = (ff_face *) a_server_font_data;
+
delete_face(a_server, face);
return 0;
}
-static FAPI_retcode
-check_cmap_for_GID(FAPI_server *server, uint *index)
+static gs_fapi_retcode
+check_cmap_for_GID(gs_fapi_server * server, uint * index)
{
- FF_face *face = (FF_face*)(server->ff.server_font_data);
+ ff_face *face = (ff_face *) (server->ff.server_font_data);
FT_Face ft_face = face->ft_face;
*index = FT_Get_Char_Index(ft_face, *index);
return 0;
}
-static void gs_freetype_destroy(i_plugin_instance *a_instance, i_plugin_client_memory *a_memory);
+static void gs_fapi_freetype_destroy(gs_fapi_server ** serv);
-static const i_plugin_descriptor TheFreeTypeDescriptor =
-{
- "FAPI",
- "FreeType",
- gs_freetype_destroy
+static const gs_fapi_server_descriptor freetypedescriptor = {
+ (const char *)"FAPI",
+ (const char *)"FreeType",
+ gs_fapi_freetype_destroy
};
-static const FAPI_server TheFreeTypeServer =
-{
- { &TheFreeTypeDescriptor },
- 16, /* frac_shift */
+static const gs_fapi_server freetypeserver = {
+ {&freetypedescriptor},
+ NULL, /* client_ctx_p */
+ 16, /* frac_shift */
{gs_no_id},
{0},
0,
@@ -1583,6 +1749,7 @@ static const FAPI_server TheFreeTypeServer =
get_font_proportional_feature,
can_retrieve_char_by_name,
can_replace_metrics,
+ NULL, /* can_simulate_style */
get_fontmatrix,
get_char_width,
get_char_raster_metrics,
@@ -1591,36 +1758,47 @@ static const FAPI_server TheFreeTypeServer =
get_char_outline,
release_char_data,
release_typeface,
- check_cmap_for_GID
+ check_cmap_for_GID,
+ NULL /* get_font_info */
};
-plugin_instantiation_proc(gs_fapi_ft_instantiate);
+int gs_fapi_ft_init(gs_memory_t * mem, gs_fapi_server ** server);
-int gs_fapi_ft_instantiate( i_plugin_client_memory *a_memory, i_plugin_instance **a_plugin_instance)
+int
+gs_fapi_ft_init(gs_memory_t * mem, gs_fapi_server ** server)
{
- FF_server *server = (FF_server*) a_memory->alloc(a_memory, sizeof (FF_server), "FF_server");
- int code;
-
- if (!server)
- return e_VMerror;
- memset(server, 0, sizeof(*server));
-
- code = gs_memory_chunk_wrap(&(server->mem), a_memory->client_data);
+ ff_server *serv;
+ int code = 0;
+ gs_memory_t *cmem = NULL;
+
+ code = gs_memory_chunk_wrap(&(cmem), mem);
if (code != 0) {
- return(code);
+ return (code);
}
- server->fapi_server = TheFreeTypeServer;
- server->ftmemory = (FT_Memory)(&(server->ftmemory_rec));
+ serv =
+ (ff_server *) gs_alloc_bytes_immovable(cmem, sizeof(ff_server),
+ "gs_fapi_ft_init");
+ if (!serv) {
+ return_error(gs_error_VMerror);
+ }
+ memset(serv, 0, sizeof(*serv));
+ serv->mem = cmem;
+ serv->fapi_server = freetypeserver;
- *a_plugin_instance = &server->fapi_server.ig;
- return 0;
+ serv->ftmemory = (FT_Memory) (&(serv->ftmemory_rec));
+
+ (*server) = (gs_fapi_server *) serv;
+ return (0);
}
-static void gs_freetype_destroy(i_plugin_instance *a_plugin_instance, i_plugin_client_memory *a_memory)
+
+void
+gs_fapi_freetype_destroy(gs_fapi_server ** serv)
{
- FF_server *server = (FF_server *)a_plugin_instance;
+ ff_server *server = (ff_server *) * serv;
+ gs_memory_t *cmem = server->mem;
FT_Done_Glyph(&server->outline_glyph->root);
FT_Done_Glyph(&server->bitmap_glyph->root);
@@ -1630,6 +1808,7 @@ static void gs_freetype_destroy(i_plugin_instance *a_plugin_instance, i_plugin_c
* FT_Done_Library () and then discard the memory ourselves
*/
FT_Done_Library(server->freetype_library);
- gs_memory_chunk_release (server->mem);
- a_memory->free(a_memory, server, "FF_server");
+ gs_free(cmem, *serv, 0, 0, "gs_fapi_freetype_destroy: ff_server");
+ *serv = NULL;
+ gs_memory_chunk_release(cmem);
}
diff --git a/gs/psi/fapibstm.c b/gs/base/fapibstm.c
index d23a98045..8441600fc 100644
--- a/gs/psi/fapibstm.c
+++ b/gs/base/fapibstm.c
@@ -32,12 +32,13 @@
typedef struct fapi_bitstream_server_s fapi_bitstream_server;
-typedef struct fapi_bitstream_server_s {
+typedef struct fapi_bitstream_server_s
+{
FAPI_server If;
int bInitialized;
FAPI_font *ff;
i_plugin_client_memory client_mem;
-}Bitstream_server;
+} Bitstream_server;
typedef struct Bitstream_face_s
{
@@ -53,22 +54,20 @@ typedef struct Bitstream_face_s
unsigned char *font_data;
} Bitstream_face;
-static int InitFont(Bitstream_server *server, FAPI_font *ff)
+static int
+InitFont(Bitstream_server * server, FAPI_font * ff)
{
unsigned char *own_font_data = NULL, *temp;
- gs_memory_t *mem = (gs_memory_t *)server->client_mem.client_data;
- Bitstream_face *face = (Bitstream_face*)ff->server_font_data;
+ gs_memory_t *mem = (gs_memory_t *) server->client_mem.client_data;
+ Bitstream_face *face = (Bitstream_face *) ff->server_font_data;
long length, written;
int error, type;
- if (ff->font_file_path)
- {
+ if (ff->font_file_path) {
}
/* Load a typeface from a representation in GhostScript's memory. */
- else
- {
- if (ff->is_type1)
- {
+ else {
+ if (ff->is_type1) {
type = ff->get_word(ff, FAPI_FONT_FEATURE_FontType, 0);
/* Tell the FAPI interface that we need to *not* decrypt the /Subrs data. */
@@ -84,17 +83,19 @@ static int InitFont(Bitstream_server *server, FAPI_font *ff)
length = FF_serialize_type2_font(ff, NULL, 0);
own_font_data = gs_malloc(mem, 1, length, "Type 1 font copy");
if (type == 1)
- written = FF_serialize_type1_font_complete(ff, own_font_data, length);
+ written =
+ FF_serialize_type1_font_complete(ff, own_font_data,
+ length);
else
written = FF_serialize_type2_font(ff, own_font_data, length);
if (written != length)
- return(e_unregistered); /* Must not happen. */
+ return (e_unregistered); /* Must not happen. */
}
/* It must be type 42 (see code in FAPI_FF_get_glyph in zfapi.c). */
- else
- {
+ else {
/* Get the length of the TrueType data. */
long length = ff->get_long(ff, FAPI_FONT_FEATURE_TT_size, 0);
+
if (length == 0)
return e_invalidfont;
@@ -107,38 +108,50 @@ static int InitFont(Bitstream_server *server, FAPI_font *ff)
}
}
face->font_data = own_font_data;
- face->Input = New_InputStream3(face->MemObject, own_font_data, length, &error);
+ face->Input =
+ New_InputStream3(face->MemObject, own_font_data, length, &error);
if (ff->is_type1) {
if (type == 1)
- face->sfnt = FF_New_sfntClass(face->MemObject, FONT_TYPE_1, 1, face->Input, NULL, NULL, &error);
+ face->sfnt =
+ FF_New_sfntClass(face->MemObject, FONT_TYPE_1, 1, face->Input,
+ NULL, NULL, &error);
else
- face->sfnt = FF_New_sfntClass(face->MemObject, FONT_TYPE_2, 1, face->Input, NULL, NULL, &error);
+ face->sfnt =
+ FF_New_sfntClass(face->MemObject, FONT_TYPE_2, 1, face->Input,
+ NULL, NULL, &error);
}
- else
- {
- face->sfnt = FF_New_sfntClass(face->MemObject, FONT_TYPE_TT_OR_T2K, 1, face->Input, NULL, NULL, &error);
+ else {
+ face->sfnt =
+ FF_New_sfntClass(face->MemObject, FONT_TYPE_TT_OR_T2K, 1,
+ face->Input, NULL, NULL, &error);
}
face->T2K = NewT2K(face->MemObject, face->sfnt, &error);
face->Initialised = 1;
return 0;
}
-static FAPI_retcode ensure_open(FAPI_server *server, const byte *server_param, int server_param_size)
+static FAPI_retcode
+ensure_open(FAPI_server * server, const byte * server_param,
+ int server_param_size)
{
return 0;
}
-static FAPI_retcode get_scaled_font(FAPI_server *server, FAPI_font *ff,
- const FAPI_font_scale *font_scale, const char *xlatmap, FAPI_descendant_code dc)
+static FAPI_retcode
+get_scaled_font(FAPI_server * server, FAPI_font * ff,
+ const FAPI_font_scale * font_scale, const char *xlatmap,
+ FAPI_descendant_code dc)
{
- Bitstream_server *Bserver = (Bitstream_server *)server;
- Bitstream_face *face = (Bitstream_face*)ff->server_font_data;
+ Bitstream_server *Bserver = (Bitstream_server *) server;
+ Bitstream_face *face = (Bitstream_face *) ff->server_font_data;
- if(face == NULL) {
- gs_memory_t *mem = (gs_memory_t *)Bserver->client_mem.client_data;
+ if (face == NULL) {
+ gs_memory_t *mem = (gs_memory_t *) Bserver->client_mem.client_data;
int error;
- face = (Bitstream_face *)gs_malloc(mem, 1, sizeof(Bitstream_face), "Bitstream_face alloc");
+ face =
+ (Bitstream_face *) gs_malloc(mem, 1, sizeof(Bitstream_face),
+ "Bitstream_face alloc");
face->MemObject = tsi_NewMemhandler(&error);
if (error)
return -1;
@@ -148,43 +161,54 @@ static FAPI_retcode get_scaled_font(FAPI_server *server, FAPI_font *ff,
}
face->HRes = font_scale->HWResolution[0] >> 16;
face->VRes = font_scale->HWResolution[1] >> 16;
- face->trans.t00 = ONE16Dot16 * 50; /* font_scale->matrix[0];*/
- face->trans.t01 = 0; /*font_scale->matrix[1];*/
- face->trans.t10 = 0; /*font_scale->matrix[2];*/
- face->trans.t11 = ONE16Dot16 * 50; /*font_scale->matrix[3];*/
+ face->trans.t00 = ONE16Dot16 * 50; /* font_scale->matrix[0]; */
+ face->trans.t01 = 0; /*font_scale->matrix[1]; */
+ face->trans.t10 = 0; /*font_scale->matrix[2]; */
+ face->trans.t11 = ONE16Dot16 * 50; /*font_scale->matrix[3]; */
return 0;
}
-static FAPI_retcode get_decodingID(FAPI_server *server, FAPI_font *ff, const char **decodingID_result)
+static FAPI_retcode
+get_decodingID(FAPI_server * server, FAPI_font * ff,
+ const char **decodingID_result)
{
return 0;
}
-static FAPI_retcode get_font_bbox(FAPI_server *server, FAPI_font *ff, int BBox[4])
+static FAPI_retcode
+get_font_bbox(FAPI_server * server, FAPI_font * ff, int BBox[4])
{
return 0;
}
-static FAPI_retcode get_font_proportional_feature(FAPI_server *server, FAPI_font *ff, bool *bProportional)
+static FAPI_retcode
+get_font_proportional_feature(FAPI_server * server, FAPI_font * ff,
+ bool * bProportional)
{
return 0;
}
-static FAPI_retcode can_retrieve_char_by_name(FAPI_server *server, FAPI_font *ff, FAPI_char_ref *c, int *result)
+static FAPI_retcode
+can_retrieve_char_by_name(FAPI_server * server, FAPI_font * ff,
+ FAPI_char_ref * c, int *result)
{
*result = 1;
return 0;
}
-static FAPI_retcode can_replace_metrics(FAPI_server *server, FAPI_font *ff, FAPI_char_ref *c, int *result)
+static FAPI_retcode
+can_replace_metrics(FAPI_server * server, FAPI_font * ff, FAPI_char_ref * c,
+ int *result)
{
*result = 1;
return 0;
}
-static FAPI_retcode get_fontmatrix(FAPI_server *I, gs_matrix *m)
+static FAPI_retcode
+get_fontmatrix(FAPI_server * I, gs_matrix * m)
{
gs_matrix *base_font_matrix = &I->initial_FontMatrix;
+
m->xx = I->initial_FontMatrix.xx;
m->xy = I->initial_FontMatrix.xy;
m->yx = I->initial_FontMatrix.yx;
@@ -194,26 +218,33 @@ static FAPI_retcode get_fontmatrix(FAPI_server *I, gs_matrix *m)
return 0;
}
-static FAPI_retcode get_char_width(FAPI_server *server, FAPI_font *ff, FAPI_char_ref *c, FAPI_metrics *metrics)
+static FAPI_retcode
+get_char_width(FAPI_server * server, FAPI_font * ff, FAPI_char_ref * c,
+ FAPI_metrics * metrics)
{
return 0;
}
-static FAPI_retcode get_char_raster_metrics(FAPI_server *server, FAPI_font *ff, FAPI_char_ref *c, FAPI_metrics *metrics)
+static FAPI_retcode
+get_char_raster_metrics(FAPI_server * server, FAPI_font * ff,
+ FAPI_char_ref * c, FAPI_metrics * metrics)
{
- Bitstream_face *face = (Bitstream_face*)ff->server_font_data;
+ Bitstream_face *face = (Bitstream_face *) ff->server_font_data;
int error;
- if(!face->Initialised)
- InitFont((Bitstream_server *)server, ff);
+ if (!face->Initialised)
+ InitFont((Bitstream_server *) server, ff);
- T2K_NewTransformation(face->T2K, 1, face->HRes, face->VRes, &face->trans, false, &error);
- T2K_RenderGlyph(face->T2K, c->char_code, 0, 0, BLACK_AND_WHITE_BITMAP,
- T2K_NAT_GRID_FIT | T2K_RETURN_OUTLINES | T2K_SCAN_CONVERT, &error);
+ T2K_NewTransformation(face->T2K, 1, face->HRes, face->VRes, &face->trans,
+ false, &error);
+ T2K_RenderGlyph(face->T2K, c->char_codes[0], 0, 0, BLACK_AND_WHITE_BITMAP,
+ T2K_NAT_GRID_FIT | T2K_RETURN_OUTLINES | T2K_SCAN_CONVERT,
+ &error);
metrics->bbox_x0 = face->T2K->fLeft26Dot6 >> 6;
metrics->bbox_y0 = 0;
- metrics->bbox_x1 = metrics->bbox_x0 + face->T2K->xLinearAdvanceWidth16Dot16 >> 16;
+ metrics->bbox_x1 =
+ metrics->bbox_x0 + face->T2K->xLinearAdvanceWidth16Dot16 >> 16;
metrics->bbox_y1 = face->T2K->fTop26Dot6 >> 6;
metrics->escapement = face->T2K->xLinearAdvanceWidth16Dot16 >> 16;
metrics->v_escapement = face->T2K->yLinearAdvanceWidth16Dot16 >> 16;
@@ -222,10 +253,11 @@ static FAPI_retcode get_char_raster_metrics(FAPI_server *server, FAPI_font *ff,
return 0;
}
-static FAPI_retcode get_char_raster(FAPI_server *server, FAPI_raster *rast)
+static FAPI_retcode
+get_char_raster(FAPI_server * server, FAPI_raster * rast)
{
FAPI_font *ff = &server->ff;
- Bitstream_face *face = (Bitstream_face*)ff->server_font_data;
+ Bitstream_face *face = (Bitstream_face *) ff->server_font_data;
rast->p = face->T2K->baseAddr;
rast->width = face->T2K->width;
@@ -233,38 +265,44 @@ static FAPI_retcode get_char_raster(FAPI_server *server, FAPI_raster *rast)
rast->line_step = face->T2K->rowBytes;
rast->orig_x = 0;
rast->orig_y = 0;
- rast->left_indent = rast->top_indent = rast->black_height = rast->black_width = 0;
+ rast->left_indent = rast->top_indent = rast->black_height =
+ rast->black_width = 0;
return 0;
}
-static FAPI_retcode get_char_outline_metrics(FAPI_server *server, FAPI_font *ff, FAPI_char_ref *c, FAPI_metrics *metrics)
+static FAPI_retcode
+get_char_outline_metrics(FAPI_server * server, FAPI_font * ff,
+ FAPI_char_ref * c, FAPI_metrics * metrics)
{
return 0;
}
-static FAPI_retcode get_char_outline(FAPI_server *server, FAPI_path *p)
+static FAPI_retcode
+get_char_outline(FAPI_server * server, FAPI_path * p)
{
return 0;
}
-static FAPI_retcode release_char_data(FAPI_server *server)
+static FAPI_retcode
+release_char_data(FAPI_server * server)
{
FAPI_font *ff = &server->ff;
- Bitstream_face *face = (Bitstream_face*)ff->server_font_data;
+ Bitstream_face *face = (Bitstream_face *) ff->server_font_data;
int error;
T2K_PurgeMemory(face->T2K, 1, &error);
return 0;
}
-static FAPI_retcode release_typeface(FAPI_server *server, void *font_data)
+static FAPI_retcode
+release_typeface(FAPI_server * server, void *font_data)
{
int error;
- Bitstream_server *Bserver = (Bitstream_server *)server;
- Bitstream_face *face = (Bitstream_face*)font_data;
- gs_memory_t *mem = (gs_memory_t *)Bserver->client_mem.client_data;
+ Bitstream_server *Bserver = (Bitstream_server *) server;
+ Bitstream_face *face = (Bitstream_face *) font_data;
+ gs_memory_t *mem = (gs_memory_t *) Bserver->client_mem.client_data;
- if(face->Initialised) {
+ if (face->Initialised) {
DeleteT2K(face->T2K, &error);
FF_Delete_sfntClass(face->sfnt, &error);
Delete_InputStream(face->Input, &error);
@@ -274,12 +312,14 @@ static FAPI_retcode release_typeface(FAPI_server *server, void *font_data)
return 0;
}
-static FAPI_retcode check_cmap_for_GID(FAPI_server *server, uint index)
+static FAPI_retcode
+check_cmap_for_GID(FAPI_server * server, uint index)
{
return 0;
}
-static void gs_fapibstm_finit(i_plugin_instance *instance, i_plugin_client_memory *mem);
+static void gs_fapibstm_finit(i_plugin_instance * instance,
+ i_plugin_client_memory * mem);
static const i_plugin_descriptor bitstream_descriptor = {
"FAPI",
@@ -288,9 +328,8 @@ static const i_plugin_descriptor bitstream_descriptor = {
};
static const FAPI_server If0 = {
- { &bitstream_descriptor
- },
- 16, /* frac_shift */
+ {&bitstream_descriptor},
+ 16, /* frac_shift */
{gs_no_id},
{0},
0,
@@ -303,6 +342,7 @@ static const FAPI_server If0 = {
get_font_proportional_feature,
can_retrieve_char_by_name,
can_replace_metrics,
+ NULL, /* can_simulate_style */
get_fontmatrix,
get_char_width,
get_char_raster_metrics,
@@ -311,18 +351,23 @@ static const FAPI_server If0 = {
get_char_outline,
release_char_data,
release_typeface,
- check_cmap_for_GID
+ check_cmap_for_GID NULL /* get_font_info */
};
-plugin_instantiation_proc(gs_fapibstm_instantiate); /* check prototype */
+plugin_instantiation_proc(gs_fapibstm_instantiate); /* check prototype */
-int gs_fapibstm_instantiate(i_plugin_client_memory *client_mem, i_plugin_instance **p_instance)
+int
+gs_fapibstm_instantiate(i_plugin_client_memory * client_mem,
+ i_plugin_instance ** p_instance)
{
int error;
tsiMemObject *mem = NULL;
fapi_bitstream_server *r;
- r = (fapi_bitstream_server *)client_mem->alloc(client_mem, sizeof(fapi_bitstream_server), "fapi_bitstream_server");
+ r = (fapi_bitstream_server *) client_mem->alloc(client_mem,
+ sizeof
+ (fapi_bitstream_server),
+ "fapi_bitstream_server");
if (r == 0)
return e_VMerror;
memset(r, 0, sizeof(*r));
@@ -333,11 +378,12 @@ int gs_fapibstm_instantiate(i_plugin_client_memory *client_mem, i_plugin_instanc
return 0;
}
-static void gs_fapibstm_finit(i_plugin_instance *this, i_plugin_client_memory *mem)
+static void
+gs_fapibstm_finit(i_plugin_instance * this, i_plugin_client_memory * mem)
{
- fapi_bitstream_server *r = (fapi_bitstream_server *)this;
+ fapi_bitstream_server *r = (fapi_bitstream_server *) this;
if (r->If.ig.d != &bitstream_descriptor)
- return; /* safety */
+ return; /* safety */
mem->free(mem, r, "fapi_bitstream_server");
}
diff --git a/gs/base/fapiufst.c b/gs/base/fapiufst.c
new file mode 100644
index 000000000..827382158
--- /dev/null
+++ b/gs/base/fapiufst.c
@@ -0,0 +1,2093 @@
+/* Copyright (C) 2001-2012 Artifex Software, Inc.
+ All Rights Reserved.
+
+ This software is provided AS-IS with no warranty, either express or
+ implied.
+
+ This software is distributed under license and may not be copied,
+ modified or distributed except as expressly authorized under the terms
+ of the license contained in the file LICENSE in this distribution.
+
+ Refer to licensing information at http://www.artifex.com or contact
+ Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael,
+ CA 94903, U.S.A., +1(415)492-9861, for further information.
+*/
+
+
+/* Agfa UFST plugin */
+
+/* GS includes : */
+#include "stdio_.h"
+#include "stream.h" /* for files.h */
+#include "strmio.h"
+
+#include "memory_.h"
+#include "gsmemory.h"
+#include "math_.h"
+#include "stat_.h" /* include before definition of esp macro, bug 691123 */
+#include "gserrors.h"
+
+#include "gp.h"
+
+#include "gxdevice.h"
+#include "gxfont.h"
+#include "gxfont1.h"
+#include "gxchar.h"
+#include "gxpath.h"
+#include "gxfcache.h"
+#include "gxchrout.h"
+#include "gximask.h"
+#include "gscoord.h"
+#include "gspaint.h"
+#include "gsfont.h"
+#include "gspath.h"
+
+#include "gxfapi.h"
+
+#include "gzstate.h"
+#include "gdevpsf.h"
+#include "gscrypt1.h"
+#include "gxfcid.h"
+#include "gsstype.h"
+#include "gxchar.h" /* for st_gs_show_enum */
+
+#include "gsmalloc.h"
+#include "gsmchunk.h"
+
+#undef frac_bits
+
+#ifndef _MSC_VER
+#define _MSC_VER 0
+#endif
+
+/* UFST includes : */
+#include "cgconfig.h"
+#include "ufstport.h"
+#include "dbg_ufst.h"
+#include "shareinc.h"
+#include "t1isfnt.h"
+#include "cgmacros.h"
+#include "sfntenum.h"
+#define DOES_ANYONE_USE_THIS_STRUCTURE /* see TTPCLEO.H, UFST 4.2 */
+#include "ttpcleo.h"
+#undef DOES_ANYONE_USE_THIS_STRUCTURE
+
+#include "cgmacros.h" /* for SWAPW() and SWAPL() */
+
+#include "gxfapiu.h"
+
+#if UFST_VERSION_MAJOR >= 6 && UFST_VERSION_MINOR >= 2
+#include "t1itype1.h"
+#endif
+
+#if UFST_VERSION_MAJOR >= 6 && UFST_VERSION_MINOR >= 2
+#undef true
+#undef false
+
+#define false FALSE
+#define true TRUE
+#define UNICODE UFST_UNICODE
+#endif
+
+/* Prior to 6.2, prototypes had empty parameter lists, causing problems
+ * when passing 64 bit pointers into the UFST functions.
+ * Prototype "properly" here.
+ */
+#if UFST_VERSION_MAJOR < 6
+#if defined (ANSI_DEFS)
+UW16 CGENTRY CGIFFfont(FSP PFONTCONTEXT fc);
+#else
+UW16 CGENTRY CGIFFfont(fc);
+PFONTCONTEXT fc;
+#endif /* ANSI_DEFS */
+#endif
+
+typedef struct fapi_ufst_server_s fapi_ufst_server;
+
+static unsigned int font_ids = 0x7fffffff;
+
+#if UFST_REENTRANT
+#define FSA_FROM_SERVER IF_STATE *pIFS = &r->IFS
+#else
+EXTERN IF_STATE if_state;
+
+#define FSA_FROM_SERVER IF_STATE *pIFS = &if_state; (void)r; (void)pIFS;
+static fapi_ufst_server *static_server_ptr_for_ufst_callback = 0;
+#endif
+
+GLOBAL UW16 PCLswapHdr(FSP LPUB8 p, UW16 gifct); /* UFST header doesn't define it. */
+
+typedef struct pcleo_glyph_list_elem_s pcleo_glyph_list_elem;
+struct pcleo_glyph_list_elem_s
+{
+ UW16 chId;
+ pcleo_glyph_list_elem *next;
+ /* more data follows here depending on font type */
+};
+
+typedef struct
+{
+ SL32 font_id;
+ uint tt_font_body_offset;
+ UW16 is_disk_font;
+ UW16 font_type;
+ UW16 platformId;
+ UW16 specificId;
+ pcleo_glyph_list_elem *glyphs;
+ char decodingID[40];
+ TTFONTINFOTYPE *ufstfontinfo;
+ UW16 ufstfontinfosize;
+} ufst_common_font_data;
+
+typedef struct
+{
+ PCLETTO_CHR_HDR h;
+ UW16 add_data;
+ UW16 charDataSize;
+ UW16 glyphID;
+} PCLETTO_CHDR;
+
+struct fapi_ufst_server_s
+{
+ gs_fapi_server If;
+ int bInitialized;
+ gs_fapi_font *ff;
+ gs_memory_t *mem;
+ byte *param;
+ int param_size;
+ IF_STATE IFS;
+ FONTCONTEXT fc;
+ void *char_data;
+ bool bRaster;
+ bool ufst_is_singleton;
+ double tran_xx, tran_xy, tran_yx, tran_yy;
+ fco_list_elem *fco_list;
+ gs_fapi_retcode callback_error;
+ gs_fapi_metrics_type metrics_type;
+ fracint sb_x, aw_x; /* replaced PS metrics. */
+};
+
+static inline void release_char_data_inline(fapi_ufst_server * r);
+static void release_glyphs(fapi_ufst_server * r, ufst_common_font_data * d);
+
+/* Type casts : */
+
+static inline fapi_ufst_server *
+If_to_I(gs_fapi_server * If)
+{
+ return (fapi_ufst_server *) If;
+}
+
+static inline fapi_ufst_server *
+IFS_to_I(IF_STATE * pIFS)
+{
+ return (fapi_ufst_server *) ((char *)pIFS -
+ offset_of(fapi_ufst_server, IFS));
+}
+
+/* assign font_id not based on fchandle value, nor read from font */
+static inline int
+assign_font_id(void)
+{
+ /* We're only allowed 5 open FCOs at one time
+ * so make sure we don't clash with those
+ */
+ if ((--font_ids) <= (5 << 16)) {
+ /* When we clash with the expected values for FCO's
+ * wrap around. No will ever have enough concurrent
+ * fonts for this to be a problem!
+ */
+ font_ids = 0x7fffffff;
+ }
+ return (font_ids);
+}
+
+/*------------------ gs_fapi_server members ------------------------------------*/
+
+static inline void
+release_char_data_inline(fapi_ufst_server * r)
+{ /* The server keeps character raster between calls to get_char_raster_metrics
+ and get_char_raster, as well as between calls to get_char_outline_metrics
+ and get_char_outline. Meanwhile this regular
+ sequence of calls may be interrupted by an error in CDefProc or setchachedevice2,
+ which may be invoked between them. In this case Ghostscript
+ is unable to provide a signal to FAPI that the data are not
+ longer needed. This would cause memory leaks in UFST heap.
+ To work around this, appropriate server's entries check whether
+ raster data were left after a previous call, and ultimately release them.
+ This function provides it.
+ */
+ if (r->char_data != NULL) {
+ FSA_FROM_SERVER;
+
+ CHARfree(FSA(MEM_HANDLE) r->char_data);
+ r->char_data = 0;
+ }
+}
+
+/*
+ * In the language switch build (which we detect because PSI_INCLUDED
+ * is defined), we use the gx_UFST_init() call to initialize the UFST,
+ * rather than calling into the UFST directly. That has the advantage
+ * that the same UFST configuration is used for PCL and PS, but the
+ * disadvantage that the dynamic parameters set in server_param are
+ * not available. Thus, it is switched through this compile time option.
+*/
+static gs_fapi_retcode
+open_UFST(fapi_ufst_server * r, const byte * server_param,
+ int server_param_size)
+{
+ int code;
+ SW16 fcHandle;
+ int l;
+ char ufst_root_dir[1024] = "";
+ char sPlugIn[1024] = "";
+ bool bSSdir = FALSE, bPlugIn = FALSE;
+ const char *keySSdir = "UFST_SSdir=";
+ const int keySSdir_length = strlen(keySSdir);
+ const char *keyPlugIn = "UFST_PlugIn=";
+ const int keyPlugIn_length = strlen(keyPlugIn);
+ const char sep = gp_file_name_list_separator;
+ const byte *p = server_param, *e = server_param + server_param_size, *q;
+
+ FSA_FROM_SERVER;
+
+ if (server_param_size > 0 && server_param) {
+ r->param =
+ (byte *) gs_malloc(r->mem, server_param_size, 1, "server_params");
+ if (!r->param) {
+ return_error(gs_error_VMerror);
+ }
+ memcpy(r->param, server_param, server_param_size);
+ r->param_size = server_param_size;
+ }
+
+ for (; p < e; p = q + 1) {
+ for (q = p; q < e && *q != sep; q++)
+ /* DO_NOTHING */ ;
+ l = q - p;
+ if (l > keySSdir_length && !memcmp(p, keySSdir, keySSdir_length)) {
+ l = q - p - keySSdir_length;
+ if (l > sizeof(ufst_root_dir) - 1)
+ l = sizeof(ufst_root_dir) - 1;
+ memcpy(ufst_root_dir, p + keySSdir_length, l);
+ ufst_root_dir[l] = 0;
+ bSSdir = TRUE;
+ }
+ else if (l > keyPlugIn_length
+ && !memcmp(p, keyPlugIn, keyPlugIn_length)) {
+ l = q - p - keyPlugIn_length;
+ if (l > sizeof(sPlugIn) - 1)
+ l = sizeof(sPlugIn) - 1;
+ memcpy(sPlugIn, p + keyPlugIn_length, l);
+ sPlugIn[l] = 0;
+ bPlugIn = TRUE;
+ }
+ else if (gs_debug_c('1'))
+ emprintf(r->mem, "Warning: Unknown UFST parameter ignored.\n");
+ }
+#if !NO_SYMSET_MAPPING
+ if (!bSSdir) {
+ strcpy(ufst_root_dir, ".");
+ if (gs_debug_c('1'))
+ emprintf(r->mem,
+ "Warning: UFST_SSdir is not specified, will search *.ss files in the curent directory.\n");
+ }
+#endif
+ code = gx_UFST_init(r->mem, (const UB8 *)ufst_root_dir);
+ if (code < 0)
+ return code;
+ r->ufst_is_singleton = (code == 1);
+ CGIFfont_access(FSA DISK_ACCESS);
+ if (bPlugIn) {
+ if ((code = gx_UFST_open_static_fco(sPlugIn, &fcHandle)) != 0)
+ return code;
+ if ((code = CGIFfco_Plugin(FSA fcHandle)) != 0)
+ return code;
+ }
+ else {
+#ifdef FCO_RDR
+ emprintf(r->mem,
+ "Warning: UFST_PlugIn is not specified, some characters may be missing.\n");
+#endif
+ }
+ return 0;
+}
+
+static LPUB8 impl_PCLchId2ptr(FSP UW16 chId);
+
+static gs_fapi_retcode
+ensure_open(gs_fapi_server * server, const byte * server_param,
+ int server_param_size)
+{
+ fapi_ufst_server *r = If_to_I(server);
+ int code;
+
+ if (r->bInitialized)
+ return 0;
+ r->bInitialized = 1;
+ {
+ code = open_UFST(r, server_param, server_param_size);
+ if (code < 0) {
+ emprintf(r->mem, "Error opening the UFST font server.\n");
+ return code;
+ }
+ }
+ gx_set_UFST_Callbacks(NULL, impl_PCLchId2ptr, impl_PCLchId2ptr);
+ return 0;
+}
+
+static UW16
+get_font_type(stream * f)
+{
+ char buf[20], mark_PS[] = "%!";
+ int i;
+
+ if (sfread(buf, 1, sizeof(buf), f) != sizeof(buf))
+ return 0;
+ if (buf[0] == 0x15 || buf[0] == 0x00) /* fixme : don't know how to do correctly. */
+ return FC_FCO_TYPE;
+ for (i = 0; i < sizeof(buf) - sizeof(mark_PS); i++)
+ if (!memcmp(buf + i, mark_PS, sizeof(mark_PS) - 1))
+ return FC_PST1_TYPE;
+ if (buf[0] == '\0' && buf[1] == '\1')
+ return FC_TT_TYPE;
+ if (buf[0] == 't' && buf[1] == 't')
+ return FC_TT_TYPE;
+ return 0; /* fixme : unknown type - actually an error. */
+}
+
+static int
+choose_decoding_general(fapi_ufst_server * r, ufst_common_font_data * d,
+ const char *cmapId)
+{
+ if (!d->decodingID[0])
+ strncpy(d->decodingID, "Unicode", sizeof(d->decodingID));
+ /* fixme : must depend on charset used in the font. */
+ return 1;
+}
+
+static int
+choose_decoding_TT(fapi_ufst_server * r, ufst_common_font_data * d,
+ const char *cmapId)
+{
+#if TT_ROM || TT_DISK
+ int platId, specId, i;
+ CMAP_QUERY q;
+ UW16 font_access;
+ bool failed;
+ void *p =
+ (d->is_disk_font ? (void *)(d + 1) : (void *)((UB8 *) d +
+ d->
+ tt_font_body_offset));
+ FSA_FROM_SERVER;
+
+ if (sscanf(cmapId, "%d.%d", &platId, &specId) != 2)
+ return 0;
+ font_access = pIFS->font_access;
+ pIFS->font_access = (d->is_disk_font ? DISK_ACCESS : ROM_ACCESS);
+ failed = CGIFtt_cmap_query(FSA p, r->fc.ttc_index, &q);
+ pIFS->font_access = font_access;
+ if (failed)
+ return 0;
+ for (i = 0; i < q.numCmap; i++)
+ if (q.entry[i].platId == platId && q.entry[i].specId == specId) {
+ d->platformId = platId;
+ d->specificId = specId;
+ return 1;
+ }
+ return 0;
+#else
+ if (!d->decodingID[0])
+ strncpy(d->decodingID, "Unicode", sizeof(d->decodingID));
+ return 1;
+#endif
+}
+
+static void
+scan_xlatmap(fapi_ufst_server * r, ufst_common_font_data * d,
+ const char *xlatmap, const char *font_kind,
+ int (*choose_proc) (fapi_ufst_server * r,
+ ufst_common_font_data * d,
+ const char *cmapId))
+{
+ const char *p = xlatmap;
+
+ while (*p) {
+ int good_kind = !strcmp(p, font_kind);
+
+ p += strlen(p) + 2;
+ while (*p) {
+ const char *cmapId = p, *decodingID = p + strlen(p) + 1;
+
+ strncpy(d->decodingID, decodingID, sizeof(d->decodingID));
+ if (!decodingID[0])
+ break;
+ p = decodingID + strlen(decodingID) + 1;
+ if (good_kind)
+ if (choose_proc(r, d, cmapId))
+ return;
+ }
+ }
+ d->decodingID[0] = 0;
+}
+
+static void
+choose_decoding(fapi_ufst_server * r, ufst_common_font_data * d,
+ const char *xlatmap)
+{
+ if (xlatmap != 0)
+ switch (d->font_type) {
+ case FC_IF_TYPE: /* fixme */
+ break;
+ case FC_PST1_TYPE:
+ scan_xlatmap(r, d, xlatmap, "PostScript",
+ choose_decoding_general);
+ break;
+ case FC_TT_TYPE:
+ scan_xlatmap(r, d, xlatmap, "TrueType", choose_decoding_TT);
+ break;
+ case FC_FCO_TYPE:
+ scan_xlatmap(r, d, xlatmap, "Microtype",
+ choose_decoding_general);
+ break;
+ }
+}
+
+static inline void
+store_word(byte ** p, ushort w)
+{
+ *((*p)++) = w / 256;
+ *((*p)++) = w % 256;
+
+}
+
+static LPUB8
+get_TT_glyph(fapi_ufst_server * r, gs_fapi_font * ff, UW16 chId)
+{
+ pcleo_glyph_list_elem *g;
+ PCLETTO_CHDR *h;
+ ufst_common_font_data *d = (ufst_common_font_data *) r->fc.font_hdr - 1;
+ LPUB8 q;
+ ushort glyph_length = ff->get_glyph(ff, chId, 0, 0);
+ bool use_XL_format = ff->is_mtx_skipped;
+
+ /*
+ * The client must set ff->is_mtx_skipped iff
+ * it requests a replaced lsb for True Type.
+ * If it is set, a replaced width to be supplied.
+ * This constraint is derived from UFST restriction :
+ * the font header format must be compatible with
+ * glyph header format.
+ */
+
+ if (glyph_length == (ushort) - 1) {
+ r->callback_error = gs_error_invalidfont;
+ return 0;
+ }
+ g = (pcleo_glyph_list_elem *) gs_malloc(r->mem,
+ sizeof(pcleo_glyph_list_elem) +
+ (use_XL_format ? 12 :
+ sizeof(PCLETTO_CHDR)) +
+ glyph_length + 2, 1,
+ "PCLETTO char");
+ if (g == 0) {
+ r->callback_error = gs_error_VMerror;
+ return 0;
+ }
+ g->chId = chId;
+ g->next = d->glyphs;
+ d->glyphs = g;
+ h = (PCLETTO_CHDR *) (g + 1);
+ h->h.format = 15;
+ if (use_XL_format) {
+ h->h.continuation = 2;
+ q = (LPUB8) h + 2;
+ store_word(&q, (ushort) (glyph_length + 10));
+ store_word(&q, (ushort) (r->sb_x >> r->If.frac_shift)); /* see can_replace_metrics */
+ store_word(&q, (ushort) (r->aw_x >> r->If.frac_shift));
+ store_word(&q, 0);
+ store_word(&q, chId);
+ }
+ else {
+ h->h.continuation = 0;
+ h->h.descriptorsize = 4;
+ h->h.ch_class = 15;
+ h->add_data = 0;
+ q = (LPUB8) & h->charDataSize;
+ store_word(&q, (ushort) (glyph_length + 4));
+ store_word(&q, chId);
+ }
+ if (ff->get_glyph(ff, chId, (LPUB8) q, glyph_length) == (ushort) - 1) {
+ r->callback_error = gs_error_invalidfont;
+ return 0;
+ }
+ q += glyph_length;
+ store_word(&q, 0); /* checksum */
+ return (LPUB8) h;
+ /*
+ * The metrics replacement here is done only for the case
+ * corresponding to non-disk TT fonts with MetricsCount != 0;
+ * Other cases are not supported because UFST cannot handle them.
+ * Here we don't take care of cases which can_replace_metrics rejects.
+ *
+ * We don't care of metrics for subglyphs, because
+ * it is ignored by TT interpreter.
+ */
+}
+
+static LPUB8
+get_T1_glyph(fapi_ufst_server * r, gs_fapi_font * ff, UW16 chId)
+{
+#if PST1_SFNTI
+#if UFST_VERSION_MAJOR >= 6 && UFST_VERSION_MINOR >= 2
+ ushort glyph_length = ff->get_glyph(ff, chId, 0, 0);
+ CDATASTR charstring;
+ PCDATASTR_DEMO pcharstring;
+ byte *cstring;
+ ufst_common_font_data *d = (ufst_common_font_data *) r->fc.font_hdr - 1;
+ MEM_HANDLE hndl;
+
+ FSA_FROM_SERVER;
+
+ d->glyphs = NULL;
+
+ charstring.len = glyph_length;
+ charstring.hdata = BUFalloc(charstring.len);
+ if (!charstring.hdata) {
+ r->callback_error = gs_error_VMerror;
+ return (NULL);
+ }
+
+ cstring = (unsigned char *)MEMptr(charstring.hdata);
+
+ if (ff->get_glyph(ff, chId, cstring, glyph_length) != glyph_length) {
+ r->callback_error = gs_error_VMerror;
+ BUFfree(charstring.hdata);
+ return (NULL);
+ }
+
+ hndl = BUFalloc(FSA(SL32) (sizeof(CDATASTR)));
+ if (!hndl) {
+ r->callback_error = gs_error_VMerror;
+ BUFfree(charstring.hdata);
+ return (NULL);
+ }
+
+ pcharstring = (PCDATASTR_DEMO) MEMptr(hndl);
+
+ pcharstring->len = charstring.len; /* Datalen */
+ pcharstring->hdata = charstring.hdata;
+ pcharstring->decrypted = 1;
+
+ return ((LPUB8) pcharstring);
+#else
+ ushort glyph_length = ff->get_glyph(ff, chId, 0, 0);
+ LPUB8 q;
+ pcleo_glyph_list_elem *g = (pcleo_glyph_list_elem *) gs_malloc(r->mem,
+ sizeof
+ (pcleo_glyph_list_elem)
+ +
+ sizeof
+ (PS_CHAR_HDR)
+ + 2 + 2 +
+ glyph_length
+ + 1, 1,
+ "PSEO char");
+ PS_CHAR_HDR *h;
+ ufst_common_font_data *d = (ufst_common_font_data *) r->fc.font_hdr - 1;
+
+ FSA_FROM_SERVER;
+
+ if (g == 0 || glyph_length == (ushort) - 1) {
+ r->callback_error = gs_error_invalidfont;
+ return 0;
+ }
+ g->chId = chId;
+ g->next = d->glyphs;
+ d->glyphs = g;
+ h = (PS_CHAR_HDR *) (g + 1);
+ h->format = 30; /* raster=4, DJ=5, IF=10, TT=15, PS=30 */
+ h->continuation = 0; /* always 0 */
+ h->descriptorsize = 2; /* always 2 */
+ h->ch_class = 11; /* contour=3, compound=4, tt=10, ps=11 */
+ h->len = 0; /* # of bytes to follow (not including csum) */
+ q = (byte *) h + sizeof(*h);
+ /* A workaround for UFST4.6 bug in t1idecod.c (UNPACK_WORD uses pIFS->ph instead ph) :
+ setting Namelen=4, rather normally it must be 0. */
+ q[0] = 0; /* Namelen */
+ q[1] = 4; /* Namelen */
+ q[2] = (glyph_length) / 256; /* Datalen */
+ q[3] = (glyph_length) % 256; /* Datalen */
+ /* Glyph name goes here, but we don't use it. */
+ q += 4;
+ glyph_length = ff->get_glyph(ff, chId, q, glyph_length);
+ q += glyph_length;
+ *q = 1; /* Decrypt flag */
+ pIFS->ph = (byte *) h + sizeof(*h); /* A workaround for UFST4.6 bug in t1idecod.c (UNPACK_WORD uses pIFS->ph instead ph) */
+ return (LPUB8) h;
+#endif
+#else
+ return 0;
+#endif
+}
+
+static pcleo_glyph_list_elem *
+find_glyph(ufst_common_font_data * d, UW16 chId)
+{
+ pcleo_glyph_list_elem *e;
+
+ for (e = d->glyphs; e != 0; e = e->next)
+ if (e->chId == chId)
+ return e;
+ return 0;
+}
+
+/* UFST callback : */
+static LPUB8
+impl_PCLchId2ptr(FSP UW16 chId)
+{
+#if UFST_REENTRANT
+ fapi_ufst_server *r = IFS_to_I(pIFS);
+#else
+ fapi_ufst_server *r = static_server_ptr_for_ufst_callback;
+#endif
+ gs_fapi_font *ff = r->ff;
+ ufst_common_font_data *d = (ufst_common_font_data *) r->fc.font_hdr - 1;
+ pcleo_glyph_list_elem *g = find_glyph(d, chId);
+ LPUB8 result = 0;
+
+ if (g != 0)
+ result = (LPUB8) (g + 1);
+ if ((r->fc.format & FC_FONTTYPE_MASK) == FC_PST1_TYPE)
+ result = get_T1_glyph(r, ff, chId);
+ if ((r->fc.format & FC_FONTTYPE_MASK) == FC_TT_TYPE)
+ result = get_TT_glyph(r, ff, chId);
+ return result;
+}
+
+static inline void
+pack_word(LPUB8 * p, UW16 v)
+{
+ LPUB8 q = (LPUB8) & v;
+
+#if (BYTEORDER == LOHI) /* defied in UFST includes */
+ (*p)[1] = q[0];
+ (*p)[0] = q[1];
+#else
+ *(UW16 *) (*p) = v;
+#endif
+ *p += 2;
+}
+
+static inline void
+pack_long(LPUB8 * p, UL32 v)
+{
+ LPUB8 q = (LPUB8) & v;
+
+#if (BYTEORDER == LOHI) /* defied in UFST includes */
+ (*p)[3] = q[0];
+ (*p)[2] = q[1];
+ (*p)[1] = q[2];
+ (*p)[0] = q[3];
+#else
+ *(UL32 *) (*p) = v;
+#endif
+ *p += 4;
+}
+
+static inline void
+pack_float(LPUB8 * p, float v)
+{
+ sprintf((char *)(*p), "%f", v);
+ *p += strlen((const char *)*p) + 1;
+}
+
+#define PACK_ZERO(p) *(p++) = 0
+#define PACK_BYTE(p, c) *(p++) = c
+#define PACK_WORD(p, i, var) pack_word(&p, ff->get_word(ff, var, i))
+#define PACK_LONG(p, i, var) pack_long(&p, ff->get_long(ff, var, i))
+
+static void
+pack_pseo_word_array(fapi_ufst_server * r, gs_fapi_font * ff, UB8 ** p,
+ UW16 max_count, gs_fapi_font_feature count_id,
+ gs_fapi_font_feature array_id)
+{
+ UW16 k = min(ff->get_word(ff, count_id, 0), max_count), j;
+
+ pack_word(p, k);
+ for (j = 0; j < k; j++)
+ PACK_WORD(*p, j, array_id);
+ for (; j < max_count; j++)
+ pack_word(p, 0);
+}
+
+static void
+pack_pseo_fhdr(fapi_ufst_server * r, gs_fapi_font * ff, UB8 * p)
+{
+ ushort j, n, skip = 0;
+
+ while (((uint64_t) p) & 0x03) /* align to QUADWORD */
+ PACK_ZERO(p);
+
+ pack_long(&p, 1); /* format = 1 */
+ for (j = 0; j < 6; j++)
+ pack_float(&p, ff->get_float(ff, gs_fapi_font_feature_FontMatrix, j));
+ while (((uint64_t) p) & 0x03) /* align to QUADWORD */
+ PACK_ZERO(p);
+ /* UFST has no definition for PSEO structure, so implement serialization : */
+ PACK_LONG(p, 0, gs_fapi_font_feature_UniqueID);
+ PACK_LONG(p, 0, gs_fapi_font_feature_BlueScale);
+ PACK_WORD(p, 0, gs_fapi_font_feature_Weight);
+ PACK_WORD(p, 0, gs_fapi_font_feature_ItalicAngle);
+ PACK_WORD(p, 0, gs_fapi_font_feature_IsFixedPitch);
+ PACK_WORD(p, 0, gs_fapi_font_feature_UnderLinePosition);
+ PACK_WORD(p, 0, gs_fapi_font_feature_UnderlineThickness);
+ PACK_WORD(p, 0, gs_fapi_font_feature_FontType);
+ PACK_WORD(p, 0, gs_fapi_font_feature_FontBBox);
+ PACK_WORD(p, 1, gs_fapi_font_feature_FontBBox);
+ PACK_WORD(p, 2, gs_fapi_font_feature_FontBBox);
+ PACK_WORD(p, 3, gs_fapi_font_feature_FontBBox);
+ pack_pseo_word_array(r, ff, &p, 14, gs_fapi_font_feature_BlueValues_count,
+ gs_fapi_font_feature_BlueValues);
+ pack_pseo_word_array(r, ff, &p, 10, gs_fapi_font_feature_OtherBlues_count,
+ gs_fapi_font_feature_OtherBlues);
+ pack_pseo_word_array(r, ff, &p, 14,
+ gs_fapi_font_feature_FamilyBlues_count,
+ gs_fapi_font_feature_FamilyBlues);
+ pack_pseo_word_array(r, ff, &p, 10,
+ gs_fapi_font_feature_FamilyOtherBlues_count,
+ gs_fapi_font_feature_FamilyOtherBlues);
+ PACK_WORD(p, 0, gs_fapi_font_feature_BlueShift);
+ PACK_WORD(p, 0, gs_fapi_font_feature_BlueFuzz);
+ PACK_WORD(p, 0, gs_fapi_font_feature_StdHW);
+ PACK_WORD(p, 0, gs_fapi_font_feature_StdVW);
+ pack_pseo_word_array(r, ff, &p, 12, gs_fapi_font_feature_StemSnapH_count,
+ gs_fapi_font_feature_StemSnapH);
+ pack_pseo_word_array(r, ff, &p, 12, gs_fapi_font_feature_StemSnapV_count,
+ gs_fapi_font_feature_StemSnapV);
+ PACK_WORD(p, 0, gs_fapi_font_feature_ForceBold);
+ PACK_WORD(p, 0, gs_fapi_font_feature_LanguageGroup);
+ PACK_WORD(p, 0, gs_fapi_font_feature_lenIV);
+ for (j = 0; j < 12; j++)
+ PACK_ZERO(p), PACK_ZERO(p); /* Reserved2 */
+ /* max data size = 107 words + 6 floats in ASCII */
+ n = ff->get_word(ff, gs_fapi_font_feature_Subrs_count, 0);
+ pack_word(&p, n);
+ for (j = 0; j < n; j++) {
+ ushort subr_len = ff->get_subr(ff, j, 0, 0);
+
+ if (subr_len != 0) {
+ pack_word(&p, j);
+ pack_word(&p, subr_len);
+ PACK_BYTE(p, 1); /* is_decrypted */
+ ff->get_subr(ff, j, p, subr_len);
+ p += subr_len;
+ }
+ else
+ skip = 1;
+ }
+ n = ff->get_word(ff, gs_fapi_font_feature_GlobalSubrs_count, 0);
+ /* get_word() doesn't have an error return value, so I've used an unlikely value */
+ if (n != 65535) {
+ pack_word(&p, n);
+ for (j = 0; j < n; j++) {
+ ushort subr_len = ff->get_gsubr(ff, j, 0, 0);
+
+ if (subr_len != 0) {
+ pack_word(&p, j);
+ pack_word(&p, subr_len);
+ PACK_BYTE(p, 1); /* is_decrypted */
+ ff->get_gsubr(ff, j, p, subr_len);
+ p += subr_len;
+ }
+ else
+ skip = 1;
+ }
+ }
+ if (skip)
+ pack_word(&p, 0xFFFF);
+}
+
+static char *
+my_strdup(fapi_ufst_server * r, const char *s, const char *cname)
+{
+ int len = strlen(s) + 1;
+ char *p = (char *)gs_malloc(r->mem, len, 1, cname);
+
+ if (p != 0)
+ memcpy(p, s, len);
+ return p;
+}
+
+static gs_fapi_retcode
+fco_open(fapi_ufst_server * r, const char *font_file_path,
+ fco_list_elem ** result)
+{
+ int code;
+ fco_list_elem *e = gx_UFST_find_static_fco(font_file_path);
+
+ if (e != NULL) {
+ *result = e;
+ return 0;
+ }
+ for (e = r->fco_list; e != 0; e = e->next) {
+ if (!strcmp(e->file_path, font_file_path))
+ break;
+ }
+ if (e == 0) {
+ SW16 fcHandle;
+
+ FSA_FROM_SERVER;
+
+ if ((code = CGIFfco_Open(FSA(UB8 *) font_file_path, &fcHandle)) != 0)
+ return code;
+ e = (fco_list_elem *) gs_malloc(r->mem, sizeof(*e), 1,
+ "fco_list_elem");
+ if (e == 0) {
+ CGIFfco_Close(FSA fcHandle);
+ return gs_error_VMerror;
+ }
+ e->open_count = 0;
+ e->fcHandle = fcHandle;
+ e->file_path = my_strdup(r, font_file_path, "fco_file_path");
+ if (e->file_path == 0) {
+ CGIFfco_Close(FSA fcHandle);
+ gs_free(r->mem, e, 0, 0, "fco_list_elem");
+ return gs_error_VMerror;
+ }
+ e->next = r->fco_list;
+ r->fco_list = e;
+ }
+ e->open_count++;
+ *result = e;
+ return 0;
+}
+
+static gs_fapi_retcode
+ufst_make_font_data(fapi_ufst_server * r, const char *font_file_path,
+ gs_fapi_font * ff, ufst_common_font_data ** return_data)
+{
+ ulong area_length = sizeof(ufst_common_font_data), tt_size = 0;
+ LPUB8 buf;
+ PCLETTO_FHDR *h;
+ ufst_common_font_data *d;
+ bool use_XL_format = ff->is_mtx_skipped;
+ int code;
+
+ FSA_FROM_SERVER;
+
+ *return_data = 0;
+ r->fc.ttc_index = ff->subfont;
+ if (ff->font_file_path == NULL) {
+#if UFST_VERSION_MAJOR < 6
+ return (e_invalidaccess);
+#else
+ area_length += PCLETTOFONTHDRSIZE;
+ if (ff->is_type1) {
+ int subrs_count =
+ ff->get_word(ff, gs_fapi_font_feature_Subrs_count, 0);
+ int subrs_length =
+ ff->get_long(ff, gs_fapi_font_feature_Subrs_total_size, 0);
+ int subrs_area_size;
+ int gsubrs_count =
+ ff->get_word(ff, gs_fapi_font_feature_GlobalSubrs_count, 0);
+
+ /* get_word() doesn't have an error return value, so I've used an unlikely value */
+ if (gsubrs_count != 65535)
+ subrs_count += gsubrs_count;
+
+ subrs_area_size = subrs_count * 5 + subrs_length + 2;
+ area_length += 360 + subrs_area_size; /* some inprecise - see pack_pseo_fhdr */
+ }
+ else {
+ tt_size = ff->get_long(ff, gs_fapi_font_feature_TT_size, 0);
+ if (tt_size == 0)
+ return gs_error_invalidfont;
+/* area_length += tt_size + (use_XL_format ? 6 : 4) + 4 + 2;*/
+ area_length += tt_size + 6 + 4 + 2;
+ }
+#endif
+ }
+ else {
+#if UFST_VERSION_MAJOR < 6
+ int sind = strlen(font_file_path) - 1;
+
+ if ((font_file_path[sind] != 'o' || font_file_path[sind] != 'O') &&
+ (font_file_path[sind - 1] != 'c'
+ || font_file_path[sind - 1] != 'C')
+ && (font_file_path[sind - 2] != 'f'
+ || font_file_path[sind - 2] != 'F')
+ && font_file_path[sind - 3] != '.') {
+ return (e_invalidaccess);
+ }
+#endif
+ area_length += strlen(font_file_path) + 1;
+ }
+ buf = gs_malloc(r->mem, area_length, 1, "ufst font data");
+ if (buf == 0)
+ return gs_error_VMerror;
+
+ memset(buf, 0x00, area_length);
+
+ d = (ufst_common_font_data *) buf;
+ d->tt_font_body_offset = 0;
+ d->platformId = 0;
+ d->specificId = 0;
+ d->decodingID[0] = 0;
+ d->glyphs = 0;
+ d->is_disk_font = (ff->font_file_path != NULL);
+ d->ufstfontinfo = NULL;
+ d->ufstfontinfosize = 0;
+
+ if (d->is_disk_font) {
+ fco_list_elem *e = gx_UFST_find_static_fco(font_file_path);
+
+ if (e != NULL) {
+ memcpy(d + 1, font_file_path, strlen(font_file_path) + 1);
+ d->font_id = (e->fcHandle << 16) | ff->subfont;
+ d->font_type = FC_FCO_TYPE;
+ }
+ else {
+ stream *f = sfopen(font_file_path, "rb", r->mem);
+
+ if (f == NULL) {
+ emprintf1(r->mem,
+ "fapiufst: Can't open %s\n", font_file_path);
+ return gs_error_undefinedfilename;
+ }
+ memcpy(d + 1, font_file_path, strlen(font_file_path) + 1);
+ d->font_type = get_font_type(f);
+ sfclose(f);
+ if (d->font_type == FC_FCO_TYPE) {
+ fco_list_elem *e;
+
+ if ((code = fco_open(r, font_file_path, &e)) != 0)
+ return code;
+ d->font_id = (e->fcHandle << 16) | ff->subfont;
+ }
+ }
+ }
+ else {
+ d->font_type = (ff->is_type1 ? FC_PST1_TYPE : FC_TT_TYPE);
+ d->font_id = ff->get_long(ff, gs_fapi_font_feature_UniqueID, 0);
+ if (d->font_id < 0) {
+ d->font_id = assign_font_id();
+ }
+ h = (PCLETTO_FHDR *) (buf + sizeof(ufst_common_font_data));
+ /* For some reason the bytes of fontDescriptorSize need swapped here
+ (PCLswapHdr() doesn't do it as needed), but only for TTF fonts - duh!?!?
+ */
+ if (ff->is_type1) {
+ h->fontDescriptorSize = PCLETTOFONTHDRSIZE;
+ }
+ else {
+ h->fontDescriptorSize = SWAPW(PCLETTOFONTHDRSIZE);
+ }
+
+ if (d->font_type == FC_TT_TYPE)
+ h->descriptorFormat = 16;
+ else
+ h->descriptorFormat = 15;
+ h->fontType = 11; /* wrong *//* 3- 11=Unicode; 0,1,2 also possible */
+ h->style_msb = 0; /* wrong *//* 4- from PCLT table in TrueType font */
+ h->reserved1 = 0;
+ h->baselinePosition = 0; /* wrong *//* 6- from head table in TT font; = 0 */
+ h->cellWidth = 1024; /* wrong *//* 8- head, use xMax - xMin */
+ h->cellHeight = 1024; /* wrong *//* 10- head, use yMax - yMin */
+ h->orientation = 0; /* 12- 0 */
+ h->spacing = 1; /* wrong *//* 13- 1=proportional, 0-fixed pitch */
+ h->characterSet = 56; /* wrong *//* 14- same as symSetCode; =56 if unbound. */
+ h->pitch = 1024; /* wrong *//* 16- PCLT */
+ h->height = 0; /* 18- 0 if TrueType */
+ h->xHeight = 512; /* wrong *//* 20- PCLT */
+ h->widthType = 0; /* wrong *//* 22- PCLT */
+ h->style_lsb = 0; /* wrong *//* 23- PCLT */
+ h->strokeWeight = 0; /* wrong *//* 24- PCLT */
+ h->typeface_lsb = 0; /* wrong *//* 25- PCLT */
+ h->typeface_msb = 0; /* wrong *//* 26- PCLT */
+ h->serifStyle = 0; /* wrong *//* 27- PCLT */
+ h->quality = 0; /* wrong *//* 28- 2 if TrueType */
+ h->placement = 0; /* wronfg *//* 29- 0 if TrueType */
+ h->underlinePosition = 0; /* 30- 0 */
+ h->underlineHeight = 0; /* 31- 0 */
+ h->textHeight = 102; /* wrong *//* 32- from OS/2 table in TT font */
+ h->textWidth = 1024; /* wrong *//* 34- OS/2 */
+ h->firstCode = 0; /* 36- set to 0 if unbound */
+ h->lastCode = 255; /* wrong *//* 38- max number of downloadable chars if unbound */
+ h->pitch_ext = 0; /* 40- 0 if TrueType */
+ h->height_ext = 0; /* 41- 0 if TrueType */
+ h->capHeight = 1024; /* wrong *//* 42- PCLT */
+ h->fontNumber = d->font_id; /* 44- PCLT */
+ h->fontName[0] = 0; /* wrong *//* 48- PCLT */
+ h->scaleFactor = 1024; /* wrong *//* 64- head:unitsPerEm */
+ h->masterUnderlinePosition = 0; /* wrong *//* 66- post table, or -20% of em */
+ h->masterUnderlineHeight = 0; /* wrong *//* 68- post table, or 5% of em */
+ h->fontScalingTechnology = 1; /* 70- 1=TrueType; 0=Intellifont */
+ h->variety = 0; /* 71- 0 if TrueType */
+ memset((LPUB8) h + PCLETTOFONTHDRSIZE, 0, 8); /* work around bug in PCLswapHdr : it wants format 10 */
+ /* fixme : Most fields above being marked "wrong" look unused by UFST.
+ Need to check for sure.
+ */
+ /* fixme : This code assumes 1-byte alignment for PCLETTO_FHDR structure.
+ Use PACK_* macros to improve.
+ */
+ PCLswapHdr(FSA(UB8 *) h, 0);
+ if (ff->is_type1) {
+ LPUB8 fontdata = (LPUB8) h + PCLETTOFONTHDRSIZE;
+
+ pack_pseo_fhdr(r, ff, fontdata);
+ }
+ else {
+ LPUB8 pseg = (LPUB8) h + PCLETTOFONTHDRSIZE;
+ LPUB8 fontdata = pseg + 6 /* (use_XL_format ? 6 : 4) */ ;
+
+
+ pseg[0] = 'G';
+ pseg[1] = 'T';
+
+ *((ulong *) (&(pseg[2]))) = SWAPL(tt_size);
+
+ d->tt_font_body_offset = (LPUB8) fontdata - (LPUB8) d;
+ if (ff->serialize_tt_font(ff, fontdata, tt_size))
+ return gs_error_invalidfont;
+ *(fontdata + tt_size) = 255;
+ *(fontdata + tt_size + 1) = 255;
+ *(fontdata + tt_size + 2) = 0;
+ *(fontdata + tt_size + 3) = 0;
+ *(fontdata + tt_size + 4) = 0;
+ *(fontdata + tt_size + 5) = 0; /* checksum */
+ }
+ }
+ *return_data = d;
+ return 0;
+}
+
+static void
+prepare_typeface(fapi_ufst_server * r, ufst_common_font_data * d)
+{
+ r->fc.format = d->font_type;
+ r->fc.font_id = d->font_id;
+ r->fc.font_hdr = (UB8 *) (d + 1);
+ if (!d->is_disk_font)
+ r->fc.format |= FC_EXTERN_TYPE;
+}
+
+static gs_fapi_retcode
+get_scaled_font_aux(gs_fapi_server * server, gs_fapi_font * ff,
+ const gs_fapi_font_scale * font_scale,
+ const char *xlatmap, gs_fapi_descendant_code dc)
+{
+ fapi_ufst_server *r = If_to_I(server);
+ FONTCONTEXT *fc = &r->fc;
+
+ /* Note : UFST doesn't provide handles for opened fonts,
+ but copies FONTCONTEXT to IFSTATE and caches it.
+ Due to this the plugin cannot provide a handle for the font.
+ This assumes that only one font context is active at a moment.
+ */
+ ufst_common_font_data *d = (ufst_common_font_data *) ff->server_font_data;
+ const double scale = F_ONE;
+ double hx, hy;
+ gs_fapi_retcode code = 0;
+ bool use_XL_format = ff->is_mtx_skipped;
+ int world_scale = 0;
+ FONT_METRICS fm;
+
+ FSA_FROM_SERVER;
+
+ if (ff->is_cid && ff->is_type1 && ff->font_file_path == NULL &&
+ (dc == gs_fapi_toplevel_begin || dc == gs_fapi_toplevel_complete)) {
+ /* Don't need any processing for the top level font of a non-disk CIDFontType 0.
+ See comment in FAPI_prepare_font.
+ Will do with its subfonts individually.
+ */
+ return 0;
+ }
+
+ ff->need_decrypt = 1;
+ if (d == 0) {
+ if ((code = ufst_make_font_data(r, ff->font_file_path, ff, &d)) != 0)
+ return code;
+ ff->server_font_data = d;
+ prepare_typeface(r, d);
+ if (ff->font_file_path != NULL || ff->is_type1) /* such fonts don't use RAW_GLYPH */
+ choose_decoding(r, d, xlatmap);
+ }
+ else {
+ prepare_typeface(r, d);
+ if (ff->font_file_path != NULL || ff->is_type1) /* such fonts don't use RAW_GLYPH */
+ choose_decoding(r, d, xlatmap);
+ }
+
+ r->tran_xx = font_scale->matrix[0] / scale, r->tran_xy =
+ font_scale->matrix[1] / scale;
+ r->tran_yx = font_scale->matrix[2] / scale, r->tran_yy =
+ font_scale->matrix[3] / scale;
+ hx = hypot(r->tran_xx, r->tran_xy), hy = hypot(r->tran_yx, r->tran_yy);
+ fc->xspot = F_ONE;
+ fc->yspot = F_ONE;
+ fc->fc_type = FC_MAT2_TYPE;
+
+ fc->s.m2.m[0] = (int)((double)font_scale->matrix[0] / hx + 0.5);
+ fc->s.m2.m[1] = (int)((double)font_scale->matrix[1] / hx + 0.5);
+ fc->s.m2.m[2] = (int)((double)font_scale->matrix[2] / hy + 0.5);
+ fc->s.m2.m[3] = (int)((double)font_scale->matrix[3] / hy + 0.5);
+ fc->s.m2.matrix_scale = 16;
+ fc->s.m2.xworld_res = font_scale->HWResolution[0] >> 16;
+ fc->s.m2.yworld_res = font_scale->HWResolution[1] >> 16;
+
+ if ((hx > 0 && hy > 0) && (hx < 1.5 || hy < 1.5)) {
+ world_scale = 8;
+ hx *= 256;
+ hy *= 256;
+
+ while (hx < 1.5 || hy < 1.5) {
+ world_scale += 8;
+ hx *= 256;
+ hy *= 256;
+ }
+ }
+ fc->s.m2.world_scale = world_scale;
+ fc->s.m2.point_size = (int)(hy * 8 + 0.5); /* 1/8ths of pixels */
+ fc->s.m2.set_size = (int)(hx * 8 + 0.5);
+ fc->numXsubpixels = font_scale->subpixels[0];
+ fc->numYsubpixels = font_scale->subpixels[1];
+ fc->alignment = (font_scale->align_to_pixels ? GAGG : GAPP);
+ fc->ExtndFlags = 0;
+ if (d->font_type == FC_TT_TYPE)
+ fc->ssnum = USER_CMAP;
+ else if (d->font_type == FC_FCO_TYPE) {
+ fc->ssnum = UNICODE;
+ }
+ else if (d->font_type == FC_PST1_TYPE) {
+ fc->ssnum = T1ENCODING;
+ }
+
+ if (d->font_type != FC_TT_TYPE && d->font_type != FC_FCO_TYPE) {
+ fc->ExtndFlags = EF_NOSYMSETMAP;
+ }
+ /* always use format 16 for TrueType fonts */
+ if (d->font_type == FC_TT_TYPE) {
+ fc->ExtndFlags |= EF_FORMAT16_TYPE;
+ }
+ fc->ExtndFlags |= EF_SUBSTHOLLOWBOX_TYPE;
+ fc->format |= FC_NON_Z_WIND; /* NON_ZERO Winding required for TrueType */
+ fc->format |= FC_INCHES_TYPE; /* output in units per inch */
+ fc->user_platID = d->platformId;
+ fc->user_specID = d->specificId;
+ if (use_XL_format)
+ fc->ExtndFlags |= EF_XLFONT_TYPE;
+ if (ff->is_vertical)
+ fc->ExtndFlags |= EF_UFSTVERT_TYPE;
+ fc->dl_ssnum = (d->specificId << 4) | d->platformId;
+ fc->ttc_index = ff->subfont;
+ r->callback_error = 0;
+
+ code = CGIFfont(FSA fc);
+ if (r->callback_error != 0)
+ return r->callback_error;
+
+ if (d->font_type == FC_FCO_TYPE) {
+ code = CGIFfont_metrics(&fm);
+ if (r->callback_error != 0)
+ return r->callback_error;
+ }
+ if (code != 0) {
+ code = gs_error_invalidfont;
+ }
+
+ if (code >= 0 && d->font_type == FC_FCO_TYPE && ff->font_file_path) {
+ UW16 bufsize = 0;
+ LPSB8 buffer = NULL;
+
+ code =
+ CGIFfco_Access(FSA ff->font_file_path, ff->subfont, TFATRIB_KEY,
+ &bufsize, NULL);
+ if (code == 0) {
+ if (bufsize > d->ufstfontinfosize) {
+ gs_free(r->mem, d->ufstfontinfo, 0, 0, "ufst font info data");
+
+ buffer = gs_malloc(r->mem, bufsize, 1, "ufst font info data");
+ if (buffer == NULL) {
+ code = gs_error_VMerror;
+ }
+ }
+ else {
+ buffer = (LPSB8) d->ufstfontinfo;
+ bufsize = d->ufstfontinfosize;
+ }
+ if (buffer) {
+ (void)CGIFfco_Access(FSA ff->font_file_path, ff->subfont,
+ TFATRIB_KEY, &bufsize, buffer);
+ d->ufstfontinfo = (TTFONTINFOTYPE *) buffer;
+ d->ufstfontinfosize = bufsize;
+ }
+ }
+ }
+
+ return code;
+}
+
+static gs_fapi_retcode
+get_scaled_font(gs_fapi_server * server, gs_fapi_font * ff,
+ const gs_fapi_font_scale * font_scale, const char *xlatmap,
+ gs_fapi_descendant_code dc)
+{
+ return (get_scaled_font_aux(server, ff, font_scale, xlatmap, dc));
+}
+
+static gs_fapi_retcode
+ufst_get_font_info(gs_fapi_server * server, gs_fapi_font * ff,
+ gs_fapi_font_info item, int index, void *data,
+ int *data_len)
+{
+ gs_fapi_retcode code = 0;
+ ufst_common_font_data *d = (ufst_common_font_data *) ff->server_font_data;
+
+ if (!d || !d->ufstfontinfo)
+ return (gs_error_invalidfont);
+
+ if (code == 0) {
+ switch (item) {
+ case gs_fapi_font_info_name:
+ {
+ LPSB8 pname =
+ ((LPSB8) d->ufstfontinfo) + d->ufstfontinfo->psname;
+ int len = strlen(pname);
+
+ if (data && *data_len >= len + 1) {
+ strcpy(data, pname);
+ }
+ *data_len = len + 1;
+ break;
+ }
+
+ case gs_fapi_font_info_uid:
+ if (*data_len >= sizeof(d->ufstfontinfo->pcltFontNumber)) {
+ *((int *)data) = d->ufstfontinfo->pcltFontNumber;
+ }
+ *data_len = sizeof(d->ufstfontinfo->pcltFontNumber);
+ break;
+
+ case gs_fapi_font_info_pitch:
+ if (*data_len >= sizeof(d->ufstfontinfo->spaceBand)) {
+ *((int *)data) = d->ufstfontinfo->spaceBand;
+ }
+ *data_len = sizeof(d->ufstfontinfo->spaceBand);
+ break;
+
+ case gs_fapi_font_info_design_units:
+ if (*data_len >= sizeof(d->ufstfontinfo->scaleFactor)) {
+ *((int *)data) = d->ufstfontinfo->scaleFactor;
+ }
+ *data_len = sizeof(d->ufstfontinfo->scaleFactor);
+ break;
+
+ default:
+ code = gs_error_invalidaccess;
+ break;
+ }
+ }
+ return (code);
+}
+
+static gs_fapi_retcode
+get_decodingID(gs_fapi_server * server, gs_fapi_font * ff,
+ const char **decodingID_result)
+{
+ fapi_ufst_server *r = If_to_I(server);
+ ufst_common_font_data *d = (ufst_common_font_data *) r->fc.font_hdr - 1;
+
+ *decodingID_result = d->decodingID;
+ return 0;
+}
+
+static gs_fapi_retcode
+get_font_bbox(gs_fapi_server * server, gs_fapi_font * ff, int BBox[4])
+{
+ fapi_ufst_server *r = If_to_I(server);
+ SW16 VLCPower = 0;
+ int code;
+
+ FSA_FROM_SERVER;
+
+ if ((code = CGIFbound_box(FSA BBox, &VLCPower)) < 0)
+ return code;
+ /* UFST expands bbox for internal needs, and retrives the expanded bbox.
+ We believe it's bug in UFST.
+ Now we collapse it back to the correct size :
+ */
+ BBox[0] += 2;
+ BBox[1] += 2;
+ BBox[2] -= 2;
+ BBox[3] -= 2;
+ BBox[0] >>= VLCPower;
+ BBox[1] >>= VLCPower;
+ BBox[2] >>= VLCPower;
+ BBox[3] >>= VLCPower;
+ return 0;
+}
+
+static gs_fapi_retcode
+get_font_proportional_feature(gs_fapi_server * server, gs_fapi_font * ff,
+ bool * bProportional)
+{
+ fapi_ufst_server *r = If_to_I(server);
+
+ FSA_FROM_SERVER;
+
+ *bProportional = FALSE;
+ if (ff->font_file_path == NULL || ff->is_type1)
+ return 0;
+#if TT_ROM || TT_DISK
+ {
+ UB8 buf[74];
+ UL32 length = sizeof(buf);
+
+ if (CGIFtt_query
+ (FSA(UB8 *) ff->font_file_path, *(UL32 *) "OS/2",
+ (UW16) ff->subfont, &length, buf) != 0)
+ return 0; /* No OS/2 table - no chance to get the info. Use default == FALSE. */
+ *bProportional = (buf[35] == 9);
+ }
+#endif
+ return 0;
+}
+
+static inline void
+make_asciiz_char_name(char *buf, int buf_length, gs_fapi_char_ref * c)
+{
+ int len = min(buf_length - 1, c->char_name_length);
+
+ memcpy(buf, c->char_name, len);
+ buf[len] = 0;
+}
+
+#define MAX_CHAR_NAME_LENGTH 30
+
+static gs_fapi_retcode
+can_retrieve_char_by_name(gs_fapi_server * server, gs_fapi_font * ff,
+ gs_fapi_char_ref * c, int *result)
+{
+ fapi_ufst_server *r = If_to_I(server);
+
+ FSA_FROM_SERVER;
+
+ *result = 0;
+
+ switch (r->fc.format & FC_FONTTYPE_MASK) {
+ case FC_PST1_TYPE:
+ *result = 1;
+ break;
+ case FC_TT_TYPE:
+ break;
+ }
+
+ return 0;
+}
+
+static gs_fapi_retcode
+can_replace_metrics(gs_fapi_server * server, gs_fapi_font * ff,
+ gs_fapi_char_ref * c, int *result)
+{
+ *result = (!ff->is_type1 && ff->font_file_path == NULL &&
+ c->metrics_scale == 0
+ && c->metrics_type == gs_fapi_metrics_replace);
+ return 0;
+}
+
+static void
+release_glyphs(fapi_ufst_server * r, ufst_common_font_data * d)
+{
+ if (d) {
+ while (d->glyphs != 0) {
+ pcleo_glyph_list_elem *e = d->glyphs;
+
+ d->glyphs = e->next;
+ gs_free(r->mem, e, 0, 0, "PCLEO char");
+ }
+ d->glyphs = NULL;
+ }
+}
+
+static gs_fapi_retcode
+ufst_get_fontmatrix(gs_fapi_server * I, gs_matrix * m)
+{
+ fapi_ufst_server *r = If_to_I(I);
+ ufst_common_font_data *d =
+ (ufst_common_font_data *) I->ff.server_font_data;
+ gs_fapi_retcode code = 0;
+ bool is_FCO_PSfont = false;
+
+ if (I->ff.is_type1 && I->ff.font_file_path) {
+ if (d == 0) {
+ if ((code =
+ ufst_make_font_data(r, I->ff.font_file_path, &(I->ff),
+ &d)) != 0)
+ return (code);
+ I->ff.server_font_data = d;
+ prepare_typeface(r, d);
+ }
+ if (d) {
+ is_FCO_PSfont = (d->font_type & FC_FCO_TYPE) > 0;
+ }
+ }
+
+ /* There are PS jobs that rely on the standard fonts having
+ * a FontMatrix of [0.001 0 0 0.001 0 0], but MT fonts actually
+ * have an identity matrix. We need to compensate here. Other
+ * fonts need an identity matrix returned here, as we apply the
+ * font matrix explicitly in the scale calculation in zfapi.c
+ * Luckily in PS, we "pretend" MT fonts are Type 1, but in
+ * PCL they have their own font type.
+ */
+ if (is_FCO_PSfont) {
+ m->xx = 0.001;
+ m->xy = 0.0;
+ m->yx = 0.0;
+ m->yy = 0.001;
+ m->tx = 0.0;
+ m->ty = 0.0;
+ }
+ else {
+ m->xx = 1.0;
+ m->xy = 0.0;
+ m->yx = 0.0;
+ m->yy = 1.0;
+ m->tx = 0.0;
+ m->ty = 0.0;
+ }
+
+#if 0
+ gs_matrix *base_font_matrix = &I->initial_FontMatrix;
+
+ m->xx = I->initial_FontMatrix.xx;
+ m->xy = I->initial_FontMatrix.xy;
+ m->yx = I->initial_FontMatrix.yx;
+ m->yy = I->initial_FontMatrix.yy;
+ m->tx = I->initial_FontMatrix.tx;
+ m->ty = I->initial_FontMatrix.ty;
+#endif
+ return (code);
+
+}
+
+static int
+export_outline(fapi_ufst_server * r, PIFOUTLINE pol, gs_fapi_path * p)
+{
+ POUTLINE_CHAR outchar;
+ SW16 num_contrs, num_segmts;
+ LPSB8 segment;
+ PINTRVECTOR points;
+ SW16 i, j;
+
+ if (pol == NULL)
+ return 0;
+ p->shift += r->If.frac_shift + pol->VLCpower;
+ outchar = &pol->ol;
+ num_contrs = outchar->num_loops;
+ for (i = 0; i < num_contrs; i++) {
+ num_segmts = outchar->loop[i].num_segmts;
+ segment =
+ (LPSB8) ((LPSB8) (outchar->loop) + outchar->loop[i].segmt_offset);
+ points =
+ (PINTRVECTOR) ((LPSB8) (outchar->loop) +
+ outchar->loop[i].coord_offset);
+ for (j = 0; j < num_segmts; j++) {
+
+ if (*segment == 0x00) {
+ if ((p->gs_error =
+ p->moveto(p, ((int64_t) points->x) << 16,
+ ((int64_t) points->y) << 16)) != 0)
+ return p->gs_error;
+ points++;
+ }
+ else if (*segment == 0x01) {
+ if ((p->gs_error =
+ p->lineto(p, ((int64_t) points->x) << 16,
+ ((int64_t) points->y) << 16)) != 0)
+ return p->gs_error;
+ points++;
+ }
+ else if (*segment == 0x02) {
+ points += 2;
+ return gs_error_invalidfont; /* This must not happen */
+ }
+ else if (*segment == 0x03) {
+ if ((p->gs_error =
+ p->curveto(p, ((int64_t) points[0].x) << 16,
+ ((int64_t) points[0].y) << 16,
+ ((int64_t) points[1].x) << 16,
+ ((int64_t) points[1].y) << 16,
+ ((int64_t) points[2].x) << 16,
+ ((int64_t) points[2].y) << 16) < 0))
+ return p->gs_error;
+ points += 3;
+ }
+ else
+ return gs_error_invalidfont; /* This must not happen */
+ segment++;
+ }
+ }
+ return 0;
+}
+
+static inline void
+set_metrics(fapi_ufst_server * r, gs_fapi_metrics * metrics,
+ SL32 design_bbox[4], SW16 design_escapement[2], SW16 du_emx,
+ SW16 du_emy)
+{
+
+ metrics->escapement = design_escapement[0];
+ metrics->v_escapement = design_escapement[1];
+ metrics->em_x = du_emx;
+ metrics->em_y = du_emy;
+ metrics->bbox_x0 = design_bbox[0];
+ metrics->bbox_y0 = design_bbox[1];
+ metrics->bbox_x1 = design_bbox[2];
+ metrics->bbox_y1 = design_bbox[3];
+}
+
+static gs_fapi_retcode
+get_char(fapi_ufst_server * r, gs_fapi_font * ff, gs_fapi_char_ref * c,
+ gs_fapi_path * p, gs_fapi_metrics * metrics, UW16 format)
+{
+ UW16 code = 0, code2 = 0;
+ UW16 cc = (UW16) c->char_codes[0];
+ SL32 design_bbox[4];
+ char PSchar_name[MAX_CHAR_NAME_LENGTH];
+ MEM_HANDLE result = NULL;
+ ufst_common_font_data *d = (ufst_common_font_data *) ff->server_font_data;
+ SW16 design_escapement[2];
+ SW16 du_emx, du_emy;
+ gs_string notdef_str;
+ const char *notdef = ".notdef";
+ const char *space = "space";
+ const void *client_char_data = ff->char_data;
+ const int client_char_data_len = ff->char_data_len;
+ int length;
+ FONTCONTEXT *fc = &r->fc;
+
+ FSA_FROM_SERVER;
+
+ design_escapement[0] = design_escapement[1] = 0;
+
+ if (ff->is_type1) {
+ /* If a charstring in a Type 1 has been replaced with a PS procedure
+ * get_glyph will return -1. We can then return char_code + 1 which
+ * tells the FAPI code we might be dealing with a procedure, and to
+ * try executing it as such.
+ */
+ ff->need_decrypt = false;
+ length = ff->get_glyph(ff, c->char_codes[0], NULL, 0);
+ if (length == -1) {
+ return (c->char_codes[0] + 1);
+ }
+ }
+ ff->need_decrypt = true;
+ memset(metrics, 0, sizeof(*metrics));
+ metrics->bbox_x1 = -1;
+
+ if (ff->is_type1 && !ff->is_cid) {
+ int len = min(ff->char_data_len, sizeof(PSchar_name) - 1);
+
+ memcpy(PSchar_name, ff->char_data, len);
+ PSchar_name[len] = 0;
+ }
+ else {
+ make_asciiz_char_name(PSchar_name, sizeof(PSchar_name), c);
+ }
+
+ CGIFchIdptr(FSA & cc, PSchar_name); /* fixme : Likely only FC_PST1_TYPE needs it. */
+ { /* hack : Changing UFST internal data. Change to r->fc doesn't help,
+ because UFST thinks that the "outline/raster" is a property of current font. */
+ pIFS->fcCur.format &= ~FC_OUTPUT_MASK;
+ pIFS->fcCur.format |= format;
+ }
+ r->bRaster = FALSE;
+ r->ff = ff;
+ r->callback_error = 0;
+ r->sb_x = c->sb_x;
+ r->aw_x = c->aw_x;
+ r->metrics_type = c->metrics_type;
+ if (d->font_type == FC_FCO_TYPE
+ && r->fc.ExtndFlags & EF_SUBSTHOLLOWBOX_TYPE) {
+ if (c->char_name != NULL && c->char_name_length == 7
+ && !memcmp(c->char_name, ".notdef", 7)) {
+ /* With EF_SUBSTHOLLOWBOX_TYPE and FCO,
+ UFST paints a hollow box insted .notdef .
+ For Adobe compatibility we substitute a space,
+ because Adobe Type 1 fonts define .notdef as a space . */
+ cc = 32;
+ }
+ }
+#if !UFST_REENTRANT
+ static_server_ptr_for_ufst_callback = r;
+#endif
+ pIFS->gpps = NULL;
+ code = CGIFchar_handle(FSA cc, &result, (SW16) 0);
+
+ if (code == ERR_TT_UNDEFINED_INSTRUCTION) {
+ int savehint = FC_DONTHINTTT(fc);
+dprintf("UFST used\n");
+ fc->ExtndFlags |= EF_TT_NOHINT;
+
+ (void)CGIFfont(FSA fc);
+ code = CGIFchar_handle(FSA cc, &result, (SW16) 0);
+
+ fc->ExtndFlags |= savehint;
+ (void)CGIFfont(FSA fc);
+ }
+ if (result == NULL
+ || (code && code != ERR_fixed_space && code != ERR_bm_buff
+ && code != ERR_bm_too_big)) {
+ /* There is no such char in the font, try the glyph 0 (notdef) : */
+ UW16 c1 = 0, ssnum = pIFS->fcCur.ssnum;
+ int savehint = FC_DONTHINTTT(fc);
+
+ fc->ExtndFlags |= EF_TT_NOHINT;
+ (void)CGIFfont(FSA fc);
+
+ if (d->font_type == FC_FCO_TYPE) {
+ /* EF_SUBSTHOLLOWBOX_TYPE must work against it.
+ Ensure the plugin plug__xi.fco is loaded. */
+ /* fixme : Due to unknown reason EF_SUBSTHOLLOWBOX_TYPE
+ doesn't work for Symbol, Dingbats, Wingdings.
+ hack : render the space character. */
+ c1 = 32;
+ }
+ else {
+ /* hack : Changing UFST internal data - see above. */
+ pIFS->fcCur.ssnum = RAW_GLYPH;
+ }
+ r->callback_error = 0;
+ notdef_str.data = notdef;
+ notdef_str.size = strlen(notdef);
+ ff->char_data = (void *)&notdef_str;
+ ff->char_data_len = 0;
+ CGIFchIdptr(FSA(void *) & c1, (void *)notdef);
+
+ code2 = CGIFchar_handle(FSA c1, &result, (SW16) 0);
+ if (code2 && code2 != ERR_fixed_space && code2 != ERR_bm_buff
+ && code2 != ERR_bm_too_big) {
+
+ notdef_str.data = space;
+ notdef_str.size = strlen(space);
+ ff->char_data = (void *)&notdef_str;
+ ff->char_data_len = 0;
+
+ CGIFchIdptr(FSA(void *) & c1, (void *)space);
+
+ code2 = CGIFchar_handle(FSA c1, &result, (SW16) 0);
+ }
+ if (!code2 || code2 == ERR_fixed_space) {
+ code = code2;
+ }
+ fc->ExtndFlags |= savehint;
+ (void)CGIFfont(FSA fc);
+ pIFS->fcCur.ssnum = ssnum;
+ }
+ ff->char_data = client_char_data;
+ ff->char_data_len = client_char_data_len;
+
+#if !UFST_REENTRANT
+ static_server_ptr_for_ufst_callback = 0;
+#endif
+ r->ff = 0;
+ release_glyphs(r, (ufst_common_font_data *) ff->server_font_data);
+ if (code != ERR_fixed_space && code != 0)
+ return code;
+ if (r->callback_error != 0)
+ return r->callback_error;
+ if (format == FC_BITMAP_TYPE) {
+ IFBITMAP *pbm = (IFBITMAP *) result;
+
+ du_emx = pbm->du_emx;
+ du_emy = pbm->du_emy;
+ r->char_data = pbm;
+ r->bRaster = TRUE;
+
+ design_escapement[0] = pbm->escapement;
+
+#if UFST_VERSION_MAJOR >= 6 && UFST_VERSION_MINOR >= 2
+
+ design_bbox[0] = pIFS->glyphMetricsDU.bbox.BBox[0];
+ design_bbox[1] = pIFS->glyphMetricsDU.bbox.BBox[1];
+ design_bbox[2] = pIFS->glyphMetricsDU.bbox.BBox[2];
+ design_bbox[3] = pIFS->glyphMetricsDU.bbox.BBox[3];
+ if (d->font_type != FC_FCO_TYPE) {
+ design_escapement[0] = pIFS->glyphMetricsDU.aw.x;
+ design_escapement[1] = pIFS->glyphMetricsDU.aw.y;
+ }
+#endif
+
+ }
+ else {
+ IFOUTLINE *pol = (IFOUTLINE *) result;
+
+ design_escapement[0] = pol->escapement;
+ du_emx = pol->du_emx;
+ du_emy = pol->du_emy;
+ r->char_data = (IFOUTLINE *) result;
+ }
+#if 1 /* UFST 5.0 */
+ if (USBOUNDBOX && d->font_type == FC_FCO_TYPE) {
+ if (pIFS->USBBOXorigScaleFactor /* fixme : Must we check this ? */
+ && pIFS->USBBOXorigScaleFactor != pIFS->USBBOXscaleFactor) {
+ /* See fco_make_gaso_and_stats in fc_if.c . Debugged with hollow box in Helvetica. */
+ /* Fixme : this looses a precision, an UFST bug has been reported. */
+ int w = pIFS->USBBOXorigScaleFactor / 2;
+
+ design_bbox[0] =
+ pIFS->USBBOXxmin * pIFS->USBBOXscaleFactor /
+ pIFS->USBBOXorigScaleFactor;
+ design_bbox[1] =
+ pIFS->USBBOXymin * pIFS->USBBOXscaleFactor /
+ pIFS->USBBOXorigScaleFactor;
+ design_bbox[2] =
+ (pIFS->USBBOXxmax * pIFS->USBBOXscaleFactor +
+ w) / pIFS->USBBOXorigScaleFactor;
+ design_bbox[3] =
+ (pIFS->USBBOXymax * pIFS->USBBOXscaleFactor +
+ w) / pIFS->USBBOXorigScaleFactor;
+ }
+ else {
+ design_bbox[0] = pIFS->USBBOXxmin;
+ design_bbox[1] = pIFS->USBBOXymin;
+ design_bbox[2] = pIFS->USBBOXxmax;
+ design_bbox[3] = pIFS->USBBOXymax;
+ }
+ }
+ else {
+#if UFST_VERSION_MAJOR >= 6 && UFST_VERSION_MINOR >= 2
+#else
+ /* fixme: UFST 5.0 doesn't provide this data.
+ Stubbing with Em box.
+ Non-FCO fonts may be cropped if a glyph goes outside Em box
+ (or occupy negative coordinates, such as 'y'.).
+ Non-FCO fonts may be uncached if Em box is much bigger than the glyph.
+ */
+ design_bbox[0] = 0;
+ design_bbox[1] = 0;
+ design_bbox[2] = du_emx;
+ design_bbox[3] = du_emy;
+#endif
+ }
+#endif
+ { /* UFST performs a dual rounding of the glyph origin : first
+ the scaled glyph design origin is rounded to pixels with floor(x + 0.5),
+ second the glyph position is rounded to pixels with floor(x + 0.5).
+ Ghostscript rounds with floor(x) due to the pixel-center-inside rule.
+
+ A right way would be to specify the half pixel offset to the glyph
+ origin for the rendering glyph, but UFST has no interface for doing that.
+ Instead that, to prevent a possible cropping while copying a glyph to cache cell,
+ we expand the design bbox in a value of a pixel size.
+ We could not determine the necessary expansion theoretically,
+ and choosen expansion coefficients empirically,
+ which appears equal to 2 pixels.
+
+ fixme: Actually the expansion is the FONTCONTEXT property,
+ so it could be computed at once when the scaled font is created.
+ */
+ const double expansion_x = 2, expansion_y = 2; /* pixels *//* adesso5.pdf */
+ const double XX =
+ r->tran_xx * (r->fc.s.m2.xworld_res >> 16) / 72 / du_emx;
+ const double XY =
+ r->tran_xy * (r->fc.s.m2.yworld_res >> 16) / 72 / du_emy;
+ const double YX =
+ r->tran_yx * (r->fc.s.m2.xworld_res >> 16) / 72 / du_emx;
+ const double YY =
+ r->tran_yy * (r->fc.s.m2.yworld_res >> 16) / 72 / du_emy;
+ const double det = XX * YY - XY * YX;
+ const double deta = det < 0 ? -det : det;
+
+ if (deta > 0.0000000001) {
+ const double xx = YY / det, xy = -XY / det;
+ const double yx = -YX / det, yy = XX / det;
+ const double dx = -(expansion_x * xx + expansion_y * xy);
+ const double dy = -(expansion_x * yx + expansion_y * yy);
+ const SL32 dxa = (SL32) ((dx < 0 ? -dx : dx) + 0.5);
+ const SL32 dya = (SL32) ((dy < 0 ? -dy : dy) + 0.5);
+
+ design_bbox[0] -= dxa;
+ design_bbox[1] -= dya;
+ design_bbox[2] += dxa;
+ design_bbox[3] += dya;
+ }
+ }
+ set_metrics(r, metrics, design_bbox, design_escapement, du_emx, du_emy);
+ if (code == ERR_fixed_space)
+ release_char_data_inline(r);
+ return 0;
+}
+
+static gs_fapi_retcode
+get_char_outline_metrics(gs_fapi_server * server, gs_fapi_font * ff,
+ gs_fapi_char_ref * c, gs_fapi_metrics * metrics)
+{
+ fapi_ufst_server *r = If_to_I(server);
+
+ release_char_data_inline(r);
+ return get_char(r, ff, c, NULL, metrics, FC_CUBIC_TYPE);
+ /* UFST cannot render enough metrics information without generating raster or outline.
+ r->char_data keeps an outline after calling this function.
+ */
+}
+
+static gs_fapi_retcode
+get_char_outline(gs_fapi_server * server, gs_fapi_path * p)
+{
+ fapi_ufst_server *r = If_to_I(server);
+
+ return export_outline(r, (IFOUTLINE *) r->char_data, p);
+}
+
+static gs_fapi_retcode
+get_char_raster_metrics(gs_fapi_server * server, gs_fapi_font * ff,
+ gs_fapi_char_ref * c, gs_fapi_metrics * metrics)
+{
+ fapi_ufst_server *r = If_to_I(server);
+ int code;
+
+ release_char_data_inline(r);
+ code = get_char(r, ff, c, NULL, metrics, FC_BITMAP_TYPE);
+ if (code == ERR_bm_buff || code == ERR_bm_too_big) /* Too big character ? */
+ return (gs_error_VMerror);
+ return code;
+ /* UFST cannot render enough metrics information without generating raster or outline.
+ r->char_data keeps a raster after calling this function.
+ */
+}
+
+static gs_fapi_retcode
+get_char_width(gs_fapi_server * server, gs_fapi_font * ff,
+ gs_fapi_char_ref * c, gs_fapi_metrics * metrics)
+{
+ fapi_ufst_server *r = If_to_I(server);
+ int code;
+
+ release_char_data_inline(r);
+ code =
+ get_char(r, ff, c, NULL, metrics,
+ server->use_outline ? FC_CUBIC_TYPE : FC_BITMAP_TYPE);
+ if (code == ERR_bm_buff || code == ERR_bm_too_big) /* Too big character ? */
+ return (gs_error_VMerror);
+ return code;
+ /* UFST cannot render enough metrics information without generating raster or outline.
+ r->char_data keeps a raster after calling this function.
+ */
+}
+
+
+static gs_fapi_retcode
+get_char_raster(gs_fapi_server * server, gs_fapi_raster * rast)
+{
+ fapi_ufst_server *r = If_to_I(server);
+
+ if (!r->bRaster)
+ return gs_error_limitcheck;
+ else if (r->char_data == NULL) {
+ rast->height = rast->width = rast->line_step = 0;
+ rast->p = 0;
+ }
+ else {
+ IFBITMAP *pbm = (IFBITMAP *) r->char_data;
+
+ rast->p = pbm->bm;
+ rast->height = pbm->top_indent + pbm->black_depth;
+ rast->width = pbm->left_indent + pbm->black_width;
+ rast->line_step = pbm->width;
+ rast->left_indent = pbm->left_indent;
+ rast->top_indent = pbm->top_indent;
+ rast->black_width = pbm->black_width;
+ rast->black_height = pbm->black_depth;
+ if (rast->width != 0) {
+ rast->orig_x = pbm->xorigin;
+ rast->orig_y = pbm->yorigin;
+ }
+ else
+ rast->orig_x = rast->orig_y = 0;
+ }
+ return 0;
+}
+
+static gs_fapi_retcode
+release_char_data(gs_fapi_server * server)
+{
+ fapi_ufst_server *r = If_to_I(server);
+
+ release_char_data_inline(r);
+ return 0;
+}
+
+static void
+release_fco(fapi_ufst_server * r, SW16 fcHandle)
+{
+ fco_list_elem **e;
+
+ if (gx_UFST_find_static_fco_handle(fcHandle) != NULL)
+ return;
+ for (e = &r->fco_list; *e != 0;)
+ if ((*e)->fcHandle == fcHandle && (--(*e)->open_count) == 0) {
+ fco_list_elem *ee = *e;
+
+ FSA_FROM_SERVER;
+
+ *e = ee->next;
+ CGIFfco_Close(FSA ee->fcHandle);
+ gs_free(r->mem, ee->file_path, 0, 0, "fco_file_path");
+ gs_free(r->mem, ee, 0, 0, "fco_list_elem");
+ }
+ else
+ e = &(*e)->next;
+}
+
+static gs_fapi_retcode
+FAPIU_release_typeface(gs_fapi_server * server, void *font_data)
+{
+ fapi_ufst_server *r = If_to_I(server);
+ ufst_common_font_data *d;
+ gs_fapi_retcode code = 0;
+
+ FSA_FROM_SERVER;
+
+ release_char_data_inline(r);
+ if (font_data == 0)
+ return 0;
+ d = (ufst_common_font_data *) font_data;
+ if (d->ufstfontinfo) {
+ gs_free(r->mem, d->ufstfontinfo, 0, 0, "ufst font data");
+ d->ufstfontinfo = NULL;
+ }
+ prepare_typeface(r, d);
+#if 1
+ if (d->is_disk_font)
+ code = CGIFhdr_font_purge(FSA & r->fc);
+ else
+ code = CGIFfont_purge(FSA & r->fc);
+#endif
+
+ release_glyphs(r, d);
+ release_fco(r, (SW16) (d->font_id >> 16));
+ gs_free(r->mem, font_data, 0, 0, "ufst font data");
+ return code;
+}
+
+static gs_fapi_retcode
+check_cmap_for_GID(gs_fapi_server * server, uint * index)
+{
+ return 0;
+}
+
+/* --------------------- The plugin definition : ------------------------- */
+
+static void gs_fapi_ufst_destroy(gs_fapi_server ** server);
+
+static const gs_fapi_server_descriptor ufst_descriptor = {
+ "FAPI",
+ "UFST",
+ gs_fapi_ufst_destroy
+};
+
+static const gs_fapi_server ufstserver = {
+ {&ufst_descriptor},
+ NULL, /* client_ctx_p */
+ 16, /* frac_shift */
+ {gs_no_id},
+ {0},
+ 0,
+ false,
+ {1, 0, 0, 1, 0, 0},
+ ensure_open,
+ get_scaled_font,
+ get_decodingID,
+ get_font_bbox,
+ get_font_proportional_feature,
+ can_retrieve_char_by_name,
+ can_replace_metrics,
+ NULL, /* can_simulate_style */
+ ufst_get_fontmatrix,
+ get_char_width,
+ get_char_raster_metrics,
+ get_char_raster,
+ get_char_outline_metrics,
+ get_char_outline,
+ release_char_data,
+ FAPIU_release_typeface,
+ check_cmap_for_GID,
+ ufst_get_font_info
+};
+
+int gs_fapi_ufst_init(gs_memory_t * mem, gs_fapi_server ** server);
+
+int
+gs_fapi_ufst_init(gs_memory_t * mem, gs_fapi_server ** server)
+{
+ fapi_ufst_server *serv;
+ int code = 0;
+ gs_memory_t *cmem = NULL;
+
+ code = gs_memory_chunk_wrap(&(cmem), mem);
+ if (code != 0) {
+ return (code);
+ }
+
+ serv =
+ (fapi_ufst_server *) gs_alloc_bytes_immovable(cmem,
+ sizeof
+ (fapi_ufst_server),
+ "fapi_ufst_server");
+ if (serv == 0)
+ return gs_error_Fatal;
+ memset(serv, 0, sizeof(*serv));
+
+ serv->mem = cmem;
+
+ serv->If = ufstserver;
+
+ (*server) = (gs_fapi_server *) serv;
+
+ return 0;
+}
+
+#ifndef UFST_MEMORY_CHECKING
+#define UFST_MEMORY_CHECKING 0
+#endif
+
+#if UFST_MEMORY_CHECKING
+extern unsigned long maxmem;
+#endif
+
+static void
+gs_fapi_ufst_destroy(gs_fapi_server ** server)
+{
+ fapi_ufst_server *r = (fapi_ufst_server *) * server;
+ gs_memory_t *cmem = r->mem;
+
+ FSA_FROM_SERVER;
+
+#if UFST_MEMORY_CHECKING
+ dmprintf1(r->mem, "UFST used %Lf kb\n", ((long double)maxmem) / 1024);
+#endif
+
+#if 0 /* Disabled against a reentrancy problem
+ in a single language build for host-based applications. */
+ gx_set_UFST_Callbacks(NULL, NULL, NULL);
+#endif
+
+ release_char_data_inline(r);
+ if (r->bInitialized && !r->ufst_is_singleton)
+ gx_UFST_fini();
+
+ if (r->param) {
+ gs_free(r->mem, r->param, 0, 0, "server_params");
+ }
+
+ gs_free(cmem, r, 0, 0, "gs_fapi_ufst_destroy: fapi_ufst_server");
+
+ gs_memory_chunk_release(cmem);
+
+ (*server) = NULL;
+}
diff --git a/gs/base/gconf.c b/gs/base/gconf.c
index 4f4724da6..36e603ef5 100644
--- a/gs/base/gconf.c
+++ b/gs/base/gconf.c
@@ -24,6 +24,7 @@
#include "gxiodev.h"
#include "gxiparam.h"
#include "gxcomp.h"
+#include "gxfapi.h"
/*
* The makefile generates the file gconfig.h, which consists of
@@ -185,6 +186,26 @@ gs_lib_device_list(const gx_device * const **plist,
return i;
}
+/* Font API support */
+#define fapi_(func) extern fapi_init_func(func);
+#include "gconf.h"
+#undef fapi_
+
+gs_fapi_server_init_func gs_fapi_server_inits[] = {
+#define fapi_(init_func) init_func,
+#include "gconf.h"
+#undef fapi_
+ NULL
+};
+
+extern_gs_get_fapi_server_inits();
+
+const gs_fapi_server_init_func *
+gs_get_fapi_server_inits(void)
+{
+ return(gs_fapi_server_inits);
+}
+
#ifdef GS_DEVS_SHARED
void
gs_lib_register_device(const gx_device *dev)
diff --git a/gs/base/genconf.c b/gs/base/genconf.c
index b1e098524..8b2347b91 100644
--- a/gs/base/genconf.c
+++ b/gs/base/genconf.c
@@ -791,6 +791,8 @@ pre: sprintf(templat, pat, pconf->name_prefix);
break;
} else if (IS_CAT("functiontype")) {
pat = "function_type_(%%s,%sbuild_function_%%s)";
+ } else if (IS_CAT("fapi")) {
+ pat = "fapi_(%s%%s_init)";
} else
goto err;
goto pre;
diff --git a/gs/base/gscdefs.h b/gs/base/gscdefs.h
index 42cdc3b2c..c9838658e 100644
--- a/gs/base/gscdefs.h
+++ b/gs/base/gscdefs.h
@@ -76,4 +76,7 @@ extern const unsigned gx_io_device_table_count;
#define extern_gs_find_compositor() \
const gs_composite_type_t * gs_find_compositor(int comp_id)
+#define extern_gs_get_fapi_server_inits() \
+ const gs_fapi_server_init_func * gs_get_fapi_server_inits(void)
+
#endif /* gscdefs_INCLUDED */
diff --git a/gs/base/gsinit.c b/gs/base/gsinit.c
index 2c223d384..b7dfe0674 100644
--- a/gs/base/gsinit.c
+++ b/gs/base/gsinit.c
@@ -23,6 +23,7 @@
#include "gsmalloc.h"
#include "gp.h"
#include "gslib.h" /* interface definition */
+#include "gxfapi.h"
#ifdef PACIFY_VALGRIND
#include <valgrind/helgrind.h>
@@ -66,6 +67,8 @@ gs_lib_init1(gs_memory_t * mem)
void
gs_lib_finit(int exit_status, int code, gs_memory_t *mem)
{
+ gs_fapi_finit (mem);
+
/* Do platform-specific cleanup. */
gp_exit(exit_status, code);
diff --git a/gs/base/gslibctx.h b/gs/base/gslibctx.h
index 7515932e1..b37b2db66 100644
--- a/gs/base/gslibctx.h
+++ b/gs/base/gslibctx.h
@@ -23,6 +23,11 @@
typedef struct name_table_s *name_table_ptr;
+#ifndef gs_fapi_server_DEFINED
+#define gs_fapi_server_DEFINED
+typedef struct gs_fapi_server_s gs_fapi_server;
+#endif
+
#ifndef gs_font_dir_DEFINED
# define gs_font_dir_DEFINED
typedef struct gs_font_dir_s gs_font_dir;
@@ -74,6 +79,7 @@ typedef struct gs_lib_ctx_s
char *profiledir; /* Directory used in searching for ICC profiles */
int profiledir_len; /* length of directory name (allows for Unicode) */
void *cms_context; /* Opaque context pointer from underlying CMS in use */
+ gs_fapi_server **fapi_servers;
} gs_lib_ctx_t;
/** initializes and stores itself in the given gs_memory_t pointer.
diff --git a/gs/base/gxfapi.c b/gs/base/gxfapi.c
new file mode 100644
index 000000000..74e346ef6
--- /dev/null
+++ b/gs/base/gxfapi.c
@@ -0,0 +1,1951 @@
+/* Copyright (C) 2001-2012 Artifex Software, Inc.
+ All Rights Reserved.
+
+ This software is provided AS-IS with no warranty, either express or
+ implied.
+
+ This software is distributed under license and may not be copied, modified
+ or distributed except as expressly authorized under the terms of that
+ license. Refer to licensing information at http://www.artifex.com/
+ or contact Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134,
+ San Rafael, CA 94903, U.S.A., +1(415)492-9861, for further information.
+*/
+
+
+#include "memory_.h"
+
+#include "gsmemory.h"
+#include "gserrors.h"
+#include "gxdevice.h"
+#include "gxfont.h"
+#include "gxfont1.h"
+#include "gxpath.h"
+#include "gxfcache.h"
+#include "gxchrout.h"
+#include "gximask.h"
+#include "gscoord.h"
+#include "gspaint.h"
+#include "gspath.h"
+#include "gzstate.h"
+#include "gxfcid.h"
+#include "gxchar.h" /* for st_gs_show_enum */
+#include "gdebug.h"
+#include "gsimage.h"
+#include "gsbittab.h"
+
+#include "gxfapi.h"
+
+/* lifted from gxchar.c */
+static const uint MAX_TEMP_BITMAP_BITS = 80000;
+
+extern_gs_get_fapi_server_inits();
+
+/* FIXME */
+static int
+gs_fapi_renderer_retcode(gs_memory_t *mem, gs_fapi_server *I,
+ gs_fapi_retcode rc)
+{
+ if (rc == 0)
+ return 0;
+ if (gs_debug_c('1')) {
+ emprintf2(mem,
+ "Error: Font Renderer Plugin ( %s ) return code = %d\n",
+ I->ig.d->subtype, rc);
+ }
+ return rc < 0 ? rc : gs_error_invalidfont;
+}
+
+typedef struct gs_fapi_outline_handler_s
+{
+ struct gx_path_s *path;
+ fixed x0;
+ fixed y0;
+ bool close_path;
+ bool need_close; /* This stuff fixes unclosed paths being rendered with UFST */
+} gs_fapi_outline_handler;
+
+static inline int64_t
+import_shift(int64_t x, int64_t n)
+{
+ return (n > 0 ? (x << n) : (x >> -n));
+}
+
+static inline int
+export_shift(int x, int n)
+{
+ return (n > 0 ? (x >> n) : (x << -n));
+}
+
+static inline int
+fapi_round(double x)
+{
+ return (int)(x + 0.5);
+}
+
+static int
+add_closepath(gs_fapi_path *I)
+{
+ gs_fapi_outline_handler *olh = (gs_fapi_outline_handler *) I->olh;
+
+ if (olh->need_close == true) {
+ olh->need_close = false;
+ I->gs_error = gx_path_close_subpath_notes(olh->path, 0);
+ }
+ return (I->gs_error);
+}
+
+static int
+add_move(gs_fapi_path *I, int64_t x, int64_t y)
+{
+ gs_fapi_outline_handler *olh = (gs_fapi_outline_handler *) I->olh;
+
+ x = import_shift(x, I->shift) + olh->x0;
+ y = -import_shift(y, I->shift) + olh->y0;
+
+ if (x > (int64_t) max_fixed) {
+ x = (int64_t) max_fixed;
+ }
+ else if (x < (int64_t) min_fixed) {
+ x = (int64_t) min_fixed;
+ }
+
+ if (y > (int64_t) max_fixed) {
+ y = (int64_t) max_fixed;
+ }
+ else if (y < (int64_t) min_fixed) {
+ y = (int64_t) min_fixed;
+ }
+
+ if (olh->need_close && olh->close_path)
+ if ((I->gs_error = add_closepath(I)) < 0)
+ return (I->gs_error);
+ olh->need_close = false;
+ I->gs_error = gx_path_add_point(olh->path, (fixed) x, (fixed) y);
+
+ return (I->gs_error);
+}
+
+static int
+add_line(gs_fapi_path *I, int64_t x, int64_t y)
+{
+ gs_fapi_outline_handler *olh = (gs_fapi_outline_handler *) I->olh;
+
+ x = import_shift(x, I->shift) + olh->x0;
+ y = -import_shift(y, I->shift) + olh->y0;
+ if (x > (int64_t) max_fixed) {
+ x = (int64_t) max_fixed;
+ }
+ else if (x < (int64_t) min_fixed) {
+ x = (int64_t) min_fixed;
+ }
+
+ if (y > (int64_t) max_fixed) {
+ y = (int64_t) max_fixed;
+ }
+ else if (y < (int64_t) min_fixed) {
+ y = (int64_t) min_fixed;
+ }
+
+ olh->need_close = true;
+ I->gs_error = gx_path_add_line_notes(olh->path, (fixed) x, (fixed) y, 0);
+ return (I->gs_error);
+}
+
+static int
+add_curve(gs_fapi_path *I, int64_t x0, int64_t y0, int64_t x1, int64_t y1,
+ int64_t x2, int64_t y2)
+{
+ gs_fapi_outline_handler *olh = (gs_fapi_outline_handler *) I->olh;
+
+ x0 = import_shift(x0, I->shift) + olh->x0;
+ y0 = -import_shift(y0, I->shift) + olh->y0;
+ x1 = import_shift(x1, I->shift) + olh->x0;
+ y1 = -import_shift(y1, I->shift) + olh->y0;
+ x2 = import_shift(x2, I->shift) + olh->x0;
+ y2 = -import_shift(y2, I->shift) + olh->y0;
+
+ if (x0 > (int64_t) max_fixed) {
+ x0 = (int64_t) max_fixed;
+ }
+ else if (x0 < (int64_t) min_fixed) {
+ x0 = (int64_t) min_fixed;
+ }
+
+ if (y0 > (int64_t) max_fixed) {
+ y0 = (int64_t) max_fixed;
+ }
+ else if (y0 < (int64_t) min_fixed) {
+ y0 = (int64_t) min_fixed;
+ }
+ if (x1 > (int64_t) max_fixed) {
+ x1 = (int64_t) max_fixed;
+ }
+ else if (x1 < (int64_t) min_fixed) {
+ x1 = (int64_t) min_fixed;
+ }
+
+ if (y1 > (int64_t) max_fixed) {
+ y1 = (int64_t) max_fixed;
+ }
+ else if (y1 < (int64_t) min_fixed) {
+ y1 = (int64_t) min_fixed;
+ }
+ if (x2 > (int64_t) max_fixed) {
+ x2 = (int64_t) max_fixed;
+ }
+ else if (x2 < (int64_t) min_fixed) {
+ x2 = (int64_t) min_fixed;
+ }
+
+ if (y2 > (int64_t) max_fixed) {
+ y2 = (int64_t) max_fixed;
+ }
+ else if (y2 < (int64_t) min_fixed) {
+ y2 = (int64_t) min_fixed;
+ }
+
+ olh->need_close = true;
+ I->gs_error =
+ gx_path_add_curve_notes(olh->path, (fixed) x0, (fixed) y0, (fixed) x1,
+ (fixed) y1, (fixed) x2, (fixed) y2, 0);
+ return (I->gs_error);
+}
+
+static gs_fapi_path path_interface_stub =
+ { NULL, 0, 0, add_move, add_line, add_curve, add_closepath };
+
+int
+gs_fapi_get_metrics_count(gs_fapi_font *ff)
+{
+ if (!ff->is_type1 && ff->is_cid) {
+ gs_font_cid2 *pfcid = (gs_font_cid2 *) ff->client_font_data;
+
+ return (pfcid->cidata.MetricsCount);
+ }
+ return 0;
+}
+
+/*
+ * Lifted from psi/zchar.c
+ * Return true if we only need the width from the rasterizer
+ * and can short-circuit the full rendering of the character,
+ * false if we need the actual character bits. This is only safe if
+ * we know the character is well-behaved, i.e., is not defined by an
+ * arbitrary PostScript procedure.
+ */
+static bool
+fapi_gs_char_show_width_only(const gs_text_enum_t *penum)
+{
+ if (!gs_text_is_width_only(penum))
+ return false;
+ switch (penum->orig_font->FontType) {
+ case ft_encrypted:
+ case ft_encrypted2:
+ case ft_CID_encrypted:
+ case ft_CID_TrueType:
+ case ft_CID_bitmap:
+ case ft_TrueType:
+ return true;
+ default:
+ return false;
+ }
+}
+
+
+
+/* If we're rendering an uncached glyph, we need to know
+ * whether we're filling it with a pattern, and whether
+ * transparency is involved - if so, we have to produce
+ * a path outline, and not a bitmap.
+ */
+static bool
+using_transparency_pattern(gs_state *pgs)
+{
+ gx_device *dev = gs_currentdevice_inline(pgs);
+
+ return ((!gs_color_writes_pure(pgs))
+ && dev->procs.begin_transparency_group != NULL
+ && dev->procs.end_transparency_group != NULL);
+}
+
+static bool
+produce_outline_char(gs_show_enum *penum_s,
+ gs_font_base *pbfont, int abits,
+ gs_log2_scale_point *log2_scale)
+{
+ gs_state *pgs = (gs_state *) penum_s->pis;
+
+ log2_scale->x = 0;
+ log2_scale->y = 0;
+
+ /* Checking both gx_compute_text_oversampling() result, and abits (below) may seem redundant,
+ * and hopefully it will be soon, but for now, gx_compute_text_oversampling() could opt to
+ * "oversample" sufficiently small glyphs (fwiw, I don't think gx_compute_text_oversampling is
+ * working as intended in that respect), regardless of the device's anti-alias setting.
+ * This was an old, partial solution for dropouts in small glyphs.
+ */
+ gx_compute_text_oversampling(penum_s, (gs_font *) pbfont, abits,
+ log2_scale);
+
+ return (pgs->in_charpath || pbfont->PaintType != 0 ||
+ (pgs->in_cachedevice != CACHE_DEVICE_CACHING
+ && using_transparency_pattern((gs_state *) penum_s->pis))
+ || (pgs->in_cachedevice != CACHE_DEVICE_CACHING
+ && (log2_scale->x > 0 || log2_scale->y > 0))
+ || (pgs->in_cachedevice != CACHE_DEVICE_CACHING && abits > 1));
+}
+
+static inline void
+gs_fapi_release_typeface(gs_fapi_server *I, void **server_font_data)
+{
+ I->release_typeface(I, *server_font_data);
+ I->face.font_id = gs_no_id;
+ if (I->ff.server_font_data == *server_font_data)
+ I->ff.server_font_data = 0;
+ *server_font_data = 0;
+}
+
+static int
+notify_remove_font(void *proc_data, void *event_data)
+{ /* gs_font_finalize passes event_data == NULL, so check it here. */
+ if (event_data == NULL) {
+ gs_font_base *pbfont = proc_data;
+ gs_fapi_server *I = pbfont->FAPI;
+
+ if (pbfont->FAPI_font_data != 0) {
+ gs_fapi_release_typeface(I, &pbfont->FAPI_font_data);
+ }
+ }
+ return 0;
+}
+
+int
+gs_fapi_prepare_font(gs_font *pfont, gs_fapi_server *I, int subfont, const char *font_file_path,
+ gs_string *full_font_buf, const char *xlatmap, const char **decodingID)
+{ /* Returns 1 iff BBox is set. */
+ /* Cleans up server's font data if failed. */
+
+ /* A renderer may need to access the top level font's data of
+ * a CIDFontType 0 (FontType 9) font while preparing its subfonts,
+ * and/or perform a completion action with the top level font after
+ * its descendants are prepared. Therefore with such fonts
+ * we first call get_scaled_font(..., FAPI_TOPLEVEL_BEGIN), then
+ * get_scaled_font(..., i) with eash descendant font index i,
+ * and then get_scaled_font(..., FAPI_TOPLEVEL_COMPLETE).
+ * For other fonts we don't call with 'i'.
+ *
+ * Actually server's data for top level CIDFontTYpe 0 non-disk fonts should not be important,
+ * because with non-disk fonts FAPI_do_char never deals with the top-level font,
+ * but does with its descendants individually.
+ * Therefore a recommendation for the renderer is don't build any special
+ * data for the top-level non-disk font of CIDFontType 0, but return immediately
+ * with success code and NULL data pointer.
+ *
+ * get_scaled_font may be called for same font at second time,
+ * so the renderen must check whether the data is already built.
+ */
+ gs_memory_t *mem = pfont->memory;
+ gs_font_base *pbfont = (gs_font_base *)pfont;
+ int code, bbox_set = 0;
+ int BBox[4], scale;
+ double size, size1;
+ gs_fapi_font_scale font_scale =
+ { {1, 0, 0, 1, 0, 0}, {0, 0}, {1, 1}, true };
+
+ scale = 1 << I->frac_shift;
+ size1 = size = 1 / hypot(pbfont->FontMatrix.xx, pbfont->FontMatrix.xy);
+ if (size < 1000)
+ size = 1000;
+ if (size1 > 100)
+ size1 = (int)(size1 + 0.5);
+
+ font_scale.matrix[0] = font_scale.matrix[3] = (int)(size * scale + 0.5);
+
+ font_scale.HWResolution[0] = (fracint) (72 * scale);
+ font_scale.HWResolution[1] = (fracint) (72 * scale);
+
+ /* The interpreter specific parts of the gs_fapi_font should
+ * be assinged by the caller - now do the generic parts.
+ */
+ I->ff.subfont = subfont;
+ I->ff.font_file_path = font_file_path;
+ I->ff.is_type1 = FAPI_ISTYPE1GLYPHDATA(pbfont);
+ I->ff.is_vertical = (pbfont->WMode != 0);
+ I->ff.memory = mem;
+ I->ff.client_ctx_p = I->client_ctx_p;
+ I->ff.client_font_data = pbfont;
+ I->ff.client_font_data2 = pbfont;
+ I->ff.server_font_data = pbfont->FAPI_font_data; /* Possibly pass it from zFAPIpassfont. */
+ if (full_font_buf) {
+ I->ff.full_font_buf = (char *)full_font_buf->data;
+ I->ff.full_font_buf_len = full_font_buf->size;
+ }
+ else {
+ I->ff.full_font_buf = NULL;
+ I->ff.full_font_buf_len = 0;
+ }
+ I->ff.is_cid = FAPI_ISCIDFONT(pbfont);
+ I->ff.is_outline_font = pbfont->PaintType != 0;
+ I->ff.is_mtx_skipped = (gs_fapi_get_metrics_count(&I->ff) != 0);
+ if ((code = gs_fapi_renderer_retcode(mem, I, I->get_scaled_font(I, &I->ff,
+ (const
+ gs_fapi_font_scale
+ *)
+ &font_scale, xlatmap, gs_fapi_toplevel_begin)))
+ < 0)
+ return code;
+ pbfont->FAPI_font_data = I->ff.server_font_data; /* Save it back to GS font. */
+ if (I->ff.server_font_data != 0) {
+ if ((code =
+ gs_fapi_renderer_retcode(mem, I,
+ I->get_font_bbox(I, &I->ff,
+ BBox))) < 0) {
+ gs_fapi_release_typeface(I, &pbfont->FAPI_font_data);
+ return code;
+ }
+ /* Refine FontBBox : */
+ pbfont->FontBBox.p.x = (double)BBox[0] * size1 / size;
+ pbfont->FontBBox.p.y = (double)BBox[1] * size1 / size;
+ pbfont->FontBBox.q.x = (double)BBox[2] * size1 / size;
+ pbfont->FontBBox.q.y = (double)BBox[3] * size1 / size;
+
+ bbox_set = 1;
+ }
+
+ if (xlatmap != NULL && pbfont->FAPI_font_data != NULL) {
+ if ((code =
+ gs_fapi_renderer_retcode(mem, I,
+ I->get_decodingID(I, &I->ff,
+ decodingID))) < 0) {
+ gs_fapi_release_typeface(I, &pbfont->FAPI_font_data);
+ return code;
+ }
+ }
+
+ /* Prepare descendant fonts : */
+ if (font_file_path == NULL && I->ff.is_type1 && I->ff.is_cid) { /* Renderers should expect same condition. */
+ gs_font_cid0 *pfcid = (gs_font_cid0 *) pbfont;
+ gs_font_type1 **FDArray = pfcid->cidata.FDArray;
+ int i, n = pfcid->cidata.FDArray_size;
+
+ I->ff.is_type1 = true;
+ I->ff.is_vertical = false; /* A subfont may be shared with another fonts. */
+ I->ff.memory = mem;
+ I->ff.client_ctx_p = I->client_ctx_p;
+ for (i = 0; i < n; i++) {
+ gs_font_type1 *pbfont1 = FDArray[i];
+ int BBox_temp[4];
+
+ pbfont1->FontBBox = pbfont->FontBBox; /* Inherit FontBBox from the type 9 font. */
+
+ I->ff.client_font_data = pbfont1;
+ pbfont1->FAPI = pbfont->FAPI;
+ I->ff.client_font_data2 = pbfont1;
+ I->ff.server_font_data = pbfont1->FAPI_font_data;
+ I->ff.is_cid = true;
+ I->ff.is_outline_font = pbfont1->PaintType != 0;
+ I->ff.is_mtx_skipped = (gs_fapi_get_metrics_count(&I->ff) != 0);
+ I->ff.subfont = 0;
+ if ((code =
+ gs_fapi_renderer_retcode(mem, I,
+ I->get_scaled_font(I, &I->ff,
+ (const
+ gs_fapi_font_scale
+ *)&font_scale,
+ NULL, i))) < 0) {
+ break;
+ }
+
+ pbfont1->FAPI_font_data = I->ff.server_font_data; /* Save it back to GS font. */
+ /* Try to do something with the descendant font to ensure that it's working : */
+ if ((code =
+ gs_fapi_renderer_retcode(mem, I,
+ I->get_font_bbox(I, &I->ff,
+ BBox_temp))) < 0) {
+ break;
+ }
+ }
+ if (i == n) {
+ code =
+ gs_fapi_renderer_retcode(mem, I,
+ I->get_scaled_font(I, &I->ff,
+ (const
+ gs_fapi_font_scale
+ *)&font_scale,
+ NULL,
+ gs_fapi_toplevel_complete));
+ if (code >= 0)
+ return bbox_set; /* Full success. */
+ }
+ /* Fail, release server's font data : */
+ for (i = 0; i < n; i++) {
+ gs_font_type1 *pbfont1 = FDArray[i];
+
+ if (pbfont1->FAPI_font_data != NULL)
+ gs_fapi_release_typeface(I, &pbfont1->FAPI_font_data);
+ }
+
+ if (pbfont->FAPI_font_data != NULL) {
+ gs_fapi_release_typeface(I, &pbfont->FAPI_font_data);
+ }
+ return_error(gs_error_invalidfont);
+ }
+
+ /* This was an "else", but could elicit a warning from static analysis tools
+ * about the potential for a non-void function without a return value.
+ */
+ code = gs_fapi_renderer_retcode(mem, I, I->get_scaled_font(I, &I->ff,
+ (const
+ gs_fapi_font_scale
+ *)&font_scale,
+ xlatmap,
+ gs_fapi_toplevel_complete));
+ if (code < 0) {
+ gs_fapi_release_typeface(I, &pbfont->FAPI_font_data);
+ return code;
+ }
+ code =
+ gs_notify_register(&pbfont->notify_list, notify_remove_font, pbfont);
+ if (code < 0) {
+ emprintf(mem,
+ "Ignoring gs_notify_register() failure for FAPI font.....");
+ }
+
+ return bbox_set;
+}
+
+
+static int
+outline_char(gs_memory_t *mem, gs_fapi_server *I, int import_shift_v,
+ gs_show_enum *penum_s, struct gx_path_s *path, bool close_path)
+{
+ gs_fapi_path path_interface = path_interface_stub;
+ gs_fapi_outline_handler olh;
+ int code;
+ gs_state *pgs;
+
+ extern_st(st_gs_show_enum);
+ extern_st(st_gs_state);
+
+ if (gs_object_type(penum_s->memory, penum_s) == &st_gs_show_enum) {
+ pgs = penum_s->pgs;
+ }
+ else {
+ if (gs_object_type(penum_s->memory, penum_s->pis) == &st_gs_state) {
+ pgs = (gs_state *) penum_s->pis;
+ }
+ else
+ /* No graphics state, give up... */
+ return_error(gs_error_undefined);
+ }
+ olh.path = path;
+ olh.x0 = pgs->ctm.tx_fixed;
+ olh.y0 = pgs->ctm.ty_fixed;
+ olh.close_path = close_path;
+ olh.need_close = false;
+ path_interface.olh = &olh;
+ path_interface.shift = import_shift_v;
+ if ((code =
+ gs_fapi_renderer_retcode(mem, I,
+ I->get_char_outline(I,
+ &path_interface))) < 0
+ || path_interface.gs_error != 0) {
+ if (path_interface.gs_error != 0)
+ return path_interface.gs_error;
+ else
+ return code;
+ }
+ if (olh.need_close && olh.close_path)
+ if ((code = add_closepath(&path_interface)) < 0)
+ return code;
+ return 0;
+}
+
+static void
+compute_em_scale(const gs_font_base *pbfont, gs_fapi_metrics *metrics,
+ double FontMatrix_div, double *em_scale_x,
+ double *em_scale_y)
+{ /* optimize : move this stuff to FAPI_refine_font */
+ gs_matrix mat;
+ gs_matrix *m = &pbfont->base->orig_FontMatrix;
+ int rounding_x, rounding_y; /* Striking out the 'float' representation error in FontMatrix. */
+ double sx, sy;
+ gs_fapi_server *I = pbfont->FAPI;
+
+ m = &mat;
+#if 1
+ I->get_fontmatrix(I, m);
+#else
+ /* Temporary: replace with a FAPI call to check *if* the library needs a replacement matrix */
+ memset(m, 0x00, sizeof(gs_matrix));
+ m->xx = m->yy = 1.0;
+#endif
+
+ if (m->xx == 0 && m->xy == 0 && m->yx == 0 && m->yy == 0)
+ m = &pbfont->base->FontMatrix;
+ sx = hypot(m->xx, m->xy) * metrics->em_x / FontMatrix_div;
+ sy = hypot(m->yx, m->yy) * metrics->em_y / FontMatrix_div;
+ rounding_x = (int)(0x00800000 / sx);
+ rounding_y = (int)(0x00800000 / sy);
+ *em_scale_x = (int)(sx * rounding_x + 0.5) / (double)rounding_x;
+ *em_scale_y = (int)(sy * rounding_y + 0.5) / (double)rounding_y;
+}
+
+static int
+fapi_copy_mono(gx_device *dev1, gs_fapi_raster *rast, int dx, int dy)
+{
+ int line_step = bitmap_raster(rast->width), code;
+
+ if (rast->line_step >= line_step) {
+ return dev_proc(dev1, copy_mono) (dev1, rast->p, 0, rast->line_step,
+ 0, dx, dy, rast->width,
+ rast->height, 0, 1);
+ }
+ else { /* bitmap data needs to be aligned, make the aligned copy : */
+ byte *p = gs_alloc_byte_array(dev1->memory, rast->height, line_step,
+ "fapi_copy_mono");
+ byte *q = p, *r = rast->p, *pe;
+
+ if (p == NULL)
+ return_error(gs_error_VMerror);
+ pe = p + rast->height * line_step;
+ for (; q < pe; q += line_step, r += rast->line_step)
+ memcpy(q, r, rast->line_step);
+ code =
+ dev_proc(dev1, copy_mono) (dev1, p, 0, line_step, 0, dx, dy,
+ rast->width, rast->height, 0, 1);
+ gs_free_object(dev1->memory, p, "fapi_copy_mono");
+ return code;
+ }
+}
+
+/*
+ * For PCL/PXL pseudo-bolding, we have to "smear" a bitmap horizontally and
+ * vertically by ORing together a rectangle of bits below and to the left of
+ * each output bit. We do this separately for horizontal and vertical
+ * smearing. Eventually, we will replace the current procedure, which takes
+ * time proportional to W * H * (N + log2(N)), with one that is only
+ * proportional to N (but takes W * N additional buffer space).
+ */
+
+/* Allocate the line buffer for bolding. We need 2 + bold scan lines. */
+static byte *
+alloc_bold_lines(gs_memory_t *mem, uint width, int bold, client_name_t cname)
+{ return gs_alloc_byte_array(mem, 2 + bold, bitmap_raster(width + bold),
+ cname);
+}
+
+/* Merge one (aligned) scan line into another, for vertical smearing. */
+static void
+bits_merge(byte *dest, const byte *src, uint nbytes)
+{ long *dp = (long *)dest;
+ const long *sp = (const long *)src;
+ uint n = (nbytes + sizeof(long) - 1) >> arch_log2_sizeof_long;
+
+ for ( ; n >= 4; sp += 4, dp += 4, n -= 4 )
+ dp[0] |= sp[0], dp[1] |= sp[1], dp[2] |= sp[2], dp[3] |= sp[3];
+ for ( ; n; ++sp, ++dp, --n )
+ *dp |= *sp;
+}
+
+/* Smear a scan line horizontally. Note that the output is wider than */
+/* the input by the amount of bolding (smear_width). */
+static void
+bits_smear_horizontally(byte *dest, const byte *src, uint width,
+ uint smear_width)
+{ uint bits_on = 0;
+ const byte *sp = src;
+ uint sbyte = *sp;
+ byte *dp = dest;
+ uint dbyte = sbyte;
+ uint sdmask = 0x80;
+ const byte *zp = src;
+ uint zmask = 0x80;
+ uint i = 0;
+
+ /* Process the first smear_width bits. */
+ { uint stop = min(smear_width, width);
+
+ for ( ; i < stop; ++i ) {
+ if ( sbyte & sdmask )
+ bits_on++;
+ else if ( bits_on )
+ dbyte |= sdmask;
+ if ( (sdmask >>= 1) == 0 )
+ sdmask = 0x80, *dp++ = dbyte, dbyte = sbyte = *++sp;
+ }
+ }
+
+ /* Process all but the last smear_width bits. */
+ { for ( ; i < width; ++i ) {
+ if ( sbyte & sdmask )
+ bits_on++;
+ else if ( bits_on )
+ dbyte |= sdmask;
+ if ( *zp & zmask )
+ --bits_on;
+ if ( (sdmask >>= 1) == 0 ) {
+ sdmask = 0x80;
+ *dp++ = dbyte;
+on: switch ( (dbyte = sbyte = *++sp) ) {
+ case 0xff:
+ if ( width - i <= 8 )
+ break;
+ *dp++ = 0xff;
+ bits_on += 8 -
+ byte_count_bits[(*zp & (zmask - 1)) + (zp[1] & -zmask)];
+ ++zp;
+ i += 8;
+ goto on;
+ case 0:
+ if ( bits_on || width - i <= 8 )
+ break;
+ *dp++ = 0;
+ /* We know there can't be any bits to be zeroed, */
+ /* because bits_on can't go negative. */
+ ++zp;
+ i += 8;
+ goto on;
+ default:
+ ;
+ }
+ }
+ if ( (zmask >>= 1) == 0 )
+ zmask = 0x80, ++zp;
+ }
+ }
+
+ /* Process the last smear_width bits. */
+ /****** WRONG IF width < smear_width ******/
+ { uint stop = width + smear_width;
+
+ for ( ; i < stop; ++i ) {
+ if ( bits_on )
+ dbyte |= sdmask;
+ if ( (sdmask >>= 1) == 0 )
+ sdmask = 0x80, *dp++ = dbyte, dbyte = 0;
+ if ( *zp & zmask )
+ --bits_on;
+ if ( (zmask >>= 1) == 0 )
+ zmask = 0x80, ++zp;
+ }
+ }
+
+ if ( sdmask != 0x80 )
+ *dp = dbyte;
+}
+
+
+static const int frac_pixel_shift = 4;
+
+/* NOTE: fapi_image_uncached_glyph() doesn't check various paramters: it assumes fapi_finish_render_aux()
+ * has done so: if it gets called from another function, the function must either do all the parameter
+ * validation, or fapi_image_uncached_glyph() must be changed to include the validation.
+ */
+static int
+fapi_image_uncached_glyph(gs_font *pfont, gs_state *pgs, gs_show_enum *penum,
+ gs_fapi_raster *rast, const int import_shift_v)
+{
+ gx_device *dev = penum->dev;
+ gs_state *penum_pgs = (gs_state *) penum->pis;
+ int code;
+ const gx_clip_path *pcpath = pgs->clip_path;
+ const gx_drawing_color *pdcolor = penum->pdcolor;
+ int rast_orig_x = rast->orig_x;
+ int rast_orig_y = -rast->orig_y;
+ gs_font_base *pbfont = (gs_font_base *)pfont;
+ gs_fapi_server *I = pbfont->FAPI;
+
+ extern_st(st_gs_show_enum);
+
+ byte *r = rast->p;
+ byte *src, *dst;
+ int h, padbytes, cpbytes, dstr = bitmap_raster(rast->width);
+ int sstr = rast->line_step;
+
+ /* we can only safely use the gx_image_fill_masked() "shortcut" if we're drawing
+ * a "simple" colour, rather than a pattern.
+ */
+ if (gs_color_writes_pure(penum_pgs) && I->ff.embolden == 0.0) {
+ if (dstr != sstr) {
+
+ /* If the stride of the bitmap we've got doesn't match what the rest
+ * of the Ghostscript world expects, make one that does.
+ * Ghostscript aligns bitmap raster memory in a platform specific
+ * manner, so see gxbitmap.h for details.
+ *
+ * Ideally the padding bytes wouldn't matter, but currently the
+ * clist code ends up compressing it using bitmap compression. To
+ * ensure consistency across runs (and to get the best possible
+ * compression ratios) we therefore set such bytes to zero. It would
+ * be nicer if this was fixed in future.
+ */
+ r = gs_alloc_bytes(penum->memory, dstr * rast->height,
+ "fapi_finish_render_aux");
+ if (!r) {
+ return_error(gs_error_VMerror);
+ }
+
+ cpbytes = sstr < dstr ? sstr : dstr;
+ padbytes = dstr - cpbytes;
+ h = rast->height;
+ src = rast->p;
+ dst = r;
+ if (padbytes > 0) {
+ while (h-- > 0) {
+ memcpy(dst, src, cpbytes);
+ memset(dst + cpbytes, 0, padbytes);
+ src += sstr;
+ dst += dstr;
+ }
+ }
+ else {
+ while (h-- > 0) {
+ memcpy(dst, src, cpbytes);
+ src += sstr;
+ dst += dstr;
+ }
+ }
+ }
+
+ if (gs_object_type(penum->memory, penum) == &st_gs_show_enum) {
+ code = gx_image_fill_masked(dev, r, 0, dstr, 0,
+ (int)(penum_pgs->ctm.tx +
+ (double)rast_orig_x /
+ (1 << frac_pixel_shift) +
+ penum->fapi_glyph_shift.x +
+ 0.5),
+ (int)(penum_pgs->ctm.ty +
+ (double)rast_orig_y /
+ (1 << frac_pixel_shift) +
+ penum->fapi_glyph_shift.y +
+ 0.5), rast->width, rast->height,
+ pdcolor, 1, rop3_default, pcpath);
+ }
+ else {
+ code = gx_image_fill_masked(dev, r, 0, dstr, 0,
+ (int)(penum_pgs->ctm.tx +
+ (double)rast_orig_x /
+ (1 << frac_pixel_shift) + 0.5),
+ (int)(penum_pgs->ctm.ty +
+ (double)rast_orig_y /
+ (1 << frac_pixel_shift) + 0.5),
+ rast->width, rast->height, pdcolor, 1,
+ rop3_default, pcpath);
+ }
+ if (rast->p != r) {
+ gs_free_object(penum->memory, r, "fapi_finish_render_aux");
+ }
+ }
+ else {
+ gs_memory_t *mem = penum->memory->non_gc_memory;
+ gs_image_enum *pie =
+ gs_image_enum_alloc(mem, "image_char(image_enum)");
+ gs_image_t image;
+ int iy, nbytes;
+ uint used;
+ int code1;
+ int x, y, w, h;
+ uint bold = 0;
+ byte *bold_lines = NULL;
+ int ascent = 0;
+
+ if (!pie) {
+ return_error(gs_error_VMerror);
+ }
+
+ x = (int)(penum_pgs->ctm.tx +
+ (double)rast_orig_x / (1 << frac_pixel_shift) + 0.5);
+ y = (int)(penum_pgs->ctm.ty +
+ (double)rast_orig_y / (1 << frac_pixel_shift) + 0.5);
+ w = rast->width;
+ h = rast->height;
+
+ if (I->ff.embolden != 0.0) {
+ bold = (uint)(2 * h * I->ff.embolden + 0.5);
+ ascent += bold;
+ bold_lines = alloc_bold_lines(pgs->memory, w, bold, "fapi_image_uncached_glyph(bold_line)");
+ if ( bold_lines == 0 ) {
+ code = gs_note_error(gs_error_VMerror);
+ return(code);
+ }
+ }
+
+ /* Make a matrix that will place the image */
+ /* at (x,y) with no transformation. */
+ gs_image_t_init_mask(&image, true);
+ gs_make_translation((floatp) - x, (floatp) (- y + ascent), &image.ImageMatrix);
+ gs_matrix_multiply(&ctm_only(penum_pgs), &image.ImageMatrix, &image.ImageMatrix);
+ image.Width = w + bold;
+ image.Height = h + bold;
+ image.adjust = false;
+ code = gs_image_init(pie, &image, false, penum_pgs);
+ nbytes = (rast->width + 7) >> 3;
+
+ switch (code) {
+ case 1: /* empty image */
+ code = 0;
+ default:
+ break;
+ case 0:
+ if (bold == 0) {
+ for (iy = 0; iy < h && code >= 0; iy++, r += sstr) {
+ code = gs_image_next(pie, r, nbytes, &used);
+ }
+ }
+ else {
+ uint dest_raster = bitmap_raster(image.Width);
+ uint dest_bytes = (image.Width + 7) >> 3;
+ int n1 = bold + 1;
+#define merged_line(i) (bold_lines + ((i) % n1 + 1) * dest_raster)
+
+ for ( y = 0; y < image.Height; y++ ) {
+ int y0 = (y < bold ? 0 : y - bold);
+ int y1 = min(y + 1, rast->height);
+ int kmask;
+ bool first = true;
+
+ if ( y < rast->height ) {
+
+ bits_smear_horizontally(merged_line(y),
+ r + y * rast->line_step, rast->width, bold);
+ /* Now re-establish the invariant -- see below. */
+ kmask = 1;
+
+ for ( ; (y & kmask) == kmask && y - kmask >= y0;
+ kmask = (kmask << 1) + 1) {
+
+ bits_merge(merged_line(y - kmask),
+ merged_line(y - (kmask >> 1)),
+ dest_bytes);
+ }
+ }
+
+ /*
+ * As of this point in the loop, we maintain the following
+ * invariant to cache partial merges of groups of lines: for
+ * each Y, y0 <= Y < y1, let K be the maximum k such that Y
+ * mod 2^k = 0 and Y + 2^k < y1; then merged_line(Y) holds
+ * the union of horizontally smeared source lines Y through
+ * Y + 2^k - 1. The idea behind this is similar to the idea
+ * of quicksort.
+ */
+
+ /* Now construct the output line. */
+ first = true;
+
+ for ( iy = y1 - 1; iy >= y0; --iy ) {
+ kmask = 1;
+
+ while ( (iy & kmask) == kmask && iy - kmask >= y0 )
+ iy -= kmask, kmask <<= 1;
+ if ( first ) {
+ memcpy(bold_lines, merged_line(iy), dest_bytes);
+ first = false;
+ }
+ else
+ bits_merge(bold_lines, merged_line(iy), dest_bytes);
+ }
+ code = gs_image_next(pie, bold_lines, dest_bytes, &used);
+ }
+ }
+#undef merged_line
+ }
+
+ if (bold_lines)
+ gs_free_object(pgs->memory, bold_lines, "fapi_image_uncached_glyph(bold_lines)");
+
+ code1 = gs_image_cleanup_and_free_enum(pie, penum_pgs);
+ if (code >= 0 && code1 < 0)
+ code = code1;
+ }
+ return (code);
+}
+
+int
+gs_fapi_finish_render(gs_font *pfont, gs_state *pgs, gs_text_enum_t *penum, gs_fapi_server *I)
+{
+ gs_show_enum *penum_s = (gs_show_enum *) penum;
+ gs_state *penum_pgs;
+ gx_device *dev1;
+ const int import_shift_v = _fixed_shift - 32; /* we always 32.32 values for the outline interface now */
+ gs_fapi_raster rast;
+ int code;
+ gs_memory_t *mem = pfont->memory;
+ gs_font_base *pbfont = (gs_font_base *)pfont;
+
+ extern_st(st_gs_show_enum);
+ extern_st(st_gs_state);
+
+ if (penum == NULL) {
+ return_error(gs_error_undefined);
+ }
+
+ /* Ensure that pis points to a st_gs_gstate (graphics state) structure */
+ if (gs_object_type(penum->memory, penum->pis) != &st_gs_state) {
+ /* If pis is not a graphics state, see if the text enumerator is a
+ * show enumerator, in which case we have a pointer to the graphics state there
+ */
+ if (gs_object_type(penum->memory, penum) == &st_gs_show_enum) {
+ penum_pgs = penum_s->pgs;
+ }
+ else
+ /* No graphics state, give up... */
+ return_error(gs_error_undefined);
+ }
+ else
+ penum_pgs = (gs_state *) penum->pis;
+
+ dev1 = gs_currentdevice_inline(penum_pgs); /* Possibly changed by zchar_set_cache. */
+
+ /* Even for "non-marking" text operations (for example, stringwidth) we are expected
+ * to have a glyph bitmap for the cache, if we're using the cache. For the
+ * non-cacheing, non-marking cases, we must not draw the glyph.
+ */
+ if (pgs->in_charpath && !SHOW_IS(penum, TEXT_DO_NONE)) {
+ if ((code =
+ outline_char(mem, I, import_shift_v, penum_s, penum_pgs->path,
+ !pbfont->PaintType)) < 0) {
+ return code;
+ }
+
+ if ((code =
+ gx_path_add_char_path(penum_pgs->show_gstate->path,
+ penum_pgs->path,
+ penum_pgs->in_charpath)) < 0) {
+ return code;
+ }
+
+ }
+ else {
+ int code = I->get_char_raster(I, &rast);
+
+ if (!SHOW_IS(penum, TEXT_DO_NONE) && I->use_outline) {
+ /* The server provides an outline instead the raster. */
+ gs_imager_state *pis = (gs_imager_state *) penum_pgs->show_gstate;
+ gs_point pt;
+
+ if ((code = gs_currentpoint(penum_pgs, &pt)) < 0)
+ return code;
+ if ((code =
+ outline_char(mem, I, import_shift_v, penum_s,
+ penum_pgs->path, !pbfont->PaintType)) < 0)
+ return code;
+ if ((code =
+ gs_imager_setflat((gs_imager_state *) penum_pgs,
+ gs_char_flatness(pis, 1.0))) < 0)
+ return code;
+ if (pbfont->PaintType) {
+ float lw = gs_currentlinewidth(penum_pgs);
+
+ gs_setlinewidth(penum_pgs, pbfont->StrokeWidth);
+ code = gs_stroke(penum_pgs);
+ gs_setlinewidth(penum_pgs, lw);
+ if (code < 0)
+ return code;
+ }
+ else {
+ gs_in_cache_device_t in_cachedevice =
+ penum_pgs->in_cachedevice;
+
+ penum_pgs->in_cachedevice = CACHE_DEVICE_NOT_CACHING;
+
+ penum_pgs->fill_adjust.x = penum_pgs->fill_adjust.y = 0;
+
+ if ((code = gs_fill(penum_pgs)) < 0)
+ return code;
+
+ penum_pgs->in_cachedevice = in_cachedevice;
+ }
+ if ((code = gs_moveto(penum_pgs, pt.x, pt.y)) < 0)
+ return code;
+ }
+ else {
+ int rast_orig_x = rast.orig_x;
+ int rast_orig_y = -rast.orig_y;
+
+ if (penum_pgs->in_cachedevice == CACHE_DEVICE_CACHING) { /* Using GS cache */
+ /* GS and renderer may transform coordinates few differently.
+ The best way is to make set_cache_device to take the renderer's bitmap metrics immediately,
+ but we need to account CDevProc, which may truncate the bitmap.
+ Perhaps GS overestimates the bitmap size,
+ so now we only add a compensating shift - the dx and dy.
+ */
+ if (rast.width != 0) {
+ int shift_rd = _fixed_shift - frac_pixel_shift;
+ int rounding = 1 << (frac_pixel_shift - 1);
+ int dx =
+ arith_rshift_slow((penum_pgs->
+ ctm.tx_fixed >> shift_rd) +
+ rast_orig_x + rounding,
+ frac_pixel_shift);
+ int dy =
+ arith_rshift_slow((penum_pgs->
+ ctm.ty_fixed >> shift_rd) +
+ rast_orig_y + rounding,
+ frac_pixel_shift);
+
+ if (dx + rast.left_indent < 0
+ || dx + rast.left_indent + rast.black_width >
+ dev1->width) {
+#ifdef DEBUG
+ if (gs_debug_c('m')) {
+ emprintf2(dev1->memory,
+ "Warning : Cropping a FAPI glyph while caching : dx=%d,%d.\n",
+ dx + rast.left_indent,
+ dx + rast.left_indent +
+ rast.black_width - dev1->width);
+ }
+#endif
+ if (dx + rast.left_indent < 0)
+ dx -= dx + rast.left_indent;
+ }
+ if (dy + rast.top_indent < 0
+ || dy + rast.top_indent + rast.black_height >
+ dev1->height) {
+#ifdef DEBUG
+ if (gs_debug_c('m')) {
+ emprintf2(dev1->memory,
+ "Warning : Cropping a FAPI glyph while caching : dx=%d,%d.\n",
+ dy + rast.top_indent,
+ dy + rast.top_indent +
+ rast.black_height - dev1->height);
+ }
+#endif
+ if (dy + rast.top_indent < 0)
+ dy -= dy + rast.top_indent;
+ }
+ if ((code = fapi_copy_mono(dev1, &rast, dx, dy)) < 0)
+ return code;
+
+ if (gs_object_type(penum->memory, penum) ==
+ &st_gs_show_enum) {
+ penum_s->cc->offset.x +=
+ float2fixed(penum_s->fapi_glyph_shift.x);
+ penum_s->cc->offset.y +=
+ float2fixed(penum_s->fapi_glyph_shift.y);
+ }
+ }
+ }
+ else if (!SHOW_IS(penum, TEXT_DO_NONE)) { /* Not using GS cache */
+ if ((code =
+ fapi_image_uncached_glyph(pfont, pgs, penum_s, &rast,
+ import_shift_v)) < 0)
+ return code;
+ }
+ }
+ }
+
+ return 0;
+}
+
+
+#define GET_U16_MSB(p) (((uint)((p)[0]) << 8) + (p)[1])
+#define GET_S16_MSB(p) (int)((GET_U16_MSB(p) ^ 0x8000) - 0x8000)
+
+#define MTX_EQ(mtx1,mtx2) (mtx1->xx == mtx2->xx && mtx1->xy == mtx2->xy && \
+ mtx1->yx == mtx2->yx && mtx1->yy == mtx2->yy && \
+ mtx1->tx == mtx2->tx && mtx1->ty == mtx2->ty)
+
+int
+gs_fapi_do_char(gs_font *pfont, gs_state *pgs, gs_text_enum_t *penum, char *font_file_path,
+ bool bBuildGlyph, gs_string *charstring, gs_string *glyphname,
+ gs_char chr, gs_glyph index, int subfont)
+{ /* Stack : <font> <code|name> --> - */
+ gs_show_enum *penum_s = (gs_show_enum *) penum;
+ gx_device *dev = gs_currentdevice_inline(pgs);
+
+ /*
+ fixme: the following code needs to optimize with a maintainence of scaled font objects
+ in graphics library and in interpreter. Now we suppose that the renderer
+ uses font cache, so redundant font opening isn't a big expense.
+ */
+ gs_fapi_char_ref cr =
+ { 0, {0}, 0, false, NULL, 0, 0, 0, 0, 0, gs_fapi_metrics_notdef };
+ gs_font_base *pbfont = (gs_font_base *)pfont;
+ const gs_matrix *ctm = &ctm_only(pgs);
+ int scale;
+ gs_fapi_metrics metrics;
+ gs_fapi_server *I = pbfont->FAPI;
+
+ gs_string enc_char_name_string;
+ bool bCID = (FAPI_ISCIDFONT(pbfont) || charstring != NULL);
+ bool bIsType1GlyphData = FAPI_ISTYPE1GLYPHDATA(pbfont);
+ gs_log2_scale_point log2_scale = { 0, 0 };
+ int alpha_bits = (*dev_proc(dev, get_alpha_bits)) (dev, go_text);
+ double FontMatrix_div = 1;
+ bool bVertical = (gs_rootfont(pgs)->WMode != 0), bVertical0 = bVertical;
+ double *sbwp, sbw[4] = { 0, 0, 0, 0 };
+ double em_scale_x, em_scale_y;
+ gs_rect char_bbox;
+ int code;
+ bool imagenow = false;
+ bool align_to_pixels = gs_currentaligntopixels(pbfont->dir);
+ gs_fapi_descendant_code fdc;
+ gs_memory_t *mem = pfont->memory;
+ enum
+ {
+ SBW_DONE,
+ SBW_SCALE,
+ SBW_FROM_RENDERER
+ } sbw_state = SBW_SCALE;
+
+ if ( index == gs_no_glyph )
+ return 0;
+
+ I->use_outline = false;
+
+ if (penum == 0)
+ return_error(gs_error_undefined);
+
+ I->use_outline =
+ produce_outline_char(penum_s, pbfont, alpha_bits, &log2_scale);
+
+ if (I->use_outline) {
+ I->max_bitmap = 0;
+ }
+ else {
+ /* FIX ME: It can be a very bad thing, right now, for the FAPI code to decide unilaterally to
+ * produce an outline, when the rest of GS expects a bitmap, so we give ourselves a
+ * 50% leeway on the maximum cache bitmap, just to be sure. Or the same maximum bitmap size
+ * used in gxchar.c
+ */
+ I->max_bitmap =
+ pbfont->dir->ccache.upper + (pbfont->dir->ccache.upper >> 1) <
+ MAX_TEMP_BITMAP_BITS ? pbfont->dir->ccache.upper +
+ (pbfont->dir->ccache.upper >> 1) : MAX_TEMP_BITMAP_BITS;
+ }
+
+ /* Compute the scale : */
+ if (!SHOW_IS(penum, TEXT_DO_NONE) && !I->use_outline) {
+ gs_currentcharmatrix(pgs, NULL, 1); /* make char_tm valid */
+ penum_s->fapi_log2_scale = log2_scale;
+ }
+ else {
+ log2_scale.x = 0;
+ log2_scale.y = 0;
+ }
+
+ /* Prepare font data
+ * This needs done here (earlier than it used to be) because FAPI/UFST has conflicting
+ * requirements in what I->get_fontmatrix() returns based on font type, so it needs to
+ * find the font type.
+ */
+
+ I->ff.memory = pbfont->memory;
+ I->ff.font_file_path = font_file_path;
+ I->ff.client_font_data = pbfont;
+ I->ff.client_font_data2 = pbfont;
+ I->ff.server_font_data = pbfont->FAPI_font_data;
+ I->ff.is_type1 = bIsType1GlyphData;
+ I->ff.is_cid = bCID;
+ I->ff.is_outline_font = pbfont->PaintType != 0;
+ I->ff.is_mtx_skipped = (gs_fapi_get_metrics_count(&I->ff) != 0);
+ I->ff.is_vertical = bVertical;
+ I->ff.client_ctx_p = I->client_ctx_p;
+
+ scale = 1 << I->frac_shift;
+ retry_oversampling:
+ if (I->face.font_id != pbfont->id ||
+ !MTX_EQ((&I->face.ctm), ctm) ||
+ I->face.log2_scale.x != log2_scale.x ||
+ I->face.log2_scale.y != log2_scale.y ||
+ I->face.align_to_pixels != align_to_pixels ||
+ I->face.HWResolution[0] != dev->HWResolution[0] ||
+ I->face.HWResolution[1] != dev->HWResolution[1]
+ ) {
+ gs_fapi_font_scale font_scale = { {1, 0, 0, 1, 0, 0}
+ , {0, 0}
+ , {1, 1}
+ , true
+ };
+ gs_matrix scale_mat, scale_ctm;
+
+ I->face.font_id = pbfont->id;
+ I->face.ctm = *ctm;
+ I->face.log2_scale = log2_scale;
+ I->face.align_to_pixels = align_to_pixels;
+ I->face.HWResolution[0] = dev->HWResolution[0];
+ I->face.HWResolution[1] = dev->HWResolution[1];
+
+ font_scale.subpixels[0] = 1 << log2_scale.x;
+ font_scale.subpixels[1] = 1 << log2_scale.y;
+ font_scale.align_to_pixels = align_to_pixels;
+
+ /* We apply the entire transform to the glyph (that is ctm x FontMatrix)
+ * at render time.
+ */
+
+ memset(&scale_ctm, 0x00, sizeof(gs_matrix));
+ scale_ctm.xx = dev->HWResolution[0] / 72;
+ scale_ctm.yy = dev->HWResolution[1] / 72;
+
+ code = gs_matrix_invert((const gs_matrix *)&scale_ctm, &scale_ctm);
+
+ code = gs_matrix_multiply(ctm, &scale_ctm, &scale_mat); /* scale_mat == CTM - resolution scaling */
+
+ code = I->get_fontmatrix(I, &scale_ctm);
+ code = gs_matrix_invert((const gs_matrix *)&scale_ctm, &scale_ctm);
+ code = gs_matrix_multiply(&scale_mat, &scale_ctm, &scale_mat); /* scale_mat == CTM - resolution scaling - FontMatrix scaling */
+
+ font_scale.matrix[0] =
+ (fracint) (scale_mat.xx * FontMatrix_div * scale + 0.5);
+ font_scale.matrix[1] =
+ -(fracint) (scale_mat.xy * FontMatrix_div * scale + 0.5);
+ font_scale.matrix[2] =
+ (fracint) (scale_mat.yx * FontMatrix_div * scale + 0.5);
+ font_scale.matrix[3] =
+ -(fracint) (scale_mat.yy * FontMatrix_div * scale + 0.5);
+ font_scale.matrix[4] =
+ (fracint) (scale_mat.tx * FontMatrix_div * scale + 0.5);
+ font_scale.matrix[5] =
+ (fracint) (scale_mat.ty * FontMatrix_div * scale + 0.5);
+
+ /* Note: the ctm mapping here is upside down. */
+ font_scale.HWResolution[0] =
+ (fracint) ((double)dev->HWResolution[0] *
+ font_scale.subpixels[0] * scale);
+ font_scale.HWResolution[1] =
+ (fracint) ((double)dev->HWResolution[1] *
+ font_scale.subpixels[1] * scale);
+
+
+ if ((hypot((double)font_scale.matrix[0], (double)font_scale.matrix[2])
+ == 0.0
+ || hypot((double)font_scale.matrix[1],
+ (double)font_scale.matrix[3]) == 0.0)) {
+
+ /* If the matrix is degenerate, force a scale to 1 unit. */
+ if (!font_scale.matrix[0])
+ font_scale.matrix[0] = 1;
+ if (!font_scale.matrix[3])
+ font_scale.matrix[3] = 1;
+ }
+
+ if (!bCID
+ || (pbfont->FontType != ft_encrypted
+ && pbfont->FontType != ft_encrypted2)) {
+ fdc = gs_fapi_toplevel_prepared;
+ }
+ else {
+ fdc = gs_fapi_toplevel_prepared;
+ }
+ if ((code =
+ gs_fapi_renderer_retcode(mem, I,
+ I->get_scaled_font(I, &I->ff,
+ &font_scale, NULL,
+ fdc))) < 0) {
+ return code;
+ }
+ }
+
+ cr.char_codes_count = 1;
+ cr.char_codes[0] = (index == GS_NO_GLYPH) ? 0 : index;
+ cr.client_char_code = chr;
+ cr.is_glyph_index = true;
+ enc_char_name_string.data = NULL;
+ enc_char_name_string.size = 0;
+
+ if (I->ff.get_glyphname_or_cid) {
+ if ((code =
+ I->ff.get_glyphname_or_cid(pbfont, charstring, glyphname, index,
+ &enc_char_name_string, font_file_path,
+ &cr, bCID)) < 0)
+ return (code);
+ }
+
+ /* Compute the metrics replacement : */
+ if (bCID && !bIsType1GlyphData) {
+ gs_font_cid2 *pfcid = (gs_font_cid2 *) pbfont;
+ int MetricsCount = pfcid->cidata.MetricsCount;
+
+ if (MetricsCount > 0) {
+ const byte *data_ptr;
+ int l = I->ff.get_glyphdirectory_data(&(I->ff), cr.char_codes[0],
+ &data_ptr);
+
+ if (MetricsCount == 2 && l >= 4) {
+ if (!bVertical0) {
+ cr.sb_x = GET_S16_MSB(data_ptr + 2) * scale;
+ cr.aw_x = GET_U16_MSB(data_ptr + 0) * scale;
+ cr.metrics_type = gs_fapi_metrics_replace;
+ }
+ }
+ else if (l >= 8) {
+ cr.sb_y = GET_S16_MSB(data_ptr + 2) * scale;
+ cr.aw_y = GET_U16_MSB(data_ptr + 0) * scale;
+ cr.sb_x = GET_S16_MSB(data_ptr + 6) * scale;
+ cr.aw_x = GET_U16_MSB(data_ptr + 4) * scale;
+ cr.metrics_type = gs_fapi_metrics_replace;
+ }
+ }
+ }
+ if (cr.metrics_type != gs_fapi_metrics_replace && bVertical) {
+ double pwv[4];
+
+ code =
+ I->ff.fapi_get_metrics(&I->ff, &enc_char_name_string, index, pwv,
+ bVertical);
+ if (code < 0)
+ return code;
+ if (code == 0 /* metricsNone */ ) {
+ if (bCID && (!bIsType1GlyphData && font_file_path)) {
+ cr.sb_x = fapi_round(sbw[2] / 2 * scale);
+ cr.sb_y = fapi_round(pbfont->FontBBox.q.y * scale);
+ cr.aw_y = fapi_round(-pbfont->FontBBox.q.x * scale); /* Sic ! */
+ cr.metrics_scale = (bIsType1GlyphData ? 1000 : 1);
+ cr.metrics_type = gs_fapi_metrics_replace;
+ sbw[0] = sbw[2] / 2;
+ sbw[1] = pbfont->FontBBox.q.y;
+ sbw[2] = 0;
+ sbw[3] = -pbfont->FontBBox.q.x; /* Sic ! */
+ sbw_state = SBW_DONE;
+ }
+ else {
+ bVertical = false;
+ }
+ }
+ else {
+ cr.sb_x = fapi_round(pwv[2] * scale);
+ cr.sb_y = fapi_round(pwv[3] * scale);
+ cr.aw_x = fapi_round(pwv[0] * scale);
+ cr.aw_y = fapi_round(pwv[1] * scale);
+ cr.metrics_scale = (bIsType1GlyphData ? 1000 : 1);
+ cr.metrics_type = (code == 2 /* metricsSideBearingAndWidth */ ? gs_fapi_metrics_replace
+ : gs_fapi_metrics_replace_width);
+ sbw[0] = pwv[2];
+ sbw[1] = pwv[3];
+ sbw[2] = pwv[0];
+ sbw[3] = pwv[1];
+ sbw_state = SBW_DONE;
+ }
+ }
+ if (cr.metrics_type == gs_fapi_metrics_notdef && !bVertical) {
+ code =
+ I->ff.fapi_get_metrics(&I->ff, &enc_char_name_string, index, sbw,
+ bVertical);
+ if (code < 0)
+ return code;
+ if (code == 0 /* metricsNone */ ) {
+ sbw_state = SBW_FROM_RENDERER;
+ if (pbfont->FontType == 2) {
+ gs_font_type1 *pfont1 = (gs_font_type1 *) pbfont;
+
+ cr.aw_x =
+ export_shift(pfont1->data.defaultWidthX,
+ _fixed_shift - I->frac_shift);
+ cr.metrics_scale = 1000;
+ cr.metrics_type = gs_fapi_metrics_add;
+ }
+ }
+ else {
+ cr.sb_x = fapi_round(sbw[0] * scale);
+ cr.sb_y = fapi_round(sbw[1] * scale);
+ cr.aw_x = fapi_round(sbw[2] * scale);
+ cr.aw_y = fapi_round(sbw[3] * scale);
+ cr.metrics_scale = (bIsType1GlyphData ? 1000 : 1);
+ cr.metrics_type = (code == 2 /* metricsSideBearingAndWidth */ ? gs_fapi_metrics_replace
+ : gs_fapi_metrics_replace_width);
+ sbw_state = SBW_DONE;
+ }
+ }
+ memset(&metrics, 0x00, sizeof(metrics));
+ /* Take metrics from font : */
+ if (fapi_gs_char_show_width_only(penum)) {
+ code = I->get_char_width(I, &I->ff, &cr, &metrics);
+ /* A VMerror could be a real out of memory, or the glyph being too big for a bitmap
+ * so it's worth retrying as an outline glyph
+ */
+ if (code == gs_error_VMerror && I->use_outline == false) {
+ I->max_bitmap = 0;
+ I->use_outline = true;
+ goto retry_oversampling;
+ }
+
+ }
+ else if (I->use_outline) {
+
+ code = I->get_char_outline_metrics(I, &I->ff, &cr, &metrics);
+ }
+ else {
+ code = I->get_char_raster_metrics(I, &I->ff, &cr, &metrics);
+ /* A VMerror could be a real out of memory, or the glyph being too big for a bitmap
+ * so it's worth retrying as an outline glyph
+ */
+ if (code == gs_error_VMerror) {
+ I->use_outline = true;
+ goto retry_oversampling;
+ }
+ if (code == gs_error_limitcheck) {
+ if (log2_scale.x > 0 || log2_scale.y > 0) {
+ penum_s->fapi_log2_scale.x = log2_scale.x =
+ penum_s->fapi_log2_scale.y = log2_scale.y = 0;
+ I->release_char_data(I);
+ goto retry_oversampling;
+ }
+ if ((code =
+ gs_fapi_renderer_retcode(mem, I,
+ I->get_char_outline_metrics(I,
+ &I->ff,
+ &cr,
+ &metrics)))
+ < 0)
+ return code;
+ }
+ }
+
+ if (!bVertical)
+ metrics.v_escapement = 0;
+
+ /* This handles the situation where a charstring has been replaced with a PS procedure.
+ * against the rules, but not *that* rare.
+ * It's also something that GS does internally to simulate font styles.
+ */
+ if (code > 0) {
+ return (gs_error_unregistered);
+ }
+
+ if ((code = gs_fapi_renderer_retcode(mem, I, code)) < 0)
+ return code;
+
+ compute_em_scale(pbfont, &metrics, FontMatrix_div, &em_scale_x,
+ &em_scale_y);
+ char_bbox.p.x = metrics.bbox_x0 / em_scale_x;
+ char_bbox.p.y = metrics.bbox_y0 / em_scale_y;
+ char_bbox.q.x = metrics.bbox_x1 / em_scale_x;
+ char_bbox.q.y = metrics.bbox_y1 / em_scale_y;
+
+ /* We must use the FontBBox, but it seems some buggy fonts have glyphs which extend outside the
+ * FontBBox, so we have to do this....
+ */
+ if (pbfont->FontType != ft_MicroType && !bCID
+ && pbfont->FontBBox.q.x > pbfont->FontBBox.p.x
+ && pbfont->FontBBox.q.y > pbfont->FontBBox.p.y) {
+ char_bbox.p.x = min(char_bbox.p.x, pbfont->FontBBox.p.x);
+ char_bbox.p.y = min(char_bbox.p.y, pbfont->FontBBox.p.y);
+ char_bbox.q.x = max(char_bbox.q.x, pbfont->FontBBox.q.x);
+ char_bbox.q.y = max(char_bbox.q.y, pbfont->FontBBox.q.y);
+ }
+
+ if (pbfont->PaintType != 0) {
+ float w = pbfont->StrokeWidth / 2;
+
+ char_bbox.p.x -= w;
+ char_bbox.p.y -= w;
+ char_bbox.q.x += w;
+ char_bbox.q.y += w;
+ }
+ penum_s->fapi_glyph_shift.x = penum_s->fapi_glyph_shift.y = 0;
+ if (sbw_state == SBW_FROM_RENDERER) {
+ int can_replace_metrics;
+
+ if ((code =
+ gs_fapi_renderer_retcode(mem, I,
+ I->can_replace_metrics(I, &I->ff, &cr,
+ &can_replace_metrics)))
+ < 0)
+ return code;
+
+ sbw[2] = metrics.escapement / em_scale_x;
+ sbw[3] = metrics.v_escapement / em_scale_y;
+ if (pbfont->FontType == 2 && !can_replace_metrics) {
+ gs_font_type1 *pfont1 = (gs_font_type1 *) pbfont;
+
+ sbw[2] += fixed2float(pfont1->data.nominalWidthX);
+ }
+ }
+ else if (sbw_state == SBW_SCALE) {
+ sbw[0] = (double)cr.sb_x / scale / em_scale_x;
+ sbw[1] = (double)cr.sb_y / scale / em_scale_y;
+ sbw[2] = (double)cr.aw_x / scale / em_scale_x;
+ sbw[3] = (double)cr.aw_y / scale / em_scale_y;
+ }
+
+ /* Setup cache and render : */
+ if (cr.metrics_type == gs_fapi_metrics_replace) {
+ /*
+ * Here we don't take care of replaced advance width
+ * because gs_text_setcachedevice handles it.
+ */
+ int can_replace_metrics;
+
+ if ((code =
+ gs_fapi_renderer_retcode(mem, I,
+ I->can_replace_metrics(I, &I->ff, &cr,
+ &can_replace_metrics)))
+ < 0)
+ return code;
+ if (!can_replace_metrics) {
+ /*
+ * The renderer should replace the lsb, but it can't.
+ * To work around we compute a displacement in integral pixels
+ * and later shift the bitmap to it. The raster will be inprecise
+ * with non-integral pixels shift.
+ */
+ char_bbox.q.x -= char_bbox.p.x;
+ char_bbox.p.x = 0;
+ gs_distance_transform((metrics.bbox_x0 / em_scale_x - sbw[0]),
+ 0, ctm, &penum_s->fapi_glyph_shift);
+ penum_s->fapi_glyph_shift.x *= 1 << log2_scale.x;
+ penum_s->fapi_glyph_shift.y *= 1 << log2_scale.y;
+ }
+ }
+
+ /*
+ * We assume that if bMetricsFromGlyphDirectory is true,
+ * the font does not specify Metrics[2] and/or CDevProc
+ * If someday we meet a font contradicting this assumption,
+ * zchar_set_cache to be improved with additional flag,
+ * to ignore Metrics[2] and CDevProc.
+ *
+ * Note that for best quality the result of CDevProc
+ * to be passed to I->get_char_raster_metrics, because
+ * both raster and metrics depend on replaced lsb.
+ * Perhaps in many cases the metrics from font is
+ * used as an argument for CDevProc. Only way to resolve
+ * is to call I->get_char_raster_metrics twice (before
+ * and after CDevProc), or better to split it into
+ * smaller functions. Unfortunately UFST cannot retrieve metrics
+ * quickly and separately from raster. Only way to resolve is
+ * to devide the replaced lsb into 2 parts, which correspond to
+ * integral and fractinal pixels, then pass the fractional shift
+ * to renderer and apply the integer shift after it.
+ *
+ * Besides that, we are not sure what to do if a font
+ * contains both Metrics[2] and CDevProc. Should
+ * CDevProc to be applied to Metrics[2] or to the metrics
+ * from glyph code ? Currently we keep a compatibility
+ * to the native GS font renderer without a deep analyzis.
+ */
+
+ /* Don't allow caching if we're only returning the metrics */
+ if (fapi_gs_char_show_width_only(penum)) {
+ pgs->in_cachedevice = CACHE_DEVICE_NOT_CACHING;
+ }
+
+ if (pgs->in_cachedevice == CACHE_DEVICE_CACHING) {
+ sbwp = sbw;
+ }
+ else {
+ /* Very occasionally, if we don't do this, setcachedevice2
+ * will decide we are cacheing, when we're not, and this
+ * causes problems when we get to show_update().
+ */
+ sbwp = NULL;
+
+ if (I->use_outline) {
+ /* HACK!!
+ * The decision about whether to cache has already been
+ * we need to prevent it being made again....
+ */
+ pgs->in_cachedevice = CACHE_DEVICE_NOT_CACHING;
+ }
+ }
+
+ if (bCID) {
+ code =
+ I->ff.fapi_set_cache(penum, pbfont, &enc_char_name_string, index,
+ sbw + 2, &char_bbox, sbwp, &imagenow);
+ }
+ else {
+ code =
+ I->ff.fapi_set_cache(penum, pbfont, &enc_char_name_string, -1,
+ sbw + 2, &char_bbox, sbwp, &imagenow);
+ }
+
+ /* If we can render the glyph now, do so.
+ * we may not be able to in the PS world if there's a CDevProc in the font
+ * in which case gs_fapi_finish_render() will be called from the PS
+ * "function" zfapi_finish_render() which has been pushed onto the
+ * stack.
+ */
+ if (code >= 0 && imagenow == true) {
+ code = gs_fapi_finish_render(pfont, pgs, penum, I);
+ I->release_char_data(I);
+ }
+
+ if (code != 0) {
+ if (code < 0) {
+ /* An error */
+ I->release_char_data(I);
+ }
+ else {
+ /* Callout to CDevProc, zsetcachedevice2, zfapi_finish_render. */
+ }
+ }
+
+ return code;
+}
+
+int
+gs_fapi_get_font_info(gs_font *pfont, gs_fapi_font_info item, int index,
+ void *data, int *data_len)
+{
+ int code = 0;
+ gs_font_base *pbfont = (gs_font_base *) pfont;
+ gs_fapi_server *I = pbfont->FAPI;
+
+ code = I->get_font_info(I, &I->ff, item, index, data, data_len);
+ return (code);
+}
+
+/* On finding a suitable FAPI instance, fapi_id will be set to point to the string of the instance name.
+ * A specific FAPI instance can be requested with the "fapi_request" parameter, but if the requested
+ * isn't found, or rejects the font, we're re-search the available instances to find one that can handle
+ * the font. If only an exact match is suitable, it is up to the *caller* to enforce that.
+ */
+int
+gs_fapi_passfont(gs_font *pfont, int subfont, char *font_file_path,
+ gs_string *full_font_buf, char *fapi_request, char *xlatmap,
+ char **fapi_id, gs_fapi_get_server_param_callback get_server_param_cb)
+{
+ gs_font_base *pbfont;
+ int code = 0;
+ gs_fapi_server *I, **list;
+ bool free_params = false;
+ gs_memory_t *mem = pfont->memory;
+ const char *decodingID = NULL;
+ bool do_restart = false;
+
+ list = gs_fapi_get_server_list(mem);
+
+ (*fapi_id) = NULL;
+
+ pbfont = (gs_font_base *) pfont;
+
+ I = *list;
+
+ if (fapi_request) {
+ if (gs_debug_c('1'))
+ dprintf1("Requested FAPI plugin: %s ", fapi_request);
+
+ while ((I = *list) != NULL
+ && strncmp(I->ig.d->subtype, fapi_request,
+ strlen(fapi_request)) != 0) {
+ list++;
+ }
+ if (!I) {
+ if (gs_debug_c('1'))
+ dprintf("not found. Falling back to normal plugin search\n");
+ list = (gs_fapi_server **) gs_fapi_get_server_list(mem);
+ I = *list;
+ }
+ else {
+ if (gs_debug_c('1'))
+ dprintf("found.\n");
+ do_restart = true;
+ }
+ }
+
+ while (I) {
+ char *server_param = NULL;
+ int server_param_size = 0;
+
+ (*get_server_param_cb) (I, (const char *)I->ig.d->subtype,
+ &server_param, &server_param_size);
+
+ if (server_param == NULL && server_param_size > 0) {
+ server_param =
+ (char *)gs_alloc_bytes_immovable(mem->non_gc_memory,
+ server_param_size,
+ "gs_fapi_passfont server params");
+ if (!server_param) {
+ return_error(gs_error_VMerror);
+ }
+ free_params = true;
+ (*get_server_param_cb) (I, (const char *)I->ig.d->subtype,
+ &server_param, &server_param_size);
+ }
+
+ if ((code =
+ gs_fapi_renderer_retcode(mem, I,
+ I->ensure_open(I, server_param,
+ server_param_size))) < 0)
+ return code;
+
+ if (free_params) {
+ gs_free_object(mem->non_gc_memory, server_param,
+ "gs_fapi_passfont server params");
+ }
+
+ pbfont->FAPI = I; /* we need the FAPI server during this stage */
+ code =
+ gs_fapi_prepare_font(pfont, I, subfont, font_file_path,
+ full_font_buf, xlatmap, &decodingID);
+ if (code >= 0) {
+ (*fapi_id) = (char *)I->ig.d->subtype;
+ return 0;
+ }
+
+ /* renderer failed, continue search */
+ pbfont->FAPI = NULL;
+ if (do_restart == true) {
+ if (gs_debug_c('1'))
+ dprintf1
+ ("Requested FAPI plugin %s failed, searching for alternative plugin\n",
+ I->ig.d->subtype);
+ list = (gs_fapi_server **) gs_fapi_get_server_list(mem);
+ do_restart = false;
+ }
+ else {
+ I = *list;
+ list++;
+ }
+ }
+ return (code);
+}
+
+bool
+gs_fapi_available(gs_memory_t *mem, char *server)
+{
+ bool retval = false;
+
+ if (server) {
+ gs_fapi_server *serv = NULL;
+
+ retval = (gs_fapi_find_server(mem, server, &serv, NULL) >= 0);
+ }
+ else {
+ retval = ((mem->gs_lib_ctx->fapi_servers) != NULL) && (*(mem->gs_lib_ctx->fapi_servers) != NULL);
+ }
+ return (retval);
+}
+
+void
+gs_fapi_set_servers_client_data(gs_memory_t *mem, const gs_fapi_font *ff_proto, void *ctx_ptr)
+{
+ gs_fapi_server **servs = gs_fapi_get_server_list(mem);
+
+ if (servs) {
+ while (*servs) {
+ (*servs)->client_ctx_p = ctx_ptr;
+ if (ff_proto)
+ (*servs)->ff = *ff_proto;
+ servs++;
+ }
+ }
+}
+
+gs_fapi_server **
+gs_fapi_get_server_list(gs_memory_t *mem)
+{
+ return (mem->gs_lib_ctx->fapi_servers);
+}
+
+int
+gs_fapi_find_server(gs_memory_t *mem, const char *name, gs_fapi_server **server,
+ gs_fapi_get_server_param_callback get_server_param_cb)
+{
+ gs_fapi_server **servs = gs_fapi_get_server_list(mem);
+ char *server_param = NULL;
+ int server_param_size = 0;
+ int code = 0;
+ bool free_params = false;
+
+ (*server) = NULL;
+
+ while (servs && *servs && strcmp((char *)(*servs)->ig.d->subtype, (char *)name)) {
+ servs++;
+ }
+
+ if (servs && *servs && get_server_param_cb) {
+ (*get_server_param_cb) ((*servs), (char *) (*servs)->ig.d->subtype,
+ &server_param, &server_param_size);
+
+ if (server_param == NULL && server_param_size > 0) {
+ server_param =
+ (char *)gs_alloc_bytes_immovable(mem->non_gc_memory,
+ server_param_size,
+ "gs_fapi_find_server server params");
+ if (!server_param) {
+ return_error(gs_error_VMerror);
+ }
+ free_params = true;
+ (*get_server_param_cb) ((*servs),
+ (const char *)(*servs)->ig.d->subtype,
+ &server_param, &server_param_size);
+ }
+
+ if ((code =
+ gs_fapi_renderer_retcode(mem, (*servs),
+ (*servs)->ensure_open((*servs),
+ server_param,
+ server_param_size)))
+ < 0) {
+ }
+
+ if (free_params) {
+ gs_free_object(mem->non_gc_memory, server_param,
+ "gs_fapi_find_server: server_param");
+ }
+
+ (*server) = (*servs);
+ }
+ else {
+ if (!servs || !(*servs)) {
+ code = gs_error_invalidaccess;
+ }
+ }
+
+
+ return (code);
+}
+
+int
+gs_fapi_init(gs_memory_t *mem)
+{
+ int code = 0;
+ int i, num_servers = 0;
+ gs_fapi_server **servs = NULL;
+ const gs_fapi_server_init_func *gs_fapi_server_inits =
+ gs_get_fapi_server_inits();
+
+ while (gs_fapi_server_inits[num_servers]) {
+ num_servers++;
+ }
+
+ servs =
+ (gs_fapi_server **) gs_alloc_bytes_immovable(mem->non_gc_memory,
+ (num_servers +
+ 1) *
+ sizeof(gs_fapi_server *),
+ "gs_fapi_init");
+ if (!servs) {
+ return_error(gs_error_VMerror);
+ }
+
+ for (i = 0; i < num_servers; i++) {
+ gs_fapi_server_init_func *f =
+ (gs_fapi_server_init_func *) & (gs_fapi_server_inits[i]);
+
+ code = (*f) (mem, &(servs[i]));
+ if (code != 0) {
+ break;
+ }
+ /* No point setting this, as in PS, the interpreter context might move
+ * But set it to NULL, just for safety */
+ servs[i]->client_ctx_p = NULL;
+ }
+
+ for (; i < num_servers + 1; i++) {
+ servs[i] = NULL;
+ }
+
+ mem->gs_lib_ctx->fapi_servers = servs;
+
+ return (code);
+}
+
+void
+gs_fapi_finit(gs_memory_t *mem)
+{
+ gs_fapi_server **servs = mem->gs_lib_ctx->fapi_servers;
+
+ while (servs && *servs) {
+ ((*servs)->ig.d->finit) (servs);
+ servs++;
+ }
+ gs_free_object(mem->non_gc_memory, mem->gs_lib_ctx->fapi_servers,
+ "gs_fapi_finit: mem->gs_lib_ctx->fapi_servers");
+ mem->gs_lib_ctx->fapi_servers = NULL;
+}
diff --git a/gs/base/gxfapi.h b/gs/base/gxfapi.h
new file mode 100644
index 000000000..1a0f5f74e
--- /dev/null
+++ b/gs/base/gxfapi.h
@@ -0,0 +1,434 @@
+/* Copyright (C) 2001-2012 Artifex Software, Inc.
+ All Rights Reserved.
+
+ This software is provided AS-IS with no warranty, either express or
+ implied.
+
+ This software is distributed under license and may not be copied, modified
+ or distributed except as expressly authorized under the terms of that
+ license. Refer to licensing information at http://www.artifex.com/
+ or contact Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134,
+ San Rafael, CA 94903, U.S.A., +1(415)492-9861, for further information.
+*/
+
+/* Font API support */
+
+#ifndef gxfapi_INCLUDED
+#define gxfapi_INCLUDED
+
+#include "gsmemory.h"
+#include "gsmatrix.h"
+#include "gsccode.h"
+#include "stdint_.h"
+
+#ifndef gs_font_base_DEFINED
+# define gs_font_base_DEFINED
+typedef struct gs_font_base_s gs_font_base;
+#endif
+
+#ifndef gs_state_DEFINED
+# define gs_state_DEFINED
+typedef struct gs_state_s gs_state;
+#endif
+
+#ifndef gs_text_enum_DEFINED
+# define gs_text_enum_DEFINED
+typedef struct gs_text_enum_s gs_text_enum_t;
+#endif
+
+#ifndef gs_font_DEFINED
+# define gs_font_DEFINED
+typedef struct gs_font_s gs_font;
+#endif
+
+typedef int fracint; /* A fractional integer with statically unknown number of fraction bits.
+ The number of bits depends on plugin and is being specified in
+ gs_fapi_server::frac_shift.
+ */
+typedef int gs_fapi_retcode;
+
+typedef enum
+{
+ gs_fapi_font_feature_FontMatrix,
+ gs_fapi_font_feature_UniqueID,
+ gs_fapi_font_feature_BlueScale,
+ gs_fapi_font_feature_Weight,
+ gs_fapi_font_feature_ItalicAngle,
+ gs_fapi_font_feature_IsFixedPitch,
+ gs_fapi_font_feature_UnderLinePosition,
+ gs_fapi_font_feature_UnderlineThickness,
+ gs_fapi_font_feature_FontType,
+ gs_fapi_font_feature_FontBBox,
+ gs_fapi_font_feature_BlueValues_count,
+ gs_fapi_font_feature_BlueValues,
+ gs_fapi_font_feature_OtherBlues_count,
+ gs_fapi_font_feature_OtherBlues,
+ gs_fapi_font_feature_FamilyBlues_count,
+ gs_fapi_font_feature_FamilyBlues,
+ gs_fapi_font_feature_FamilyOtherBlues_count,
+ gs_fapi_font_feature_FamilyOtherBlues,
+ gs_fapi_font_feature_BlueShift,
+ gs_fapi_font_feature_BlueFuzz,
+ gs_fapi_font_feature_StdHW,
+ gs_fapi_font_feature_StdVW,
+ gs_fapi_font_feature_StemSnapH_count,
+ gs_fapi_font_feature_StemSnapH,
+ gs_fapi_font_feature_StemSnapV_count,
+ gs_fapi_font_feature_StemSnapV,
+ gs_fapi_font_feature_ForceBold,
+ gs_fapi_font_feature_LanguageGroup,
+ gs_fapi_font_feature_lenIV,
+ gs_fapi_font_feature_GlobalSubrs_count,
+ gs_fapi_font_feature_Subrs_count,
+ gs_fapi_font_feature_Subrs_total_size,
+ gs_fapi_font_feature_TT_size,
+ /* Multiple Master specifics */
+ gs_fapi_font_feature_DollarBlend,
+ gs_fapi_font_feature_DollarBlend_length,
+ gs_fapi_font_feature_BlendAxisTypes_count,
+ gs_fapi_font_feature_BlendAxisTypes,
+ gs_fapi_font_feature_BlendPrivate_count,
+ gs_fapi_font_feature_BlendFontInfo_count,
+ gs_fapi_font_feature_WeightVector_count,
+ gs_fapi_font_feature_WeightVector,
+ gs_fapi_font_feature_BlendDesignPositionsArrays_count,
+ gs_fapi_font_feature_BlendDesignPositionsArrayValue,
+ gs_fapi_font_feature_BlendDesignMapArrays_count,
+ gs_fapi_font_feature_BlendDesignMapSubArrays_count,
+ gs_fapi_font_feature_BlendDesignMapArrayValue,
+ /* End MM specifics */
+ /* CharString emission */
+ gs_fapi_font_feature_CharStrings_count,
+ /* End CharString emission */
+} gs_fapi_font_feature;
+
+typedef enum
+{
+ gs_fapi_metrics_notdef,
+ gs_fapi_metrics_add, /* Add to native glyph width. */
+ gs_fapi_metrics_replace_width, /* Replace the native glyph width. */
+ gs_fapi_metrics_replace /* Replace the native glyph width and lsb. */
+} gs_fapi_metrics_type;
+
+typedef struct
+{
+ gs_char client_char_code; /* Debug purpose. */
+ gs_glyph char_codes[4];
+ int char_codes_count;
+ bool is_glyph_index; /* true if char_code contains glyph index */
+ const unsigned char *char_name; /* to be used exclusively with char_code. */
+ unsigned int char_name_length;
+ gs_fapi_metrics_type metrics_type;
+ fracint sb_x, sb_y, aw_x, aw_y; /* replaced PS metrics. */
+ int metrics_scale; /* Scale for replaced PS metrics.
+ Zero means "em box size". */
+} gs_fapi_char_ref;
+
+
+typedef struct
+{
+ int platform_id;
+ int encoding_id;
+} gs_fapi_ttf_cmap_request;
+
+#define GS_FAPI_NUM_TTF_CMAP_REQ 10
+
+typedef struct gs_fapi_font_s gs_fapi_font;
+struct gs_fapi_font_s
+{
+ /* server's data : */
+ void *server_font_data;
+ bool need_decrypt;
+ /* client's data : */
+ const gs_memory_t *memory;
+ const char *font_file_path;
+ const char *full_font_buf; /* If the font data is entirely contained in a memory buffer */
+ int full_font_buf_len;
+ int subfont;
+ bool is_type1; /* Only for non-disk fonts; dirty for disk fonts. */
+ bool is_cid;
+ bool is_outline_font;
+ bool is_mtx_skipped; /* Ugly. Only UFST needs. */
+ bool is_vertical;
+ gs_fapi_ttf_cmap_request ttf_cmap_req[GS_FAPI_NUM_TTF_CMAP_REQ]; /* Lets client request a specific cmap to be set. Also, a couple of fallbacks */
+ void *client_ctx_p;
+ void *client_font_data;
+ void *client_font_data2;
+ const void *char_data;
+ int char_data_len;
+ float embolden;
+ unsigned short (*get_word) (gs_fapi_font *ff,
+ gs_fapi_font_feature var_id, int index);
+ unsigned long (*get_long) (gs_fapi_font *ff, gs_fapi_font_feature var_id,
+ int index);
+ float (*get_float) (gs_fapi_font *ff, gs_fapi_font_feature var_id,
+ int index);
+ int (*get_name) (gs_fapi_font *ff, gs_fapi_font_feature var_id,
+ int index, char *buffer, int len);
+ int (*get_proc) (gs_fapi_font *ff, gs_fapi_font_feature var_id,
+ int index, char *Buffer);
+ unsigned short (*get_gsubr) (gs_fapi_font *ff, int index, byte *buf,
+ ushort buf_length);
+ unsigned short (*get_subr) (gs_fapi_font *ff, int index, byte *buf,
+ ushort buf_length);
+ unsigned short (*get_raw_subr) (gs_fapi_font *ff, int index, byte *buf,
+ ushort buf_length);
+ int (*get_glyph) (gs_fapi_font *ff, int char_code, byte *buf,
+ ushort buf_length);
+ unsigned short (*serialize_tt_font) (gs_fapi_font *ff, void *buf,
+ int buf_size);
+ unsigned short (*get_charstring) (gs_fapi_font *ff, int index,
+ byte *buf, ushort buf_length);
+ unsigned short (*get_charstring_name) (gs_fapi_font *ff, int index,
+ byte *buf, ushort buf_length);
+ int (*get_glyphdirectory_data) (gs_fapi_font *ff, int char_code,
+ const byte **ptr);
+ int (*get_glyphname_or_cid) (gs_font_base *pbfont,
+ gs_string *charstring, gs_string *name,
+ int ccode, gs_string *enc_char_name,
+ char *font_file_path, gs_fapi_char_ref *cr,
+ bool bCID);
+ int (*fapi_get_metrics) (gs_fapi_font *ff, gs_string *char_name,
+ int cid, double *m, bool vertical);
+ int (*fapi_set_cache) (gs_text_enum_t *penum,
+ const gs_font_base *pbfont,
+ const gs_string *char_name, int cid,
+ const double pwidth[2], const gs_rect *pbbox,
+ const double Metrics2_sbw_default[4],
+ bool *imagenow);
+};
+
+typedef struct gs_fapi_face_s gs_fapi_face;
+struct gs_fapi_face_s
+{
+ gs_id font_id;
+ gs_matrix ctm;
+ gs_log2_scale_point log2_scale;
+ bool align_to_pixels;
+ float HWResolution[2];
+};
+
+typedef struct gs_fapi_path_s gs_fapi_path;
+struct gs_fapi_path_s
+{
+ void *olh; /* Client's data. */
+ int shift;
+ int gs_error;
+ int (*moveto) (gs_fapi_path *, int64_t, int64_t);
+ int (*lineto) (gs_fapi_path *, int64_t, int64_t);
+ int (*curveto) (gs_fapi_path *, int64_t, int64_t, int64_t, int64_t,
+ int64_t, int64_t);
+ int (*closepath) (gs_fapi_path *);
+};
+
+typedef struct gs_fapi_font_scale_s
+{
+ fracint matrix[6];
+ fracint HWResolution[2];
+ int subpixels[2];
+ bool align_to_pixels;
+} gs_fapi_font_scale;
+
+typedef struct gs_fapi_metrics_s
+{
+ int bbox_x0, bbox_y0, bbox_x1, bbox_y1; /* design units */
+ int escapement; /* design units */
+ int v_escapement; /* design units */
+ int em_x, em_y; /* design units */
+} gs_fapi_metrics;
+
+typedef struct
+{ /* 1bit/pixel only, rows are byte-aligned. */
+ void *p;
+ int width, height, line_step;
+ int orig_x, orig_y; /* origin, 1/16s pixel */
+ int left_indent, top_indent;
+ int black_width, black_height;
+} gs_fapi_raster;
+
+#ifndef gs_fapi_server_DEFINED
+#define gs_fapi_server_DEFINED
+typedef struct gs_fapi_server_s gs_fapi_server;
+#endif
+
+typedef enum gs_fapi_descendant_code_s
+{ /* Possible values are descendant font indices and 4 ones defined below. */
+ gs_fapi_descendant_prepared = -1, /* See FAPI_prepare_font in zfapi.c . */
+ gs_fapi_toplevel_prepared = -2,
+ gs_fapi_toplevel_begin = -3,
+ gs_fapi_toplevel_complete = -4
+} gs_fapi_descendant_code;
+
+/* interrogate scaler about style simulation capabilities
+ * for a given font
+ */
+typedef enum gs_fapi_style_s
+{
+ gs_fapi_style_bold = 1
+} gs_fapi_style;
+
+/* interrogate scaler about style simulation capabilities
+ * for a given font
+ */
+typedef enum gs_fapi_font_info_s
+{
+ gs_fapi_font_info_name = 1,
+ gs_fapi_font_info_bbox = 2,
+ gs_fapi_font_info_pitch = 3,
+ gs_fapi_font_info_uid = 4,
+ gs_fapi_font_info_design_units = 5
+} gs_fapi_font_info;
+
+typedef struct gs_fapi_server_descriptor_s gs_fapi_server_descriptor;
+typedef struct gs_fapi_server_instance_s gs_fapi_server_instance;
+
+struct gs_fapi_server_descriptor_s
+{
+ const char *type;
+ const char *subtype;
+ void (*finit) (gs_fapi_server **server);
+};
+
+struct gs_fapi_server_instance_s
+{ /* Base class for various plugins */
+ const gs_fapi_server_descriptor *d;
+};
+
+
+struct gs_fapi_server_s
+{
+ gs_fapi_server_instance ig;
+ void *client_ctx_p;
+ int frac_shift; /* The number of fractional bits in coordinates. */
+ gs_fapi_face face;
+ gs_fapi_font ff;
+ int max_bitmap;
+ bool use_outline;
+ gs_matrix initial_FontMatrix; /* Font Matrix at the time the font is defined */
+ /* Used to use the stored 'OrigFont' entry but */
+ /* this did not change f a font was defined */
+ /* using an existing base font */
+
+
+
+ gs_fapi_retcode(*ensure_open) (gs_fapi_server *server, const char *param, int param_size);
+ gs_fapi_retcode(*get_scaled_font) (gs_fapi_server *server, gs_fapi_font *ff, const gs_fapi_font_scale *scale, const char *xlatmap, gs_fapi_descendant_code dc);
+ gs_fapi_retcode(*get_decodingID) (gs_fapi_server *server, gs_fapi_font *ff, const char **decodingID);
+ gs_fapi_retcode(*get_font_bbox) (gs_fapi_server *server, gs_fapi_font *ff, int BBox[4]);
+ gs_fapi_retcode(*get_font_proportional_feature) (gs_fapi_server *server, gs_fapi_font *ff, bool *bProportional);
+ gs_fapi_retcode(*can_retrieve_char_by_name) (gs_fapi_server *server, gs_fapi_font *ff, gs_fapi_char_ref *c, int *result);
+ gs_fapi_retcode(*can_replace_metrics) (gs_fapi_server *server, gs_fapi_font *ff, gs_fapi_char_ref *c, int *result);
+ gs_fapi_retcode(*can_simulate_style) (gs_fapi_server *server, gs_fapi_font *ff, gs_fapi_style style, void *style_data);
+ gs_fapi_retcode(*get_fontmatrix) (gs_fapi_server *server, gs_matrix *m);
+ gs_fapi_retcode(*get_char_width) (gs_fapi_server *server, gs_fapi_font *ff, gs_fapi_char_ref *c, gs_fapi_metrics *metrics);
+ gs_fapi_retcode(*get_char_raster_metrics) (gs_fapi_server *server, gs_fapi_font *ff, gs_fapi_char_ref *c, gs_fapi_metrics *metrics);
+ gs_fapi_retcode(*get_char_raster) (gs_fapi_server *server, gs_fapi_raster *r);
+ gs_fapi_retcode(*get_char_outline_metrics) (gs_fapi_server *server, gs_fapi_font *ff, gs_fapi_char_ref *c, gs_fapi_metrics *metrics);
+ gs_fapi_retcode(*get_char_outline) (gs_fapi_server *server, gs_fapi_path *p);
+ gs_fapi_retcode(*release_char_data) (gs_fapi_server *server);
+
+ gs_fapi_retcode(*release_typeface) (gs_fapi_server *server, void *server_font_data);
+ gs_fapi_retcode(*check_cmap_for_GID) (gs_fapi_server *server, uint *index);
+ gs_fapi_retcode(*get_font_info) (gs_fapi_server *server, gs_fapi_font *ff, gs_fapi_font_info item, int index, void *data, int *datalen);
+
+ /* Some people get confused with terms "font cache" and "character cache".
+ "font cache" means a cache for scaled font objects, which mainly
+ keep the font header information and rules for adjusting it to specific raster.
+ "character cahce" is a cache for specific character outlines and/or character rasters.
+ */
+ /* get_scaled_font opens a typeface with a server and scales it according to CTM and HWResolution.
+ This creates a server's scaled font object.
+ Since UFST doesn't provide a handle to this object,
+ we need to build the data for it and call this function whenever scaled font data may change.
+ The server must cache scaled fonts internally.
+ Note that FreeType doesn't provide internal font cache,
+ so the bridge must do.
+ */
+ /* Due to the interpreter fallback with CDevProc,
+ get_char_raster_metrics leaves some data kept by the server,
+ so taht get_char_raster uses them and release_char_data releases them.
+ Therefore calls from GS to these functions must not
+ interfer with different characters.
+ */
+};
+
+/* The font type 10 (ft_CID_user_defined) must not pass to FAPI. */
+#define FAPI_ISCIDFONT(basefont) basefont->FontType == ft_CID_encrypted ||\
+ basefont->FontType == ft_CID_user_defined || \
+ basefont->FontType == ft_CID_TrueType
+
+
+#define FAPI_ISTYPE1GLYPHDATA(basefont) pbfont->FontType == ft_encrypted || \
+ basefont->FontType == ft_encrypted2 ||\
+ basefont->FontType == ft_CID_encrypted
+
+typedef int (*gs_fapi_get_server_param_callback) (gs_fapi_server *I,
+ const char *subtype,
+ char **server_param,
+ int *server_param_size);
+
+typedef int (*gs_fapi_server_init_func) (gs_memory_t *mem,
+ gs_fapi_server **server);
+
+#define fapi_init_func(proc)\
+ int proc(gs_memory_t *mem, gs_fapi_server **server)
+
+/* Convienence function which uses a client's "prototype" gs_fapi_font
+ * to fill in the actual fapi font for a gs_font, and sets the opaque
+ * pointer for the client's private data (ctx_ptr).
+ */
+void gs_fapi_set_servers_client_data(gs_memory_t *mem,
+ const gs_fapi_font *ff_proto,
+ void *ctx_ptr);
+
+/* Retrieve and initialize a FAPI server by name */
+int gs_fapi_find_server(gs_memory_t *mem, const char *name,
+ gs_fapi_server **server,
+ gs_fapi_get_server_param_callback
+ get_server_param_cb);
+
+gs_fapi_server **gs_fapi_get_server_list(gs_memory_t *mem);
+
+/* Check if a FAPI server is available by name (server). If
+ * server == NULL it just checks whether FAPI is there at all
+ */
+bool gs_fapi_available(gs_memory_t *mem, char *server);
+
+int gs_fapi_get_metrics_count(gs_fapi_font *ff);
+
+int
+gs_fapi_prepare_font(gs_font *pfont, gs_fapi_server *I, int subfont, const char *font_file_path,
+ gs_string *full_font_buf, const char *xlatmap, const char **decodingID);
+
+int
+gs_fapi_finish_render(gs_font *pfont, gs_state *pgs, gs_text_enum_t *penum, gs_fapi_server *I);
+
+int
+gs_fapi_do_char(gs_font *pfont, gs_state *pgs, gs_text_enum_t *penum, char *font_file_path,
+ bool bBuildGlyph, gs_string *charstring, gs_string *glyphname,
+ gs_char chr, gs_glyph index, int subfont);
+
+/* "General purpose" call to allow the client to interrogate
+ * the font through the FAPI server - WARNING: depends on the
+ * capabilities of the server.
+ * The caller needs to pass in memory (data) large enough (data_len)
+ * to hold the requested information - data == NULL, or data_len too
+ * small will see data_len set to the required amount, and an error
+ * returned.
+ */
+int
+gs_fapi_get_font_info(gs_font *pfont, gs_fapi_font_info item, int index,
+ void *data, int *data_len);
+
+int
+gs_fapi_passfont(gs_font *pfont, int subfont, char *font_file_path,
+ gs_string *full_font_buf, char *fapi_request, char *xlatmap,
+ char **fapi_id, gs_fapi_get_server_param_callback get_server_param_cb);
+
+int gs_fapi_init(gs_memory_t *mem);
+
+void gs_fapi_finit(gs_memory_t *mem);
+
+
+void gx_fapi_get_ulp_character_data(byte **header, byte **character_data);
+#endif /* gxfapi_INCLUDED */
diff --git a/gs/base/gxfapiu.c b/gs/base/gxfapiu.c
index 1b65152b9..7ee9408bf 100644
--- a/gs/base/gxfapiu.c
+++ b/gs/base/gxfapiu.c
@@ -19,6 +19,7 @@
/* GS includes : */
#include "std.h"
#include "gx.h"
+#include "stream.h"
#include "strmio.h"
#include "gsmalloc.h"
@@ -50,16 +51,22 @@ static gs_memory_t *gs_mem_ctx = NULL;
struct IF_STATE;
-static LPUB8 stub_PCLEO_charptr(FSP LPUB8 pfont_hdr, UW16 sym_code)
-{ return NULL;
+static LPUB8
+stub_PCLEO_charptr(FSP LPUB8 pfont_hdr, UW16 sym_code)
+{
+ return NULL;
}
-static LPUB8 stub_PCLchId2ptr(FSP UW16 chId)
-{ return NULL;
+static LPUB8
+stub_PCLchId2ptr(FSP UW16 chId)
+{
+ return NULL;
}
-static LPUB8 stub_PCLglyphID2Ptr(FSP UW16 glyphID)
-{ return NULL;
+static LPUB8
+stub_PCLglyphID2Ptr(FSP UW16 glyphID)
+{
+ return NULL;
}
/* This global is defined here because the UFST needs it to link against. */
@@ -73,130 +80,157 @@ They could be stored in the gs_lib_ctx but that would require casting the types
to avoid including ufst's typedefs.
*/
-static LPUB8 (*m_PCLEO_charptr)(FSP LPUB8 pfont_hdr, UW16 sym_code) = stub_PCLEO_charptr;
-static LPUB8 (*m_PCLchId2ptr)(FSP UW16 chId) = stub_PCLchId2ptr;
-static LPUB8 (*m_PCLglyphID2Ptr)(FSP UW16 glyphID) = stub_PCLglyphID2Ptr;
+static LPUB8(*m_PCLEO_charptr) (FSP LPUB8 pfont_hdr, UW16 sym_code) =
+ stub_PCLEO_charptr;
+static LPUB8(*m_PCLchId2ptr) (FSP UW16 chId) = stub_PCLchId2ptr;
+static LPUB8(*m_PCLglyphID2Ptr) (FSP UW16 glyphID) = stub_PCLglyphID2Ptr;
+
#if !UFST_REENTRANT
-static fco_list_elem static_fco_list[MAX_STATIC_FCO_COUNT] = {0, 0, 0, 0};
+static fco_list_elem static_fco_list[MAX_STATIC_FCO_COUNT] = { 0, 0, 0, 0 };
static char static_fco_paths[MAX_STATIC_FCO_COUNT][gp_file_name_sizeof];
static int static_fco_count = 0;
static bool ufst_initialized = FALSE;
#endif
-LPUB8 PCLEO_charptr(FSP LPUB8 pfont_hdr, UW16 sym_code)
-{ return m_PCLEO_charptr(FSA pfont_hdr, sym_code);
+LPUB8
+PCLEO_charptr(FSP LPUB8 pfont_hdr, UW16 sym_code)
+{
+ return m_PCLEO_charptr(FSA pfont_hdr, sym_code);
}
-LPUB8 PCLchId2ptr(FSP UW16 chId)
-{ return m_PCLchId2ptr(FSA chId);
+LPUB8
+PCLchId2ptr(FSP UW16 chId)
+{
+ return m_PCLchId2ptr(FSA chId);
}
-LPUB8 PCLglyphID2Ptr(FSP UW16 glyphID)
-{ return m_PCLglyphID2Ptr(FSA glyphID);
+LPUB8
+PCLglyphID2Ptr(FSP UW16 glyphID)
+{
+ return m_PCLglyphID2Ptr(FSA glyphID);
}
/* File handling intermediates */
-FILE * FAPIU_fopen (char *path, char *mode)
+void *
+FAPIU_fopen(char *path, char *mode)
{
if (!gs_mem_ctx)
return NULL;
- return((FILE *)sfopen(path, mode, gs_mem_ctx));
+ return ((void *)sfopen(path, mode, gs_mem_ctx));
}
-int FAPIU_fread (void *ptr, int size, int count, FILE *s)
+int
+FAPIU_fread(void *ptr, int size, int count, void *s)
{
- return(sfread(ptr, size, count, (stream *)(s)));
+ return (sfread(ptr, size, count, (stream *) (s)));
}
-int FAPIU_fgetc (FILE *s)
+int
+FAPIU_fgetc(void *s)
{
- return(sfgetc((stream *)(s)));
+ return (sfgetc((stream *) (s)));
}
-int FAPIU_fseek (FILE *s, int offset, int whence)
+int
+FAPIU_fseek(void *s, int offset, int whence)
{
- return(sfseek((stream *)(s), offset, whence));
+ return (sfseek((stream *) (s), offset, whence));
}
-int FAPIU_frewind (FILE *s)
+int
+FAPIU_frewind(void *s)
{
- return(srewind((stream *)(s)));
+ return (srewind((stream *) (s)));
}
-int FAPIU_ftell (FILE *s)
+int
+FAPIU_ftell(void *s)
{
- return(sftell((stream *)(s)));
+ return (sftell((stream *) (s)));
}
-int FAPIU_feof (FILE *s)
+int
+FAPIU_feof(void *s)
{
- return(sfeof((stream *)(s)));
+ return (sfeof((stream *) (s)));
}
-int FAPIU_ferror (FILE *s)
+int
+FAPIU_ferror(void *s)
{
- return(sferror((stream *)(s)));
+ return (sferror((stream *) (s)));
}
-int FAPIU_fclose (FILE *s)
+int
+FAPIU_fclose(void *s)
{
- return(sfclose((stream *)(s)));
+ return (sfclose((stream *) (s)));
}
-void * FAPIU_open (char *path, int mode)
+void *
+FAPIU_open(char *path, int mode)
{
+ void *s;
+
if (!gs_mem_ctx)
- return NULL;
+ return (void *)-1;
/* FIXME: "mode" needs work */
- return(sfopen(path, "r+", gs_mem_ctx));
+ s = sfopen(path, "r+", gs_mem_ctx);
+ if (!s)
+ s = (void *)-1;
+
+ return (s);
}
-int FAPIU_read (void *s, void *ptr, int count)
+int
+FAPIU_read(void *s, void *ptr, int count)
{
- return(sfread(ptr, 1, count, (stream *)(s)));
+ return (sfread(ptr, 1, count, (stream *) (s)));
}
-int FAPIU_lseek (void *s, int offset, int whence)
+int
+FAPIU_lseek(void *s, int offset, int whence)
{
- int pos = sfseek (s, offset, whence);
+ int pos = sfseek(s, offset, whence);
- if (pos >= 0)
- {
+ if (pos >= 0) {
pos = sftell(s);
}
- return(pos);
+ return (pos);
}
-int fapi_ufseek (stream *s, long offset, int whence)
+int
+fapi_ufseek(stream * s, long offset, int whence)
{
- int pos = sfseek (s, offset, whence);
+ int pos = sfseek(s, offset, whence);
- if (pos >= 0)
- {
+ if (pos >= 0) {
pos = sftell(s);
}
- return(pos);
+ return (pos);
}
-int FAPIU_close (void *s)
+int
+FAPIU_close(void *s)
{
- return(sfclose((stream *)(s)));
+ return (sfclose((stream *) (s)));
}
#if UFST_VERSION_MAJOR >= 6 && UFST_VERSION_MINOR >= 2
-GLOBAL VOID MEMinit(FSP0)
+GLOBAL VOID
+MEMinit(FSP0)
{
- if_state.pserver->mem_avail[CACHE_POOL] = 16 * 1024 * 1024;
- if_state.pserver->mem_fund[CACHE_POOL] = 16 * 1024 * 1024;
+ if_state.pserver->mem_avail[CACHE_POOL] = 16 * 1024 * 1024;
+ if_state.pserver->mem_fund[CACHE_POOL] = 16 * 1024 * 1024;
- if_state.pserver->mem_avail[BUFFER_POOL] = 4 * 1024 * 1024;
- if_state.pserver->mem_fund[BUFFER_POOL] = 4 * 1024 * 1024;
+ if_state.pserver->mem_avail[BUFFER_POOL] = 4 * 1024 * 1024;
+ if_state.pserver->mem_fund[BUFFER_POOL] = 4 * 1024 * 1024;
- if_state.pserver->mem_avail[CHARGEN_POOL] = 16 * 1024 * 1024;
- if_state.pserver->mem_fund[CHARGEN_POOL] = 16 * 1024 * 1024;
+ if_state.pserver->mem_avail[CHARGEN_POOL] = 16 * 1024 * 1024;
+ if_state.pserver->mem_fund[CHARGEN_POOL] = 16 * 1024 * 1024;
}
#ifndef UFST_MEMORY_CHECKING
@@ -208,20 +242,22 @@ static unsigned long curmem = 0;
unsigned long maxmem = 0;
#endif
-GLOBAL MEM_HANDLE MEMalloc(FSP UW16 pool, SL32 size)
+GLOBAL MEM_HANDLE
+MEMalloc(FSP UW16 pool, SL32 size)
{
- void *ptr;
+ char *ptr;
+
#if UFST_MEMORY_CHECKING
- void *ptr2;
+ char *ptr2;
size += sizeof(long) + 2 * sizeof(void *);
#endif
size += sizeof(long);
- ptr = gs_malloc (gs_mem_ctx, size, 1, "UFST MEMalloc");
- if(!ptr) {
- return(NIL_MH);
+ ptr = gs_malloc(gs_mem_ctx, size, 1, "UFST MEMalloc");
+ if (!ptr) {
+ return (NIL_MH);
}
else {
*((long *)ptr) = size;
@@ -240,18 +276,21 @@ GLOBAL MEM_HANDLE MEMalloc(FSP UW16 pool, SL32 size)
size -= 2 * sizeof(long);
*((char *)ptr) = ptr2;
*((char *)(ptr + size - sizeof(void *))) = ptr2;
- ptr += sizeof(void *);
+ ptr += sizeof(char *);
#endif
- return((MEM_HANDLE)ptr);
+ return ((MEM_HANDLE) ptr);
}
}
-GLOBAL VOID MEMfree(FSP UW16 pool, MEM_HANDLE ptr)
+GLOBAL VOID
+MEMfree(FSP UW16 pool, MEM_HANDLE ptr0)
{
int size = 0;
void *ptr1;
+ char *ptr = (char *)ptr0;
+
#if UFST_MEMORY_CHECKING
int size1;
void *ptr2;
@@ -282,8 +321,8 @@ GLOBAL VOID MEMfree(FSP UW16 pool, MEM_HANDLE ptr)
}
#endif
- memset (ptr, 0x00, size);
- gs_free (gs_mem_ctx, ptr, 0, 0, "UFST MEMfree");
+ memset(ptr, 0x00, size);
+ gs_free(gs_mem_ctx, ptr, 0, 0, "UFST MEMfree");
}
#endif
@@ -298,12 +337,18 @@ GLOBAL VOID MEMfree(FSP UW16 pool, MEM_HANDLE ptr)
really change on the first demand only.
See also a comment in gs_fapiufst_finit.
*/
-void gx_set_UFST_Callbacks(LPUB8 (*p_PCLEO_charptr)(FSP LPUB8 pfont_hdr, UW16 sym_code),
- LPUB8 (*p_PCLchId2ptr)(FSP UW16 chId),
- LPUB8 (*p_PCLglyphID2Ptr)(FSP UW16 glyphID))
-{ m_PCLEO_charptr = (p_PCLEO_charptr != NULL ? p_PCLEO_charptr : stub_PCLEO_charptr);
- m_PCLchId2ptr = (p_PCLchId2ptr != NULL ? p_PCLchId2ptr : stub_PCLchId2ptr);
- m_PCLglyphID2Ptr = (p_PCLglyphID2Ptr != NULL ? p_PCLglyphID2Ptr : stub_PCLglyphID2Ptr);
+void
+gx_set_UFST_Callbacks(LPUB8(*p_PCLEO_charptr)
+ (FSP LPUB8 pfont_hdr, UW16 sym_code),
+ LPUB8(*p_PCLchId2ptr) (FSP UW16 chId),
+ LPUB8(*p_PCLglyphID2Ptr) (FSP UW16 glyphID))
+{
+ m_PCLEO_charptr =
+ (p_PCLEO_charptr != NULL ? p_PCLEO_charptr : stub_PCLEO_charptr);
+ m_PCLchId2ptr =
+ (p_PCLchId2ptr != NULL ? p_PCLchId2ptr : stub_PCLchId2ptr);
+ m_PCLglyphID2Ptr =
+ (p_PCLglyphID2Ptr != NULL ? p_PCLglyphID2Ptr : stub_PCLglyphID2Ptr);
}
#define MAX_OPEN_LIBRARIES 5 /* NB */
@@ -315,9 +360,9 @@ void gx_set_UFST_Callbacks(LPUB8 (*p_PCLEO_charptr)(FSP LPUB8 pfont_hdr, UW16 s
* <0 = error.
*/
int
-gx_UFST_init(gs_memory_t *mem, const UB8 *ufst_root_dir)
+gx_UFST_init(gs_memory_t * mem, const UB8 * ufst_root_dir)
{
- IFCONFIG config_block;
+ IFCONFIG config_block;
int status;
#if !UFST_REENTRANT
@@ -327,8 +372,8 @@ gx_UFST_init(gs_memory_t *mem, const UB8 *ufst_root_dir)
#endif
strcpy(config_block.ufstPath, ufst_root_dir);
strcpy(config_block.typePath, ufst_root_dir);
- config_block.num_files = MAX_OPEN_LIBRARIES; /* max open library files */
- config_block.bit_map_width = BITMAP_WIDTH; /* bitmap width 1, 2 or 4 */
+ config_block.num_files = MAX_OPEN_LIBRARIES; /* max open library files */
+ config_block.bit_map_width = BITMAP_WIDTH; /* bitmap width 1, 2 or 4 */
/* These parameters were set in open_UFST() (fapiufst.c) but were left
uninitialized in pl_load_built_in_fonts() (plulfont.c). */
@@ -344,6 +389,7 @@ gx_UFST_init(gs_memory_t *mem, const UB8 *ufst_root_dir)
gs_mem_ctx = NULL;
return status;
}
+ CGIFfont_access(FSA DISK_ACCESS);
if ((status = CGIFenter(FSA0)) != 0) {
dmprintf1(mem, "CGIFenter() error: %u\n",status);
gs_mem_ctx = NULL;
@@ -352,7 +398,7 @@ gx_UFST_init(gs_memory_t *mem, const UB8 *ufst_root_dir)
#if !UFST_REENTRANT
ufst_initialized = TRUE;
#endif
- return 1; /* first time, caller may have more initialization to do */
+ return 1; /* first time, caller may have more initialization to do */
}
int
@@ -368,7 +414,8 @@ gx_UFST_fini(void)
/* Access to the static FCO list for the language switching project. */
-fco_list_elem *gx_UFST_find_static_fco(const char *font_file_path)
+fco_list_elem *
+gx_UFST_find_static_fco(const char *font_file_path)
{
#if !UFST_REENTRANT
int i;
@@ -380,7 +427,8 @@ fco_list_elem *gx_UFST_find_static_fco(const char *font_file_path)
return NULL;
}
-fco_list_elem *gx_UFST_find_static_fco_handle(SW16 fcHandle)
+fco_list_elem *
+gx_UFST_find_static_fco_handle(SW16 fcHandle)
{
#if !UFST_REENTRANT
int i;
@@ -392,7 +440,8 @@ fco_list_elem *gx_UFST_find_static_fco_handle(SW16 fcHandle)
return NULL;
}
-SW16 gx_UFST_find_fco_handle_by_name(const char *font_file_path)
+SW16
+gx_UFST_find_fco_handle_by_name(const char *font_file_path)
{
#if !UFST_REENTRANT
fco_list_elem *fco = gx_UFST_find_static_fco(font_file_path);
@@ -403,7 +452,8 @@ SW16 gx_UFST_find_fco_handle_by_name(const char *font_file_path)
#endif
}
-UW16 gx_UFST_open_static_fco(const char *font_file_path, SW16 *result_fcHandle)
+UW16
+gx_UFST_open_static_fco(const char *font_file_path, SW16 * result_fcHandle)
{
#if !UFST_REENTRANT
SW16 fcHandle;
@@ -412,7 +462,7 @@ UW16 gx_UFST_open_static_fco(const char *font_file_path, SW16 *result_fcHandle)
if (static_fco_count >= MAX_STATIC_FCO_COUNT)
return ERR_fco_NoMem;
- code = CGIFfco_Open(FSA (UB8 *)font_file_path, &fcHandle);
+ code = CGIFfco_Open(FSA(UB8 *) font_file_path, &fcHandle);
if (code != 0)
return code;
e = &static_fco_list[static_fco_count];
@@ -420,7 +470,7 @@ UW16 gx_UFST_open_static_fco(const char *font_file_path, SW16 *result_fcHandle)
sizeof(static_fco_paths[static_fco_count]));
e->file_path = static_fco_paths[static_fco_count];
e->fcHandle = fcHandle;
- e->open_count = -1; /* Unused for static FCOs. */
+ e->open_count = -1; /* Unused for static FCOs. */
static_fco_count++;
*result_fcHandle = fcHandle;
return 0;
@@ -430,7 +480,8 @@ UW16 gx_UFST_open_static_fco(const char *font_file_path, SW16 *result_fcHandle)
#endif
}
-UW16 gx_UFST_close_static_fco(SW16 fcHandle)
+UW16
+gx_UFST_close_static_fco(SW16 fcHandle)
{
#if !UFST_REENTRANT
int i;
@@ -450,10 +501,11 @@ UW16 gx_UFST_close_static_fco(SW16 fcHandle)
return 0;
}
-void gx_UFST_close_static_fcos()
+void
+gx_UFST_close_static_fcos()
{
#if !UFST_REENTRANT
- for(; static_fco_count; )
+ for (; static_fco_count;)
gx_UFST_close_static_fco(static_fco_list[0].fcHandle);
#endif
}
@@ -464,9 +516,10 @@ void gx_UFST_close_static_fcos()
* Returns: VOID
* Notes: This is a stub implementation for graymap.
*/
-GLOBAL VOID BLACKPIX(FSP SW16 x, SW16 y )
+GLOBAL VOID
+BLACKPIX(FSP SW16 x, SW16 y)
{
- return;
+ return;
}
/* -------------------------------- GRAYPIX --------------------------------
@@ -474,8 +527,9 @@ GLOBAL VOID BLACKPIX(FSP SW16 x, SW16 y )
* Returns: VOID
* Notes: This is a stub implementation for graymap.
*/
-GLOBAL VOID GRAYPIX(FSP SW16 x, SW16 y, SW16 v )
+GLOBAL VOID
+GRAYPIX(FSP SW16 x, SW16 y, SW16 v)
{
- return;
+ return;
}
-#endif /* GRAYSCALING */
+#endif /* GRAYSCALING */
diff --git a/gs/base/gxfapiu.h b/gs/base/gxfapiu.h
index 03b705716..47197de37 100644
--- a/gs/base/gxfapiu.h
+++ b/gs/base/gxfapiu.h
@@ -35,14 +35,17 @@
really change on the first demand only.
See also a comment in gs_fapiufst_finit.
*/
-void gx_set_UFST_Callbacks(LPUB8 (*p_PCLEO_charptr)(FSP LPUB8 pfont_hdr, UW16 sym_code),
- LPUB8 (*p_PCLchId2ptr)(FSP UW16 chId),
- LPUB8 (*p_PCLglyphID2Ptr)(FSP UW16 glyphID));
+void
+gx_set_UFST_Callbacks(LPUB8(*p_PCLEO_charptr)
+ (FSP LPUB8 pfont_hdr, UW16 sym_code),
+ LPUB8(*p_PCLchId2ptr) (FSP UW16 chId),
+ LPUB8(*p_PCLglyphID2Ptr) (FSP UW16 glyphID));
void gx_reset_UFST_Callbacks(void);
typedef struct fco_list_elem_s fco_list_elem;
-struct fco_list_elem_s {
+struct fco_list_elem_s
+{
int open_count;
SW16 fcHandle;
char *file_path;
@@ -51,8 +54,10 @@ struct fco_list_elem_s {
/* Access to the static FCO list for the language switching project : */
/* For the language switch : */
-UW16 gx_UFST_open_static_fco(const char *font_file_path, SW16 *result_fcHandle);
+UW16 gx_UFST_open_static_fco(const char *font_file_path,
+ SW16 * result_fcHandle);
UW16 gx_UFST_close_static_fco(SW16 fcHandle);
+
/* close all open FCO's */
void gx_UFST_close_static_fcos(void);
SW16 gx_UFST_find_fco_handle_by_name(const char *font_file_path);
@@ -61,22 +66,22 @@ SW16 gx_UFST_find_fco_handle_by_name(const char *font_file_path);
fco_list_elem *gx_UFST_find_static_fco(const char *font_file_path);
fco_list_elem *gx_UFST_find_static_fco_handle(SW16 fcHandle);
-int gx_UFST_init(gs_memory_t *mem, const UB8 *ufst_root_dir);
+int gx_UFST_init(gs_memory_t * mem, const UB8 * ufst_root_dir);
int gx_UFST_fini(void);
-FILE * FAPIU_fopen (char *path, char *mode);
-void * FAPIU_open (char *path, int mode);
-int FAPIU_fread (void *ptr, int size, int count, FILE *s);
-int FAPIU_read (void *s, void *ptr, int count);
-int FAPIU_fgetc (FILE *s);
-int FAPIU_fseek (FILE *s, int offset, int whence);
-int FAPIU_lseek (void *s, int offset, int whence);
-int FAPIU_frewind (FILE *s);
-int FAPIU_ftell (FILE *s);
-int FAPIU_feof (FILE *s);
-int FAPIU_ferror (FILE *s);
-int FAPIU_fclose (FILE *s);
-int FAPIU_close (void *s);
+void *FAPIU_fopen(char *path, char *mode);
+void *FAPIU_open(char *path, int mode);
+int FAPIU_fread(void *ptr, int size, int count, void *s);
+int FAPIU_read(void *s, void *ptr, int count);
+int FAPIU_fgetc(void *s);
+int FAPIU_fseek(void *s, int offset, int whence);
+int FAPIU_lseek(void *s, int offset, int whence);
+int FAPIU_frewind(void *s);
+int FAPIU_ftell(void *s);
+int FAPIU_feof(void *s);
+int FAPIU_ferror(void *s);
+int FAPIU_fclose(void *s);
+int FAPIU_close(void *s);
#endif /* gxfapiu_INCLUDED */
diff --git a/gs/base/gxfont.h b/gs/base/gxfont.h
index 6de7fc502..582656f8a 100644
--- a/gs/base/gxfont.h
+++ b/gs/base/gxfont.h
@@ -446,9 +446,9 @@ int gs_font_notify_register(gs_font *font, gs_notify_proc_t proc,
int gs_font_notify_unregister(gs_font *font, gs_notify_proc_t proc,
void *proc_data);
-#ifndef FAPI_server_DEFINED
-#define FAPI_server_DEFINED
-typedef struct FAPI_server_s FAPI_server;
+#ifndef gs_fapi_server_DEFINED
+#define gs_fapi_server_DEFINED
+typedef struct gs_fapi_server_s gs_fapi_server;
#endif
/* Define a base (not composite) font. */
@@ -456,7 +456,7 @@ typedef struct FAPI_server_s FAPI_server;
gs_font_common;\
gs_rect FontBBox;\
gs_uid UID;\
- FAPI_server *FAPI; \
+ gs_fapi_server *FAPI; \
void *FAPI_font_data; \
gs_encoding_index_t encoding_index;\
gs_encoding_index_t nearest_encoding_index /* (may be >= 0 even if */\
diff --git a/gs/base/lib.mak b/gs/base/lib.mak
index 48a6f5b21..e8d873c0e 100644
--- a/gs/base/lib.mak
+++ b/gs/base/lib.mak
@@ -950,7 +950,7 @@ $(GLOBJ)gsimpath.$(OBJ) : $(GLSRC)gsimpath.c $(AK) $(gx_h)\
$(GLOBJ)gsinit.$(OBJ) : $(GLSRC)gsinit.c $(AK) $(memory__h) $(stdio__h)\
$(gdebug_h) $(gp_h) $(gscdefs_h) $(gslib_h) $(gsmalloc_h) $(gsmemory_h)\
- $(MAKEDIRS)
+ $(gxfapi_h) $(MAKEDIRS)
$(GLCC) $(GLO_)gsinit.$(OBJ) $(C_) $(GLSRC)gsinit.c
$(GLOBJ)gsiodev.$(OBJ) : $(GLSRC)gsiodev.c $(AK) $(gx_h) $(gserrors_h)\
@@ -1203,6 +1203,79 @@ $(GLOBJ)gdevnfwd.$(OBJ) : $(GLSRC)gdevnfwd.c $(AK) $(gx_h)\
$(MAKEDIRS)
$(GLCC) $(GLO_)gdevnfwd.$(OBJ) $(C_) $(GLSRC)gdevnfwd.c
+# ---------------- Font API ---------------- #
+
+gxfapi_h=$(GLSRC)gxfapi.h $(gsmemory_h) $(gsmatrix_h) $(gsccode_h) $(stdint__h)
+
+# stub for UFST bridge support :
+
+$(GLD)gxfapiu.dev : $(LIB_MAK) $(ECHOGS_XE)
+ $(SETMOD) $(GLD)gxfapiu
+
+wrfont_h=$(stdpre_h) $(GLSRC)wrfont.h
+write_t1_h=$(gxfapi_h) $(GLSRC)write_t1.h
+write_t2_h=$(gxfapi_h) $(GLSRC)write_t2.h
+
+$(GLOBJ)write_t1.$(OBJ) : $(GLSRC)write_t1.c $(AK)\
+ $(wrfont_h) $(write_t1_h)
+ $(GLCC) $(FT_CFLAGS) $(GLO_)write_t1.$(OBJ) $(C_) $(GLSRC)write_t1.c
+
+$(GLOBJ)write_t2.$(OBJ) : $(GLSRC)write_t2.c $(AK)\
+ $(wrfont_h) $(write_t2_h) $(gxfont_h) $(gxfont1_h) $(gzstate_h) $(stdpre_h)
+ $(GLCC) $(FT_CFLAGS) $(GLO_)write_t2.$(OBJ) $(C_) $(GLSRC)write_t2.c
+
+$(GLOBJ)wrfont.$(OBJ) : $(GLSRC)wrfont.c $(AK)\
+ $(wrfont_h) $(stdio__h)
+ $(GLCC) $(FT_CFLAGS) $(GLO_)wrfont.$(OBJ) $(C_) $(GLSRC)wrfont.c
+
+# stub for UFST bridge :
+
+$(GLD)fapiu.dev : $(INT_MAK) $(ECHOGS_XE)
+ $(SETMOD) $(GLD)fapiu
+
+# stub for Bitstream bridge (see fapi_bs.mak):
+
+$(GLD)fapib.dev : $(INT_MAK) $(ECHOGS_XE)
+ $(SETMOD) $(GLD)fapib
+
+# FreeType bridge :
+
+# the top-level makefile should define
+# FT_CFLAGS for the include directive and other switches
+
+$(GLD)fapif1.dev : $(INT_MAK) $(ECHOGS_XE) $(GLOBJ)fapi_ft.$(OBJ) \
+ $(GLOBJ)write_t1.$(OBJ) $(GLOBJ)write_t2.$(OBJ) $(GLOBJ)wrfont.$(OBJ) \
+ $(GLD)freetype.dev
+ $(SETMOD) $(GLD)fapif1 $(GLOBJ)fapi_ft.$(OBJ) $(GLOBJ)write_t1.$(OBJ)
+ $(ADDMOD) $(GLD)fapif1 $(GLOBJ)write_t2.$(OBJ) $(GLOBJ)wrfont.$(OBJ)
+ $(ADDMOD) $(GLD)fapif1 -include $(GLD)freetype
+ $(ADDMOD) $(GLD)fapif1 -fapi fapi_ft
+
+$(GLOBJ)fapi_ft.$(OBJ) : $(GLSRC)fapi_ft.c $(AK)\
+ $(stdio__h) $(malloc__h) $(write_t1_h) $(write_t2_h) $(math__h) $(gserrors_h)\
+ $(gsmemory_h) $(gsmalloc_h) $(gxfixed_h) $(gdebug_h) $(gxbitmap_h) $(gsmchunk_h) \
+ $(stream_h) $(gxiodev_h) $(gsfname_h) $(gxfapi_h)
+ $(GLCC) $(FT_CFLAGS) $(GLO_)fapi_ft.$(OBJ) $(C_) $(GLSRC)fapi_ft.c
+
+# stub for FreeType bridge :
+
+$(GLD)fapif0.dev : $(INT_MAK) $(ECHOGS_XE)
+ $(SETMOD) $(GLD)fapif0
+
+
+$(GLOBJ)gxfapi.$(OBJ) : $(GLSRC)gxfapi.c $(memory__h) $(gsmemory_h) $(gserrors_h) $(gxdevice_h) \
+ $(gxfont_h) $(gxfont1_h) $(gxpath_h) $(gxfcache_h) $(gxchrout_h) $(gximask_h) \
+ $(gscoord_h) $(gspaint_h) $(gspath_h) $(gzstate_h) $(gxfcid_h) $(gxchar_h) \
+ $(gdebug_h) $(gsimage_h) $(gxfapi_h) $(gsbittab_h)
+ $(GLCC) $(GLO_)gxfapi.$(OBJ) $(C_) $(GLSRC)gxfapi.c
+
+$(GLD)gxfapi.dev : $(LIB_MAK) $(ECHOGS_XE) $(GLOBJ)gxfapi.$(OBJ) $(GLD)fapiu$(UFST_BRIDGE).dev \
+ $(GLD)fapif$(FT_BRIDGE).dev $(GLD)fapib$(BITSTREAM_BRIDGE).dev
+ $(SETMOD) $(GLD)gxfapi $(GLOBJ)gxfapi.$(OBJ)
+ $(ADDMOD) $(GLD)gxfapi -include $(GLD)fapiu$(UFST_BRIDGE)
+ $(ADDMOD) $(GLD)gxfapi -include $(GLD)fapif$(FT_BRIDGE)
+ $(ADDMOD) $(GLD)gxfapi -include $(GLD)fapib$(BITSTREAM_BRIDGE)
+
### Other device support
# Provide a mapping between StandardEncoding and ISOLatin1Encoding.
@@ -1263,7 +1336,7 @@ LIB_ALL=$(LIBs) $(LIBx) $(LIBd)
# but not in the link, to catch compilation problems.
LIB_O=$(GLOBJ)gdevmpla.$(OBJ) $(GLOBJ)gdevmrun.$(OBJ) $(GLOBJ)gshtx.$(OBJ) $(GLOBJ)gsnogc.$(OBJ)
$(GLD)libs.dev : $(LIB_MAK) $(ECHOGS_XE) $(LIBs) $(LIB_O) $(GLD)gsiodevs.dev $(GLD)translib.dev \
- $(GLD)clist.dev
+ $(GLD)clist.dev $(GLD)gxfapi.dev
$(SETMOD) $(GLD)libs $(LIB0s)
$(ADDMOD) $(GLD)libs $(LIB1s)
$(ADDMOD) $(GLD)libs $(LIB2s)
@@ -1284,6 +1357,8 @@ $(GLD)libs.dev : $(LIB_MAK) $(ECHOGS_XE) $(LIBs) $(LIB_O) $(GLD)gsiodevs.dev $(G
$(ADDMOD) $(GLD)libs -include $(GLD)gsiodevs
$(ADDMOD) $(GLD)libs -include $(GLD)translib
$(ADDMOD) $(GLD)libs -include $(GLD)clist
+ $(ADDMOD) $(GLD)libs $(GLD)gxfapi
+ $(ADDMOD) $(GLD)libs -init fapi
$(GLD)libx.dev : $(LIB_MAK) $(ECHOGS_XE) $(LIBx)
$(SETMOD) $(GLD)libx $(LIB1x)
$(ADDMOD) $(GLD)libx $(LIB2x)
@@ -3127,32 +3202,6 @@ $(GLOBJ)gsiomacres.$(OBJ) : $(GLSRC)gsiomacres.c $(gdebug_h) $(gp_h)\
$(malloc__h) $(stdio__h) $(stream_h) $(string__h) $(MAKEDIRS)
$(GLCC) $(GLO_)gsiomacres.$(OBJ) $(C_) $(GLSRC)gsiomacres.c
-# ---------------- Font API ---------------- #
-
-# UFST bridge support :
-# This stuff dispatches UFST callbacks for a multilianual (PS, PCL) architecture.
-
-UFST_INC_1=$(I_)$(UFST_ROOT)$(D)sys$(D)inc$(_I) $(I_)$(UFST_ROOT)$(D)rts$(D)inc$(_I) $(I_)$(UFST_ROOT)$(D)rts$(D)tt$(_I)
-UFST_INC_=$(UFST_INC_1) $(I_)$(UFST_ROOT)$(D)rts$(D)fco$(_I) $(I_)$(UFST_ROOT)$(D)rts$(D)gray$(_I)
-
-gxfapiu_h=$(GLSRC)gxfapiu.h $(gp_h)
-
-$(GLD)gxfapiu1.dev : $(LIB_MAK) $(ECHOGS_XE) $(GLOBJ)gxfapiu.$(OBJ)
- $(SETMOD) $(GLD)gxfapiu1 $(GLOBJ)gxfapiu.$(OBJ)
-
-$(GLOBJ)gxfapiu.$(OBJ) : $(GLSRC)gxfapiu.c\
- $(gx_h) $(gxfapiu_h) $(gsmalloc_h) $(std_h) $(strmio_h)\
- $(UFST_ROOT)$(D)rts$(D)inc$(D)cgconfig.h\
- $(UFST_ROOT)$(D)rts$(D)inc$(D)shareinc.h\
- $(UFST_ROOT)$(D)sys$(D)inc$(D)ufstport.h
- $(GLCC) $(UFST_CFLAGS) $(UFST_INC_) $(GLO_)gxfapiu.$(OBJ) $(C_) $(GLSRC)gxfapiu.c
-
-
-# stub for UFST bridge support :
-
-$(GLD)gxfapiu.dev : $(LIB_MAK) $(ECHOGS_XE)
- $(SETMOD) $(GLD)gxfapiu
-
# ================ Platform-specific modules ================ #
# Platform-specific code doesn't really belong here: this is code that is
# shared among multiple platforms.
diff --git a/gs/base/stub.mak b/gs/base/stub.mak
new file mode 100644
index 000000000..28f89040f
--- /dev/null
+++ b/gs/base/stub.mak
@@ -0,0 +1,18 @@
+# Copyright (C) 2001-2012 Artifex Software, Inc.
+# All Rights Reserved.
+#
+# This software is provided AS-IS with no warranty, either express or
+# implied.
+#
+# This software is distributed under license and may not be copied,
+# modified or distributed except as expressly authorized under the terms
+# of the license contained in the file LICENSE in this distribution.
+#
+# Refer to licensing information at http://www.artifex.com or contact
+# Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael,
+# CA 94903, U.S.A., +1(415)492-9861, for further information.
+#
+#
+# empty "stub" makefile - used to stand in for an optional makefile
+# to keep the make "include" directive happy.
+
diff --git a/gs/base/winlib.mak b/gs/base/winlib.mak
index cafc3197a..927157865 100644
--- a/gs/base/winlib.mak
+++ b/gs/base/winlib.mak
@@ -136,6 +136,9 @@ BEGINFILES=$(GLGENDIR)\ccf32.tr\
!include $(GLSRCDIR)\gs.mak
!include $(GLSRCDIR)\lib.mak
!include $(GLSRCDIR)\freetype.mak
+!ifdef UFST_ROOT
+!include $(UFST_ROOT)\fapiufst.mak
+!endif
!include $(GLSRCDIR)\jpeg.mak
# zlib.mak must precede png.mak
!include $(GLSRCDIR)\zlib.mak
diff --git a/gs/base/wrfont.c b/gs/base/wrfont.c
new file mode 100644
index 000000000..69b8ee806
--- /dev/null
+++ b/gs/base/wrfont.c
@@ -0,0 +1,86 @@
+/* Copyright (C) 2001-2012 Artifex Software, Inc.
+ All Rights Reserved.
+
+ This software is provided AS-IS with no warranty, either express or
+ implied.
+
+ This software is distributed under license and may not be copied,
+ modified or distributed except as expressly authorized under the terms
+ of the license contained in the file LICENSE in this distribution.
+
+ Refer to licensing information at http://www.artifex.com or contact
+ Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael,
+ CA 94903, U.S.A., +1(415)492-9861, for further information.
+*/
+
+/*
+Support functions to serialize fonts as PostScript code that can
+then be passed to FreeType via the FAPI FreeType bridge.
+Started by Graham Asher, 9th August 2002.
+*/
+
+#include "wrfont.h"
+#include "stdio_.h"
+
+#define EEXEC_KEY 55665
+#define EEXEC_FACTOR 52845
+#define EEXEC_OFFSET 22719
+
+void
+WRF_init(WRF_output * a_output, unsigned char *a_buffer, long a_buffer_size)
+{
+ a_output->m_pos = a_buffer;
+ a_output->m_limit = a_buffer_size;
+ a_output->m_count = 0;
+ a_output->m_encrypt = false;
+ a_output->m_key = EEXEC_KEY;
+}
+
+void
+WRF_wbyte(WRF_output * a_output, unsigned char a_byte)
+{
+ if (a_output->m_count < a_output->m_limit) {
+ if (a_output->m_encrypt) {
+ a_byte ^= (a_output->m_key >> 8);
+ a_output->m_key =
+ (unsigned short)((a_output->m_key + a_byte) * EEXEC_FACTOR +
+ EEXEC_OFFSET);
+ }
+ *a_output->m_pos++ = a_byte;
+ }
+ a_output->m_count++;
+}
+
+void
+WRF_wtext(WRF_output * a_output, const unsigned char *a_string, long a_length)
+{
+ while (a_length > 0) {
+ WRF_wbyte(a_output, *a_string++);
+ a_length--;
+ }
+}
+
+void
+WRF_wstring(WRF_output * a_output, const char *a_string)
+{
+ while (*a_string)
+ WRF_wbyte(a_output, *a_string++);
+}
+
+void
+WRF_wfloat(WRF_output * a_output, double a_float)
+{
+ char buffer[32];
+
+ sprintf(buffer, "%f", a_float);
+ WRF_wstring(a_output, buffer);
+}
+
+void
+WRF_wint(WRF_output * a_output, long a_int)
+{
+ char buffer[32];
+
+ sprintf(buffer, "%ld", a_int);
+ WRF_wstring(a_output, buffer);
+}
diff --git a/gs/psi/wrfont.h b/gs/base/wrfont.h
index cc32dace7..3e4e25556 100644
--- a/gs/psi/wrfont.h
+++ b/gs/base/wrfont.h
@@ -26,19 +26,21 @@ Started by Graham Asher, 9th August 2002.
#include "stdpre.h"
typedef struct WRF_output_
- {
- unsigned char* m_pos;
- long m_limit;
- long m_count;
- bool m_encrypt;
- unsigned short m_key;
- } WRF_output;
-
-void WRF_init(WRF_output* a_output,unsigned char* a_buffer,long a_buffer_size);
-void WRF_wbyte(WRF_output* a_output,unsigned char a_byte);
-void WRF_wtext(WRF_output* a_output,const unsigned char* a_string,long a_length);
-void WRF_wstring(WRF_output* a_output,const char* a_string);
-void WRF_wfloat(WRF_output* a_output,double a_float);
-void WRF_wint(WRF_output* a_output,long a_int);
+{
+ unsigned char *m_pos;
+ long m_limit;
+ long m_count;
+ bool m_encrypt;
+ unsigned short m_key;
+} WRF_output;
+
+void WRF_init(WRF_output * a_output, unsigned char *a_buffer,
+ long a_buffer_size);
+void WRF_wbyte(WRF_output * a_output, unsigned char a_byte);
+void WRF_wtext(WRF_output * a_output, const unsigned char *a_string,
+ long a_length);
+void WRF_wstring(WRF_output * a_output, const char *a_string);
+void WRF_wfloat(WRF_output * a_output, double a_float);
+void WRF_wint(WRF_output * a_output, long a_int);
#endif
diff --git a/gs/base/write_t1.c b/gs/base/write_t1.c
new file mode 100644
index 000000000..4cffac49f
--- /dev/null
+++ b/gs/base/write_t1.c
@@ -0,0 +1,450 @@
+/* Copyright (C) 2001-2012 Artifex Software, Inc.
+ All Rights Reserved.
+
+ This software is provided AS-IS with no warranty, either express or
+ implied.
+
+ This software is distributed under license and may not be copied,
+ modified or distributed except as expressly authorized under the terms
+ of the license contained in the file LICENSE in this distribution.
+
+ Refer to licensing information at http://www.artifex.com or contact
+ Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael,
+ CA 94903, U.S.A., +1(415)492-9861, for further information.
+*/
+
+/*
+Functions to serialize a type 1 font as PostScript code that can then be
+passed to FreeType via the FAPI FreeType bridge.
+Started by Graham Asher, 26th July 2002.
+*/
+
+#include <stdio.h>
+#include "wrfont.h"
+#include "write_t1.h"
+
+/*
+Public structures and functions in this file are prefixed with FF_ because they are part of
+the FAPI FreeType implementation.
+*/
+
+static void
+write_word_entry(gs_fapi_font * a_fapi_font, WRF_output * a_output,
+ const char *a_name, int a_index, int a_divisor)
+{
+ short x;
+
+ WRF_wbyte(a_output, '/');
+ WRF_wstring(a_output, a_name);
+ WRF_wbyte(a_output, ' ');
+ /* Get the value and convert it from unsigned to signed by assigning it to a short. */
+ x = a_fapi_font->get_word(a_fapi_font, a_index, 0);
+ /* Divide by the divisor to bring it back to font units. */
+ x = (short)(x / a_divisor);
+ WRF_wint(a_output, x);
+ WRF_wstring(a_output, " def\n");
+}
+
+static void
+write_array_entry_with_count(gs_fapi_font * a_fapi_font,
+ WRF_output * a_output, const char *a_name,
+ int a_index, int a_count, int a_divisor)
+{
+ int i;
+
+ if (a_count <= 0)
+ return;
+
+ WRF_wbyte(a_output, '/');
+ WRF_wstring(a_output, a_name);
+ WRF_wstring(a_output, " [");
+ for (i = 0; i < a_count; i++) {
+ /* Get the value and convert it from unsigned to signed by assigning it to a short. */
+ short x = a_fapi_font->get_word(a_fapi_font, a_index, i);
+
+ /* Divide by the divisor to bring it back to font units. */
+ x = (short)(x / a_divisor);
+ WRF_wint(a_output, x);
+ WRF_wbyte(a_output, (byte) (i == a_count - 1 ? ']' : ' '));
+ }
+ WRF_wstring(a_output, " def\n");
+}
+
+static void
+write_array_entry(gs_fapi_font * a_fapi_font, WRF_output * a_output,
+ const char *a_name, int a_index, int a_divisor)
+{
+ /* NOTE that the feature index must be preceded by the count index for this to work. */
+ int count = a_fapi_font->get_word(a_fapi_font, a_index - 1, 0);
+
+ write_array_entry_with_count(a_fapi_font, a_output, a_name, a_index,
+ count, a_divisor);
+}
+
+static void
+write_subrs(gs_fapi_font * a_fapi_font, WRF_output * a_output, int raw)
+{
+ int i;
+ int count =
+ a_fapi_font->get_word(a_fapi_font, gs_fapi_font_feature_Subrs_count,
+ 0);
+ if (count <= 0)
+ return;
+
+ WRF_wstring(a_output, "/Subrs ");
+ WRF_wint(a_output, count);
+ WRF_wstring(a_output, " array\n");
+
+ for (i = 0; i < count; i++) {
+ long length;
+ long buffer_size;
+
+ if (raw)
+ length = a_fapi_font->get_raw_subr(a_fapi_font, i, 0, 0);
+ else
+ length = a_fapi_font->get_subr(a_fapi_font, i, 0, 0);
+ WRF_wstring(a_output, "dup ");
+ WRF_wint(a_output, i);
+ WRF_wbyte(a_output, ' ');
+ WRF_wint(a_output, length);
+ WRF_wstring(a_output, " RD ");
+
+ /* Get the subroutine into the buffer and encrypt it in place. */
+ buffer_size = a_output->m_limit - a_output->m_count;
+ if (buffer_size >= length) {
+ if (raw)
+ a_fapi_font->get_raw_subr(a_fapi_font, i, a_output->m_pos,
+ (ushort) length);
+ else
+ a_fapi_font->get_subr(a_fapi_font, i, a_output->m_pos,
+ (ushort) length);
+ WRF_wtext(a_output, a_output->m_pos, length);
+ } else
+ a_output->m_count += length;
+
+ WRF_wstring(a_output, " NP\n");
+ }
+
+ WRF_wstring(a_output, "ND\n");
+}
+
+static void
+write_charstrings(gs_fapi_font * a_fapi_font, WRF_output * a_output)
+{
+ long length;
+ long buffer_size;
+ int i, count = a_fapi_font->get_word(a_fapi_font,
+ gs_fapi_font_feature_CharStrings_count,
+ 0);
+ char NameBuf[256];
+
+ if (count <= 0)
+ return;
+
+ WRF_wstring(a_output, "2 index /CharStrings ");
+ WRF_wint(a_output, count);
+ WRF_wstring(a_output, " dict dup begin\n");
+ for (i = 0; i < count; i++) {
+ length =
+ a_fapi_font->get_charstring_name(a_fapi_font, i,
+ (byte *) & NameBuf, 256);
+ if (length > 0) {
+ length = a_fapi_font->get_charstring(a_fapi_font, i, 0, 0);
+
+ WRF_wbyte(a_output, '/');
+ WRF_wstring(a_output, (const char *)&NameBuf);
+ WRF_wbyte(a_output, ' ');
+ WRF_wint(a_output, length);
+ WRF_wstring(a_output, " RD ");
+
+ /* Get the CharString into the buffer and encrypt it in place. */
+ buffer_size = a_output->m_limit - a_output->m_count;
+ if (buffer_size >= length) {
+ a_fapi_font->get_charstring(a_fapi_font, i, a_output->m_pos,
+ (ushort) length);
+ WRF_wtext(a_output, a_output->m_pos, length);
+ } else
+ a_output->m_count += length;
+ WRF_wstring(a_output, " ND\n");
+ }
+ }
+ WRF_wstring(a_output, " end");
+}
+
+static int
+is_MM_font(gs_fapi_font * a_fapi_font)
+{
+ return a_fapi_font->get_word(a_fapi_font,
+ gs_fapi_font_feature_DollarBlend, 0);
+}
+
+static void
+write_private_dictionary(gs_fapi_font * a_fapi_font, WRF_output * a_output,
+ int Write_CharStrings)
+{
+ a_output->m_encrypt = true;
+
+ /* Write 4 bytes that must encrypt to at least one character that cannot be a valid hexadecimal character. */
+ WRF_wstring(a_output, "XXXX");
+
+ /*+ to do: correct size of dictionary from 8. */
+ WRF_wstring(a_output, "dup /Private 8 dict dup begin\n");
+
+ WRF_wstring(a_output, "/MinFeature {16 16} def\n");
+ WRF_wstring(a_output, "/password 5839 def\n");
+ if (Write_CharStrings)
+ write_word_entry(a_fapi_font, a_output, "lenIV",
+ gs_fapi_font_feature_lenIV, 1);
+ else
+ WRF_wstring(a_output, "/lenIV -1 def\n"); /* indicate that /subrs are not encoded. */
+ write_word_entry(a_fapi_font, a_output, "BlueFuzz",
+ gs_fapi_font_feature_BlueFuzz, 16);
+
+ WRF_wstring(a_output, "/BlueScale ");
+ WRF_wfloat(a_output,
+ a_fapi_font->get_long(a_fapi_font,
+ gs_fapi_font_feature_BlueScale,
+ 0) / 65536.0);
+ WRF_wstring(a_output, " def\n");
+
+ write_word_entry(a_fapi_font, a_output, "BlueShift",
+ gs_fapi_font_feature_BlueShift, 16);
+ write_array_entry(a_fapi_font, a_output, "BlueValues",
+ gs_fapi_font_feature_BlueValues, 16);
+ write_array_entry(a_fapi_font, a_output, "OtherBlues",
+ gs_fapi_font_feature_OtherBlues, 16);
+ write_array_entry(a_fapi_font, a_output, "FamilyBlues",
+ gs_fapi_font_feature_FamilyBlues, 16);
+ write_array_entry(a_fapi_font, a_output, "FamilyOtherBlues",
+ gs_fapi_font_feature_FamilyOtherBlues, 16);
+ write_word_entry(a_fapi_font, a_output, "ForceBold",
+ gs_fapi_font_feature_ForceBold, 1);
+ write_array_entry_with_count(a_fapi_font, a_output, "StdHW",
+ gs_fapi_font_feature_StdHW, 1, 16);
+ write_array_entry_with_count(a_fapi_font, a_output, "StdVW",
+ gs_fapi_font_feature_StdVW, 1, 16);
+ write_array_entry(a_fapi_font, a_output, "StemSnapH",
+ gs_fapi_font_feature_StemSnapH, 16);
+ write_array_entry(a_fapi_font, a_output, "StemSnapV",
+ gs_fapi_font_feature_StemSnapV, 16);
+
+ if (is_MM_font(a_fapi_font)) {
+ WRF_wstring(a_output, "3 index /Blend get /Private get begin\n");
+ WRF_wstring(a_output, "|-\n");
+ }
+ if (Write_CharStrings)
+ write_subrs(a_fapi_font, a_output, 1);
+ else
+ write_subrs(a_fapi_font, a_output, 0);
+ if (Write_CharStrings)
+ write_charstrings(a_fapi_font, a_output);
+}
+
+static void
+write_blend_dictionary(gs_fapi_font * a_fapi_font, WRF_output * a_output)
+{
+}
+
+static void
+write_main_dictionary(gs_fapi_font * a_fapi_font, WRF_output * a_output,
+ int Write_CharStrings)
+{
+ int i;
+
+ WRF_wstring(a_output, "5 dict begin\n");
+
+ WRF_wstring(a_output, "/FontType 1 def\n");
+
+ WRF_wstring(a_output, "/FontMatrix [");
+ for (i = 0; i < 6; i++) {
+ WRF_wfloat(a_output,
+ a_fapi_font->get_float(a_fapi_font,
+ gs_fapi_font_feature_FontMatrix,
+ i));
+ WRF_wbyte(a_output, (byte) (i == 5 ? ']' : ' '));
+ }
+ WRF_wbyte(a_output, '\n');
+
+ /* For now, specify standard encoding - I think GS will pass glyph indices so doesn't matter. */
+ WRF_wstring(a_output, "/Encoding StandardEncoding def\n");
+
+ WRF_wstring(a_output, "/FontBBox {");
+ for (i = 0; i < 4; i++) {
+ short x =
+ a_fapi_font->get_word(a_fapi_font, gs_fapi_font_feature_FontBBox,
+ i);
+ WRF_wint(a_output, x);
+ WRF_wbyte(a_output, (byte) (i == 3 ? '}' : ' '));
+ }
+ WRF_wbyte(a_output, '\n');
+ if (is_MM_font(a_fapi_font)) {
+ short x, x2;
+ float x1;
+ uint i, j, entries;
+ char Buffer[255];
+
+ entries = 0;
+ x = a_fapi_font->get_word(a_fapi_font,
+ gs_fapi_font_feature_BlendAxisTypes_count,
+ 0);
+ if (x)
+ entries++;
+ x = a_fapi_font->get_word(a_fapi_font,
+ gs_fapi_font_feature_BlendDesignPositionsArrays_count,
+ 0);
+ if (x)
+ entries++;
+ x = a_fapi_font->get_word(a_fapi_font,
+ gs_fapi_font_feature_BlendDesignMapArrays_count,
+ 0);
+ if (x)
+ entries++;
+
+ sprintf(Buffer, "/FontInfo %d dict dup begin\n", entries);
+ WRF_wstring(a_output, Buffer);
+ x = a_fapi_font->get_word(a_fapi_font,
+ gs_fapi_font_feature_BlendAxisTypes_count,
+ 0);
+ if (x) {
+ WRF_wstring(a_output, "/BlendAxisTypes [");
+ for (i = 0; i < x; i++) {
+ WRF_wstring(a_output, " /");
+ a_fapi_font->get_name(a_fapi_font,
+ gs_fapi_font_feature_BlendAxisTypes, i,
+ (char *)&Buffer, 255);
+ WRF_wstring(a_output, Buffer);
+ }
+ WRF_wstring(a_output, "] def\n");
+ }
+ x = a_fapi_font->get_word(a_fapi_font,
+ gs_fapi_font_feature_BlendDesignPositionsArrays_count,
+ 0);
+ if (x) {
+ WRF_wstring(a_output, "/BlendDesignPositions [");
+ x2 = a_fapi_font->get_word(a_fapi_font,
+ gs_fapi_font_feature_BlendAxisTypes_count,
+ 0);
+ for (i = 0; i < x; i++) {
+ WRF_wstring(a_output, "[");
+ for (j = 0; j < x2; j++) {
+ x1 = a_fapi_font->get_float(a_fapi_font,
+ gs_fapi_font_feature_BlendDesignPositionsArrayValue,
+ i * 8 + j);
+ sprintf(Buffer, "%f ", x1);
+ WRF_wstring(a_output, Buffer);
+ }
+ WRF_wstring(a_output, "]");
+ }
+ WRF_wstring(a_output, "] def\n");
+ }
+ x = a_fapi_font->get_word(a_fapi_font,
+ gs_fapi_font_feature_BlendDesignMapArrays_count,
+ 0);
+ if (x) {
+ WRF_wstring(a_output, "/BlendDesignMap [");
+ for (i = 0; i < x; i++) {
+ x2 = a_fapi_font->get_word(a_fapi_font,
+ gs_fapi_font_feature_BlendDesignMapSubArrays_count,
+ i);
+ WRF_wstring(a_output, "[");
+ for (j = 0; j < x2; j++) {
+ WRF_wstring(a_output, "[");
+ x1 = a_fapi_font->get_float(a_fapi_font,
+ gs_fapi_font_feature_BlendDesignPositionsArrayValue,
+ i * 64 + j * 64);
+ sprintf(Buffer, "%f ", x1);
+ WRF_wstring(a_output, Buffer);
+ x1 = a_fapi_font->get_float(a_fapi_font,
+ gs_fapi_font_feature_BlendDesignPositionsArrayValue,
+ i * 64 + j * 64 + 1);
+ sprintf(Buffer, "%f ", x1);
+ WRF_wstring(a_output, Buffer);
+ WRF_wstring(a_output, "]");
+ }
+ WRF_wstring(a_output, "]");
+ }
+ WRF_wstring(a_output, "] def\n");
+ }
+ WRF_wstring(a_output, "end readonly def\n");
+
+ /* Previously we tried to write $Blend twice - the "real" one from the font,
+ * and the boiler plate one below.
+ * For now, I assume there was a good reason for including the second, but it may
+ * be because the "get_proc" method below was missing the code to handle PS name
+ * objects.
+ */
+ if ((x =
+ a_fapi_font->get_word(a_fapi_font,
+ gs_fapi_font_feature_DollarBlend_length,
+ 0)) > 0) {
+ WRF_wstring(a_output, "/$Blend {");
+
+ if (a_output->m_count)
+ a_output->m_count += x;
+ x = a_fapi_font->get_proc(a_fapi_font,
+ gs_fapi_font_feature_DollarBlend, 0,
+ (char *)a_output->m_pos);
+ if (a_output->m_pos)
+ a_output->m_pos += x;
+ WRF_wstring(a_output, "} def\n");
+ } else {
+ WRF_wstring(a_output,
+ "/$Blend {0.1 mul exch 0.45 mul add exch 0.17 mul add add} def\n");
+ }
+ WRF_wstring(a_output, "/WeightVector [");
+ x = a_fapi_font->get_word(a_fapi_font,
+ gs_fapi_font_feature_WeightVector_count, 0);
+ for (i = 0; i < x; i++) {
+ x1 = a_fapi_font->get_float(a_fapi_font,
+ gs_fapi_font_feature_WeightVector, i);
+ sprintf(Buffer, "%f ", x1);
+ WRF_wstring(a_output, Buffer);
+ }
+ WRF_wstring(a_output, "] def\n");
+ }
+ WRF_wstring(a_output, "currentdict end\ncurrentfile eexec\n");
+ write_private_dictionary(a_fapi_font, a_output, Write_CharStrings);
+ if (is_MM_font(a_fapi_font)) {
+ write_blend_dictionary(a_fapi_font, a_output);
+ }
+}
+
+/**
+Write a Type 1 font in textual format and return its length in bytes.
+If a_buffer_size is less than the total length, only a_buffer_size bytes are written, but the total
+length is returned correctly.
+
+The PostScript is non-standard. The main dictionary contains no /Charstrings dictionary. This
+is supplied to FreeType using the incremental interface, There is also no /PaintType entry. This is required
+by PostScript but FreeType doesn't use it.
+*/
+long
+gs_fapi_serialize_type1_font(gs_fapi_font * a_fapi_font,
+ unsigned char *a_buffer, long a_buffer_size)
+{
+ WRF_output output;
+
+ WRF_init(&output, a_buffer, a_buffer_size);
+
+ /* Leading comment identifying a Type 1 font. */
+ WRF_wstring(&output, "%!PS-AdobeFont-1\n");
+
+ write_main_dictionary(a_fapi_font, &output, 0);
+ return output.m_count;
+}
+
+long
+gs_fapi_serialize_type1_font_complete(gs_fapi_font * a_fapi_font,
+ unsigned char *a_buffer,
+ long a_buffer_size)
+{
+ WRF_output output;
+
+ WRF_init(&output, a_buffer, a_buffer_size);
+
+ /* Leading comment identifying a Type 1 font. */
+ WRF_wstring(&output, "%!PS-AdobeFont-1\n");
+
+ write_main_dictionary(a_fapi_font, &output, 1);
+ return output.m_count;
+}
diff --git a/gs/psi/write_t1.h b/gs/base/write_t1.h
index 6f685bcbb..c65c0a529 100644
--- a/gs/psi/write_t1.h
+++ b/gs/base/write_t1.h
@@ -23,9 +23,13 @@ Started by Graham Asher, 26th July 2002.
#ifndef write_t1_INCLUDED
#define write_t1_INCLUDED
-#include "ifapi.h"
-
-long FF_serialize_type1_font(FAPI_font* a_fapi_font,unsigned char* a_buffer,long a_buffer_size);
-long FF_serialize_type1_font_complete(FAPI_font* a_fapi_font,unsigned char* a_buffer,long a_buffer_size);
+#include "gxfapi.h"
+
+long gs_fapi_serialize_type1_font(gs_fapi_font * a_fapi_font,
+ unsigned char *a_buffer,
+ long a_buffer_size);
+long gs_fapi_serialize_type1_font_complete(gs_fapi_font * a_fapi_font,
+ unsigned char *a_buffer,
+ long a_buffer_size);
#endif
diff --git a/gs/base/write_t2.c b/gs/base/write_t2.c
new file mode 100644
index 000000000..dfe4738ea
--- /dev/null
+++ b/gs/base/write_t2.c
@@ -0,0 +1,515 @@
+/* Copyright (C) 2001-2012 Artifex Software, Inc.
+ All Rights Reserved.
+
+ This software is provided AS-IS with no warranty, either express or
+ implied.
+
+ This software is distributed under license and may not be copied,
+ modified or distributed except as expressly authorized under the terms
+ of the license contained in the file LICENSE in this distribution.
+
+ Refer to licensing information at http://www.artifex.com or contact
+ Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael,
+ CA 94903, U.S.A., +1(415)492-9861, for further information.
+*/
+
+/*
+Functions to serialize a type 1 font so that it can then be
+passed to FreeType via the FAPI FreeType bridge.
+Started by Graham Asher, 9th August 2002.
+*/
+#include "stdpre.h"
+#include "gzstate.h"
+#include "wrfont.h"
+#include "write_t2.h"
+#include "gxfont.h"
+#include "gxfont1.h"
+
+/*
+Public structures and functions in this file are prefixed with FF_ because they are part of
+the FAPI FreeType implementation.
+*/
+
+static void
+write_4_byte_int(unsigned char *a_output, long a_int)
+{
+ a_output[0] = (unsigned char)(a_int >> 24);
+ a_output[1] = (unsigned char)(a_int >> 16);
+ a_output[2] = (unsigned char)(a_int >> 8);
+ a_output[3] = (unsigned char)(a_int & 0xFF);
+}
+
+static void
+write_type2_int(WRF_output * a_output, long a_int)
+{
+ if (a_int >= -107 && a_int <= 107)
+ WRF_wbyte(a_output, (unsigned char)(a_int + 139));
+ else if (a_int >= -32768 && a_int <= 32767) {
+ if (a_int >= 108 && a_int <= 1131)
+ a_int += 63124;
+ else if (a_int >= -1131 && a_int <= -108)
+ a_int = -a_int + 64148;
+ else
+ WRF_wbyte(a_output, 28);
+ WRF_wbyte(a_output, (unsigned char)(a_int >> 8));
+ WRF_wbyte(a_output, (unsigned char)(a_int & 0xFF));
+ } else {
+ unsigned char buffer[4];
+
+ WRF_wbyte(a_output, 29);
+ write_4_byte_int(buffer, a_int);
+ WRF_wtext(a_output, buffer, 4);
+ }
+}
+
+static void
+write_type2_float(WRF_output * a_output, double a_float)
+{
+ char buffer[32];
+ const char *p = buffer;
+ int high = true;
+ char c = 0;
+
+ sprintf(buffer, "%f", a_float);
+ WRF_wbyte(a_output, 30);
+ for (;;) {
+ char n = 0;
+
+ if (*p >= '0' && *p <= '9')
+ n = (char)(*p - '0');
+ else if (*p == '.')
+ n = 0xA;
+ else if (*p == 'e' || *p == 'E') {
+ if (p[1] == '-') {
+ p++;
+ n = 0xC;
+ } else
+ n = 0xB;
+ } else if (*p == '-')
+ n = 0xE;
+ else if (*p == 0)
+ n = 0xF;
+ if (high) {
+ if (*p == 0)
+ WRF_wbyte(a_output, 0xFF);
+ else
+ c = (char)(n << 4);
+ } else {
+ c |= n;
+ WRF_wbyte(a_output, c);
+ }
+
+ if (*p == 0)
+ break;
+
+ high = !high;
+ p++;
+ }
+}
+
+static void
+write_header(WRF_output * a_output)
+{
+ WRF_wtext(a_output, (const unsigned char *)"\x1\x0\x4\x1", 4);
+}
+
+static void
+write_name_index(WRF_output * a_output)
+{
+ /* Write a dummy name of 'x'. */
+ WRF_wtext(a_output, (const unsigned char *)"\x0\x1\x1\x1\x2" "x", 6);
+}
+
+static void
+write_word_entry(gs_fapi_font * a_fapi_font, WRF_output * a_output,
+ int a_feature_id, int a_feature_count, bool a_two_byte_op,
+ int a_op, int a_divisor)
+{
+ if (a_feature_count > 0) {
+ int i;
+
+ for (i = 0; i < a_feature_count; i++) {
+ /* Get the value and convert it from unsigned to signed. */
+ short x = a_fapi_font->get_word(a_fapi_font, a_feature_id, i);
+
+ /* Divide by the divisor to bring it back to font units. */
+ x = (short)(x / a_divisor);
+ write_type2_int(a_output, x);
+ }
+ if (a_two_byte_op)
+ WRF_wbyte(a_output, 12);
+ WRF_wbyte(a_output, (unsigned char)a_op);
+ }
+}
+
+static void
+write_delta_array_entry(gs_fapi_font * a_fapi_font, WRF_output * a_output,
+ int a_feature_id, bool a_two_byte_op, int a_op,
+ int a_divisor)
+{
+ int i;
+
+ /* NOTE that the feature index (a_feature_id) must be preceded by the count index for this to work. */
+ int count = a_fapi_font->get_word(a_fapi_font, a_feature_id - 1, 0);
+
+ if (count > 0) {
+ short prev_value = 0;
+
+ for (i = 0; i < count; i++) {
+ /* Get the value and convert it from unsigned to signed. */
+ short value = a_fapi_font->get_word(a_fapi_font, a_feature_id, i);
+
+ /* Divide by the divisor to bring it back to font units. */
+ value = (short)(value / a_divisor);
+ write_type2_int(a_output, value - prev_value);
+ prev_value = value;
+ }
+ if (a_two_byte_op)
+ WRF_wbyte(a_output, 12);
+ WRF_wbyte(a_output, (unsigned char)a_op);
+ }
+}
+
+static void
+write_float_entry(gs_fapi_font * a_fapi_font, WRF_output * a_output,
+ int a_feature_id, int a_feature_count, bool a_two_byte_op,
+ int a_op)
+{
+ if (a_feature_count > 0) {
+ int i;
+
+ for (i = 0; i < a_feature_count; i++) {
+ double x = a_fapi_font->get_float(a_fapi_font, a_feature_id, i);
+
+ write_type2_float(a_output, x);
+ }
+ if (a_two_byte_op)
+ WRF_wbyte(a_output, 12);
+ WRF_wbyte(a_output, (unsigned char)a_op);
+ }
+}
+
+static void
+write_font_dict_index(gs_fapi_font * a_fapi_font, WRF_output * a_output,
+ unsigned char **a_charset_offset_ptr,
+ unsigned char **a_charstrings_offset_ptr,
+ unsigned char **a_private_dict_length_ptr)
+{
+ unsigned char *data_start = 0;
+
+ WRF_wtext(a_output, (const unsigned char *)"\x0\x1\x2\x0\x1\x0\x0", 7); /* count = 1, offset size = 2, first offset = 1, last offset = 0 (to be filled in later). */
+ if (a_output->m_pos)
+ data_start = a_output->m_pos;
+ write_word_entry(a_fapi_font, a_output, gs_fapi_font_feature_FontBBox, 4,
+ false, 5, 1);
+ write_float_entry(a_fapi_font, a_output, gs_fapi_font_feature_FontMatrix,
+ 6, true, 7);
+ write_type2_int(a_output, 0); /* 0 = Standard Encoding. */
+ WRF_wbyte(a_output, 16); /* 16 = opcode for 'encoding'. */
+ *a_charset_offset_ptr = a_output->m_pos;
+ WRF_wtext(a_output, (const unsigned char *)"\x1d" "xxxx", 5); /* placeholder for the offset to the charset, which will be a 5-byte integer. */
+ WRF_wbyte(a_output, 15); /* opcode for 'charset' */
+ *a_charstrings_offset_ptr = a_output->m_pos;
+ WRF_wtext(a_output, (const unsigned char *)"\x1d" "xxxx", 5); /* placeholder for the offset to the Charstrings index, which will be a 5-byte integer. */
+ WRF_wbyte(a_output, 17); /* opcode for 'Charstrings' */
+ *a_private_dict_length_ptr = a_output->m_pos;
+ WRF_wtext(a_output, (const unsigned char *)"\x1d" "xxxx\x1d" "yyyy", 10); /* placeholder for size and offset of Private dictionary, which will be 5-byte integers. */
+ WRF_wbyte(a_output, 18); /* opcode for 'Private' */
+ if (a_output->m_pos) {
+ int last_offset = a_output->m_pos - data_start + 1;
+
+ data_start[-2] = (unsigned char)(last_offset >> 8);
+ data_start[-1] = (unsigned char)(last_offset & 0xFF);
+ }
+}
+
+/**
+Write the character set. Return the number of characters.
+For the moment this is always 1. The number cannot be obtained
+via the FAPI interface, and FreeType doesn't need to know anything more
+than the fact that there is at least one character.
+*/
+static int
+write_charset(WRF_output * a_output, unsigned char *a_charset_offset_ptr)
+{
+ const int characters = 1;
+ int i = 0;
+
+ /* Write the offset to the start of the charset to the top dictionary. */
+ if (a_output->m_pos)
+ write_4_byte_int(a_charset_offset_ptr + 1, a_output->m_count);
+
+ /*
+ Write the charset. Write one less than the number of characters,
+ because the first one is assumed to be .notdef. For the moment
+ write all the others as .notdef (SID = 0) because we don't actually
+ need the charset at the moment.
+ */
+ WRF_wbyte(a_output, 0); /* format = 0 */
+ for (i = 1; i < characters; i++) {
+ WRF_wbyte(a_output, 0);
+ WRF_wbyte(a_output, 0);
+ }
+
+ return characters;
+}
+
+/**
+Write a set of empty charstrings. The only reason for the existence of the charstrings index is to tell
+FreeType how many glyphs there are.
+*/
+static void
+write_charstrings_index(WRF_output * a_output, int a_characters,
+ unsigned char *a_charstrings_offset_ptr)
+{
+ /* Write the offset to the charstrings index to the top dictionary. */
+ if (a_output->m_pos)
+ write_4_byte_int(a_charstrings_offset_ptr + 1, a_output->m_count);
+
+ /* Write the index. */
+ WRF_wbyte(a_output, (unsigned char)(a_characters >> 8));
+ WRF_wbyte(a_output, (unsigned char)(a_characters & 0xFF));
+ WRF_wbyte(a_output, 1); /* offset size = 1. */
+ while (a_characters-- >= 0)
+ WRF_wbyte(a_output, 1); /* offset = 1 */
+}
+
+static void
+write_gsubrs_index(gs_fapi_font * a_fapi_font, WRF_output * a_output)
+{
+ unsigned char *cur_offset = 0;
+ unsigned char *data_start = 0;
+ int i;
+ int count = a_fapi_font->get_word(a_fapi_font,
+ gs_fapi_font_feature_GlobalSubrs_count,
+ 0);
+
+ WRF_wbyte(a_output, (unsigned char)(count >> 8));
+ WRF_wbyte(a_output, (unsigned char)(count & 0xFF));
+
+ if (count <= 0)
+ return;
+
+ WRF_wbyte(a_output, 4); /* offset size = 4 bytes */
+ WRF_wtext(a_output, (const unsigned char *)"\x0\x0\x0\x1", 4); /* first offset = 1 */
+
+ if (a_output->m_pos)
+ cur_offset = a_output->m_pos;
+
+ /* Write dummy bytes for the offsets at the end of each data item. */
+ for (i = 0; i < count; i++)
+ WRF_wtext(a_output, (const unsigned char *)"xxxx", 4);
+
+ if (a_output->m_pos)
+ data_start = a_output->m_pos;
+
+ for (i = 0; i < count; i++) {
+ long buffer_size = a_output->m_limit - a_output->m_count;
+ long length = a_fapi_font->get_gsubr(a_fapi_font, i, a_output->m_pos,
+ (ushort) buffer_size);
+
+ if (a_output->m_pos)
+ WRF_wtext(a_output, a_output->m_pos, length);
+ else
+ a_output->m_count += length;
+ if (cur_offset) {
+ long pos = a_output->m_pos - data_start + 1;
+
+ write_4_byte_int(cur_offset, pos);
+ cur_offset += 4;
+ }
+ }
+}
+
+static void
+write_subrs_index(gs_fapi_font * a_fapi_font, WRF_output * a_output)
+{
+ unsigned char *cur_offset = 0;
+ unsigned char *data_start = 0;
+ int i;
+ int count =
+ a_fapi_font->get_word(a_fapi_font, gs_fapi_font_feature_Subrs_count,
+ 0);
+
+ WRF_wbyte(a_output, (unsigned char)(count >> 8));
+ WRF_wbyte(a_output, (unsigned char)(count & 0xFF));
+
+ if (count <= 0)
+ return;
+
+ WRF_wbyte(a_output, 4); /* offset size = 4 bytes */
+ WRF_wtext(a_output, (const unsigned char *)"\x0\x0\x0\x1", 4); /* first offset = 1 */
+
+ if (a_output->m_pos)
+ cur_offset = a_output->m_pos;
+
+ /* Write dummy bytes for the offsets at the end of each data item. */
+ for (i = 0; i < count; i++)
+ WRF_wtext(a_output, (const unsigned char *)"xxxx", 4);
+
+ if (a_output->m_pos)
+ data_start = a_output->m_pos;
+
+ for (i = 0; i < count; i++) {
+ long buffer_size = a_output->m_limit - a_output->m_count;
+ long length = a_fapi_font->get_subr(a_fapi_font, i, a_output->m_pos,
+ (ushort) buffer_size);
+
+ if (a_output->m_pos)
+ WRF_wtext(a_output, a_output->m_pos, length);
+ else
+ a_output->m_count += length;
+ if (cur_offset) {
+ long pos = a_output->m_pos - data_start + 1;
+
+ write_4_byte_int(cur_offset, pos);
+ cur_offset += 4;
+ }
+ }
+}
+
+static void
+write_private_dict(gs_fapi_font * a_fapi_font, WRF_output * a_output,
+ unsigned char *a_private_dict_length_ptr)
+{
+ int count, initial = a_output->m_count;
+
+ /* Write the offset to the start of the private dictionary to the top dictionary. */
+ unsigned char *start = a_output->m_pos;
+
+ if (a_output->m_pos)
+ write_4_byte_int(a_private_dict_length_ptr + 6, a_output->m_count);
+
+ write_word_entry(a_fapi_font, a_output, gs_fapi_font_feature_BlueFuzz, 1,
+ true, 11, 16);
+
+ write_type2_float(a_output,
+ a_fapi_font->get_long(a_fapi_font,
+ gs_fapi_font_feature_BlueScale,
+ 0) / 65536.0);
+ WRF_wbyte(a_output, 12);
+ WRF_wbyte(a_output, 9);
+
+ write_word_entry(a_fapi_font, a_output, gs_fapi_font_feature_BlueShift, 1,
+ true, 10, 16);
+ write_delta_array_entry(a_fapi_font, a_output,
+ gs_fapi_font_feature_BlueValues, false, 6, 16);
+ write_delta_array_entry(a_fapi_font, a_output,
+ gs_fapi_font_feature_OtherBlues, false, 7, 16);
+ write_delta_array_entry(a_fapi_font, a_output,
+ gs_fapi_font_feature_FamilyBlues, false, 8, 16);
+ write_delta_array_entry(a_fapi_font, a_output,
+ gs_fapi_font_feature_FamilyOtherBlues, false, 9,
+ 16);
+ write_word_entry(a_fapi_font, a_output, gs_fapi_font_feature_ForceBold, 1,
+ true, 14, 1);
+ write_word_entry(a_fapi_font, a_output, gs_fapi_font_feature_StdHW, 1,
+ false, 10, 16);
+ write_word_entry(a_fapi_font, a_output, gs_fapi_font_feature_StdVW, 1,
+ false, 11, 16);
+ write_delta_array_entry(a_fapi_font, a_output,
+ gs_fapi_font_feature_StemSnapH, true, 12, 16);
+ write_delta_array_entry(a_fapi_font, a_output,
+ gs_fapi_font_feature_StemSnapV, true, 13, 16);
+
+ /*
+ Write the default width and the nominal width. These values are not available via
+ the FAPI interface so we have to get a pointer to the Type 1 font structure and
+ extract them directly.
+ */
+ {
+ gs_font_type1 *t1 = (gs_font_type1 *) a_fapi_font->client_font_data;
+
+ write_type2_float(a_output, fixed2float(t1->data.defaultWidthX));
+ WRF_wbyte(a_output, 20);
+ write_type2_float(a_output, fixed2float(t1->data.nominalWidthX));
+ WRF_wbyte(a_output, 21);
+ }
+
+ count =
+ a_fapi_font->get_word(a_fapi_font, gs_fapi_font_feature_Subrs_count,
+ 0);
+ /* If we have local /Subrs we need to make a new dict ( see calling routine) and
+ * we also need to add an entry to the Provate dict with an offset to the /Subrs
+ * dict. This is complicated by the fact that the offset includes the data for
+ * the offset (its contained in the Private dict) and the size of the data depends
+ * on its value (because of number representation).
+ */
+ if (count) {
+ int n = 1, n1;
+
+ do {
+ n1 = a_output->m_count - initial + 1 + n; /* one for the operator, plus the size needed for the representation */
+ switch (n) {
+ case 1:
+ if (n1 >= -107 && n1 <= 107) {
+ write_type2_int(a_output, n1);
+ n = 5;
+ }
+ break;
+ case 2:
+ if ((n1 >= 108 && n1 <= 1131)
+ || (n1 >= -1131 && n1 <= -108)) {
+ write_type2_int(a_output, n1);
+ n = 5;
+ }
+ break;
+ case 3:
+ if (n1 >= -32768 && n1 <= 32767) {
+ write_type2_int(a_output, n1);
+ n = 5;
+ }
+ break;
+ case 4:
+ break;
+ case 5:
+ write_type2_int(a_output, n1);
+ break;
+ }
+ n++;
+ }
+ while (n < 5);
+
+ WRF_wbyte(a_output, 19);
+ }
+
+ /* Write the length in bytes of the private dictionary to the top dictionary. */
+ if (a_output->m_pos)
+ write_4_byte_int(a_private_dict_length_ptr + 1,
+ a_output->m_pos - start);
+}
+
+/**
+Write a Type 2 font in binary format and return its length in bytes.
+If a_buffer_size is less than the total length, only a_buffer_size bytes are written, but the total
+length is returned correctly.
+*/
+long
+gs_fapi_serialize_type2_font(gs_fapi_font * a_fapi_font,
+ unsigned char *a_buffer, long a_buffer_size)
+{
+ unsigned char *charset_offset_ptr = NULL;
+ unsigned char *charstrings_offset_ptr = NULL;
+ unsigned char *private_dict_length_ptr = NULL;
+ int characters = 0;
+
+ WRF_output output;
+
+ WRF_init(&output, a_buffer, a_buffer_size);
+
+ write_header(&output);
+ write_name_index(&output);
+ write_font_dict_index(a_fapi_font, &output, &charset_offset_ptr,
+ &charstrings_offset_ptr, &private_dict_length_ptr);
+
+ /* Write an empty string index. */
+ WRF_wtext(&output, (const unsigned char *)"\x0\x0", 2);
+
+ write_gsubrs_index(a_fapi_font, &output);
+ characters = write_charset(&output, charset_offset_ptr);
+ write_charstrings_index(&output, characters, charstrings_offset_ptr);
+ write_private_dict(a_fapi_font, &output, private_dict_length_ptr);
+ write_subrs_index(a_fapi_font, &output);
+
+ return output.m_count;
+}
diff --git a/gs/psi/write_t2.h b/gs/base/write_t2.h
index 13c411192..8fe062a86 100644
--- a/gs/psi/write_t2.h
+++ b/gs/base/write_t2.h
@@ -23,8 +23,10 @@ Started by Graham Asher, 9th August 2002.
#ifndef write_t2_INCLUDED
#define write_t2_INCLUDED
-#include "ifapi.h"
+#include "gxfapi.h"
-long FF_serialize_type2_font(FAPI_font* a_fapi_font,unsigned char* a_buffer,long a_buffer_size);
+long gs_fapi_serialize_type2_font(gs_fapi_font * a_fapi_font,
+ unsigned char *a_buffer,
+ long a_buffer_size);
#endif
diff --git a/gs/psi/fapiufst.c b/gs/psi/fapiufst.c
deleted file mode 100644
index eb14a9544..000000000
--- a/gs/psi/fapiufst.c
+++ /dev/null
@@ -1,1781 +0,0 @@
-/* Copyright (C) 2001-2012 Artifex Software, Inc.
- All Rights Reserved.
-
- This software is provided AS-IS with no warranty, either express or
- implied.
-
- This software is distributed under license and may not be copied,
- modified or distributed except as expressly authorized under the terms
- of the license contained in the file LICENSE in this distribution.
-
- Refer to licensing information at http://www.artifex.com or contact
- Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael,
- CA 94903, U.S.A., +1(415)492-9861, for further information.
-*/
-
-
-/* Agfa UFST plugin */
-
-/* GS includes : */
-#include "stdio_.h"
-#include "stream.h"
-#include "strmio.h"
-
-#include "memory_.h"
-#include "gsmemory.h"
-#include "math_.h"
-#include "stat_.h" /* include before definition of esp macro, bug 691123 */
-#include "ghost.h"
-#include "gp.h"
-#include "oper.h"
-#include "gxdevice.h"
-#include "gxfont.h"
-#include "gxfont1.h"
-#include "gxchar.h"
-#include "gxpath.h"
-#include "gxfcache.h"
-#include "gxchrout.h"
-#include "gximask.h"
-#include "gscoord.h"
-#include "gspaint.h"
-#include "gsfont.h"
-#include "gspath.h"
-#include "bfont.h"
-#include "dstack.h"
-#include "estack.h"
-#include "ichar.h"
-#include "idict.h"
-#include "iname.h"
-#include "ifont.h"
-#include "icid.h"
-#include "igstate.h"
-#include "icharout.h"
-#include "ifapi.h"
-#include "iplugin.h"
-#include "store.h"
-#include "gzstate.h"
-#include "gdevpsf.h"
-#include "stream.h" /* for files.h */
-#include "gscrypt1.h"
-#include "gxfcid.h"
-#include "gsstype.h"
-#include "gxchar.h" /* for st_gs_show_enum */
-#include "ipacked.h" /* for packed_next */
-#include "iddict.h"
-#include "ifont42.h" /* for string_array_access_proc */
-#include "gsmalloc.h"
-#include "gsmchunk.h"
-
-#undef frac_bits
-
-#ifndef _MSC_VER
-#define _MSC_VER 0
-#endif
-
-/* UFST includes : */
-#include "cgconfig.h"
-#include "ufstport.h"
-#include "dbg_ufst.h"
-#include "shareinc.h"
-#include "t1isfnt.h"
-#include "cgmacros.h"
-#include "sfntenum.h"
-#define DOES_ANYONE_USE_THIS_STRUCTURE /* see TTPCLEO.H, UFST 4.2 */
-#include "ttpcleo.h"
-#undef DOES_ANYONE_USE_THIS_STRUCTURE
-#include "gxfapiu.h"
-
-/* more gs includes */
-#include "iref.h"
-#include "ialloc.h"
-#include "imemory.h"
-#include "iname.h"
-#include "iapi.h"
-#include "iminst.h"
-#include "imain.h"
-#include "igstate.h"
-#include "idict.h"
-#include "dstack.h"
-#include "store.h"
-
-#if UFST_VERSION_MAJOR >= 6 && UFST_VERSION_MINOR >= 2
-#include "t1itype1.h"
-#endif
-
-#if UFST_VERSION_MAJOR >= 6 && UFST_VERSION_MINOR >= 2
-#undef true
-#undef false
-
-#define false FALSE
-#define true TRUE
-#define UNICODE UFST_UNICODE
-#endif
-
-#ifndef UFSTFONTDIR
-#define UFSTFONTDIR ""
-#endif
-
-#define UFST_PlugIn_Str "UFST_PlugIn"
-#define UFST_PlugIn_Path "mtfonts/pcl45/mt3/plug__xi.fco"
-
-#define FCOfontfilePath "mtfonts/pclps2/mt3/pclp2_xj.fco"
-#define FCOfontfileStr "FCOfontfile"
-
-#define FCOfontfile2Str "FCOfontfile2"
-#define FCOfontfile2Path "mtfonts/pcl45/mt3/wd____xh.fco"
-
-#define FAPIfontmapStr "FAPIfontmap"
-#define FAPIfontmap "FCOfontmap-PCLPS2"
-
-/* Prior to 6.2, prototypes had empty parameter lists, causing problems
- * when passing 64 bit pointers into the UFST functions.
- * Prototype "properly" here.
- */
-#if UFST_VERSION_MAJOR < 6
-#if defined (ANSI_DEFS)
-UW16 CGENTRY CGIFFfont (FSP PFONTCONTEXT fc);
-#else
-UW16 CGENTRY CGIFFfont (fc);
- PFONTCONTEXT fc;
-#endif /* ANSI_DEFS */
-#endif
-
-typedef struct fapi_ufst_server_s fapi_ufst_server;
-
-static unsigned int font_ids = 0x7fffffff;
-
-#if UFST_REENTRANT
-#define FSA_FROM_SERVER IF_STATE *pIFS = &r->IFS
-#else
-EXTERN IF_STATE if_state;
-#define FSA_FROM_SERVER IF_STATE *pIFS = &if_state; (void)r; (void)pIFS;
-static fapi_ufst_server *static_server_ptr_for_ufst_callback = 0;
-#endif
-
-GLOBAL UW16 PCLswapHdr( FSP LPUB8 p, UW16 gifct ); /* UFST header doesn't define it. */
-
-typedef struct pcleo_glyph_list_elem_s pcleo_glyph_list_elem;
-struct pcleo_glyph_list_elem_s {
- UW16 chId;
- pcleo_glyph_list_elem *next;
- /* more data follows here depending on font type */
-};
-
-typedef struct {
- SL32 font_id;
- uint tt_font_body_offset;
- UW16 is_disk_font;
- UW16 font_type;
- UW16 platformId;
- UW16 specificId;
- pcleo_glyph_list_elem *glyphs;
- char decodingID[40];
-} ufst_common_font_data;
-
-typedef struct {
- PCLETTO_CHR_HDR h;
- UW16 add_data;
- UW16 charDataSize;
- UW16 glyphID;
-} PCLETTO_CHDR;
-
-struct fapi_ufst_server_s {
- FAPI_server If;
- int bInitialized;
- FAPI_font *ff;
- gs_memory_t *mem;
- byte *param;
- int param_size;
- IF_STATE IFS;
- FONTCONTEXT fc;
- void *char_data;
- bool bRaster;
- bool ufst_is_singleton;
- double tran_xx, tran_xy, tran_yx, tran_yy;
- fco_list_elem *fco_list;
- FAPI_retcode callback_error;
- FAPI_metrics_type metrics_type;
- FracInt sb_x, aw_x; /* replaced PS metrics. */
-};
-
-static inline void release_char_data_inline(fapi_ufst_server *r);
-static void release_glyphs(fapi_ufst_server *r, ufst_common_font_data *d);
-
-/* Type casts : */
-
-static inline fapi_ufst_server *If_to_I(FAPI_server *If)
-{ return (fapi_ufst_server *)If;
-}
-
-static inline fapi_ufst_server *IFS_to_I(IF_STATE *pIFS)
-{ return (fapi_ufst_server *)((char *)pIFS - offset_of(fapi_ufst_server, IFS));
-}
-
-/* assign font_id not based on fchandle value, nor read from font */
-static inline int assign_font_id(void)
-{
- /* We're only allowed 5 open FCOs at one time
- * so make sure we don't clash with those
- */
- if ((--font_ids) <= (5 << 16)) {
- /* When we clash with the expected values for FCO's
- * wrap around. No will ever have enough concurrent
- * fonts for this to be a problem!
- */
- font_ids = 0x7fffffff;
- }
- return(font_ids);
-}
-
-/*------------------ FAPI_server members ------------------------------------*/
-
-static inline void release_char_data_inline(fapi_ufst_server *r)
-{ /* The server keeps character raster between calls to get_char_raster_metrics
- and get_char_raster, as well as between calls to get_char_outline_metrics
- and get_char_outline. Meanwhile this regular
- sequence of calls may be interrupted by an error in CDefProc or setchachedevice2,
- which may be invoked between them. In this case Ghostscript
- is unable to provide a signal to FAPI that the data are not
- longer needed. This would cause memory leaks in UFST heap.
- To work around this, appropriate server's entries check whether
- raster data were left after a previous call, and ultimately release them.
- This function provides it.
- */
- if (r->char_data != NULL) {
- FSA_FROM_SERVER;
-
- CHARfree(FSA (MEM_HANDLE)r->char_data);
- r->char_data = 0;
- }
-}
-
-/*
- * In the language switch build (which we detect because PSI_INCLUDED
- * is defined), we use the gx_UFST_init() call to initialize the UFST,
- * rather than calling into the UFST directly. That has the advantage
- * that the same UFST configuration is used for PCL and PS, but the
- * disadvantage that the dynamic parameters set in server_param are
- * not available. Thus, it is switched through this compile time option.
-*/
-static FAPI_retcode open_UFST(fapi_ufst_server *r, const byte *server_param, int server_param_size)
-{
- int code;
- SW16 fcHandle;
- int l;
- char ufst_root_dir[1024] = "";
- char sPlugIn[1024] = "";
- bool bSSdir = FALSE, bPlugIn = FALSE;
- const char *keySSdir = "UFST_SSdir=";
- const int keySSdir_length = strlen(keySSdir);
- const char *keyPlugIn = "UFST_PlugIn=";
- const int keyPlugIn_length = strlen(keyPlugIn);
- const char sep = gp_file_name_list_separator;
- const byte *p = server_param, *e = server_param + server_param_size, *q;
- FSA_FROM_SERVER;
-
- if (server_param_size > 0 && server_param) {
- r->param = (byte *)gs_malloc(r->mem, server_param_size, 1, "server_params");
- if (!r->param) {
- return_error (e_VMerror);
- }
- memcpy(r->param, server_param, server_param_size);
- r->param_size = server_param_size;
- }
-
- for (; p < e ; p = q + 1) {
- for (q = p; q < e && *q != sep; q++)
- /* DO_NOTHING */;
- l = q - p;
- if (l > keySSdir_length && !memcmp(p, keySSdir, keySSdir_length)) {
- l = q - p - keySSdir_length;
- if (l > sizeof(ufst_root_dir) - 1)
- l = sizeof(ufst_root_dir) - 1;
- memcpy(ufst_root_dir, p + keySSdir_length, l);
- ufst_root_dir[l] = 0;
- bSSdir = TRUE;
- } else if (l > keyPlugIn_length && !memcmp(p, keyPlugIn, keyPlugIn_length)) {
- l = q - p - keyPlugIn_length;
- if (l > sizeof(sPlugIn) - 1)
- l = sizeof(sPlugIn) - 1;
- memcpy(sPlugIn, p + keyPlugIn_length, l);
- sPlugIn[l] = 0;
- bPlugIn = TRUE;
- } else
- emprintf(r->mem,
- "Warning: Unknown UFST parameter ignored.\n");
- }
-#if !NO_SYMSET_MAPPING
- if (!bSSdir) {
- strcpy(ufst_root_dir, ".");
- emprintf(r->mem,
- "Warning: UFST_SSdir is not specified, will search *.ss files in the curent directory.\n");
- }
-#endif
- code = gx_UFST_init(r->mem, (const UB8 *)ufst_root_dir);
- if (code < 0)
- return code;
- r->ufst_is_singleton = (code == 1);
- CGIFfont_access (FSA DISK_ACCESS);
- if (bPlugIn) {
- if ((code = gx_UFST_open_static_fco(sPlugIn, &fcHandle)) != 0)
- return code;
- if ((code = CGIFfco_Plugin(FSA fcHandle)) != 0)
- return code;
- } else {
-#ifdef FCO_RDR
- emprintf(r->mem,
- "Warning: UFST_PlugIn is not specified, some characters may be missing.\n");
-#endif
- }
- return 0;
-}
-
-static LPUB8 impl_PCLchId2ptr(FSP UW16 chId);
-
-static FAPI_retcode ensure_open(FAPI_server *server, const byte *server_param, int server_param_size)
-{ fapi_ufst_server *r = If_to_I(server);
- int code;
-
- if (r->bInitialized)
- return 0;
- r->bInitialized = 1;
- {
- code = open_UFST(r, server_param, server_param_size);
- if (code < 0) {
- emprintf(r->mem, "Error opening the UFST font server.\n");
- return code;
- }
- }
- gx_set_UFST_Callbacks(NULL, impl_PCLchId2ptr, impl_PCLchId2ptr);
- return 0;
-}
-
-static UW16 get_font_type(stream *f)
-{ char buf[20], mark_PS[]="%!";
- int i;
-
- if (sfread(buf, 1, sizeof(buf), f) != sizeof(buf))
- return 0;
- if (buf[0] == 0x15 || buf[0] == 0x00) /* fixme : don't know how to do correctly. */
- return FC_FCO_TYPE;
- for (i = 0; i < sizeof(buf) - sizeof(mark_PS); i++)
- if(!memcmp(buf + i, mark_PS, sizeof(mark_PS) - 1))
- return FC_PST1_TYPE;
- if (buf[0] == '\0' && buf[1] == '\1')
- return FC_TT_TYPE;
- if (buf[0] == 't' && buf[1] == 't')
- return FC_TT_TYPE;
- return 0; /* fixme : unknown type - actually an error. */
-}
-
-static int choose_decoding_general(fapi_ufst_server *r, ufst_common_font_data *d, const char *cmapId)
-{
- if (!d->decodingID[0])
- strncpy(d->decodingID, "Unicode", sizeof(d->decodingID));
- /* fixme : must depend on charset used in the font. */
- return 1;
-}
-
-static int choose_decoding_TT(fapi_ufst_server *r, ufst_common_font_data *d, const char *cmapId)
-{
-#if TT_ROM || TT_DISK
- int platId, specId, i;
- CMAP_QUERY q;
- UW16 font_access;
- bool failed;
- void *p = (d->is_disk_font ? (void *)(d + 1) : (void *)((UB8 *)d + d->tt_font_body_offset));
- FSA_FROM_SERVER;
-
- if (sscanf(cmapId, "%d.%d", &platId, &specId) != 2)
- return 0;
- font_access = pIFS->font_access;
- pIFS->font_access = (d->is_disk_font ? DISK_ACCESS : ROM_ACCESS);
- failed = CGIFtt_cmap_query(FSA p, r->fc.ttc_index, &q);
- pIFS->font_access = font_access;
- if(failed)
- return 0;
- for (i = 0; i < q.numCmap; i++)
- if (q.entry[i].platId == platId && q.entry[i].specId == specId) {
- d->platformId = platId;
- d->specificId = specId;
- return 1;
- }
- return 0;
-#else
- if (!d->decodingID[0])
- strncpy(d->decodingID, "Unicode", sizeof(d->decodingID));
- return 1;
-#endif
-}
-
-static void scan_xlatmap(fapi_ufst_server *r, ufst_common_font_data *d, const char *xlatmap, const char *font_kind,
- int (*choose_proc)(fapi_ufst_server *r, ufst_common_font_data *d, const char *cmapId))
-{ const char *p = xlatmap;
-
- while(*p) {
- int good_kind =!strcmp(p, font_kind);
- p += strlen(p) + 2;
- while(*p) {
- const char *cmapId = p, *decodingID = p + strlen(p) + 1;
- strncpy(d->decodingID, decodingID, sizeof(d->decodingID));
- if (!decodingID[0])
- break;
- p = decodingID + strlen(decodingID) + 1;
- if (good_kind)
- if (choose_proc(r, d, cmapId))
- return;
- }
- }
- d->decodingID[0] = 0;
-}
-
-static void choose_decoding(fapi_ufst_server *r, ufst_common_font_data *d, const char *xlatmap)
-{ if (xlatmap != 0)
- switch (d->font_type) {
- case FC_IF_TYPE: /* fixme */ break;
- case FC_PST1_TYPE: scan_xlatmap(r, d, xlatmap, "PostScript", choose_decoding_general); break;
- case FC_TT_TYPE: scan_xlatmap(r, d, xlatmap, "TrueType", choose_decoding_TT); break;
- case FC_FCO_TYPE: scan_xlatmap(r, d, xlatmap, "Microtype", choose_decoding_general); break;
- }
-}
-
-static inline void store_word(byte **p, ushort w)
-{ *((*p)++) = w / 256;
- *((*p)++) = w % 256;
-
-}
-
-static LPUB8 get_TT_glyph(fapi_ufst_server *r, FAPI_font *ff, UW16 chId)
-{ pcleo_glyph_list_elem *g;
- PCLETTO_CHDR *h;
- ufst_common_font_data *d = (ufst_common_font_data *)r->fc.font_hdr - 1;
- LPUB8 q;
- ushort glyph_length = ff->get_glyph(ff, chId, 0, 0);
- bool use_XL_format = ff->is_mtx_skipped;
-
- /*
- * The client must set ff->is_mtx_skipped iff
- * it requests a replaced lsb for True Type.
- * If it is set, a replaced width to be supplied.
- * This constraint is derived from UFST restriction :
- * the font header format must be compatible with
- * glyph header format.
- */
-
- if (glyph_length == (ushort)-1) {
- r->callback_error = e_invalidfont;
- return 0;
- }
- g = (pcleo_glyph_list_elem *)gs_malloc(r->mem,
- sizeof(pcleo_glyph_list_elem) +
- (use_XL_format ? 12 : sizeof(PCLETTO_CHDR)) + glyph_length + 2, 1,
- "PCLETTO char");
- if (g == 0) {
- r->callback_error = e_VMerror;
- return 0;
- }
- g->chId = chId;
- g->next = d->glyphs;
- d->glyphs = g;
- h = (PCLETTO_CHDR *)(g + 1);
- h->h.format = 15;
- if (use_XL_format) {
- h->h.continuation = 2;
- q = (LPUB8)h + 2;
- store_word(&q, (ushort)(glyph_length + 10));
- store_word(&q, (ushort)(r->sb_x >> r->If.frac_shift)); /* see can_replace_metrics */
- store_word(&q, (ushort)(r->aw_x >> r->If.frac_shift));
- store_word(&q, 0);
- store_word(&q, chId);
- } else {
- h->h.continuation = 0;
- h->h.descriptorsize = 4;
- h->h.ch_class = 15;
- h->add_data = 0;
- q = (LPUB8)&h->charDataSize;
- store_word(&q, (ushort)(glyph_length + 4));
- store_word(&q, chId);
- }
- if (ff->get_glyph(ff, chId, (LPUB8)q, glyph_length) == (ushort)-1) {
- r->callback_error = e_invalidfont;
- return 0;
- }
- q += glyph_length;
- store_word(&q, 0); /* checksum */
- return (LPUB8)h;
- /*
- * The metrics replacement here is done only for the case
- * corresponding to non-disk TT fonts with MetricsCount != 0;
- * Other cases are not supported because UFST cannot handle them.
- * Here we don't take care of cases which can_replace_metrics rejects.
- *
- * We don't care of metrics for subglyphs, because
- * it is ignored by TT interpreter.
- */
-}
-
-static LPUB8 get_T1_glyph(fapi_ufst_server *r, FAPI_font *ff, UW16 chId)
-{
-#if PST1_SFNTI
-#if UFST_VERSION_MAJOR >= 6 && UFST_VERSION_MINOR >= 2
- ushort glyph_length = ff->get_glyph(ff, chId, 0, 0);
- CDATASTR charstring;
- PCDATASTR_DEMO pcharstring;
- byte *cstring;
- ufst_common_font_data *d = (ufst_common_font_data *)r->fc.font_hdr - 1;
- MEM_HANDLE hndl;
- FSA_FROM_SERVER;
-
- d->glyphs = NULL;
-
- charstring.len = glyph_length;
- charstring.hdata = BUFalloc(charstring.len);
- if (!charstring.hdata)
- {
- r->callback_error = e_VMerror;
- return (NULL);
- }
-
- cstring = (unsigned char *)MEMptr(charstring.hdata);
-
- if (ff->get_glyph(ff, chId, cstring, glyph_length) != glyph_length)
- {
- r->callback_error = e_VMerror;
- BUFfree(charstring.hdata);
- return (NULL);
- }
-
- hndl = BUFalloc (FSA (SL32)(sizeof (CDATASTR)));
- if (!hndl)
- {
- r->callback_error = e_VMerror;
- BUFfree(charstring.hdata);
- return (NULL);
- }
-
- pcharstring = (PCDATASTR_DEMO)MEMptr(hndl);
-
- pcharstring->len = charstring.len; /* Datalen */
- pcharstring->hdata = charstring.hdata;
- pcharstring->decrypted = 1;
-
- return ((LPUB8) pcharstring);
-#else
- ushort glyph_length = ff->get_glyph(ff, chId, 0, 0);
- LPUB8 q;
- pcleo_glyph_list_elem *g = (pcleo_glyph_list_elem *)gs_malloc(r->mem,
- sizeof(pcleo_glyph_list_elem) + sizeof(PS_CHAR_HDR) + 2 + 2 + glyph_length + 1, 1, "PSEO char");
- PS_CHAR_HDR *h;
- ufst_common_font_data *d = (ufst_common_font_data *)r->fc.font_hdr - 1;
- FSA_FROM_SERVER;
-
- if (g == 0 || glyph_length == (ushort)-1) {
- r->callback_error = e_invalidfont;
- return 0;
- }
- g->chId = chId;
- g->next = d->glyphs;
- d->glyphs = g;
- h = (PS_CHAR_HDR *)(g + 1);
- h->format = 30; /* raster=4, DJ=5, IF=10, TT=15, PS=30 */
- h->continuation = 0; /* always 0 */
- h->descriptorsize = 2; /* always 2 */
- h->ch_class = 11; /* contour=3, compound=4, tt=10, ps=11 */
- h->len = 0; /* # of bytes to follow (not including csum) */
- q = (byte *)h + sizeof(*h);
- /* A workaround for UFST4.6 bug in t1idecod.c (UNPACK_WORD uses pIFS->ph instead ph) :
- setting Namelen=4, rather normally it must be 0. */
- q[0] = 0; /* Namelen */
- q[1] = 4; /* Namelen */
- q[2] = (glyph_length) / 256; /* Datalen */
- q[3] = (glyph_length) % 256; /* Datalen */
- /* Glyph name goes here, but we don't use it. */
- q += 4;
- glyph_length = ff->get_glyph(ff, chId, q, glyph_length);
- q += glyph_length;
- *q = 1; /* Decrypt flag */
- pIFS->ph = (byte *)h + sizeof(*h); /* A workaround for UFST4.6 bug in t1idecod.c (UNPACK_WORD uses pIFS->ph instead ph) */
- return (LPUB8)h;
-#endif
-#else
- return 0;
-#endif
-}
-
-static pcleo_glyph_list_elem * find_glyph(ufst_common_font_data *d, UW16 chId)
-{ pcleo_glyph_list_elem *e;
-
- for (e = d->glyphs; e != 0; e = e->next)
- if (e->chId == chId)
- return e;
- return 0;
-}
-
-/* UFST callback : */
-static LPUB8 impl_PCLchId2ptr(FSP UW16 chId)
-{
-#if UFST_REENTRANT
- fapi_ufst_server *r = IFS_to_I(pIFS);
-#else
- fapi_ufst_server *r = static_server_ptr_for_ufst_callback;
-#endif
- FAPI_font *ff = r->ff;
- ufst_common_font_data *d = (ufst_common_font_data *)r->fc.font_hdr - 1;
- pcleo_glyph_list_elem *g = find_glyph(d, chId);
- LPUB8 result = 0;
-
- if (g != 0)
- result = (LPUB8)(g + 1);
- if ((r->fc.format & FC_FONTTYPE_MASK) == FC_PST1_TYPE)
- result = get_T1_glyph(r, ff, chId);
- if ((r->fc.format & FC_FONTTYPE_MASK) == FC_TT_TYPE)
- result = get_TT_glyph(r, ff, chId);
- return result;
-}
-
-static inline void pack_word(LPUB8 *p, UW16 v)
-{ LPUB8 q = (LPUB8)&v;
-
-#if (BYTEORDER == LOHI) /* defied in UFST includes */
- (*p)[1] = q[0];
- (*p)[0] = q[1];
-#else
- *(UW16 *)(*p) = v;
-#endif
- *p += 2;
-}
-
-static inline void pack_long(LPUB8 *p, UL32 v)
-{ LPUB8 q = (LPUB8)&v;
-
-#if (BYTEORDER == LOHI) /* defied in UFST includes */
- (*p)[3] = q[0];
- (*p)[2] = q[1];
- (*p)[1] = q[2];
- (*p)[0] = q[3];
-#else
- *(UL32 *)(*p) = v;
-#endif
- *p += 4;
-}
-
-static inline void pack_float(LPUB8 *p, float v)
-{ sprintf((char *)(*p), "%f", v);
- *p += strlen((const char *)*p) + 1;
-}
-
-#define PACK_ZERO(p) *(p++) = 0
-#define PACK_BYTE(p, c) *(p++) = c
-#define PACK_WORD(p, i, var) pack_word(&p, ff->get_word(ff, var, i))
-#define PACK_LONG(p, i, var) pack_long(&p, ff->get_long(ff, var, i))
-
-static void pack_pseo_word_array(fapi_ufst_server *r, FAPI_font *ff, UB8 **p,
- UW16 max_count, fapi_font_feature count_id, fapi_font_feature array_id)
-{ UW16 k = min(ff->get_word(ff, count_id, 0), max_count), j;
-
- pack_word(p, k);
- for (j = 0; j < k; j++)
- PACK_WORD(*p, j, array_id);
- for (; j < max_count; j++)
- pack_word(p, 0);
-}
-
-static void pack_pseo_fhdr(fapi_ufst_server *r, FAPI_font *ff, UB8 *p)
-{ ushort j, n, skip = 0;
-
- while (((uint64_t)p) & 0x03) /* align to QUADWORD */
- PACK_ZERO(p);
- pack_long(&p, 1); /* format = 1 */
- for (j = 0; j < 6; j++)
- pack_float(&p, ff->get_float(ff, FAPI_FONT_FEATURE_FontMatrix, j));
- while (((uint64_t)p) & 0x03) /* align to QUADWORD */
- PACK_ZERO(p);
- /* UFST has no definition for PSEO structure, so implement serialization : */
- PACK_LONG(p, 0, FAPI_FONT_FEATURE_UniqueID);
- PACK_LONG(p, 0, FAPI_FONT_FEATURE_BlueScale);
- PACK_WORD(p, 0, FAPI_FONT_FEATURE_Weight);
- PACK_WORD(p, 0, FAPI_FONT_FEATURE_ItalicAngle);
- PACK_WORD(p, 0, FAPI_FONT_FEATURE_IsFixedPitch);
- PACK_WORD(p, 0, FAPI_FONT_FEATURE_UnderLinePosition);
- PACK_WORD(p, 0, FAPI_FONT_FEATURE_UnderlineThickness);
- PACK_WORD(p, 0, FAPI_FONT_FEATURE_FontType);
- PACK_WORD(p, 0, FAPI_FONT_FEATURE_FontBBox);
- PACK_WORD(p, 1, FAPI_FONT_FEATURE_FontBBox);
- PACK_WORD(p, 2, FAPI_FONT_FEATURE_FontBBox);
- PACK_WORD(p, 3, FAPI_FONT_FEATURE_FontBBox);
- pack_pseo_word_array(r, ff, &p, 14, FAPI_FONT_FEATURE_BlueValues_count, FAPI_FONT_FEATURE_BlueValues);
- pack_pseo_word_array(r, ff, &p, 10, FAPI_FONT_FEATURE_OtherBlues_count, FAPI_FONT_FEATURE_OtherBlues);
- pack_pseo_word_array(r, ff, &p, 14, FAPI_FONT_FEATURE_FamilyBlues_count, FAPI_FONT_FEATURE_FamilyBlues);
- pack_pseo_word_array(r, ff, &p, 10, FAPI_FONT_FEATURE_FamilyOtherBlues_count, FAPI_FONT_FEATURE_FamilyOtherBlues);
- PACK_WORD(p, 0, FAPI_FONT_FEATURE_BlueShift);
- PACK_WORD(p, 0, FAPI_FONT_FEATURE_BlueFuzz);
- PACK_WORD(p, 0, FAPI_FONT_FEATURE_StdHW);
- PACK_WORD(p, 0, FAPI_FONT_FEATURE_StdVW);
- pack_pseo_word_array(r, ff, &p, 12, FAPI_FONT_FEATURE_StemSnapH_count, FAPI_FONT_FEATURE_StemSnapH);
- pack_pseo_word_array(r, ff, &p, 12, FAPI_FONT_FEATURE_StemSnapV_count, FAPI_FONT_FEATURE_StemSnapV);
- PACK_WORD(p, 0, FAPI_FONT_FEATURE_ForceBold);
- PACK_WORD(p, 0, FAPI_FONT_FEATURE_LanguageGroup);
- PACK_WORD(p, 0, FAPI_FONT_FEATURE_lenIV);
- for (j = 0; j < 12; j++)
- PACK_ZERO(p), PACK_ZERO(p); /* Reserved2 */
- /* max data size = 107 words + 6 floats in ASCII */
- n = ff->get_word(ff, FAPI_FONT_FEATURE_Subrs_count, 0);
- pack_word(&p, n);
- for (j = 0; j < n; j++) {
- ushort subr_len = ff->get_subr(ff, j, 0, 0);
- if (subr_len != 0) {
- pack_word(&p, j);
- pack_word(&p, subr_len);
- PACK_BYTE(p, 1); /* is_decrypted */
- ff->get_subr(ff, j, p, subr_len);
- p += subr_len;
- } else
- skip = 1;
- }
- n = ff->get_word(ff, FAPI_FONT_FEATURE_GlobalSubrs_count, 0);
- /* get_word() doesn't have an error return value, so I've used an unlikely value */
- if (n != 65535) {
- pack_word(&p, n);
- for (j = 0; j < n; j++) {
- ushort subr_len = ff->get_gsubr(ff, j, 0, 0);
- if (subr_len != 0) {
- pack_word(&p, j);
- pack_word(&p, subr_len);
- PACK_BYTE(p, 1); /* is_decrypted */
- ff->get_gsubr(ff, j, p, subr_len);
- p += subr_len;
- } else
- skip = 1;
- }
- }
- if (skip)
- pack_word(&p, 0xFFFF);
-}
-
-static char *my_strdup(fapi_ufst_server *r, const char *s, const char *cname)
-{ int len = strlen(s) + 1;
- char *p = (char *)gs_malloc(r->mem, len, 1, cname);
-
- if (p != 0)
- memcpy(p, s, len);
- return p;
-}
-
-static FAPI_retcode fco_open(fapi_ufst_server *r, const char *font_file_path, fco_list_elem **result)
-{ int code;
- fco_list_elem *e = gx_UFST_find_static_fco(font_file_path);
-
- if (e != NULL) {
- *result = e;
- return 0;
- }
- for (e = r->fco_list; e != 0; e = e->next) {
- if (!strcmp(e->file_path, font_file_path))
- break;
- }
- if (e == 0) {
- SW16 fcHandle;
- FSA_FROM_SERVER;
-
- if ((code = CGIFfco_Open(FSA (UB8 *)font_file_path, &fcHandle)) != 0)
- return code;
- e = (fco_list_elem *)gs_malloc(r->mem, sizeof(*e), 1, "fco_list_elem");
- if (e == 0) {
- CGIFfco_Close(FSA fcHandle);
- return e_VMerror;
- }
- e->open_count = 0;
- e->fcHandle = fcHandle;
- e->file_path = my_strdup(r, font_file_path, "fco_file_path");
- if (e->file_path == 0) {
- CGIFfco_Close(FSA fcHandle);
- gs_free(r->mem, e, 0, 0, "fco_list_elem");
- return e_VMerror;
- }
- e->next = r->fco_list;
- r->fco_list = e;
- }
- e->open_count++;
- *result = e;
- return 0;
-}
-
-static FAPI_retcode make_font_data(fapi_ufst_server *r, const char *font_file_path, FAPI_font *ff, ufst_common_font_data **return_data)
-{ ulong area_length = sizeof(ufst_common_font_data), tt_size = 0;
- LPUB8 buf;
- PCLETTO_FHDR *h;
- ufst_common_font_data *d;
- bool use_XL_format = ff->is_mtx_skipped;
- int code;
- FSA_FROM_SERVER;
-
- *return_data = 0;
- r->fc.ttc_index = ff->subfont;
- if (ff->font_file_path == NULL) {
-#if UFST_VERSION_MAJOR < 6
- return(e_invalidaccess);
-#else
- area_length += PCLETTOFONTHDRSIZE;
- if (ff->is_type1) {
- int subrs_count = ff->get_word(ff, FAPI_FONT_FEATURE_Subrs_count, 0);
- int subrs_length = ff->get_long(ff, FAPI_FONT_FEATURE_Subrs_total_size, 0);
- int subrs_area_size;
- int gsubrs_count = ff->get_word(ff, FAPI_FONT_FEATURE_GlobalSubrs_count, 0);
-
- /* get_word() doesn't have an error return value, so I've used an unlikely value */
- if (gsubrs_count != 65535)
- subrs_count += gsubrs_count;
-
- subrs_area_size = subrs_count * 5 + subrs_length + 2;
- area_length += 360 + subrs_area_size; /* some inprecise - see pack_pseo_fhdr */
- } else {
- tt_size = ff->get_long(ff, FAPI_FONT_FEATURE_TT_size, 0);
- if (tt_size == 0)
- return e_invalidfont;
- area_length += tt_size + (use_XL_format ? 6 : 4) + 4 + 2;
- }
-#endif
- } else {
-#if UFST_VERSION_MAJOR < 6
- int sind = strlen(font_file_path) - 1;
-
- if ((font_file_path[sind] != 'o' || font_file_path[sind] != 'O') &&
- (font_file_path[sind - 1] != 'c' || font_file_path[sind - 1] != 'C') &&
- (font_file_path[sind - 2] != 'f' || font_file_path[sind - 2] != 'F') &&
- font_file_path[sind - 3] != '.') {
- return(e_invalidaccess);
- }
-#endif
- area_length += strlen(font_file_path) + 1;
- }
- buf = gs_malloc(r->mem, area_length, 1, "ufst font data");
- if (buf == 0)
- return e_VMerror;
-
- memset(buf, 0x00, area_length);
-
- d = (ufst_common_font_data *)buf;
- d->tt_font_body_offset = 0;
- d->platformId = 0;
- d->specificId = 0;
- d->decodingID[0] = 0;
- d->glyphs = 0;
- d->is_disk_font = (ff->font_file_path != NULL);
- if (d->is_disk_font) {
- fco_list_elem *e = gx_UFST_find_static_fco(font_file_path);
-
- if (e != NULL) {
- memcpy(d + 1, font_file_path, strlen(font_file_path) + 1);
- d->font_id = (e->fcHandle << 16) | ff->subfont;
- d->font_type = FC_FCO_TYPE;
- } else {
- stream *f = sfopen(font_file_path, "rb", r->mem);
- if (f == NULL) {
- emprintf1(r->mem,
- "fapiufst: Can't open %s\n",
- font_file_path);
- return e_undefinedfilename;
- }
- memcpy(d + 1, font_file_path, strlen(font_file_path) + 1);
- d->font_type = get_font_type(f);
- sfclose(f);
- if (d->font_type == FC_FCO_TYPE) {
- fco_list_elem *e;
- if ((code = fco_open(r, font_file_path, &e)) != 0)
- return code;
- d->font_id = (e->fcHandle << 16) | ff->subfont;
- }
- }
- } else {
- d->font_type = (ff->is_type1 ? FC_PST1_TYPE : FC_TT_TYPE);
- d->font_id = ff->get_long(ff, FAPI_FONT_FEATURE_UniqueID, 0);
- if (d->font_id < 0) {
- d->font_id = assign_font_id();
- }
- h = (PCLETTO_FHDR *)(buf + sizeof(ufst_common_font_data));
- h->fontDescriptorSize = PCLETTOFONTHDRSIZE;
- h->descriptorFormat = 15;
- h->fontType = 11; /* wrong */ /* 3- 11=Unicode; 0,1,2 also possible */
- h->style_msb = 0; /* wrong */ /* 4- from PCLT table in TrueType font */
- h->reserved1 = 0;
- h->baselinePosition = 0; /* wrong */ /* 6- from head table in TT font; = 0 */
- h->cellWidth = 1024; /* wrong */ /* 8- head, use xMax - xMin */
- h->cellHeight = 1024; /* wrong */ /* 10- head, use yMax - yMin */
- h->orientation = 0; /* 12- 0 */
- h->spacing = 1; /* wrong */ /* 13- 1=proportional, 0-fixed pitch */
- h->characterSet = 56; /* wrong */ /* 14- same as symSetCode; =56 if unbound. */
- h->pitch = 1024; /* wrong */ /* 16- PCLT */
- h->height = 0; /* 18- 0 if TrueType */
- h->xHeight = 512; /* wrong */ /* 20- PCLT */
- h->widthType = 0; /* wrong */ /* 22- PCLT */
- h->style_lsb = 0; /* wrong */ /* 23- PCLT */
- h->strokeWeight = 0; /* wrong */ /* 24- PCLT */
- h->typeface_lsb = 0; /* wrong */ /* 25- PCLT */
- h->typeface_msb = 0; /* wrong */ /* 26- PCLT */
- h->serifStyle = 0; /* wrong */ /* 27- PCLT */
- h->quality = 0; /* wrong */ /* 28- 2 if TrueType */
- h->placement = 0; /* wronfg */ /* 29- 0 if TrueType */
- h->underlinePosition = 0; /* 30- 0 */
- h->underlineHeight = 0; /* 31- 0 */
- h->textHeight = 102; /* wrong */ /* 32- from OS/2 table in TT font */
- h->textWidth = 1024; /* wrong */ /* 34- OS/2 */
- h->firstCode = 0; /* 36- set to 0 if unbound */
- h->lastCode = 255; /* wrong */ /* 38- max number of downloadable chars if unbound */
- h->pitch_ext = 0; /* 40- 0 if TrueType */
- h->height_ext = 0; /* 41- 0 if TrueType */
- h->capHeight = 1024; /* wrong */ /* 42- PCLT */
- h->fontNumber = d->font_id; /* 44- PCLT */
- h->fontName[0] = 0; /* wrong */ /* 48- PCLT */
- h->scaleFactor = 1024; /* wrong */ /* 64- head:unitsPerEm */
- h->masterUnderlinePosition = 0; /* wrong */ /* 66- post table, or -20% of em */
- h->masterUnderlineHeight = 0; /* wrong */ /* 68- post table, or 5% of em */
- h->fontScalingTechnology = 1; /* 70- 1=TrueType; 0=Intellifont */
- h->variety = 0; /* 71- 0 if TrueType */
- memset((LPUB8)h + PCLETTOFONTHDRSIZE, 0 ,8); /* work around bug in PCLswapHdr : it wants format 10 */
- /* fixme : Most fields above being marked "wrong" look unused by UFST.
- Need to check for sure.
- */
- /* fixme : This code assumes 1-byte alignment for PCLETTO_FHDR structure.
- Use PACK_* macros to improve.
- */
- PCLswapHdr(FSA (UB8 *)h, 0);
- if (ff->is_type1) {
- LPUB8 fontdata = (LPUB8)h + PCLETTOFONTHDRSIZE;
- pack_pseo_fhdr(r, ff, fontdata);
- } else {
- LPUB8 pseg = (LPUB8)h + PCLETTOFONTHDRSIZE;
- LPUB8 fontdata = pseg + (use_XL_format ? 6 : 4);
- if (tt_size > 65000)
- return e_unregistered; /* Must not happen because we skept 'glyp', 'loca' and 'cmap'. */
- pseg[0] = 'G';
- pseg[1] = 'T';
- if (use_XL_format) {
- pseg[2] = tt_size >> 24;
- pseg[3] = (tt_size >> 16) % 256;
- pseg[4] = (tt_size >> 8) % 256;
- pseg[5] = tt_size % 256;
- } else {
- pseg[2] = tt_size / 256;
- pseg[3] = tt_size % 256;
- }
- d->tt_font_body_offset = (LPUB8)fontdata - (LPUB8)d;
- if (ff->serialize_tt_font(ff, fontdata, tt_size))
- return e_invalidfont;
- *(fontdata + tt_size ) = 255;
- *(fontdata + tt_size + 1) = 255;
- *(fontdata + tt_size + 2) = 0;
- *(fontdata + tt_size + 3) = 0;
- *(fontdata + tt_size + 4) = 0;
- *(fontdata + tt_size + 5) = 0; /* checksum */
- }
- }
- *return_data = d;
- return 0;
-}
-
-static void prepare_typeface(fapi_ufst_server *r, ufst_common_font_data *d)
-{ r->fc.format = d->font_type;
- r->fc.font_id = d->font_id;
- r->fc.font_hdr = (UB8 *)(d + 1);
- if (!d->is_disk_font)
- r->fc.format |= FC_EXTERN_TYPE;
-}
-
-static FAPI_retcode get_scaled_font(FAPI_server *server, FAPI_font *ff,
- const FAPI_font_scale *font_scale, const char *xlatmap, FAPI_descendant_code dc)
-{ fapi_ufst_server *r = If_to_I(server);
- FONTCONTEXT *fc = &r->fc;
- /* Note : UFST doesn't provide handles for opened fonts,
- but copies FONTCONTEXT to IFSTATE and caches it.
- Due to this the plugin cannot provide a handle for the font.
- This assumes that only one font context is active at a moment.
- */
- ufst_common_font_data *d = (ufst_common_font_data *)ff->server_font_data;
- const double scale = F_ONE;
- double hx, hy;
- FAPI_retcode code = 0;
- bool use_XL_format = ff->is_mtx_skipped;
- int world_scale = 0;
- FONT_METRICS fm;
- FSA_FROM_SERVER;
-
- if (ff->is_cid && ff->is_type1 && ff->font_file_path == NULL &&
- (dc == FAPI_TOPLEVEL_BEGIN || dc == FAPI_TOPLEVEL_COMPLETE)) {
- /* Don't need any processing for the top level font of a non-disk CIDFontType 0.
- See comment in FAPI_prepare_font.
- Will do with its subfonts individually.
- */
- return 0;
- }
-
- ff->need_decrypt = 1;
- if (d == 0) {
- if ((code = make_font_data(r, ff->font_file_path, ff, &d)) != 0)
- return code;
- ff->server_font_data = d;
- prepare_typeface(r, d);
- if (ff->font_file_path != NULL || ff->is_type1) /* such fonts don't use RAW_GLYPH */
- choose_decoding(r, d, xlatmap);
- }
- else {
- prepare_typeface(r, d);
- if (ff->font_file_path != NULL || ff->is_type1) /* such fonts don't use RAW_GLYPH */
- choose_decoding(r, d, xlatmap);
- }
-
- r->tran_xx = font_scale->matrix[0] / scale, r->tran_xy = font_scale->matrix[1] / scale;
- r->tran_yx = font_scale->matrix[2] / scale, r->tran_yy = font_scale->matrix[3] / scale;
- hx = hypot(r->tran_xx, r->tran_xy), hy = hypot(r->tran_yx, r->tran_yy);
- fc->xspot = F_ONE;
- fc->yspot = F_ONE;
- fc->fc_type = FC_MAT2_TYPE;
-
- fc->s.m2.m[0] = (int)((double)font_scale->matrix[0] / hx + 0.5);
- fc->s.m2.m[1] = (int)((double)font_scale->matrix[1] / hx + 0.5);
- fc->s.m2.m[2] = (int)((double)font_scale->matrix[2] / hy + 0.5);
- fc->s.m2.m[3] = (int)((double)font_scale->matrix[3] / hy + 0.5);
- fc->s.m2.matrix_scale = 16;
- fc->s.m2.xworld_res = font_scale->HWResolution[0] >> 16;
- fc->s.m2.yworld_res = font_scale->HWResolution[1] >> 16;
-
- if ((hx > 0 && hy > 0) && (hx < 1.5 || hy < 1.5)) {
- world_scale = 8;
- hx *= 256;
- hy *= 256;
-
- while (hx < 1.5 || hy < 1.5) {
- world_scale += 8;
- hx *= 256;
- hy *= 256;
- }
- }
- fc->s.m2.world_scale = world_scale;
- fc->s.m2.point_size = (int)(hy * 8 + 0.5); /* 1/8ths of pixels */
- fc->s.m2.set_size = (int)(hx * 8 + 0.5);
- fc->numXsubpixels = font_scale->subpixels[0];
- fc->numYsubpixels = font_scale->subpixels[1];
- fc->alignment = (font_scale->align_to_pixels ? GAGG : GAPP);
- fc->ExtndFlags = 0;
- if (d->font_type == FC_TT_TYPE)
- fc->ssnum = USER_CMAP;
- else if (d->font_type == FC_FCO_TYPE) {
- fc->ssnum = UNICODE;
- } else if (d->font_type == FC_PST1_TYPE) {
- fc->ssnum = T1ENCODING;
- }
-
- if (d->font_type != FC_TT_TYPE && d->font_type != FC_FCO_TYPE) {
- fc->ExtndFlags = EF_NOSYMSETMAP;
- }
- fc->ExtndFlags |= EF_SUBSTHOLLOWBOX_TYPE;
- fc->format |= FC_NON_Z_WIND; /* NON_ZERO Winding required for TrueType */
- fc->format |= FC_INCHES_TYPE; /* output in units per inch */
- fc->user_platID = d->platformId;
- fc->user_specID = d->specificId;
- if (use_XL_format)
- fc->ExtndFlags |= EF_XLFONT_TYPE;
- if (ff->is_vertical)
- fc->ExtndFlags |= EF_UFSTVERT_TYPE;
- fc->dl_ssnum = (d->specificId << 4) | d->platformId;
- fc->ttc_index = ff->subfont;
- r->callback_error = 0;
-
- code = CGIFfont(FSA fc);
- if (r->callback_error != 0)
- return r->callback_error;
-
- code = CGIFfont_metrics(&fm);
- if (r->callback_error != 0)
- return r->callback_error;
-
- return code;
-}
-
-static FAPI_retcode get_decodingID(FAPI_server *server, FAPI_font *ff, const char **decodingID_result)
-{ fapi_ufst_server *r = If_to_I(server);
- ufst_common_font_data *d = (ufst_common_font_data *)r->fc.font_hdr - 1;
-
- *decodingID_result = d->decodingID;
- return 0;
-}
-
-static FAPI_retcode get_font_bbox(FAPI_server *server, FAPI_font *ff, int BBox[4])
-{ fapi_ufst_server *r = If_to_I(server);
- SW16 VLCPower = 0;
- int code;
- FSA_FROM_SERVER;
-
- if ((code = CGIFbound_box(FSA BBox, &VLCPower)) < 0)
- return code;
- /* UFST expands bbox for internal needs, and retrives the expanded bbox.
- We believe it's bug in UFST.
- Now we collapse it back to the correct size :
- */
- BBox[0] += 2;
- BBox[1] += 2;
- BBox[2] -= 2;
- BBox[3] -= 2;
- BBox[0] >>= VLCPower;
- BBox[1] >>= VLCPower;
- BBox[2] >>= VLCPower;
- BBox[3] >>= VLCPower;
- return 0;
-}
-
-static FAPI_retcode get_font_proportional_feature(FAPI_server *server, FAPI_font *ff, bool *bProportional)
-{ fapi_ufst_server *r = If_to_I(server);
- FSA_FROM_SERVER;
-
- *bProportional = FALSE;
- if (ff->font_file_path == NULL || ff->is_type1)
- return 0;
-#if TT_ROM || TT_DISK
- {
- UB8 buf[74];
- UL32 length = sizeof(buf);
-
- if (CGIFtt_query(FSA (UB8 *)ff->font_file_path, *(UL32 *)"OS/2", (UW16)ff->subfont, &length, buf) != 0)
- return 0; /* No OS/2 table - no chance to get the info. Use default == FALSE. */
- *bProportional = (buf[35] == 9);
- }
-#endif
- return 0;
-}
-
-static inline void make_asciiz_char_name(char *buf, int buf_length, FAPI_char_ref *c)
-{ int len = min(buf_length - 1, c->char_name_length);
-
- memcpy(buf, c->char_name, len);
- buf[len] = 0;
-}
-
-#define MAX_CHAR_NAME_LENGTH 30
-
-static FAPI_retcode can_retrieve_char_by_name(FAPI_server *server, FAPI_font *ff, FAPI_char_ref *c, int *result)
-{ fapi_ufst_server *r = If_to_I(server);
- FSA_FROM_SERVER;
-
- *result = 0;
-
- switch (r->fc.format & FC_FONTTYPE_MASK) {
- case FC_PST1_TYPE :
- *result = 1;
- break;
- case FC_TT_TYPE :
- break;
- }
-
- return 0;
-}
-
-static FAPI_retcode can_replace_metrics(FAPI_server *server, FAPI_font *ff, FAPI_char_ref *c, int *result)
-{ *result = (!ff->is_type1 && ff->font_file_path == NULL &&
- c->metrics_scale == 0 && c->metrics_type == FAPI_METRICS_REPLACE);
- return 0;
-}
-
-static void release_glyphs(fapi_ufst_server *r, ufst_common_font_data *d)
-{
- if (d) {
- while (d->glyphs != 0) {
- pcleo_glyph_list_elem *e = d->glyphs;
- d->glyphs = e->next;
- gs_free(r->mem, e, 0, 0, "PCLEO char");
- }
- d->glyphs = NULL;
- }
-}
-
-static FAPI_retcode get_fontmatrix(FAPI_server *I, gs_matrix *m)
-{
- fapi_ufst_server *r = If_to_I(I);
- ufst_common_font_data *d = (ufst_common_font_data *)I->ff.server_font_data;
- FAPI_retcode code = 0;
-
- if (d == 0) {
- if ((code = make_font_data(r, I->ff.font_file_path, &(I->ff), &d)) != 0)
- return (code);
- I->ff.server_font_data = d;
- prepare_typeface(r, d);
- }
-
- /* There are PS jobs that rely on the standard fonts having
- * a FontMatrix of [0.001 0 0 0.001 0 0], but MT fonts actually
- * have an identity matrix. We need to compensate here. Other
- * fonts need an identity matrix returned here, as we apply the
- * font matrix explicitly in the scale calculation in zfapi.c
- */
- if (d->font_type & FC_FCO_TYPE) {
- m->xx = 0.001;
- m->xy = 0.0;
- m->yx = 0.0;
- m->yy = 0.001;
- m->tx = 0.0;
- m->ty = 0.0;
- }
- else {
- m->xx = 1.0;
- m->xy = 0.0;
- m->yx = 0.0;
- m->yy = 1.0;
- m->tx = 0.0;
- m->ty = 0.0;
- }
-
-#if 0
- gs_matrix *base_font_matrix = &I->initial_FontMatrix;
- m->xx = I->initial_FontMatrix.xx;
- m->xy = I->initial_FontMatrix.xy;
- m->yx = I->initial_FontMatrix.yx;
- m->yy = I->initial_FontMatrix.yy;
- m->tx = I->initial_FontMatrix.tx;
- m->ty = I->initial_FontMatrix.ty;
-#endif
- return (code);
-
-}
-
-static int export_outline(fapi_ufst_server *r, PIFOUTLINE pol, FAPI_path *p)
-{ POUTLINE_CHAR outchar;
- SW16 num_contrs,num_segmts;
- LPSB8 segment;
- PINTRVECTOR points;
- SW16 i,j;
-
- if (pol == NULL)
- return 0;
- p->shift += r->If.frac_shift + pol->VLCpower;
- outchar = &pol->ol;
- num_contrs = outchar->num_loops;
- for(i = 0; i<num_contrs; i++) {
- num_segmts = outchar->loop[i].num_segmts;
- segment = (LPSB8)((LPSB8)(outchar->loop) + outchar->loop[i].segmt_offset);
- points = (PINTRVECTOR)((LPSB8)(outchar->loop) + outchar->loop[i].coord_offset);
- for(j=0; j<num_segmts; j++) {
-
- if(*segment == 0x00) {
- if ((p->gs_error = p->moveto(p, ((int64_t)points->x) << 16, ((int64_t)points->y) << 16)) != 0)
- return p->gs_error;
- points++;
- } else if (*segment == 0x01) {
- if ((p->gs_error = p->lineto(p, ((int64_t)points->x) << 16, ((int64_t)points->y) << 16)) != 0)
- return p->gs_error;
- points++;
- } else if (*segment == 0x02) {
- points+=2;
- return e_invalidfont; /* This must not happen */
- } else if (*segment == 0x03) {
- if ((p->gs_error = p->curveto(p, ((int64_t)points[0].x) << 16, ((int64_t)points[0].y) << 16,
- ((int64_t)points[1].x) << 16, ((int64_t)points[1].y) << 16,
- ((int64_t)points[2].x) << 16, ((int64_t)points[2].y)<< 16) < 0))
- return p->gs_error;
- points+=3;
- } else
- return e_invalidfont; /* This must not happen */
- segment++;
- }
- }
- return 0;
-}
-
-static inline void set_metrics(fapi_ufst_server *r, FAPI_metrics *metrics, SL32 design_bbox[4], SW16 design_escapement[2], SW16 du_emx, SW16 du_emy)
-{
-
- metrics->escapement = design_escapement[0];
- metrics->v_escapement = design_escapement[1];
- metrics->em_x = du_emx;
- metrics->em_y = du_emy;
- metrics->bbox_x0 = design_bbox[0];
- metrics->bbox_y0 = design_bbox[1];
- metrics->bbox_x1 = design_bbox[2];
- metrics->bbox_y1 = design_bbox[3];
-}
-
-static FAPI_retcode get_char(fapi_ufst_server *r, FAPI_font *ff, FAPI_char_ref *c, FAPI_path *p, FAPI_metrics *metrics, UW16 format)
-{
- UW16 code = 0, code2 = 0;
- UW16 cc = (UW16)c->char_code;
- SL32 design_bbox[4];
- char PSchar_name[MAX_CHAR_NAME_LENGTH];
- MEM_HANDLE result;
- ufst_common_font_data *d = (ufst_common_font_data *)ff->server_font_data;
- SW16 design_escapement[2];
- SW16 du_emx, du_emy;
- const char *notdef = ".notdef";
- const void *client_char_data = ff->char_data;
- const int client_char_data_len = ff->char_data_len;
- bool need_decrypt = ff->need_decrypt;
- int length;
- FSA_FROM_SERVER;
-
- design_escapement[0] = design_escapement[1] = 0;
-
- if (ff->is_type1) {
- /* If a charstring in a Type 1 has been replaced with a PS procedure
- * get_glyph will return -1. We can then return char_code + 1 which
- * tells the FAPI code we might be dealing with a procedure, and to
- * try executing it as such.
- */
- ff->need_decrypt = false;
- length = ff->get_glyph(ff, c->char_code, NULL, 0);
- ff->need_decrypt = need_decrypt;
- if (length == -1) {
- return(c->char_code + 1);
- }
- }
-
- memset(metrics, 0, sizeof(*metrics));
- metrics->bbox_x1 = -1;
-
- if (ff->is_type1 && !ff->is_cid) {
- int len = min(ff->char_data_len, sizeof(PSchar_name) - 1);
- memcpy (PSchar_name, ff->char_data, len);
- PSchar_name[len] = 0;
- } else {
- make_asciiz_char_name(PSchar_name, sizeof(PSchar_name), c);
- }
-
- CGIFchIdptr(FSA &cc, PSchar_name); /* fixme : Likely only FC_PST1_TYPE needs it. */
- { /* hack : Changing UFST internal data. Change to r->fc doesn't help,
- because UFST thinks that the "outline/raster" is a property of current font. */
- pIFS->fcCur.format &= ~FC_OUTPUT_MASK;
- pIFS->fcCur.format |= format;
- }
- r->bRaster = FALSE;
- r->ff = ff;
- r->callback_error = 0;
- r->sb_x = c->sb_x;
- r->aw_x = c->aw_x;
- r->metrics_type = c->metrics_type;
- if (d->font_type == FC_FCO_TYPE && r->fc.ExtndFlags & EF_SUBSTHOLLOWBOX_TYPE) {
- if (c->char_name != NULL && c->char_name_length == 7 &&
- !memcmp(c->char_name, ".notdef", 7)) {
- /* With EF_SUBSTHOLLOWBOX_TYPE and FCO,
- UFST paints a hollow box insted .notdef .
- For Adobe compatibility we substitute a space,
- because Adobe Type 1 fonts define .notdef as a space . */
- cc = 32;
- }
- }
-#if !UFST_REENTRANT
- static_server_ptr_for_ufst_callback = r;
-#endif
- code = CGIFchar_handle(FSA cc, &result, (SW16)0);
- if (code && code != ERR_fixed_space && code != ERR_bm_buff && code != ERR_bm_too_big) {
- /* There is no such char in the font, try the glyph 0 (notdef) : */
- UW16 c1 = 0, ssnum = pIFS->fcCur.ssnum;
-
- if (d->font_type == FC_FCO_TYPE) {
- /* EF_SUBSTHOLLOWBOX_TYPE must work against it.
- Ensure the plugin plug__xi.fco is loaded. */
- /* fixme : Due to unknown reason EF_SUBSTHOLLOWBOX_TYPE
- doesn't work for Symbol, Dingbats, Wingdings.
- hack : render the space character. */
- c1 = 32;
- } else {
- /* hack : Changing UFST internal data - see above. */
- pIFS->fcCur.ssnum = RAW_GLYPH;
- }
- r->callback_error = 0;
- ff->char_data = (void *)notdef;
- ff->char_data_len = strlen(notdef);
- CGIFchIdptr(FSA (void *)&c1, (void *)notdef);
- code2 = CGIFchar_handle(FSA c1, &result, (SW16)0);
- if (code2 && code2 != ERR_fixed_space && code2 != ERR_bm_buff && code2 != ERR_bm_too_big) {
- ff->char_data = (void *)"space";
- ff->char_data_len = strlen("space");
- CGIFchIdptr(FSA (void *)&c1, (void *)"space");
- code2 = CGIFchar_handle(FSA c1, &result, (SW16)0);
- }
- if (!code2 || code2 == ERR_fixed_space) {
- code = code2;
- }
- pIFS->fcCur.ssnum = ssnum;
- }
- ff->char_data = client_char_data;
- ff->char_data_len = client_char_data_len;
-
-#if !UFST_REENTRANT
- static_server_ptr_for_ufst_callback = 0;
-#endif
- r->ff = 0;
- release_glyphs(r, (ufst_common_font_data *)ff->server_font_data);
- if (code != ERR_fixed_space && code != 0)
- return code;
- if (r->callback_error != 0)
- return r->callback_error;
- if (format == FC_BITMAP_TYPE) {
- IFBITMAP *pbm = (IFBITMAP *)result;
-
- du_emx = pbm->du_emx;
- du_emy = pbm->du_emy;
- r->char_data = pbm;
- r->bRaster = TRUE;
-
- design_escapement[0] = pbm->escapement;
-
-#if UFST_VERSION_MAJOR >= 6 && UFST_VERSION_MINOR >= 2
-
- design_bbox[0] = pIFS->glyphMetricsDU.bbox.BBox[0];
- design_bbox[1] = pIFS->glyphMetricsDU.bbox.BBox[1];
- design_bbox[2] = pIFS->glyphMetricsDU.bbox.BBox[2];
- design_bbox[3] = pIFS->glyphMetricsDU.bbox.BBox[3];
- if (d->font_type != FC_FCO_TYPE) {
- design_escapement[0] = pIFS->glyphMetricsDU.aw.x;
- design_escapement[1] = pIFS->glyphMetricsDU.aw.y;
- }
-#endif
-
- } else {
- IFOUTLINE *pol = (IFOUTLINE *)result;
-
- design_escapement[0] = pol->escapement;
- du_emx = pol->du_emx;
- du_emy = pol->du_emy;
- r->char_data = (IFOUTLINE *)result;
- }
-#if 1 /* UFST 5.0 */
- if (USBOUNDBOX && d->font_type == FC_FCO_TYPE) {
- if (pIFS->USBBOXorigScaleFactor /* fixme : Must we check this ? */
- && pIFS->USBBOXorigScaleFactor != pIFS->USBBOXscaleFactor) {
- /* See fco_make_gaso_and_stats in fc_if.c . Debugged with hollow box in Helvetica. */
- /* Fixme : this looses a precision, an UFST bug has been reported. */
- int w = pIFS->USBBOXorigScaleFactor / 2;
-
- design_bbox[0] = pIFS->USBBOXxmin * pIFS->USBBOXscaleFactor / pIFS->USBBOXorigScaleFactor;
- design_bbox[1] = pIFS->USBBOXymin * pIFS->USBBOXscaleFactor / pIFS->USBBOXorigScaleFactor;
- design_bbox[2] = (pIFS->USBBOXxmax * pIFS->USBBOXscaleFactor + w) / pIFS->USBBOXorigScaleFactor;
- design_bbox[3] = (pIFS->USBBOXymax * pIFS->USBBOXscaleFactor + w) / pIFS->USBBOXorigScaleFactor;
- } else {
- design_bbox[0] = pIFS->USBBOXxmin;
- design_bbox[1] = pIFS->USBBOXymin;
- design_bbox[2] = pIFS->USBBOXxmax;
- design_bbox[3] = pIFS->USBBOXymax;
- }
- } else {
-#if UFST_VERSION_MAJOR >= 6 && UFST_VERSION_MINOR >= 2
-#else
- /* fixme: UFST 5.0 doesn't provide this data.
- Stubbing with Em box.
- Non-FCO fonts may be cropped if a glyph goes outside Em box
- (or occupy negative coordinates, such as 'y'.).
- Non-FCO fonts may be uncached if Em box is much bigger than the glyph.
- */
- design_bbox[0] = 0;
- design_bbox[1] = 0;
- design_bbox[2] = du_emx;
- design_bbox[3] = du_emy;
-#endif
- }
-#endif
- { /* UFST performs a dual rounding of the glyph origin : first
- the scaled glyph design origin is rounded to pixels with floor(x + 0.5),
- second the glyph position is rounded to pixels with floor(x + 0.5).
- Ghostscript rounds with floor(x) due to the pixel-center-inside rule.
-
- A right way would be to specify the half pixel offset to the glyph
- origin for the rendering glyph, but UFST has no interface for doing that.
- Instead that, to prevent a possible cropping while copying a glyph to cache cell,
- we expand the design bbox in a value of a pixel size.
- We could not determine the necessary expansion theoretically,
- and choosen expansion coefficients empirically,
- which appears equal to 2 pixels.
-
- fixme: Actually the expansion is the FONTCONTEXT property,
- so it could be computed at once when the scaled font is created.
- */
- const double expansion_x = 2, expansion_y = 2; /* pixels */ /* adesso5.pdf */
- const double XX = r->tran_xx * (r->fc.s.m2.xworld_res >> 16) / 72 / du_emx;
- const double XY = r->tran_xy * (r->fc.s.m2.yworld_res >> 16) / 72 / du_emy;
- const double YX = r->tran_yx * (r->fc.s.m2.xworld_res >> 16) / 72 / du_emx;
- const double YY = r->tran_yy * (r->fc.s.m2.yworld_res >> 16) / 72 / du_emy;
- const double det = XX * YY - XY * YX;
- const double deta = det < 0 ? -det : det;
-
- if (deta > 0.0000000001) {
- const double xx = YY / det, xy = -XY / det;
- const double yx = -YX / det, yy = XX / det;
- const double dx = -(expansion_x * xx + expansion_y * xy);
- const double dy = -(expansion_x * yx + expansion_y * yy);
- const SL32 dxa = (SL32)((dx < 0 ? -dx : dx) + 0.5);
- const SL32 dya = (SL32)((dy < 0 ? -dy : dy) + 0.5);
-
- design_bbox[0] -= dxa;
- design_bbox[1] -= dya;
- design_bbox[2] += dxa;
- design_bbox[3] += dya;
- }
- }
- set_metrics(r, metrics, design_bbox, design_escapement, du_emx, du_emy);
- if (code == ERR_fixed_space)
- release_char_data_inline(r);
- return 0;
-}
-
-static FAPI_retcode get_char_outline_metrics(FAPI_server *server, FAPI_font *ff, FAPI_char_ref *c, FAPI_metrics *metrics)
-{ fapi_ufst_server *r = If_to_I(server);
-
- release_char_data_inline(r);
- return get_char(r, ff, c, NULL, metrics, FC_CUBIC_TYPE);
- /* UFST cannot render enough metrics information without generating raster or outline.
- r->char_data keeps an outline after calling this function.
- */
-}
-
-static FAPI_retcode get_char_outline(FAPI_server *server, FAPI_path *p)
-{ fapi_ufst_server *r = If_to_I(server);
-
- return export_outline(r, (IFOUTLINE *)r->char_data, p);
-}
-
-static FAPI_retcode get_char_raster_metrics(FAPI_server *server, FAPI_font *ff, FAPI_char_ref *c, FAPI_metrics *metrics)
-{
- fapi_ufst_server *r = If_to_I(server);
- int code;
-
- release_char_data_inline(r);
- code = get_char(r, ff, c, NULL, metrics, FC_BITMAP_TYPE);
- if (code == ERR_bm_buff || code == ERR_bm_too_big) /* Too big character ? */
- return (e_VMerror);
- return code;
- /* UFST cannot render enough metrics information without generating raster or outline.
- r->char_data keeps a raster after calling this function.
- */
-}
-
-static FAPI_retcode get_char_width(FAPI_server *server, FAPI_font *ff, FAPI_char_ref *c, FAPI_metrics *metrics)
-{
- fapi_ufst_server *r = If_to_I(server);
- int code;
-
- release_char_data_inline(r);
- code = get_char(r, ff, c, NULL, metrics, server->use_outline ? FC_CUBIC_TYPE : FC_BITMAP_TYPE);
- if (code == ERR_bm_buff || code == ERR_bm_too_big) /* Too big character ? */
- return (e_VMerror);
- return code;
- /* UFST cannot render enough metrics information without generating raster or outline.
- r->char_data keeps a raster after calling this function.
- */
-}
-
-
-static FAPI_retcode get_char_raster(FAPI_server *server, FAPI_raster *rast)
-{ fapi_ufst_server *r = If_to_I(server);
-
- if (!r->bRaster)
- return e_limitcheck;
- else if (r->char_data == NULL) {
- rast->height = rast->width = rast->line_step = 0;
- rast->p = 0;
- } else {
- IFBITMAP *pbm = (IFBITMAP *)r->char_data;
- rast->p = pbm->bm;
- rast->height = pbm->top_indent + pbm->black_depth;
- rast->width = pbm->left_indent + pbm->black_width;
- rast->line_step = pbm->width;
- rast->left_indent = pbm->left_indent;
- rast->top_indent = pbm->top_indent;
- rast->black_width = pbm->black_width;
- rast->black_height = pbm->black_depth;
- if (rast->width != 0) {
- rast->orig_x = pbm->xorigin;
- rast->orig_y = pbm->yorigin;
- } else
- rast->orig_x = rast->orig_y = 0;
- }
- return 0;
-}
-
-static FAPI_retcode release_char_data(FAPI_server *server)
-{ fapi_ufst_server *r = If_to_I(server);
-
- release_char_data_inline(r);
- return 0;
-}
-
-static void release_fco(fapi_ufst_server *r, SW16 fcHandle)
-{
- fco_list_elem **e;
-
- if(gx_UFST_find_static_fco_handle(fcHandle) != NULL)
- return;
- for (e = &r->fco_list; *e != 0; )
- if ((*e)->fcHandle == fcHandle && (--(*e)->open_count) == 0) {
- fco_list_elem *ee = *e;
- FSA_FROM_SERVER;
-
- *e = ee->next;
- CGIFfco_Close(FSA ee->fcHandle);
- gs_free(r->mem, ee->file_path, 0, 0, "fco_file_path");
- gs_free(r->mem, ee, 0, 0, "fco_list_elem");
- } else
- e = &(*e)->next;
-}
-
-static FAPI_retcode FAPIU_release_typeface(FAPI_server *server, void *font_data)
-{ fapi_ufst_server *r = If_to_I(server);
- ufst_common_font_data *d;
- FAPI_retcode code = 0;
- FSA_FROM_SERVER;
-
- release_char_data_inline(r);
- if (font_data == 0)
- return 0;
- d = (ufst_common_font_data *)font_data;
-#if 0
- prepare_typeface(r, d);
- if (d->is_disk_font)
- code = CGIFhdr_font_purge(FSA &r->fc);
- else
- code = CGIFfont_purge(FSA &r->fc);
-#endif
-
- release_glyphs(r, d);
- release_fco(r, (SW16)(d->font_id >> 16));
- gs_free(r->mem, font_data, 0, 0, "ufst font data");
- return code;
-}
-
-static FAPI_retcode check_cmap_for_GID(FAPI_server *server, uint *index)
-{
- return 0;
-}
-
-/* --------------------- The plugin definition : ------------------------- */
-
-static void gs_fapiufst_finit(i_plugin_instance *instance, i_plugin_client_memory *mem);
-
-static const i_plugin_descriptor ufst_descriptor = {
- "FAPI",
- "UFST",
- gs_fapiufst_finit
-};
-
-static const FAPI_server If0 = {
- { &ufst_descriptor
- },
- 16, /* frac_shift */
- {gs_no_id},
- {0},
- 0,
- false,
- {1, 0, 0, 1, 0, 0},
- ensure_open,
- get_scaled_font,
- get_decodingID,
- get_font_bbox,
- get_font_proportional_feature,
- can_retrieve_char_by_name,
- can_replace_metrics,
- get_fontmatrix,
- get_char_width,
- get_char_raster_metrics,
- get_char_raster,
- get_char_outline_metrics,
- get_char_outline,
- release_char_data,
- FAPIU_release_typeface,
- check_cmap_for_GID
-};
-
-static int fapiu_make_string (i_ctx_t *i_ctx_p, const char *str, ref *obj)
-{
- int len = strlen(str);
- byte *sbody;
-
- sbody = ialloc_string(len, "fapiu_make_string");
- if (!sbody) {
- return(e_VMerror);
- }
- memcpy (sbody, str, len);
-
- make_string(obj, a_all | icurrent_space, len, sbody);
-
- return(0);
-}
-
-plugin_instantiation_proc(gs_fapiufst_instantiate); /* check prototype */
-
-int gs_fapiufst_instantiate(i_plugin_client_memory *client_mem, i_plugin_instance **p_instance)
-{
- fapi_ufst_server *r = (fapi_ufst_server *)client_mem->alloc(client_mem, sizeof(fapi_ufst_server), "fapi_ufst_server");
- i_ctx_t *i_ctx_p = NULL;
- gs_main_instance *inst;
- ref entry;
- char tmppath[gp_file_name_sizeof];
- int code = 0;
-
- if (r == 0)
- return e_Fatal;
- memset(r, 0, sizeof(*r));
- r->If = If0;
-
- code = gs_memory_chunk_wrap(&(r->mem), client_mem->client_data);
- if (code != 0) {
- return(code);
- }
-
- *p_instance = &r->If.ig;
-
- inst = get_minst_from_memory((const gs_memory_t *)(client_mem->client_data));
- i_ctx_p = inst->i_ctx_p;
-
- /* The following entries will get overwritten if the user specifies alternative settings
- * on the command line.
- */
- strncpy(tmppath, UFSTFONTDIR, gp_file_name_sizeof);
- strncat(tmppath, UFST_PlugIn_Path, gp_file_name_sizeof - strlen(tmppath));
-
- fapiu_make_string (i_ctx_p, (const char *)tmppath, &entry);
- (void)dict_put_string(systemdict, UFST_PlugIn_Str, &entry, NULL);
-
- strncpy(tmppath, UFSTFONTDIR, gp_file_name_sizeof);
- strncat(tmppath, FCOfontfilePath, gp_file_name_sizeof - strlen(tmppath));
-
- fapiu_make_string (i_ctx_p, (const char *)tmppath, &entry);
- (void)dict_put_string(systemdict, FCOfontfileStr, &entry, NULL);
-
- strncpy(tmppath, UFSTFONTDIR, gp_file_name_sizeof);
- strncat(tmppath, FCOfontfile2Path, gp_file_name_sizeof - strlen(tmppath));
-
- fapiu_make_string (i_ctx_p, (const char *)tmppath, &entry);
- (void)dict_put_string(systemdict, FCOfontfile2Str, &entry, NULL);
-
- fapiu_make_string (i_ctx_p, FAPIfontmap, &entry);
- (void)dict_put_string(systemdict, FAPIfontmapStr, &entry, NULL);
-
- return 0;
-}
-
-#ifndef UFST_MEMORY_CHECKING
-#define UFST_MEMORY_CHECKING 0
-#endif
-
-#if UFST_MEMORY_CHECKING
-extern unsigned long maxmem;
-#endif
-
-static void gs_fapiufst_finit(i_plugin_instance *this, i_plugin_client_memory *mem)
-{ fapi_ufst_server *r = (fapi_ufst_server *)this;
- FSA_FROM_SERVER;
-
-#if UFST_MEMORY_CHECKING
- dmprintf1(r->mem, "UFST used %Lf kb\n", ((long double)maxmem) / 1024);
-#endif
-
- if (r->If.ig.d != &ufst_descriptor)
- return; /* safety */
-#if 0 /* Disabled against a reentrancy problem
- in a single language build for host-based applications. */
- gx_set_UFST_Callbacks(NULL, NULL, NULL);
-#endif
- release_char_data_inline(r);
- if (r->bInitialized && !r->ufst_is_singleton)
- gx_UFST_fini();
- if (r->param) {
- gs_free (r->mem, r->param, 0, 0, "server_params");
- }
- gs_memory_chunk_release (r->mem);
-
- mem->free(mem, r, "fapi_ufst_server");
-}
diff --git a/gs/psi/ifapi.h b/gs/psi/ifapi.h
index a13c42afe..104466e19 100644
--- a/gs/psi/ifapi.h
+++ b/gs/psi/ifapi.h
@@ -25,225 +25,6 @@
#include "memory_.h"
#include "gp.h"
-typedef int FracInt; /* A fractional integer with statically unknown number of fraction bits.
- The number of bits depends on plugin and is being specified in
- FAPI_server::frac_shift.
- */
-typedef int FAPI_retcode;
-
-typedef enum {
- FAPI_FONT_FEATURE_FontMatrix,
- FAPI_FONT_FEATURE_UniqueID,
- FAPI_FONT_FEATURE_BlueScale,
- FAPI_FONT_FEATURE_Weight,
- FAPI_FONT_FEATURE_ItalicAngle,
- FAPI_FONT_FEATURE_IsFixedPitch,
- FAPI_FONT_FEATURE_UnderLinePosition,
- FAPI_FONT_FEATURE_UnderlineThickness,
- FAPI_FONT_FEATURE_FontType,
- FAPI_FONT_FEATURE_FontBBox,
- FAPI_FONT_FEATURE_BlueValues_count,
- FAPI_FONT_FEATURE_BlueValues,
- FAPI_FONT_FEATURE_OtherBlues_count,
- FAPI_FONT_FEATURE_OtherBlues,
- FAPI_FONT_FEATURE_FamilyBlues_count,
- FAPI_FONT_FEATURE_FamilyBlues,
- FAPI_FONT_FEATURE_FamilyOtherBlues_count,
- FAPI_FONT_FEATURE_FamilyOtherBlues,
- FAPI_FONT_FEATURE_BlueShift,
- FAPI_FONT_FEATURE_BlueFuzz,
- FAPI_FONT_FEATURE_StdHW,
- FAPI_FONT_FEATURE_StdVW,
- FAPI_FONT_FEATURE_StemSnapH_count,
- FAPI_FONT_FEATURE_StemSnapH,
- FAPI_FONT_FEATURE_StemSnapV_count,
- FAPI_FONT_FEATURE_StemSnapV,
- FAPI_FONT_FEATURE_ForceBold,
- FAPI_FONT_FEATURE_LanguageGroup,
- FAPI_FONT_FEATURE_lenIV,
- FAPI_FONT_FEATURE_GlobalSubrs_count,
- FAPI_FONT_FEATURE_Subrs_count,
- FAPI_FONT_FEATURE_Subrs_total_size,
- FAPI_FONT_FEATURE_TT_size,
- /* Multiple Master specifics */
- FAPI_FONT_FEATURE_DollarBlend,
- FAPI_FONT_FEATURE_DollarBlend_length,
- FAPI_FONT_FEATURE_BlendAxisTypes_count,
- FAPI_FONT_FEATURE_BlendAxisTypes,
- FAPI_FONT_FEATURE_BlendPrivate_count,
- FAPI_FONT_FEATURE_BlendFontInfo_count,
- FAPI_FONT_FEATURE_WeightVector_count,
- FAPI_FONT_FEATURE_WeightVector,
- FAPI_FONT_FEATURE_BlendDesignPositionsArrays_count,
- FAPI_FONT_FEATURE_BlendDesignPositionsArrayValue,
- FAPI_FONT_FEATURE_BlendDesignMapArrays_count,
- FAPI_FONT_FEATURE_BlendDesignMapSubArrays_count,
- FAPI_FONT_FEATURE_BlendDesignMapArrayValue,
- /* End MM specifics */
- /* CharString emission */
- FAPI_FONT_FEATURE_CharStrings_count,
- /* End CharString emission */
-} fapi_font_feature;
-
-typedef enum {
- FAPI_METRICS_NOTDEF,
- FAPI_METRICS_ADD, /* Add to native glyph width. */
- FAPI_METRICS_REPLACE_WIDTH, /* Replace the native glyph width. */
- FAPI_METRICS_REPLACE /* Replace the native glyph width and lsb. */
-} FAPI_metrics_type;
-
-typedef struct {
- int char_code; /* Backwards compatibility. Depricated. */
- int client_char_code; /* Debug purpose. */
- int char_codes[4];
- int char_codes_count;
- bool is_glyph_index; /* true if char_code contains glyph index */
- const unsigned char *char_name; /* to be used exclusively with char_code. */
- unsigned int char_name_length;
- FAPI_metrics_type metrics_type;
- FracInt sb_x, sb_y, aw_x, aw_y; /* replaced PS metrics. */
- int metrics_scale; /* Scale for replaced PS metrics.
- Zero means "em box size". */
-} FAPI_char_ref;
-
-typedef struct FAPI_font_s FAPI_font;
-struct FAPI_font_s {
- /* server's data : */
- void *server_font_data;
- bool need_decrypt;
- /* client's data : */
- const gs_memory_t *memory;
- const char *font_file_path;
- int subfont;
- bool is_type1; /* Only for non-disk fonts; dirty for disk fonts. */
- bool is_cid;
- bool is_outline_font;
- bool is_mtx_skipped; /* Ugly. Only UFST needs. */
- bool is_vertical;
- void *client_ctx_p;
- void *client_font_data;
- void *client_font_data2;
- const void *char_data;
- int char_data_len;
- unsigned short (*get_word )(FAPI_font *ff, fapi_font_feature var_id, int index);
- unsigned long (*get_long )(FAPI_font *ff, fapi_font_feature var_id, int index);
- float (*get_float)(FAPI_font *ff, fapi_font_feature var_id, int index);
- int (*get_name) (FAPI_font *ff, fapi_font_feature var_id, int index, char *buffer, int len);
- int (*get_proc) (FAPI_font *ff, fapi_font_feature var_id, int index, char *Buffer);
- unsigned short (*get_gsubr)(FAPI_font *ff, int index, byte *buf, ushort buf_length);
- unsigned short (*get_subr) (FAPI_font *ff, int index, byte *buf, ushort buf_length);
- unsigned short (*get_raw_subr) (FAPI_font *ff, int index, byte *buf, ushort buf_length);
- int (*get_glyph)(FAPI_font *ff, int char_code, byte *buf, ushort buf_length);
- unsigned short (*serialize_tt_font)(FAPI_font *ff, void *buf, int buf_size);
- unsigned short (*get_charstring) (FAPI_font *ff, int index, byte *buf, ushort buf_length);
- unsigned short (*get_charstring_name) (FAPI_font *ff, int index, byte *buf, ushort buf_length);
-};
-
-typedef struct FAPI_face_s FAPI_face;
-struct FAPI_face_s {
- gs_id font_id;
- gs_matrix ctm;
- gs_log2_scale_point log2_scale;
- bool align_to_pixels;
- float HWResolution[2];
-};
-
-typedef struct FAPI_path_s FAPI_path;
-struct FAPI_path_s {
- void *olh; /* Client's data. */
- int shift;
- int gs_error;
- int (*moveto )(FAPI_path *, int64_t, int64_t);
- int (*lineto )(FAPI_path *, int64_t, int64_t);
- int (*curveto )(FAPI_path *, int64_t, int64_t, int64_t, int64_t, int64_t, int64_t);
- int (*closepath)(FAPI_path *);
-};
-
-typedef struct FAPI_font_scale_s {
- FracInt matrix[6];
- FracInt HWResolution[2];
- int subpixels[2];
- bool align_to_pixels;
-} FAPI_font_scale;
-
-typedef struct FAPI_metrics_s {
- int bbox_x0, bbox_y0, bbox_x1, bbox_y1; /* design units */
- int escapement; /* design units */
- int v_escapement; /* design units */
- int em_x, em_y; /* design units */
-} FAPI_metrics;
-
-typedef struct { /* 1bit/pixel only, rows are byte-aligned. */
- void *p;
- int width, height, line_step;
- int orig_x, orig_y; /* origin, 1/16s pixel */
- int left_indent, top_indent;
- int black_width, black_height;
-} FAPI_raster;
-
-#ifndef FAPI_server_DEFINED
-#define FAPI_server_DEFINED
-typedef struct FAPI_server_s FAPI_server;
-#endif
-
-typedef enum FAPI_descendant_code_s { /* Possible values are descendant font indices and 4 ones defined below. */
- FAPI_DESCENDANT_PREPARED = -1, /* See FAPI_prepare_font in zfapi.c . */
- FAPI_TOPLEVEL_PREPARED = -2,
- FAPI_TOPLEVEL_BEGIN = -3,
- FAPI_TOPLEVEL_COMPLETE = -4
-} FAPI_descendant_code;
-
-struct FAPI_server_s {
- i_plugin_instance ig;
- int frac_shift; /* The number of fractional bits in coordinates. */
- FAPI_face face;
- FAPI_font ff;
- int max_bitmap;
- bool use_outline;
- gs_matrix initial_FontMatrix; /* Font Matrix at the time the font is defined */
- /* Used to use the stored 'OrigFont' entry but */
- /* this did not change f a font was defined */
- /* using an existing base font */
- FAPI_retcode (*ensure_open)(FAPI_server *server, const byte * param, int param_size);
- FAPI_retcode (*get_scaled_font)(FAPI_server *server, FAPI_font *ff, const FAPI_font_scale *scale, const char *xlatmap, FAPI_descendant_code dc);
- FAPI_retcode (*get_decodingID)(FAPI_server *server, FAPI_font *ff, const char **decodingID);
- FAPI_retcode (*get_font_bbox)(FAPI_server *server, FAPI_font *ff, int BBox[4]);
- FAPI_retcode (*get_font_proportional_feature)(FAPI_server *server, FAPI_font *ff, bool *bProportional);
- FAPI_retcode (*can_retrieve_char_by_name)(FAPI_server *server, FAPI_font *ff, FAPI_char_ref *c, int *result);
- FAPI_retcode (*can_replace_metrics)(FAPI_server *server, FAPI_font *ff, FAPI_char_ref *c, int *result);
- FAPI_retcode (*get_fontmatrix)(FAPI_server *server, gs_matrix *m);
- FAPI_retcode (*get_char_width)(FAPI_server *server, FAPI_font *ff, FAPI_char_ref *c, FAPI_metrics *metrics);
- FAPI_retcode (*get_char_raster_metrics)(FAPI_server *server, FAPI_font *ff, FAPI_char_ref *c, FAPI_metrics *metrics);
- FAPI_retcode (*get_char_raster)(FAPI_server *server, FAPI_raster *r);
- FAPI_retcode (*get_char_outline_metrics)(FAPI_server *server, FAPI_font *ff, FAPI_char_ref *c, FAPI_metrics *metrics);
- FAPI_retcode (*get_char_outline)(FAPI_server *server, FAPI_path *p);
- FAPI_retcode (*release_char_data)(FAPI_server *server);
- FAPI_retcode (*release_typeface)(FAPI_server *server, void *server_font_data);
- FAPI_retcode (*check_cmap_for_GID)(FAPI_server *server, uint *index);
- /* Some people get confused with terms "font cache" and "character cache".
- "font cache" means a cache for scaled font objects, which mainly
- keep the font header information and rules for adjusting it to specific raster.
- "character cahce" is a cache for specific character outlines and/or character rasters.
- */
- /* get_scaled_font opens a typeface with a server and scales it according to CTM and HWResolution.
- This creates a server's scaled font object.
- Since UFST doesn't provide a handle to this object,
- we need to build the data for it and call this function whenever scaled font data may change.
- The server must cache scaled fonts internally.
- Note that FreeType doesn't provide internal font cache,
- so the bridge must do.
- */
- /* GS cannot provide information when a scaled font to be closed.
- Therefore we don't provide close_scaled_font function in this interface.
- The server must cache scaled fonts, and close ones which were
- not in use during a long time.
- */
- /* Due to the interpreter fallback with CDevProc,
- get_char_raster_metrics leaves some data kept by the server,
- so taht get_char_raster uses them and release_char_data releases them.
- Therefore calls from GS to these functions must not
- interfer with different characters.
- */
-};
+#include "gxfapi.h"
#endif /* ifapi_INCLUDED */
diff --git a/gs/psi/int.mak b/gs/psi/int.mak
index 12092844a..92f296e32 100644
--- a/gs/psi/int.mak
+++ b/gs/psi/int.mak
@@ -565,7 +565,8 @@ INT_ALL=$(INT_OBJS) $(INT_CONFIG)
# though we don't strictly need it unless we have the pdfwrite device.
$(PSD)psbase.dev : $(INT_MAK) $(ECHOGS_XE) $(INT_OBJS)\
$(PSD)isupport.dev $(PSD)nobtoken.dev $(PSD)nousparm.dev\
- $(GLD)rld.dev $(GLD)rle.dev $(GLD)sfile.dev $(PSD)dscparse.dev
+ $(GLD)rld.dev $(GLD)rle.dev $(GLD)sfile.dev $(PSD)dscparse.dev \
+ $(PSD)fapi_ps.dev
$(SETMOD) $(PSD)psbase $(INT_MAIN)
$(ADDMOD) $(PSD)psbase -obj $(INT_CONFIG)
$(ADDMOD) $(PSD)psbase -obj $(INT1)
@@ -612,6 +613,7 @@ $(PSD)psl1.dev : $(INT_MAK) $(ECHOGS_XE)\
$(PSD)psbase.dev $(PSD)bcp.dev $(PSD)path1.dev $(PSD)type1.dev
$(SETMOD) $(PSD)psl1 -include $(PSD)psbase $(PSD)bcp $(PSD)path1 $(PSD)type1
$(ADDMOD) $(PSD)psl1 -emulator PostScript PostScriptLevel1
+ $(ADDMOD) $(PSD)psbase -include $(GLD)fapi_ps
# -------- Level 1 color extensions (CMYK color and colorimage) -------- #
@@ -1769,33 +1771,11 @@ $(PSD)pdfread.dev : $(INT_MAK) $(ECHOGS_XE) \
$(PSD)cslayer.dev : $(INT_MAK) $(ECHOGS_XE) $(PSD)pdfread.dev
$(SETMOD) $(PSD)cslayer -ps pdf_cslayer
-# ---------------- Font API ---------------- #
-
-$(PSD)fapi.dev : $(INT_MAK) $(ECHOGS_XE) $(PSOBJ)zfapi.$(OBJ)\
- $(PSD)fapiu$(UFST_BRIDGE).dev $(PSD)fapif$(FT_BRIDGE).dev \
- $(PSD)fapib$(BITSTREAM_BRIDGE).dev
- $(SETMOD) $(PSD)fapi $(PSOBJ)zfapi.$(OBJ)
- $(ADDMOD) $(PSD)fapi -oper zfapi
- $(ADDMOD) $(PSD)fapi -ps gs_fntem gs_fapi
- $(ADDMOD) $(PSD)fapi -include $(PSD)fapiu$(UFST_BRIDGE)
- $(ADDMOD) $(PSD)fapi -include $(PSD)fapif$(FT_BRIDGE)
- $(ADDMOD) $(PSD)fapi -include $(PSD)fapib$(BITSTREAM_BRIDGE)
-
-wrfont_h=$(stdpre_h) $(PSSRC)wrfont.h
-write_t1_h=$(ifapi_h) $(PSSRC)write_t1.h
-write_t2_h=$(ifapi_h) $(PSSRC)write_t2.h
-
-$(PSOBJ)write_t1.$(OBJ) : $(PSSRC)write_t1.c $(AK)\
- $(wrfont_h) $(write_t1_h)
- $(PSCC) $(FT_CFLAGS) $(PSO_)write_t1.$(OBJ) $(C_) $(PSSRC)write_t1.c
-
-$(PSOBJ)write_t2.$(OBJ) : $(PSSRC)write_t2.c $(AK)\
- $(wrfont_h) $(write_t2_h) $(ghost_h) $(gxfont_h) $(gxfont1_h)
- $(PSCC) $(FT_CFLAGS) $(PSO_)write_t2.$(OBJ) $(C_) $(PSSRC)write_t2.c
-
-$(PSOBJ)wrfont.$(OBJ) : $(PSSRC)wrfont.c $(AK)\
- $(wrfont_h) $(stdio__h)
- $(PSCC) $(FT_CFLAGS) $(PSO_)wrfont.$(OBJ) $(C_) $(PSSRC)wrfont.c
+# ---------------- PS Support for Font API ---------------- #
+$(PSD)fapi_ps.dev : $(LIB_MAK) $(ECHOGS_XE) $(PSOBJ)zfapi.$(OBJ)
+ $(SETMOD) $(PSD)fapi_ps $(PSOBJ)zfapi.$(OBJ)
+ $(ADDMOD) $(PSD)fapi_ps -oper zfapi
+ $(ADDMOD) $(PSD)fapi_ps -ps gs_fntem gs_fapi
$(PSOBJ)zfapi.$(OBJ) : $(PSSRC)zfapi.c $(OP) $(math__h) $(memory__h) $(string__h)\
$(stat__h)\
@@ -1808,156 +1788,6 @@ $(PSOBJ)zfapi.$(OBJ) : $(PSSRC)zfapi.c $(OP) $(math__h) $(memory__h) $(string__h
$(oper_h) $(store_h) $(stream_h)
$(PSCC) $(PSO_)zfapi.$(OBJ) $(C_) $(PSSRC)zfapi.c
-# Bitstream bridge :
-
-BITSTREAM_LIB=$(BITSTREAM_ROOT)$(D)core$(D)
-BITSTREAM_INC=$(I_)"$(BITSTREAM_ROOT)$(D)core"
-
-$(PSD)fapib1.dev : $(INT_MAK) $(ECHOGS_XE) \
- $(PSOBJ)fapibstm.$(OBJ) $(PSOBJ)t2k.$(OBJ) $(PSOBJ)t2kextra.$(OBJ) $(PSOBJ)tsimem.$(OBJ)\
- $(PSOBJ)t2ktt.$(OBJ) $(PSOBJ)cstream.$(OBJ) $(PSOBJ)fft1hint.$(OBJ) $(PSOBJ)ghints.$(OBJ)\
- $(PSOBJ)glyph.$(OBJ) $(PSOBJ)t1.$(OBJ) $(PSOBJ)t2kstrm.$(OBJ) $(PSOBJ)truetype.$(OBJ)\
- $(PSOBJ)util.$(OBJ) $(PSOBJ)fnt.$(OBJ) $(PSOBJ)pclread.$(OBJ) $(PSOBJ)t2ksc.$(OBJ)\
- $(PSOBJ)write_t1.$(OBJ) $(PSOBJ)write_t2.$(OBJ) $(PSOBJ)wrfont.$(OBJ)
- $(SETMOD) $(PSD)fapib1 $(PSOBJ)fapibstm.$(OBJ)
- $(ADDMOD) $(PSD)fapib1 $(PSOBJ)t2k.$(OBJ) $(PSOBJ)t2kextra.$(OBJ) $(PSOBJ)fnt.$(OBJ)
- $(ADDMOD) $(PSD)fapib1 $(PSOBJ)tsimem.$(OBJ) $(PSOBJ)t2ktt.$(OBJ) $(PSOBJ)util.$(OBJ)
- $(ADDMOD) $(PSD)fapib1 $(PSOBJ)t2kstrm.$(OBJ) $(PSOBJ)truetype.$(OBJ) $(PSOBJ)cstream.$(OBJ)
- $(ADDMOD) $(PSD)fapib1 $(PSOBJ)fft1hint.$(OBJ) $(PSOBJ)ghints.$(OBJ) $(PSOBJ)glyph.$(OBJ)
- $(ADDMOD) $(PSD)fapib1 $(PSOBJ)t1.$(OBJ) $(PSOBJ)pclread.$(OBJ) $(PSOBJ)t2ksc.$(OBJ)
- $(ADDMOD) $(PSD)fapib1 $(PSOBJ)write_t1.$(OBJ) $(PSOBJ)write_t2.$(OBJ) $(PSOBJ)wrfont.$(OBJ)
- $(ADDMOD) $(PSD)fapib1 -plugin fapibstm
-
-$(PSOBJ)fapibstm.$(OBJ) : $(PSSRC)fapibstm.c $(AK)\
- $(memory__h) $(stdio__h) $(math__h) $(strmio_h)\
- $(ierrors_h) $(iplugin_h) $(ifapi_h) $(gxfapi_h) $(gp_h)
- $(PSCC) $(BITSTREAM_CFLAGS) $(BITSTREAM_INC) $(PSO_)fapibstm.$(OBJ) $(C_) $(PSSRC)fapibstm.c
-
-$(PSOBJ)t2k.$(OBJ) : "$(BITSTREAM_LIB)t2k.c" $(AK)
- $(PSCC) $(BITSTREAM_CFLAGS) $(BITSTREAM_INC) $(PSO_)t2k.$(OBJ) $(C_) "$(BITSTREAM_LIB)t2k.c"
-
-$(PSOBJ)t2kextra.$(OBJ) : "$(BITSTREAM_LIB)t2kextra.c" $(AK)
- $(PSCC) $(BITSTREAM_CFLAGS) $(BITSTREAM_INC) $(PSO_)t2kextra.$(OBJ) $(C_) "$(BITSTREAM_LIB)t2kextra.c"
-
-$(PSOBJ)tsimem.$(OBJ) : "$(BITSTREAM_LIB)tsimem.c" $(AK)
- $(PSCC) $(BITSTREAM_CFLAGS) $(BITSTREAM_INC) $(PSO_)tsimem.$(OBJ) $(C_) "$(BITSTREAM_LIB)tsimem.c"
-
-$(PSOBJ)t2ktt.$(OBJ) : "$(BITSTREAM_LIB)t2ktt.c" $(AK)
- $(PSCC) $(BITSTREAM_CFLAGS) $(BITSTREAM_INC) $(PSO_)t2ktt.$(OBJ) $(C_) "$(BITSTREAM_LIB)t2ktt.c"
-
-$(PSOBJ)cstream.$(OBJ) : "$(BITSTREAM_LIB)cstream.c" $(AK)
- $(PSCC) $(BITSTREAM_CFLAGS) $(BITSTREAM_INC) $(PSO_)cstream.$(OBJ) $(C_) "$(BITSTREAM_LIB)cstream.c"
-
-$(PSOBJ)fft1hint.$(OBJ) : "$(BITSTREAM_LIB)fft1hint.c" $(AK)
- $(PSCC) $(BITSTREAM_CFLAGS) $(BITSTREAM_INC) $(PSO_)fft1hint.$(OBJ) $(C_) "$(BITSTREAM_LIB)fft1hint.c"
-
-$(PSOBJ)ghints.$(OBJ) : "$(BITSTREAM_LIB)ghints.c" $(AK)
- $(PSCC) $(BITSTREAM_CFLAGS) $(BITSTREAM_INC) $(PSO_)ghints.$(OBJ) $(C_) "$(BITSTREAM_LIB)ghints.c"
-
-$(PSOBJ)glyph.$(OBJ) : "$(BITSTREAM_LIB)glyph.c" $(AK)
- $(PSCC) $(BITSTREAM_CFLAGS) $(BITSTREAM_INC) $(PSO_)glyph.$(OBJ) $(C_) "$(BITSTREAM_LIB)glyph.c"
-
-$(PSOBJ)t1.$(OBJ) : "$(BITSTREAM_LIB)t1.c" $(AK)
- $(PSCC) $(BITSTREAM_CFLAGS) $(BITSTREAM_INC) $(PSO_)t1.$(OBJ) $(C_) "$(BITSTREAM_LIB)t1.c"
-
-$(PSOBJ)t2kstrm.$(OBJ) : "$(BITSTREAM_LIB)t2kstrm.c" $(AK)
- $(PSCC) $(BITSTREAM_CFLAGS) $(BITSTREAM_INC) $(PSO_)t2kstrm.$(OBJ) $(C_) "$(BITSTREAM_LIB)t2kstrm.c"
-
-$(PSOBJ)truetype.$(OBJ) : "$(BITSTREAM_LIB)truetype.c" $(AK)
- $(PSCC) $(BITSTREAM_CFLAGS) $(BITSTREAM_INC) $(PSO_)truetype.$(OBJ) $(C_) "$(BITSTREAM_LIB)truetype.c"
-
-$(PSOBJ)util.$(OBJ) : "$(BITSTREAM_LIB)util.c" $(AK)
- $(PSCC) $(BITSTREAM_CFLAGS) $(BITSTREAM_INC) $(PSO_)util.$(OBJ) $(C_) "$(BITSTREAM_LIB)util.c"
-
-$(PSOBJ)fnt.$(OBJ) : "$(BITSTREAM_LIB)fnt.c" $(AK)
- $(PSCC) $(BITSTREAM_CFLAGS) $(BITSTREAM_INC) $(PSO_)fnt.$(OBJ) $(C_) "$(BITSTREAM_LIB)fnt.c"
-
-$(PSOBJ)pclread.$(OBJ) : "$(BITSTREAM_LIB)pclread.c" $(AK)
- $(PSCC) $(BITSTREAM_CFLAGS) $(BITSTREAM_INC) $(PSO_)pclread.$(OBJ) $(C_) "$(BITSTREAM_LIB)pclread.c"
-
-$(PSOBJ)t2ksc.$(OBJ) : "$(BITSTREAM_LIB)t2ksc.c" $(AK)
- $(PSCC) $(BITSTREAM_CFLAGS) $(BITSTREAM_INC) $(PSO_)t2ksc.$(OBJ) $(C_) "$(BITSTREAM_LIB)t2ksc.c"
-
-# stub for Bitstream bridge :
-
-$(PSD)fapib.dev : $(INT_MAK) $(ECHOGS_XE)
- $(SETMOD) $(PSD)fapib
-
-
-# UFST bridge :
-
-UFST_LIB=$(UFST_ROOT)$(D)rts$(D)lib$(D)
-UFST_INC0=$(I_)$(UFST_ROOT)$(D)sys$(D)inc$(_I) $(I_)$(UFST_ROOT)$(D)rts$(D)inc$(_I)
-UFST_INC1=$(UFST_INC0) $(I_)$(UFST_ROOT)$(D)rts$(D)psi$(_I)
-UFST_INC2=$(UFST_INC1) $(I_)$(UFST_ROOT)$(D)rts$(D)fco$(_I)
-UFST_INC3=$(UFST_INC2) $(I_)$(UFST_ROOT)$(D)rts$(D)gray$(_I)
-UFST_INC=$(UFST_INC3) $(I_)$(UFST_ROOT)$(D)rts$(D)tt$(_I)
-
-$(PSD)fapiu1.dev : $(INT_MAK) $(ECHOGS_XE) \
- $(UFST_LIB)fco_lib$(UFST_LIB_EXT) $(UFST_LIB)if_lib$(UFST_LIB_EXT) \
- $(UFST_LIB)psi_lib$(UFST_LIB_EXT) $(UFST_LIB)tt_lib$(UFST_LIB_EXT) \
- $(PSOBJ)fapiufst.$(OBJ)
- $(SETMOD) $(PSD)fapiu1 $(PSOBJ)fapiufst.$(OBJ)
- $(ADDMOD) $(PSD)fapiu1 -plugin fapiufst
- $(ADDMOD) $(PSD)fapiu1 -link $(UFST_LIB)if_lib$(UFST_LIB_EXT) $(UFST_LIB)fco_lib$(UFST_LIB_EXT)
- $(ADDMOD) $(PSD)fapiu1 -link $(UFST_LIB)tt_lib$(UFST_LIB_EXT) $(UFST_LIB)psi_lib$(UFST_LIB_EXT)
-
-fapiufst_1 : $(PSSRC)fapiufst.c $(AK)\
- $(memory__h) $(stdio__h) $(math__h) $(strmio_h)\
- $(ierrors_h) $(iplugin_h) $(ifapi_h) $(gxfapi_h) $(gp_h) $(gxfapiu_h) \
- $(UFST_ROOT)$(D)rts$(D)inc$(D)cgconfig.h\
- $(UFST_ROOT)$(D)rts$(D)inc$(D)shareinc.h\
- $(UFST_ROOT)$(D)sys$(D)inc$(D)ufstport.h\
- $(UFST_ROOT)$(D)sys$(D)inc$(D)cgmacros.h\
- $(UFST_ROOT)$(D)rts$(D)psi$(D)t1isfnt.h\
- $(UFST_ROOT)$(D)rts$(D)tt$(D)sfntenum.h\
- $(UFST_ROOT)$(D)rts$(D)tt$(D)ttpcleo.h
- $(PSCC) $(UFST_CFLAGS) -DUFSTFONTDIR=$(UFSTROMFONTDIR) $(UFST_INC) $(PSO_)fapiufst.$(OBJ) $(C_) $(PSSRC)fapiufst.c
-
-fapiufst_0 : $(PSSRC)fapiufst.c $(AK)\
- $(memory__h) $(stdio__h) $(math__h) $(strmio_h)\
- $(ierrors_h) $(iplugin_h) $(ifapi_h) $(gxfapi_h) $(gp_h) $(gxfapiu_h) \
- $(UFST_ROOT)$(D)rts$(D)inc$(D)cgconfig.h\
- $(UFST_ROOT)$(D)rts$(D)inc$(D)shareinc.h\
- $(UFST_ROOT)$(D)sys$(D)inc$(D)ufstport.h\
- $(UFST_ROOT)$(D)sys$(D)inc$(D)cgmacros.h\
- $(UFST_ROOT)$(D)rts$(D)psi$(D)t1isfnt.h\
- $(UFST_ROOT)$(D)rts$(D)tt$(D)sfntenum.h\
- $(UFST_ROOT)$(D)rts$(D)tt$(D)ttpcleo.h
- $(PSCC) $(UFST_CFLAGS) -DUFSTFONTDIR=$(UFSTDISCFONTDIR) $(UFST_INC) $(PSO_)fapiufst.$(OBJ) $(C_) $(PSSRC)fapiufst.c
-
-
-$(PSOBJ)fapiufst.$(OBJ) : fapiufst_$(COMPILE_INITS)
-
-# stub for UFST bridge :
-
-$(PSD)fapiu.dev : $(INT_MAK) $(ECHOGS_XE)
- $(SETMOD) $(PSD)fapiu
-
-# FreeType bridge :
-
-# the top-level makefile should define
-# FT_CFLAGS for the include directive and other switches
-
-$(PSD)fapif1.dev : $(INT_MAK) $(ECHOGS_XE) $(PSOBJ)fapi_ft.$(OBJ) \
- $(PSOBJ)write_t1.$(OBJ) $(PSOBJ)write_t2.$(OBJ) $(PSOBJ)wrfont.$(OBJ) \
- $(GLD)freetype.dev
- $(SETMOD) $(PSD)fapif1 $(PSOBJ)fapi_ft.$(OBJ) $(PSOBJ)write_t1.$(OBJ)
- $(ADDMOD) $(PSD)fapif1 $(PSOBJ)write_t2.$(OBJ) $(PSOBJ)wrfont.$(OBJ)
- $(ADDMOD) $(PSD)fapif1 -plugin fapi_ft
- $(ADDMOD) $(PSD)fapif1 -include $(GLD)freetype
-
-$(PSOBJ)fapi_ft.$(OBJ) : $(PSSRC)fapi_ft.c $(AK)\
- $(stdio__h) $(math__h) $(ifapi_h) $(gserrors_h)\
- $(write_t1_h) $(write_t2_h)
- $(PSCC) $(FT_CFLAGS) $(PSO_)fapi_ft.$(OBJ) $(C_) $(PSSRC)fapi_ft.c
-
-# stub for FreeType bridge :
-
-$(PSD)fapif0.dev : $(INT_MAK) $(ECHOGS_XE)
- $(SETMOD) $(PSD)fapif0
-
-
# ---------------- Custom color dummy callback ---------------- #
$(PSOBJ)zncdummy.$(OBJ) : $(PSSRC)zncdummy.c $(OP) $(GX) $(math_h)\
diff --git a/gs/psi/msvc.mak b/gs/psi/msvc.mak
index 8d676476c..53e1417ca 100644
--- a/gs/psi/msvc.mak
+++ b/gs/psi/msvc.mak
@@ -911,7 +911,7 @@ JPX_CFLAGS = $JPX_CFLAGS -DUSE_OPENJPEG_JP2
# Choose the language feature(s) to include. See gs.mak for details.
!ifndef FEATURE_DEVS
-FEATURE_DEVS=$(PSD)psl3.dev $(PSD)pdf.dev $(PSD)dpsnext.dev $(PSD)ttfont.dev $(PSD)rasterop.dev $(PSD)epsf.dev $(PSD)mshandle.dev $(PSD)mspoll.dev $(PSD)fapi.dev $(PSD)jbig2.dev $(PSD)jpx.dev $(PSD)winutf8.dev
+FEATURE_DEVS=$(PSD)psl3.dev $(PSD)pdf.dev $(PSD)dpsnext.dev $(PSD)ttfont.dev $(PSD)rasterop.dev $(PSD)epsf.dev $(PSD)mshandle.dev $(PSD)mspoll.dev $(PSD)fapi_ps.dev $(PSD)jbig2.dev $(PSD)jpx.dev $(PSD)winutf8.dev
!ifndef METRO
FEATURE_DEVS=$(FEATURE_DEVS) $(PSD)msprinter.dev $(GLD)pipe.dev
!endif
diff --git a/gs/psi/wrfont.c b/gs/psi/wrfont.c
deleted file mode 100644
index af7f66a46..000000000
--- a/gs/psi/wrfont.c
+++ /dev/null
@@ -1,80 +0,0 @@
-/* Copyright (C) 2001-2012 Artifex Software, Inc.
- All Rights Reserved.
-
- This software is provided AS-IS with no warranty, either express or
- implied.
-
- This software is distributed under license and may not be copied,
- modified or distributed except as expressly authorized under the terms
- of the license contained in the file LICENSE in this distribution.
-
- Refer to licensing information at http://www.artifex.com or contact
- Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael,
- CA 94903, U.S.A., +1(415)492-9861, for further information.
-*/
-
-
-/*
-Support functions to serialize fonts as PostScript code that can
-then be passed to FreeType via the FAPI FreeType bridge.
-Started by Graham Asher, 9th August 2002.
-*/
-
-#include "wrfont.h"
-#include "stdio_.h"
-
-#define EEXEC_KEY 55665
-#define EEXEC_FACTOR 52845
-#define EEXEC_OFFSET 22719
-
-void WRF_init(WRF_output* a_output,unsigned char* a_buffer,long a_buffer_size)
- {
- a_output->m_pos = a_buffer;
- a_output->m_limit = a_buffer_size;
- a_output->m_count = 0;
- a_output->m_encrypt = false;
- a_output->m_key = EEXEC_KEY;
- }
-
-void WRF_wbyte(WRF_output* a_output,unsigned char a_byte)
- {
- if (a_output->m_count < a_output->m_limit)
- {
- if (a_output->m_encrypt)
- {
- a_byte ^= (a_output->m_key >> 8);
- a_output->m_key = (unsigned short)((a_output->m_key + a_byte) * EEXEC_FACTOR + EEXEC_OFFSET);
- }
- *a_output->m_pos++ = a_byte;
- }
- a_output->m_count++;
- }
-
-void WRF_wtext(WRF_output* a_output,const unsigned char* a_string,long a_length)
- {
- while (a_length > 0)
- {
- WRF_wbyte(a_output,*a_string++);
- a_length--;
- }
- }
-
-void WRF_wstring(WRF_output* a_output,const char* a_string)
- {
- while (*a_string)
- WRF_wbyte(a_output,*a_string++);
- }
-
-void WRF_wfloat(WRF_output* a_output,double a_float)
- {
- char buffer[32];
- sprintf(buffer,"%f",a_float);
- WRF_wstring(a_output,buffer);
- }
-
-void WRF_wint(WRF_output* a_output,long a_int)
- {
- char buffer[32];
- sprintf(buffer,"%ld",a_int);
- WRF_wstring(a_output,buffer);
- }
diff --git a/gs/psi/write_t1.c b/gs/psi/write_t1.c
deleted file mode 100644
index efe3c2ec0..000000000
--- a/gs/psi/write_t1.c
+++ /dev/null
@@ -1,372 +0,0 @@
-/* Copyright (C) 2001-2012 Artifex Software, Inc.
- All Rights Reserved.
-
- This software is provided AS-IS with no warranty, either express or
- implied.
-
- This software is distributed under license and may not be copied,
- modified or distributed except as expressly authorized under the terms
- of the license contained in the file LICENSE in this distribution.
-
- Refer to licensing information at http://www.artifex.com or contact
- Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael,
- CA 94903, U.S.A., +1(415)492-9861, for further information.
-*/
-
-
-
-/*
-Functions to serialize a type 1 font as PostScript code that can then be
-passed to FreeType via the FAPI FreeType bridge.
-Started by Graham Asher, 26th July 2002.
-*/
-
-#include <stdio.h>
-#include "wrfont.h"
-#include "write_t1.h"
-
-/*
-Public structures and functions in this file are prefixed with FF_ because they are part of
-the FAPI FreeType implementation.
-*/
-
-static void write_word_entry(FAPI_font* a_fapi_font,WRF_output* a_output,const char* a_name,int a_index,int a_divisor)
- {
- short x;
- WRF_wbyte(a_output,'/');
- WRF_wstring(a_output,a_name);
- WRF_wbyte(a_output,' ');
- /* Get the value and convert it from unsigned to signed by assigning it to a short. */
- x = a_fapi_font->get_word(a_fapi_font,a_index,0);
- /* Divide by the divisor to bring it back to font units. */
- x = (short)(x / a_divisor);
- WRF_wint(a_output,x);
- WRF_wstring(a_output," def\n");
- }
-
-static void write_array_entry_with_count(FAPI_font* a_fapi_font,WRF_output* a_output,const char* a_name,int a_index,int a_count,int a_divisor)
- {
- int i;
-
- if (a_count <= 0)
- return;
-
- WRF_wbyte(a_output,'/');
- WRF_wstring(a_output,a_name);
- WRF_wstring(a_output," [");
- for (i = 0; i < a_count; i++)
- {
- /* Get the value and convert it from unsigned to signed by assigning it to a short. */
- short x = a_fapi_font->get_word(a_fapi_font,a_index,i);
- /* Divide by the divisor to bring it back to font units. */
- x = (short)(x / a_divisor);
- WRF_wint(a_output,x);
- WRF_wbyte(a_output,(byte)(i == a_count - 1 ? ']' : ' '));
- }
- WRF_wstring(a_output," def\n");
- }
-
-static void write_array_entry(FAPI_font* a_fapi_font,WRF_output* a_output,const char* a_name,int a_index,int a_divisor)
- {
- /* NOTE that the feature index must be preceded by the count index for this to work. */
- int count = a_fapi_font->get_word(a_fapi_font,a_index - 1,0);
- write_array_entry_with_count(a_fapi_font,a_output,a_name,a_index,count,a_divisor);
- }
-
-static void write_subrs(FAPI_font* a_fapi_font,WRF_output* a_output, int raw)
- {
- int i;
- int count = a_fapi_font->get_word(a_fapi_font,FAPI_FONT_FEATURE_Subrs_count,0);
- if (count <= 0)
- return;
-
- WRF_wstring(a_output,"/Subrs ");
- WRF_wint(a_output,count);
- WRF_wstring(a_output," array\n");
-
- for (i = 0; i < count; i++)
- {
- long length;
- long buffer_size;
- if (raw)
- length = a_fapi_font->get_raw_subr(a_fapi_font,i,0,0);
- else
- length = a_fapi_font->get_subr(a_fapi_font,i,0,0);
- WRF_wstring(a_output,"dup ");
- WRF_wint(a_output,i);
- WRF_wbyte(a_output,' ');
- WRF_wint(a_output,length);
- WRF_wstring(a_output," RD ");
-
- /* Get the subroutine into the buffer and encrypt it in place. */
- buffer_size = a_output->m_limit - a_output->m_count;
- if (buffer_size >= length)
- {
- if (raw)
- a_fapi_font->get_raw_subr(a_fapi_font,i,a_output->m_pos,(ushort)length);
- else
- a_fapi_font->get_subr(a_fapi_font,i,a_output->m_pos,(ushort)length);
- WRF_wtext(a_output,a_output->m_pos,length);
- }
- else
- a_output->m_count += length;
-
- WRF_wstring(a_output," NP\n");
- }
-
- WRF_wstring(a_output,"ND\n");
- }
-
-static void write_charstrings(FAPI_font *a_fapi_font, WRF_output *a_output)
-{
- long length;
- long buffer_size;
- int i, count = a_fapi_font->get_word(a_fapi_font,FAPI_FONT_FEATURE_CharStrings_count,0);
- char NameBuf[256];
- if (count <= 0)
- return;
-
- WRF_wstring(a_output, "2 index /CharStrings ");
- WRF_wint(a_output,count);
- WRF_wstring(a_output, " dict dup begin\n");
- for (i=0;i< count;i++)
- {
- length = a_fapi_font->get_charstring_name(a_fapi_font,i,(byte *)&NameBuf,256);
- if (length > 0)
- {
- length = a_fapi_font->get_charstring(a_fapi_font,i,0,0);
-
- WRF_wbyte(a_output,'/');
- WRF_wstring(a_output, (const char*)&NameBuf);
- WRF_wbyte(a_output,' ');
- WRF_wint(a_output,length);
- WRF_wstring(a_output," RD ");
-
- /* Get the CharString into the buffer and encrypt it in place. */
- buffer_size = a_output->m_limit - a_output->m_count;
- if (buffer_size >= length)
- {
- a_fapi_font->get_charstring(a_fapi_font,i,a_output->m_pos,(ushort)length);
- WRF_wtext(a_output,a_output->m_pos,length);
- }
- else
- a_output->m_count += length;
- WRF_wstring(a_output," ND\n");
- }
- }
- WRF_wstring(a_output, " end");
-}
-
-static int is_MM_font(FAPI_font *a_fapi_font)
-{
- return a_fapi_font->get_word(a_fapi_font,FAPI_FONT_FEATURE_DollarBlend,0);
-}
-
-static void write_private_dictionary(FAPI_font* a_fapi_font,WRF_output* a_output, int Write_CharStrings)
- {
- a_output->m_encrypt = true;
-
- /* Write 4 bytes that must encrypt to at least one character that cannot be a valid hexadecimal character. */
- WRF_wstring(a_output,"XXXX");
-
- /*+ to do: correct size of dictionary from 8. */
- WRF_wstring(a_output,"dup /Private 8 dict dup begin\n");
-
- WRF_wstring(a_output,"/MinFeature {16 16} def\n");
- WRF_wstring(a_output,"/password 5839 def\n");
- if (Write_CharStrings)
- write_word_entry(a_fapi_font,a_output,"lenIV",FAPI_FONT_FEATURE_lenIV,1);
- else
- WRF_wstring(a_output,"/lenIV -1 def\n"); /* indicate that /subrs are not encoded. */
- write_word_entry(a_fapi_font,a_output,"BlueFuzz",FAPI_FONT_FEATURE_BlueFuzz,16);
-
- WRF_wstring(a_output,"/BlueScale ");
- WRF_wfloat(a_output,a_fapi_font->get_long(a_fapi_font,FAPI_FONT_FEATURE_BlueScale,0) / 65536.0);
- WRF_wstring(a_output," def\n");
-
- write_word_entry(a_fapi_font,a_output,"BlueShift",FAPI_FONT_FEATURE_BlueShift,16);
- write_array_entry(a_fapi_font,a_output,"BlueValues",FAPI_FONT_FEATURE_BlueValues,16);
- write_array_entry(a_fapi_font,a_output,"OtherBlues",FAPI_FONT_FEATURE_OtherBlues,16);
- write_array_entry(a_fapi_font,a_output,"FamilyBlues",FAPI_FONT_FEATURE_FamilyBlues,16);
- write_array_entry(a_fapi_font,a_output,"FamilyOtherBlues",FAPI_FONT_FEATURE_FamilyOtherBlues,16);
- write_word_entry(a_fapi_font,a_output,"ForceBold",FAPI_FONT_FEATURE_ForceBold,1);
- write_array_entry_with_count(a_fapi_font,a_output,"StdHW",FAPI_FONT_FEATURE_StdHW,1,16);
- write_array_entry_with_count(a_fapi_font,a_output,"StdVW",FAPI_FONT_FEATURE_StdVW,1,16);
- write_array_entry(a_fapi_font,a_output,"StemSnapH",FAPI_FONT_FEATURE_StemSnapH,16);
- write_array_entry(a_fapi_font,a_output,"StemSnapV",FAPI_FONT_FEATURE_StemSnapV,16);
-
- if (is_MM_font(a_fapi_font)) {
- WRF_wstring(a_output,"3 index /Blend get /Private get begin\n");
- WRF_wstring(a_output,"|-\n");
- }
- if (Write_CharStrings)
- write_subrs(a_fapi_font,a_output, 1);
- else
- write_subrs(a_fapi_font,a_output, 0);
- if (Write_CharStrings)
- write_charstrings(a_fapi_font,a_output);
- }
-
-static void write_blend_dictionary(FAPI_font* a_fapi_font,WRF_output* a_output)
-{
-}
-
-static void write_main_dictionary(FAPI_font* a_fapi_font,WRF_output* a_output, int Write_CharStrings)
- {
- int i;
- WRF_wstring(a_output,"5 dict begin\n");
-
- WRF_wstring(a_output,"/FontType 1 def\n");
-
- WRF_wstring(a_output,"/FontMatrix [");
- for (i = 0; i < 6; i++)
- {
- WRF_wfloat(a_output,a_fapi_font->get_float(a_fapi_font,FAPI_FONT_FEATURE_FontMatrix,i));
- WRF_wbyte(a_output,(byte)(i == 5 ? ']' : ' '));
- }
- WRF_wbyte(a_output,'\n');
-
- /* For now, specify standard encoding - I think GS will pass glyph indices so doesn't matter. */
- WRF_wstring(a_output,"/Encoding StandardEncoding def\n");
-
- WRF_wstring(a_output,"/FontBBox {");
- for (i = 0; i < 4; i++)
- {
- short x = a_fapi_font->get_word(a_fapi_font,FAPI_FONT_FEATURE_FontBBox,i);
- WRF_wint(a_output,x);
- WRF_wbyte(a_output,(byte)(i == 3 ? '}' : ' '));
- }
- WRF_wbyte(a_output,'\n');
- if (is_MM_font(a_fapi_font)) {
- short x,x2;
- float x1;
- uint i, j, entries;
- char Buffer[255];
-
- entries = 0;
- x = a_fapi_font->get_word(a_fapi_font,FAPI_FONT_FEATURE_BlendAxisTypes_count,0);
- if (x)
- entries++;
- x = a_fapi_font->get_word(a_fapi_font,FAPI_FONT_FEATURE_BlendDesignPositionsArrays_count,0);
- if (x)
- entries++;
- x = a_fapi_font->get_word(a_fapi_font,FAPI_FONT_FEATURE_BlendDesignMapArrays_count,0);
- if (x)
- entries++;
-
- sprintf(Buffer, "/FontInfo %d dict dup begin\n", entries);
- WRF_wstring(a_output, Buffer);
- x = a_fapi_font->get_word(a_fapi_font,FAPI_FONT_FEATURE_BlendAxisTypes_count,0);
- if (x) {
- WRF_wstring(a_output, "/BlendAxisTypes [");
- for (i = 0;i < x;i++) {
- WRF_wstring(a_output," /");
- a_fapi_font->get_name(a_fapi_font,FAPI_FONT_FEATURE_BlendAxisTypes,i, (char *)&Buffer,255);
- WRF_wstring(a_output,Buffer);
- }
- WRF_wstring(a_output,"] def\n");
- }
- x = a_fapi_font->get_word(a_fapi_font,FAPI_FONT_FEATURE_BlendDesignPositionsArrays_count,0);
- if (x) {
- WRF_wstring(a_output, "/BlendDesignPositions [");
- x2 = a_fapi_font->get_word(a_fapi_font,FAPI_FONT_FEATURE_BlendAxisTypes_count,0);
- for (i = 0;i < x; i++) {
- WRF_wstring(a_output,"[");
- for (j = 0; j < x2; j++) {
- x1 = a_fapi_font->get_float(a_fapi_font,FAPI_FONT_FEATURE_BlendDesignPositionsArrayValue,i*8+j);
- sprintf(Buffer, "%f ", x1);
- WRF_wstring(a_output,Buffer);
- }
- WRF_wstring(a_output,"]");
- }
- WRF_wstring(a_output, "] def\n");
- }
- x = a_fapi_font->get_word(a_fapi_font,FAPI_FONT_FEATURE_BlendDesignMapArrays_count,0);
- if (x) {
- WRF_wstring(a_output, "/BlendDesignMap [");
- for (i = 0;i < x;i++) {
- x2 = a_fapi_font->get_word(a_fapi_font,FAPI_FONT_FEATURE_BlendDesignMapSubArrays_count,i);
- WRF_wstring(a_output,"[");
- for (j = 0; j < x2; j++) {
- WRF_wstring(a_output,"[");
- x1 = a_fapi_font->get_float(a_fapi_font,FAPI_FONT_FEATURE_BlendDesignPositionsArrayValue,i*64+j*64);
- sprintf(Buffer, "%f ", x1);
- WRF_wstring(a_output,Buffer);
- x1 = a_fapi_font->get_float(a_fapi_font,FAPI_FONT_FEATURE_BlendDesignPositionsArrayValue,i*64+j*64 + 1);
- sprintf(Buffer, "%f ", x1);
- WRF_wstring(a_output,Buffer);
- WRF_wstring(a_output,"]");
- }
- WRF_wstring(a_output,"]");
- }
- WRF_wstring(a_output, "] def\n");
- }
- WRF_wstring(a_output,"end readonly def\n");
-
- /* Previously we tried to write $Blend twice - the "real" one from the font,
- * and the boiler plate one below.
- * For now, I assume there was a good reason for including the second, but it may
- * be because the "get_proc" method below was missing the code to handle PS name
- * objects.
- */
- if ((x = a_fapi_font->get_word(a_fapi_font,FAPI_FONT_FEATURE_DollarBlend_length,0)) > 0) {
- WRF_wstring(a_output,"/$Blend {");
-
- if(a_output->m_count)
- a_output->m_count += x;
- x = a_fapi_font->get_proc(a_fapi_font,FAPI_FONT_FEATURE_DollarBlend,0,(char *)a_output->m_pos);
- if(a_output->m_pos)
- a_output->m_pos += x;
- WRF_wstring(a_output,"} def\n");
- }
- else {
- WRF_wstring(a_output,"/$Blend {0.1 mul exch 0.45 mul add exch 0.17 mul add add} def\n");
- }
- WRF_wstring(a_output,"/WeightVector [");
- x = a_fapi_font->get_word(a_fapi_font,FAPI_FONT_FEATURE_WeightVector_count,0);
- for (i = 0;i < x;i++) {
- x1 = a_fapi_font->get_float(a_fapi_font,FAPI_FONT_FEATURE_WeightVector,i);
- sprintf(Buffer, "%f ", x1);
- WRF_wstring(a_output,Buffer);
- }
- WRF_wstring(a_output,"] def\n");
- }
- WRF_wstring(a_output,"currentdict end\ncurrentfile eexec\n");
- write_private_dictionary(a_fapi_font,a_output, Write_CharStrings);
- if (is_MM_font(a_fapi_font)) {
- write_blend_dictionary(a_fapi_font, a_output);
- }
- }
-
-/**
-Write a Type 1 font in textual format and return its length in bytes.
-If a_buffer_size is less than the total length, only a_buffer_size bytes are written, but the total
-length is returned correctly.
-
-The PostScript is non-standard. The main dictionary contains no /Charstrings dictionary. This
-is supplied to FreeType using the incremental interface, There is also no /PaintType entry. This is required
-by PostScript but FreeType doesn't use it.
-*/
-long FF_serialize_type1_font(FAPI_font* a_fapi_font,unsigned char* a_buffer,long a_buffer_size)
- {
- WRF_output output;
- WRF_init(&output,a_buffer,a_buffer_size);
-
- /* Leading comment identifying a Type 1 font. */
- WRF_wstring(&output,"%!PS-AdobeFont-1\n");
-
- write_main_dictionary(a_fapi_font,&output, 0);
- return output.m_count;
- }
-
-long FF_serialize_type1_font_complete(FAPI_font* a_fapi_font,unsigned char* a_buffer,long a_buffer_size)
- {
- WRF_output output;
- WRF_init(&output,a_buffer,a_buffer_size);
-
- /* Leading comment identifying a Type 1 font. */
- WRF_wstring(&output,"%!PS-AdobeFont-1\n");
-
- write_main_dictionary(a_fapi_font,&output, 1);
- return output.m_count;
- }
diff --git a/gs/psi/write_t2.c b/gs/psi/write_t2.c
deleted file mode 100644
index 4e9c958f1..000000000
--- a/gs/psi/write_t2.c
+++ /dev/null
@@ -1,469 +0,0 @@
-/* Copyright (C) 2001-2012 Artifex Software, Inc.
- All Rights Reserved.
-
- This software is provided AS-IS with no warranty, either express or
- implied.
-
- This software is distributed under license and may not be copied,
- modified or distributed except as expressly authorized under the terms
- of the license contained in the file LICENSE in this distribution.
-
- Refer to licensing information at http://www.artifex.com or contact
- Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael,
- CA 94903, U.S.A., +1(415)492-9861, for further information.
-*/
-
-
-/* $Id: write_t2.c 10782 2010-02-22 11:45:33Z chrisl $ */
-
-/*
-Functions to serialize a type 1 font so that it can then be
-passed to FreeType via the FAPI FreeType bridge.
-Started by Graham Asher, 9th August 2002.
-*/
-
-#include "wrfont.h"
-#include "write_t2.h"
-#include "ghost.h"
-#include "gxfont.h"
-#include "gxfont1.h"
-
-/*
-Public structures and functions in this file are prefixed with FF_ because they are part of
-the FAPI FreeType implementation.
-*/
-
-static void write_4_byte_int(unsigned char* a_output,long a_int)
- {
- a_output[0] = (unsigned char)(a_int >> 24);
- a_output[1] = (unsigned char)(a_int >> 16);
- a_output[2] = (unsigned char)(a_int >> 8);
- a_output[3] = (unsigned char)(a_int & 0xFF);
- }
-
-static void write_type2_int(WRF_output* a_output,long a_int)
- {
- if (a_int >= -107 && a_int <= 107)
- WRF_wbyte(a_output,(unsigned char)(a_int + 139));
- else if (a_int >= -32768 && a_int <= 32767)
- {
- if (a_int >= 108 && a_int <= 1131)
- a_int += 63124;
- else if (a_int >= -1131 && a_int <= -108)
- a_int = -a_int + 64148;
- else
- WRF_wbyte(a_output,28);
- WRF_wbyte(a_output,(unsigned char)(a_int >> 8));
- WRF_wbyte(a_output,(unsigned char)(a_int & 0xFF));
- }
- else
- {
- unsigned char buffer[4];
- WRF_wbyte(a_output,29);
- write_4_byte_int(buffer,a_int);
- WRF_wtext(a_output,buffer,4);
- }
- }
-
-static void write_type2_float(WRF_output* a_output,double a_float)
- {
- char buffer[32];
- const char* p = buffer;
- int high = true;
- char c = 0;
- sprintf(buffer,"%f",a_float);
- WRF_wbyte(a_output,30);
- for (;;)
- {
- char n = 0;
- if (*p >= '0' && *p <= '9')
- n = (char)(*p - '0');
- else if (*p == '.')
- n = 0xA;
- else if (*p == 'e' || *p == 'E')
- {
- if (p[1] == '-')
- {
- p++;
- n = 0xC;
- }
- else
- n = 0xB;
- }
- else if (*p == '-')
- n = 0xE;
- else if (*p == 0)
- n = 0xF;
- if (high)
- {
- if (*p == 0)
- WRF_wbyte(a_output,0xFF);
- else
- c = (char)(n << 4);
- }
- else
- {
- c |= n;
- WRF_wbyte(a_output,c);
- }
-
- if (*p == 0)
- break;
-
- high = !high;
- p++;
- }
- }
-
-static void write_header(WRF_output* a_output)
- {
- WRF_wtext(a_output,(const unsigned char*)"\x1\x0\x4\x1",4);
- }
-
-static void write_name_index(WRF_output* a_output)
- {
- /* Write a dummy name of 'x'. */
- WRF_wtext(a_output,(const unsigned char*)"\x0\x1\x1\x1\x2""x",6);
- }
-
-static void write_word_entry(FAPI_font* a_fapi_font,WRF_output* a_output,int a_feature_id,
- int a_feature_count,bool a_two_byte_op,int a_op,int a_divisor)
- {
- if (a_feature_count > 0)
- {
- int i;
- for (i = 0; i < a_feature_count; i++)
- {
- /* Get the value and convert it from unsigned to signed. */
- short x = a_fapi_font->get_word(a_fapi_font,a_feature_id,i);
- /* Divide by the divisor to bring it back to font units. */
- x = (short)(x / a_divisor);
- write_type2_int(a_output,x);
- }
- if (a_two_byte_op)
- WRF_wbyte(a_output,12);
- WRF_wbyte(a_output,(unsigned char)a_op);
- }
- }
-
-static void write_delta_array_entry(FAPI_font* a_fapi_font,WRF_output* a_output,int a_feature_id,
- bool a_two_byte_op,int a_op,int a_divisor)
- {
- int i;
- /* NOTE that the feature index (a_feature_id) must be preceded by the count index for this to work. */
- int count = a_fapi_font->get_word(a_fapi_font,a_feature_id - 1,0);
- if (count > 0)
- {
- short prev_value = 0;
- for (i = 0; i < count; i++)
- {
- /* Get the value and convert it from unsigned to signed. */
- short value = a_fapi_font->get_word(a_fapi_font,a_feature_id,i);
- /* Divide by the divisor to bring it back to font units. */
- value = (short)(value / a_divisor);
- write_type2_int(a_output,value - prev_value);
- prev_value = value;
- }
- if (a_two_byte_op)
- WRF_wbyte(a_output,12);
- WRF_wbyte(a_output,(unsigned char)a_op);
- }
- }
-
-static void write_float_entry(FAPI_font* a_fapi_font,WRF_output* a_output,int a_feature_id,int a_feature_count,bool a_two_byte_op,int a_op)
- {
- if (a_feature_count > 0)
- {
- int i;
- for (i = 0; i < a_feature_count; i++)
- {
- double x = a_fapi_font->get_float(a_fapi_font,a_feature_id,i);
- write_type2_float(a_output,x);
- }
- if (a_two_byte_op)
- WRF_wbyte(a_output,12);
- WRF_wbyte(a_output,(unsigned char)a_op);
- }
- }
-
-static void write_font_dict_index(FAPI_font* a_fapi_font,WRF_output* a_output,
- unsigned char** a_charset_offset_ptr,
- unsigned char** a_charstrings_offset_ptr,
- unsigned char** a_private_dict_length_ptr)
- {
- unsigned char* data_start = 0;
- WRF_wtext(a_output,(const unsigned char *)"\x0\x1\x2\x0\x1\x0\x0",7); /* count = 1, offset size = 2, first offset = 1, last offset = 0 (to be filled in later). */
- if (a_output->m_pos)
- data_start = a_output->m_pos;
- write_word_entry(a_fapi_font,a_output,FAPI_FONT_FEATURE_FontBBox,4,false,5,1);
- write_float_entry(a_fapi_font,a_output,FAPI_FONT_FEATURE_FontMatrix,6,true,7);
- write_type2_int(a_output,0); /* 0 = Standard Encoding. */
- WRF_wbyte(a_output,16); /* 16 = opcode for 'encoding'. */
- *a_charset_offset_ptr = a_output->m_pos;
- WRF_wtext(a_output,(const unsigned char *)"\x1d""xxxx",5); /* placeholder for the offset to the charset, which will be a 5-byte integer. */
- WRF_wbyte(a_output,15); /* opcode for 'charset' */
- *a_charstrings_offset_ptr = a_output->m_pos;
- WRF_wtext(a_output,(const unsigned char *)"\x1d""xxxx",5); /* placeholder for the offset to the Charstrings index, which will be a 5-byte integer. */
- WRF_wbyte(a_output,17); /* opcode for 'Charstrings' */
- *a_private_dict_length_ptr = a_output->m_pos;
- WRF_wtext(a_output,(const unsigned char *)"\x1d""xxxx\x1d""yyyy",10); /* placeholder for size and offset of Private dictionary, which will be 5-byte integers. */
- WRF_wbyte(a_output,18); /* opcode for 'Private' */
- if (a_output->m_pos)
- {
- int last_offset = a_output->m_pos - data_start + 1;
- data_start[-2] = (unsigned char)(last_offset >> 8);
- data_start[-1] = (unsigned char)(last_offset & 0xFF);
- }
- }
-
-/**
-Write the character set. Return the number of characters.
-For the moment this is always 1. The number cannot be obtained
-via the FAPI interface, and FreeType doesn't need to know anything more
-than the fact that there is at least one character.
-*/
-static int write_charset(WRF_output* a_output,unsigned char* a_charset_offset_ptr)
- {
- const int characters = 1;
- int i = 0;
-
- /* Write the offset to the start of the charset to the top dictionary. */
- if (a_output->m_pos)
- write_4_byte_int(a_charset_offset_ptr + 1,a_output->m_count);
-
- /*
- Write the charset. Write one less than the number of characters,
- because the first one is assumed to be .notdef. For the moment
- write all the others as .notdef (SID = 0) because we don't actually
- need the charset at the moment.
- */
- WRF_wbyte(a_output,0); /* format = 0 */
- for (i = 1; i < characters; i++)
- {
- WRF_wbyte(a_output,0);
- WRF_wbyte(a_output,0);
- }
-
- return characters;
- }
-
-/**
-Write a set of empty charstrings. The only reason for the existence of the charstrings index is to tell
-FreeType how many glyphs there are.
-*/
-static void write_charstrings_index(WRF_output* a_output,int a_characters,unsigned char* a_charstrings_offset_ptr)
- {
- /* Write the offset to the charstrings index to the top dictionary. */
- if (a_output->m_pos)
- write_4_byte_int(a_charstrings_offset_ptr + 1,a_output->m_count);
-
- /* Write the index. */
- WRF_wbyte(a_output,(unsigned char)(a_characters >> 8));
- WRF_wbyte(a_output,(unsigned char)(a_characters & 0xFF));
- WRF_wbyte(a_output,1); /* offset size = 1. */
- while (a_characters-- >= 0)
- WRF_wbyte(a_output,1); /* offset = 1 */
- }
-
-static void write_gsubrs_index(FAPI_font* a_fapi_font,WRF_output* a_output)
- {
- unsigned char* cur_offset = 0;
- unsigned char* data_start = 0;
- int i;
- int count = a_fapi_font->get_word(a_fapi_font,FAPI_FONT_FEATURE_GlobalSubrs_count,0);
-
- WRF_wbyte(a_output,(unsigned char)(count >> 8));
- WRF_wbyte(a_output,(unsigned char)(count & 0xFF));
-
- if (count <= 0)
- return;
-
- WRF_wbyte(a_output,4); /* offset size = 4 bytes */
- WRF_wtext(a_output,(const unsigned char *)"\x0\x0\x0\x1",4); /* first offset = 1 */
-
- if (a_output->m_pos)
- cur_offset = a_output->m_pos;
-
- /* Write dummy bytes for the offsets at the end of each data item. */
- for (i = 0; i < count; i++)
- WRF_wtext(a_output,(const unsigned char *)"xxxx",4);
-
- if (a_output->m_pos)
- data_start = a_output->m_pos;
-
- for (i = 0; i < count; i++)
- {
- long buffer_size = a_output->m_limit - a_output->m_count;
- long length = a_fapi_font->get_gsubr(a_fapi_font,i,a_output->m_pos,(ushort)buffer_size);
- if (a_output->m_pos)
- WRF_wtext(a_output,a_output->m_pos,length);
- else
- a_output->m_count += length;
- if (cur_offset)
- {
- long pos = a_output->m_pos - data_start + 1;
- write_4_byte_int(cur_offset,pos);
- cur_offset += 4;
- }
- }
- }
-
-static void write_subrs_index(FAPI_font* a_fapi_font,WRF_output* a_output)
- {
- unsigned char* cur_offset = 0;
- unsigned char* data_start = 0;
- int i;
- int count = a_fapi_font->get_word(a_fapi_font,FAPI_FONT_FEATURE_Subrs_count,0);
-
- WRF_wbyte(a_output,(unsigned char)(count >> 8));
- WRF_wbyte(a_output,(unsigned char)(count & 0xFF));
-
- if (count <= 0)
- return;
-
- WRF_wbyte(a_output,4); /* offset size = 4 bytes */
- WRF_wtext(a_output,(const unsigned char *)"\x0\x0\x0\x1",4); /* first offset = 1 */
-
- if (a_output->m_pos)
- cur_offset = a_output->m_pos;
-
- /* Write dummy bytes for the offsets at the end of each data item. */
- for (i = 0; i < count; i++)
- WRF_wtext(a_output,(const unsigned char *)"xxxx",4);
-
- if (a_output->m_pos)
- data_start = a_output->m_pos;
-
- for (i = 0; i < count; i++)
- {
- long buffer_size = a_output->m_limit - a_output->m_count;
- long length = a_fapi_font->get_subr(a_fapi_font,i,a_output->m_pos,(ushort)buffer_size);
- if (a_output->m_pos)
- WRF_wtext(a_output,a_output->m_pos,length);
- else
- a_output->m_count += length;
- if (cur_offset)
- {
- long pos = a_output->m_pos - data_start + 1;
- write_4_byte_int(cur_offset,pos);
- cur_offset += 4;
- }
- }
- }
-
-static void write_private_dict(FAPI_font* a_fapi_font,WRF_output* a_output,unsigned char* a_private_dict_length_ptr)
- {
- int count, initial = a_output->m_count;
- /* Write the offset to the start of the private dictionary to the top dictionary. */
- unsigned char* start = a_output->m_pos;
- if (a_output->m_pos)
- write_4_byte_int(a_private_dict_length_ptr + 6,a_output->m_count);
-
- write_word_entry(a_fapi_font,a_output,FAPI_FONT_FEATURE_BlueFuzz,1,true,11,16);
-
- write_type2_float(a_output,a_fapi_font->get_long(a_fapi_font,FAPI_FONT_FEATURE_BlueScale,0) / 65536.0);
- WRF_wbyte(a_output,12);
- WRF_wbyte(a_output,9);
-
- write_word_entry(a_fapi_font,a_output,FAPI_FONT_FEATURE_BlueShift,1,true,10,16);
- write_delta_array_entry(a_fapi_font,a_output,FAPI_FONT_FEATURE_BlueValues,false,6,16);
- write_delta_array_entry(a_fapi_font,a_output,FAPI_FONT_FEATURE_OtherBlues,false,7,16);
- write_delta_array_entry(a_fapi_font,a_output,FAPI_FONT_FEATURE_FamilyBlues,false,8,16);
- write_delta_array_entry(a_fapi_font,a_output,FAPI_FONT_FEATURE_FamilyOtherBlues,false,9,16);
- write_word_entry(a_fapi_font,a_output,FAPI_FONT_FEATURE_ForceBold,1,true,14,1);
- write_word_entry(a_fapi_font,a_output,FAPI_FONT_FEATURE_StdHW,1,false,10,16);
- write_word_entry(a_fapi_font,a_output,FAPI_FONT_FEATURE_StdVW,1,false,11,16);
- write_delta_array_entry(a_fapi_font,a_output,FAPI_FONT_FEATURE_StemSnapH,true,12,16);
- write_delta_array_entry(a_fapi_font,a_output,FAPI_FONT_FEATURE_StemSnapV,true,13,16);
-
- /*
- Write the default width and the nominal width. These values are not available via
- the FAPI interface so we have to get a pointer to the Type 1 font structure and
- extract them directly.
- */
- {
- gs_font_type1* t1 = (gs_font_type1*)a_fapi_font->client_font_data;
- write_type2_float(a_output,fixed2float(t1->data.defaultWidthX));
- WRF_wbyte(a_output,20);
- write_type2_float(a_output,fixed2float(t1->data.nominalWidthX));
- WRF_wbyte(a_output,21);
- }
-
- count = a_fapi_font->get_word(a_fapi_font,FAPI_FONT_FEATURE_Subrs_count,0);
- /* If we have local /Subrs we need to make a new dict ( see calling routine) and
- * we also need to add an entry to the Provate dict with an offset to the /Subrs
- * dict. This is complicated by the fact that the offset includes the data for
- * the offset (its contained in the Private dict) and the size of the data depends
- * on its value (because of number representation).
- */
- if (count) {
- int n = 1, n1;
-
- do {
- n1 = a_output->m_count - initial + 1 + n; /* one for the operator, plus the size needed for the representation */
- switch (n) {
- case 1:
- if (n1 >= -107 && n1 <= 107) {
- write_type2_int(a_output, n1);
- n = 5;
- }
- break;
- case 2:
- if ((n1 >= 108 && n1 <= 1131) || (n1 >= -1131 && n1 <= -108)) {
- write_type2_int(a_output, n1);
- n = 5;
- }
- break;
- case 3:
- if (n1 >= -32768 && n1 <= 32767) {
- write_type2_int(a_output, n1);
- n = 5;
- }
- break;
- case 4:
- break;
- case 5:
- write_type2_int(a_output, n1);
- break;
- }
- n++;
- } while (n < 5);
-
- WRF_wbyte(a_output,19);
- }
-
- /* Write the length in bytes of the private dictionary to the top dictionary. */
- if (a_output->m_pos)
- write_4_byte_int(a_private_dict_length_ptr + 1,a_output->m_pos - start);
- }
-
-/**
-Write a Type 2 font in binary format and return its length in bytes.
-If a_buffer_size is less than the total length, only a_buffer_size bytes are written, but the total
-length is returned correctly.
-*/
-long FF_serialize_type2_font(FAPI_font* a_fapi_font,unsigned char* a_buffer,long a_buffer_size)
- {
- unsigned char* charset_offset_ptr = NULL;
- unsigned char* charstrings_offset_ptr = NULL;
- unsigned char* private_dict_length_ptr = NULL;
- int characters = 0;
-
- WRF_output output;
- WRF_init(&output,a_buffer,a_buffer_size);
-
- write_header(&output);
- write_name_index(&output);
- write_font_dict_index(a_fapi_font,&output,&charset_offset_ptr,&charstrings_offset_ptr,&private_dict_length_ptr);
-
- /* Write an empty string index. */
- WRF_wtext(&output,(const unsigned char *)"\x0\x0",2);
-
- write_gsubrs_index(a_fapi_font,&output);
- characters = write_charset(&output,charset_offset_ptr);
- write_charstrings_index(&output,characters,charstrings_offset_ptr);
- write_private_dict(a_fapi_font,&output,private_dict_length_ptr);
- write_subrs_index(a_fapi_font,&output);
-
- return output.m_count;
- }
diff --git a/gs/psi/zfapi.c b/gs/psi/zfapi.c
index c1f94930a..5ea81dcdb 100644
--- a/gs/psi/zfapi.c
+++ b/gs/psi/zfapi.c
@@ -16,11 +16,11 @@
/* Font API client */
-#include "stdlib.h" /* abs() */
+#include "stdlib.h" /* abs() */
#include "memory_.h"
#include "math_.h"
-#include "stat_.h" /* include before definition of esp macro, bug 691123 */
+#include "stat_.h" /* include before definition of esp macro, bug 691123 */
#include "string_.h"
#include "ghost.h"
#include "gp.h"
@@ -48,6 +48,7 @@
#include "icid.h"
#include "igstate.h"
#include "icharout.h"
+
#include "ifapi.h"
#include "iplugin.h"
#include "store.h"
@@ -58,173 +59,21 @@
#include "gxfcid.h"
#include "gsstype.h"
#include "gxchar.h" /* for st_gs_show_enum */
-#include "ipacked.h" /* for packed_next */
+#include "ipacked.h" /* for packed_next */
#include "iddict.h"
-#include "ifont42.h" /* for string_array_access_proc */
+#include "ifont42.h" /* for string_array_access_proc */
#include "gdebug.h"
#include "gsimage.h"
#include "gxcldev.h"
#include "gxdevmem.h"
-/* lifted from gxchar.c */
-static const uint MAX_TEMP_BITMAP_BITS = 80000;
-/* -------------------------------------------------------- */
-
-typedef struct FAPI_outline_handler_s {
- struct gx_path_s *path;
- fixed x0, y0;
- bool close_path, need_close; /* This stuff fixes unclosed paths being rendered with UFST */
-} FAPI_outline_handler;
-
-static inline int64_t import_shift(int64_t x, int64_t n)
-{ return n > 0 ? x << n : x >> -n;
-}
-
-static inline int export_shift(int x, int n)
-{ return n > 0 ? x >> n : x << -n;
-}
-
-static inline int fapi_round(double x)
-{ return (int)(x + 0.5);
-}
-
-static int add_closepath(FAPI_path *I)
-{ FAPI_outline_handler *olh = (FAPI_outline_handler *)I->olh;
-
- if (olh->need_close == true) {
- olh->need_close = false;
- I->gs_error = gx_path_close_subpath_notes(olh->path, 0);
- }
- return I->gs_error;
-}
-
-static int add_move(FAPI_path *I, int64_t x, int64_t y)
-{ FAPI_outline_handler *olh = (FAPI_outline_handler *)I->olh;
-
- x = import_shift(x, I->shift) + olh->x0;
- y = -import_shift(y, I->shift) + olh->y0;
-
- if (x > (int64_t)max_fixed) {
- x = (int64_t)max_fixed;
- }
- else if (x < (int64_t)min_fixed) {
- x = (int64_t)min_fixed;
- }
-
- if (y > (int64_t)max_fixed) {
- y = (int64_t)max_fixed;
- }
- else if (y < (int64_t)min_fixed) {
- y = (int64_t)min_fixed;
- }
-
- if (olh->need_close && olh->close_path)
- if ((I->gs_error = add_closepath(I)) < 0)
- return I->gs_error;
- olh->need_close = false;
- I->gs_error = gx_path_add_point(olh->path, (fixed)x, (fixed)y);
-
- return I->gs_error;
-}
-
-static int add_line(FAPI_path *I, int64_t x, int64_t y)
-{ FAPI_outline_handler *olh = (FAPI_outline_handler *)I->olh;
-
- x = import_shift(x, I->shift) + olh->x0;
- y = -import_shift(y, I->shift) + olh->y0;
- if (x > (int64_t)max_fixed) {
- x = (int64_t)max_fixed;
- }
- else if (x < (int64_t)min_fixed) {
- x = (int64_t)min_fixed;
- }
-
- if (y > (int64_t)max_fixed) {
- y = (int64_t)max_fixed;
- }
- else if (y < (int64_t)min_fixed) {
- y = (int64_t)min_fixed;
- }
-
- olh->need_close = true;
- I->gs_error = gx_path_add_line_notes(olh->path, (fixed)x, (fixed)y, 0);
- return I->gs_error;
-}
-
-static int add_curve(FAPI_path *I, int64_t x0, int64_t y0, int64_t x1, int64_t y1, int64_t x2, int64_t y2)
-{ FAPI_outline_handler *olh = (FAPI_outline_handler *)I->olh;
-
- x0 = import_shift(x0, I->shift) + olh->x0;
- y0 = -import_shift(y0, I->shift) + olh->y0;
- x1 = import_shift(x1, I->shift) + olh->x0;
- y1 = -import_shift(y1, I->shift) + olh->y0;
- x2 = import_shift(x2, I->shift) + olh->x0;
- y2 = -import_shift(y2, I->shift) + olh->y0;
-
- if (x0 > (int64_t)max_fixed) {
- x0 = (int64_t)max_fixed;
- }
- else if (x0 < (int64_t)min_fixed) {
- x0 = (int64_t)min_fixed;
- }
-
- if (y0 > (int64_t)max_fixed) {
- y0 = (int64_t)max_fixed;
- }
- else if (y0 < (int64_t)min_fixed) {
- y0 = (int64_t)min_fixed;
- }
- if (x1 > (int64_t)max_fixed) {
- x1 = (int64_t)max_fixed;
- }
- else if (x1 < (int64_t)min_fixed) {
- x1 = (int64_t)min_fixed;
- }
-
- if (y1 > (int64_t)max_fixed) {
- y1 = (int64_t)max_fixed;
- }
- else if (y1 < (int64_t)min_fixed) {
- y1 = (int64_t)min_fixed;
- }
- if (x2 > (int64_t)max_fixed) {
- x2 = (int64_t)max_fixed;
- }
- else if (x2 < (int64_t)min_fixed) {
- x2 = (int64_t)min_fixed;
- }
-
- if (y2 > (int64_t)max_fixed) {
- y2 = (int64_t)max_fixed;
- }
- else if (y2 < (int64_t)min_fixed) {
- y2 = (int64_t)min_fixed;
- }
-
- olh->need_close = true;
- I->gs_error = gx_path_add_curve_notes(olh->path, (fixed)x0, (fixed)y0, (fixed)x1, (fixed)y1, (fixed)x2, (fixed)y2, 0);
- return I->gs_error;
-}
-
-static FAPI_path path_interface_stub = { NULL, 0, 0, add_move, add_line, add_curve, add_closepath };
-
-static inline bool IsCIDFont(const gs_font_base *pbfont)
-{ return (pbfont->FontType == ft_CID_encrypted ||
- pbfont->FontType == ft_CID_user_defined ||
- pbfont->FontType == ft_CID_TrueType);
- /* The font type 10 (ft_CID_user_defined) must not pass to FAPI. */
-}
-
-static inline bool IsType1GlyphData(const gs_font_base *pbfont)
-{ return pbfont->FontType == ft_encrypted ||
- pbfont->FontType == ft_encrypted2 ||
- pbfont->FontType == ft_CID_encrypted;
-}
+#include "gxfapi.h"
/* -------------------------------------------------------- */
typedef struct sfnts_reader_s sfnts_reader;
-struct sfnts_reader_s {
+struct sfnts_reader_s
+{
ref *sfnts;
const gs_memory_t *memory;
const byte *p;
@@ -232,14 +81,15 @@ struct sfnts_reader_s {
uint offset;
uint length;
bool error;
- byte (*rbyte)(sfnts_reader *r);
- ushort (*rword)(sfnts_reader *r);
- ulong (*rlong)(sfnts_reader *r);
- int (*rstring)(sfnts_reader *r, byte *v, int length);
- void (*seek)(sfnts_reader *r, ulong pos);
+ byte(*rbyte) (sfnts_reader *r);
+ ushort(*rword) (sfnts_reader *r);
+ ulong(*rlong) (sfnts_reader *r);
+ int (*rstring) (sfnts_reader *r, byte *v, int length);
+ void (*seek) (sfnts_reader *r, ulong pos);
};
-static void sfnts_next_elem(sfnts_reader *r)
+static void
+sfnts_next_elem(sfnts_reader *r)
{
ref s;
int code;
@@ -257,50 +107,64 @@ static void sfnts_next_elem(sfnts_reader *r)
if (r->error)
return;
r->p = s.value.const_bytes;
- r->length = r_size(&s) & ~(uint)1; /* See Adobe Technical Note # 5012, section 4.2. */
+ r->length = r_size(&s) & ~(uint) 1; /* See Adobe Technical Note # 5012, section 4.2. */
r->offset = 0;
}
-static inline byte sfnts_reader_rbyte_inline(sfnts_reader *r)
-{ if (r->offset >= r->length)
+static inline byte
+sfnts_reader_rbyte_inline(sfnts_reader *r)
+{
+ if (r->offset >= r->length)
sfnts_next_elem(r);
return (r->error ? 0 : r->p[r->offset++]);
}
-static byte sfnts_reader_rbyte(sfnts_reader *r) /* old compiler compatibility */
-{ return sfnts_reader_rbyte_inline(r);
+static byte
+sfnts_reader_rbyte(sfnts_reader *r)
+{ /* old compiler compatibility */
+ return (sfnts_reader_rbyte_inline(r));
}
-static ushort sfnts_reader_rword(sfnts_reader *r)
-{ return (sfnts_reader_rbyte_inline(r) << 8) + sfnts_reader_rbyte_inline(r);
+static ushort
+sfnts_reader_rword(sfnts_reader *r)
+{
+ return ((sfnts_reader_rbyte_inline(r) << 8) +
+ sfnts_reader_rbyte_inline(r));
}
-static ulong sfnts_reader_rlong(sfnts_reader *r)
-{ return (sfnts_reader_rbyte_inline(r) << 24) + (sfnts_reader_rbyte_inline(r) << 16) +
- (sfnts_reader_rbyte_inline(r) << 8) + sfnts_reader_rbyte_inline(r);
+static ulong
+sfnts_reader_rlong(sfnts_reader *r)
+{
+ return ((sfnts_reader_rbyte_inline(r) << 24) +
+ (sfnts_reader_rbyte_inline(r) << 16) +
+ (sfnts_reader_rbyte_inline(r) << 8) +
+ sfnts_reader_rbyte_inline(r));
}
-static int sfnts_reader_rstring(sfnts_reader *r, byte *v, int length)
+static int
+sfnts_reader_rstring(sfnts_reader *r, byte *v, int length)
{
int rlength = length;
if (length <= 0)
- return(0);
+ return (0);
while (!r->error) {
int l = min(length, r->length - r->offset);
+
memcpy(v, r->p + r->offset, l);
length -= l;
r->offset += l;
if (length <= 0)
- return(rlength);
+ return (rlength);
v += l;
sfnts_next_elem(r);
}
- return(rlength - length);
+ return (rlength - length);
}
-static void sfnts_reader_seek(sfnts_reader *r, ulong pos)
-{ /* fixme : optimize */
+static void
+sfnts_reader_seek(sfnts_reader *r, ulong pos)
+{ /* fixme : optimize */
ulong skipped = 0;
r->index = -1;
@@ -312,8 +176,10 @@ static void sfnts_reader_seek(sfnts_reader *r, ulong pos)
r->offset = pos - skipped;
}
-static void sfnts_reader_init(sfnts_reader *r, ref *pdr)
-{ r->rbyte = sfnts_reader_rbyte;
+static void
+sfnts_reader_init(sfnts_reader *r, ref *pdr)
+{
+ r->rbyte = sfnts_reader_rbyte;
r->rword = sfnts_reader_rword;
r->rlong = sfnts_reader_rlong;
r->rstring = sfnts_reader_rstring;
@@ -329,43 +195,52 @@ static void sfnts_reader_init(sfnts_reader *r, ref *pdr)
/* -------------------------------------------------------- */
typedef struct sfnts_writer_s sfnts_writer;
-struct sfnts_writer_s {
+struct sfnts_writer_s
+{
byte *buf, *p;
int buf_size;
- void (*wbyte)(sfnts_writer *w, byte v);
- void (*wword)(sfnts_writer *w, ushort v);
- void (*wlong)(sfnts_writer *w, ulong v);
- void (*wstring)(sfnts_writer *w, byte *v, int length);
+ void (*wbyte) (sfnts_writer *w, byte v);
+ void (*wword) (sfnts_writer *w, ushort v);
+ void (*wlong) (sfnts_writer *w, ulong v);
+ void (*wstring) (sfnts_writer *w, byte *v, int length);
};
-static void sfnts_writer_wbyte(sfnts_writer *w, byte v)
-{ if (w->buf + w->buf_size < w->p + 1)
- return; /* safety */
+static void
+sfnts_writer_wbyte(sfnts_writer *w, byte v)
+{
+ if (w->buf + w->buf_size < w->p + 1)
+ return; /* safety */
w->p[0] = v;
w->p++;
}
-static void sfnts_writer_wword(sfnts_writer *w, ushort v)
-{ if (w->buf + w->buf_size < w->p + 2)
- return; /* safety */
+static void
+sfnts_writer_wword(sfnts_writer *w, ushort v)
+{
+ if (w->buf + w->buf_size < w->p + 2)
+ return; /* safety */
w->p[0] = v / 256;
w->p[1] = v % 256;
w->p += 2;
}
-static void sfnts_writer_wlong(sfnts_writer *w, ulong v)
-{ if (w->buf + w->buf_size < w->p + 4)
- return; /* safety */
+static void
+sfnts_writer_wlong(sfnts_writer *w, ulong v)
+{
+ if (w->buf + w->buf_size < w->p + 4)
+ return; /* safety */
w->p[0] = v >> 24;
w->p[1] = (v >> 16) & 0xFF;
- w->p[2] = (v >> 8) & 0xFF;
+ w->p[2] = (v >> 8) & 0xFF;
w->p[3] = v & 0xFF;
w->p += 4;
}
-static void sfnts_writer_wstring(sfnts_writer *w, byte *v, int length)
-{ if (w->buf + w->buf_size < w->p + length)
- return; /* safety */
+static void
+sfnts_writer_wstring(sfnts_writer *w, byte *v, int length)
+{
+ if (w->buf + w->buf_size < w->p + length)
+ return; /* safety */
memcpy(w->p, v, length);
w->p += length;
}
@@ -380,29 +255,34 @@ static const sfnts_writer sfnts_writer_stub = {
/* -------------------------------------------------------- */
-static inline bool sfnts_need_copy_table(byte *tag)
-{ return memcmp(tag, "glyf", 4) &&
- memcmp(tag, "glyx", 4) && /* Presents in files created by AdobePS5.dll Version 5.1.2 */
- memcmp(tag, "loca", 4) &&
- memcmp(tag, "locx", 4) && /* Presents in files created by AdobePS5.dll Version 5.1.2 */
- memcmp(tag, "cmap", 4);
+static inline bool
+sfnts_need_copy_table(byte *tag)
+{
+ return (memcmp(tag, "glyf", 4) && memcmp(tag, "glyx", 4) && /* Presents in files created by AdobePS5.dll Version 5.1.2 */
+ memcmp(tag, "loca", 4) && memcmp(tag, "locx", 4) && /* Presents in files created by AdobePS5.dll Version 5.1.2 */
+ memcmp(tag, "cmap", 4));
}
-static void sfnt_copy_table(sfnts_reader *r, sfnts_writer *w, int length)
-{ byte buf[1024];
+static void
+sfnt_copy_table(sfnts_reader *r, sfnts_writer *w, int length)
+{
+ byte buf[1024];
while (length > 0 && !r->error) {
int l = min(length, sizeof(buf));
+
(void)r->rstring(r, buf, l);
w->wstring(w, buf, l);
length -= l;
}
}
-static ulong sfnts_copy_except_glyf(sfnts_reader *r, sfnts_writer *w)
-{ /* Note : TTC is not supported and probably is unuseful for Type 42. */
+static ulong
+sfnts_copy_except_glyf(sfnts_reader *r, sfnts_writer *w)
+{ /* Note : TTC is not supported and probably is unuseful for Type 42. */
/* This skips glyf, loca and cmap from copying. */
- struct {
+ struct
+ {
byte tag[4];
ulong checkSum, offset, offset_new, length;
} tables[30];
@@ -413,9 +293,9 @@ static ulong sfnts_copy_except_glyf(sfnts_reader *r, sfnts_writer *w)
ushort searchRange, entrySelector = 0, rangeShift, v;
ulong size_new = 12;
- r->rword(r); /* searchRange */
- r->rword(r); /* entrySelector */
- r->rword(r); /* rangeShift */
+ r->rword(r); /* searchRange */
+ r->rword(r); /* entrySelector */
+ r->rword(r); /* rangeShift */
for (i = 0; i < num_tables; i++) {
if (r->error)
return 0;
@@ -425,8 +305,9 @@ static ulong sfnts_copy_except_glyf(sfnts_reader *r, sfnts_writer *w)
tables[i].length = r->rlong(r);
tables[i].offset_new = size_new;
if (sfnts_need_copy_table(tables[i].tag)) {
- num_tables_new ++;
- size_new += (tables[i].length + alignment - 1) / alignment * alignment;
+ num_tables_new++;
+ size_new +=
+ (tables[i].length + alignment - 1) / alignment * alignment;
}
}
size_new += num_tables_new * 16;
@@ -447,186 +328,253 @@ static ulong sfnts_copy_except_glyf(sfnts_reader *r, sfnts_writer *w)
w->wword(w, searchRange);
w->wword(w, entrySelector);
w->wword(w, rangeShift);
- for (i = 0; i < num_tables; i++)
+ for (i = 0; i < num_tables; i++) {
if (sfnts_need_copy_table(tables[i].tag)) {
w->wstring(w, tables[i].tag, 4);
w->wlong(w, tables[i].checkSum);
w->wlong(w, tables[i].offset_new + num_tables_new * 16);
w->wlong(w, tables[i].length);
}
- for (i = 0; i < num_tables; i++)
+ }
+ for (i = 0; i < num_tables; i++) {
if (sfnts_need_copy_table(tables[i].tag)) {
int k = tables[i].length;
+
r->seek(r, tables[i].offset);
if (r->error)
return 0;
if (w->p - w->buf != tables[i].offset_new + num_tables_new * 16)
- return 0; /* the algorithm consistency check */
+ return 0; /* the algorithm consistency check */
sfnt_copy_table(r, w, tables[i].length);
for (; k & (alignment - 1); k++)
w->wbyte(w, 0);
}
- return size_new;
+ }
+ return (size_new);
}
-static ulong true_type_size(ref *pdr)
-{ sfnts_reader r;
+static ulong
+true_type_size(ref *pdr)
+{
+ sfnts_reader r;
sfnts_reader_init(&r, pdr);
- return sfnts_copy_except_glyf(&r, 0);
+ return (sfnts_copy_except_glyf(&r, 0));
}
-static ushort FAPI_FF_serialize_tt_font(FAPI_font *ff, void *buf, int buf_size)
-{ ref *pdr = (ref *)ff->client_font_data2;
+static ushort
+FAPI_FF_serialize_tt_font(gs_fapi_font *ff, void *buf, int buf_size)
+{
+ ref *pdr = pfont_dict(((gs_font_base *) ff->client_font_data2));
sfnts_reader r;
sfnts_writer w = sfnts_writer_stub;
w.buf_size = buf_size;
w.buf = w.p = buf;
sfnts_reader_init(&r, pdr);
- if(!sfnts_copy_except_glyf(&r, &w))
- return 1;
- return r.error;
+ if (!sfnts_copy_except_glyf(&r, &w))
+ return (1);
+ return (r.error);
}
-static inline ushort float_to_ushort(float v)
-{ return (ushort)(v * 16); /* fixme : the scale may depend on renderer */
+static inline ushort
+float_to_ushort(float v)
+{
+ return ((ushort) (v * 16)); /* fixme : the scale may depend on renderer */
}
-static ushort FAPI_FF_get_word(FAPI_font *ff, fapi_font_feature var_id, int index)
-{ gs_font_type1 *pfont = (gs_font_type1 *)ff->client_font_data;
- ref *pdr = (ref *)ff->client_font_data2;
-
- switch((int)var_id) {
- case FAPI_FONT_FEATURE_Weight: return 0; /* wrong */
- case FAPI_FONT_FEATURE_ItalicAngle: return 0; /* wrong */
- case FAPI_FONT_FEATURE_IsFixedPitch: return 0; /* wrong */
- case FAPI_FONT_FEATURE_UnderLinePosition: return 0; /* wrong */
- case FAPI_FONT_FEATURE_UnderlineThickness: return 0; /* wrong */
- case FAPI_FONT_FEATURE_FontType: return (pfont->FontType == 2 ? 2 : 1);
- case FAPI_FONT_FEATURE_FontBBox:
+static ushort
+FAPI_FF_get_word(gs_fapi_font *ff, gs_fapi_font_feature var_id, int index)
+{
+ gs_font_type1 *pfont = (gs_font_type1 *) ff->client_font_data;
+ ref *pdr = pfont_dict(((gs_font_base *) ff->client_font_data2));
+
+ switch ((int)var_id) {
+ case gs_fapi_font_feature_Weight:
+ return 0; /* wrong */
+ case gs_fapi_font_feature_ItalicAngle:
+ return 0; /* wrong */
+ case gs_fapi_font_feature_IsFixedPitch:
+ return 0; /* wrong */
+ case gs_fapi_font_feature_UnderLinePosition:
+ return 0; /* wrong */
+ case gs_fapi_font_feature_UnderlineThickness:
+ return 0; /* wrong */
+ case gs_fapi_font_feature_FontType:
+ return (pfont->FontType == 2 ? 2 : 1);
+ case gs_fapi_font_feature_FontBBox:
switch (index) {
- case 0 : return (ushort)pfont->FontBBox.p.x;
- case 1 : return (ushort)pfont->FontBBox.p.y;
- case 2 : return (ushort)pfont->FontBBox.q.x;
- case 3 : return (ushort)pfont->FontBBox.q.y;
+ case 0:
+ return ((ushort) pfont->FontBBox.p.x);
+ case 1:
+ return ((ushort) pfont->FontBBox.p.y);
+ case 2:
+ return ((ushort) pfont->FontBBox.q.x);
+ case 3:
+ return ((ushort) pfont->FontBBox.q.y);
}
return 0;
- case FAPI_FONT_FEATURE_BlueValues_count: return pfont->data.BlueValues.count;
- case FAPI_FONT_FEATURE_BlueValues: return float_to_ushort(pfont->data.BlueValues.values[index]);
- case FAPI_FONT_FEATURE_OtherBlues_count: return pfont->data.OtherBlues.count;
- case FAPI_FONT_FEATURE_OtherBlues: return float_to_ushort(pfont->data.OtherBlues.values[index]);
- case FAPI_FONT_FEATURE_FamilyBlues_count: return pfont->data.FamilyBlues.count;
- case FAPI_FONT_FEATURE_FamilyBlues: return float_to_ushort(pfont->data.FamilyBlues.values[index]);
- case FAPI_FONT_FEATURE_FamilyOtherBlues_count: return pfont->data.FamilyOtherBlues.count;
- case FAPI_FONT_FEATURE_FamilyOtherBlues: return float_to_ushort(pfont->data.FamilyOtherBlues.values[index]);
- case FAPI_FONT_FEATURE_BlueShift: return float_to_ushort(pfont->data.BlueShift);
- case FAPI_FONT_FEATURE_BlueFuzz: return float_to_ushort(pfont->data.BlueShift);
- case FAPI_FONT_FEATURE_StdHW: return (pfont->data.StdHW.count == 0 ? 0 : float_to_ushort(pfont->data.StdHW.values[0])); /* UFST bug ? */
- case FAPI_FONT_FEATURE_StdVW: return (pfont->data.StdVW.count == 0 ? 0 : float_to_ushort(pfont->data.StdVW.values[0])); /* UFST bug ? */
- case FAPI_FONT_FEATURE_StemSnapH_count: return pfont->data.StemSnapH.count;
- case FAPI_FONT_FEATURE_StemSnapH: return float_to_ushort(pfont->data.StemSnapH.values[index]);
- case FAPI_FONT_FEATURE_StemSnapV_count: return pfont->data.StemSnapV.count;
- case FAPI_FONT_FEATURE_StemSnapV: return float_to_ushort(pfont->data.StemSnapV.values[index]);
- case FAPI_FONT_FEATURE_ForceBold: return pfont->data.ForceBold;
- case FAPI_FONT_FEATURE_LanguageGroup: return pfont->data.LanguageGroup;
- case FAPI_FONT_FEATURE_lenIV: return (ff->need_decrypt ? 0 : pfont->data.lenIV);
- case FAPI_FONT_FEATURE_GlobalSubrs_count:
- { ref *Private, *GlobalSubrs;
+ case gs_fapi_font_feature_BlueValues_count:
+ return (pfont->data.BlueValues.count);
+ case gs_fapi_font_feature_BlueValues:
+ return (float_to_ushort(pfont->data.BlueValues.values[index]));
+ case gs_fapi_font_feature_OtherBlues_count:
+ return (pfont->data.OtherBlues.count);
+ case gs_fapi_font_feature_OtherBlues:
+ return (float_to_ushort(pfont->data.OtherBlues.values[index]));
+ case gs_fapi_font_feature_FamilyBlues_count:
+ return (pfont->data.FamilyBlues.count);
+ case gs_fapi_font_feature_FamilyBlues:
+ return (float_to_ushort(pfont->data.FamilyBlues.values[index]));
+ case gs_fapi_font_feature_FamilyOtherBlues_count:
+ return (pfont->data.FamilyOtherBlues.count);
+ case gs_fapi_font_feature_FamilyOtherBlues:
+ return (float_to_ushort
+ (pfont->data.FamilyOtherBlues.values[index]));
+ case gs_fapi_font_feature_BlueShift:
+ return (float_to_ushort(pfont->data.BlueShift));
+ case gs_fapi_font_feature_BlueFuzz:
+ return (float_to_ushort(pfont->data.BlueShift));
+ case gs_fapi_font_feature_StdHW:
+ return (pfont->data.StdHW.count == 0 ? 0 : float_to_ushort(pfont->data.StdHW.values[0])); /* UFST bug ? */
+ case gs_fapi_font_feature_StdVW:
+ return (pfont->data.StdVW.count == 0 ? 0 : float_to_ushort(pfont->data.StdVW.values[0])); /* UFST bug ? */
+ case gs_fapi_font_feature_StemSnapH_count:
+ return (pfont->data.StemSnapH.count);
+ case gs_fapi_font_feature_StemSnapH:
+ return (float_to_ushort(pfont->data.StemSnapH.values[index]));
+ case gs_fapi_font_feature_StemSnapV_count:
+ return (pfont->data.StemSnapV.count);
+ case gs_fapi_font_feature_StemSnapV:
+ return (float_to_ushort(pfont->data.StemSnapV.values[index]));
+ case gs_fapi_font_feature_ForceBold:
+ return (pfont->data.ForceBold);
+ case gs_fapi_font_feature_LanguageGroup:
+ return (pfont->data.LanguageGroup);
+ case gs_fapi_font_feature_lenIV:
+ return (ff->need_decrypt ? 0 : pfont->data.lenIV);
+ case gs_fapi_font_feature_GlobalSubrs_count:
+ {
+ ref *Private, *GlobalSubrs;
+
if (pfont->FontType == ft_encrypted2) {
if (dict_find_string(pdr, "Private", &Private) <= 0)
return 0;
- if (dict_find_string(Private, "GlobalSubrs", &GlobalSubrs) <= 0)
+ if (dict_find_string(Private, "GlobalSubrs", &GlobalSubrs)
+ <= 0)
return 0;;
- return r_size(GlobalSubrs);
+ return (r_size(GlobalSubrs));
}
/* Since we don't have an error return capability, use as unlikely a value as possible */
- return(65535);
+ return (65535);
}
- case FAPI_FONT_FEATURE_Subrs_count:
- { ref *Private, *Subrs;
+ case gs_fapi_font_feature_Subrs_count:
+ {
+ ref *Private, *Subrs;
+
if (dict_find_string(pdr, "Private", &Private) <= 0)
return 0;
if (dict_find_string(Private, "Subrs", &Subrs) <= 0)
return 0;
- return r_size(Subrs);
+ return (r_size(Subrs));
}
- case FAPI_FONT_FEATURE_CharStrings_count:
- { ref *CharStrings;
+ case gs_fapi_font_feature_CharStrings_count:
+ {
+ ref *CharStrings;
+
if (dict_find_string(pdr, "CharStrings", &CharStrings) <= 0)
return 0;
- return dict_length(CharStrings);
+ return (dict_length(CharStrings));
}
/* Multiple Master specific */
- case FAPI_FONT_FEATURE_DollarBlend:
- { ref *DBlend;
+ case gs_fapi_font_feature_DollarBlend:
+ {
+ ref *DBlend;
+
if (dict_find_string(pdr, "$Blend", &DBlend) <= 0)
return 0;
return 1;
}
- case FAPI_FONT_FEATURE_BlendAxisTypes_count:
- { ref *Info, *Axes;
+ case gs_fapi_font_feature_BlendAxisTypes_count:
+ {
+ ref *Info, *Axes;
+
if (dict_find_string(pdr, "FontInfo", &Info) <= 0)
return 0;
if (dict_find_string(Info, "BlendAxisTypes", &Axes) <= 0)
return 0;
- return r_size(Axes);
+ return (r_size(Axes));
}
- case FAPI_FONT_FEATURE_BlendFontInfo_count:
- { ref *Info, *FontInfo;
+ case gs_fapi_font_feature_BlendFontInfo_count:
+ {
+ ref *Info, *FontInfo;
+
if (dict_find_string(pdr, "Blend", &Info) <= 0)
return 0;
if (dict_find_string(Info, "FontInfo", &FontInfo) <= 0)
return 0;
- return dict_length(FontInfo);
+ return (dict_length(FontInfo));
}
- case FAPI_FONT_FEATURE_BlendPrivate_count:
- { ref *Info, *Private;
+ case gs_fapi_font_feature_BlendPrivate_count:
+ {
+ ref *Info, *Private;
+
if (dict_find_string(pdr, "Blend", &Info) <= 0)
return 0;
if (dict_find_string(Info, "Private", &Private) <= 0)
return 0;
- return dict_length(Private);
+ return (dict_length(Private));
}
- case FAPI_FONT_FEATURE_WeightVector_count:
- { ref *Array;
+ case gs_fapi_font_feature_WeightVector_count:
+ {
+ ref *Array;
+
if (dict_find_string(pdr, "WeightVector", &Array) <= 0)
return 0;
- return r_size(Array);
+ return (r_size(Array));
}
- case FAPI_FONT_FEATURE_BlendDesignPositionsArrays_count:
- { ref *Info, *Array;
+ case gs_fapi_font_feature_BlendDesignPositionsArrays_count:
+ {
+ ref *Info, *Array;
+
if (dict_find_string(pdr, "FontInfo", &Info) <= 0)
return 0;
- if (dict_find_string(Info, "BlendDesignPositions", &Array) <= 0)
+ if (dict_find_string(Info, "BlendDesignPositions", &Array) <=
+ 0)
return 0;
- return r_size(Array);
+ return (r_size(Array));
}
- case FAPI_FONT_FEATURE_BlendDesignMapArrays_count:
- { ref *Info, *Array;
+ case gs_fapi_font_feature_BlendDesignMapArrays_count:
+ {
+ ref *Info, *Array;
+
if (dict_find_string(pdr, "FontInfo", &Info) <= 0)
return 0;
if (dict_find_string(Info, "BlendDesignMap", &Array) <= 0)
return 0;
- return r_size(Array);
+ return (r_size(Array));
}
- case FAPI_FONT_FEATURE_BlendDesignMapSubArrays_count:
- { ref *Info, *Array, SubArray;
+ case gs_fapi_font_feature_BlendDesignMapSubArrays_count:
+ {
+ ref *Info, *Array, SubArray;
+
if (dict_find_string(pdr, "FontInfo", &Info) <= 0)
return 0;
if (dict_find_string(Info, "BlendDesignMap", &Array) <= 0)
return 0;
if (array_get(ff->memory, Array, index, &SubArray) < 0)
return 0;
- return r_size(&SubArray);
+ return (r_size(&SubArray));
}
- case FAPI_FONT_FEATURE_DollarBlend_length:
- { ref *DBlend, Element, string;
+ case gs_fapi_font_feature_DollarBlend_length:
+ {
+ ref *DBlend, Element, string;
int i, length = 0;
char Buffer[32];
+
if (dict_find_string(pdr, "$Blend", &DBlend) <= 0)
return 0;
- for (i = 0;i < r_size(DBlend);i++) {
+ for (i = 0; i < r_size(DBlend); i++) {
if (array_get(ff->memory, DBlend, i, &Element) < 0)
return 0;
switch (r_btype(&Element)) {
@@ -643,10 +591,11 @@ static ushort FAPI_FF_get_word(FAPI_font *ff, fapi_font_feature var_id, int inde
length += strlen(Buffer) + 1;
break;
case t_operator:
- { op_def const *op;
+ {
+ op_def const *op;
- op = op_index_def(r_size(&Element));
- length += strlen(op->oname + 1) + 1;
+ op = op_index_def(r_size(&Element));
+ length += strlen(op->oname + 1) + 1;
}
break;
default:
@@ -660,43 +609,53 @@ static ushort FAPI_FF_get_word(FAPI_font *ff, fapi_font_feature var_id, int inde
return 0;
}
-static ulong FAPI_FF_get_long(FAPI_font *ff, fapi_font_feature var_id, int index)
-{ gs_font_type1 *pfont = (gs_font_type1 *)ff->client_font_data;
- ref *pdr = (ref *)ff->client_font_data2;
+static ulong
+FAPI_FF_get_long(gs_fapi_font *ff, gs_fapi_font_feature var_id, int index)
+{
+ gs_font_type1 *pfont = (gs_font_type1 *) ff->client_font_data;
+
+ ref *pdr = pfont_dict(((gs_font_base *) ff->client_font_data2));
- switch((int)var_id) {
- case FAPI_FONT_FEATURE_UniqueID: return pfont->UID.id;
- case FAPI_FONT_FEATURE_BlueScale: return (ulong)(pfont->data.BlueScale * 65536);
- case FAPI_FONT_FEATURE_Subrs_total_size :
- { ref *Private, *Subrs, v;
+ switch ((int)var_id) {
+ case gs_fapi_font_feature_UniqueID:
+ return (pfont->UID.id);
+ case gs_fapi_font_feature_BlueScale:
+ return ((ulong) (pfont->data.BlueScale * 65536));
+ case gs_fapi_font_feature_Subrs_total_size:
+ {
+ ref *Private, *Subrs, v;
int lenIV = max(pfont->data.lenIV, 0), k;
ulong size = 0;
long i;
- const char *name[2] = {"Subrs", "GlobalSubrs"};
+ const char *name[2] = { "Subrs", "GlobalSubrs" };
if (dict_find_string(pdr, "Private", &Private) <= 0)
return 0;
for (k = 0; k < 2; k++) {
if (dict_find_string(Private, name[k], &Subrs) > 0)
for (i = r_size(Subrs) - 1; i >= 0; i--) {
array_get(pfont->memory, Subrs, i, &v);
- size += r_size(&v) - (ff->need_decrypt ? 0 : lenIV);
+ size +=
+ r_size(&v) - (ff->need_decrypt ? 0 : lenIV);
}
}
return size;
}
- case FAPI_FONT_FEATURE_TT_size:
- return true_type_size(pdr);
+ case gs_fapi_font_feature_TT_size:
+ return (true_type_size(pdr));
}
return 0;
}
-static float FAPI_FF_get_float(FAPI_font *ff, fapi_font_feature var_id, int index)
-{ gs_font_base *pbfont = (gs_font_base *)ff->client_font_data;
- ref *pdr = (ref *)ff->client_font_data2;
- FAPI_server *I = pbfont->FAPI;
+static float
+FAPI_FF_get_float(gs_fapi_font *ff, gs_fapi_font_feature var_id, int index)
+{
+ gs_font_base *pbfont = (gs_font_base *) ff->client_font_data2;
+ ref *pdr = pfont_dict(pbfont);
+
+ gs_fapi_server *I = pbfont->FAPI;
- switch((int)var_id) {
- case FAPI_FONT_FEATURE_FontMatrix:
+ switch ((int)var_id) {
+ case gs_fapi_font_feature_FontMatrix:
{
double FontMatrix_div;
gs_matrix m, *mptr;
@@ -704,24 +663,33 @@ static float FAPI_FF_get_float(FAPI_font *ff, fapi_font_feature var_id, int inde
if (I && I->get_fontmatrix) {
FontMatrix_div = 1;
mptr = &m;
- I->get_fontmatrix (I, mptr);
+ I->get_fontmatrix(I, mptr);
}
else {
- FontMatrix_div = (ff->is_cid && !IsCIDFont(pbfont) ? 1000 : 1);
+ FontMatrix_div =
+ ((ff->is_cid
+ && (!FAPI_ISCIDFONT(pbfont))) ? 1000 : 1);
mptr = &(pbfont->base->FontMatrix);
}
- switch(index) {
- case 0 : return mptr->xx / FontMatrix_div;
- case 1 : return mptr->xy / FontMatrix_div;
- case 2 : return mptr->yx / FontMatrix_div;
- case 3 : return mptr->yy / FontMatrix_div;
- case 4 : return mptr->tx / FontMatrix_div;
- case 5 : return mptr->ty / FontMatrix_div;
+ switch (index) {
+ case 0:
+ return (mptr->xx / FontMatrix_div);
+ case 1:
+ return (mptr->xy / FontMatrix_div);
+ case 2:
+ return (mptr->yx / FontMatrix_div);
+ case 3:
+ return (mptr->yy / FontMatrix_div);
+ case 4:
+ return (mptr->tx / FontMatrix_div);
+ case 5:
+ return (mptr->ty / FontMatrix_div);
}
}
- case FAPI_FONT_FEATURE_WeightVector:
- { ref *Array, value;
+ case gs_fapi_font_feature_WeightVector:
+ {
+ ref *Array, value;
if (dict_find_string(pdr, "WeightVector", &Array) <= 0)
return 0;
@@ -729,20 +697,24 @@ static float FAPI_FF_get_float(FAPI_font *ff, fapi_font_feature var_id, int inde
return 0;
if (!r_has_type(&value, t_integer)) {
if (r_has_type(&value, t_real)) {
- return value.value.realval;
- } else
+ return (value.value.realval);
+ }
+ else
return 0;
}
else
- return (float)value.value.intval;
+ return ((float)value.value.intval);
}
- case FAPI_FONT_FEATURE_BlendDesignPositionsArrayValue:
- { ref *Info, *Array, SubArray, value;
+ case gs_fapi_font_feature_BlendDesignPositionsArrayValue:
+ {
+ ref *Info, *Array, SubArray, value;
int array_index = index / 8;
+
index %= 8;
if (dict_find_string(pdr, "FontInfo", &Info) <= 0)
return 0;
- if (dict_find_string(Info, "BlendDesignPositions", &Array) <= 0)
+ if (dict_find_string(Info, "BlendDesignPositions", &Array) <=
+ 0)
return 0;
if (array_get(ff->memory, Array, array_index, &SubArray) < 0)
return 0;
@@ -750,16 +722,19 @@ static float FAPI_FF_get_float(FAPI_font *ff, fapi_font_feature var_id, int inde
return 0;
if (!r_has_type(&value, t_integer)) {
if (r_has_type(&value, t_real)) {
- return value.value.realval;
- } else
+ return (value.value.realval);
+ }
+ else
return 0;
}
else
- return (float)value.value.intval;
+ return ((float)value.value.intval);
}
- case FAPI_FONT_FEATURE_BlendDesignMapArrayValue:
- { ref *Info, *Array, SubArray, SubSubArray, value;
+ case gs_fapi_font_feature_BlendDesignMapArrayValue:
+ {
+ ref *Info, *Array, SubArray, SubSubArray, value;
int array_index = index / 64;
+
index %= 8;
if (dict_find_string(pdr, "FontInfo", &Info) <= 0)
return 0;
@@ -773,58 +748,68 @@ static float FAPI_FF_get_float(FAPI_font *ff, fapi_font_feature var_id, int inde
return 0;
if (!r_has_type(&value, t_integer)) {
if (r_has_type(&value, t_real)) {
- return value.value.realval;
- } else
+ return (value.value.realval);
+ }
+ else
return 0;
}
else
- return (float)value.value.intval;
+ return ((float)value.value.intval);
}
}
return 0;
}
-static int FAPI_FF_get_name(FAPI_font *ff, fapi_font_feature var_id, int index, char *Buffer, int len)
+static int
+FAPI_FF_get_name(gs_fapi_font *ff, gs_fapi_font_feature var_id, int index,
+ char *Buffer, int len)
{
- ref name, string, *pdr = (ref *)ff->client_font_data2;
+ ref name, string;
+ ref *pdr = pfont_dict(((gs_font_base *) ff->client_font_data2));
+
+ switch ((int)var_id) {
+ case gs_fapi_font_feature_BlendAxisTypes:
+ {
+ ref *Info, *Axes;
- switch((int)var_id) {
- case FAPI_FONT_FEATURE_BlendAxisTypes:
- { ref *Info, *Axes;
if (dict_find_string(pdr, "FontInfo", &Info) <= 0)
return 0;
if (dict_find_string(Info, "BlendAxisTypes", &Axes) <= 0)
return 0;
- if(!r_has_type(Axes, t_array))
+ if (!r_has_type(Axes, t_array))
return 0;
if (array_get(ff->memory, Axes, index, &name) < 0)
return 0;
}
}
name_string_ref(ff->memory, &name, &string);
- if(r_size(&string) >= len)
+ if (r_size(&string) >= len)
return 0;
memcpy(Buffer, string.value.const_bytes, r_size(&string));
Buffer[r_size(&string)] = 0x00;
return 1;
}
-static int FAPI_FF_get_proc(FAPI_font *ff, fapi_font_feature var_id, int index, char *Buffer)
+static int
+FAPI_FF_get_proc(gs_fapi_font *ff, gs_fapi_font_feature var_id, int index,
+ char *Buffer)
{
- ref *pdr = (ref *)ff->client_font_data2;
+ ref *pdr = pfont_dict(((gs_font_base *) ff->client_font_data2));
char *ptr = Buffer;
if (!Buffer)
return 0;
- switch((int)var_id) {
- case FAPI_FONT_FEATURE_DollarBlend:
- { ref *DBlend, Element, string;
+ switch ((int)var_id) {
+ case gs_fapi_font_feature_DollarBlend:
+ {
+ ref *DBlend, Element, string;
int i;
char Buf[32];
+
if (dict_find_string(pdr, "$Blend", &DBlend) <= 0)
return 0;
- for (i = 0;i < r_size(DBlend);i++) {
+ for (i = 0; i < r_size(DBlend); i++) {
*ptr++ = 0x20;
if (array_get(ff->memory, DBlend, i, &Element) < 0)
return 0;
@@ -832,7 +817,8 @@ static int FAPI_FF_get_proc(FAPI_font *ff, fapi_font_feature var_id, int index,
case t_name:
name_string_ref(ff->memory, &Element, &string);
- strncpy(ptr, (char *)string.value.const_bytes, r_size(&string));
+ strncpy(ptr, (char *)string.value.const_bytes,
+ r_size(&string));
ptr += r_size(&string);
break;
case t_real:
@@ -846,11 +832,12 @@ static int FAPI_FF_get_proc(FAPI_font *ff, fapi_font_feature var_id, int index,
ptr += strlen(Buf);
break;
case t_operator:
- { op_def const *op;
+ {
+ op_def const *op;
- op = op_index_def(r_size(&Element));
- strcpy(ptr, op->oname + 1);
- ptr += strlen(op->oname + 1);
+ op = op_index_def(r_size(&Element));
+ strcpy(ptr, op->oname + 1);
+ ptr += strlen(op->oname + 1);
}
break;
default:
@@ -859,13 +846,17 @@ static int FAPI_FF_get_proc(FAPI_font *ff, fapi_font_feature var_id, int index,
}
}
}
- return ptr - Buffer;
+ return (ptr - Buffer);
}
-static inline void decode_bytes(byte *p, const byte *s, int l, int lenIV)
-{ ushort state = 4330;
+
+static inline void
+decode_bytes(byte *p, const byte *s, int l, int lenIV)
+{
+ ushort state = 4330;
for (; l; s++, l--) {
uchar c = (*s ^ (state >> 8));
+
state = (*s + state) * crypt_c1 + crypt_c2;
if (lenIV > 0)
lenIV--;
@@ -876,24 +867,30 @@ static inline void decode_bytes(byte *p, const byte *s, int l, int lenIV)
}
}
-static ushort get_type1_data(FAPI_font *ff, const ref *type1string,
- byte *buf, ushort buf_length)
-{ gs_font_type1 *pfont = (gs_font_type1 *)ff->client_font_data;
+static ushort
+get_type1_data(gs_fapi_font *ff, const ref *type1string,
+ byte *buf, ushort buf_length)
+{
+ gs_font_type1 *pfont = (gs_font_type1 *) ff->client_font_data;
int lenIV = max(pfont->data.lenIV, 0);
int length = r_size(type1string) - (ff->need_decrypt ? lenIV : 0);
if (buf != 0) {
- int l = min(length, buf_length); /*safety */
+ int l = min(length, buf_length); /*safety */
+
if (ff->need_decrypt && pfont->data.lenIV >= 0)
- decode_bytes(buf, type1string->value.const_bytes, l + lenIV, lenIV);
+ decode_bytes(buf, type1string->value.const_bytes, l + lenIV,
+ lenIV);
else
memcpy(buf, type1string->value.const_bytes, l);
}
return length;
}
-static ushort FAPI_FF_get_gsubr(FAPI_font *ff, int index, byte *buf, ushort buf_length)
-{ ref *pdr = (ref *)ff->client_font_data2;
+static ushort
+FAPI_FF_get_gsubr(gs_fapi_font *ff, int index, byte *buf, ushort buf_length)
+{
+ ref *pdr = pfont_dict(((gs_font_base *) ff->client_font_data2));
ref *Private, *GlobalSubrs, subr;
if (dict_find_string(pdr, "Private", &Private) <= 0)
@@ -901,43 +898,52 @@ static ushort FAPI_FF_get_gsubr(FAPI_font *ff, int index, byte *buf, ushort buf_
if (dict_find_string(Private, "GlobalSubrs", &GlobalSubrs) <= 0)
return 0;
if (array_get(ff->memory,
- GlobalSubrs, index, &subr) < 0 || r_type(&subr) != t_string)
+ GlobalSubrs, index, &subr) < 0 || r_type(&subr) != t_string)
return 0;
- return get_type1_data(ff, &subr, buf, buf_length);
+ return (get_type1_data(ff, &subr, buf, buf_length));
}
-static ushort FAPI_FF_get_subr(FAPI_font *ff, int index, byte *buf, ushort buf_length)
-{ ref *pdr = (ref *)ff->client_font_data2;
+static ushort
+FAPI_FF_get_subr(gs_fapi_font *ff, int index, byte *buf, ushort buf_length)
+{
+ ref *pdr = pfont_dict(((gs_font_base *) ff->client_font_data2));
ref *Private, *Subrs, subr;
if (dict_find_string(pdr, "Private", &Private) <= 0)
return 0;
if (dict_find_string(Private, "Subrs", &Subrs) <= 0)
return 0;
- if (array_get(ff->memory, Subrs, index, &subr) < 0 || r_type(&subr) != t_string)
+ if (array_get(ff->memory, Subrs, index, &subr) < 0
+ || r_type(&subr) != t_string)
return 0;
- return get_type1_data(ff, &subr, buf, buf_length);
+ return (get_type1_data(ff, &subr, buf, buf_length));
}
-static ushort FAPI_FF_get_raw_subr(FAPI_font *ff, int index, byte *buf, ushort buf_length)
-{ ref *pdr = (ref *)ff->client_font_data2;
+static ushort
+FAPI_FF_get_raw_subr(gs_fapi_font *ff, int index, byte *buf,
+ ushort buf_length)
+{
+ ref *pdr = pfont_dict(((gs_font_base *) ff->client_font_data2));
ref *Private, *Subrs, subr;
if (dict_find_string(pdr, "Private", &Private) <= 0)
return 0;
if (dict_find_string(Private, "Subrs", &Subrs) <= 0)
return 0;
- if (array_get(ff->memory, Subrs, index, &subr) < 0 || r_type(&subr) != t_string)
+ if (array_get(ff->memory, Subrs, index, &subr) < 0
+ || r_type(&subr) != t_string)
return 0;
if (buf && buf_length && buf_length >= r_size(&subr)) {
memcpy(buf, subr.value.const_bytes, r_size(&subr));
}
- return r_size(&subr);
+ return (r_size(&subr));
}
-static ushort FAPI_FF_get_charstring_name(FAPI_font *ff, int index, byte *buf, ushort buf_length)
+static ushort
+FAPI_FF_get_charstring_name(gs_fapi_font *ff, int index, byte *buf,
+ ushort buf_length)
{
- ref *pdr = (ref *)ff->client_font_data2;
+ ref *pdr = pfont_dict(((gs_font_base *) ff->client_font_data2));
ref *CharStrings, eltp[2], string;
if (dict_find_string(pdr, "CharStrings", &CharStrings) <= 0)
@@ -945,16 +951,18 @@ static ushort FAPI_FF_get_charstring_name(FAPI_font *ff, int index, byte *buf, u
if (dict_index_entry(CharStrings, index, eltp) < 0)
return 0;
name_string_ref(ff->memory, &eltp[0], &string);
- if(r_size(&string) > buf_length)
- return r_size(&string);
+ if (r_size(&string) > buf_length)
+ return (r_size(&string));
memcpy(buf, string.value.const_bytes, r_size(&string));
buf[r_size(&string)] = 0x00;
- return r_size(&string);
+ return (r_size(&string));
}
-static ushort FAPI_FF_get_charstring(FAPI_font *ff, int index, byte *buf, ushort buf_length)
+static ushort
+FAPI_FF_get_charstring(gs_fapi_font *ff, int index, byte *buf,
+ ushort buf_length)
{
- ref *pdr = (ref *)ff->client_font_data2;
+ ref *pdr = pfont_dict(((gs_font_base *) ff->client_font_data2));
ref *CharStrings, eltp[2];
if (dict_find_string(pdr, "CharStrings", &CharStrings) <= 0)
@@ -964,57 +972,57 @@ static ushort FAPI_FF_get_charstring(FAPI_font *ff, int index, byte *buf, ushort
if (buf && buf_length && buf_length >= r_size(&eltp[1])) {
memcpy(buf, eltp[1].value.const_bytes, r_size(&eltp[1]));
}
- return r_size(&eltp[1]);
+ return (r_size(&eltp[1]));
}
-static bool sfnt_get_glyph_offset(ref *pdr, gs_font_type42 *pfont42, int index, ulong *offset0)
-{ /* Note : TTC is not supported and probably is unuseful for Type 42. */
+static bool
+sfnt_get_glyph_offset(ref *pdr, gs_font_type42 *pfont42, int index,
+ ulong *offset0)
+{ /* Note : TTC is not supported and probably is unuseful for Type 42. */
sfnts_reader r;
int glyf_elem_size = (pfont42->data.indexToLocFormat) ? 4 : 2;
sfnts_reader_init(&r, pdr);
r.seek(&r, pfont42->data.loca + index * glyf_elem_size);
- *offset0 = pfont42->data.glyf + (glyf_elem_size == 2 ? r.rword(&r) * 2 : r.rlong(&r));
- return r.error;
+ *offset0 =
+ pfont42->data.glyf + (glyf_elem_size ==
+ 2 ? r.rword(&r) * 2 : r.rlong(&r));
+ return (r.error);
}
-static int get_GlyphDirectory_data_ptr(const gs_memory_t *mem,
- ref *pdr, int char_code, const byte **ptr)
+static int
+ps_get_GlyphDirectory_data_ptr(gs_fapi_font *ff, int char_code,
+ const byte **ptr)
{
+ ref *pdr = pfont_dict(((gs_font_base *) ff->client_font_data2));
ref *GlyphDirectory, glyph0, *glyph = &glyph0, glyph_index;
+
if (dict_find_string(pdr, "GlyphDirectory", &GlyphDirectory) > 0) {
if (((r_type(GlyphDirectory) == t_dictionary &&
- (make_int(&glyph_index, char_code),
- dict_find(GlyphDirectory, &glyph_index, &glyph) > 0)) ||
+ (make_int(&glyph_index, char_code),
+ dict_find(GlyphDirectory, &glyph_index, &glyph) > 0)) ||
(r_type(GlyphDirectory) == t_array &&
- array_get(mem, GlyphDirectory, char_code, &glyph0) >= 0)
+ array_get(ff->memory, GlyphDirectory, char_code, &glyph0) >= 0)
)
&& r_type(glyph) == t_string) {
- *ptr = glyph->value.const_bytes;
- return r_size(glyph);
- } else
- /* We have a GlyphDirectory, but couldn't find the glyph. If we
- * return -1 then we will attempt to use glyf and loca which
- * will fail. Instead return 0, so we execute an 'empty' glyph.
- */
- return 0;
+ *ptr = glyph->value.const_bytes;
+ return (r_size(glyph));
+ }
+ else
+ /* We have a GlyphDirectory, but couldn't find the glyph. If we
+ * return -1 then we will attempt to use glyf and loca which
+ * will fail. Instead return 0, so we execute an 'empty' glyph.
+ */
+ return 0;
}
return -1;
}
-static bool get_MetricsCount(FAPI_font *ff)
-{ if (!ff->is_type1 && ff->is_cid) {
- gs_font_cid2 *pfcid = (gs_font_cid2 *)ff->client_font_data;
-
- return pfcid->cidata.MetricsCount;
- }
- return 0;
-}
-
-static int get_charstring(FAPI_font *ff, int char_code, ref **proc)
+static int
+get_charstring(gs_fapi_font *ff, int char_code, ref **proc, ref *char_name)
{
- ref *CharStrings, char_name;
- ref *pdr = (ref *)ff->client_font_data2;
+ ref *CharStrings;
+ ref *pdr = pfont_dict(((gs_font_base *) ff->client_font_data2));
if (ff->is_type1) {
if (ff->is_cid)
@@ -1028,26 +1036,36 @@ static int get_charstring(FAPI_font *ff, int char_code, ref **proc)
* with 'glyphshow' may render a character which has no
* Encoding entry.
*/
- if (name_ref(ff->memory, ff->char_data,
- ff->char_data_len, &char_name, -1) < 0)
+ if (name_ref
+ (ff->memory, ff->char_data, ff->char_data_len, char_name,
+ -1) < 0)
return -1;
- } else { /* seac */
- i_ctx_t *i_ctx_p = (i_ctx_t *)ff->client_ctx_p;
+ }
+ else { /* seac */
+ i_ctx_t *i_ctx_p = (i_ctx_t *) ff->client_ctx_p;
ref *StandardEncoding;
- if (dict_find_string(systemdict, "StandardEncoding", &StandardEncoding) <= 0 ||
- array_get(ff->memory, StandardEncoding, char_code, &char_name) < 0)
- if (name_ref(ff->memory, (const byte *)".notdef", 7, &char_name, -1) < 0)
+ if (dict_find_string
+ (systemdict, "StandardEncoding", &StandardEncoding) <= 0
+ || array_get(ff->memory, StandardEncoding, char_code,
+ char_name) < 0) {
+ if (name_ref
+ (ff->memory, (const byte *)".notdef", 7, char_name,
+ -1) < 0)
return -1;
+ }
}
- if (dict_find(CharStrings, &char_name, (ref **)proc) <= 0)
+ if (dict_find(CharStrings, char_name, (ref **) proc) <= 0)
return -1;
}
return 0;
}
-static int FAPI_FF_get_glyph(FAPI_font *ff, int char_code, byte *buf, ushort buf_length)
-{ /*
+static int
+FAPI_FF_get_glyph(gs_fapi_font *ff, int char_code, byte *buf,
+ ushort buf_length)
+{
+ /*
* We assume that renderer requests glyph data with multiple
* consecutive calls to this function.
*
@@ -1062,17 +1080,24 @@ static int FAPI_FF_get_glyph(FAPI_font *ff, int char_code, byte *buf, ushort buf
* of subglyphs (N may be less if the renderer caches glyph data,
* or discontinues rendering on an exception).
*/
- ref *pdr = (ref *)ff->client_font_data2;
+ ref *pdr = pfont_dict(((gs_font_base *) ff->client_font_data2));
+
ushort glyph_length;
- i_ctx_t *i_ctx_p = (i_ctx_t *)ff->client_ctx_p;
+ i_ctx_t *i_ctx_p = (i_ctx_t *) ff->client_ctx_p;
if (ff->is_type1) {
if (ff->is_cid) {
- const ref *glyph = ff->char_data;
+ const gs_string *char_str = (const gs_string *)ff->char_data;
+ ref glyph;
- glyph_length = get_type1_data(ff, glyph, buf, buf_length);
- } else {
+ make_string(&glyph, avm_foreign | a_readonly, char_str->size,
+ char_str->data);
+
+ glyph_length = get_type1_data(ff, &glyph, buf, buf_length);
+ }
+ else {
ref *CharStrings, char_name, *glyph;
+
if (ff->char_data != NULL) {
/*
* Can't use char_code in this case because hooked Type 1 fonts
@@ -1090,19 +1115,26 @@ static int FAPI_FF_get_glyph(FAPI_font *ff, int char_code, byte *buf, ushort buf
*/
ff->char_data = NULL;
}
- } else { /* seac */
+ }
+ else { /* seac */
ref *StandardEncoding;
- if (dict_find_string(systemdict, "StandardEncoding", &StandardEncoding) <= 0 ||
- array_get(ff->memory, StandardEncoding, char_code, &char_name) < 0)
- if (name_ref(ff->memory, (const byte *)".notdef", 7, &char_name, -1) < 0)
+ if (dict_find_string
+ (systemdict, "StandardEncoding", &StandardEncoding) <= 0
+ || array_get(ff->memory, StandardEncoding, char_code,
+ &char_name) < 0)
+ if (name_ref
+ (ff->memory, (const byte *)".notdef", 7, &char_name,
+ -1) < 0)
return -1;
}
if (dict_find_string(pdr, "CharStrings", &CharStrings) <= 0)
return -1;
if (dict_find(CharStrings, &char_name, &glyph) <= 0) {
- if (name_ref(ff->memory, (const byte *)".notdef", 7, &char_name, -1) < 0) {
+ if (name_ref
+ (ff->memory, (const byte *)".notdef", 7, &char_name,
+ -1) < 0) {
return -1;
}
if (dict_find(CharStrings, &char_name, &glyph) <= 0) {
@@ -1113,35 +1145,51 @@ static int FAPI_FF_get_glyph(FAPI_font *ff, int char_code, byte *buf, ushort buf
return -1;
glyph_length = get_type1_data(ff, glyph, buf, buf_length);
}
- } else { /* type 42 */
+ }
+ else { /* type 42 */
const byte *data_ptr;
- int l = get_GlyphDirectory_data_ptr(ff->memory, pdr, char_code, &data_ptr);
+ int l = ff->get_glyphdirectory_data(ff, char_code, &data_ptr);
/* We should only render the TT notdef if we've been told to - logic lifted from zchar42.c */
- if (!i_ctx_p->RenderTTNotdef && ((ff->char_data_len == 7 && strncmp((const char *)ff->char_data, ".notdef", 7) == 0)
- || (ff->char_data_len > 9 && strncmp((const char *)ff->char_data, ".notdef~GS", 10) == 0))) {
- glyph_length = 0;
+ if (!i_ctx_p->RenderTTNotdef
+ &&
+ ((ff->char_data_len == 7
+ && strncmp((const char *)ff->char_data, ".notdef", 7) == 0)
+ || (ff->char_data_len > 9
+ && strncmp((const char *)ff->char_data, ".notdef~GS",
+ 10) == 0))) {
+ glyph_length = 0;
}
else {
if (l >= 0) {
- int MetricsCount = get_MetricsCount(ff), mc = MetricsCount << 1;
+ int MetricsCount = gs_fapi_get_metrics_count(ff), mc =
+ MetricsCount << 1;
- glyph_length = max((ushort)(l - mc), 0); /* safety */
+ glyph_length = max((ushort) (l - mc), 0); /* safety */
if (buf != 0 && glyph_length > 0)
- memcpy(buf, data_ptr + mc, min(glyph_length, buf_length)/* safety */);
- } else {
- gs_font_type42 *pfont42 = (gs_font_type42 *)ff->client_font_data;
+ memcpy(buf, data_ptr + mc,
+ min(glyph_length, buf_length) /* safety */ );
+ }
+ else {
+ gs_font_type42 *pfont42 =
+ (gs_font_type42 *) ff->client_font_data;
ulong offset0, length_read;
- bool error = sfnt_get_glyph_offset(pdr, pfont42, char_code, &offset0);
+ bool error =
+ sfnt_get_glyph_offset(pdr, pfont42, char_code, &offset0);
- glyph_length = (error ? -1 : pfont42->data.len_glyphs[char_code]);
+ glyph_length =
+ (error ? -1 : pfont42->data.len_glyphs[char_code]);
if (buf != 0 && !error) {
sfnts_reader r;
+
sfnts_reader_init(&r, pdr);
r.seek(&r, offset0);
- length_read = r.rstring(&r, buf, min(glyph_length, buf_length)/* safety */);
+ length_read =
+ r.rstring(&r, buf,
+ min(glyph_length,
+ buf_length) /* safety */ );
if (r.error == 1) {
glyph_length = -1;
}
@@ -1159,55 +1207,69 @@ static int FAPI_FF_get_glyph(FAPI_font *ff, int char_code, byte *buf, ushort buf
return glyph_length;
}
-/* If we're rendering an uncached glyph, we need to know
- * whether we're filling it with a pattern, and whether
- * transparency is involved - if so, we have to produce
- * a path outline, and not a bitmap.
- */
-static bool using_transparency_pattern (gs_state *pgs)
+static int
+ps_fapi_get_metrics(gs_fapi_font *ff, gs_string *char_name, int cid,
+ double *m, bool vertical)
{
- gx_device *dev = gs_currentdevice_inline(pgs);
-
- return((!gs_color_writes_pure(pgs)) && dev->procs.begin_transparency_group != NULL && dev->procs.end_transparency_group != NULL);
-}
-
-static bool produce_outline_char (i_ctx_t *i_ctx_p, gs_show_enum *penum_s, gs_font_base *pbfont, int abits, gs_log2_scale_point *log2_scale)
-{
- gs_state *pgs = (gs_state *)penum_s->pis;
-
- log2_scale->x = 0;
- log2_scale->y = 0;
-
- /* Checking both gx_compute_text_oversampling() result, and abits (below) may seem redundant,
- * and hopefully it will be soon, but for now, gx_compute_text_oversampling() could opt to
- * "oversample" sufficiently small glyphs (fwiw, I don't think gx_compute_text_oversampling is
- * working as intended in that respect), regardless of the device's anti-alias setting.
- * This was an old, partial solution for dropouts in small glyphs.
- */
- gx_compute_text_oversampling(penum_s, (gs_font *)pbfont, abits, log2_scale);
+ ref glyph;
+ int code;
+ gs_font_base *pbfont = ((gs_font_base *) ff->client_font_data2);
- return (pgs->in_charpath || pbfont->PaintType != 0 ||
- (pgs->in_cachedevice != CACHE_DEVICE_CACHING && using_transparency_pattern ((gs_state *)penum_s->pis)) ||
- (pgs->in_cachedevice != CACHE_DEVICE_CACHING && (log2_scale->x > 0 || log2_scale->y > 0)) ||
- (pgs->in_cachedevice != CACHE_DEVICE_CACHING && abits > 1));
-}
+ if (char_name->data != NULL) {
+ make_string(&glyph, avm_foreign | a_readonly, char_name->size,
+ char_name->data);
+ }
+ else {
+ make_int(&glyph, cid);
+ }
-static const FAPI_font ff_stub = {
- 0, /* server_font_data */
- 0, /* need_decrypt */
- NULL, /* const gs_memory_t */
- 0, /* font_file_path */
- 0, /* subfont */
- false, /* is_type1 */
- false, /* is_cid */
- false, /* is_outline_font */
- false, /* is_mtx_skipped */
- false, /* is_vertical */
- 0, /* client_ctx_p */
- 0, /* client_font_data */
- 0, /* client_font_data2 */
- 0, /* char_data */
- 0, /* char_data_len */
+ if (vertical) {
+ code = zchar_get_metrics2(pbfont, &glyph, m);
+ }
+ else {
+ code = zchar_get_metrics(pbfont, &glyph, m);
+ }
+
+ make_null(&glyph);
+
+ return (code);
+}
+
+
+/* forward declaration for the ps_ff_stub assignment */
+static int ps_get_glyphname_or_cid(gs_font_base *pbfont,
+ gs_string *charstring, gs_string *name,
+ int ccode, gs_string *enc_char_name,
+ char *font_file_path,
+ gs_fapi_char_ref *cr, bool bCID);
+
+static int ps_fapi_set_cache(gs_text_enum_t *penum,
+ const gs_font_base *pbfont,
+ const gs_string *char_name, int cid,
+ const double pwidth[2], const gs_rect *pbbox,
+ const double Metrics2_sbw_default[4],
+ bool *imagenow);
+
+static const gs_fapi_font ps_ff_stub = {
+ 0, /* server_font_data */
+ 0, /* need_decrypt */
+ NULL, /* const gs_memory_t */
+ 0, /* font_file_path */
+ 0, /* full_font_buf */
+ 0, /* full_font_buf_len */
+ 0, /* subfont */
+ false, /* is_type1 */
+ false, /* is_cid */
+ false, /* is_outline_font */
+ false, /* is_mtx_skipped */
+ false, /* is_vertical */
+ {{-1, -1}}, /* ttf_cmap_req */
+ 0, /* client_ctx_p */
+ 0, /* client_font_data */
+ 0, /* client_font_data2 */
+ 0, /* char_data */
+ 0, /* char_data_len */
+ 0, /* embolden */
FAPI_FF_get_word,
FAPI_FF_get_long,
FAPI_FF_get_float,
@@ -1219,11 +1281,17 @@ static const FAPI_font ff_stub = {
FAPI_FF_get_glyph,
FAPI_FF_serialize_tt_font,
FAPI_FF_get_charstring,
- FAPI_FF_get_charstring_name
+ FAPI_FF_get_charstring_name,
+ ps_get_GlyphDirectory_data_ptr,
+ ps_get_glyphname_or_cid,
+ ps_fapi_get_metrics,
+ ps_fapi_set_cache
};
-static int FAPI_get_xlatmap(i_ctx_t *i_ctx_p, char **xlatmap)
-{ ref *pref;
+static int
+FAPI_get_xlatmap(i_ctx_t *i_ctx_p, char **xlatmap)
+{
+ ref *pref;
int code;
if ((code = dict_find_string(systemdict, ".xlatmap", &pref)) < 0)
@@ -1232,250 +1300,109 @@ static int FAPI_get_xlatmap(i_ctx_t *i_ctx_p, char **xlatmap)
return_error(e_typecheck);
*xlatmap = (char *)pref->value.bytes;
/* Note : this supposes that xlatmap doesn't move in virtual memory.
- Garbager must not be called while plugin executes get_scaled_font, get_decodingID.
- Fix some day with making copy of xlatmap in system memory.
- */
+ Garbager must not be called while plugin executes get_scaled_font, get_decodingID.
+ Fix some day with making copy of xlatmap in system memory.
+ */
return 0;
}
-static int renderer_retcode(i_ctx_t *i_ctx_p, FAPI_server *I, FAPI_retcode rc)
-{ if (rc == 0)
+static int
+renderer_retcode(gs_memory_t *mem, gs_fapi_server *I, gs_fapi_retcode rc)
+{
+ if (rc == 0)
return 0;
- emprintf2(imemory,
+ emprintf2(mem,
"Error: Font Renderer Plugin ( %s ) return code = %d\n",
- I->ig.d->subtype,
- rc);
+ I->ig.d->subtype, rc);
return rc < 0 ? rc : e_invalidfont;
}
-static int zFAPIavailable(i_ctx_t *i_ctx_p)
-{ i_plugin_holder *h = i_plugin_get_list(i_ctx_p);
- bool available = true;
+/* <server name>/<null> object .FAPIavailable bool */
+static int
+zFAPIavailable(i_ctx_t *i_ctx_p)
+{
os_ptr op = osp;
+ char *serv_name = NULL;
+ ref name_ref;
- for (; h != 0; h = h->next)
- if (!strcmp(h->I->d->type,"FAPI"))
- goto found;
- available = false;
- found :
- push(1);
- make_bool(op, available);
- return 0;
-}
+ if (r_has_type(op, t_name)) {
+ name_string_ref(imemory, op, &name_ref);
-static void get_server_param(i_ctx_t *i_ctx_p, const char *subtype, const byte **server_param, int *server_param_size)
-{ ref *FAPIconfig, *options, *server_options;
-
- if (dict_find_string(systemdict, ".FAPIconfig", &FAPIconfig) >= 0 && r_has_type(FAPIconfig, t_dictionary)) {
- if (dict_find_string(FAPIconfig, "ServerOptions", &options) >= 0 && r_has_type(options, t_dictionary)) {
- if (dict_find_string(options, subtype, &server_options) >= 0 && r_has_type(server_options, t_string)) {
- *server_param = server_options->value.const_bytes;
- *server_param_size = r_size(server_options);
- }
+ serv_name =
+ (char *) ref_to_string(&name_ref, imemory, "zFAPIavailable");
+ if (!serv_name) {
+ return_error(e_VMerror);
}
}
-}
-static int FAPI_find_plugin(i_ctx_t *i_ctx_p, const char *subtype, FAPI_server **pI)
-{ i_plugin_holder *h = i_plugin_get_list(i_ctx_p);
- int code;
-
- for (; h != 0; h = h->next)
- if (!strcmp(h->I->d->type,"FAPI"))
- if (!strcmp(h->I->d->subtype, subtype)) {
- FAPI_server *I = *pI = (FAPI_server *)h->I;
- const byte *server_param = NULL;
- int server_param_size = 0;
+ make_bool(op, gs_fapi_available(imemory, serv_name));
- get_server_param(i_ctx_p, subtype, &server_param, &server_param_size);
- if ((code = renderer_retcode(i_ctx_p, I, I->ensure_open(I, server_param, server_param_size))) < 0)
- return code;
- return 0;
- }
- return_error(e_invalidfont);
+ if (serv_name) {
+ gs_free_string(imemory, (byte *) serv_name,
+ strlen((char *)serv_name) + 1, "zFAPIavailable");
+ }
+ return (0);
}
-static inline void release_typeface(FAPI_server *I, void **server_font_data)
+static void
+ps_get_server_param(gs_fapi_server *I, const byte *subtype,
+ byte **server_param, int *server_param_size)
{
- I->release_typeface(I, *server_font_data);
- I->face.font_id = gs_no_id;
- if (I->ff.server_font_data == *server_font_data)
- I->ff.server_font_data = 0;
- *server_font_data = 0;
-}
-
-static int FAPI_prepare_font(i_ctx_t *i_ctx_p, FAPI_server *I, ref *pdr, gs_font_base *pbfont,
- const char *font_file_path, const FAPI_font_scale *font_scale,
- const char *xlatmap, int BBox[4], const char **decodingID)
-{ /* Returns 1 iff BBox is set. */
- /* Cleans up server's font data if failed. */
-
- /* A renderer may need to access the top level font's data of
- * a CIDFontType 0 (FontType 9) font while preparing its subfonts,
- * and/or perform a completion action with the top level font after
- * its descendants are prepared. Therefore with such fonts
- * we first call get_scaled_font(..., FAPI_TOPLEVEL_BEGIN), then
- * get_scaled_font(..., i) with eash descendant font index i,
- * and then get_scaled_font(..., FAPI_TOPLEVEL_COMPLETE).
- * For other fonts we don't call with 'i'.
- *
- * Actually server's data for top level CIDFontTYpe 0 non-disk fonts should not be important,
- * because with non-disk fonts FAPI_do_char never deals with the top-level font,
- * but does with its descendants individually.
- * Therefore a recommendation for the renderer is don't build any special
- * data for the top-level non-disk font of CIDFontType 0, but return immediately
- * with success code and NULL data pointer.
- *
- * get_scaled_font may be called for same font at second time,
- * so the renderen must check whether the data is already built.
- */
- int code, bbox_set = 0;
- ref *SubfontId;
- int subfont;
-
- I->ff = ff_stub;
- if (dict_find_string(pdr, "SubfontId", &SubfontId) >= 0 && r_has_type(SubfontId, t_integer))
- subfont = SubfontId->value.intval;
- else
- subfont = 0;
- I->ff.subfont = subfont;
- I->ff.font_file_path = font_file_path;
- I->ff.is_type1 = IsType1GlyphData(pbfont);
- I->ff.is_vertical = (pbfont->WMode != 0);
- I->ff.memory = imemory;
- I->ff.client_ctx_p = i_ctx_p;
- I->ff.client_font_data = pbfont;
- I->ff.client_font_data2 = pdr;
- I->ff.server_font_data = pbfont->FAPI_font_data; /* Possibly pass it from zFAPIpassfont. */
- I->ff.is_cid = IsCIDFont(pbfont);
- I->ff.is_outline_font = pbfont->PaintType != 0;
- I->ff.is_mtx_skipped = (get_MetricsCount(&I->ff) != 0);
- if ((code = renderer_retcode(i_ctx_p, I, I->get_scaled_font(I, &I->ff,
- font_scale, xlatmap, FAPI_TOPLEVEL_BEGIN))) < 0)
- return code;
- pbfont->FAPI_font_data = I->ff.server_font_data; /* Save it back to GS font. */
- if (I->ff.server_font_data != 0) {
- if ((code = renderer_retcode(i_ctx_p, I, I->get_font_bbox(I, &I->ff, BBox))) < 0) {
- release_typeface(I, &pbfont->FAPI_font_data);
- return code;
- }
- bbox_set = 1;
- }
- if (xlatmap != NULL && pbfont->FAPI_font_data != NULL)
- if ((code = renderer_retcode(i_ctx_p, I, I->get_decodingID(I, &I->ff, decodingID))) < 0) {
- release_typeface(I, &pbfont->FAPI_font_data);
- return code;
- }
- /* Prepare descendant fonts : */
- if (font_file_path == NULL && I->ff.is_type1 && I->ff.is_cid) { /* Renderers should expect same condition. */
- gs_font_cid0 *pfcid = (gs_font_cid0 *)pbfont;
- gs_font_type1 **FDArray = pfcid->cidata.FDArray;
- int i, n = pfcid->cidata.FDArray_size;
- ref *rFDArray, f;
-
- if (dict_find_string(pdr, "FDArray", &rFDArray) <= 0 || r_type(rFDArray) != t_array)
- return_error(e_invalidfont);
- I->ff = ff_stub;
- I->ff.is_type1 = true;
- I->ff.is_vertical = false; /* A subfont may be shared with another fonts. */
- I->ff.memory = imemory;
- I->ff.client_ctx_p = i_ctx_p;
- for (i = 0; i < n; i++) {
- gs_font_type1 *pbfont1 = FDArray[i];
- int BBox_temp[4];
-
- pbfont1->FontBBox = pbfont->FontBBox; /* Inherit FontBBox from the type 9 font. */
- if(array_get(imemory, rFDArray, i, &f) < 0 || r_type(&f) != t_dictionary)
- return_error(e_invalidfont);
-
- I->ff.client_font_data = pbfont1;
- pbfont1->FAPI = pbfont->FAPI;
- I->ff.client_font_data2 = &f;
- I->ff.server_font_data = pbfont1->FAPI_font_data;
- I->ff.is_cid = true;
- I->ff.is_outline_font = pbfont1->PaintType != 0;
- I->ff.is_mtx_skipped = (get_MetricsCount(&I->ff) != 0);
- I->ff.subfont = 0;
- if ((code = renderer_retcode(i_ctx_p, I, I->get_scaled_font(I, &I->ff,
- font_scale, NULL, i))) < 0)
- break;
- pbfont1->FAPI_font_data = I->ff.server_font_data; /* Save it back to GS font. */
- /* Try to do something with the descendant font to ensure that it's working : */
- if ((code = renderer_retcode(i_ctx_p, I, I->get_font_bbox(I, &I->ff, BBox_temp))) < 0)
- break;
- }
- if (i == n) {
- code = renderer_retcode(i_ctx_p, I, I->get_scaled_font(I, &I->ff,
- font_scale, NULL, FAPI_TOPLEVEL_COMPLETE));
- if (code >= 0)
- return bbox_set; /* Full success. */
- }
- /* Fail, release server's font data : */
- for (i = 0; i < n; i++) {
- gs_font_type1 *pbfont1 = FDArray[i];
-
- if (pbfont1->FAPI_font_data != NULL)
- release_typeface(I, &pbfont1->FAPI_font_data);
- }
- if (pbfont->FAPI_font_data != NULL)
- release_typeface(I, &pbfont->FAPI_font_data);
- return_error(e_invalidfont);
- } else {
- code = renderer_retcode(i_ctx_p, I, I->get_scaled_font(I, &I->ff,
- font_scale, xlatmap, FAPI_TOPLEVEL_COMPLETE));
- if (code < 0) {
- release_typeface(I, &pbfont->FAPI_font_data);
- return code;
+ ref *FAPIconfig, *options, *server_options;
+ i_ctx_t *i_ctx_p = (i_ctx_t *) I->client_ctx_p;
+
+ if (dict_find_string(systemdict, ".FAPIconfig", &FAPIconfig) >= 0
+ && r_has_type(FAPIconfig, t_dictionary)) {
+ if (dict_find_string(FAPIconfig, "ServerOptions", &options) >= 0
+ && r_has_type(options, t_dictionary)) {
+ if (dict_find_string(options, (char *)subtype, &server_options) >=
+ 0 && r_has_type(server_options, t_string)) {
+ *server_param = (byte *) server_options->value.const_bytes;
+ *server_param_size = r_size(server_options);
+ }
}
- return bbox_set;
}
}
-static int FAPI_refine_font(i_ctx_t *i_ctx_p, os_ptr op, gs_font_base *pbfont, const char *font_file_path)
-{ ref *pdr = op; /* font dict */
- double size, size1;
- int BBox[4], scale;
+static int
+FAPI_refine_font(i_ctx_t *i_ctx_p, os_ptr op, gs_font *pfont,
+ int subfont, const char *font_file_path)
+{
+ ref *pdr = op; /* font dict */
const char *decodingID = NULL;
char *xlatmap = NULL;
- FAPI_server *I = pbfont->FAPI;
- FAPI_font_scale font_scale = {{1, 0, 0, 1, 0, 0}, {0, 0}, {1, 1}, true};
+ gs_font_base *pbfont = (gs_font_base *)pfont;
+ gs_fapi_server *I = pbfont->FAPI;
ref *Decoding_old;
int code;
if (font_file_path != NULL && pbfont->FAPI_font_data == NULL)
if ((code = FAPI_get_xlatmap(i_ctx_p, &xlatmap)) < 0)
return code;
- scale = 1 << I->frac_shift;
- size1 = size = 1 / hypot(pbfont->FontMatrix.xx, pbfont->FontMatrix.xy);
- if (size < 1000)
- size = 1000;
- if (size1 > 100)
- size1 = (int)(size1 + 0.5);
- font_scale.matrix[0] = font_scale.matrix[3] = (int)(size * scale + 0.5);
- font_scale.HWResolution[0] = (FracInt)(72 * scale);
- font_scale.HWResolution[1] = (FracInt)(72 * scale);
-
- code = FAPI_prepare_font(i_ctx_p, I, pdr, pbfont, font_file_path, &font_scale, xlatmap, BBox, &decodingID);
+
+ gs_fapi_set_servers_client_data(imemory, NULL, i_ctx_p);
+
+ code =
+ gs_fapi_prepare_font(pfont, I, subfont, font_file_path,
+ NULL, xlatmap, &decodingID);
if (code < 0)
return code;
if (code > 0) {
- /* Refine FontBBox : */
+ /* save refined FontBBox back to PS world */
ref *v, mat[4], arr;
int attrs;
- pbfont->FontBBox.p.x = (double)BBox[0] * size1 / size;
- pbfont->FontBBox.p.y = (double)BBox[1] * size1 / size;
- pbfont->FontBBox.q.x = (double)BBox[2] * size1 / size;
- pbfont->FontBBox.q.y = (double)BBox[3] * size1 / size;
if (dict_find_string(op, "FontBBox", &v) > 0) {
- if(!r_has_type(v, t_array) && !r_has_type(v, t_shortarray) && !r_has_type(v, t_mixedarray))
+ if (!r_has_type(v, t_array) && !r_has_type(v, t_shortarray)
+ && !r_has_type(v, t_mixedarray))
return_error(e_invalidfont);
make_real(&mat[0], pbfont->FontBBox.p.x);
make_real(&mat[1], pbfont->FontBBox.p.y);
make_real(&mat[2], pbfont->FontBBox.q.x);
make_real(&mat[3], pbfont->FontBBox.q.y);
- if(r_has_type(v, t_shortarray) || r_has_type(v, t_mixedarray) || r_size(v) < 4) {
+ if (r_has_type(v, t_shortarray) || r_has_type(v, t_mixedarray)
+ || r_size(v) < 4) {
/* Create a new full blown array in case the values are reals */
code = ialloc_ref_array(&arr, a_all, 4, "array");
if (code < 0)
@@ -1488,11 +1415,16 @@ static int FAPI_refine_font(i_ctx_t *i_ctx_p, os_ptr op, gs_font_base *pbfont, c
ref_assign_new(v->value.refs + 1, &mat[1]);
ref_assign_new(v->value.refs + 2, &mat[2]);
ref_assign_new(v->value.refs + 3, &mat[3]);
- } else {
- ref_assign_old(v, v->value.refs + 0, &mat[0], "FAPI_refine_font_BBox");
- ref_assign_old(v, v->value.refs + 1, &mat[1], "FAPI_refine_font_BBox");
- ref_assign_old(v, v->value.refs + 2, &mat[2], "FAPI_refine_font_BBox");
- ref_assign_old(v, v->value.refs + 3, &mat[3], "FAPI_refine_font_BBox");
+ }
+ else {
+ ref_assign_old(v, v->value.refs + 0, &mat[0],
+ "FAPI_refine_font_BBox");
+ ref_assign_old(v, v->value.refs + 1, &mat[1],
+ "FAPI_refine_font_BBox");
+ ref_assign_old(v, v->value.refs + 2, &mat[2],
+ "FAPI_refine_font_BBox");
+ ref_assign_old(v, v->value.refs + 3, &mat[3],
+ "FAPI_refine_font_BBox");
}
attrs = v->tas.type_attrs;
r_clear_attrs(v, a_all);
@@ -1501,53 +1433,51 @@ static int FAPI_refine_font(i_ctx_t *i_ctx_p, os_ptr op, gs_font_base *pbfont, c
}
/* Assign a Decoding : */
- if (decodingID != 0 && *decodingID && dict_find_string(pdr, "Decoding", &Decoding_old) <= 0) {
- ref Decoding;
+ if (decodingID != 0 && *decodingID
+ && dict_find_string(pdr, "Decoding", &Decoding_old) <= 0) {
+ ref Decoding;
- if (IsCIDFont(pbfont)) {
+ if (FAPI_ISCIDFONT(pbfont)) {
ref *CIDSystemInfo, *Ordering, SubstNWP;
byte buf[30];
- int ordering_length, decodingID_length = min(strlen(decodingID), sizeof(buf) - 2);
+ int ordering_length, decodingID_length =
+ min(strlen(decodingID), sizeof(buf) - 2);
- if (dict_find_string(pdr, "CIDSystemInfo", &CIDSystemInfo) <= 0 || !r_has_type(CIDSystemInfo, t_dictionary))
+ if (dict_find_string(pdr, "CIDSystemInfo", &CIDSystemInfo) <= 0
+ || !r_has_type(CIDSystemInfo, t_dictionary))
return_error(e_invalidfont);
- if (dict_find_string(CIDSystemInfo, "Ordering", &Ordering) <= 0 || !r_has_type(Ordering, t_string))
+
+ if (dict_find_string(CIDSystemInfo, "Ordering", &Ordering) <= 0
+ || !r_has_type(Ordering, t_string)) {
return_error(e_invalidfont);
- ordering_length = min(r_size(Ordering), sizeof(buf) - 2 - decodingID_length);
+ }
+
+ ordering_length =
+ min(r_size(Ordering), sizeof(buf) - 2 - decodingID_length);
memcpy(buf, Ordering->value.const_bytes, ordering_length);
- if ((code = name_ref(imemory, buf, ordering_length, &SubstNWP, 0)) < 0)
+ if ((code =
+ name_ref(imemory, buf, ordering_length, &SubstNWP, 0)) < 0)
return code;
- if ((code = dict_put_string(pdr, "SubstNWP", &SubstNWP, NULL)) < 0)
+ if ((code =
+ dict_put_string(pdr, "SubstNWP", &SubstNWP, NULL)) < 0)
return code;
buf[ordering_length] = '.';
memcpy(buf + ordering_length + 1, decodingID, decodingID_length);
- buf[decodingID_length + 1 + ordering_length] = 0; /* Debug purpose only */
+ buf[decodingID_length + 1 + ordering_length] = 0; /* Debug purpose only */
if ((code = name_ref(imemory, buf,
- decodingID_length + 1 + ordering_length, &Decoding, 0)) < 0)
- return code;
- } else
- if ((code = name_ref(imemory, (const byte *)decodingID,
- strlen(decodingID), &Decoding, 0)) < 0)
+ decodingID_length + 1 + ordering_length,
+ &Decoding, 0)) < 0)
return code;
+ }
+ else if ((code = name_ref(imemory, (const byte *)decodingID,
+ strlen(decodingID), &Decoding, 0)) < 0)
+ return code;
if ((code = dict_put_string(pdr, "Decoding", &Decoding, NULL)) < 0)
return code;
}
return 0;
}
-static int notify_remove_font(void *proc_data, void *event_data)
-{ /* gs_font_finalize passes event_data == NULL, so check it here. */
- if (event_data == NULL) {
- gs_font_base *pbfont = proc_data;
- FAPI_server *I = pbfont->FAPI;
-
- if (pbfont->FAPI_font_data != 0) {
- release_typeface(I, &pbfont->FAPI_font_data);
- }
- }
- return 0;
-}
-
/* <string|name> <font> <is_disk_font> .rebuildfontFAPI <string|name> <font> */
/* Rebuild a font for handling it with an external renderer.
@@ -1559,52 +1489,75 @@ static int notify_remove_font(void *proc_data, void *event_data)
This operator must not be called with devices which embed fonts.
*/
-static int zFAPIrebuildfont(i_ctx_t *i_ctx_p)
-{ os_ptr op = osp;
+static int
+zFAPIrebuildfont(i_ctx_t *i_ctx_p)
+{
+ os_ptr op = osp;
build_proc_refs build;
gs_font *pfont;
- int code = font_param(op - 1, &pfont), code1;
- gs_font_base *pbfont = (gs_font_base *)pfont;
+ int code = font_param(op - 1, &pfont);
+ gs_font_base *pbfont = (gs_font_base *) pfont;
ref *v;
- char *font_file_path = NULL, FAPI_ID[20];
+ char *font_file_path = NULL;
+ char FAPI_ID[20];
const byte *pchars;
uint len;
font_data *pdata;
- FAPI_server *I;
+ gs_fapi_server *I;
bool has_buildglyph;
bool has_buildchar;
+ int subfont;
if (code < 0)
return code;
check_type(*op, t_boolean);
- if (pbfont->FAPI != 0) {
- /* If the font was processed with zFAPIpassfont,
- it already has an attached FAPI and server_font_data.
- Don't change them here.
- */
- } else {
- if (dict_find_string(op - 1, "FAPI", &v) <= 0 || !r_has_type(v, t_name))
+ /* If someone has copied the font dictionary, we may still
+ * have the FAPI entry in the dict, but not have the FAPI
+ * server assigned in the font object.
+ */
+ if (pbfont->FAPI == NULL) {
+ if (dict_find_string(op - 1, "FAPI", &v) <= 0
+ || !r_has_type(v, t_name))
return_error(e_invalidfont);
obj_string_data(imemory, v, &pchars, &len);
len = min(len, sizeof(FAPI_ID) - 1);
- strncpy(FAPI_ID, (const char *)pchars, len);
+ strncpy((char *)FAPI_ID, (const char *)pchars, len);
FAPI_ID[len] = 0;
- if ((code = FAPI_find_plugin(i_ctx_p, FAPI_ID, &pbfont->FAPI)) < 0)
- return code;
+
+ gs_fapi_set_servers_client_data(imemory, NULL, i_ctx_p);
+
+ code =
+ gs_fapi_find_server(imemory, FAPI_ID,
+ (gs_fapi_server **) & (pbfont->FAPI),
+ (gs_fapi_get_server_param_callback)
+ ps_get_server_param);
+ if (!pbfont->FAPI || code < 0) {
+ return_error(e_invalidfont);
+ }
}
- pdata = (font_data *)pfont->client_data;
+
+ pdata = (font_data *) pfont->client_data;
I = pbfont->FAPI;
+ if (dict_find_string((op - 1), "SubfontId", &v) >= 0
+ && r_has_type(v, t_integer))
+ subfont = v->value.intval;
+ else
+ subfont = 0;
+
+
if (r_type(&(pdata->BuildGlyph)) != t_null) {
has_buildglyph = true;
- } else {
+ }
+ else {
has_buildglyph = false;
}
if (r_type(&(pdata->BuildChar)) != t_null) {
has_buildchar = true;
- } else {
+ }
+ else {
has_buildchar = false;
}
@@ -1613,416 +1566,148 @@ static int zFAPIrebuildfont(i_ctx_t *i_ctx_p)
has_buildglyph = true;
}
- if (dict_find_string(op - 1, "Path", &v) <= 0 || !r_has_type(v, t_string))
+ if (dict_find_string(op - 1, "Path", &v) <= 0 || !r_has_type(v, t_string)) {
v = NULL;
+ }
+
if (pfont->FontType == ft_CID_encrypted && v == NULL) {
- if ((code = build_proc_name_refs(imemory, &build, ".FAPIBuildGlyph9", ".FAPIBuildGlyph9")) < 0)
+ if ((code = build_proc_name_refs(imemory, &build, ".FAPIBuildGlyph9",
+ ".FAPIBuildGlyph9")) < 0) {
return code;
- } else
- if ((code = build_proc_name_refs(imemory, &build, ".FAPIBuildChar", ".FAPIBuildGlyph")) < 0)
+ }
+ }
+ else {
+ if ((code = build_proc_name_refs(imemory, &build, ".FAPIBuildChar",
+ ".FAPIBuildGlyph")) < 0) {
return code;
- if ((r_type(&(pdata->BuildChar)) != t_null && pdata->BuildChar.value.pname && build.BuildChar.value.pname &&
- name_index(imemory, &pdata->BuildChar) == name_index(imemory, &build.BuildChar))
- || (r_type(&(pdata->BuildGlyph)) != t_null && pdata->BuildGlyph.value.pname && build.BuildGlyph.value.pname &&
- name_index(imemory, &pdata->BuildGlyph) == name_index(imemory, &build.BuildGlyph))) {
- /* Already rebuilt - maybe a substituted font. */
- } else {
+ }
+ }
+
+ if (!
+ ((r_type(&(pdata->BuildChar)) != t_null
+ && pdata->BuildChar.value.pname && build.BuildChar.value.pname
+ && name_index(imemory, &pdata->BuildChar) == name_index(imemory,
+ &build.
+ BuildChar))
+ || (r_type(&(pdata->BuildGlyph)) != t_null
+ && pdata->BuildGlyph.value.pname && build.BuildGlyph.value.pname
+ && name_index(imemory, &pdata->BuildGlyph) == name_index(imemory,
+ &build.
+ BuildGlyph))))
+ {
if (has_buildchar == true) {
ref_assign_new(&pdata->BuildChar, &build.BuildChar);
- } else {
+ }
+ else {
make_null(&pdata->BuildChar);
}
if (has_buildglyph == true) {
ref_assign_new(&pdata->BuildGlyph, &build.BuildGlyph);
- } else {
+ }
+ else {
make_null(&pdata->BuildGlyph);
}
- if (v != NULL)
- font_file_path = ref_to_string(v, imemory_global, "font file path");
- code = FAPI_refine_font(i_ctx_p, op - 1, pbfont, font_file_path);
- memcpy(&I->initial_FontMatrix, &pbfont->FontMatrix, sizeof(gs_matrix));
- if (font_file_path != NULL)
- gs_free_string(imemory_global, (byte *)font_file_path, r_size(v) + 1, "font file path");
- code1 = gs_notify_register(&pfont->notify_list, notify_remove_font, pbfont);
- (void)code1; /* Recover possible error just ignoring it. */
+ if (v != NULL) {
+ font_file_path =
+ ref_to_string(v, imemory_global, "font file path");
+ }
+
+ code =
+ FAPI_refine_font(i_ctx_p, op - 1, pfont, subfont,
+ font_file_path);
+
+ memcpy(&I->initial_FontMatrix, &pbfont->FontMatrix,
+ sizeof(gs_matrix));
+
+ if (font_file_path != NULL) {
+ gs_free_string(imemory_global, (byte *) font_file_path,
+ r_size(v) + 1, "font file path");
+ }
}
pop(1);
return code;
}
-static ulong array_find(const gs_memory_t *mem, ref *Encoding, ref *char_name) {
+static ulong
+array_find(const gs_memory_t *mem, ref *Encoding, ref *char_name)
+{
ulong n = r_size(Encoding), i;
ref v;
+
for (i = 0; i < n; i++)
if (array_get(mem, Encoding, i, &v) < 0)
break;
- else if(r_type(char_name) == r_type(&v) && char_name->value.const_pname == v.value.const_pname)
+ else if (r_type(char_name) == r_type(&v)
+ && char_name->value.const_pname == v.value.const_pname)
return i;
return 0;
}
-static int outline_char(i_ctx_t *i_ctx_p, FAPI_server *I, int import_shift_v, gs_show_enum *penum_s, struct gx_path_s *path, bool close_path)
-{ FAPI_path path_interface = path_interface_stub;
- FAPI_outline_handler olh;
- int code;
- gs_state *pgs;
- extern_st(st_gs_show_enum);
- extern_st(st_gs_state);
-
- if (gs_object_type(penum_s->memory, penum_s) == &st_gs_show_enum) {
- pgs = penum_s->pgs;
- } else {
- if (gs_object_type(penum_s->memory, penum_s->pis) == &st_gs_state) {
- pgs = (gs_state *)penum_s->pis;
- } else
- /* No graphics state, give up... */
- return_error(e_undefined);
- }
- olh.path = path;
- olh.x0 = pgs->ctm.tx_fixed;
- olh.y0 = pgs->ctm.ty_fixed;
- olh.close_path = close_path;
- olh.need_close = false;
- path_interface.olh = &olh;
- path_interface.shift = import_shift_v;
- if ((code = renderer_retcode(i_ctx_p, I, I->get_char_outline(I, &path_interface))) < 0 || path_interface.gs_error != 0) {
- if (path_interface.gs_error != 0)
- return path_interface.gs_error;
- else
- return code;
- }
- if (olh.need_close && olh.close_path)
- if ((code = add_closepath(&path_interface)) < 0)
- return code;
- return 0;
-}
+static int
+zfapi_finish_render(i_ctx_t *i_ctx_p)
+{
+ os_ptr op = osp;
+ gs_font *pfont;
+ int code = font_param(op - 1, &pfont);
-static void compute_em_scale(const gs_font_base *pbfont, FAPI_metrics *metrics, double FontMatrix_div, double *em_scale_x, double *em_scale_y)
-{ /* optimize : move this stuff to FAPI_refine_font */
- gs_matrix mat;
- gs_matrix *m = &pbfont->base->orig_FontMatrix;
- int rounding_x, rounding_y; /* Striking out the 'float' representation error in FontMatrix. */
- double sx, sy;
- FAPI_server *I = pbfont->FAPI;
-
- m = &mat;
-#if 1
- I->get_fontmatrix(I, m);
-#else
- /* Temporary: replace with a FAPI call to check *if* the library needs a replacement matrix */
- memset(m, 0x00, sizeof(gs_matrix));
- m->xx = m->yy = 1.0;
-#endif
+ if (code == 0) {
+ gs_font_base *pbfont = (gs_font_base *) pfont;
+ gs_fapi_server *I = pbfont->FAPI;
+ gs_text_enum_t *penum = op_show_find(i_ctx_p);
- if (m->xx == 0 && m->xy == 0 && m->yx == 0 && m->yy == 0)
- m = &pbfont->base->FontMatrix;
- sx = hypot(m->xx, m->xy) * metrics->em_x / FontMatrix_div;
- sy = hypot(m->yx, m->yy) * metrics->em_y / FontMatrix_div;
- rounding_x = (int)(0x00800000 / sx);
- rounding_y = (int)(0x00800000 / sy);
- *em_scale_x = (int)(sx * rounding_x + 0.5) / (double)rounding_x;
- *em_scale_y = (int)(sy * rounding_y + 0.5) / (double)rounding_y;
-}
+ gs_fapi_set_servers_client_data(imemory, NULL, i_ctx_p);
-static int fapi_copy_mono(gx_device *dev1, FAPI_raster *rast, int dx, int dy)
-{ if ((rast->line_step & (align_bitmap_mod - 1)) == 0)
- return dev_proc(dev1, copy_mono)(dev1, rast->p, 0, rast->line_step, 0, dx, dy, rast->width, rast->height, 0, 1);
- else { /* bitmap data needs to be aligned, make the aligned copy : */
- int line_step = bitmap_raster(rast->width), code;
- byte *p = gs_alloc_byte_array(dev1->memory, rast->height, line_step, "fapi_copy_mono");
- byte *q = p, *r = rast->p, *pe;
- if (p == NULL)
- return_error(e_VMerror);
- pe = p + rast->height * line_step;
- for (; q < pe; q+=line_step, r += rast->line_step)
- memcpy(q, r, rast->line_step);
- code = dev_proc(dev1, copy_mono)(dev1, p, 0, line_step, 0, dx, dy, rast->width, rast->height, 0, 1);
- gs_free_object(dev1->memory, p, "fapi_copy_mono");
- return code;
+ code = gs_fapi_finish_render(pfont, igs, penum, I);
+ pop(2);
+ I->release_char_data(I);
}
+ return code;
}
-static const int frac_pixel_shift = 4;
-
-/* NOTE: fapi_image_uncached_glyph() doesn't check various paramters: it assumes fapi_finish_render_aux()
- * has done so: if it gets called from another function, the function must either do all the parameter
- * validation, or fapi_image_uncached_glyph() must be changed to include the validation.
- */
-static int fapi_image_uncached_glyph (i_ctx_t *i_ctx_p, gs_show_enum *penum, FAPI_raster *rast, const int import_shift_v)
+static int
+ps_fapi_set_cache(gs_text_enum_t *penum, const gs_font_base *pbfont,
+ const gs_string *char_name, int cid,
+ const double pwidth[2], const gs_rect *pbbox,
+ const double Metrics2_sbw_default[4], bool *imagenow)
{
- gx_device *dev = penum->dev;
- gs_state *pgs = (gs_state *)penum->pis;
- int code;
- const gx_clip_path * pcpath = i_ctx_p->pgs->clip_path;
- const gx_drawing_color * pdcolor = penum->pdcolor;
- int rast_orig_x = rast->orig_x;
- int rast_orig_y = - rast->orig_y;
- extern_st(st_gs_show_enum);
-
- byte *r = rast->p;
- byte *src, *dst;
- int h, padbytes, cpbytes, dstr = bitmap_raster(rast->width);
- int sstr = rast->line_step;
-
- /* we can only safely use the gx_image_fill_masked() "shortcut" if we're drawing
- * a "simple" colour, rather than a pattern.
- */
- if (gs_color_writes_pure(pgs)) {
- if (dstr != sstr) {
-
- /* If the stride of the bitmap we've got doesn't match what the rest
- * of the Ghostscript world expects, make one that does.
- * Ghostscript aligns bitmap raster memory in a platform specific
- * manner, so see gxbitmap.h for details.
- *
- * Ideally the padding bytes wouldn't matter, but currently the
- * clist code ends up compressing it using bitmap compression. To
- * ensure consistency across runs (and to get the best possible
- * compression ratios) we therefore set such bytes to zero. It would
- * be nicer if this was fixed in future.
- */
- r = gs_alloc_bytes(penum->memory, dstr * rast->height, "fapi_finish_render_aux");
- if (!r) {
- return_error(e_VMerror);
- }
+ i_ctx_t *i_ctx_p = (i_ctx_t *) pbfont->FAPI->client_ctx_p;
+ op_proc_t exec_cont = 0; /* dummy - see below */
+ int code = 0;
- cpbytes = sstr < dstr ? sstr: dstr;
- padbytes = dstr-cpbytes;
- h = rast->height;
- src = rast->p;
- dst = r;
- if (padbytes > 0)
- {
- while (h-- > 0) {
- memcpy(dst, src, cpbytes);
- memset(dst+cpbytes, 0, padbytes);
- src += sstr;
- dst += dstr;
- }
- }
- else
- {
- while (h-- > 0) {
- memcpy(dst, src, cpbytes);
- src += sstr;
- dst += dstr;
- }
- }
- }
+ if (cid < 0) {
+ ref cname;
- if (gs_object_type(penum->memory, penum) == &st_gs_show_enum) {
- code = gx_image_fill_masked(dev, r, 0, dstr, 0,
- (int)(pgs->ctm.tx + (double)rast_orig_x / (1 << frac_pixel_shift) + penum->fapi_glyph_shift.x + 0.5),
- (int)(pgs->ctm.ty + (double)rast_orig_y / (1 << frac_pixel_shift) + penum->fapi_glyph_shift.y + 0.5),
- rast->width, rast->height,
- pdcolor, 1, rop3_default, pcpath);
- } else {
- code = gx_image_fill_masked(dev, r, 0, dstr, 0,
- (int)(pgs->ctm.tx + (double)rast_orig_x / (1 << frac_pixel_shift) + 0.5),
- (int)(pgs->ctm.ty + (double)rast_orig_y / (1 << frac_pixel_shift) + 0.5),
- rast->width, rast->height,
- pdcolor, 1, rop3_default, pcpath);
- }
- if (rast->p != r) {
- gs_free_object(penum->memory, r, "fapi_finish_render_aux");
- }
+ make_string(&cname, avm_foreign | a_readonly, char_name->size,
+ char_name->data);
+ code =
+ zchar_set_cache(i_ctx_p, pbfont, &cname, NULL, pwidth, pbbox,
+ zfapi_finish_render, &exec_cont,
+ Metrics2_sbw_default);
}
else {
- gs_memory_t *mem = penum->memory->non_gc_memory;
- gs_image_enum *pie = gs_image_enum_alloc(mem, "image_char(image_enum)");
- gs_image_t image;
- int iy, nbytes;
- uint used;
- int code1;
- int x, y, w, h;
-
- if (!pie) {
- return_error(e_VMerror);
- }
+ ref cidref;
- x = (int) (pgs->ctm.tx + (double)rast_orig_x / (1 << frac_pixel_shift) + 0.5);
- y = (int) (pgs->ctm.ty + (double)rast_orig_y / (1 << frac_pixel_shift) + 0.5);
- w = rast->width;
- h = rast->height;
-
- /* Make a matrix that will place the image */
- /* at (x,y) with no transformation. */
- gs_image_t_init_mask(&image, true);
- gs_make_translation((floatp) -x, (floatp) -y, &image.ImageMatrix);
- gs_matrix_multiply(&ctm_only(pgs), &image.ImageMatrix, &image.ImageMatrix);
- image.Width = w;
- image.Height = h;
- image.adjust = false;
- code = gs_image_init(pie, &image, false, pgs);
- nbytes = (rast->width + 7) >> 3;
-
- switch (code) {
- case 1: /* empty image */
- code = 0;
- default:
- break;
- case 0:
- for (iy = 0; iy < h && code >= 0; iy++, r += sstr)
- code = gs_image_next(pie, r, nbytes, &used);
- }
- code1 = gs_image_cleanup_and_free_enum(pie, pgs);
- if (code >= 0 && code1 < 0)
- code = code1;
+ make_int(&cidref, cid);
+ code = zchar_set_cache(i_ctx_p, pbfont, &cidref, NULL, pwidth, pbbox,
+ zfapi_finish_render, &exec_cont,
+ Metrics2_sbw_default);
}
- return(code);
-}
-
-static int fapi_finish_render_aux(i_ctx_t *i_ctx_p, gs_font_base *pbfont, FAPI_server *I)
-{ gs_text_enum_t *penum = op_show_find(i_ctx_p);
- gs_show_enum *penum_s = (gs_show_enum *)penum;
- gs_state *pgs;
- gx_device *dev1;
- const int import_shift_v = _fixed_shift - 32; /* we always 32.32 values for the outline interface now */
- FAPI_raster rast = {0};
- int code;
- extern_st(st_gs_show_enum);
- extern_st(st_gs_state);
- if(penum == NULL) {
- return_error(e_undefined);
+ if (code >= 0 && exec_cont != NULL) {
+ *imagenow = true;
}
-
- /* Ensure that pis points to a st_gs_gstate (graphics state) structure */
- if (gs_object_type(penum->memory, penum->pis) != &st_gs_state) {
- /* If pis is not a graphics state, see if the text enumerator is a
- * show enumerator, in which case we have a pointer to the graphics state there
- */
- if (gs_object_type(penum->memory, penum) == &st_gs_show_enum) {
- pgs = penum_s->pgs;
- } else
- /* No graphics state, give up... */
- return_error(e_undefined);
- } else
- pgs = (gs_state *)penum->pis;
-
- dev1 = gs_currentdevice_inline(pgs); /* Possibly changed by zchar_set_cache. */
-
- /* Even for "non-marking" text operations (for example, stringwidth) we are expected
- * to have a glyph bitmap for the cache, if we're using the cache. For the
- * non-cacheing, non-marking cases, we must not draw the glyph.
- */
- if (igs->in_charpath && !SHOW_IS(penum, TEXT_DO_NONE)) {
- if ((code = outline_char(i_ctx_p, I, import_shift_v, penum_s, pgs->path, !pbfont->PaintType)) < 0)
- return code;
-
- if ((code = gx_path_add_char_path(pgs->show_gstate->path, pgs->path, pgs->in_charpath)) < 0)
- return code;
-
- } else {
- int code;
-
- code = I->get_char_raster(I, &rast);
- if (!SHOW_IS(penum, TEXT_DO_NONE) && I->use_outline) {
- /* The server provides an outline instead the raster. */
- gs_imager_state *pis = (gs_imager_state *)pgs->show_gstate;
- gs_point pt;
-
- if ((code = gs_currentpoint(pgs, &pt)) < 0)
- return code;
- if ((code = outline_char(i_ctx_p, I, import_shift_v, penum_s, pgs->path, !pbfont->PaintType)) < 0)
- return code;
- if ((code = gs_imager_setflat((gs_imager_state *)pgs, gs_char_flatness(pis, 1.0))) < 0)
- return code;
- if (pbfont->PaintType) {
- float lw = gs_currentlinewidth(pgs);
-
- gs_setlinewidth(pgs, pbfont->StrokeWidth);
- code = gs_stroke(pgs);
- gs_setlinewidth(pgs, lw);
- if (code < 0)
- return code;
- } else {
- gs_in_cache_device_t in_cachedevice = pgs->in_cachedevice;
- pgs->in_cachedevice = CACHE_DEVICE_NOT_CACHING;
-
- pgs->fill_adjust.x = pgs->fill_adjust.y = 0;
-
- if ((code = gs_fill(pgs)) < 0)
- return code;
-
- pgs->in_cachedevice = in_cachedevice;
- }
- if ((code = gs_moveto(pgs, pt.x, pt.y)) < 0)
- return code;
- } else {
- int rast_orig_x = rast.orig_x;
- int rast_orig_y = - rast.orig_y;
-
- if (pgs->in_cachedevice == CACHE_DEVICE_CACHING) { /* Using GS cache */
- /* GS and renderer may transform coordinates few differently.
- The best way is to make set_cache_device to take the renderer's bitmap metrics immediately,
- but we need to account CDevProc, which may truncate the bitmap.
- Perhaps GS overestimates the bitmap size,
- so now we only add a compensating shift - the dx and dy.
- */
- if (rast.width != 0) {
- int shift_rd = _fixed_shift - frac_pixel_shift;
- int rounding = 1 << (frac_pixel_shift - 1);
- int dx = arith_rshift_slow((pgs->ctm.tx_fixed >> shift_rd) + rast_orig_x + rounding, frac_pixel_shift);
- int dy = arith_rshift_slow((pgs->ctm.ty_fixed >> shift_rd) + rast_orig_y + rounding, frac_pixel_shift);
-
- if (dx + rast.left_indent < 0 || dx + rast.left_indent + rast.black_width > dev1->width) {
-#ifdef DEBUG
- if (gs_debug_c('m')) {
- emprintf2(dev1->memory,
- "Warning : Cropping a FAPI glyph while caching : dx=%d,%d.\n",
- dx + rast.left_indent,
- dx + rast.left_indent + rast.black_width - dev1->width);
- }
-#endif
- if (dx + rast.left_indent < 0)
- dx -= dx + rast.left_indent;
- }
- if (dy + rast.top_indent < 0 || dy + rast.top_indent + rast.black_height > dev1->height) {
-#ifdef DEBUG
- if (gs_debug_c('m')) {
- emprintf2(dev1->memory,
- "Warning : Cropping a FAPI glyph while caching : dx=%d,%d.\n",
- dy + rast.top_indent,
- dy + rast.top_indent + rast.black_height - dev1->height);
- }
-#endif
- if (dy + rast.top_indent < 0)
- dy -= dy + rast.top_indent;
- }
- if ((code = fapi_copy_mono(dev1, &rast, dx, dy)) < 0)
- return code;
-
- if (gs_object_type(penum->memory, penum) == &st_gs_show_enum) {
- penum_s->cc->offset.x += float2fixed(penum_s->fapi_glyph_shift.x);
- penum_s->cc->offset.y += float2fixed(penum_s->fapi_glyph_shift.y);
- }
- }
- } else if (!SHOW_IS(penum, TEXT_DO_NONE)) { /* Not using GS cache */
- if ((code = fapi_image_uncached_glyph(i_ctx_p, penum_s, &rast, import_shift_v)) < 0)
- return code;
- }
- }
+ else {
+ *imagenow = false;
}
- pop(2);
- return 0;
+ /* We ignore the value of exec_cont here, and leave it up to
+ * gs_fapi_do_char() to do the "right" thing based on the
+ * return value
+ */
+ return (code);
}
-static int fapi_finish_render(i_ctx_t *i_ctx_p)
-{ os_ptr op = osp;
- gs_font *pfont;
- int code = font_param(op - 1, &pfont);
-
- if (code == 0) {
- gs_font_base *pbfont = (gs_font_base *) pfont;
- FAPI_server *I = pbfont->FAPI;
- code = fapi_finish_render_aux(i_ctx_p, pbfont, I);
- I->release_char_data(I);
- }
- return code;
-}
static const byte *
find_substring(const byte *where, int length, const char *what)
@@ -2037,398 +1722,247 @@ find_substring(const byte *where, int length, const char *what)
return NULL;
}
-#define GET_U16_MSB(p) (((uint)((p)[0]) << 8) + (p)[1])
-#define GET_S16_MSB(p) (int)((GET_U16_MSB(p) ^ 0x8000) - 0x8000)
-
-#define MTX_EQ(mtx1,mtx2) (mtx1->xx == mtx2->xx && mtx1->xy == mtx2->xy && \
- mtx1->yx == mtx2->yx && mtx1->yy == mtx2->yy && \
- mtx1->tx == mtx2->tx && mtx1->ty == mtx2->ty)
-
-static int FAPI_do_char(i_ctx_t *i_ctx_p, gs_font_base *pbfont, gx_device *dev, char *font_file_path, bool bBuildGlyph, ref *charstring)
-{ /* Stack : <font> <code|name> --> - */
- os_ptr op = osp;
- ref *pdr = op - 1;
- gs_text_enum_t *penum = op_show_find(i_ctx_p);
- gs_show_enum *penum_s = (gs_show_enum *)penum;
- /*
- fixme: the following code needs to optimize with a maintainence of scaled font objects
- in graphics library and in interpreter. Now we suppose that the renderer
- uses font cache, so redundant font opening isn't a big expense.
- */
- FAPI_char_ref cr = {0, 0, {0}, 0, false, NULL, 0, 0, 0, 0, 0, FAPI_METRICS_NOTDEF};
- const gs_matrix * ctm = &ctm_only(igs);
- int scale;
- FAPI_metrics metrics;
- FAPI_server *I = pbfont->FAPI;
- int client_char_code = 0;
- ref char_name, enc_char_name, *SubfontId;
+static int
+ps_get_glyphname_or_cid(gs_font_base *pbfont, gs_string *charstring,
+ gs_string *name, int ccode,
+ gs_string *enc_char_name, char *font_file_path,
+ gs_fapi_char_ref *cr, bool bCID)
+{
+ ref *pdr = pfont_dict(pbfont);
+ int client_char_code = ccode;
+ ref char_name, cname_str;
+ int code = 0;
+ gs_fapi_server *I = pbfont->FAPI;
bool is_TT_from_type42 = (pbfont->FontType == ft_TrueType && font_file_path == NULL);
- bool is_embedded_type1 = ((pbfont->FontType == ft_encrypted ||
- pbfont->FontType == ft_encrypted2) &&
- font_file_path == NULL);
- bool bCID = (IsCIDFont(pbfont) || charstring != NULL);
- bool bIsType1GlyphData = IsType1GlyphData(pbfont);
- gs_log2_scale_point log2_scale = {0, 0};
- int alpha_bits = (*dev_proc(dev, get_alpha_bits)) (dev, go_text);
- double FontMatrix_div = 1;
- bool bVertical = (gs_rootfont(igs)->WMode != 0), bVertical0 = bVertical;
- double *sbwp, sbw[4] = {0, 0, 0, 0};
- double em_scale_x, em_scale_y;
- gs_rect char_bbox;
- op_proc_t exec_cont = 0;
- int code;
- bool align_to_pixels = gs_currentaligntopixels(pbfont->dir);
- enum {
- SBW_DONE,
- SBW_SCALE,
- SBW_FROM_RENDERER
- } sbw_state = SBW_SCALE;
-
- I->use_outline = false;
- memset(&char_bbox, 0x00, sizeof(char_bbox));
-
- I->ff = ff_stub;
- if(bBuildGlyph && !bCID) {
- if (r_type(op) != t_name) {
- name_enter_string (imemory, ".notdef", op);
- }
- check_type(*op, t_name);
- } else {
-
- if (bBuildGlyph && pbfont->FontType == ft_CID_TrueType && r_has_type(op, t_name)) {
- ref *chstrs, *chs;
- /* This logic is lifted from %Type11BuildGlyph in gs_cidfn.ps
- * Note we only have to deal with mistakenly being given a name object
- * here, the out of range CID is handled later
- */
- if ((dict_find_string(op - 1, "CharStrings", &chstrs)) <= 0) {
- return_error(e_undefined);
- }
-
- if ((dict_find_string(chstrs, ".notdef", &chs)) <= 0) {
- return_error(e_undefined);
- }
- ref_assign_inline(op, chs);
- }
-
- check_type(*op, t_integer);
- }
+ bool is_glyph_index = false;
+ bool is_embedded_type1 =
+ ((pbfont->FontType == ft_encrypted
+ || pbfont->FontType == ft_encrypted2) && font_file_path == NULL);
+ i_ctx_t *i_ctx_p = (i_ctx_t *) I->client_ctx_p;
- if (penum == 0)
- return_error(e_undefined);
-
- I->use_outline = produce_outline_char(i_ctx_p, penum_s, pbfont, alpha_bits, &log2_scale);
- if (I->use_outline) {
- I->max_bitmap = 0;
- }
- else {
- /* FIX ME: It can be a very bad thing, right now, for the FAPI code to decide unilaterally to
- * produce an outline, when the rest of GS expects a bitmap, so we give ourselves a
- * 50% leeway on the maximum cache bitmap, just to be sure. Or the same maximum bitmap size
- * used in gxchar.c
- */
- I->max_bitmap = pbfont->dir->ccache.upper + (pbfont->dir->ccache.upper >> 1) < MAX_TEMP_BITMAP_BITS ?
- pbfont->dir->ccache.upper + (pbfont->dir->ccache.upper >> 1) : MAX_TEMP_BITMAP_BITS;
- }
-
- /* Compute the scale : */
- if (!SHOW_IS(penum, TEXT_DO_NONE) && !I->use_outline) {
- gs_currentcharmatrix(igs, NULL, 1); /* make char_tm valid */
- penum_s->fapi_log2_scale = log2_scale;
+ /* Obtain the character name : */
+ if (bCID) {
+ client_char_code = ccode;
+ make_null(&char_name);
+ enc_char_name->data = NULL;
+ enc_char_name->size = 0;
}
else {
- log2_scale.x = 0;
- log2_scale.y = 0;
- }
-
- /* Prepare font data
- * This needs done here (earlier than it used to be) because FAPI/UFST has conflicting
- * requirements in what I->get_fontmatrix() returns based on font type, so it needs to
- * find the font type.
- */
- if (dict_find_string(pdr, "SubfontId", &SubfontId) > 0 && r_has_type(SubfontId, t_integer))
- I->ff.subfont = SubfontId->value.intval;
- else
- I->ff.subfont = 0;
- I->ff.memory = pbfont->memory;
- I->ff.font_file_path = font_file_path;
- I->ff.client_font_data = pbfont;
- I->ff.client_font_data2 = pdr;
- I->ff.server_font_data = pbfont->FAPI_font_data;
- I->ff.is_type1 = bIsType1GlyphData;
- I->ff.is_cid = bCID;
- I->ff.is_outline_font = pbfont->PaintType != 0;
- I->ff.is_mtx_skipped = (get_MetricsCount(&I->ff) != 0);
- I->ff.is_vertical = bVertical;
- I->ff.client_ctx_p = i_ctx_p;
-
- scale = 1 << I->frac_shift;
-retry_oversampling:
- if (I->face.font_id != pbfont->id ||
- !MTX_EQ((&I->face.ctm),ctm) ||
- I->face.log2_scale.x != log2_scale.x ||
- I->face.log2_scale.y != log2_scale.y ||
- I->face.align_to_pixels != align_to_pixels ||
- I->face.HWResolution[0] != dev->HWResolution[0] ||
- I->face.HWResolution[1] != dev->HWResolution[1]
- ) {
- FAPI_font_scale font_scale = {{1, 0, 0, 1, 0, 0}, {0, 0}, {1, 1}, true};
- gs_matrix scale_mat, scale_ctm;
-
- I->face.font_id = pbfont->id;
- I->face.ctm = *ctm;
- I->face.log2_scale = log2_scale;
- I->face.align_to_pixels = align_to_pixels;
- I->face.HWResolution[0] = dev->HWResolution[0];
- I->face.HWResolution[1] = dev->HWResolution[1];
-
- font_scale.subpixels[0] = 1 << log2_scale.x;
- font_scale.subpixels[1] = 1 << log2_scale.y;
- font_scale.align_to_pixels = align_to_pixels;
-
-#if 1
- /* We apply the entire transform to the glyph (that is ctm x FontMatrix)
- * at render time.
- */
-
- memset(&scale_ctm, 0x00, sizeof(gs_matrix));
- scale_ctm.xx = dev->HWResolution[0]/72;
- scale_ctm.yy = dev->HWResolution[1]/72;
-
- code = gs_matrix_invert((const gs_matrix *)&scale_ctm, &scale_ctm);
-
- code = gs_matrix_multiply(ctm, &scale_ctm, &scale_mat); /* scale_mat == CTM - resolution scaling */
-
- code = I->get_fontmatrix(I, &scale_ctm);
- code = gs_matrix_invert((const gs_matrix *)&scale_ctm, &scale_ctm);
- code = gs_matrix_multiply(&scale_mat, &scale_ctm, &scale_mat); /* scale_mat == CTM - resolution scaling - FontMatrix scaling */
-
- font_scale.matrix[0] = (FracInt)(scale_mat.xx * FontMatrix_div * scale + 0.5);
- font_scale.matrix[1] = -(FracInt)(scale_mat.xy * FontMatrix_div * scale + 0.5);
- font_scale.matrix[2] = (FracInt)(scale_mat.yx * FontMatrix_div * scale + 0.5);
- font_scale.matrix[3] = -(FracInt)(scale_mat.yy * FontMatrix_div * scale + 0.5);
- font_scale.matrix[4] = (FracInt)(scale_mat.tx * FontMatrix_div * scale + 0.5);
- font_scale.matrix[5] = (FracInt)(scale_mat.ty * FontMatrix_div * scale + 0.5);
-#else
-
-# if 1
- base_font_matrix = &I->initial_FontMatrix;
-# else
- base_font_matrix = &pbfont->base->orig_FontMatrix;
-# endif
- if (base_font_matrix->xx == 0 && base_font_matrix->xy == 0 &&
- base_font_matrix->yx == 0 && base_font_matrix->yy == 0)
- base_font_matrix = &pbfont->base->FontMatrix;
- dx = hypot(base_font_matrix->xx, base_font_matrix->xy);
- dy = hypot(base_font_matrix->yx, base_font_matrix->yy);
- /* Trick : we need to restore the font scale from ctm, pbfont->FontMatrix,
- and base_font_matrix. We assume that base_font_matrix is
- a multiple of pbfont->FontMatrix with a constant from scalefont.
- But we cannot devide ctm by pbfont->FontMatrix for getting
- a proper result: the base_font_matrix may be XY transposition,
- but we must not cut out the transposition from ctm.
- Therefore we use the norm of base_font_matrix columns as the divisors
- for X and Y. It is not clear what to do when base_font_matrix is anisotropic
- (i.e. dx != dy), but we did not meet such fonts before now.
- */
- font_scale.matrix[0] = (FracInt)(ctm->xx * FontMatrix_div / dx * 72 / dev->HWResolution[0] * scale + 0.5);
- font_scale.matrix[1] = -(FracInt)(ctm->xy * FontMatrix_div / dy * 72 / dev->HWResolution[0] * scale + 0.5);
- font_scale.matrix[2] = (FracInt)(ctm->yx * FontMatrix_div / dx * 72 / dev->HWResolution[1] * scale + 0.5);
- font_scale.matrix[3] = -(FracInt)(ctm->yy * FontMatrix_div / dy * 72 / dev->HWResolution[1] * scale + 0.5);
- font_scale.matrix[4] = (FracInt)(ctm->tx * FontMatrix_div / dx * 72 / dev->HWResolution[0] * scale + 0.5);
- font_scale.matrix[5] = (FracInt)(ctm->ty * FontMatrix_div / dy * 72 / dev->HWResolution[1] * scale + 0.5);
-#endif
- /* Note: the ctm mapping here is upside down. */
- font_scale.HWResolution[0] = (FracInt)((double)dev->HWResolution[0] * font_scale.subpixels[0] * scale);
- font_scale.HWResolution[1] = (FracInt)((double)dev->HWResolution[1] * font_scale.subpixels[1] * scale);
-
+ if (ccode >= 0) {
+ /* Translate from PS encoding to char name : */
+ ref *Encoding;
- if ((hypot ((double)font_scale.matrix[0], (double)font_scale.matrix[2]) == 0.0
- || hypot ((double)font_scale.matrix[1], (double)font_scale.matrix[3]) == 0.0)) {
- /* If the matrix is degenerate, force a scale to 1 unit. */
- if (!font_scale.matrix[0]) font_scale.matrix[0] = 1;
- if (!font_scale.matrix[3]) font_scale.matrix[3] = 1;
+ client_char_code = ccode;
+ if (dict_find_string(pdr, "Encoding", &Encoding) > 0 &&
+ (r_has_type(Encoding, t_array) ||
+ r_has_type(Encoding, t_shortarray)
+ || r_has_type(Encoding, t_mixedarray))) {
+ if (array_get(imemory, Encoding, client_char_code, &char_name)
+ < 0)
+ if ((code =
+ name_ref(imemory, (const byte *)".notdef", 7,
+ &char_name, -1)) < 0)
+ return code;
+ }
+ else {
+ return_error(e_invalidfont);
+ }
}
+ else {
+ code =
+ names_ref(imemory->gs_lib_ctx->gs_name_table,
+ (const byte *)name->data, name->size, &char_name,
+ 0);
- if ((code = renderer_retcode(i_ctx_p, I, I->get_scaled_font(I, &I->ff, &font_scale,
- NULL,
- (!bCID || (pbfont->FontType != ft_encrypted &&
- pbfont->FontType != ft_encrypted2)
- ? FAPI_TOPLEVEL_PREPARED : FAPI_DESCENDANT_PREPARED)))) < 0)
- return code;
- }
- else {
+ }
+ /* We need to store the name as we get it (from the Encoding array), in case it's
+ * had the name extended (with "~GS~xx"), we'll remove the extension before passing
+ * it to the renderer for a disk based font. But the metrics dictionary may have
+ * been constructed using the extended name....
+ */
+ name_string_ref(imemory, &char_name, &cname_str);
+ enc_char_name->data = cname_str.value.bytes;
+ enc_char_name->size = r_size(&cname_str);
}
- /* Obtain the character name : */
- if (bCID) {
- int_param(op, 0xFFFF, &client_char_code);
- make_null(&char_name);
- } else if (r_has_type(op, t_integer)) {
- /* Translate from PS encoding to char name : */
- ref *Encoding;
- int_param(op, 0xFF, &client_char_code);
- if (dict_find_string(pdr, "Encoding", &Encoding) > 0 &&
- (r_has_type(Encoding, t_array) ||
- r_has_type(Encoding, t_shortarray) || r_has_type(Encoding, t_mixedarray))) {
- if (array_get(imemory, Encoding, client_char_code, &char_name) < 0)
- if ((code = name_ref(imemory, (const byte *)".notdef", 7, &char_name, -1)) < 0)
- return code;
- } else
- return_error(e_invalidfont);
- } else
- char_name = *op;
-
- /* We need to store the name as we get it (from the Encoding array), in case it's
- * had the name extended (with "~GS~xx"), we'll remove the extension before passing
- * it to the renderer for a disk based font. But the metrics dictionary may have
- * been constructed using the extended name....
- */
- ref_assign(&enc_char_name, &char_name);
-
/* Obtain the character code or glyph index : */
- cr.char_codes_count = 1;
+ cr->char_codes_count = 1;
if (bCID) {
if (font_file_path != NULL) {
ref *Decoding, *TT_cmap, *SubstNWP;
ref src_type, dst_type;
- bool is_glyph_index = true;
uint c;
- if (dict_find_string(pdr, "Decoding", &Decoding) <= 0 || !r_has_type(Decoding, t_dictionary))
+ is_glyph_index = true;
+
+ if (dict_find_string(pdr, "Decoding", &Decoding) <= 0
+ || !r_has_type(Decoding, t_dictionary))
return_error(e_invalidfont);
- if (dict_find_string(pdr, "SubstNWP", &SubstNWP) <= 0 || !r_has_type(SubstNWP, t_array))
+ if (dict_find_string(pdr, "SubstNWP", &SubstNWP) <= 0
+ || !r_has_type(SubstNWP, t_array))
return_error(e_invalidfont);
- if (dict_find_string(pdr, "TT_cmap", &TT_cmap) <= 0 || !r_has_type(TT_cmap, t_dictionary)) {
+ if (dict_find_string(pdr, "TT_cmap", &TT_cmap) <= 0
+ || !r_has_type(TT_cmap, t_dictionary)) {
ref *DecodingArray, char_code, char_code1, ih;
int i = client_char_code % 256, n;
make_int(&ih, client_char_code / 256);
/* Check the Decoding array for this block of CIDs */
- if (dict_find(Decoding, &ih, &DecodingArray) <= 0 ||
- !r_has_type(DecodingArray, t_array) ||
- array_get(imemory, DecodingArray, i, &char_code) < 0)
+ if (dict_find(Decoding, &ih, &DecodingArray) <= 0
+ || !r_has_type(DecodingArray, t_array)
+ || array_get(imemory, DecodingArray, i, &char_code) < 0) {
return_error(e_invalidfont);
+ }
/* Check the Decoding entry */
- if (r_has_type(&char_code, t_integer))
+ if (r_has_type(&char_code, t_integer)) {
n = 1;
+ }
else if (r_has_type(&char_code, t_array)) {
DecodingArray = &char_code;
i = 0;
n = r_size(DecodingArray);
- } else
+ }
+ else {
return_error(e_invalidfont);
+ }
- for (;n--; i++) {
- if (array_get(imemory, DecodingArray, i, &char_code1) < 0 ||
- !r_has_type(&char_code1, t_integer))
+ for (; n--; i++) {
+ if (array_get(imemory, DecodingArray, i, &char_code1) < 0
+ || !r_has_type(&char_code1, t_integer)) {
return_error(e_invalidfont);
+ }
c = char_code1.value.intval;
I->check_cmap_for_GID(I, &c);
if (c != 0)
break;
}
- } else {
+ }
+ else {
ref *CIDSystemInfo;
ref *Ordering;
/* We only have to lookup the char code if we're *not* using an identity ordering */
- if (dict_find_string(pdr, "CIDSystemInfo", &CIDSystemInfo) >= 0 && r_has_type(CIDSystemInfo, t_dictionary) &&
- dict_find_string(CIDSystemInfo, "Ordering", &Ordering) >= 0 && r_has_type(Ordering, t_string) &&
- strncmp((const char *)Ordering->value.bytes, "Identity", 8) != 0) {
-
- code = cid_to_TT_charcode(imemory, Decoding, TT_cmap, SubstNWP,
- client_char_code, &c, &src_type, &dst_type);
- if (code < 0)
+ if (dict_find_string(pdr, "CIDSystemInfo", &CIDSystemInfo) >=
+ 0 && r_has_type(CIDSystemInfo, t_dictionary)
+ && dict_find_string(CIDSystemInfo, "Ordering",
+ &Ordering) >= 0
+ && r_has_type(Ordering, t_string)
+ && strncmp((const char *)Ordering->value.bytes,
+ "Identity", 8) != 0) {
+
+ if ((code =
+ cid_to_TT_charcode(imemory, Decoding, TT_cmap,
+ SubstNWP, client_char_code, &c,
+ &src_type, &dst_type)) < 0) {
return code;
+ }
- /* cid_to_TT_charcode() returns 1 if it found a
- * matching character code. Otherwise it returns
- * zero after setting c to zero (.notdef glyph id)
- * or a negative value on error. */
-#if 0
- if (code > 0)
- is_glyph_index = false;
-#endif
- }
- else {
- c = client_char_code;
- }
- }
- cr.char_codes[0] = c;
- cr.is_glyph_index = is_glyph_index;
- /* fixme : process the narrow/wide/proportional mapping type,
- using src_type, dst_type. Should adjust the 'matrix' above.
- Call get_font_proportional_feature for proper choice.
+ }
+ else {
+ c = client_char_code;
+ }
+ }
+ cr->char_codes[0] = c;
+ cr->is_glyph_index = is_glyph_index;
+ /* fixme : process the narrow/wide/proportional mapping type,
+ using src_type, dst_type. Should adjust the 'matrix' above.
+ Call get_font_proportional_feature for proper choice.
+ */
+ }
+ else {
+ ref *CIDMap;
+ byte *Map;
+ int c_code = client_char_code;
+ int gdb = 2;
+ int i;
+ ref *GDBytes = NULL;
+
+ if ((dict_find_string(pdr, "GDBytes", &GDBytes) > 0)
+ && r_has_type(GDBytes, t_integer)) {
+ gdb = GDBytes->value.intval;
+ }
+
+ /* The PDF Reference says that we should use a CIDToGIDMap, but the PDF
+ * interpreter converts this into a CIDMap (see pdf_font.ps, processCIDToGIDMap)
*/
- } else {
- ref *CIDMap;
- byte *Map;
- int ccode = client_char_code;
- int gdb = 2;
- int i;
- ref *GDBytes = NULL;
-
- if ((dict_find_string(pdr, "GDBytes", &GDBytes) > 0) && r_has_type(GDBytes, t_integer)) {
- gdb = GDBytes->value.intval;
- }
-
- /* The PDF Reference says that we should use a CIDToGIDMap, but the PDF
- * interpreter converts this into a CIDMap (see pdf_font.ps, processCIDToGIDMap)
- */
- if (dict_find_string(pdr, "CIDMap", &CIDMap) > 0 && !r_has_type(CIDMap, t_name) &&
- (r_has_type(CIDMap, t_array) || r_has_type(CIDMap, t_string))) {
+ if (dict_find_string(pdr, "CIDMap", &CIDMap) > 0
+ && !r_has_type(CIDMap, t_name) && (r_has_type(CIDMap, t_array)
+ || r_has_type(CIDMap,
+ t_string))) {
if (r_has_type(CIDMap, t_array)) {
- /* Too big for single string, so its an array of 2 strings */
- code = string_array_access_proc(pbfont->memory, CIDMap, 1, client_char_code * gdb, gdb, NULL, NULL, (const byte **)&Map);
-
- } else {
- if (CIDMap->tas.rsize < ccode * gdb) {
- ccode = 0;
- }
- Map = &CIDMap->value.bytes[ccode * gdb];
- }
- cr.char_codes[0] = 0;
-
- for (i = 0; i < gdb; i++) {
- cr.char_codes[0] = (cr.char_codes[0] << 8) + Map[i];
- }
- }
- else
- cr.char_codes[0] = client_char_code;
- }
- } else if (is_TT_from_type42) {
- /* This font must not use 'cmap', so compute glyph index from CharStrings : */
- ref *CharStrings, *glyph_index;
- if (dict_find_string(pdr, "CharStrings", &CharStrings) <= 0 || !r_has_type(CharStrings, t_dictionary))
- return_error(e_invalidfont);
- if ((dict_find(CharStrings, &char_name, &glyph_index) < 0) || r_has_type(glyph_index, t_null)) {
+ /* Too big for single string, so its an array of 2 strings */
+ code =
+ string_array_access_proc(pbfont->memory, CIDMap, 1,
+ client_char_code * gdb, gdb,
+ NULL, NULL,
+ (const byte **)&Map);
+ }
+ else {
+ if (CIDMap->tas.rsize < c_code * gdb) {
+ c_code = 0;
+ }
+ Map = &CIDMap->value.bytes[c_code * gdb];
+ }
+ cr->char_codes[0] = 0;
+
+ for (i = 0; i < gdb; i++) {
+ cr->char_codes[0] = (cr->char_codes[0] << 8) + Map[i];
+ }
+ }
+ else
+ cr->char_codes[0] = client_char_code;
+ }
+ }
+ else if (is_TT_from_type42) {
+ /* This font must not use 'cmap', so compute glyph index from CharStrings : */
+ ref *CharStrings, *glyph_index;
+
+ if (dict_find_string(pdr, "CharStrings", &CharStrings) <= 0
+ || !r_has_type(CharStrings, t_dictionary))
+ return_error(e_invalidfont);
+ if ((dict_find(CharStrings, &char_name, &glyph_index) < 0)
+ || r_has_type(glyph_index, t_null)) {
#ifdef DEBUG
ref *pvalue;
- if (gs_debug_c('1') && (dict_find_string(systemdict,"QUIET", &pvalue)) > 0 &&
- (r_has_type(pvalue, t_boolean) && pvalue->value.boolval == false)) {
+
+ if (gs_debug_c('1')
+ && (dict_find_string(systemdict, "QUIET", &pvalue)) > 0
+ && (r_has_type(pvalue, t_boolean)
+ && pvalue->value.boolval == false)) {
char *glyphn;
- name_string_ref (imemory, &char_name, &char_name);
+ name_string_ref(imemory, &char_name, &char_name);
- glyphn = ref_to_string(&char_name, imemory, "FAPI_do_char");
+ glyphn =
+ ref_to_string(&char_name, imemory,
+ "ps_get_glyphname_or_cid");
if (glyphn) {
- dmprintf2(imemory, " Substituting .notdef for %s in the font %s \n", glyphn, pbfont->font_name.chars);
- gs_free_string(imemory, (byte *)glyphn, strlen(glyphn) + 1, "FAPI_do_char");
+ dmprintf2(imemory, " Substituting .notdef for %s in the font %s \n",
+ glyphn, pbfont->font_name.chars);
+ gs_free_string(imemory, (byte *) glyphn,
+ strlen(glyphn) + 1,
+ "ps_get_glyphname_or_cid");
}
}
#endif
- cr.char_codes[0] = 0; /* .notdef */
- if ((code = name_ref(imemory, (const byte *)".notdef", 7, &char_name, -1)) < 0)
+ cr->char_codes[0] = 0; /* .notdef */
+ if ((code =
+ name_ref(imemory, (const byte *)".notdef", 7, &char_name,
+ -1)) < 0)
return code;
- } else if (r_has_type(glyph_index, t_integer))
- cr.char_codes[0] = glyph_index->value.intval;
+ }
+ else if (r_has_type(glyph_index, t_integer)) {
+ cr->char_codes[0] = glyph_index->value.intval;
+ }
else {
+#if 1 /* I can't find this ever being used, no idea what it's for..... */
+ os_ptr op = osp;
+
/* Check execution stack has space for BuldChar proc and finish_render */
check_estack(2);
/* check space and duplicate the glyph index for BuildChar */
@@ -2436,23 +1970,28 @@ retry_oversampling:
push(1);
ref_assign_inline(op, op - 1);
/* Come back to fapi_finish_render after running the BuildChar */
- push_op_estack(fapi_finish_render);
+ push_op_estack(zfapi_finish_render);
++esp;
ref_assign(esp, glyph_index);
return o_push_estack;
+#else
+ return (e_invalidfont);
+#endif
}
- cr.is_glyph_index = true;
- } else if (is_embedded_type1) {
+ cr->is_glyph_index = true;
+ }
+ else if (is_embedded_type1) {
/* Since the client passes charstring by callback using I->ff.char_data,
- the client doesn't need to provide a good cr here.
- Perhaps since UFST uses char codes as glyph cache keys (UFST 4.2 cannot use names),
- we provide font char codes equal to document's char codes.
- This trick assumes that Encoding can't point different glyphs
- for same char code. The last should be true due to
- PLRM3, "5.9.4 Subsetting and Incremental Definition of Glyphs".
- */
- if (r_has_type(op, t_integer))
- cr.char_codes[0] = client_char_code;
+ the client doesn't need to provide a good cr here.
+ Perhaps since UFST uses char codes as glyph cache keys (UFST 4.2 cannot use names),
+ we provide font char codes equal to document's char codes.
+ This trick assumes that Encoding can't point different glyphs
+ for same char code. The last should be true due to
+ PLRM3, "5.9.4 Subsetting and Incremental Definition of Glyphs".
+ */
+ if (ccode >= 0) {
+ cr->char_codes[0] = client_char_code;
+ }
else {
/*
* Reverse Encoding here, because it can be an incremental one.
@@ -2460,40 +1999,61 @@ retry_oversampling:
* if the encoding doesn't contain the glyph name rendered with glyphshow.
*/
ref *Encoding;
- if (dict_find_string(osp - 1, "Encoding", &Encoding) > 0)
- cr.char_codes[0] = (uint)array_find(imemory, Encoding, op);
+ ref glyph;
+
+ name_ref(pbfont->memory, name->data, name->size, &glyph, false);
+
+ if (dict_find_string(osp - 1, "Encoding", &Encoding) > 0) {
+ cr->char_codes[0] =
+ (uint) array_find(imemory, Encoding, &glyph);
+ }
else
return_error(e_invalidfont);
}
- } else { /* a non-embedded font, i.e. a disk font */
+ }
+ else { /* a non-embedded font, i.e. a disk font */
bool can_retrieve_char_by_name = false;
const byte *p;
- obj_string_data(imemory, &char_name, &cr.char_name, &cr.char_name_length);
- p = find_substring(cr.char_name, cr.char_name_length, gx_extendeg_glyph_name_separator);
+ obj_string_data(imemory, &char_name, &cr->char_name,
+ &cr->char_name_length);
+ p = find_substring(cr->char_name, cr->char_name_length,
+ gx_extendeg_glyph_name_separator);
if (p != NULL) {
- cr.char_name_length = p - cr.char_name;
- name_ref(pbfont->memory, cr.char_name, cr.char_name_length, &char_name, true);
+ cr->char_name_length = p - cr->char_name;
+ name_ref(pbfont->memory, cr->char_name, cr->char_name_length,
+ &char_name, true);
}
- if ((code = renderer_retcode(i_ctx_p, I, I->can_retrieve_char_by_name(I, &I->ff, &cr, &can_retrieve_char_by_name))) < 0)
+ if ((code =
+ renderer_retcode(imemory, I,
+ I->can_retrieve_char_by_name(I, &I->ff, cr,
+ &can_retrieve_char_by_name)))
+ < 0)
return code;
+
if (!can_retrieve_char_by_name) {
/* Translate from char name to encoding used with 3d party font technology : */
ref *Decoding, *char_code;
- if (dict_find_string(osp - 1, "Decoding", &Decoding) > 0 && r_has_type(Decoding, t_dictionary)) {
+
+ if (dict_find_string(osp - 1, "Decoding", &Decoding) > 0
+ && r_has_type(Decoding, t_dictionary)) {
if (dict_find(Decoding, &char_name, &char_code) > 0) {
code = 0;
if (r_has_type(char_code, t_integer)) {
- int_param(char_code, 0xFFFF, &cr.char_codes[0]);
- } else if (r_has_type(char_code, t_array) || r_has_type(char_code, t_shortarray)) {
+ int c_code;
+ int_param(char_code, 0xFFFF, &c_code);
+ cr->char_codes[0] = (gs_glyph)c_code;
+ }
+ else if (r_has_type(char_code, t_array)
+ || r_has_type(char_code, t_shortarray)) {
int i;
ref v;
- cr.char_codes_count = r_size(char_code);
- if (cr.char_codes_count > count_of(cr.char_codes))
+ cr->char_codes_count = r_size(char_code);
+ if (cr->char_codes_count > count_of(cr->char_codes))
code = gs_note_error(e_rangecheck);
if (code >= 0) {
- for (i = 0; i < cr.char_codes_count; i++) {
+ for (i = 0; i < cr->char_codes_count; i++) {
code = array_get(imemory, char_code, i, &v);
if (code < 0)
break;
@@ -2501,18 +2061,21 @@ retry_oversampling:
code = gs_note_error(e_rangecheck);
break;
}
- cr.char_codes[i] = v.value.intval;
+ cr->char_codes[i] = v.value.intval;
}
}
- } else
+ }
+ else {
code = gs_note_error(e_rangecheck);
+ }
if (code < 0) {
char buf[16];
- int l = cr.char_name_length;
+ int l = cr->char_name_length;
- if (l > sizeof(buf) - 1)
+ if (l > sizeof(buf) - 1) {
l = sizeof(buf) - 1;
- memcpy(buf, cr.char_name, l);
+ }
+ memcpy(buf, cr->char_name, l);
buf[l] = 0;
emprintf1(imemory,
"Wrong decoding entry for the character '%s'.\n",
@@ -2523,11 +2086,6 @@ retry_oversampling:
}
}
}
- cr.char_code = cr.char_codes[0];
- cr.client_char_code = client_char_code;
-#if 0 /* Debug purpose only: search chars in UFST fonts. */
- cr.char_code = client_char_code; /* remove for release !!!!!!!!!!!!!!!! */
-#endif
/* Provide glyph data for renderer : */
/* Occasionally, char_name is already a glyph index to pass to the rendering engine
@@ -2537,372 +2095,178 @@ retry_oversampling:
*/
if (!I->ff.is_cid && r_has_type(&char_name, t_name)) {
ref sname;
+
name_string_ref(imemory, &char_name, &sname);
I->ff.char_data = sname.value.const_bytes;
I->ff.char_data_len = r_size(&sname);
- } else if (I->ff.is_type1)
+ }
+ else if (I->ff.is_type1) {
I->ff.char_data = charstring;
+ }
- /* Compute the metrics replacement : */
+ cr->is_glyph_index = is_glyph_index;
+ cr->client_char_code = client_char_code;
- if(bCID && !bIsType1GlyphData) {
- gs_font_cid2 *pfcid = (gs_font_cid2 *)pbfont;
- int MetricsCount = pfcid->cidata.MetricsCount;
+ return (code);
+}
- if (MetricsCount > 0) {
- const byte *data_ptr;
- int l = get_GlyphDirectory_data_ptr(imemory, pdr, cr.char_code, &data_ptr);
- if (MetricsCount == 2 && l >= 4) {
- if (!bVertical0) {
- cr.sb_x = GET_S16_MSB(data_ptr + 2) * scale;
- cr.aw_x = GET_U16_MSB(data_ptr + 0) * scale;
- cr.metrics_type = FAPI_METRICS_REPLACE;
- }
- } else if (l >= 8){
- cr.sb_y = GET_S16_MSB(data_ptr + 2) * scale;
- cr.aw_y = GET_U16_MSB(data_ptr + 0) * scale;
- cr.sb_x = GET_S16_MSB(data_ptr + 6) * scale;
- cr.aw_x = GET_U16_MSB(data_ptr + 4) * scale;
- cr.metrics_type = FAPI_METRICS_REPLACE;
- }
- }
- }
- if (cr.metrics_type != FAPI_METRICS_REPLACE && bVertical) {
- double pwv[4];
- code = zchar_get_metrics2(pbfont, &enc_char_name, pwv);
- if (code < 0)
- return code;
- if (code == metricsNone) {
- if (bCID && (!bIsType1GlyphData && font_file_path)) {
- cr.sb_x = fapi_round(sbw[2] / 2 * scale);
- cr.sb_y = fapi_round(pbfont->FontBBox.q.y * scale);
- cr.aw_y = fapi_round(- pbfont->FontBBox.q.x * scale); /* Sic ! */
- cr.metrics_scale = (bIsType1GlyphData ? 1000 : 1);
- cr.metrics_type = FAPI_METRICS_REPLACE;
- sbw[0] = sbw[2] / 2;
- sbw[1] = pbfont->FontBBox.q.y;
- sbw[2] = 0;
- sbw[3] = - pbfont->FontBBox.q.x; /* Sic ! */
- sbw_state = SBW_DONE;
- } else
- bVertical = false;
- } else {
- cr.sb_x = fapi_round(pwv[2] * scale);
- cr.sb_y = fapi_round(pwv[3] * scale);
- cr.aw_x = fapi_round(pwv[0] * scale);
- cr.aw_y = fapi_round(pwv[1] * scale);
- cr.metrics_scale = (bIsType1GlyphData ? 1000 : 1);
- cr.metrics_type = (code == metricsSideBearingAndWidth ?
- FAPI_METRICS_REPLACE : FAPI_METRICS_REPLACE_WIDTH);
- sbw[0] = pwv[2];
- sbw[1] = pwv[3];
- sbw[2] = pwv[0];
- sbw[3] = pwv[1];
- sbw_state = SBW_DONE;
- }
- }
- if (cr.metrics_type == FAPI_METRICS_NOTDEF && !bVertical) {
- code = zchar_get_metrics(pbfont, &enc_char_name, sbw);
- if (code < 0)
- return code;
- if (code == metricsNone) {
- sbw_state = SBW_FROM_RENDERER;
- if (pbfont->FontType == 2) {
- gs_font_type1 *pfont1 = (gs_font_type1 *)pbfont;
-
- cr.aw_x = export_shift(pfont1->data.defaultWidthX, _fixed_shift - I->frac_shift);
- cr.metrics_scale = 1000;
- cr.metrics_type = FAPI_METRICS_ADD;
+static int
+FAPI_char(i_ctx_t *i_ctx_p, bool bBuildGlyph, ref *charstring)
+{ /* Stack : <font> <code|name> --> - */
+ os_ptr op = osp;
+ ref *pdr = op - 1;
+ ref *v;
+ char *font_file_path = NULL;
+ gs_font *pfont;
+ int code = font_param(osp - 1, &pfont);
+
+ if (code == 0) {
+ gs_font_base *pbfont = (gs_font_base *) pfont;
+ bool bCID = (FAPI_ISCIDFONT(pbfont) || charstring != NULL);
+ int subfont;
+ gs_fapi_server *I = pbfont->FAPI;
+ gs_text_enum_t *penum = op_show_find(i_ctx_p);
+ gs_string char_string, *c_string_p = NULL;
+ gs_string char_name, *c_name_p = NULL;
+ int cindex = -1;
+ ref gname;
+
+ /* initialise the FAPI font, this includes language specific stuff */
+ I->ff = ps_ff_stub;
+
+ if (bBuildGlyph && !bCID) {
+ if (r_type(op) != t_name) {
+ name_enter_string(imemory, ".notdef", op);
}
- } else {
- cr.sb_x = fapi_round(sbw[0] * scale);
- cr.sb_y = fapi_round(sbw[1] * scale);
- cr.aw_x = fapi_round(sbw[2] * scale);
- cr.aw_y = fapi_round(sbw[3] * scale);
- cr.metrics_scale = (bIsType1GlyphData ? 1000 : 1);
- cr.metrics_type = (code == metricsSideBearingAndWidth ?
- FAPI_METRICS_REPLACE : FAPI_METRICS_REPLACE_WIDTH);
- sbw_state = SBW_DONE;
- }
- }
- memset(&metrics, 0x00, sizeof(metrics));
- /* Take metrics from font : */
- if (zchar_show_width_only(penum)) {
- code = I->get_char_width(I, &I->ff, &cr, &metrics);
- /* A VMerror could be a real out of memory, or the glyph being too big for a bitmap
- * so it's worth retrying as an outline glyph
- */
- if (code == e_VMerror && I->use_outline == false) {
- I->max_bitmap = 0;
- I->use_outline = true;
- goto retry_oversampling;
- }
+ check_type(*op, t_name);
- } else if (I->use_outline) {
+ name_string_ref(imemory, op, &gname);
+ c_name_p = &char_name;
+ c_name_p->data = gname.value.bytes;
+ c_name_p->size = r_size(&gname);
- code = I->get_char_outline_metrics(I, &I->ff, &cr, &metrics);
- } else {
-#if 0 /* Debug purpose only. */
- code = e_limitcheck;
-#else
- code = I->get_char_raster_metrics(I, &I->ff, &cr, &metrics);
-#endif
- /* A VMerror could be a real out of memory, or the glyph being too big for a bitmap
- * so it's worth retrying as an outline glyph
- */
- if (code == e_VMerror) {
- I->use_outline = true;
- goto retry_oversampling;
}
+ else {
+ if (bBuildGlyph && pbfont->FontType == ft_CID_TrueType
+ && r_has_type(op, t_name)) {
+ ref *chstrs, *chs;
+
+ /* This logic is lifted from %Type11BuildGlyph in gs_cidfn.ps
+ * Note we only have to deal with mistakenly being given a name object
+ * here, the out of range CID is handled later
+ */
+ if ((dict_find_string(op - 1, "CharStrings", &chstrs)) <= 0) {
+ return_error(e_undefined);
+ }
- if (code == e_limitcheck) {
- if(log2_scale.x > 0 || log2_scale.y > 0) {
- penum_s->fapi_log2_scale.x = log2_scale.x = penum_s->fapi_log2_scale.y = log2_scale.y = 0;
- I->release_char_data(I);
- goto retry_oversampling;
+ if ((dict_find_string(chstrs, ".notdef", &chs)) <= 0) {
+ return_error(e_undefined);
+ }
+ ref_assign_inline(op, chs);
}
- if ((code = renderer_retcode(i_ctx_p, I, I->get_char_outline_metrics(I, &I->ff, &cr, &metrics))) < 0)
- return code;
- }
- }
- /* This handles the situation where a charstring has been replaced with a PS procedure.
- * against the rules, but not *that* rare.
- * It's also something that GS does internally to simulate font styles.
- */
- if (code > 0) {
- os_ptr op = osp;
- ref *proc;
- if ((get_charstring(&I->ff, code - 1, &proc) >= 0) && (r_has_type(proc, t_array) || r_has_type(proc, t_mixedarray))) {
- push(2);
- ref_assign(op - 1, &char_name);
- ref_assign(op, proc);
- return(zchar_exec_char_proc(i_ctx_p));
+ make_null(&gname);
+ check_type(*op, t_integer);
+ int_param(op, 0xFFFF, &cindex);
}
- }
-
- if ((code = renderer_retcode(i_ctx_p, I, code)) < 0)
- return code;
-
- compute_em_scale(pbfont, &metrics, FontMatrix_div, &em_scale_x, &em_scale_y);
- char_bbox.p.x = metrics.bbox_x0 / em_scale_x;
- char_bbox.p.y = metrics.bbox_y0 / em_scale_y;
- char_bbox.q.x = metrics.bbox_x1 / em_scale_x;
- char_bbox.q.y = metrics.bbox_y1 / em_scale_y;
-
- /* We must use the FontBBox, but it seems some buggy fonts have glyphs which extend outside the
- * FontBBox, so we have to do this....
- */
- if (!bCID && pbfont->FontBBox.q.x > pbfont->FontBBox.p.x
- && pbfont->FontBBox.q.y > pbfont->FontBBox.p.y) {
- char_bbox.p.x = min(char_bbox.p.x, pbfont->FontBBox.p.x);
- char_bbox.p.y = min(char_bbox.p.y, pbfont->FontBBox.p.y);
- char_bbox.q.x = max(char_bbox.q.x, pbfont->FontBBox.q.x);
- char_bbox.q.y = max(char_bbox.q.y, pbfont->FontBBox.q.y);
- }
-
- if (pbfont->PaintType != 0) {
- float w = pbfont->StrokeWidth / 2;
-
- char_bbox.p.x -= w;
- char_bbox.p.y -= w;
- char_bbox.q.x += w;
- char_bbox.q.y += w;
- }
- penum_s->fapi_glyph_shift.x = penum_s->fapi_glyph_shift.y = 0;
- if (sbw_state == SBW_FROM_RENDERER) {
- int can_replace_metrics;
-
- if ((code = renderer_retcode(i_ctx_p, I, I->can_replace_metrics(I, &I->ff, &cr, &can_replace_metrics))) < 0)
- return code;
- sbw[2] = metrics.escapement / em_scale_x;
- sbw[3] = metrics.v_escapement / em_scale_y;
- if (pbfont->FontType == 2 && !can_replace_metrics) {
- gs_font_type1 *pfont1 = (gs_font_type1 *)pbfont;
+ if (dict_find_string(pdr, "SubfontId", &v) > 0
+ && r_has_type(v, t_integer))
+ subfont = v->value.intval;
+ else
+ subfont = 0;
- sbw[2] += fixed2float(pfont1->data.nominalWidthX);
+ if (dict_find_string(osp - 1, "Path", &v) > 0
+ && r_has_type(v, t_string)) {
+ font_file_path = ref_to_string(v, imemory, "font file path");
}
- } else if (sbw_state == SBW_SCALE) {
- sbw[0] = (double)cr.sb_x / scale / em_scale_x;
- sbw[1] = (double)cr.sb_y / scale / em_scale_y;
- sbw[2] = (double)cr.aw_x / scale / em_scale_x;
- sbw[3] = (double)cr.aw_y / scale / em_scale_y;
- }
- /* Setup cache and render : */
- if (cr.metrics_type == FAPI_METRICS_REPLACE) {
- /*
- * Here we don't take care of replaced advance width
- * because gs_text_setcachedevice handles it.
- */
- int can_replace_metrics;
-
- if ((code = renderer_retcode(i_ctx_p, I, I->can_replace_metrics(I, &I->ff, &cr, &can_replace_metrics))) < 0)
- return code;
- if (!can_replace_metrics) {
- /*
- * The renderer should replace the lsb, but it can't.
- * To work around we compute a displacement in integral pixels
- * and later shift the bitmap to it. The raster will be inprecise
- * with non-integral pixels shift.
- */
- char_bbox.q.x -= char_bbox.p.x;
- char_bbox.p.x = 0;
- gs_distance_transform((metrics.bbox_x0 / em_scale_x - sbw[0]),
- 0, ctm, &penum_s->fapi_glyph_shift);
- penum_s->fapi_glyph_shift.x *= 1 << log2_scale.x;
- penum_s->fapi_glyph_shift.y *= 1 << log2_scale.y;
+ if (charstring) {
+ c_string_p = &char_string;
+ c_string_p->data = charstring->value.bytes;
+ c_string_p->size = r_size(charstring);
}
- }
- /*
- * We assume that if bMetricsFromGlyphDirectory is true,
- * the font does not specify Metrics[2] and/or CDevProc
- * If someday we meet a font contradicting this assumption,
- * zchar_set_cache to be improved with additional flag,
- * to ignore Metrics[2] and CDevProc.
- *
- * Note that for best quality the result of CDevProc
- * to be passed to I->get_char_raster_metrics, because
- * both raster and metrics depend on replaced lsb.
- * Perhaps in many cases the metrics from font is
- * used as an argument for CDevProc. Only way to resolve
- * is to call I->get_char_raster_metrics twice (before
- * and after CDevProc), or better to split it into
- * smaller functions. Unfortunately UFST cannot retrieve metrics
- * quickly and separately from raster. Only way to resolve is
- * to devide the replaced lsb into 2 parts, which correspond to
- * integral and fractinal pixels, then pass the fractional shift
- * to renderer and apply the integer shift after it.
- *
- * Besides that, we are not sure what to do if a font
- * contains both Metrics[2] and CDevProc. Should
- * CDevProc to be applied to Metrics[2] or to the metrics
- * from glyph code ? Currently we keep a compatibility
- * to the native GS font renderer without a deep analyzis.
- */
-
- if (igs->in_cachedevice == CACHE_DEVICE_CACHING) {
- sbwp = sbw;
- }
- else {
- /* Very occasionally, if we don't do this, setcachedevice2
- * will decide we are cacheing, when we're not, and this
- * causes problems when we get to show_update().
- */
- sbwp = NULL;
-
- if (I->use_outline) {
- /* HACK!!
- * The decision about whether to cache has already been
- * we need to prevent it being made again....
- */
- igs->in_cachedevice = CACHE_DEVICE_NOT_CACHING;
+ code =
+ gs_fapi_do_char(pfont, igs, penum, font_file_path,
+ bBuildGlyph, c_string_p, c_name_p, (gs_char)cindex, (gs_glyph)cindex,
+ subfont);
+ if (font_file_path != NULL) {
+ gs_free_string(imemory, (byte *) font_file_path, r_size(v) + 1,
+ "font file path");
}
- }
-
- if (bCID)
- code = zchar_set_cache(i_ctx_p, pbfont, op,
- NULL, sbw + 2, &char_bbox,
- fapi_finish_render, &exec_cont, sbwp);
- else
- code = zchar_set_cache(i_ctx_p, pbfont, &char_name,
- NULL, sbw + 2, &char_bbox,
- fapi_finish_render, &exec_cont, sbwp);
-
- if (code >= 0 && exec_cont != 0)
- code = (*exec_cont)(i_ctx_p);
- if (code != 0) {
- if (code < 0) {
- /* An error */
- I->release_char_data(I);
- } else {
- /* Callout to CDevProc, zsetcachedevice2, fapi_finish_render. */
+ /* This handles the situation where a charstring has been replaced with a PS procedure.
+ * against the rules, but not *that* rare.
+ * It's also something that GS does internally to simulate font styles.
+ */
+ if (code == gs_error_unregistered) {
+ os_ptr op = osp;
+ ref *proc, gname;
+
+ if (I->ff.is_type1
+ && (get_charstring(&I->ff, cindex, &proc, &gname) >= 0)
+ && (r_has_type(proc, t_array)
+ || r_has_type(proc, t_mixedarray))) {
+ push(2);
+ ref_assign(op - 1, &gname);
+ ref_assign(op, proc);
+ return (zchar_exec_char_proc(i_ctx_p));
+ }
+ else {
+ return_error(e_invalidfont);
+ }
}
}
-
- return code;
-}
-
-static int FAPI_char(i_ctx_t *i_ctx_p, bool bBuildGlyph, ref *charstring)
-{ /* Stack : <font> <code|name> --> - */
- ref *v;
- char *font_file_path = NULL;
- gx_device *dev = gs_currentdevice_inline(igs);
- gs_font *pfont;
- int code = font_param(osp - 1, &pfont);
-
- if (code == 0) {
- gs_font_base *pbfont = (gs_font_base *) pfont;
- if (dict_find_string(osp - 1, "Path", &v) > 0 && r_has_type(v, t_string))
- font_file_path = ref_to_string(v, imemory, "font file path");
- code = FAPI_do_char(i_ctx_p, pbfont, dev, font_file_path, bBuildGlyph, charstring);
- if (font_file_path != NULL)
- gs_free_string(imemory, (byte *)font_file_path, r_size(v) + 1, "font file path");
- }
+ /* We've already imaged teh glyph, pop the operands */
+ if (code == 0)
+ pop(2);
return code;
}
-static int FAPIBuildGlyph9aux(i_ctx_t *i_ctx_p)
+static int
+zFAPIBuildGlyph9(i_ctx_t *i_ctx_p)
{
- os_ptr op = osp; /* <font0> <cid> <font9> <cid> */
+ /* The alghorithm is taken from %Type9BuildGlyph - see gs_cidfn.ps . */
+ os_ptr lop, op = osp;
+ int cid, code;
+ avm_space s = ialloc_space(idmemory);
ref font9 = *pfont_dict(gs_currentfont(igs));
ref *rFDArray, f;
int font_index;
- int code;
+ check_type(op[0], t_integer);
+ check_type(op[-1], t_dictionary);
+ cid = op[0].value.intval;
+ push(2);
+ op[-1] = *pfont_dict(gs_currentfont(igs));
+ op[0] = op[-2]; /* <font0> <cid> <font9> <cid> */
+ ialloc_set_space(idmemory, (r_is_local(op - 3) ? avm_global : avm_local)); /* for ztype9mapcid */
+
+ /* stack: <font0> <cid> <font9> <cid> */
if ((code = ztype9mapcid(i_ctx_p)) < 0)
- return code; /* <font0> <cid> <charstring> <font_index> */
+ return code; /* <font0> <cid> <charstring> <font_index> */
/* fixme: what happens if the charstring is absent ?
Can FDArray contain 'null' (see %Type9BuildGlyph in gs_cidfn.ps)? */
font_index = op[0].value.intval;
- if (dict_find_string(&font9, "FDArray", &rFDArray) <= 0 || r_type(rFDArray) != t_array)
+ if (dict_find_string(&font9, "FDArray", &rFDArray) <= 0
+ || r_type(rFDArray) != t_array)
return_error(e_invalidfont);
- if(array_get(imemory, rFDArray, font_index, &f) < 0 || r_type(&f) != t_dictionary)
+ if (array_get(imemory, rFDArray, font_index, &f) < 0
+ || r_type(&f) != t_dictionary)
return_error(e_invalidfont);
+
op[0] = op[-2];
- op[-2] = op[-1]; /* Keep the charstring on ostack for the garbager. */
- op[-1] = f; /* <font0> <charstring> <subfont> <cid> */
+ op[-2] = op[-1]; /* Keep the charstring on ostack for the garbager. */
+ op[-1] = f; /* <font0> <charstring> <subfont> <cid> */
if ((code = FAPI_char(i_ctx_p, true, op - 2)) < 0)
return code;
- /* <font0> <charstring> */
- return code;
-}
-
-/* <font> <code> .FAPIBuildChar - */
-static int zFAPIBuildChar(i_ctx_t *i_ctx_p)
-{
- return FAPI_char(i_ctx_p, false, NULL);
-}
-
-/* non-CID : <font> <code> .FAPIBuildGlyph - */
-/* CID : <font> <name> .FAPIBuildGlyph - */
-static int zFAPIBuildGlyph(i_ctx_t *i_ctx_p)
-{
- return FAPI_char(i_ctx_p, true, NULL);
-}
+ /* stack: <font0> <charstring> */
-/* <font> <cid> .FAPIBuildGlyph9 - */
-static int zFAPIBuildGlyph9(i_ctx_t *i_ctx_p)
-{
- /* The alghorithm is taken from %Type9BuildGlyph - see gs_cidfn.ps . */
- os_ptr lop, op = osp;
- int cid, code;
- avm_space s = ialloc_space(idmemory);
-
- check_type(op[ 0], t_integer);
- check_type(op[-1], t_dictionary);
- cid = op[0].value.intval;
- push(2);
- op[-1] = *pfont_dict(gs_currentfont(igs));
- op[0] = op[-2]; /* <font0> <cid> <font9> <cid> */
- ialloc_set_space(idmemory, (r_is_local(op - 3) ? avm_global : avm_local)); /* for ztype9mapcid */
- code = FAPIBuildGlyph9aux(i_ctx_p);
lop = osp;
if (code == 5) {
int i, ind = (lop - op);
+
op = osp;
for (i = ind; i >= 0; i--) {
@@ -2910,146 +2274,128 @@ static int zFAPIBuildGlyph9(i_ctx_t *i_ctx_p)
}
pop(2);
}
- else if (code < 0) { /* <font0> <dirty> <dirty> <dirty> */
+ else if (code < 0) { /* <font0> <dirty> <dirty> <dirty> */
/* Adjust ostack for the correct error handling : */
make_int(op - 2, cid);
- pop(2); /* <font0> <cid> */
- } else if (code != 5) { /* <font0> <dirty> */
-
-
- pop(2); /* */
+ pop(2); /* <font0> <cid> */
+ }
+ else if (code != 5) { /* <font0> <dirty> */
+
+
+ pop(2); /* */
/* Note that this releases the charstring, and it may be garbage-collected
- before the interpreter calls fapi_finish_render. This requires the server
- to keep glyph raster internally between calls to get_char_raster_metrics
- and get_char_raster. Perhaps UFST cannot provide metrics without
- building a raster, so this constraint actually goes from UFST.
- */
+ before the interpreter calls fapi_finish_render. This requires the server
+ to keep glyph raster internally between calls to get_char_raster_metrics
+ and get_char_raster. Perhaps UFST cannot provide metrics without
+ building a raster, so this constraint actually goes from UFST.
+ */
}
ialloc_set_space(idmemory, s);
return code;
}
-static int do_FAPIpassfont(i_ctx_t *i_ctx_p, char *font_file_path, bool *success)
-{ ref *pdr = osp; /* font dict */
+/* <font> <code> .FAPIBuildChar - */
+static int
+zFAPIBuildChar(i_ctx_t *i_ctx_p)
+{
+ return FAPI_char(i_ctx_p, false, NULL);
+}
+
+/* non-CID : <font> <code> .FAPIBuildGlyph - */
+/* CID : <font> <name> .FAPIBuildGlyph - */
+static int
+zFAPIBuildGlyph(i_ctx_t *i_ctx_p)
+{
+ return FAPI_char(i_ctx_p, true, NULL);
+}
+
+
+/* <font_dict> .FAPIpassfont bool <font_dict> */
+/* must insert /FAPI to font dictionary */
+static int
+zFAPIpassfont(i_ctx_t *i_ctx_p)
+{
+ os_ptr op = osp;
gs_font *pfont;
- int code = font_param(osp, &pfont);
- gs_font_base *pbfont;
- int BBox[4];
- i_plugin_holder *h = i_plugin_get_list(i_ctx_p);
+ int code;
+ char *font_file_path = NULL;
+ ref *v;
char *xlatmap = NULL;
- FAPI_font_scale font_scale = {{1, 0, 0, 1, 0, 0}, {0, 0}, {1, 1}, true};
- const char *decodingID = NULL;
- ref *req, reqstr;
- bool do_restart = false;
+ char *fapi_request = NULL;
+ char *fapi_id = NULL;
+ ref reqstr;
+ int subfont;
+
+ /* Normally embedded fonts have no Path, but if a CID font is
+ * emulated with a TT font, and it is hooked with FAPI,
+ * the path presents and is neccessary to access the full font data.
+ */
+ check_type(*op, t_dictionary);
+ code = font_param(osp, &pfont);
if (code < 0)
return code;
+
+ if (dict_find_string(op, "SubfontId", &v) >= 0
+ && r_has_type(v, t_integer))
+ subfont = v->value.intval;
+ else
+ subfont = 0;
+
code = FAPI_get_xlatmap(i_ctx_p, &xlatmap); /* Useful for emulated fonts hooked with FAPI. */
if (code < 0)
return code;
- pbfont = (gs_font_base *)pfont;
-
- *success = false;
/* If the font dictionary contains a FAPIPlugInReq key, the the PS world wants us
* to try to use a specific FAPI plugin, so find it, and try it....
*/
- if (dict_find_string(pdr, "FAPIPlugInReq", &req) >= 0 && r_type(req) == t_name) {
- char *fapi_request;
- name_string_ref (imemory, req, &reqstr);
+ if (dict_find_string(op, "FAPIPlugInReq", &v) >= 0 && r_type(v) == t_name) {
- fapi_request = ref_to_string(&reqstr, imemory, "FAPI_do_char");
- if (fapi_request) {
- dmprintf1(imemory, "Requested FAPI plugin: %s ", fapi_request);
+ name_string_ref(imemory, v, &reqstr);
- while (h && (strncmp(h->I->d->type, "FAPI", 4) != 0 || strncmp(h->I->d->subtype, fapi_request, strlen(fapi_request)) != 0)) {
- h = h->next;
- }
- if (!h) {
- dmprintf(imemory, "not found. Falling back to normal plugin search\n");
- h = i_plugin_get_list(i_ctx_p);
- }
- else {
- dmprintf(imemory, "found.\n");
- do_restart = true;
- }
- gs_free_string(imemory, (byte *)fapi_request, strlen(fapi_request) + 1, "do_FAPIpassfont");
- }
+ fapi_request = ref_to_string(&reqstr, imemory, "zFAPIpassfont");
}
- while (h) {
- ref FAPI_ID;
- FAPI_server *I;
- const byte *server_param = NULL;
- int server_param_size = 0;
-
- if (!strcmp(h->I->d->type, "FAPI")) {
- I = (FAPI_server *)h->I;
- get_server_param(i_ctx_p, I->ig.d->subtype, &server_param, &server_param_size);
- if ((code = renderer_retcode(i_ctx_p, I, I->ensure_open(I, server_param, server_param_size))) < 0)
- return code;
- font_scale.HWResolution[0] = font_scale.HWResolution[1] = 72 << I->frac_shift;
- font_scale.matrix[0] = font_scale.matrix[3] = 1 << I->frac_shift;
+ if (dict_find_string(op, "Path", &v) > 0 && r_has_type(v, t_string))
+ font_file_path = ref_to_string(v, imemory_global, "font file path");
- pbfont->FAPI = I; /* we need the FAPI server during this stage */
- code = FAPI_prepare_font(i_ctx_p, I, pdr, pbfont, font_file_path, &font_scale, xlatmap, BBox, &decodingID);
- if (code >= 0) {
- if ((code = name_ref(imemory, (const byte *)I->ig.d->subtype, strlen(I->ig.d->subtype), &FAPI_ID, false)) < 0)
- return code;
- if ((code = dict_put_string(pdr, "FAPI", &FAPI_ID, NULL)) < 0)
- return code; /* Insert FAPI entry to font dictionary. */
- *success = true;
- return 0;
- }
- }
- /* renderer failed, continue search */
- pbfont->FAPI = NULL;
- if (do_restart == true) {
- dmprintf1(imemory, "Requested FAPI plugin %s failed, searching for alternative plugin\n", h->I->d->subtype);
- h = i_plugin_get_list(i_ctx_p);
- do_restart = false;
- }
- else {
- h = h->next;
- }
- }
- /* Could not find renderer, return with false success. */
- return 0;
-}
+ gs_fapi_set_servers_client_data(imemory, &ps_ff_stub, i_ctx_p);
-/* <font_dict> .FAPIpassfont bool <font_dict> */
-/* must insert /FAPI to font dictionary */
-/* This operator must not be called with devices which embed fonts. */
-static int zFAPIpassfont(i_ctx_t *i_ctx_p)
-{ os_ptr op = osp;
- int code;
- bool found = false;
- char *font_file_path = NULL;
- ref *v;
+ code =
+ gs_fapi_passfont(pfont, subfont, font_file_path, NULL, fapi_request, xlatmap,
+ &fapi_id, (gs_fapi_get_server_param_callback)ps_get_server_param);
- /* Normally embedded fonts have no Path, but if a CID font is
- * emulated with a TT font, and it is hooked with FAPI,
- * the path presents and is neccessary to access the full font data.
- */
- check_type(*op, t_dictionary);
- if (dict_find_string(op, "Path", &v) > 0 && r_has_type(v, t_string))
- font_file_path = ref_to_string(v, imemory_global, "font file path");
- code = do_FAPIpassfont(i_ctx_p, font_file_path, &found);
if (font_file_path != NULL)
- gs_free_string(imemory_global, (byte *)font_file_path, r_size(v) + 1, "font file path");
- if(code != 0)
+ gs_free_string(imemory_global, (byte *) font_file_path, r_size(v) + 1,
+ "font file path");
+
+ if (fapi_request != NULL)
+ gs_free_string(imemory, (byte *) fapi_request,
+ strlen(fapi_request) + 1, "do_FAPIpassfont");
+ if (code != 0)
return code;
+
+ if (code >= 0 && fapi_id != NULL) {
+ ref FAPI_ID;
+
+ if ((code =
+ name_ref(imemory, (const byte *)fapi_id,
+ strlen(fapi_id), &FAPI_ID, false)) < 0)
+ return code;
+ if ((code = dict_put_string(op, "FAPI", &FAPI_ID, NULL)) < 0)
+ return code; /* Insert FAPI entry to font dictionary. */
+ }
push(1);
- make_bool(op, found);
+ make_bool(op, (fapi_id != NULL));
return 0;
}
-const op_def zfapi_op_defs[] =
-{ {"2.FAPIavailable", zFAPIavailable},
- {"2.FAPIpassfont", zFAPIpassfont},
+const op_def zfapi_op_defs[] = {
+ {"1.FAPIavailable", zFAPIavailable},
+ {"2.FAPIpassfont", zFAPIpassfont},
{"2.FAPIrebuildfont", zFAPIrebuildfont},
- {"2.FAPIBuildChar", zFAPIBuildChar},
- {"2.FAPIBuildGlyph", zFAPIBuildGlyph},
+ {"2.FAPIBuildChar", zFAPIBuildChar},
+ {"2.FAPIBuildGlyph", zFAPIBuildGlyph},
{"2.FAPIBuildGlyph9", zFAPIBuildGlyph9},
op_def_end(0)
};
diff --git a/language_switch/pspcl6_gcc.mak b/language_switch/pspcl6_gcc.mak
index c6a75a59a..9380b60d9 100644
--- a/language_switch/pspcl6_gcc.mak
+++ b/language_switch/pspcl6_gcc.mak
@@ -83,8 +83,7 @@ FEATURE_DEVS ?= \
$(DD)htxlib.dev \
$(DD)ttfont.dev \
$(DD)pipe.dev \
- $(DD)gsnogc.dev \
- $(DD)fapi.dev
+ $(DD)gsnogc.dev
# extra objects.
XOBJS?=$(GLOBJDIR)/gsargs.o $(GLOBJDIR)/gconfig.o \
diff --git a/main/pcl6_msvc.mak b/main/pcl6_msvc.mak
index f5e9f7440..49d0beda8 100644
--- a/main/pcl6_msvc.mak
+++ b/main/pcl6_msvc.mak
@@ -132,7 +132,7 @@ PNGCCFLAGS=-DPNG_USER_MEM_SUPPORTED
SHARE_LIBPNG=0
!endif
-# Specify the location of lcms
+# Specify the location of g
!ifndef LCMSSRCDIR
LCMSSRCDIR=..\gs\lcms
!endif
@@ -258,6 +258,37 @@ SVGOBJDIR=$(GENDIR)
SBRDIR=$(GENDIR)
!endif
+!ifndef FT_BRIDGE
+FT_BRIDGE=1
+!endif
+
+SHARE_FT=0
+FTSRCDIR=$(GLSRCDIR)/../freetype
+FT_CFLAGS=-I$(GLSRCDIR)/../freetype/include
+FT_LIBS=
+FT_CONFIG_SYSTEM_ZLIB=
+
+
+# Define whether to compile in UFST. Note that freetype will/must be disabled.
+# FAPI/UFST depends on UFST_BRIDGE being undefined - hence the construct below.
+# (i.e. use "UFST_BRIDGE=1" or *not to define UFST_BRIDGE to anything*)
+!ifndef UFST_BRIDGE
+UFST_BRIDGE=
+!endif
+UFST_ROOT=$(GLSRCDIR)/../ufst
+UFST_LIB_EXT=.a
+
+UFST_ROMFS_ARGS=-b \
+ -P $(UFST_ROOT)/fontdata/mtfonts/pcl45/mt3/ -d fontdata/mtfonts/pcl45/mt3/ pcl___xj.fco plug__xi.fco wd____xh.fco \
+ -P $(UFST_ROOT)/fontdata/mtfonts/pclps2/mt3/ -d fontdata/mtfonts/pclps2/mt3/ pclp2_xj.fco \
+ -c -P $(PSSRCDIR)/../lib/ -d Resource/Init/ FAPIconfig-FCO
+
+UFSTROMFONTDIR=\"%rom%fontdata/\"
+UFSTDISCFONTDIR=\"$(UFST_ROOT)/fontdata/\"
+
+
+UFST_CFLAGS=-DGCCx86
+
# Language and configuration. These are actually platform-independent,
# but we define them here just to keep all parameters in one place.
!ifndef TARGET_DEVS
@@ -311,58 +342,6 @@ PCL_FONT_SCALER=$(PL_SCALER)
PXL_FONT_SCALER=$(PL_SCALER)
!endif
-# flags for UFST scaler.
-!if "$(PL_SCALER)" == "ufst"
-
-!ifndef UFST_ROOT
-UFST_ROOT=..\ufst
-!endif
-
-UFST_BRIDGE=1
-
-!ifndef UFST_LIB_EXT
-UFST_LIB_EXT=.lib
-!endif
-
-!ifndef UFST_LIB
-UFST_LIB=$(UFST_ROOT)\rts\lib\
-!endif
-
-!ifndef UFST_CFLAGS
-UFST_CFLAGS= -DUFST_BRIDGE=$(UFST_BRIDGE) -DUFST_LIB_EXT=$(UFST_LIB_EXT) -DMSVC -DUFST_ROOT=$(UFST_ROOT)
-!endif
-
-!ifndef UFST_INCLUDES
-UFST_INCLUDES=$(I_)$(UFST_ROOT)\rts\inc $(I_)$(UFST_ROOT)\sys\inc $(I_)$(UFST_ROOT)\rts\fco $(I_)$(UFST_ROOT)\rts\gray $(I_)$(UFST_ROOT)\rts\tt -DAGFA_FONT_TABLE
-!endif
-
-!if "$(BUNDLE_FONTS)" == "1"
-
-!ifndef UFST_ROMFS_ARGS
-UFST_ROMFS_ARGS=-b \
--P $(UFST_ROOT)/fontdata/mtfonts/pcl45/mt3/ -d fontdata/mtfonts/pcl45/mt3/ pcl___xj.fco plug__xi.fco wd____xh.fco \
--P $(UFST_ROOT)/fontdata/mtfonts/pclps2/mt3/ -d fontdata/mtfonts/pclps2/mt3/ pclp2_xj.fco \
--c -P $(PSSRCDIR)/../lib/ -d Resource/Init/ FAPIconfig-FCO
-!endif
-!ifndef UFSTFONTDIR
-UFSTFONTDIR=%rom%fontdata/
-!endif
-
-!else
-
-!ifndef UFSTFONTDIR
-UFSTFONTDIR=/usr/local/fontdata5.0/
-!endif
-
-!endif
-
-!ifndef EXTRALIBS
-EXTRALIBS= $(UFST_LIB)if_lib.lib $(UFST_LIB)fco_lib.lib $(UFST_LIB)tt_lib.lib $(UFST_LIB)if_lib.lib
-!endif
-
-!endif
-# end PL_SCALER == ufst
-
# flags for artifex scaler
!if "$(PL_SCALER)" == "afs"
# The mkromfs arguments for including the PCL fonts if COMPILE_INITS=1
diff --git a/pcl/pcfontpg.c b/pcl/pcfontpg.c
index 2379813c4..9354b5f91 100644
--- a/pcl/pcfontpg.c
+++ b/pcl/pcfontpg.c
@@ -23,7 +23,11 @@
#include "pcstate.h"
#include "pcursor.h"
#include "pcommand.h"
+
+#define fontnames(agfascreenfontname, agfaname, urwname) urwname
#include "plftable.h"
+#undef fontnames
+
#include "pllfont.h"
/* utility procedure to print n blank lines */
diff --git a/pcl/pcfsel.c b/pcl/pcfsel.c
index 7b689ce78..7cb3ce051 100644
--- a/pcl/pcfsel.c
+++ b/pcl/pcfsel.c
@@ -84,8 +84,38 @@ dmprint_font_params_t(const gs_memory_t *mem, const pl_font_params_t *pfp)
#include "plftable.h"
static void
+dmprint_ufst_font_name(const gs_memory_t *mem, const pl_font_t *pfont)
+{
+#define fontnames(agfascreenfontname, agfaname, urwname) agfaname
+#include "plftable.h"
+ int i;
+ bool found = false;
+
+ for (i = 0; strlen(resident_table[i].full_font_name); i++) {
+ if (!memcmp(&resident_table[i].params,
+ &pfont->params, sizeof(pfont->params))) {
+
+ found = true;
+ break;
+ }
+ }
+ if (found) {
+ dmprintf1(mem, "%s ", resident_table[i].full_font_name);
+ } else {
+ if (pfont->storage == pcds_internal) {
+ dmprintf(mem, "internal font not found in resident table");
+ dmprintf1(mem, "%s\n", pfont->font_file);
+ }
+ dmprintf(mem, "external font ");
+ }
+#undef fontnames
+}
+
+static void
dmprint_font_name(const gs_memory_t *mem, const pl_font_t *pfont)
{
+#define fontnames(agfascreenfontname, agfaname, urwname) urwname
+#include "plftable.h"
int i;
bool found = false;
@@ -106,14 +136,19 @@ dmprint_font_name(const gs_memory_t *mem, const pl_font_t *pfont)
}
dmprintf(mem, "external font ");
}
+#undef fontnames
}
static void
dmprint_font_t(const gs_memory_t *mem, const pl_font_t *pfont)
{
- dmprint_font_name(mem, pfont);
+ if (pfont->scaling_technology == plfst_MicroType)
+ dmprint_ufst_font_name(mem, pfont);
+ else
+ dmprint_font_name(mem, pfont);
+
dmprintf3(mem, "storage=%d scaling=%d type=%d ",
- pfont->storage, pfont->scaling_technology, pfont->font_type);
+ pfont->storage, pfont->scaling_technology, pfont->font_type);
dmprint_cc(mem, pfont->character_complement);
dmputs(mem, ";\n ");
dmprint_font_params_t(mem, &pfont->params);
diff --git a/pcl/pcl.mak b/pcl/pcl.mak
index 81b998e7b..1a08b44b4 100644
--- a/pcl/pcl.mak
+++ b/pcl/pcl.mak
@@ -820,7 +820,8 @@ $(PCLOBJ)pcsfont.$(OBJ): $(PCLSRC)pcsfont.c \
$(gsmatrix_h) \
$(gsutil_h) \
$(gxfont_h) \
- $(gxfont42_h)
+ $(gxfont42_h) \
+ $(plfapi_h)
$(PCLCCC) $(PCLSRC)pcsfont.c $(PCLO_)pcsfont.$(OBJ)
# Chapter 12
diff --git a/pcl/pcsfont.c b/pcl/pcsfont.c
index 218359859..2093e7b87 100644
--- a/pcl/pcsfont.c
+++ b/pcl/pcsfont.c
@@ -32,6 +32,8 @@
#include "plvalue.h"
#include "plmain.h" /* for high_level_device...
hopefully this will go away soon */
+#include "plfapi.h"
+
#include "gsbitops.h"
#include "gsccode.h"
#include "gsmatrix.h"
@@ -365,6 +367,7 @@ bitmap: pfont = gs_alloc_struct(mem, gs_font_base, &st_gs_font_base,
}
case plfst_TrueType:
{
+
gs_font_type42 *pfont;
{ static const pl_font_offset_errors_t errors = {
gs_error_invalidfont, 0
@@ -442,7 +445,15 @@ bitmap: pfont = gs_alloc_struct(mem, gs_font_base, &st_gs_font_base,
pl_dict_put(&pcs->soft_fonts, current_font_id,
current_font_id_size, plfont);
plfont->pfont->procs.define_font = gs_no_define_font;
- return gs_definefont(pcs->font_dir, plfont->pfont);
+
+ if ((code = gs_definefont(pcs->font_dir, plfont->pfont)) != 0) {
+ return(code);
+ }
+
+ if (plfont->scaling_technology == plfst_TrueType)
+ code = pl_fapi_passfont(plfont, 0, NULL, NULL, NULL, 0);
+
+ return(code);
}
static int /* ESC * c <char_code> E */
diff --git a/pl/pl.mak b/pl/pl.mak
index b13221a48..b6d146e01 100644
--- a/pl/pl.mak
+++ b/pl/pl.mak
@@ -121,6 +121,7 @@ $(PLOBJ)pjl.dev: $(PL_MAK) $(ECHOGS_XE) $(pjl_obj)
pldebug_h=$(PLSRC)pldebug.h
pldict_h=$(PLSRC)pldict.h
pldraw_h=$(PLSRC)pldraw.h $(gsiparam_h)
+plfapi_h=$(PLSRC)plfapi.h
pllfont_h=$(PLSRC)pllfont.h
plmain_h=$(PLSRC)plmain.h $(gsargs_h) $(gsgc_h)
plplatf_h=$(PLSRC)plplatf.h
@@ -180,9 +181,16 @@ $(PLOBJ)plfont.$(OBJ): $(PLSRC)plfont.c $(AK) $(memory__h) $(stdio__h)\
$(gschar_h) $(gserrors_h) $(gsmatrix_h) $(gsmemory_h)\
$(gsstate_h) $(gsstruct_h) $(gsmatrix_h) $(gstypes_h) $(gsutil_h)\
$(gsimage_h) $(gxfont_h) $(gxfont42_h) $(gzstate_h)\
- $(gxfache_h) $(plfont_h) $(plvalue_h) $(plchar_h)
+ $(gxfache_h) $(plfont_h) $(plvalue_h) $(plchar_h) \
+ $(plfapi_h)
$(PLCCC) $(PLSRC)plfont.c $(PLO_)plfont.$(OBJ)
+$(PLOBJ)plfapi.$(OBJ): $(PLSRC)plfapi.c $(plfapi_h) $(gxfapi_h) $(memory__h) \
+ $(gsmemory_h) $(gserrors_h) $(gxdevice_h) $(gxfont_h) $(gzstate_h) \
+ $(gxchar_h) $(gdebug_h) $(plfont_h) $(gxfapi_h) $(plchar_h) \
+ $(gsimage_h) $(gspath_h)
+ $(PLCCC) $(PLSRC)plfapi.c $(PLO_)plfapi.$(OBJ)
+
#ufst font module.
$(PLOBJ)plufont.$(OBJ): $(PLSRC)plufont.c $(AK) $(memory__h) $(stdio__h)\
$(gdebug_h)\
@@ -252,7 +260,8 @@ $(PLOBJ)pllfont.$(OBJ): $(PLSRC)pllfont.c $(pllfont_h) $(AK)\
$(ctype__h) $(stdio__h) $(string__h) $(strmio_h) $(stream_h)\
$(gx_h) $(gp_h) $(gsccode_h) $(gserrors_h) $(gsmatrix_h) $(gsutil_h)\
$(gxfont_h) $(gxfont42_h) $(gxiodev_h) \
- $(plfont_h) $(pldict_h) $(plvalue_h) $(plftable_h)
+ $(plfont_h) $(pldict_h) $(plvalue_h) $(plftable_h) $(plfapi_h) \
+ $(gxfapi_h) $(plufstlp_h) $(plvocab_h)
$(PLCCC) $(PLSRC)pllfont.c $(PLO_)pllfont.$(OBJ)
pl_obj1=$(PLOBJ)pldict.$(OBJ) $(PLOBJ)pldraw.$(OBJ) $(PLOBJ)plsymbol.$(OBJ) $(PLOBJ)plvalue.$(OBJ) $(PLOBJ)plht.$(OBJ) $(PLOBJ)plsrgb.$(OBJ)
@@ -280,6 +289,19 @@ $(PLOBJ)afs.dev: $(PL_MAK) $(ECHOGS_XE) $(afs_obj)
$(PLOBJ)ufst.dev: $(PL_MAK) $(ECHOGS_XE) $(ufst_obj)
$(SETMOD) $(PLOBJ)ufst $(ufst_obj)
+plufstlp_h=$(PLSRC)plufstlp.h $(studio__h) $(string__h) $(gsmemory_h) \
+ $(gstypes_h)
+
+$(PLOBJ)plufstlp1.$(OBJ): $(PLSRC)plufstlp1.c $(plufstlp_h)
+ $(PLCCC) $(UFST_CFLAGS) $(I_)$(UFST_ROOT)$(D)rts$(D)inc$(_I) $(PLSRC)plufstlp1.c $(PLO_)plufstlp1.$(OBJ)
+
+$(PLOBJ)plufstlp.$(OBJ): $(PLSRC)plufstlp.c $(plufstlp_h)
+ $(PLCCC) $(PLSRC)plufstlp.c $(PLO_)plufstlp.$(OBJ)
+
+fapi_objs=$(PLOBJ)plfapi.$(OBJ)
+$(PLOBJ)fapi_pl.dev: $(PL_MAK) $(ECHOGS_XE) $(fapi_objs)
+ $(SETMOD) $(PLOBJ)fapi_pl $(fapi_objs)
+
### BROKEN #####
# Bitstream font device
@@ -287,11 +309,14 @@ $(PLOBJ)bfs.dev: $(PL_MAK) $(ECHOGS_XE) $(pl_obj1) $(pl_obj2)
$(SETMOD) $(PLOBJ)bfs $(pl_obj1) $(pl_obj2)
### END BROKEN ###
-$(PLOBJ)pl.dev: $(PL_MAK) $(ECHOGS_XE) $(pl_obj)
+$(PLOBJ)pl.dev: $(PL_MAK) $(ECHOGS_XE) $(pl_obj) $(PLOBJ)fapi_pl.dev \
+ $(PLOBJ)plufstlp$(UFST_BRIDGE).$(OBJ)
$(SETMOD) $(PLOBJ)pl $(pl_obj1)
$(ADDMOD) $(PLOBJ)pl $(pl_obj2)
$(ADDMOD) $(PLOBJ)pl $(pl_obj3)
- $(ADDMOD) $(PLOBJ)pl -include $(PLOBJ)$(PL_SCALER)
+ $(ADDMOD) $(PLOBJ)pl $(PLOBJ)plufstlp$(UFST_BRIDGE).$(OBJ)
+ $(ADDMOD) $(PLOBJ)pl -include $(PLOBJ)fapi_pl.dev
+ $(ADDMOD) $(PLOBJ)pl -include $(PLOBJ)$(PL_SCALER)
###### Command-line driver's main program #####
diff --git a/pl/plchar.c b/pl/plchar.c
index 9e3444c3c..51278b4d2 100644
--- a/pl/plchar.c
+++ b/pl/plchar.c
@@ -505,7 +505,7 @@ pl_tt_string_proc(gs_font_type42 *pfont, ulong offset, uint length, const byte *
/* Return the vertical substitute for a glyph, if it has one; */
/* otherwise return gs_no_glyph. */
-static gs_glyph
+gs_glyph
pl_font_vertical_glyph(gs_glyph glyph, const pl_font_t *plfont)
{ long VT = plfont->offsets.VT;
const byte *vtseg;
@@ -846,7 +846,7 @@ pl_font_galley_character(gs_char chr, const pl_font_t *plfont)
/* Encode a character for a TrueType font. */
/* What we actually return is the TT glyph index. Note that */
/* we may return either gs_no_glyph or 0 for an undefined character. */
-static gs_glyph
+gs_glyph
pl_tt_encode_char(gs_font *pfont_generic, gs_char chr, gs_glyph_space_t not_used)
{
gs_font_type42 *pfont = (gs_font_type42 *)pfont_generic;
diff --git a/pl/plchar.h b/pl/plchar.h
index c1d7bea8b..a1d196547 100644
--- a/pl/plchar.h
+++ b/pl/plchar.h
@@ -29,4 +29,13 @@ int pl_tt_get_outline(gs_font_type42 *pfont, uint index, gs_glyph_data_t *pdata)
ulong tt_find_table(gs_font_type42 *pfont, const char *tname, uint *plen);
+gs_glyph
+pl_tt_encode_char(gs_font *pfont_generic, gs_char chr, gs_glyph_space_t not_used);
+
+gs_glyph
+pl_font_vertical_glyph(gs_glyph glyph, const pl_font_t *plfont);
+
+int
+pl_tt_get_outline(gs_font_type42 *pfont, uint index, gs_glyph_data_t *pdata);
+
#endif /* plchar_INCLUDED */
diff --git a/pl/plfapi.c b/pl/plfapi.c
new file mode 100644
index 000000000..19f07d9cd
--- /dev/null
+++ b/pl/plfapi.c
@@ -0,0 +1,572 @@
+/* Copyright (C) 2001-2012 Artifex Software, Inc.
+ All Rights Reserved.
+
+ This software is provided AS-IS with no warranty, either express or
+ implied.
+
+ This software is distributed under license and may not be copied, modified
+ or distributed except as expressly authorized under the terms of that
+ license. Refer to licensing information at http://www.artifex.com/
+ or contact Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134,
+ San Rafael, CA 94903, U.S.A., +1(415)492-9861, for further information.
+*/
+
+/* Font API support */
+
+#include "memory_.h"
+#include "gsmemory.h"
+#include "gserrors.h"
+#include "gxdevice.h"
+#include "gxfont.h"
+#include "gzstate.h"
+#include "gxchar.h" /* for st_gs_show_enum */
+#include "gdebug.h"
+#include "gxfapi.h"
+#include "gscoord.h"
+#include "gsimage.h" /* for gs_image_enum for plchar.h */
+#include "gspath.h"
+
+#include "plfont.h"
+#include "plchar.h"
+#include "plfapi.h"
+
+/* defaults for locations of font collection objects (fco's) and
+ plugins the root data directory. These are internally separated with
+ ':' but environment variable use the gp separator */
+
+#ifndef UFSTFONTDIR
+#if 0
+static const char *UFSTFONTDIR = "/usr/local/fontdata5.0/"; /* A bogus linux location */
+#endif
+static const char *UFSTFONTDIR = ""; /* A bogus linux location */
+#endif
+
+/* default list of fcos and plugins - relative to UFSTFONTDIR */
+static const char *UFSTFCOS =
+ "%rom%fontdata/mtfonts/pclps2/mt3/pclp2_xj.fco:%rom%fontdata/mtfonts/pcl45/mt3/wd____xh.fco";
+static const char *UFSTPLUGINS =
+ "%rom%fontdata/mtfonts/pcl45/mt3/plug__xi.fco";
+
+static const char *UFSTDIRPARM = "UFST_SSdir=";
+static const char *UFSTPLUGINPARM = "UFST_PlugIn=";
+extern const char gp_file_name_list_separator;
+
+/* forward declarations for the pl_ff_stub definition */
+static ulong
+pl_fapi_get_long(gs_fapi_font *ff, gs_fapi_font_feature var_id, int index);
+
+static int
+pl_fapi_get_cid (gs_font_base *pbfont, gs_string *charstring, gs_string *name,
+ int ccode, gs_string *enc_char_name,char *font_file_path,
+ gs_fapi_char_ref *cr, bool bCID);
+
+static int
+pl_fapi_get_glyph(gs_fapi_font *ff, int char_code, byte *buf,
+ ushort buf_length);
+
+static ushort
+pl_fapi_serialize_tt_font(gs_fapi_font *ff, void *buf, int buf_size);
+
+static int
+pl_get_glyphdirectory_data(gs_fapi_font *ff, int char_code,
+ const byte **ptr);
+
+static int
+pl_fapi_set_cache(gs_text_enum_t *penum, const gs_font_base *pbfont,
+ const gs_string *char_name, int cid,
+ const double pwidth[2], const gs_rect *pbbox,
+ const double Metrics2_sbw_default[4], bool *imagenow);
+
+static int
+pl_fapi_get_metrics(gs_fapi_font *ff, gs_string *char_name, int cid,
+ double *m, bool vertical);
+
+static const gs_fapi_font pl_ff_stub = {
+ 0, /* server_font_data */
+ 0, /* need_decrypt */
+ NULL, /* const gs_memory_t */
+ 0, /* font_file_path */
+ 0, /* full_font_buf */
+ 0, /* full_font_buf_len */
+ 0, /* subfont */
+ false, /* is_type1 */
+ false, /* is_cid */
+ false, /* is_outline_font */
+ false, /* is_mtx_skipped */
+ false, /* is_vertical */
+ {{3,10}, {3,1},{-1,-1},{-1,-1}, {-1,-1}}, /* ttf_cmap_req */
+ 0, /* client_ctx_p */
+ 0, /* client_font_data */
+ 0, /* client_font_data2 */
+ 0, /* char_data */
+ 0, /* char_data_len */
+ 0, /* embolden */
+ NULL, /* get_word */
+ pl_fapi_get_long, /* get_long */
+ NULL, /* get_float */
+ NULL, /* get_name */
+ NULL, /* get_proc */
+ NULL, /* get_gsubr */
+ NULL, /* get_subr */
+ NULL, /* get_raw_subr */
+ pl_fapi_get_glyph, /* get_glyph */
+ pl_fapi_serialize_tt_font, /* serialize_tt_font */
+ NULL, /* get_charstring */
+ NULL, /* get_charstring_name */
+ pl_get_glyphdirectory_data, /* get_GlyphDirectory_data_ptr */
+ pl_fapi_get_cid, /* get_glyphname_or_cid */
+ pl_fapi_get_metrics, /* fapi_get_metrics */
+ pl_fapi_set_cache /* fapi_set_cache */
+};
+
+static ulong
+pl_fapi_get_long(gs_fapi_font *ff, gs_fapi_font_feature var_id, int index)
+{
+ gs_font *pfont = (gs_font *) ff->client_font_data;
+ pl_font_t *plfont = (pl_font_t *) pfont->client_data;
+
+ ulong value = -1;
+
+ (void)index;
+
+ if (var_id == gs_fapi_font_feature_TT_size) {
+ value =
+ plfont->header_size - (plfont->offsets.GT +
+ (plfont->large_sizes ? 6 : 4));
+ }
+ return (value);
+}
+
+static int
+pl_fapi_get_cid (gs_font_base *pbfont, gs_string *charstring, gs_string *name,
+ int ccode, gs_string *enc_char_name, char *font_file_path,
+ gs_fapi_char_ref *cr, bool bCID)
+{
+ pl_font_t *plfont = pbfont->client_data;
+ gs_glyph vertical, index = ccode;
+ (void) charstring;
+ (void) name;
+ (void) enc_char_name;
+ (void) font_file_path;
+ (void) bCID;
+
+ if (plfont->allow_vertical_substitutes) {
+ vertical = pl_font_vertical_glyph(ccode, plfont);
+
+ if ( vertical != gs_no_glyph )
+ index = vertical;
+ }
+ cr->char_codes[0] = index;
+ return(0);
+}
+
+static int
+pl_fapi_get_glyph(gs_fapi_font *ff, int char_code, byte *buf,
+ ushort buf_length)
+{
+ gs_font *pfont = (gs_font *) ff->client_font_data;
+
+ /* Zero is a valid size for a TTF glyph, so init to that.
+ */
+ int size = 0;
+ gs_glyph_data_t pdata;
+
+ if (pl_tt_get_outline((gs_font_type42 *) pfont, char_code, &pdata) == 0) {
+ size = pdata.bits.size;
+
+ if (buf && buf_length >= size) {
+ memcpy(buf, pdata.bits.data, size);
+ }
+ }
+
+ return (size);
+}
+
+static ushort
+pl_fapi_serialize_tt_font(gs_fapi_font *ff, void *buf, int buf_size)
+{
+ gs_font *pfont = (gs_font *) ff->client_font_data;
+ pl_font_t *plfont = (pl_font_t *) pfont->client_data;
+ short code = -1;
+ int offset = (plfont->offsets.GT + (plfont->large_sizes ? 6 : 4));
+
+ if (buf_size >= (plfont->header_size - offset)) {
+ code = 0;
+
+ memcpy(buf, (plfont->header + offset), buf_size);
+ }
+ return ((ushort) code);
+}
+
+static int
+pl_get_glyphdirectory_data(gs_fapi_font *ff, int char_code,
+ const byte **ptr)
+{
+ return (0);
+}
+
+static int
+pl_fapi_get_metrics(gs_fapi_font *ff, gs_string *char_name, int cid,
+ double *m, bool vertical)
+{
+ return (0);
+}
+
+static int
+pl_fapi_set_cache(gs_text_enum_t *penum, const gs_font_base *pbfont,
+ const gs_string *char_name, int cid,
+ const double pwidth[2], const gs_rect *pbbox,
+ const double Metrics2_sbw_default[4], bool *imagenow)
+{
+ gs_state *pgs = (gs_state *) penum->pis;
+ float w2[6];
+ int code = 0;
+ gs_fapi_server *I = pbfont->FAPI;
+
+ if ((penum->text.operation & TEXT_DO_DRAW) && (pbfont->WMode & 1) && pwidth[0] == 1.0 ) {
+ gs_rect tmp_pbbox;
+ gs_matrix save_ctm;
+ const gs_matrix id_ctm = {1.0, 0.0, 0.0, 1.0, 0.0, 0.0};
+ /* This is kind of messy, but the cache entry has already been calculated
+ using the in-force matrix. The problem is that we have to call gs_setcachedevice
+ with the in-force matrix, not the rotated one, so we have to recalculate the extents
+ to be correct for the rotated glyph.
+ */
+
+ /* save the ctm */
+ gs_currentmatrix(pgs, &save_ctm);
+ gs_setmatrix(pgs, &id_ctm);
+
+ /* magic numbers - we don't completelely understand
+ the translation magic used by HP. This provides a
+ good approximation */
+ gs_translate(pgs, 1.0/1.15, -(1.0 - 1.0/1.15));
+ gs_rotate(pgs, 90);
+
+ gs_transform(pgs, pbbox->p.x, pbbox->p.y, &tmp_pbbox.p);
+ gs_transform(pgs, pbbox->q.x, pbbox->q.y, &tmp_pbbox.q);
+
+ w2[0] = pwidth[0];
+ w2[1] = pwidth[1];
+ w2[2] = tmp_pbbox.p.x;
+ w2[3] = tmp_pbbox.p.y;
+ w2[4] = tmp_pbbox.q.x;
+ w2[5] = tmp_pbbox.q.y;
+
+ gs_setmatrix(pgs, &save_ctm);
+ }
+ else {
+ w2[0] = pwidth[0];
+ w2[1] = pwidth[1];
+ w2[2] = pbbox->p.x;
+ w2[3] = pbbox->p.y;
+ w2[4] = pbbox->q.x;
+ w2[5] = pbbox->q.y;
+ }
+
+ if (pbfont->PaintType) {
+ double expand =
+ max(1.415,
+ gs_currentmiterlimit(pgs)) * gs_currentlinewidth(pgs) / 2;
+
+ w2[2] -= expand;
+ w2[3] -= expand;
+ w2[4] += expand;
+ w2[5] += expand;
+ }
+
+ if (I->ff.embolden != 0) {
+ code = gs_setcharwidth((gs_show_enum *)penum, pgs, w2[0], w2[1]);
+ }
+ else {
+ if ((code = gs_setcachedevice((gs_show_enum *)penum, pgs, w2)) < 0) {
+ return(code);
+ }
+ }
+
+ if ((penum->text.operation & TEXT_DO_DRAW) && (pbfont->WMode & 1) && pwidth[0] == 1.0 ) {
+ *imagenow = false;
+ return(gs_error_unknownerror);
+ }
+
+ *imagenow = true;
+ return (code);
+}
+
+static int
+pl_fapi_set_cache_rotate(gs_text_enum_t *penum, const gs_font_base *pbfont,
+ const gs_string *char_name, int cid,
+ const double pwidth[2], const gs_rect *pbbox,
+ const double Metrics2_sbw_default[4], bool *imagenow)
+{
+ *imagenow = true;
+ return (0);
+}
+
+
+static int
+pl_fapi_build_char(gs_show_enum *penum, gs_state *pgs, gs_font *pfont,
+ gs_char chr, gs_glyph glyph)
+{
+ int code;
+ gs_matrix save_ctm;
+ gs_font_base *pbfont = (gs_font_base *)pfont;
+ pl_font_t *plfont = (pl_font_t *) pfont->client_data;
+ gs_fapi_server *I = pbfont->FAPI;
+
+ I->ff.embolden = plfont->bold_fraction;
+
+ code =
+ gs_fapi_do_char(pfont, pgs, (gs_text_enum_t *)penum, NULL, false, NULL,
+ NULL, chr, glyph, 0);
+
+ if (code == gs_error_unknownerror) {
+ gs_fapi_font tmp_ff;
+
+ tmp_ff.fapi_set_cache = I->ff.fapi_set_cache;
+
+ /* save the ctm */
+ gs_currentmatrix(pgs, &save_ctm);
+
+ /* magic numbers - we don't completelely understand
+ the translation magic used by HP. This provides a
+ good approximation */
+ gs_translate(pgs, 1.0/1.15, -(1.0 - 1.0/1.15));
+ gs_rotate(pgs, 90);
+
+ I->ff.fapi_set_cache = pl_fapi_set_cache_rotate;
+
+ code =
+ gs_fapi_do_char(pfont, pgs, (gs_text_enum_t *)penum, NULL, false, NULL,
+ NULL, chr, glyph, 0);
+
+ I->ff.fapi_set_cache = tmp_ff.fapi_set_cache;
+
+ gs_setmatrix(pgs, &save_ctm);
+ }
+
+ I->ff.embolden = 0;
+
+ return (code);
+}
+
+/* FIXME: environment variables.... */
+const char *
+pl_fapi_ufst_get_fco_list(gs_memory_t *mem)
+{
+ return (UFSTFCOS);
+}
+
+const char *
+pl_fapi_ufst_get_font_dir(gs_memory_t *mem)
+{
+ return (UFSTFONTDIR);
+}
+
+static void
+pl_get_server_param(gs_fapi_server *I, const char *subtype,
+ char **server_param, int *server_param_size)
+{
+ int length = 0;
+ char SEPARATOR_STRING[2];
+
+ SEPARATOR_STRING[0] = (char)gp_file_name_list_separator;
+ SEPARATOR_STRING[1] = '\0';
+
+ length += strlen(UFSTDIRPARM);
+ length += strlen(UFSTFONTDIR);
+ length += strlen(SEPARATOR_STRING);
+ length += strlen(UFSTPLUGINPARM);
+ length += strlen(UFSTPLUGINS);
+ length++;
+
+ if ((*server_param) != NULL && (*server_param_size) >= length) {
+ strcpy((char *)*server_param, (char *)UFSTDIRPARM);
+ strcat((char *)*server_param, (char *)UFSTFONTDIR);
+ strcat((char *)*server_param, (char *)SEPARATOR_STRING);
+ strcat((char *)*server_param, (char *)UFSTPLUGINPARM);
+ strcat((char *)*server_param, (char *)UFSTPLUGINS);
+ }
+ else {
+ *server_param = NULL;
+ *server_param_size = length;
+ }
+}
+
+
+static inline int
+pl_fapi_get_mtype_font_info(gs_font *pfont, gs_fapi_font_info item,
+ void *data, int *size)
+{
+ return (gs_fapi_get_font_info(pfont, item, 0, data, size));
+}
+
+int
+pl_fapi_get_mtype_font_name(gs_font *pfont, byte *data, int *size)
+{
+ return (pl_fapi_get_mtype_font_info
+ (pfont, gs_fapi_font_info_name, data, size));
+}
+
+int
+pl_fapi_get_mtype_font_number(gs_font *pfont, int *font_number)
+{
+ int size = (int)sizeof(*font_number);
+
+ return (pl_fapi_get_mtype_font_info
+ (pfont, gs_fapi_font_info_uid, font_number, &size));
+}
+
+int
+pl_fapi_get_mtype_font_spaceBand(gs_font *pfont, uint *spaceBand)
+{
+ int size = (int)sizeof(*spaceBand);
+
+ return (pl_fapi_get_mtype_font_info
+ (pfont, gs_fapi_font_info_pitch, spaceBand, &size));
+}
+
+int
+pl_fapi_get_mtype_font_scaleFactor(gs_font *pfont, uint *scaleFactor)
+{
+ int size = (int)sizeof(*scaleFactor);
+
+ return (pl_fapi_get_mtype_font_info
+ (pfont, gs_fapi_font_info_design_units, scaleFactor, &size));
+}
+static int
+pl_fapi_char_metrics(const pl_font_t *plfont, const void *vpgs,
+ gs_char char_code, float metrics[4])
+{
+ int code = 0;
+ gs_text_enum_t *penum;
+ gs_font *pfont = plfont->pfont;
+ gs_text_params_t text;
+ gs_char buf[2];
+ gs_state *pgs = (gs_state *) vpgs;
+ /* NAFF: undefined glyph would be better handled inside FAPI */
+ gs_char chr = char_code;
+ gs_glyph unused_glyph = gs_no_glyph;
+ gs_glyph glyph = pl_tt_encode_char(pfont, chr, unused_glyph);
+
+
+ gs_gsave(pgs);
+
+ pgs->font = pfont;
+ pgs->root_font = pfont;
+
+ if (pfont->WMode & 1) {
+ gs_glyph vertical = pl_font_vertical_glyph(glyph, plfont);
+
+ if (vertical != gs_no_glyph)
+ glyph = vertical;
+ }
+
+ /* undefined character */
+ if (glyph == 0xffff || glyph == gs_no_glyph)
+ return 1;
+
+ code = gs_moveto(pgs, 0.0, 0.0);
+
+ buf[0] = char_code;
+ buf[1] = '\0';
+
+ text.operation = TEXT_FROM_CHARS | TEXT_DO_NONE | TEXT_RETURN_WIDTH;
+ text.data.chars = buf;
+ text.size = 1;
+
+ if (code >= 0)
+ code = gs_text_begin(pgs, &text, pfont->memory, &penum);
+
+ if (code >= 0)
+ code = gs_text_process(penum);
+
+ if (code >= 0) {
+ metrics[0] = metrics[1] = 0;
+ metrics[2] = penum->returned.total_width.x;
+ metrics[3] = penum->returned.total_width.y;
+
+ gs_text_release(penum, "show_char_foreground");
+ }
+ gs_grestore(pgs);
+
+ return (code);
+}
+
+static int
+pl_fapi_char_width(const pl_font_t *plfont, const void *pgs, gs_char char_code,
+ gs_point *pwidth)
+{
+ float metrics[4];
+ int code = 0;
+
+ code = pl_fapi_char_metrics(plfont, pgs, char_code, metrics);
+
+ pwidth->x = metrics[2];
+ pwidth->y = 0;
+
+ return (code);
+}
+
+static gs_glyph
+pl_fapi_encode_char(gs_font *pfont, gs_char pchr, gs_glyph_space_t not_used)
+{
+ return (gs_glyph) pchr;
+}
+
+int
+pl_fapi_passfont(pl_font_t *plfont, int subfont, char *fapi_request,
+ char *file_name, byte *font_data, int font_data_len)
+{
+ char *fapi_id = NULL;
+ int code = 0;
+ gs_string fdata;
+ gs_font *pfont = plfont->pfont;
+
+ if (!gs_fapi_available(pfont->memory, NULL)) {
+ return (code);
+ }
+
+ fdata.data = font_data;
+ fdata.size = font_data_len;
+
+ /* The plfont should contain everything we need, but setting the client data for the server
+ * to pbfont makes as much sense as setting it to NULL.
+ */
+ gs_fapi_set_servers_client_data(pfont->memory, &pl_ff_stub, pfont);
+
+ code =
+ gs_fapi_passfont(pfont, subfont, (char *)file_name, &fdata, (char *)fapi_request,
+ NULL, (char **)&fapi_id,
+ (gs_fapi_get_server_param_callback)pl_get_server_param);
+
+ if (code >= 0 && fapi_id == NULL) {
+ code = gs_error_invalidfont;
+ }
+
+ pfont->procs.build_char = pl_fapi_build_char;
+ if (pfont->FontType == ft_MicroType) {
+ pfont->procs.encode_char = pl_fapi_encode_char;
+ }
+ plfont->char_width = pl_fapi_char_width;
+ plfont->char_metrics = pl_fapi_char_metrics;
+
+ return (code);
+}
+
+bool
+pl_fapi_ufst_available(gs_memory_t *mem)
+{
+ gs_fapi_server *serv = NULL;
+ int code =
+ gs_fapi_find_server(mem, (char *)"UFST", &serv,
+ (gs_fapi_get_server_param_callback)
+ pl_get_server_param);
+
+ if (code == 0 && serv != NULL) {
+ return (true);
+ }
+ else {
+ return (false);
+ }
+}
diff --git a/pl/plfapi.h b/pl/plfapi.h
new file mode 100644
index 000000000..ae2cb1afb
--- /dev/null
+++ b/pl/plfapi.h
@@ -0,0 +1,34 @@
+/* Copyright (C) 2001-2012 Artifex Software, Inc.
+ All Rights Reserved.
+
+ This software is provided AS-IS with no warranty, either express or
+ implied.
+
+ This software is distributed under license and may not be copied, modified
+ or distributed except as expressly authorized under the terms of that
+ license. Refer to licensing information at http://www.artifex.com/
+ or contact Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134,
+ San Rafael, CA 94903, U.S.A., +1(415)492-9861, for further information.
+*/
+
+/* Font API support */
+
+int pl_fapi_rebuildfont(gs_font *pfont);
+
+int
+pl_fapi_passfont(pl_font_t *plfont, int subfont, char *fapi_request,
+ char *file_name, byte *font_data, int font_data_len);
+
+int pl_fapi_get_mtype_font_name(gs_font *pfont, byte *data, int *size);
+
+int pl_fapi_get_mtype_font_number(gs_font *pfont, int *font_number);
+
+int pl_fapi_get_mtype_font_spaceBand(gs_font *pfont, uint *spaceBand);
+
+int pl_fapi_get_mtype_font_scaleFactor(gs_font *pfont, uint *scaleFactor);
+
+const char *pl_fapi_ufst_get_fco_list(gs_memory_t *mem);
+
+const char *pl_fapi_ufst_get_font_dir(gs_memory_t *mem);
+
+bool pl_fapi_ufst_available(gs_memory_t *mem);
diff --git a/pl/plfont.c b/pl/plfont.c
index 5303a8c59..23e41f3d9 100644
--- a/pl/plfont.c
+++ b/pl/plfont.c
@@ -37,6 +37,9 @@
#include "plvalue.h"
#include "plchar.h"
#include "strmio.h"
+#include "stream.h"
+
+#include "plfapi.h"
/* Structure descriptors */
private_st_pl_font();
@@ -658,41 +661,46 @@ int
pl_fill_in_font(gs_font *pfont, pl_font_t *plfont, gs_font_dir *pdir, gs_memory_t *mem, const char *font_name)
{
int i;
+ gs_font_base *pbfont = (gs_font_base *)pfont;
+
plfont->pfont = pfont;
/* Initialize generic font data. */
- gs_make_identity(&pfont->orig_FontMatrix);
- pfont->next = pfont->prev = 0;
- pfont->memory = mem;
- pfont->dir = pdir;
- pfont->is_resource = false;
- gs_notify_init(&pfont->notify_list, gs_memory_stable(mem));
- pfont->base = pfont;
- pfont->client_data = plfont;
- pfont->WMode = 0;
- pfont->PaintType = 0;
- pfont->StrokeWidth = 0;
- pfont->is_cached = 0;
- pfont->procs.init_fstack = gs_default_init_fstack;
- pfont->procs.next_char_glyph = gs_default_next_char_glyph;
+ gs_make_identity(&pbfont->orig_FontMatrix);
+ gs_make_identity(&pbfont->FontMatrix);
+ pbfont->next = pbfont->prev = 0;
+ pbfont->memory = mem;
+ pbfont->dir = pdir;
+ pbfont->is_resource = false;
+ gs_notify_init(&pbfont->notify_list, gs_memory_stable(mem));
+ pbfont->base = pbfont;
+ pbfont->client_data = plfont;
+ pbfont->WMode = 0;
+ pbfont->PaintType = 0;
+ pbfont->StrokeWidth = 0;
+ pbfont->is_cached = 0;
+ pbfont->procs.init_fstack = gs_default_init_fstack;
+ pbfont->procs.next_char_glyph = gs_default_next_char_glyph;
+ pbfont->FAPI = NULL;
+ pbfont->FAPI_font_data = NULL;
- pfont->procs.glyph_name = pl_glyph_name;
- pfont->procs.decode_glyph = pl_decode_glyph;
- /* NB pfont->procs.callbacks.known_encode = pl_known_encode; */
- pfont->procs.define_font = gs_no_define_font;
- pfont->procs.make_font = gs_no_make_font;
- pfont->procs.font_info = gs_default_font_info;
- pfont->procs.glyph_info = gs_default_glyph_info;
- pfont->procs.glyph_outline = gs_no_glyph_outline;
- pfont->id = gs_next_ids(mem, 1);
- pfont->font_name.size = strlen(font_name);
- strncpy((char *)pfont->font_name.chars, font_name, pfont->font_name.size);
+ pbfont->procs.glyph_name = pl_glyph_name;
+ pbfont->procs.decode_glyph = pl_decode_glyph;
+ /* NB pbfont->procs.callbacks.known_encode = pl_known_encode; */
+ pbfont->procs.define_font = gs_no_define_font;
+ pbfont->procs.make_font = gs_no_make_font;
+ pbfont->procs.font_info = gs_default_font_info;
+ pbfont->procs.glyph_info = gs_default_glyph_info;
+ pbfont->procs.glyph_outline = gs_no_glyph_outline;
+ pbfont->id = gs_next_ids(mem, 1);
+ pbfont->font_name.size = strlen(font_name);
+ strncpy((char *)pbfont->font_name.chars, font_name, pbfont->font_name.size);
/* replace spaces with '-', seems acrobat doesn't like spaces. */
- for (i = 0; i < pfont->font_name.size; i++) {
- if (pfont->font_name.chars[i] == ' ')
- pfont->font_name.chars[i] = '-';
+ for (i = 0; i < pbfont->font_name.size; i++) {
+ if (pbfont->font_name.chars[i] == ' ')
+ pbfont->font_name.chars[i] = '-';
}
- strncpy((char *)pfont->key_name.chars, font_name, sizeof(pfont->font_name.chars));
- pfont->key_name.size = strlen(font_name);
+ strncpy((char *)pbfont->key_name.chars, font_name, sizeof(pbfont->font_name.chars));
+ pbfont->key_name.size = strlen(font_name);
return 0;
}
@@ -958,6 +966,19 @@ pl_load_tt_font(stream *in, gs_font_dir *pdir, gs_memory_t *mem,
int code;
gs_font_type42 *pfont;
pl_font_t *plfont;
+
+ byte *file_name = NULL;
+ gs_const_string pfname;
+
+ if (sfilename(in, &pfname) == 0) {
+ file_name = gs_alloc_bytes(mem, pfname.size + 1, "pl_load_tt_font file_name");
+ if (!file_name) {
+ return (gs_error_VMerror);
+ }
+ /* the stream code guarantees the string is null terminated */
+ memcpy(file_name, pfname.data, pfname.size + 1);
+ }
+
/* get the data from the file */
code = pl_alloc_tt_fontfile_buffer(in, mem, &tt_font_datap, &size);
if ( code < 0 )
@@ -983,12 +1004,22 @@ pl_load_tt_font(stream *in, gs_font_dir *pdir, gs_memory_t *mem,
code = gs_definefont(pdir, (gs_font *)pfont);
}
}
+
if ( code < 0 ) {
gs_free_object(mem, plfont, "pl_tt_load_font(pl_font_t)");
gs_free_object(mem, pfont, "pl_tt_load_font(gs_font_type42)");
pl_free_tt_fontfile_buffer(mem, tt_font_datap);
return code;
}
+
+ code = pl_fapi_passfont(plfont, 0 , NULL, NULL, plfont->header + 6, plfont->header_size - 6);
+ if (file_name) {
+ gs_free_object(mem, file_name, "pl_load_tt_font file_name");
+ }
+ if (code < 0) {
+ return(code);
+ }
+
*pplfont = plfont;
return 0;
}
diff --git a/pl/plfont.h b/pl/plfont.h
index 191ee2050..89582db32 100644
--- a/pl/plfont.h
+++ b/pl/plfont.h
@@ -109,6 +109,7 @@ typedef struct pl_font_params_s {
typedef struct pl_font_glyph_s {
gs_glyph glyph;
const byte *data;
+ int data_len;
} pl_font_glyph_t;
typedef struct pl_glyph_table_s {
pl_font_glyph_t *table;
@@ -279,7 +280,7 @@ int pl_alloc_tt_fontfile_buffer(stream *in, gs_memory_t *mem, byte **pptt_font_d
int pl_free_tt_fontfile_buffer(gs_memory_t *mem, byte *ptt_font_data);
/* Add a glyph to a font. Return -1 if the table is full. */
-int pl_font_add_glyph(pl_font_t *plfont, gs_glyph glyph, const byte *data);
+int pl_font_add_glyph(pl_font_t *plfont, gs_glyph glyph, const byte *cdata);
/* Determine the escapement of a character in a font / symbol set. */
/* If the font is bound, the symbol set is ignored. */
diff --git a/pl/plftable.c b/pl/plftable.c
index a7950a259..fbb6896e9 100644
--- a/pl/plftable.c
+++ b/pl/plftable.c
@@ -20,651 +20,3 @@
#include "gstypes.h"
#include "plfont.h"
#include "plftable.h"
-
-/* The AGFA_FONT_TABLE definition is defined when the system is
- compiled to use the MonoType font scaler. It can also be defined
- here locally withe AGFA_SCREENFONTS to use Monotype font names with
- the TrueType screen fonts distributed with the UFST. The latter
- configuration uses the artifex fontscaler. NB configuration is
- awkward. */
-
-/* #define AGFA_FONT_TABLE */
-/* #define AGFA_SCREENFONTS */
-
-#ifdef AGFA_FONT_TABLE
-#ifdef AGFA_SCREENFONTS
-#define fontnames(agfascreenfontname, agfaname, urwname) agfascreenfontname
-#else
-#define fontnames(agfascreenfontname, agfaname, urwname) agfaname
-#endif
-#else
-#define fontnames(agfascreenfontname, agfaname, urwname) urwname
-#endif
-
-const font_resident_t resident_table[] = {
-#define C(b) ((byte)((b) ^ 0xff))
-#define cc_alphabetic\
- { C(0), C(0), C(0), C(0), C(0xff), C(0xc0), C(0), C(plgv_Unicode) }
-#define cc_symbol\
- { C(0), C(0), C(0), C(4), C(0), C(0), C(0), C(plgv_Unicode) }
-#define cc_dingbats\
- { C(0), C(0), C(0), C(1), C(0), C(0), C(0), C(plgv_Unicode) }
- /*
- * Per TRM 23-87, PCL5 printers are supposed to have Univers
- * and CG Times fonts. Substitute Arial for Univers and
- * Times for CG Times.
- */
- /* hack the vendor value to be agfa's. */
-#define agfa (4096)
- /* definition for style word as defined on 11-19 PCLTRM */
-#define style_word(posture, width, structure) \
- ((posture) + (4 * (width)) + (32 * (structure)))
-#define REGULAR (style_word(0, 0, 0))
-#define ITALIC (style_word(1, 0, 0))
-#define CONDENSEDITALIC (style_word(1, 1, 0))
-#define CONDENSED (style_word(0, 1, 0))
-#define LIGHT (-3)
-#define NOBOLD (0)
-#define MEDIUMBOLD (1)
-#define TWOBOLD (2)
-#define BOLD (3)
-#define EXBOLD (4)
-
- {
- fontnames("Courier", "CourierMT", "NimbusMono-Reg"),
- {'C','o','u','r','i','e','r',' ',' ',' ',' ',' ',' ',' ',' ',' '},
- {0, 0, {600.0, 720000.0/600.0}, 0, REGULAR, NOBOLD, 4099, 0},
- cc_alphabetic, plft_Unicode
- },
-
- {
- fontnames("CGTimes", "CGTimes", "NimbusRomanNo4-Lig"),
- {'C','G',' ','T','i','m','e','s',' ',' ',' ',' ',' ',' ',' ',' '},
- {0, 1, {295.0, 720000.0/295.0}, 0, REGULAR, NOBOLD, 4101, 1},
- cc_alphabetic, plft_Unicode
- },
-
- {
- fontnames("CGTimesBold", "CGTimes-Bold", "NimbusRomanNo4-Bol"),
- {'C','G',' ','T','i','m','e','s',' ',' ',' ',' ',' ',' ','B','d'},
- {0, 1, {295.0, 720000.0/295.0}, 0, REGULAR, BOLD, 4101, 2},
- cc_alphabetic, plft_Unicode
- },
-
- {
- fontnames("CGTimesItalic", "CGTimes-Italic", "NimbusRomanNo4-LigIta"),
- {'C','G',' ','T','i','m','e','s',' ',' ',' ',' ',' ',' ','I','t'},
- {0, 1, {295.0, 720000.0/295.0}, 0, ITALIC, NOBOLD, 4101, 3},
- cc_alphabetic, plft_Unicode
- },
-
- {
- fontnames("CGTimesBoldItalic", "CGTimes-BoldItalic", "NimbusRomanNo4-BolIta"),
- {'C','G',' ','T','i','m','e','s',' ',' ',' ',' ','B','d','I','t'},
- {0, 1, {295.0, 720000.0/295.0}, 0, ITALIC, BOLD, 4101, 4},
- cc_alphabetic, plft_Unicode
- },
-
- {
- fontnames("CGOmega", "CGOmega", "URWClassico-Reg"),
- {'C','G',' ','O','m','e','g','a',' ',' ',' ',' ',' ',' ',' ',' '},
- {0, 1, {276.0, 720000.0/276.0}, 0, REGULAR, NOBOLD, 4113, 5},
- cc_alphabetic, plft_Unicode
- },
-
- {
- fontnames("CGOmegaBold", "CGOmega-Bold", "URWClassico-Bol"),
- {'C','G',' ','O','m','e','g','a',' ',' ',' ',' ',' ',' ','B','d'},
- {0, 1, {276.0, 720000.0/276.0}, 0, REGULAR, BOLD, 4113, 6},
- cc_alphabetic, plft_Unicode
- },
-
- {
- fontnames("CGOmegaItalic", "CGOmega-Italic", "URWClassico-Ita"),
- {'C','G',' ','O','m','e','g','a',' ',' ',' ',' ',' ',' ','I','t'},
- {0, 1, {276.0, 720000.0/276.0}, 0, ITALIC, NOBOLD, 4113, 7},
- cc_alphabetic, plft_Unicode
- },
-
- {
- fontnames("CGOmegaBoldItalic", "CGOmega-BoldItalic", "URWClassico-BolIta"),
- {'C','G',' ','O','m','e','g','a',' ',' ',' ',' ','B','d','I','t'},
- {0, 1, {276.0, 720000.0/276.0}, 0, ITALIC, BOLD, 4113, 8},
- cc_alphabetic, plft_Unicode
- },
-
- {
- fontnames("Coronet", "Coronet", "Coronet"),
- {'C','o','r','o','n','e','t',' ',' ',' ',' ',' ',' ',' ',' ',' '},
- {0, 1, {203.0, 720000.0/203.0}, 0, ITALIC, NOBOLD, 4116, 9},
- cc_alphabetic, plft_Unicode
- },
-
- {
- fontnames("ClarendonCondensedBold", "Clarendon-Condensed-Bold", "ClarendonURW-BolCon"),
- {'C','l','a','r','e','n','d','o','n',' ',' ',' ','C','d','B','d'},
- {0, 1, {221.0, 720000.0/221.0}, 0, CONDENSED, BOLD, 4140, 10},
- cc_alphabetic, plft_Unicode
- },
-
- {
- fontnames("UniversMedium", "Univers-Medium", "U001-Reg"),
- {'U','n','i','v','e','r','s',' ',' ',' ',' ',' ',' ',' ','M','d'},
- {0, 1, {332.0, 720000.0/332.0}, 0, REGULAR, NOBOLD, 4148, 11},
- cc_alphabetic, plft_Unicode
- },
-
- {
- fontnames("UniversBold", "Univers-Bold", "U001-Bol"),
- {'U','n','i','v','e','r','s',' ',' ',' ',' ',' ',' ',' ','B','d'},
- {0, 1, {332.0, 720000.0/332.0}, 0, REGULAR, BOLD, 4148, 12},
- cc_alphabetic, plft_Unicode
- },
-
- {
- fontnames("UniversMediumItalic", "Univers-MediumItalic", "U001-Ita"),
- {'U','n','i','v','e','r','s',' ',' ',' ',' ',' ','M','d','I','t'},
- {0, 1, {332.0, 720000.0/332.0}, 0, ITALIC, NOBOLD, 4148, 13},
- cc_alphabetic, plft_Unicode
- },
-
- {
- fontnames("UniversBoldItalic", "Univers-BoldItalic", "U001-BolIta"),
- {'U','n','i','v','e','r','s',' ',' ',' ',' ',' ','B','d','I','t'},
- {0, 1, {332.0, 720000.0/332.0}, 0, ITALIC, BOLD, 4148, 14},
- cc_alphabetic, plft_Unicode
- },
-
- {
- fontnames("UniversCondensedMedium", "Univers-Condensed-Medium", "U001Con-Reg"),
- {'U','n','i','v','e','r','s',' ',' ',' ',' ',' ','C','d','M','d'},
- {0, 1, {221.0, 720000.0/221.0}, 0, CONDENSED, NOBOLD, 4148, 15},
- cc_alphabetic, plft_Unicode
- },
-
- {
- fontnames("UniversCondensedBold", "Univers-Condensed-Bold", "U001Con-Bol"),
- {'U','n','i','v','e','r','s',' ',' ',' ',' ',' ','C','d','B','d'},
- {0, 1, {221.0, 720000.0/221.0}, 0, CONDENSED, BOLD, 4148, 16},
- cc_alphabetic, plft_Unicode
- },
-
- {
- fontnames("UniversCondensedMediumItalic", "Univers-Condensed-MediumItalic", "U001Con-Ita"),
- {'U','n','i','v','e','r','s',' ',' ',' ','C','d','M','d','I','t'},
- {0, 1, {221.0, 720000.0/221.0}, 0, CONDENSEDITALIC, NOBOLD, 4148, 17},
- cc_alphabetic, plft_Unicode
- },
-
- {
- fontnames("UniversCondensedBoldItalic", "Univers-Condensed-BoldItalic", "U001Con-BolIta"),
- {'U','n','i','v','e','r','s',' ',' ',' ','C','d','B','d','I','t'},
- {0, 1, {221.0, 720000.0/221.0}, 0, CONDENSEDITALIC, BOLD, 4148, 18},
- cc_alphabetic, plft_Unicode
- },
-
- {
- fontnames("AntiqueOlive", "AntiqueOlive", "AntiqueOlive-Reg"),
- {'A','n','t','i','q','O','l','i','v','e',' ',' ',' ',' ',' ',' '},
- {0, 1, {295.0, 720000.0/295.0}, 0, REGULAR, NOBOLD, 4168, 19},
- cc_alphabetic, plft_Unicode
- },
-
- {
- fontnames("AntiqueOliveBold", "AntiqueOlive-Bold", "AntiqueOlive-Bol"),
- {'A','n','t','i','q','O','l','i','v','e',' ',' ',' ',' ','B','d'},
- {0, 1, {332.0, 720000.0/332.0}, 0, REGULAR, BOLD, 4168, 20},
- cc_alphabetic, plft_Unicode
- },
-
- {
- fontnames("AntiqueOliveItalic", "AntiqueOlive-Italic", "AntiqueOlive-Ita"),
- {'A','n','t','i','q','O','l','i','v','e',' ',' ',' ',' ','I','t'},
- {0, 1, {294.0, 720000.0/294.0}, 0, ITALIC, NOBOLD, 4168, 21},
- cc_alphabetic, plft_Unicode
- },
-
- {
- fontnames("GaramondAntiqua", "Garamond-Antiqua", "GaramondNo8-Reg"),
- {'G','a','r','a','m','o','n','d',' ','A','n','t','i','q','u','a'},
- {0, 1, {258.0, 720000.0/258.0}, 0, REGULAR, NOBOLD, 4197, 22},
- cc_alphabetic, plft_Unicode
- },
-
- {
- fontnames("GaramondHalbfett", "Garamond-Halbfett", "GaramondNo8-Med"),
- {'G','a','r','a','m','o','n','d',' ',' ',' ',' ',' ','H','l','b'},
- {0, 1, {276.0, 720000.0/276.0}, 0, REGULAR, BOLD, 4197, 23},
- cc_alphabetic, plft_Unicode
- },
-
- {
- fontnames("GaramondKursiv", "Garamond-Kursiv", "GaramondNo8-Ita"),
- {'G','a','r','a','m','o','n','d',' ',' ',' ',' ','K','r','s','v'},
- {0, 1, {240.0, 720000.0/240.0}, 0, ITALIC, NOBOLD, 4197, 24},
- cc_alphabetic, plft_Unicode
- },
-
- {
- fontnames("GaramondKursivHalbfett", "Garamond-KursivHalbfett", "GaramondNo8-MedIta"),
- {'G','a','r','a','m','o','n','d',' ','K','r','s','v','H','l','b'},
- {0, 1, {258.0, 720000.0/258.0}, 0, ITALIC, BOLD, 4197, 25},
- cc_alphabetic, plft_Unicode
- },
-
- {
- fontnames("Marigold", "Marigold", "Mauritius-Reg"),
- {'M','a','r','i','g','o','l','d',' ',' ',' ',' ',' ',' ',' ',' '},
- {0, 1, {221.0, 720000.0/221.0}, 0, REGULAR, NOBOLD, 4297, 26},
- cc_alphabetic, plft_Unicode
- },
-
- {
- fontnames("AlbertusMedium", "Albertus-Medium", "A028-Med"),
- {'A','l','b','e','r','t','u','s',' ',' ',' ',' ',' ',' ','M','d'},
- {0, 1, {313.0, 720000.0/313.0}, 0, REGULAR, MEDIUMBOLD, 4362, 27},
- cc_alphabetic, plft_Unicode
- },
-
- {
- fontnames("AlbertusExtraBold", "Albertus-ExtraBold", "A028-Ext"),
- {'A','l','b','e','r','t','u','s',' ',' ',' ',' ',' ',' ','X','b'},
- {0, 1, {369.0, 720000.0/369.0}, 0, REGULAR, EXBOLD, 4362, 28},
- cc_alphabetic, plft_Unicode
- },
-
- {
- fontnames("Arial", "Arial", "A030-Reg"),
- {'A','r','i','a','l',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' '},
- {0, 1, {278.0, 720000.0/278.0}, 0, REGULAR, NOBOLD, 16602, 29},
- cc_alphabetic, plft_Unicode
- },
-
- {
- fontnames("Arial-BoldMT", "Arial-Bold", "A030-Bol"),
- {'A','r','i','a','l',' ',' ',' ',' ',' ',' ',' ',' ',' ','B','d'},
- {0, 1, {278.0, 720000.0/278.0}, 0, REGULAR, BOLD, 16602, 30},
- cc_alphabetic, plft_Unicode
- },
-
- {
- fontnames("Arial-ItalicMT", "Arial-Italic", "A030-Ita"),
- {'A','r','i','a','l',' ',' ',' ',' ',' ',' ',' ',' ',' ','I','t'},
- {0, 1, {278.0, 720000.0/278.0}, 0, ITALIC, NOBOLD, 16602, 31},
- cc_alphabetic, plft_Unicode
- },
-
- {
- fontnames("Arial-BoldItalicMT", "Arial-BoldItalic", "A030-BolIta"),
- {'A','r','i','a','l',' ',' ',' ',' ',' ',' ',' ','B','d','I','t'},
- {0, 1, {278.0, 720000.0/278.0}, 0, ITALIC, BOLD, 16602, 32},
- cc_alphabetic, plft_Unicode
- },
-
- {
- fontnames("TimesNewRoman", "TimesNewRoman", "NimbusRomanNo9-Reg"),
- {'T','i','m','e','s','N','e','w','R','m','n',' ',' ',' ',' ',' '},
- {0, 1, {250.0, 720000.0/250.0}, 0, REGULAR, NOBOLD, 16901, 33},
- cc_alphabetic, plft_Unicode
- },
-
- {
- fontnames("TimesNewRoman-Bold", "TimesNewRoman-Bold", "NimbusRomanNo9-Med"),
- {'T','i','m','e','s','N','e','w','R','m','n',' ',' ',' ','B','d'},
- {0, 1, {250.0, 720000.0/250.0}, 0, REGULAR, BOLD, 16901, 34},
- cc_alphabetic, plft_Unicode
- },
-
- {
- fontnames("TimesNewRoman-Italic", "TimesNewRoman-Italic", "NimbusRomanNo9-Ita"),
- {'T','i','m','e','s','N','e','w','R','m','n',' ',' ',' ','I','t'},
- {0, 1, {250.0, 720000.0/250.0}, 0, ITALIC, NOBOLD, 16901, 36},
- cc_alphabetic, plft_Unicode
- },
-
- {
- fontnames("TimesNewRoman-BoldItalic", "TimesNewRoman-BoldItalic", "NimbusRomanNo9-MedIta"),
- {'T','i','m','e','s','N','e','w','R','m','n',' ','B','d','I','t'},
- {0, 1, {250.0, 720000.0/250.0}, 0, ITALIC, BOLD, 16901, 35},
- cc_alphabetic, plft_Unicode
- },
-
- {
- fontnames("Helvetica", "Helvetica", "NimbusSanL-Regu"),
- {'H','e','l','v','e','t','i','c','a',' ',' ',' ',' ',' ',' ',' '},
- {0, 1, {278.0, 720000.0/278.0}, 0, REGULAR, NOBOLD, 24580, 37},
- cc_alphabetic, plft_Unicode
- },
-
- {
- fontnames("Helvetica-Bold", "Helvetica-Bold", "NimbusSanL-Bold"),
- {'H','e','l','v','e','t','i','c','a',' ',' ',' ',' ',' ','B','d'},
- {0, 1, {278.0, 720000.0/278.0}, 0, REGULAR, BOLD, 24580, 38},
- cc_alphabetic, plft_Unicode
- },
-
- {
- fontnames("Helvetica-BoldOblique", "Helvetica-BoldOblique", "NimbusSanL-BoldItal"),
- {'H','e','l','v','e','t','i','c','a',' ',' ',' ','B','d','O','b'},
- {0, 1, {278.0, 720000.0/278.0}, 0, ITALIC, BOLD, 24580, 40},
- cc_alphabetic, plft_Unicode
- },
-
- {
- fontnames("Helvetica-Narrow", "Helvetica-Narrow", "NimbusSanL-ReguCond"),
- {'H','e','l','v','e','t','i','c','a',' ',' ',' ',' ',' ','N','r'},
- {0, 1, {228.0, 720000.0/228.0}, 0, CONDENSED, NOBOLD, 24580, 41},
- cc_alphabetic, plft_Unicode
- },
-
- {
- fontnames("Helvetica-Narrow-Bold", "Helvetica-Narrow-Bold", "NimbusSanL-BoldCond"),
- {'H','e','l','v','e','t','i','c','a',' ',' ',' ','N','r','B','d'},
- {0, 1, {228.0, 720000.0/228.0}, 0, CONDENSED, BOLD, 24580, 42},
- cc_alphabetic, plft_Unicode
- },
-
- {
- fontnames("Helvetica-Narrow-BoldOblique", "Helvetica-Narrow-BoldOblique", "NimbusSanL-BoldCondItal"),
- {'H','e','l','v','e','t','i','c','a',' ','N','r','B','d','O','b'},
- {0, 1, {228.0, 720000.0/228.0}, 0, CONDENSEDITALIC, BOLD, 24580, 44},
- cc_alphabetic, plft_Unicode
- },
-
- {
- fontnames("Helvetica-Narrow-Oblique", "Helvetica-Narrow-Oblique", "NimbusSanL-ReguCondItal"),
- {'H','e','l','v','e','t','i','c','a',' ',' ',' ','N','r','O','b'},
- {0, 1, {228.0, 720000.0/228.0}, 0, CONDENSEDITALIC, NOBOLD, 24580, 43},
- cc_alphabetic, plft_Unicode
- },
-
- {
- fontnames("Helvetica-Oblique", "Helvetica-Oblique", "NimbusSanL-ReguItal"),
- {'H','e','l','v','e','t','i','c','a',' ',' ',' ',' ',' ','O','b'},
- {0, 1, {278.0, 720000.0/278.0}, 0, ITALIC, NOBOLD, 24580, 39},
- cc_alphabetic, plft_Unicode
- },
-
- {
- fontnames("Palatino-Roman", "Palatino-Roman", "URWPalladioL-Roma"),
- {'P','a','l','a','t','i','n','o',' ',' ',' ',' ',' ','R','m','n'},
- {0, 1, {250.0, 720000.0/250.0}, 0, REGULAR, NOBOLD, 24591, 45},
- cc_alphabetic, plft_Unicode
- },
-
- {
- fontnames("Palatino-Italic", "Palatino-Italic", "URWPalladioL-Ital"),
- {'P','a','l','a','t','i','n','o',' ',' ',' ',' ',' ',' ','I','t'},
- {0, 1, {250.0, 720000.0/250.0}, 0, ITALIC, NOBOLD, 24591, 47},
- cc_alphabetic, plft_Unicode
- },
-
- {
- fontnames("Palatino-Bold", "Palatino-Bold", "URWPalladioL-Bold"),
- {'P','a','l','a','t','i','n','o',' ',' ',' ',' ',' ',' ','B','d'},
- {0, 1, {250.0, 720000.0/250.0}, 0, REGULAR, BOLD, 24591, 46},
- cc_alphabetic, plft_Unicode
- },
-
- {
- fontnames("Palatino-BoldItalic", "Palatino-BoldItalic", "URWPalladioL-BoldItal"),
- {'P','a','l','a','t','i','n','o',' ',' ',' ',' ','B','d','I','t'},
- {0, 1, {250.0, 720000.0/250.0}, 0, ITALIC, BOLD, 24591, 48},
- cc_alphabetic, plft_Unicode
- },
-
- {
- fontnames("AvantGarde-Book", "AvantGarde-Book", "URWGothicL-Book"),
- {'I','T','C','A','v','a','n','t','G','a','r','d',' ',' ','B','k'},
- {0, 1, {277.0, 720000.0/277.0}, 0, REGULAR, NOBOLD, 24607, 49},
- cc_alphabetic, plft_Unicode
- },
-
- {
- fontnames("AvantGarde-Demi", "AvantGarde-Demi", "URWGothicL-Demi"),
- {'I','T','C','A','v','a','n','t','G','a','r','d',' ',' ','D','b'},
- {0, 1, {280.0, 720000.0/280.0}, 0, REGULAR, TWOBOLD, 24607, 50},
- cc_alphabetic, plft_Unicode
- },
-
- {
- fontnames("AvantGarde-BookOblique", "AvantGarde-BookOblique", "URWGothicL-BookObli"),
- {'I','T','C','A','v','a','n','t','G','a','r','d','B','k','O','b'},
- {0, 1, {277.0, 720000.0/277.0}, 0, ITALIC, NOBOLD, 24607, 51},
- cc_alphabetic, plft_Unicode
- },
-
- {
- fontnames("AvantGarde-DemiOblique", "AvantGarde-DemiOblique", "URWGothicL-DemiObli"),
- {'I','T','C','A','v','a','n','t','G','a','r','d','D','b','O','b'},
- {0, 1, {280.0, 720000.0/280.0}, 0, ITALIC, TWOBOLD, 24607, 52},
- cc_alphabetic, plft_Unicode
- },
-
- {
- fontnames("Bookman-Light", "Bookman-Light", "URWBookmanL-Ligh"),
- {'I','T','C','B','o','o','k','m','a','n',' ',' ',' ',' ','L','t'},
- {0, 1, {320.0, 720000.0/320.0}, 0, REGULAR, LIGHT, 24623, 53},
- cc_alphabetic, plft_Unicode
- },
-
- {
- fontnames("Bookman-Demi", "Bookman-Demi", "URWBookmanL-DemiBold"),
- {'I','T','C','B','o','o','k','m','a','n',' ',' ',' ',' ','D','b'},
- {0, 1, {340.0, 720000.0/340.0}, 0, REGULAR, TWOBOLD, 24623, 54},
- cc_alphabetic, plft_Unicode
- },
-
- {
- fontnames("Bookman-LightItalic", "Bookman-LightItalic", "URWBookmanL-LighItal"),
- {'I','T','C','B','o','o','k','m','a','n',' ',' ','L','t','I','t'},
- {0, 1, {300.0, 720000.0/300.0}, 0, ITALIC, LIGHT, 24623, 55},
- cc_alphabetic, plft_Unicode
- },
-
- {
- fontnames("Bookman-DemiItalic", "Bookman-DemiItalic", "URWBookmanL-DemiBoldItal"),
- {'I','T','C','B','o','o','k','m','a','n',' ',' ','D','b','I','t'},
- {0, 1, {340.0, 720000.0/340.0}, 0, ITALIC, TWOBOLD, 24623, 56},
- cc_alphabetic, plft_Unicode
- },
-
- {
- fontnames("NewCenturySchlbk-Bold", "NewCenturySchlbk-Bold", "CenturySchL-Bold"),
- {'N','w','C','e','n','t','S','c','h','l','b','k',' ',' ','B','d'},
- {0, 1, {287.0, 720000.0/287.0}, 0, REGULAR, BOLD, 24703, 58},
- cc_alphabetic, plft_Unicode
- },
-
- {
- fontnames("NewCenturySchlbk-BoldItalic", "NewCenturySchlbk-BoldItalic", "CenturySchL-BoldItal"),
- {'N','w','C','e','n','t','S','c','h','l','b','k','B','d','I','t'},
- {0, 1, {287.0, 720000.0/287.0}, 0, ITALIC, BOLD, 24703, 60},
- cc_alphabetic, plft_Unicode
- },
-
- {
- fontnames("NewCenturySchlbk-Italic", "NewCenturySchlbk-Italic", "CenturySchL-Ital"),
- {'N','w','C','e','n','t','S','c','h','l','b','k',' ',' ','I','t'},
- {0, 1, {278.0, 720000.0/278.0}, 0, ITALIC, NOBOLD, 24703, 59},
- cc_alphabetic, plft_Unicode
- },
-
- {
- fontnames("NewCenturySchlbk-Roman", "NewCenturySchlbk-Roman", "CenturySchL-Roma"),
- {'N','w','C','e','n','t','S','c','h','l','b','k',' ','R','m','n'},
- {0, 1, {278.0, 720000.0/278.0}, 0, REGULAR, NOBOLD, 24703, 57},
- cc_alphabetic, plft_Unicode
- },
-
- {
- fontnames("Times-Roman", "Times-Roman", "NimbusRomNo9L-Regu"),
- {'T','i','m','e','s',' ',' ',' ',' ',' ',' ',' ',' ','R','m','n'},
- {0, 1, {250.0, 720000.0/250.0}, 0, REGULAR, NOBOLD, 25093, 61},
- cc_alphabetic, plft_Unicode
- },
-
- {
- fontnames("Times-Bold", "Times-Bold", "NimbusRomNo9L-Medi"),
- {'T','i','m','e','s',' ',' ',' ',' ',' ',' ',' ',' ',' ','B','d'},
- {0, 1, {250.0, 720000.0/250.0}, 0, REGULAR, BOLD, 25093, 62},
- cc_alphabetic, plft_Unicode
- },
-
- {
- fontnames("Times-Italic", "Times-Italic", "NimbusRomNo9L-ReguItal"),
- {'T','i','m','e','s',' ',' ',' ',' ',' ',' ',' ',' ',' ','I','t'},
- {0, 1, {250.0, 720000.0/250.0}, 0, ITALIC, NOBOLD, 25093, 63},
- cc_alphabetic, plft_Unicode
- },
-
- {
- fontnames("Times-BoldItalic", "Times-BoldItalic", "NimbusRomNo9L-MediItal"),
- {'T','i','m','e','s',' ',' ',' ',' ',' ',' ',' ','B','d','I','t'},
- {0, 1, {250.0, 720000.0/250.0}, 0, ITALIC, BOLD, 25093, 64},
- cc_alphabetic, plft_Unicode
- },
-
- {
- fontnames("ZapfChancery-MediumItalic", "ZapfChancery-MediumItalic", "URWChanceryL-MediItal"),
- {'Z','a','p','f','C','h','a','n','c','e','r','y','M','d','I','t'},
- {0, 1, {220.0, 720000.0/220.0},0, ITALIC, NOBOLD, 45099, 65},
- cc_alphabetic, plft_Unicode
- },
-
- {
- fontnames("SymbolMT", "Symbol", "StandardSymL"),
- {'S','y','m','b','o','l',' ',' ',' ',' ',' ',' ',' ',' ',' ',' '},
- {621, 1, {250.0, 720000.0/250.0}, 0, REGULAR, NOBOLD, 16686, 66},
- cc_symbol, plft_8bit_printable
- },
-
- /* NB Symbol - Symbol PS for URW are the same. Adding the
- confusion AGFA has 2 different fonts presumably Symbol and
- SymbolPS, each called Symbol. */
- {
- fontnames("SymbPS", "SymbPS", "StandardSymL"),
- {'S','y','m','b','o','l','P','S',' ',' ',' ',' ',' ',' ',' ',' '},
- {621, 1, {250.0, 720000.0/250.0}, 0, REGULAR, NOBOLD, 45358, 67},
- cc_symbol, plft_8bit_printable
- },
-
- {
- fontnames("Wingdings-Regular", "Wingdings-Regular", "New Dingbats"),
- {'W','i','n','g','d','i','n','g','s',' ',' ',' ',' ',' ',' ',' '},
- {18540, 1, {1000.0, 720000.0/1000.0},0, REGULAR, NOBOLD, 31402, 68},
- cc_dingbats, plft_8bit
- },
-
- {
- fontnames("ZapfDingbats", "ZapfDingbats", "Dingbats"),
- {'Z','a','p','f','D','i','n','g','b','a','t','s',' ',' ',' ',' '},
- {460, 1, {280.0, 720000.0/280.0},0, REGULAR, NOBOLD, 45101, 69},
- cc_dingbats, plft_8bit
- },
-
- {
- fontnames("CourierBold", "CourierMT-Bold", "NimbusMono-Bol"),
- {'C','o','u','r','i','e','r',' ',' ',' ',' ',' ',' ',' ','B','d'},
- {0, 0, {600.0, 720000.0/600.0}, 0, REGULAR, BOLD, 4099, 70},
- cc_alphabetic, plft_Unicode
- },
-
- {
- fontnames("CourierItalic", "CourierMT-Italic", "NimbusMono-Ita"),
- {'C','o','u','r','i','e','r',' ',' ',' ',' ',' ',' ',' ','I','t'},
- {0, 0, {600.0, 720000.0/600.0}, 0, ITALIC, NOBOLD, 4099, 71},
- cc_alphabetic, plft_Unicode
- },
-
- {
- fontnames("CourierBoldItalic", "CourierMT-BoldItalic", "NimbusMono-BolIta"),
- {'C','o','u','r','i','e','r',' ',' ',' ',' ',' ','B','d','I','t'},
- {0, 0, {600.0, 720000.0/600.0}, 0, ITALIC, BOLD, 4099, 72},
- cc_alphabetic, plft_Unicode
- },
-
- {
- fontnames("LetterGothic", "LetterGothic", "LetterGothic-Reg"),
- {'L','e','t','t','e','r','G','o','t','h','i','c',' ',' ',' ',' '},
- {0, 0, {500.0, 720000.0/500.0}, 0, REGULAR, NOBOLD, 4102, 73},
- cc_alphabetic, plft_Unicode
- },
-
- {
- fontnames("LetterGothicBold", "LetterGothic-Bold", "LetterGothic-Bol"),
- {'L','e','t','t','e','r','G','o','t','h','i','c',' ',' ','B','d'},
- {0, 0, {500.0, 720000.0/500.0}, 0, REGULAR, BOLD, 4102, 74},
- cc_alphabetic, plft_Unicode
- },
-
- {
- fontnames("LetterGothicItalic", "LetterGothic-Italic", "LetterGothic-Ita"),
- {'L','e','t','t','e','r','G','o','t','h','i','c',' ',' ','I','t'},
- {0, 0, {500.0, 720000.0/500.0}, 0, ITALIC, NOBOLD, 4102, 75},
- cc_alphabetic, plft_Unicode
- },
-
- {
- fontnames("Courier", "Courier", "NimbusMonL-Regu"),
- {'C','o','u','r','i','e','r','P','S',' ',' ',' ',' ',' ',' ',' '},
- {0, 0, {600.0, 720000.0/600.0}, 0, REGULAR, NOBOLD, 24579, 76},
- cc_alphabetic, plft_Unicode
- },
-
- {
- fontnames("Courier-Bold", "Courier-Bold", "NimbusMonL-Bold"),
- {'C','o','u','r','i','e','r','P','S',' ',' ',' ',' ',' ','B','d'},
- {0, 0, {600.0, 720000.0/600.0}, 0, REGULAR, BOLD, 24579, 77},
- cc_alphabetic, plft_Unicode
- },
-
- {
- fontnames("Courier-BoldOblique", "Courier-BoldOblique", "NimbusMonL-BoldObli"),
- {'C','o','u','r','i','e','r','P','S',' ',' ',' ','B','d','O','b'},
- {0, 0, {600.0, 720000.0/600.0}, 0, ITALIC, BOLD, 24579, 79},
- cc_alphabetic, plft_Unicode
- },
-
- {
- fontnames("Courier-Oblique", "Courier-Oblique", "NimbusMonL-ReguObli"),
- {'C','o','u','r','i','e','r','P','S',' ',' ',' ',' ',' ','O','b'},
- {0, 0, {600.0, 720000.0/600.0}, 0, ITALIC, NOBOLD, 24579, 78},
- cc_alphabetic, plft_Unicode
- },
-
- /************** NB SEMI-WRONG the artifex lineprinter is unbound ****************/
- {fontnames("noname", "noname", "ArtLinePrinter"), {'L','i','n','e',' ','P','r','i','n','t','e','r',' ',' ','0','N'},
- {14, 0, {431.0, 720000.0/431.0}, 34, REGULAR, NOBOLD, 0, 82},
- cc_alphabetic, plft_8bit_printable},
- {fontnames("noname", "noname", "ArtLinePrinter"), {'L','i','n','e',' ','P','r','i','n','t','e','r',' ',' ','6','N'},
- {206, 0, {431.0, 720000.0/431.0}, 34, REGULAR, NOBOLD, 0, 88}, cc_alphabetic, plft_8bit_printable},
- {fontnames("noname", "noname", "ArtLinePrinter"), {'L','i','n','e',' ','P','r','i','n','t','e','r',' ',' ','9','N'},
- {302, 0, {431.0, 720000.0/431.0}, 34, REGULAR, NOBOLD, 0, 89}, cc_alphabetic, plft_8bit_printable},
- {fontnames("noname", "noname", "ArtLinePrinter"), {'L','i','n','e',' ','P','r','i','n','t','e','r',' ','1','0','U'},
- {341, 0, {431.0, 720000.0/431.0}, 34, REGULAR, NOBOLD, 0, 80}, cc_alphabetic, plft_8bit_printable},
- {fontnames("noname", "noname", "ArtLinePrinter"), {'L','i','n','e',' ','P','r','i','n','t','e','r',' ','1','1','U'},
- {373, 0, {431.0, 720000.0/431.0}, 34, REGULAR, NOBOLD, 0, 83}, cc_alphabetic, plft_8bit_printable},
- {fontnames("noname", "noname", "ArtLinePrinter"), {'L','i','n','e',' ','P','r','i','n','t','e','r',' ','1','2','U'},
- {405, 0, {431.0, 720000.0/431.0}, 34, REGULAR, NOBOLD, 0, 84}, cc_alphabetic, plft_8bit_printable},
- {fontnames("noname", "noname", "ArtLinePrinter"), {'L','i','n','e',' ','P','r','i','n','t','e','r',' ',' ','1','U'},
- {53, 0, {431.0, 720000.0/431.0}, 34, REGULAR, NOBOLD, 0, 85}, cc_alphabetic, plft_8bit_printable},
- {fontnames("noname", "noname", "ArtLinePrinter"), {'L','i','n','e',' ','P','r','i','n','t','e','r',' ',' ','2','N'},
- {78, 0, {431.0, 720000.0/431.0}, 34, REGULAR, NOBOLD, 0, 86}, cc_alphabetic, plft_8bit_printable},
- {fontnames("noname", "noname", "ArtLinePrinter"), {'L','i','n','e',' ','P','r','i','n','t','e','r',' ',' ','5','N'},
- {174, 0, {431.0, 720000.0/431.0}, 34, REGULAR, NOBOLD, 0, 87}, cc_alphabetic, plft_8bit_printable},
- {fontnames("noname", "noname", "ArtLinePrinter"), {'L','i','n','e',' ','P','r','i','n','t','e','r',' ',' ','8','U'},
- {277, 0, {431.0, 720000.0/431.0}, 34, REGULAR, NOBOLD, 0, 81}, cc_alphabetic, plft_8bit_printable},
- {fontnames("","", ""), {'0','0'},
- {0, 0, {0, 0}, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0, 0, 0}, 0}
-#undef C
-#undef cc_alphabetic
-#undef cc_symbol
-#undef cc_dingbats
-#undef pitch_1
-#undef agfa_value
-};
-
-/* a null entry terminates the list, so - 1 */
-const int pl_built_in_resident_font_table_count =
- countof(resident_table) - 1;
diff --git a/pl/plftable.h b/pl/plftable.h
index a9e4bc7e1..c3ed43dd3 100644
--- a/pl/plftable.h
+++ b/pl/plftable.h
@@ -27,8 +27,652 @@ typedef struct font_resident {
pl_font_type_t font_type;
} font_resident_t;
-extern const font_resident_t resident_table[];
+#endif /* plftable_INCLUDED */
-extern const int pl_built_in_resident_font_table_count;
+/* #define AGFA_FONT_TABLE */
+/* #define AGFA_SCREENFONTS */
-#endif /* plftable_INCLUDED */
+#ifdef fontnames
+
+#if 0
+
+#ifdef AGFA_FONT_TABLE
+#ifdef AGFA_SCREENFONTS
+#define fontnames(agfascreenfontname, agfaname, urwname) agfascreenfontname
+#else
+#define fontnames(agfascreenfontname, agfaname, urwname) agfaname
+#endif
+#else
+#define fontnames(agfascreenfontname, agfaname, urwname) urwname
+#endif
+#endif
+
+
+static const font_resident_t resident_table[] = {
+#define C(b) ((byte)((b) ^ 0xff))
+#define cc_alphabetic\
+ { C(0), C(0), C(0), C(0), C(0xff), C(0xc0), C(0), C(plgv_Unicode) }
+#define cc_symbol\
+ { C(0), C(0), C(0), C(4), C(0), C(0), C(0), C(plgv_Unicode) }
+#define cc_dingbats\
+ { C(0), C(0), C(0), C(1), C(0), C(0), C(0), C(plgv_Unicode) }
+ /*
+ * Per TRM 23-87, PCL5 printers are supposed to have Univers
+ * and CG Times fonts. Substitute Arial for Univers and
+ * Times for CG Times.
+ */
+ /* hack the vendor value to be agfa's. */
+#define agfa (4096)
+ /* definition for style word as defined on 11-19 PCLTRM */
+#define style_word(posture, width, structure) \
+ ((posture) + (4 * (width)) + (32 * (structure)))
+#define REGULAR (style_word(0, 0, 0))
+#define ITALIC (style_word(1, 0, 0))
+#define CONDENSEDITALIC (style_word(1, 1, 0))
+#define CONDENSED (style_word(0, 1, 0))
+#define LIGHT (-3)
+#define NOBOLD (0)
+#define MEDIUMBOLD (1)
+#define TWOBOLD (2)
+#define BOLD (3)
+#define EXBOLD (4)
+
+ {
+ fontnames("Courier", "CourierMT", "NimbusMono-Reg"),
+ {'C','o','u','r','i','e','r',' ',' ',' ',' ',' ',' ',' ',' ',' '},
+ {0, 0, {600.0, 720000.0/600.0}, 0, REGULAR, NOBOLD, 4099, 0},
+ cc_alphabetic, plft_Unicode
+ },
+
+ {
+ fontnames("CGTimes", "CGTimes", "NimbusRomanNo4-Lig"),
+ {'C','G',' ','T','i','m','e','s',' ',' ',' ',' ',' ',' ',' ',' '},
+ {0, 1, {295.0, 720000.0/295.0}, 0, REGULAR, NOBOLD, 4101, 1},
+ cc_alphabetic, plft_Unicode
+ },
+
+ {
+ fontnames("CGTimesBold", "CGTimes-Bold", "NimbusRomanNo4-Bol"),
+ {'C','G',' ','T','i','m','e','s',' ',' ',' ',' ',' ',' ','B','d'},
+ {0, 1, {295.0, 720000.0/295.0}, 0, REGULAR, BOLD, 4101, 2},
+ cc_alphabetic, plft_Unicode
+ },
+
+ {
+ fontnames("CGTimesItalic", "CGTimes-Italic", "NimbusRomanNo4-LigIta"),
+ {'C','G',' ','T','i','m','e','s',' ',' ',' ',' ',' ',' ','I','t'},
+ {0, 1, {295.0, 720000.0/295.0}, 0, ITALIC, NOBOLD, 4101, 3},
+ cc_alphabetic, plft_Unicode
+ },
+
+ {
+ fontnames("CGTimesBoldItalic", "CGTimes-BoldItalic", "NimbusRomanNo4-BolIta"),
+ {'C','G',' ','T','i','m','e','s',' ',' ',' ',' ','B','d','I','t'},
+ {0, 1, {295.0, 720000.0/295.0}, 0, ITALIC, BOLD, 4101, 4},
+ cc_alphabetic, plft_Unicode
+ },
+
+ {
+ fontnames("CGOmega", "CGOmega", "URWClassico-Reg"),
+ {'C','G',' ','O','m','e','g','a',' ',' ',' ',' ',' ',' ',' ',' '},
+ {0, 1, {276.0, 720000.0/276.0}, 0, REGULAR, NOBOLD, 4113, 5},
+ cc_alphabetic, plft_Unicode
+ },
+
+ {
+ fontnames("CGOmegaBold", "CGOmega-Bold", "URWClassico-Bol"),
+ {'C','G',' ','O','m','e','g','a',' ',' ',' ',' ',' ',' ','B','d'},
+ {0, 1, {276.0, 720000.0/276.0}, 0, REGULAR, BOLD, 4113, 6},
+ cc_alphabetic, plft_Unicode
+ },
+
+ {
+ fontnames("CGOmegaItalic", "CGOmega-Italic", "URWClassico-Ita"),
+ {'C','G',' ','O','m','e','g','a',' ',' ',' ',' ',' ',' ','I','t'},
+ {0, 1, {276.0, 720000.0/276.0}, 0, ITALIC, NOBOLD, 4113, 7},
+ cc_alphabetic, plft_Unicode
+ },
+
+ {
+ fontnames("CGOmegaBoldItalic", "CGOmega-BoldItalic", "URWClassico-BolIta"),
+ {'C','G',' ','O','m','e','g','a',' ',' ',' ',' ','B','d','I','t'},
+ {0, 1, {276.0, 720000.0/276.0}, 0, ITALIC, BOLD, 4113, 8},
+ cc_alphabetic, plft_Unicode
+ },
+
+ {
+ fontnames("Coronet", "Coronet", "Coronet"),
+ {'C','o','r','o','n','e','t',' ',' ',' ',' ',' ',' ',' ',' ',' '},
+ {0, 1, {203.0, 720000.0/203.0}, 0, ITALIC, NOBOLD, 4116, 9},
+ cc_alphabetic, plft_Unicode
+ },
+
+ {
+ fontnames("ClarendonCondensedBold", "Clarendon-Condensed-Bold", "ClarendonURW-BolCon"),
+ {'C','l','a','r','e','n','d','o','n',' ',' ',' ','C','d','B','d'},
+ {0, 1, {221.0, 720000.0/221.0}, 0, CONDENSED, BOLD, 4140, 10},
+ cc_alphabetic, plft_Unicode
+ },
+
+ {
+ fontnames("UniversMedium", "Univers-Medium", "U001-Reg"),
+ {'U','n','i','v','e','r','s',' ',' ',' ',' ',' ',' ',' ','M','d'},
+ {0, 1, {332.0, 720000.0/332.0}, 0, REGULAR, NOBOLD, 4148, 11},
+ cc_alphabetic, plft_Unicode
+ },
+
+ {
+ fontnames("UniversBold", "Univers-Bold", "U001-Bol"),
+ {'U','n','i','v','e','r','s',' ',' ',' ',' ',' ',' ',' ','B','d'},
+ {0, 1, {332.0, 720000.0/332.0}, 0, REGULAR, BOLD, 4148, 12},
+ cc_alphabetic, plft_Unicode
+ },
+
+ {
+ fontnames("UniversMediumItalic", "Univers-MediumItalic", "U001-Ita"),
+ {'U','n','i','v','e','r','s',' ',' ',' ',' ',' ','M','d','I','t'},
+ {0, 1, {332.0, 720000.0/332.0}, 0, ITALIC, NOBOLD, 4148, 13},
+ cc_alphabetic, plft_Unicode
+ },
+
+ {
+ fontnames("UniversBoldItalic", "Univers-BoldItalic", "U001-BolIta"),
+ {'U','n','i','v','e','r','s',' ',' ',' ',' ',' ','B','d','I','t'},
+ {0, 1, {332.0, 720000.0/332.0}, 0, ITALIC, BOLD, 4148, 14},
+ cc_alphabetic, plft_Unicode
+ },
+
+ {
+ fontnames("UniversCondensedMedium", "Univers-Condensed-Medium", "U001Con-Reg"),
+ {'U','n','i','v','e','r','s',' ',' ',' ',' ',' ','C','d','M','d'},
+ {0, 1, {221.0, 720000.0/221.0}, 0, CONDENSED, NOBOLD, 4148, 15},
+ cc_alphabetic, plft_Unicode
+ },
+
+ {
+ fontnames("UniversCondensedBold", "Univers-Condensed-Bold", "U001Con-Bol"),
+ {'U','n','i','v','e','r','s',' ',' ',' ',' ',' ','C','d','B','d'},
+ {0, 1, {221.0, 720000.0/221.0}, 0, CONDENSED, BOLD, 4148, 16},
+ cc_alphabetic, plft_Unicode
+ },
+
+ {
+ fontnames("UniversCondensedMediumItalic", "Univers-Condensed-MediumItalic", "U001Con-Ita"),
+ {'U','n','i','v','e','r','s',' ',' ',' ','C','d','M','d','I','t'},
+ {0, 1, {221.0, 720000.0/221.0}, 0, CONDENSEDITALIC, NOBOLD, 4148, 17},
+ cc_alphabetic, plft_Unicode
+ },
+
+ {
+ fontnames("UniversCondensedBoldItalic", "Univers-Condensed-BoldItalic", "U001Con-BolIta"),
+ {'U','n','i','v','e','r','s',' ',' ',' ','C','d','B','d','I','t'},
+ {0, 1, {221.0, 720000.0/221.0}, 0, CONDENSEDITALIC, BOLD, 4148, 18},
+ cc_alphabetic, plft_Unicode
+ },
+
+ {
+ fontnames("AntiqueOlive", "AntiqueOlive", "AntiqueOlive-Reg"),
+ {'A','n','t','i','q','O','l','i','v','e',' ',' ',' ',' ',' ',' '},
+ {0, 1, {295.0, 720000.0/295.0}, 0, REGULAR, NOBOLD, 4168, 19},
+ cc_alphabetic, plft_Unicode
+ },
+
+ {
+ fontnames("AntiqueOliveBold", "AntiqueOlive-Bold", "AntiqueOlive-Bol"),
+ {'A','n','t','i','q','O','l','i','v','e',' ',' ',' ',' ','B','d'},
+ {0, 1, {332.0, 720000.0/332.0}, 0, REGULAR, BOLD, 4168, 20},
+ cc_alphabetic, plft_Unicode
+ },
+
+ {
+ fontnames("AntiqueOliveItalic", "AntiqueOlive-Italic", "AntiqueOlive-Ita"),
+ {'A','n','t','i','q','O','l','i','v','e',' ',' ',' ',' ','I','t'},
+ {0, 1, {294.0, 720000.0/294.0}, 0, ITALIC, NOBOLD, 4168, 21},
+ cc_alphabetic, plft_Unicode
+ },
+
+ {
+ fontnames("GaramondAntiqua", "Garamond-Antiqua", "GaramondNo8-Reg"),
+ {'G','a','r','a','m','o','n','d',' ','A','n','t','i','q','u','a'},
+ {0, 1, {258.0, 720000.0/258.0}, 0, REGULAR, NOBOLD, 4197, 22},
+ cc_alphabetic, plft_Unicode
+ },
+
+ {
+ fontnames("GaramondHalbfett", "Garamond-Halbfett", "GaramondNo8-Med"),
+ {'G','a','r','a','m','o','n','d',' ',' ',' ',' ',' ','H','l','b'},
+ {0, 1, {276.0, 720000.0/276.0}, 0, REGULAR, BOLD, 4197, 23},
+ cc_alphabetic, plft_Unicode
+ },
+
+ {
+ fontnames("GaramondKursiv", "Garamond-Kursiv", "GaramondNo8-Ita"),
+ {'G','a','r','a','m','o','n','d',' ',' ',' ',' ','K','r','s','v'},
+ {0, 1, {240.0, 720000.0/240.0}, 0, ITALIC, NOBOLD, 4197, 24},
+ cc_alphabetic, plft_Unicode
+ },
+
+ {
+ fontnames("GaramondKursivHalbfett", "Garamond-KursivHalbfett", "GaramondNo8-MedIta"),
+ {'G','a','r','a','m','o','n','d',' ','K','r','s','v','H','l','b'},
+ {0, 1, {258.0, 720000.0/258.0}, 0, ITALIC, BOLD, 4197, 25},
+ cc_alphabetic, plft_Unicode
+ },
+
+ {
+ fontnames("Marigold", "Marigold", "Mauritius-Reg"),
+ {'M','a','r','i','g','o','l','d',' ',' ',' ',' ',' ',' ',' ',' '},
+ {0, 1, {221.0, 720000.0/221.0}, 0, REGULAR, NOBOLD, 4297, 26},
+ cc_alphabetic, plft_Unicode
+ },
+
+ {
+ fontnames("AlbertusMedium", "Albertus-Medium", "A028-Med"),
+ {'A','l','b','e','r','t','u','s',' ',' ',' ',' ',' ',' ','M','d'},
+ {0, 1, {313.0, 720000.0/313.0}, 0, REGULAR, MEDIUMBOLD, 4362, 27},
+ cc_alphabetic, plft_Unicode
+ },
+
+ {
+ fontnames("AlbertusExtraBold", "Albertus-ExtraBold", "A028-Ext"),
+ {'A','l','b','e','r','t','u','s',' ',' ',' ',' ',' ',' ','X','b'},
+ {0, 1, {369.0, 720000.0/369.0}, 0, REGULAR, EXBOLD, 4362, 28},
+ cc_alphabetic, plft_Unicode
+ },
+
+ {
+ fontnames("Arial", "Arial", "A030-Reg"),
+ {'A','r','i','a','l',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' '},
+ {0, 1, {278.0, 720000.0/278.0}, 0, REGULAR, NOBOLD, 16602, 29},
+ cc_alphabetic, plft_Unicode
+ },
+
+ {
+ fontnames("Arial-BoldMT", "Arial-Bold", "A030-Bol"),
+ {'A','r','i','a','l',' ',' ',' ',' ',' ',' ',' ',' ',' ','B','d'},
+ {0, 1, {278.0, 720000.0/278.0}, 0, REGULAR, BOLD, 16602, 30},
+ cc_alphabetic, plft_Unicode
+ },
+
+ {
+ fontnames("Arial-ItalicMT", "Arial-Italic", "A030-Ita"),
+ {'A','r','i','a','l',' ',' ',' ',' ',' ',' ',' ',' ',' ','I','t'},
+ {0, 1, {278.0, 720000.0/278.0}, 0, ITALIC, NOBOLD, 16602, 31},
+ cc_alphabetic, plft_Unicode
+ },
+
+ {
+ fontnames("Arial-BoldItalicMT", "Arial-BoldItalic", "A030-BolIta"),
+ {'A','r','i','a','l',' ',' ',' ',' ',' ',' ',' ','B','d','I','t'},
+ {0, 1, {278.0, 720000.0/278.0}, 0, ITALIC, BOLD, 16602, 32},
+ cc_alphabetic, plft_Unicode
+ },
+
+ {
+ fontnames("TimesNewRoman", "TimesNewRoman", "NimbusRomanNo9-Reg"),
+ {'T','i','m','e','s','N','e','w','R','m','n',' ',' ',' ',' ',' '},
+ {0, 1, {250.0, 720000.0/250.0}, 0, REGULAR, NOBOLD, 16901, 33},
+ cc_alphabetic, plft_Unicode
+ },
+
+ {
+ fontnames("TimesNewRoman-Bold", "TimesNewRoman-Bold", "NimbusRomanNo9-Med"),
+ {'T','i','m','e','s','N','e','w','R','m','n',' ',' ',' ','B','d'},
+ {0, 1, {250.0, 720000.0/250.0}, 0, REGULAR, BOLD, 16901, 34},
+ cc_alphabetic, plft_Unicode
+ },
+
+ {
+ fontnames("TimesNewRoman-Italic", "TimesNewRoman-Italic", "NimbusRomanNo9-Ita"),
+ {'T','i','m','e','s','N','e','w','R','m','n',' ',' ',' ','I','t'},
+ {0, 1, {250.0, 720000.0/250.0}, 0, ITALIC, NOBOLD, 16901, 36},
+ cc_alphabetic, plft_Unicode
+ },
+
+ {
+ fontnames("TimesNewRoman-BoldItalic", "TimesNewRoman-BoldItalic", "NimbusRomanNo9-MedIta"),
+ {'T','i','m','e','s','N','e','w','R','m','n',' ','B','d','I','t'},
+ {0, 1, {250.0, 720000.0/250.0}, 0, ITALIC, BOLD, 16901, 35},
+ cc_alphabetic, plft_Unicode
+ },
+
+ {
+ fontnames("Helvetica", "Helvetica", "NimbusSanL-Regu"),
+ {'H','e','l','v','e','t','i','c','a',' ',' ',' ',' ',' ',' ',' '},
+ {0, 1, {278.0, 720000.0/278.0}, 0, REGULAR, NOBOLD, 24580, 37},
+ cc_alphabetic, plft_Unicode
+ },
+
+ {
+ fontnames("Helvetica-Bold", "Helvetica-Bold", "NimbusSanL-Bold"),
+ {'H','e','l','v','e','t','i','c','a',' ',' ',' ',' ',' ','B','d'},
+ {0, 1, {278.0, 720000.0/278.0}, 0, REGULAR, BOLD, 24580, 38},
+ cc_alphabetic, plft_Unicode
+ },
+
+ {
+ fontnames("Helvetica-BoldOblique", "Helvetica-BoldOblique", "NimbusSanL-BoldItal"),
+ {'H','e','l','v','e','t','i','c','a',' ',' ',' ','B','d','O','b'},
+ {0, 1, {278.0, 720000.0/278.0}, 0, ITALIC, BOLD, 24580, 40},
+ cc_alphabetic, plft_Unicode
+ },
+
+ {
+ fontnames("Helvetica-Narrow", "Helvetica-Narrow", "NimbusSanL-ReguCond"),
+ {'H','e','l','v','e','t','i','c','a',' ',' ',' ',' ',' ','N','r'},
+ {0, 1, {228.0, 720000.0/228.0}, 0, CONDENSED, NOBOLD, 24580, 41},
+ cc_alphabetic, plft_Unicode
+ },
+
+ {
+ fontnames("Helvetica-Narrow-Bold", "Helvetica-Narrow-Bold", "NimbusSanL-BoldCond"),
+ {'H','e','l','v','e','t','i','c','a',' ',' ',' ','N','r','B','d'},
+ {0, 1, {228.0, 720000.0/228.0}, 0, CONDENSED, BOLD, 24580, 42},
+ cc_alphabetic, plft_Unicode
+ },
+
+ {
+ fontnames("Helvetica-Narrow-BoldOblique", "Helvetica-Narrow-BoldOblique", "NimbusSanL-BoldCondItal"),
+ {'H','e','l','v','e','t','i','c','a',' ','N','r','B','d','O','b'},
+ {0, 1, {228.0, 720000.0/228.0}, 0, CONDENSEDITALIC, BOLD, 24580, 44},
+ cc_alphabetic, plft_Unicode
+ },
+
+ {
+ fontnames("Helvetica-Narrow-Oblique", "Helvetica-Narrow-Oblique", "NimbusSanL-ReguCondItal"),
+ {'H','e','l','v','e','t','i','c','a',' ',' ',' ','N','r','O','b'},
+ {0, 1, {228.0, 720000.0/228.0}, 0, CONDENSEDITALIC, NOBOLD, 24580, 43},
+ cc_alphabetic, plft_Unicode
+ },
+
+ {
+ fontnames("Helvetica-Oblique", "Helvetica-Oblique", "NimbusSanL-ReguItal"),
+ {'H','e','l','v','e','t','i','c','a',' ',' ',' ',' ',' ','O','b'},
+ {0, 1, {278.0, 720000.0/278.0}, 0, ITALIC, NOBOLD, 24580, 39},
+ cc_alphabetic, plft_Unicode
+ },
+
+ {
+ fontnames("Palatino-Roman", "Palatino-Roman", "URWPalladioL-Roma"),
+ {'P','a','l','a','t','i','n','o',' ',' ',' ',' ',' ','R','m','n'},
+ {0, 1, {250.0, 720000.0/250.0}, 0, REGULAR, NOBOLD, 24591, 45},
+ cc_alphabetic, plft_Unicode
+ },
+
+ {
+ fontnames("Palatino-Italic", "Palatino-Italic", "URWPalladioL-Ital"),
+ {'P','a','l','a','t','i','n','o',' ',' ',' ',' ',' ',' ','I','t'},
+ {0, 1, {250.0, 720000.0/250.0}, 0, ITALIC, NOBOLD, 24591, 47},
+ cc_alphabetic, plft_Unicode
+ },
+
+ {
+ fontnames("Palatino-Bold", "Palatino-Bold", "URWPalladioL-Bold"),
+ {'P','a','l','a','t','i','n','o',' ',' ',' ',' ',' ',' ','B','d'},
+ {0, 1, {250.0, 720000.0/250.0}, 0, REGULAR, BOLD, 24591, 46},
+ cc_alphabetic, plft_Unicode
+ },
+
+ {
+ fontnames("Palatino-BoldItalic", "Palatino-BoldItalic", "URWPalladioL-BoldItal"),
+ {'P','a','l','a','t','i','n','o',' ',' ',' ',' ','B','d','I','t'},
+ {0, 1, {250.0, 720000.0/250.0}, 0, ITALIC, BOLD, 24591, 48},
+ cc_alphabetic, plft_Unicode
+ },
+
+ {
+ fontnames("AvantGarde-Book", "AvantGarde-Book", "URWGothicL-Book"),
+ {'I','T','C','A','v','a','n','t','G','a','r','d',' ',' ','B','k'},
+ {0, 1, {277.0, 720000.0/277.0}, 0, REGULAR, NOBOLD, 24607, 49},
+ cc_alphabetic, plft_Unicode
+ },
+
+ {
+ fontnames("AvantGarde-Demi", "AvantGarde-Demi", "URWGothicL-Demi"),
+ {'I','T','C','A','v','a','n','t','G','a','r','d',' ',' ','D','b'},
+ {0, 1, {280.0, 720000.0/280.0}, 0, REGULAR, TWOBOLD, 24607, 50},
+ cc_alphabetic, plft_Unicode
+ },
+
+ {
+ fontnames("AvantGarde-BookOblique", "AvantGarde-BookOblique", "URWGothicL-BookObli"),
+ {'I','T','C','A','v','a','n','t','G','a','r','d','B','k','O','b'},
+ {0, 1, {277.0, 720000.0/277.0}, 0, ITALIC, NOBOLD, 24607, 51},
+ cc_alphabetic, plft_Unicode
+ },
+
+ {
+ fontnames("AvantGarde-DemiOblique", "AvantGarde-DemiOblique", "URWGothicL-DemiObli"),
+ {'I','T','C','A','v','a','n','t','G','a','r','d','D','b','O','b'},
+ {0, 1, {280.0, 720000.0/280.0}, 0, ITALIC, TWOBOLD, 24607, 52},
+ cc_alphabetic, plft_Unicode
+ },
+
+ {
+ fontnames("Bookman-Light", "Bookman-Light", "URWBookmanL-Ligh"),
+ {'I','T','C','B','o','o','k','m','a','n',' ',' ',' ',' ','L','t'},
+ {0, 1, {320.0, 720000.0/320.0}, 0, REGULAR, LIGHT, 24623, 53},
+ cc_alphabetic, plft_Unicode
+ },
+
+ {
+ fontnames("Bookman-Demi", "Bookman-Demi", "URWBookmanL-DemiBold"),
+ {'I','T','C','B','o','o','k','m','a','n',' ',' ',' ',' ','D','b'},
+ {0, 1, {340.0, 720000.0/340.0}, 0, REGULAR, TWOBOLD, 24623, 54},
+ cc_alphabetic, plft_Unicode
+ },
+
+ {
+ fontnames("Bookman-LightItalic", "Bookman-LightItalic", "URWBookmanL-LighItal"),
+ {'I','T','C','B','o','o','k','m','a','n',' ',' ','L','t','I','t'},
+ {0, 1, {300.0, 720000.0/300.0}, 0, ITALIC, LIGHT, 24623, 55},
+ cc_alphabetic, plft_Unicode
+ },
+
+ {
+ fontnames("Bookman-DemiItalic", "Bookman-DemiItalic", "URWBookmanL-DemiBoldItal"),
+ {'I','T','C','B','o','o','k','m','a','n',' ',' ','D','b','I','t'},
+ {0, 1, {340.0, 720000.0/340.0}, 0, ITALIC, TWOBOLD, 24623, 56},
+ cc_alphabetic, plft_Unicode
+ },
+
+ {
+ fontnames("NewCenturySchlbk-Bold", "NewCenturySchlbk-Bold", "CenturySchL-Bold"),
+ {'N','w','C','e','n','t','S','c','h','l','b','k',' ',' ','B','d'},
+ {0, 1, {287.0, 720000.0/287.0}, 0, REGULAR, BOLD, 24703, 58},
+ cc_alphabetic, plft_Unicode
+ },
+
+ {
+ fontnames("NewCenturySchlbk-BoldItalic", "NewCenturySchlbk-BoldItalic", "CenturySchL-BoldItal"),
+ {'N','w','C','e','n','t','S','c','h','l','b','k','B','d','I','t'},
+ {0, 1, {287.0, 720000.0/287.0}, 0, ITALIC, BOLD, 24703, 60},
+ cc_alphabetic, plft_Unicode
+ },
+
+ {
+ fontnames("NewCenturySchlbk-Italic", "NewCenturySchlbk-Italic", "CenturySchL-Ital"),
+ {'N','w','C','e','n','t','S','c','h','l','b','k',' ',' ','I','t'},
+ {0, 1, {278.0, 720000.0/278.0}, 0, ITALIC, NOBOLD, 24703, 59},
+ cc_alphabetic, plft_Unicode
+ },
+
+ {
+ fontnames("NewCenturySchlbk-Roman", "NewCenturySchlbk-Roman", "CenturySchL-Roma"),
+ {'N','w','C','e','n','t','S','c','h','l','b','k',' ','R','m','n'},
+ {0, 1, {278.0, 720000.0/278.0}, 0, REGULAR, NOBOLD, 24703, 57},
+ cc_alphabetic, plft_Unicode
+ },
+
+ {
+ fontnames("Times-Roman", "Times-Roman", "NimbusRomNo9L-Regu"),
+ {'T','i','m','e','s',' ',' ',' ',' ',' ',' ',' ',' ','R','m','n'},
+ {0, 1, {250.0, 720000.0/250.0}, 0, REGULAR, NOBOLD, 25093, 61},
+ cc_alphabetic, plft_Unicode
+ },
+
+ {
+ fontnames("Times-Bold", "Times-Bold", "NimbusRomNo9L-Medi"),
+ {'T','i','m','e','s',' ',' ',' ',' ',' ',' ',' ',' ',' ','B','d'},
+ {0, 1, {250.0, 720000.0/250.0}, 0, REGULAR, BOLD, 25093, 62},
+ cc_alphabetic, plft_Unicode
+ },
+
+ {
+ fontnames("Times-Italic", "Times-Italic", "NimbusRomNo9L-ReguItal"),
+ {'T','i','m','e','s',' ',' ',' ',' ',' ',' ',' ',' ',' ','I','t'},
+ {0, 1, {250.0, 720000.0/250.0}, 0, ITALIC, NOBOLD, 25093, 63},
+ cc_alphabetic, plft_Unicode
+ },
+
+ {
+ fontnames("Times-BoldItalic", "Times-BoldItalic", "NimbusRomNo9L-MediItal"),
+ {'T','i','m','e','s',' ',' ',' ',' ',' ',' ',' ','B','d','I','t'},
+ {0, 1, {250.0, 720000.0/250.0}, 0, ITALIC, BOLD, 25093, 64},
+ cc_alphabetic, plft_Unicode
+ },
+
+ {
+ fontnames("ZapfChancery-MediumItalic", "ZapfChancery-MediumItalic", "URWChanceryL-MediItal"),
+ {'Z','a','p','f','C','h','a','n','c','e','r','y','M','d','I','t'},
+ {0, 1, {220.0, 720000.0/220.0},0, ITALIC, NOBOLD, 45099, 65},
+ cc_alphabetic, plft_Unicode
+ },
+
+ {
+ fontnames("SymbolMT", "Symbol", "StandardSymL"),
+ {'S','y','m','b','o','l',' ',' ',' ',' ',' ',' ',' ',' ',' ',' '},
+ {621, 1, {250.0, 720000.0/250.0}, 0, REGULAR, NOBOLD, 16686, 66},
+ cc_symbol, plft_8bit_printable
+ },
+
+ /* NB Symbol - Symbol PS for URW are the same. Adding the
+ confusion AGFA has 2 different fonts presumably Symbol and
+ SymbolPS, each called Symbol. */
+ {
+ fontnames("SymbPS", "SymbPS", "StandardSymL"),
+ {'S','y','m','b','o','l','P','S',' ',' ',' ',' ',' ',' ',' ',' '},
+ {621, 1, {250.0, 720000.0/250.0}, 0, REGULAR, NOBOLD, 45358, 67},
+ cc_symbol, plft_8bit_printable
+ },
+
+ {
+ fontnames("Wingdings-Regular", "Wingdings-Regular", "New Dingbats"),
+ {'W','i','n','g','d','i','n','g','s',' ',' ',' ',' ',' ',' ',' '},
+ {18540, 1, {1000.0, 720000.0/1000.0},0, REGULAR, NOBOLD, 31402, 68},
+ cc_dingbats, plft_8bit
+ },
+
+ {
+ fontnames("ZapfDingbats", "ZapfDingbats", "Dingbats"),
+ {'Z','a','p','f','D','i','n','g','b','a','t','s',' ',' ',' ',' '},
+ {460, 1, {280.0, 720000.0/280.0},0, REGULAR, NOBOLD, 45101, 69},
+ cc_dingbats, plft_8bit
+ },
+
+ {
+ fontnames("CourierBold", "CourierMT-Bold", "NimbusMono-Bol"),
+ {'C','o','u','r','i','e','r',' ',' ',' ',' ',' ',' ',' ','B','d'},
+ {0, 0, {600.0, 720000.0/600.0}, 0, REGULAR, BOLD, 4099, 70},
+ cc_alphabetic, plft_Unicode
+ },
+
+ {
+ fontnames("CourierItalic", "CourierMT-Italic", "NimbusMono-Ita"),
+ {'C','o','u','r','i','e','r',' ',' ',' ',' ',' ',' ',' ','I','t'},
+ {0, 0, {600.0, 720000.0/600.0}, 0, ITALIC, NOBOLD, 4099, 71},
+ cc_alphabetic, plft_Unicode
+ },
+
+ {
+ fontnames("CourierBoldItalic", "CourierMT-BoldItalic", "NimbusMono-BolIta"),
+ {'C','o','u','r','i','e','r',' ',' ',' ',' ',' ','B','d','I','t'},
+ {0, 0, {600.0, 720000.0/600.0}, 0, ITALIC, BOLD, 4099, 72},
+ cc_alphabetic, plft_Unicode
+ },
+
+ {
+ fontnames("LetterGothic", "LetterGothic", "LetterGothic-Reg"),
+ {'L','e','t','t','e','r','G','o','t','h','i','c',' ',' ',' ',' '},
+ {0, 0, {500.0, 720000.0/500.0}, 0, REGULAR, NOBOLD, 4102, 73},
+ cc_alphabetic, plft_Unicode
+ },
+
+ {
+ fontnames("LetterGothicBold", "LetterGothic-Bold", "LetterGothic-Bol"),
+ {'L','e','t','t','e','r','G','o','t','h','i','c',' ',' ','B','d'},
+ {0, 0, {500.0, 720000.0/500.0}, 0, REGULAR, BOLD, 4102, 74},
+ cc_alphabetic, plft_Unicode
+ },
+
+ {
+ fontnames("LetterGothicItalic", "LetterGothic-Italic", "LetterGothic-Ita"),
+ {'L','e','t','t','e','r','G','o','t','h','i','c',' ',' ','I','t'},
+ {0, 0, {500.0, 720000.0/500.0}, 0, ITALIC, NOBOLD, 4102, 75},
+ cc_alphabetic, plft_Unicode
+ },
+
+ {
+ fontnames("Courier", "Courier", "NimbusMonL-Regu"),
+ {'C','o','u','r','i','e','r','P','S',' ',' ',' ',' ',' ',' ',' '},
+ {0, 0, {600.0, 720000.0/600.0}, 0, REGULAR, NOBOLD, 24579, 76},
+ cc_alphabetic, plft_Unicode
+ },
+
+ {
+ fontnames("Courier-Bold", "Courier-Bold", "NimbusMonL-Bold"),
+ {'C','o','u','r','i','e','r','P','S',' ',' ',' ',' ',' ','B','d'},
+ {0, 0, {600.0, 720000.0/600.0}, 0, REGULAR, BOLD, 24579, 77},
+ cc_alphabetic, plft_Unicode
+ },
+
+ {
+ fontnames("Courier-BoldOblique", "Courier-BoldOblique", "NimbusMonL-BoldObli"),
+ {'C','o','u','r','i','e','r','P','S',' ',' ',' ','B','d','O','b'},
+ {0, 0, {600.0, 720000.0/600.0}, 0, ITALIC, BOLD, 24579, 79},
+ cc_alphabetic, plft_Unicode
+ },
+
+ {
+ fontnames("Courier-Oblique", "Courier-Oblique", "NimbusMonL-ReguObli"),
+ {'C','o','u','r','i','e','r','P','S',' ',' ',' ',' ',' ','O','b'},
+ {0, 0, {600.0, 720000.0/600.0}, 0, ITALIC, NOBOLD, 24579, 78},
+ cc_alphabetic, plft_Unicode
+ },
+
+ /************** NB SEMI-WRONG the artifex lineprinter is unbound ****************/
+ {fontnames("noname", "noname", "ArtLinePrinter"), {'L','i','n','e',' ','P','r','i','n','t','e','r',' ',' ','0','N'},
+ {14, 0, {431.0, 720000.0/431.0}, 34, REGULAR, NOBOLD, 0, 82},
+ cc_alphabetic, plft_8bit_printable},
+ {fontnames("noname", "noname", "ArtLinePrinter"), {'L','i','n','e',' ','P','r','i','n','t','e','r',' ',' ','6','N'},
+ {206, 0, {431.0, 720000.0/431.0}, 34, REGULAR, NOBOLD, 0, 88}, cc_alphabetic, plft_8bit_printable},
+ {fontnames("noname", "noname", "ArtLinePrinter"), {'L','i','n','e',' ','P','r','i','n','t','e','r',' ',' ','9','N'},
+ {302, 0, {431.0, 720000.0/431.0}, 34, REGULAR, NOBOLD, 0, 89}, cc_alphabetic, plft_8bit_printable},
+ {fontnames("noname", "noname", "ArtLinePrinter"), {'L','i','n','e',' ','P','r','i','n','t','e','r',' ','1','0','U'},
+ {341, 0, {431.0, 720000.0/431.0}, 34, REGULAR, NOBOLD, 0, 80}, cc_alphabetic, plft_8bit_printable},
+ {fontnames("noname", "noname", "ArtLinePrinter"), {'L','i','n','e',' ','P','r','i','n','t','e','r',' ','1','1','U'},
+ {373, 0, {431.0, 720000.0/431.0}, 34, REGULAR, NOBOLD, 0, 83}, cc_alphabetic, plft_8bit_printable},
+ {fontnames("noname", "noname", "ArtLinePrinter"), {'L','i','n','e',' ','P','r','i','n','t','e','r',' ','1','2','U'},
+ {405, 0, {431.0, 720000.0/431.0}, 34, REGULAR, NOBOLD, 0, 84}, cc_alphabetic, plft_8bit_printable},
+ {fontnames("noname", "noname", "ArtLinePrinter"), {'L','i','n','e',' ','P','r','i','n','t','e','r',' ',' ','1','U'},
+ {53, 0, {431.0, 720000.0/431.0}, 34, REGULAR, NOBOLD, 0, 85}, cc_alphabetic, plft_8bit_printable},
+ {fontnames("noname", "noname", "ArtLinePrinter"), {'L','i','n','e',' ','P','r','i','n','t','e','r',' ',' ','2','N'},
+ {78, 0, {431.0, 720000.0/431.0}, 34, REGULAR, NOBOLD, 0, 86}, cc_alphabetic, plft_8bit_printable},
+ {fontnames("noname", "noname", "ArtLinePrinter"), {'L','i','n','e',' ','P','r','i','n','t','e','r',' ',' ','5','N'},
+ {174, 0, {431.0, 720000.0/431.0}, 34, REGULAR, NOBOLD, 0, 87}, cc_alphabetic, plft_8bit_printable},
+ {fontnames("noname", "noname", "ArtLinePrinter"), {'L','i','n','e',' ','P','r','i','n','t','e','r',' ',' ','8','U'},
+ {277, 0, {431.0, 720000.0/431.0}, 34, REGULAR, NOBOLD, 0, 81}, cc_alphabetic, plft_8bit_printable},
+ {fontnames("","", ""), {'0','0'},
+ {0, 0, {0, 0}, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0, 0, 0}, 0}
+#undef C
+#undef cc_alphabetic
+#undef cc_symbol
+#undef cc_dingbats
+#undef pitch_1
+#undef agfa_value
+};
+
+/* a null entry terminates the list, so - 1 */
+const int pl_built_in_resident_font_table_count =
+ countof(resident_table) - 1;
+#endif /* fontnames */
diff --git a/pl/pllfont.c b/pl/pllfont.c
index 40ac1340b..6f6a68c09 100644
--- a/pl/pllfont.c
+++ b/pl/pllfont.c
@@ -35,6 +35,13 @@
#include "pllfont.h"
#include "plftable.h"
#include "plvalue.h"
+#include "plvocab.h"
+#include "gxfapi.h"
+#include "plfapi.h"
+#include "plufstlp.h"
+
+
+extern const char gp_file_name_list_separator;
/* Load some built-in fonts. This must be done at initialization time, but
* after the state and memory are set up. Return an indication of whether
@@ -162,11 +169,54 @@ int get_name_from_tt_file(stream *tt_file, gs_memory_t *mem, char *pfontfilename
#ifdef DEBUG
static void
+check_resident_ufst_fonts(pl_dict_t *pfontdict, bool use_unicode_names_for_keys, gs_memory_t *mem)
+{
+#define fontnames(agfascreenfontname, agfaname, urwname) agfaname
+#include "plftable.h"
+ int j;
+
+ for ( j = 0; strlen(resident_table[j].full_font_name) != 0
+ && j < pl_built_in_resident_font_table_count; j++ ) {
+ void *value;
+ /* lookup unicode key in the resident table */
+ if ( use_unicode_names_for_keys ) {
+ if ( !pl_dict_lookup(pfontdict,
+ (const byte *)resident_table[j].unicode_fontname,
+ sizeof(resident_table[j].unicode_fontname),
+ &value, true, NULL) /* return data ignored */ ) {
+ int i;
+ dmprintf(mem, "Font with unicode key: ");
+ for (i = 0;
+ i < sizeof(resident_table[j].unicode_fontname)/sizeof(resident_table[j].unicode_fontname[0]);
+ i++) {
+ dmprintf1(mem, "%c", (char)resident_table[j].unicode_fontname[i]);
+ }
+ dmprintf1(mem, " not available in font dictionary, resident table position: %d\n", j);
+ }
+ } else {
+ byte key[3];
+ key[2] = (byte)j;
+ key[0] = key[1] = 0;
+ if ( !pl_dict_lookup(pfontdict,
+ key,
+ sizeof(key),
+ &value, true, NULL) /* return data ignored */ )
+ dmprintf2(mem, "%s not available in font dictionary, resident table position: %d\n",
+ resident_table[j].full_font_name, j);
+ }
+ }
+ return;
+#undef fontnames
+}
+
+static void
check_resident_fonts(pl_dict_t *pfontdict, gs_memory_t *mem)
{
+#define fontnames(agfascreenfontname, agfaname, urwname) urwname
+#include "plftable.h"
int i;
for (i = 0;
- strlen(resident_table[i].full_font_name) != 0;
+ strlen(resident_table[i].full_font_name) != 0 && i < pl_built_in_resident_font_table_count;
i ++)
if (!pl_lookup_font_by_pjl_number(pfontdict, i)) {
int j;
@@ -178,15 +228,348 @@ check_resident_fonts(pl_dict_t *pfontdict, gs_memory_t *mem)
dmprintf1(mem, "'%c'", resident_table[i].unicode_fontname[j]);
dmprintf(mem, "\n");
}
+#undef fontnames
}
#endif
+/* Load a built-in AGFA MicroType font */
+static int
+pl_fill_in_mt_font(gs_font_base *pfont, pl_font_t *plfont, ushort handle, char *fco_path,
+ gs_font_dir *pdir, gs_memory_t *mem, long unique_id)
+{
+ int code = 0;
+
+ if ( pfont == 0 || plfont == 0 )
+ code = gs_note_error(gs_error_VMerror);
+ else
+ { /* Initialize general font boilerplate. */
+ code = pl_fill_in_font((gs_font *)pfont, plfont, pdir, mem, "illegal font");
+ if ( code >= 0 )
+ { /* Initialize MicroType font boilerplate. */
+ plfont->header = 0;
+ plfont->header_size = 0;
+ plfont->scaling_technology = plfst_MicroType;
+ plfont->font_type = plft_Unicode;
+ plfont->large_sizes = true;
+ plfont->is_xl_format = false;
+ plfont->allow_vertical_substitutes = false;
+
+ gs_make_identity(&pfont->FontMatrix);
+ pfont->FontMatrix.xx = pfont->FontMatrix.yy = 0.001;
+ pfont->FontType = ft_MicroType;
+ pfont->BitmapWidths = true;
+ pfont->ExactSize = fbit_use_outlines;
+ pfont->InBetweenSize = fbit_use_outlines;
+ pfont->TransformedChar = fbit_use_outlines;
+
+ pfont->FontBBox.p.x = pfont->FontBBox.p.y =
+ pfont->FontBBox.q.x = pfont->FontBBox.q.y = 0;
+
+ uid_set_UniqueID(&pfont->UID, unique_id | (handle << 16));
+ pfont->encoding_index = 1; /****** WRONG ******/
+ pfont->nearest_encoding_index = 1; /****** WRONG ******/
+ }
+ }
+ return (code);
+}
+
+int
+pl_load_ufst_lineprinter(gs_memory_t *mem, pl_dict_t *pfontdict, gs_font_dir *pdir,
+ int storage, bool use_unicode_names_for_keys)
+{
+#define fontnames(agfascreenfontname, agfaname, urwname) agfaname
+#include "plftable.h"
+ int i;
+
+ for (i = 0; strlen(resident_table[i].full_font_name) != 0 && i < pl_built_in_resident_font_table_count; i++) {
+ if (resident_table[i].params.typeface_family == 0) {
+ const byte *header = NULL;
+ const byte *char_data = NULL;
+ pl_font_t *pplfont = pl_alloc_font(mem, "pl_load_ufst_lineprinter pplfont");
+ gs_font_base *pfont = gs_alloc_struct(mem, gs_font_base, &st_gs_font_base,
+ "pl_load_ufst_lineprinter pfont");
+ int code;
+
+ pl_get_ulp_character_data((byte **)&header, (byte **)&char_data);
+
+ if (!header || !char_data) {
+ return -1;
+ }
+
+ /* these shouldn't happen during system setup */
+ if (pplfont == 0 || pfont == 0)
+ return -1;
+ if (pl_fill_in_font((gs_font *)pfont, pplfont, pdir, mem, "lineprinter fonts") < 0)
+ return -1;
+
+ pl_fill_in_bitmap_font(pfont, gs_next_ids(mem, 1));
+ pplfont->params = resident_table[i].params;
+ memcpy(pplfont->character_complement, resident_table[i].character_complement, 8);
+
+ if ( use_unicode_names_for_keys )
+ pl_dict_put(pfontdict, (const byte *)resident_table[i].unicode_fontname, 32, pplfont );
+ else {
+ byte key[3];
+ key[2] = (byte)i;
+ key[0] = key[1] = 0;
+ pl_dict_put(pfontdict, key, sizeof(key), pplfont);
+ }
+ pplfont->storage = storage; /* should be an internal font */
+ pplfont->data_are_permanent = true;
+ pplfont->header = (byte *)header;
+ pplfont->font_type = plft_8bit_printable;
+ pplfont->scaling_technology = plfst_bitmap;
+ pplfont->is_xl_format = false;
+ pplfont->resolution.x = pplfont->resolution.y = 300;
+
+ code = pl_font_alloc_glyph_table(pplfont, 256, mem,
+ "pl_load_ufst_lineprinter pplfont (glyph table)");
+ if ( code < 0 )
+ return code;
+
+ while (1) {
+
+ uint width = pl_get_uint16(char_data + 12);
+ uint height = pl_get_uint16(char_data + 14);
+ uint ccode_plus_header_plus_data = 2 + 16 + (((width + 7) >> 3) * height);
+ uint ucode = pl_map_MSL_to_Unicode(pl_get_uint16(char_data), 0);
+ int code = 0;
+
+ /* NB this shouldn't happen but it does, should be
+ looked at */
+ if (ucode != 0xffff)
+ code = pl_font_add_glyph(pplfont, ucode, char_data + 2);
+
+ if (code < 0)
+ /* shouldn't happen */
+ return -1;
+ /* calculate the offset of the next character code in the table */
+ char_data += ccode_plus_header_plus_data;
+
+ /* char code 0 is end of table */
+ if (pl_get_uint16(char_data) == 0)
+ break;
+ }
+ code = gs_definefont(pdir, (gs_font *)pfont);
+ if (code < 0)
+ /* shouldn't happen */
+ return -1;
+ }
+ }
+ return 0;
+#undef fontnames
+}
+
+static int
+pl_load_built_in_mtype_fonts(const char *pathname, gs_memory_t *mem,
+ pl_dict_t *pfontdict, gs_font_dir *pdir,
+ int storage, bool use_unicode_names_for_keys)
+{
+#define fontnames(agfascreenfontname, agfaname, urwname) agfaname
+#include "plftable.h"
+
+ int i, k;
+ short status = 0;
+ int bSize;
+ byte key[3];
+ char pthnm[1024];
+ char *ufst_root_dir;
+ char *fco;
+ pl_font_t *plfont = NULL;
+ gs_font *pfont= NULL;
+ gs_font_base *pbfont;
+
+ (void)pl_built_in_resident_font_table_count;
+
+ /* don't load fonts more than once */
+ if (pl_dict_length(pfontdict, true) > 0)
+ return 1;
+
+ if (!pl_fapi_ufst_available (mem)) {
+ return(0);
+ }
+
+
+ /*
+ * Open and install the various font collection objects.
+ *
+ * For each font collection object, step through the object until it is
+ * exhausted, placing any fonts found in the built_in_fonts dcitonary.
+ *
+ */
+ ufst_root_dir = (char *)pl_fapi_ufst_get_font_dir(mem);
+ fco = (char *)pl_fapi_ufst_get_fco_list(mem);
+ for (k = 0; strlen(fco) > 0; k++) {
+ status = 0;
+ /* build and open (get handle) for the k'th fco file name */
+ strcpy((char *)pthnm, ufst_root_dir);
+
+ for (i = 2; fco[i] != gp_file_name_list_separator && fco[i]; i++);
+
+ strncat(pthnm, fco, i);
+ fco += (i + 1);
+
+ /* enumerat the files in this fco */
+ for ( i = 0; status == 0; i++, key[2] += 1 ) {
+ char *pname = NULL;
+
+ /* If we hit a font we're not going to use, we'll reuse the allocated
+ * memory.
+ */
+ if (!plfont) {
+
+ pbfont = gs_alloc_struct(mem, gs_font_base, &st_gs_font_base, "pl_mt_load_font(gs_font_base)");
+ plfont = pl_alloc_font(mem, "pl_mt_load_font(pl_font_t)");
+ if (!pbfont || !plfont) {
+ gs_free_object(mem, plfont, "pl_mt_load_font(pl_font_t)");
+ gs_free_object(mem, pfont, "pl_mt_load_font(gs_font_base)");
+ dmprintf1(mem, "VM error for built-in font %d", i);
+ continue;
+ }
+ }
+ pfont = (gs_font *)pbfont;
+
+ status = pl_fill_in_mt_font (pbfont, plfont, i, pthnm, pdir, mem, i);
+ if (status < 0) {
+ dmprintf2(mem, "Error %d for built-in font %d", status, i);
+ continue;
+ }
+
+ status = pl_fapi_passfont(plfont, i, (char *)"UFST", pthnm, NULL, 0);
+
+ if (status != 0) {
+ dmprintf1(mem, "CGIFfco_Access error %d\n", status);
+ }
+ else {
+ int font_number = 0;
+ /* unfortunately agfa has 2 fonts named symbol. We
+ believe the font with internal number, NB, NB, NB */
+ char *symname = (char *)"SymbPS";
+ int j;
+ uint spaceBand;
+ uint scaleFactor;
+ bool used = false;
+
+ /* For Microtype fonts, once we get here, these
+ * pl_fapi_get*() calls cannot fail, so we can
+ * safely ignore the return value
+ */
+ (void)pl_fapi_get_mtype_font_name(pfont, NULL, &bSize);
+
+ pname = (char *)gs_alloc_bytes( mem, bSize, "pl_mt_load_font: font name buffer" );
+ if (!pname) {
+ dmprintf1(mem, "VM Error for built-in font %d", i);
+ continue;
+ }
+
+ (void)pl_fapi_get_mtype_font_name(pfont, (byte *)pname, &bSize);
+
+ (void)pl_fapi_get_mtype_font_number(pfont, &font_number);
+ (void)pl_fapi_get_mtype_font_spaceBand(pfont, &spaceBand);
+ (void)pl_fapi_get_mtype_font_scaleFactor(pfont, &scaleFactor);
+
+ if ( font_number == 24463 ) {
+ gs_free_object(mem, pname, "pl_mt_load_font: font name buffer");
+ pname = symname;
+ }
+
+ for (j = 0; strlen(resident_table[j].full_font_name); j++) {
+ uint pitch_cp;
+
+ if (strcmp((char *)resident_table[j].full_font_name, (char *)pname) != 0)
+ continue;
+
+ pitch_cp = (spaceBand * 100.0) / scaleFactor + 0.5;
+
+#ifdef DEBUG
+ if (gs_debug_c('=') )
+ dmprintf2(mem, "Loading %s from fco %s\n", pname, pthnm );
+#endif
+ /* Record the differing points per inch value
+ for Intellifont derived fonts. */
+
+ if (scaleFactor == 8782) {
+ plfont->pts_per_inch = 72.307;
+ pitch_cp = (spaceBand * 100 * 72.0) / (scaleFactor * 72.307) + 0.5;
+ }
+
+#ifdef DEBUG
+ if (gs_debug_c('=') )
+ dmprintf3(mem, "scale factor=%d, pitch (cp)=%d per_inch_x100=%d\n", scaleFactor, pitch_cp, (uint)(720000.0/pitch_cp));
+#endif
+
+ plfont->font_type = resident_table[j].font_type;
+ plfont->storage = storage;
+ plfont->data_are_permanent = false;
+ plfont->params = resident_table[j].params;
+
+ /*
+ * NB: though the TTFONTINFOTYPE structure has a
+ * pcltChComp field, it is not filled in by the UFST
+ * code (which just initializes it to 0). Hence, the
+ * hard-coded information in the resident font
+ * initialization structure is used.
+ */
+ memcpy(plfont->character_complement, resident_table[j].character_complement, 8);
+
+ status = gs_definefont(pdir, (gs_font *)pfont);
+ if (status < 0) {
+ status = 0;
+ continue;
+ }
+ status = pl_fapi_passfont(plfont, i, (char *)"UFST", pthnm, NULL, 0);
+ if (status < 0) {
+ status = 0;
+ continue;
+ }
+ if ( use_unicode_names_for_keys )
+ pl_dict_put( pfontdict, (const byte *)resident_table[j].unicode_fontname, 32, plfont );
+ else {
+ key[2] = (byte)j;
+ key[0] = key[1] = 0;
+ pl_dict_put( pfontdict, key, sizeof(key), plfont );
+ }
+ used = true;
+ }
+ /* If we've stored the font, null the local reference */
+ if (used) {
+ plfont = NULL;
+ pfont = NULL;
+ }
+ if (pname != symname)
+ gs_free_object(mem, pname, "pl_mt_load_font: font name buffer");
+ pname = NULL;
+ }
+ }
+ } /* end enumerate fco loop */
+
+ gs_free_object(mem, plfont, "pl_mt_load_font(pl_font_t)");
+ gs_free_object(mem, pfont, "pl_mt_load_font(gs_font_base)");
+
+ /* finally add lineprinter NB return code ignored */
+ (void)pl_load_ufst_lineprinter(mem, pfontdict, pdir, storage, use_unicode_names_for_keys);
+
+#ifdef DEBUG
+ if (gs_debug_c('=') )
+ check_resident_ufst_fonts(pfontdict, use_unicode_names_for_keys, mem);
+#endif
+
+ if (status == 0)
+ return(1);
+
+ return(0);
+#undef fontnames
+}
+
+
/* NOTES ABOUT NB NB - if the font dir necessary */
int
pl_load_built_in_fonts(const char *pathname, gs_memory_t *mem,
pl_dict_t *pfontdict, gs_font_dir *pdir,
int storage, bool use_unicode_names_for_keys)
{
+#define fontnames(agfascreenfontname, agfaname, urwname) urwname
+#include "plftable.h"
const font_resident_t *residentp;
/* get rid of this should be keyed by pjl font number */
byte key[3];
@@ -196,6 +579,12 @@ pl_load_built_in_fonts(const char *pathname, gs_memory_t *mem,
bool found;
bool found_any = false;
const char pattern[] = "*";
+ int code = 0;
+ (void)pl_built_in_resident_font_table_count;
+
+ if ((code = pl_load_built_in_mtype_fonts(pathname, mem, pfontdict, pdir, storage, use_unicode_names_for_keys))) {
+ return(code);
+ }
if (pathname == NULL) {
/* no font pathname */
@@ -347,6 +736,7 @@ pl_load_built_in_fonts(const char *pathname, gs_memory_t *mem,
check_resident_fonts(pfontdict, mem);
#endif
return found_any;
+#undef fontnames
}
/* These are not implemented */
diff --git a/pl/pllfont.h b/pl/pllfont.h
index 2af0decb1..f29361dc6 100644
--- a/pl/pllfont.h
+++ b/pl/pllfont.h
@@ -25,4 +25,8 @@
int pl_load_built_in_fonts(const char *pathname, gs_memory_t *mem, pl_dict_t *pfontdict, gs_font_dir *pdir, int storage, bool use_unicode_names_for_keys);
int pl_load_simm_fonts(const char *pathname, gs_memory_t *mem, pl_dict_t *pfontdict, gs_font_dir *pdir, int storage);
int pl_load_cartridge_fonts(const char *pathname, gs_memory_t *mem, pl_dict_t *pfontdict, gs_font_dir *pdir, int storage);
+int
+pl_load_ufst_lineprinter(gs_memory_t *mem, pl_dict_t *pfontdict, gs_font_dir *pdir,
+ int storage, bool use_unicode_names_for_keys);
+
#endif /* plfont_INCLUDED */
diff --git a/pl/plmain.c b/pl/plmain.c
index b811ed499..dd28a2362 100644
--- a/pl/plmain.c
+++ b/pl/plmain.c
@@ -212,6 +212,10 @@ close_job(pl_main_universe_t *universe, pl_main_instance_t *pti)
return pl_dnit_job(universe->curr_instance);
}
+/* temporary declaration - see below */
+void
+gs_fapi_finit(gs_memory_t *mem);
+
/* ----------- Command-line driver for pl_interp's ------ */
/*
* Here is the real main program.
@@ -239,10 +243,30 @@ pl_main_aux(
pl_platform_init(mem->gs_lib_ctx->fstdout);
+
pjl_mem = mem;
gs_lib_init1(pjl_mem);
+ {
+ int i;
+ /* Noddy options check for "-dDisableFAPI" or "-DDisableFAPI"
+ * This is here for two reasons: first we need to handle it before
+ * the interpreter starts. Second, it's temporary, we'll remove it
+ * once FAPI has matured a little.
+ * We don't need to remove the param, the later option parsing will
+ * just ignore it.
+ */
+ for (i = 1; i < argc; i++) {
+ if (!strncmp(argv[i], "-dDisableFAPI", 13)
+ || !strncmp(argv[i], "-DDisableFAPI", 13)) {
+
+ gs_fapi_finit(mem);
+ break;
+ }
+ }
+ }
+
/* Create a memory allocator to allocate various states from */
{
/*
diff --git a/pl/pluchar.c b/pl/pluchar.c
index 2cbfe3f8f..b0dff8e1f 100644
--- a/pl/pluchar.c
+++ b/pl/pluchar.c
@@ -55,9 +55,19 @@
#include "cgconfig.h"
#include "ufstport.h"
#include "shareinc.h"
+
#include "gxfapiu.h"
#include "plchar.h"
+#if UFST_VERSION_MAJOR >= 6 && UFST_VERSION_MINOR >= 2
+#undef true
+#undef false
+
+#define false FALSE
+#define true TRUE
+#define UNICODE UFST_UNICODE
+#endif
+
/* ---------------- UFST utilities ---------------- */
#define UFST_SCALE 16
@@ -164,11 +174,22 @@ static int
pl_set_ufst_font(const pl_font_t * plfont, FONTCONTEXT * pfc)
{
uint status = CGIFfont(FSA pfc);
+ FONT_METRICS fm;
if (status != 0)
dmprintf1(plfont->pfont->memory, "CGIFfont error %d\n", status);
else
- plfont_last = plfont; /* record this font for use in call-backs */
+ {
+ /* UFST 6.2 *appears* to need this to "concretize" the font
+ * we've just set.
+ */
+ status = CGIFfont_metrics(&fm);
+ if (status != 0)
+ dprintf1("CGIFfont error %d\n", status);
+ else
+ plfont_last = plfont; /* record this font for use in call-backs */
+ }
+
return status;
}
diff --git a/pl/plufont.c b/pl/plufont.c
index 76fbe18f7..d87597a33 100644
--- a/pl/plufont.c
+++ b/pl/plufont.c
@@ -41,6 +41,15 @@
#include "shareinc.h"
#include "strmio.h"
+#if UFST_VERSION_MAJOR >= 6 && UFST_VERSION_MINOR >= 2
+#undef true
+#undef false
+
+#define false FALSE
+#define true TRUE
+#define UNICODE UFST_UNICODE
+#endif
+
/* Structure descriptors */
private_st_pl_font();
diff --git a/pl/plufstlp.c b/pl/plufstlp.c
new file mode 100644
index 000000000..ee9c47279
--- /dev/null
+++ b/pl/plufstlp.c
@@ -0,0 +1,27 @@
+/* Copyright (C) 2001-2012 Artifex Software, Inc.
+ All Rights Reserved.
+
+ This software is provided AS-IS with no warranty, either express or
+ implied.
+
+ This software is distributed under license and may not be copied,
+ modified or distributed except as expressly authorized under the terms
+ of the license contained in the file LICENSE in this distribution.
+
+ Refer to licensing information at http://www.artifex.com or contact
+ Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael,
+ CA 94903, U.S.A., +1(415)492-9861, for further information.
+*/
+
+#include "stdio_.h"
+#include "string_.h"
+#include "gsmemory.h"
+#include "gstypes.h"
+#include "gxfapi.h"
+#include "plufstlp.h"
+
+void pl_get_ulp_character_data(byte **header, byte **character_data)
+{
+ *header = NULL;
+ *character_data = NULL;
+}
diff --git a/pl/plufstlp.h b/pl/plufstlp.h
new file mode 100644
index 000000000..cf7ecd486
--- /dev/null
+++ b/pl/plufstlp.h
@@ -0,0 +1,16 @@
+/* Copyright (C) 2001-2012 Artifex Software, Inc.
+ All Rights Reserved.
+
+ This software is provided AS-IS with no warranty, either express or
+ implied.
+
+ This software is distributed under license and may not be copied,
+ modified or distributed except as expressly authorized under the terms
+ of the license contained in the file LICENSE in this distribution.
+
+ Refer to licensing information at http://www.artifex.com or contact
+ Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael,
+ CA 94903, U.S.A., +1(415)492-9861, for further information.
+*/
+
+void pl_get_ulp_character_data(byte **header, byte **character_data);
diff --git a/pl/plufstlp1.c b/pl/plufstlp1.c
new file mode 100644
index 000000000..9a20935fe
--- /dev/null
+++ b/pl/plufstlp1.c
@@ -0,0 +1,27 @@
+/* Copyright (C) 2001-2012 Artifex Software, Inc.
+ All Rights Reserved.
+
+ This software is provided AS-IS with no warranty, either express or
+ implied.
+
+ This software is distributed under license and may not be copied,
+ modified or distributed except as expressly authorized under the terms
+ of the license contained in the file LICENSE in this distribution.
+
+ Refer to licensing information at http://www.artifex.com or contact
+ Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael,
+ CA 94903, U.S.A., +1(415)492-9861, for further information.
+*/
+#include "stdio_.h"
+#include "string_.h"
+#include "gsmemory.h"
+#include "gstypes.h"
+#include "plufstlp.h"
+
+#include "plulp.c"
+
+void pl_get_ulp_character_data(byte **header, byte **character_data)
+{
+ *header = pl_ulp_header;
+ *character_data = pl_ulp_character_data;
+}
diff --git a/pl/plulfont.c b/pl/plulfont.c
index 34f540d2d..4a40bbc13 100644
--- a/pl/plulfont.c
+++ b/pl/plulfont.c
@@ -20,6 +20,7 @@
#include "string_.h"
#include "gsmemory.h"
#include "gstypes.h"
+#include "gserrors.h"
#include "gp.h"
#include "gpgetenv.h"
#include "plfont.h"
@@ -41,6 +42,15 @@
#include "shareinc.h"
#include "gxfapiu.h"
+#if UFST_VERSION_MAJOR >= 6 && UFST_VERSION_MINOR >= 2
+#undef true
+#undef false
+
+#define false FALSE
+#define true TRUE
+#define UNICODE UFST_UNICODE
+#endif
+
/* the line printer font NB FIXME use a header file. */
#include "plulp.c"
/* global warning. ufst state structure passed to each ufst function */
@@ -311,7 +321,9 @@ pl_load_built_in_fonts(const char *pathname, gs_memory_t *mem, pl_dict_t *pfontd
int err_cd;
if (strcmp(resident_table[j].full_font_name, pname) != 0)
continue;
+
err_cd = pl_load_mt_font(fcoHandle, pdir, mem, i, &plfont);
+
if (err_cd != 0)
return gs_throw1(err_cd, "An unrecoverable failure occurred while loading the resident font %s\n", pname);
else {
diff --git a/pxl/pxfont.c b/pxl/pxfont.c
index 92ac2d530..229c46405 100644
--- a/pxl/pxfont.c
+++ b/pxl/pxfont.c
@@ -42,6 +42,19 @@
#include "gzstate.h"
#include "pxptable.h"
+#include "plfapi.h"
+
+/* ---------------- Initialization ---------------- */
+
+int
+pxfont_init(px_state_t *pxs)
+{ /* Allocate the font directory now. */
+ pxs->font_dir = gs_font_dir_alloc(pxs->memory);
+ if ( pxs->font_dir == 0 )
+ return_error(errorInsufficientMemory);
+ return 0;
+}
+
/* ---------------- Operator utilities ---------------- */
static const pl_symbol_map_t *
@@ -144,6 +157,7 @@ int
px_define_font(px_font_t *pxfont, byte *header, ulong size, gs_id id, px_state_t *pxs)
{ gs_memory_t *mem = pxs->memory;
uint num_chars;
+ int code = 0;
/* Check for a valid font. */
if ( size < 8 /* header */ + 6 /* 1 required segment */ +
@@ -245,7 +259,15 @@ px_define_font(px_font_t *pxfont, byte *header, ulong size, gs_id id, px_state_t
pxfont->is_xl_format = false;
}
- return gs_definefont(pxs->font_dir, pxfont->pfont);
+ if ((code = gs_definefont(pxs->font_dir, pxfont->pfont)) < 0) {
+ return(code);
+ }
+
+ if (pxfont->scaling_technology == plfst_TrueType) {
+ code = pl_fapi_passfont(pxfont, 0, NULL, NULL, NULL, 0);
+ }
+
+ return(code);
}
/* Concatenate a widened (16-bit) font name onto an error message string. */
diff --git a/pxl/pxl.mak b/pxl/pxl.mak
index bf306685a..fea40939f 100644
--- a/pxl/pxl.mak
+++ b/pxl/pxl.mak
@@ -148,7 +148,7 @@ $(PXLOBJ)pxfont.$(OBJ): $(PXLSRC)pxfont.c $(AK) $(math__h) $(stdio__h) $(string_
$(gspaint_h) $(gspath_h) $(gsstate_h) $(gsstruct_h) $(gsutil_h)\
$(gxchar_h) $(gxfixed_h) $(gxfont_h) $(gxfont42_h) $(gxpath_h) $(gzstate_h)\
$(plvalue_h)\
- $(pxfont_h) $(pxoper_h) $(pxptable_h) $(pxstate_h)
+ $(pxfont_h) $(pxoper_h) $(pxptable_h) $(pxstate_h) $(plfapi_h)
$(PXLCCC) $(UFST_INCLUDES) $(PXLSRC)pxfont.c $(PXLO_)pxfont.$(OBJ)
$(PXLOBJ)pxgstate.$(OBJ): $(PXLSRC)pxgstate.c $(AK) $(math__h) $(memory__h) $(stdio__h)\
diff --git a/xps/ghostxps.h b/xps/ghostxps.h
index 37b2bbf90..65c218ea9 100644
--- a/xps/ghostxps.h
+++ b/xps/ghostxps.h
@@ -73,6 +73,8 @@
#include "zlib.h"
+#include "xpsfapi.h"
+
#ifndef MIN
#define MIN(a,b) ((a) < (b) ? (a) : (b))
#endif
diff --git a/xps/xps.mak b/xps/xps.mak
index cbeb9d804..d10bbe27d 100644
--- a/xps/xps.mak
+++ b/xps/xps.mak
@@ -117,6 +117,9 @@ $(XPSOBJ)xpsttf.$(OBJ): $(XPSSRC)xpsttf.c $(XPSINCLUDES)
$(XPSOBJ)xpscff.$(OBJ): $(XPSSRC)xpscff.c $(XPSINCLUDES)
$(XPSCCC) $(XPSSRC)xpscff.c $(XPSO_)xpscff.$(OBJ)
+$(XPSOBJ)xpsfapi.$(OBJ): $(XPSSRC)xpsfapi.c $(XPSINCLUDES)
+ $(XPSCCC) $(XPSSRC)xpsfapi.c $(XPSO_)xpsfapi.$(OBJ)
+
$(XPS_TOP_OBJ): $(XPSSRC)xpstop.c $(XPSGEN)pconf.h $(pltop_h) $(XPSINCLUDES)
$(CP_) $(XPSGEN)pconf.h $(XPSGEN)pconfig.h
@@ -149,6 +152,7 @@ XPS_OBJS=\
$(XPSOBJ)xpsfont.$(OBJ) \
$(XPSOBJ)xpsttf.$(OBJ) \
$(XPSOBJ)xpscff.$(OBJ) \
+ $(XPSOBJ)xpsfapi.$(OBJ)
# NB - note this is a bit squirrely. Right now the pjl interpreter is
# required and shouldn't be and PLOBJ==XPSGEN is required.
diff --git a/xps/xps_msvc.mak b/xps/xps_msvc.mak
index 959ed995d..7b1c15792 100644
--- a/xps/xps_msvc.mak
+++ b/xps/xps_msvc.mak
@@ -27,6 +27,39 @@ XPS_INCLUDED=TRUE
PL_SCALER=afs
!endif
+!ifndef FT_BRIDGE
+FT_BRIDGE=1
+!endif
+
+SHARE_FT=0
+FTSRCDIR=$(GLSRCDIR)/../freetype
+FT_CFLAGS=-I$(GLSRCDIR)/../freetype/include
+FT_LIBS=
+FT_CONFIG_SYSTEM_ZLIB=
+
+
+# Define whether to compile in UFST. Note that freetype will/must be disabled.
+# FAPI/UFST depends on UFST_BRIDGE being undefined - hence the construct below.
+# (i.e. use "UFST_BRIDGE=1" or *not to define UFST_BRIDGE to anything*)
+!ifndef UFST_BRIDGE
+UFST_BRIDGE=
+!endif
+UFST_ROOT=$(GLSRCDIR)/../ufst
+UFST_LIB_EXT=.a
+
+UFST_ROMFS_ARGS=-b \
+ -P $(UFST_ROOT)/fontdata/mtfonts/pcl45/mt3/ -d fontdata/mtfonts/pcl45/mt3/ pcl___xj.fco plug__xi.fco wd____xh.fco \
+ -P $(UFST_ROOT)/fontdata/mtfonts/pclps2/mt3/ -d fontdata/mtfonts/pclps2/mt3/ pclp2_xj.fco \
+ -c -P $(PSSRCDIR)/../lib/ -d Resource/Init/ FAPIconfig-FCO
+
+UFSTROMFONTDIR=\"%rom%fontdata/\"
+UFSTDISCFONTDIR=\"$(UFST_ROOT)/fontdata/\"
+
+
+UFST_CFLAGS=-DGCCx86
+
+
+
# If we are building MEMENTO=1, then adjust default debug flags
!if "$(MEMENTO)"=="1"
!ifndef DEBUG
diff --git a/xps/xpscff.c b/xps/xpscff.c
index b6ca4d537..9620ddf94 100644
--- a/xps/xpscff.c
+++ b/xps/xpscff.c
@@ -942,7 +942,10 @@ xps_init_postscript_font(xps_context_t *ctx, xps_font_t *font)
return gs_rethrow(code, "cannot read cff file structure");
}
- gs_definefont(ctx->fontdir, font->font);
+ if ((code = gs_definefont(ctx->fontdir, font->font)) < 0) {
+ return(code);
+ }
- return 0;
+ code = xps_fapi_passfont (font->font, NULL, NULL, font->data, font->length);
+ return code;
}
diff --git a/xps/xpsfapi.c b/xps/xpsfapi.c
new file mode 100644
index 000000000..d81abb75f
--- /dev/null
+++ b/xps/xpsfapi.c
@@ -0,0 +1,213 @@
+/* Copyright (C) 2001-2012 Artifex Software, Inc.
+ All Rights Reserved.
+
+ This software is provided AS-IS with no warranty, either express or
+ implied.
+
+ This software is distributed under license and may not be copied, modified
+ or distributed except as expressly authorized under the terms of that
+ license. Refer to licensing information at http://www.artifex.com/
+ or contact Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134,
+ San Rafael, CA 94903, U.S.A., +1(415)492-9861, for further information.
+*/
+
+/* Font API support */
+#include "memory_.h"
+#include "gsmemory.h"
+#include "gserrors.h"
+#include "gxdevice.h"
+#include "gxfont.h"
+#include "gzstate.h"
+#include "gxchar.h" /* for st_gs_show_enum */
+#include "gdebug.h"
+#include "gxfapi.h"
+
+#include "xpsfapi.h"
+
+/* forward declarations for the pl_ff_stub definition */
+static ulong
+xps_fapi_get_long(gs_fapi_font *ff, gs_fapi_font_feature var_id, int index);
+
+static int
+xps_fapi_get_glyph(gs_fapi_font *ff, int char_code, byte *buf,
+ ushort buf_length);
+
+static ushort
+xps_fapi_serialize_tt_font(gs_fapi_font *ff, void *buf, int buf_size);
+
+static int
+xps_get_glyphdirectory_data(gs_fapi_font *ff, int char_code,
+ const byte **ptr);
+
+static int
+xps_fapi_set_cache(gs_text_enum_t *penum, const gs_font_base *pbfont,
+ const gs_string *char_name, int cid,
+ const double pwidth[2], const gs_rect *pbbox,
+ const double Metrics2_sbw_default[4], bool *imagenow);
+
+static int
+xps_fapi_get_metrics(gs_fapi_font *ff, gs_string *char_name, int cid,
+ double *m, bool vertical);
+
+static const gs_fapi_font pl_ff_stub = {
+ 0, /* server_font_data */
+ 0, /* need_decrypt */
+ NULL, /* const gs_memory_t */
+ 0, /* font_file_path */
+ 0, /* full_font_buf */
+ 0, /* full_font_buf_len */
+ 0, /* subfont */
+ false, /* is_type1 */
+ false, /* is_cid */
+ false, /* is_outline_font */
+ false, /* is_mtx_skipped */
+ false, /* is_vertical */
+ {
+ {3,10}, {3,1},{3,5},{3,4},\
+ {3,3},{3,2},{3,0},{1,0},
+ {-1,-1}}, /* ttf_cmap_req */
+ 0, /* client_ctx_p */
+ 0, /* client_font_data */
+ 0, /* client_font_data2 */
+ 0, /* char_data */
+ 0, /* char_data_len */
+ 0, /* embolden */
+ NULL, /* get_word */
+ xps_fapi_get_long, /* get_long */
+ NULL, /* get_float */
+ NULL, /* get_name */
+ NULL, /* get_proc */
+ NULL, /* get_gsubr */
+ NULL, /* get_subr */
+ NULL, /* get_raw_subr */
+ xps_fapi_get_glyph, /* get_glyph */
+ xps_fapi_serialize_tt_font, /* serialize_tt_font */
+ NULL, /* get_charstring */
+ NULL, /* get_charstring_name */
+ xps_get_glyphdirectory_data, /* get_GlyphDirectory_data_ptr */
+ 0, /* get_glyphname_or_cid */
+ xps_fapi_get_metrics, /* fapi_get_metrics */
+ xps_fapi_set_cache /* fapi_set_cache */
+};
+
+static ulong
+xps_fapi_get_long(gs_fapi_font *ff, gs_fapi_font_feature var_id, int index)
+{
+ ulong value = -1;
+
+ return (value);
+}
+
+static int
+xps_fapi_get_glyph(gs_fapi_font *ff, int char_code, byte *buf,
+ ushort buf_length)
+{
+ int size = -1;
+
+ return (size);
+}
+
+static ushort
+xps_fapi_serialize_tt_font(gs_fapi_font *ff, void *buf, int buf_size)
+{
+ int code = -1;
+
+ return ((ushort) code);
+}
+
+static int
+xps_get_glyphdirectory_data(gs_fapi_font *ff, int char_code,
+ const byte **ptr)
+{
+ return (0);
+}
+
+static int
+xps_fapi_get_metrics(gs_fapi_font *ff, gs_string *char_name, int cid,
+ double *m, bool vertical)
+{
+ return (0);
+}
+
+static int
+xps_fapi_set_cache(gs_text_enum_t *penum, const gs_font_base *pbfont,
+ const gs_string *char_name, int cid,
+ const double pwidth[2], const gs_rect *pbbox,
+ const double Metrics2_sbw_default[4], bool *imagenow)
+{
+ gs_state *pgs = (gs_state *) penum->pis;
+ float w2[6];
+
+ w2[0] = pwidth[0];
+ w2[1] = pwidth[1];
+ w2[2] = pbbox->p.x;
+ w2[3] = pbbox->p.y;
+ w2[4] = pbbox->q.x;
+ w2[5] = pbbox->q.y;
+ if (pbfont->PaintType) {
+ double expand =
+ max(1.415,
+ gs_currentmiterlimit(pgs)) * gs_currentlinewidth(pgs) / 2;
+
+ w2[2] -= expand;
+ w2[3] -= expand;
+ w2[4] += expand;
+ w2[5] += expand;
+ }
+ *imagenow = true;
+ return (gs_setcachedevice((gs_show_enum *)penum, pgs, w2));
+}
+
+static int
+xps_fapi_build_char(gs_show_enum *penum, gs_state *pgs, gs_font *pfont,
+ gs_char chr, gs_glyph glyph)
+{
+ int code;
+
+ code =
+ gs_fapi_do_char(pfont, pgs,(gs_text_enum_t *)penum, NULL, false, NULL,
+ NULL, chr, glyph, 0);
+
+ return (code);
+}
+
+static void
+xps_get_server_param(gs_fapi_server *I, const char *subtype,
+ char **server_param, int *server_param_size)
+{
+ *server_param = NULL;
+ *server_param_size = 0;
+}
+
+int
+xps_fapi_passfont(gs_font *pfont, char *fapi_request, char *file_name,
+ byte *font_data, int font_data_len)
+{
+ char *fapi_id = NULL;
+ int code = 0;
+ gs_string fdata;
+
+ if (!gs_fapi_available(pfont->memory, NULL)) {
+ return (code);
+ }
+
+ fdata.data = font_data;
+ fdata.size = font_data_len;
+
+ /* The plfont should contain everything we need, but setting the client data for the server
+ * to pbfont makes as much sense as setting it to NULL.
+ */
+ gs_fapi_set_servers_client_data(pfont->memory, &pl_ff_stub, pfont);
+
+ code =
+ gs_fapi_passfont(pfont, 0, file_name, &fdata, fapi_request, NULL,
+ &fapi_id,
+ (gs_fapi_get_server_param_callback)xps_get_server_param);
+
+ if (code >= 0 && fapi_id == NULL) {
+ code = gs_error_invalidfont;
+ }
+
+ pfont->procs.build_char = xps_fapi_build_char;
+ return (code);
+}
diff --git a/xps/xpsfapi.h b/xps/xpsfapi.h
new file mode 100644
index 000000000..67e1d52f5
--- /dev/null
+++ b/xps/xpsfapi.h
@@ -0,0 +1,21 @@
+/* Copyright (C) 2001-2012 Artifex Software, Inc.
+ All Rights Reserved.
+
+ This software is provided AS-IS with no warranty, either express or
+ implied.
+
+ This software is distributed under license and may not be copied, modified
+ or distributed except as expressly authorized under the terms of that
+ license. Refer to licensing information at http://www.artifex.com/
+ or contact Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134,
+ San Rafael, CA 94903, U.S.A., +1(415)492-9861, for further information.
+*/
+
+/* Font API support */
+
+int
+xps_fapi_rebuildfont(gs_font *pfont);
+
+int
+xps_fapi_passfont(gs_font *pfont, char *fapi_request, char *file_name,
+ byte *font_data, int font_data_len);
diff --git a/xps/xpsttf.c b/xps/xpsttf.c
index b70868e74..7d3bd21e0 100644
--- a/xps/xpsttf.c
+++ b/xps/xpsttf.c
@@ -19,6 +19,7 @@
#include "ghostxps.h"
#include <gxfont.h>
+#include "xpsfapi.h"
/*
* Some extra TTF parsing magic that isn't covered by the graphics library.
@@ -321,6 +322,8 @@ xps_true_callback_build_char(gs_show_enum *penum, gs_state *pgs, gs_font *pfont,
int
xps_init_truetype_font(xps_context_t *ctx, xps_font_t *font)
{
+ int code = 0;
+
font->font = (void*) gs_alloc_struct(ctx->memory, gs_font_type42, &st_gs_font_type42, "xps_font type42");
if (!font->font)
return gs_throw(gs_error_VMerror, "out of memory");
@@ -403,7 +406,10 @@ xps_init_truetype_font(xps_context_t *ctx, xps_font_t *font)
p42->data.get_glyph_index = xps_true_get_glyph_index;
}
- gs_definefont(ctx->fontdir, font->font);
+ if ((code = gs_definefont(ctx->fontdir, font->font)) < 0) {
+ return(code);
+ }
- return 0;
+ code = xps_fapi_passfont (font->font, NULL, NULL, font->data, font->length);
+ return code;
}