aboutsummaryrefslogtreecommitdiff
path: root/libXfont/src
diff options
context:
space:
mode:
Diffstat (limited to 'libXfont/src')
-rw-r--r--libXfont/src/FreeType/Makefile.am15
-rw-r--r--libXfont/src/FreeType/Makefile.in461
-rw-r--r--libXfont/src/FreeType/ft.h95
-rw-r--r--libXfont/src/FreeType/ftenc.c246
-rw-r--r--libXfont/src/FreeType/ftfuncs.c3970
-rw-r--r--libXfont/src/FreeType/ftfuncs.h190
-rw-r--r--libXfont/src/FreeType/fttools.c148
-rw-r--r--libXfont/src/FreeType/xttcap.c731
-rw-r--r--libXfont/src/FreeType/xttcap.h135
-rw-r--r--libXfont/src/Makefile.am78
-rw-r--r--libXfont/src/Makefile.in650
-rw-r--r--libXfont/src/Speedo/Makefile.am34
-rw-r--r--libXfont/src/Speedo/Makefile.in497
-rw-r--r--libXfont/src/Speedo/adobe-iso.h200
-rw-r--r--libXfont/src/Speedo/bics-iso.h224
-rw-r--r--libXfont/src/Speedo/bics-unicode.c138
-rw-r--r--libXfont/src/Speedo/bics-unicode.h3
-rw-r--r--libXfont/src/Speedo/do_char.c809
-rw-r--r--libXfont/src/Speedo/do_trns.c498
-rw-r--r--libXfont/src/Speedo/keys.h56
-rw-r--r--libXfont/src/Speedo/out_bl2d.c772
-rw-r--r--libXfont/src/Speedo/out_blk.c706
-rw-r--r--libXfont/src/Speedo/out_outl.c290
-rw-r--r--libXfont/src/Speedo/out_scrn.c1090
-rw-r--r--libXfont/src/Speedo/out_util.c339
-rw-r--r--libXfont/src/Speedo/reset.c129
-rw-r--r--libXfont/src/Speedo/set_spcs.c763
-rw-r--r--libXfont/src/Speedo/set_trns.c1214
-rw-r--r--libXfont/src/Speedo/spdo_prv.h262
-rw-r--r--libXfont/src/Speedo/speedo.h874
-rw-r--r--libXfont/src/Speedo/spencode.c67
-rw-r--r--libXfont/src/Speedo/sperr.c127
-rw-r--r--libXfont/src/Speedo/spfile.c460
-rw-r--r--libXfont/src/Speedo/spfont.c453
-rw-r--r--libXfont/src/Speedo/spfuncs.c167
-rw-r--r--libXfont/src/Speedo/spglyph.c399
-rw-r--r--libXfont/src/Speedo/spinfo.c462
-rw-r--r--libXfont/src/Speedo/spint.h178
-rw-r--r--libXfont/src/Speedo/useropt.h41
-rw-r--r--libXfont/src/Type1/Makefile.am52
-rw-r--r--libXfont/src/Type1/Makefile.in516
-rw-r--r--libXfont/src/Type1/arith.c212
-rw-r--r--libXfont/src/Type1/arith.h71
-rw-r--r--libXfont/src/Type1/blues.h95
-rw-r--r--libXfont/src/Type1/cluts.h35
-rw-r--r--libXfont/src/Type1/curves.c228
-rw-r--r--libXfont/src/Type1/curves.h44
-rw-r--r--libXfont/src/Type1/digit.h64
-rw-r--r--libXfont/src/Type1/fontfcn.c317
-rw-r--r--libXfont/src/Type1/fontfcn.h114
-rw-r--r--libXfont/src/Type1/fonts.h49
-rw-r--r--libXfont/src/Type1/hdigit.h94
-rw-r--r--libXfont/src/Type1/hints.c890
-rw-r--r--libXfont/src/Type1/hints.h48
-rw-r--r--libXfont/src/Type1/lines.c188
-rw-r--r--libXfont/src/Type1/lines.h37
-rw-r--r--libXfont/src/Type1/objects.c944
-rw-r--r--libXfont/src/Type1/objects.h293
-rw-r--r--libXfont/src/Type1/paths.c748
-rw-r--r--libXfont/src/Type1/paths.h205
-rw-r--r--libXfont/src/Type1/pictures.h50
-rw-r--r--libXfont/src/Type1/regions.c1328
-rw-r--r--libXfont/src/Type1/regions.h224
-rw-r--r--libXfont/src/Type1/scanfont.c1526
-rw-r--r--libXfont/src/Type1/spaces.c941
-rw-r--r--libXfont/src/Type1/spaces.h151
-rw-r--r--libXfont/src/Type1/strokes.h38
-rw-r--r--libXfont/src/Type1/t1funcs.c754
-rw-r--r--libXfont/src/Type1/t1hdigit.h40
-rw-r--r--libXfont/src/Type1/t1imager.h84
-rw-r--r--libXfont/src/Type1/t1info.c496
-rw-r--r--libXfont/src/Type1/t1intf.h54
-rw-r--r--libXfont/src/Type1/t1io.c299
-rw-r--r--libXfont/src/Type1/t1malloc.c759
-rw-r--r--libXfont/src/Type1/t1snap.c85
-rw-r--r--libXfont/src/Type1/t1stdio.h94
-rw-r--r--libXfont/src/Type1/t1unicode.c251
-rw-r--r--libXfont/src/Type1/t1unicode.h25
-rw-r--r--libXfont/src/Type1/token.c1208
-rw-r--r--libXfont/src/Type1/token.h79
-rw-r--r--libXfont/src/Type1/tokst.h510
-rw-r--r--libXfont/src/Type1/trig.h41
-rw-r--r--libXfont/src/Type1/type1.c1797
-rw-r--r--libXfont/src/Type1/util.c194
-rw-r--r--libXfont/src/Type1/util.h190
-rw-r--r--libXfont/src/bitmap/Makefile.am19
-rw-r--r--libXfont/src/bitmap/Makefile.in473
-rw-r--r--libXfont/src/bitmap/bdfread.c967
-rw-r--r--libXfont/src/bitmap/bdfutils.c340
-rw-r--r--libXfont/src/bitmap/bitmap.c160
-rw-r--r--libXfont/src/bitmap/bitmapfunc.c265
-rw-r--r--libXfont/src/bitmap/bitmaputil.c232
-rw-r--r--libXfont/src/bitmap/bitscale.c1987
-rw-r--r--libXfont/src/bitmap/fontink.c219
-rw-r--r--libXfont/src/bitmap/pcfread.c1024
-rw-r--r--libXfont/src/bitmap/pcfwrite.c468
-rw-r--r--libXfont/src/bitmap/snfread.c514
-rw-r--r--libXfont/src/bitmap/snfstr.h184
-rw-r--r--libXfont/src/builtins/Makefile.am17
-rw-r--r--libXfont/src/builtins/Makefile.in463
-rw-r--r--libXfont/src/builtins/buildfont14
-rw-r--r--libXfont/src/builtins/builtin.h64
-rw-r--r--libXfont/src/builtins/dir.c217
-rw-r--r--libXfont/src/builtins/file.c133
-rw-r--r--libXfont/src/builtins/fonts.c1255
-rw-r--r--libXfont/src/builtins/fpe.c95
-rw-r--r--libXfont/src/builtins/render.c136
-rw-r--r--libXfont/src/dummy.c0
-rw-r--r--libXfont/src/fc/Makefile.am16
-rw-r--r--libXfont/src/fc/Makefile.in462
-rw-r--r--libXfont/src/fc/fsconvert.c724
-rw-r--r--libXfont/src/fc/fserve.c3269
-rw-r--r--libXfont/src/fc/fserve.h93
-rw-r--r--libXfont/src/fc/fservestr.h202
-rw-r--r--libXfont/src/fc/fsio.c454
-rw-r--r--libXfont/src/fc/fsio.h180
-rw-r--r--libXfont/src/fc/fslibos.h220
-rw-r--r--libXfont/src/fc/fstrans.c28
-rw-r--r--libXfont/src/fontfile/Makefile.am36
-rw-r--r--libXfont/src/fontfile/Makefile.in487
-rw-r--r--libXfont/src/fontfile/bitsource.c174
-rw-r--r--libXfont/src/fontfile/bufio.c206
-rw-r--r--libXfont/src/fontfile/bunzip2.c179
-rw-r--r--libXfont/src/fontfile/catalogue.c478
-rw-r--r--libXfont/src/fontfile/decompress.c410
-rw-r--r--libXfont/src/fontfile/defaults.c77
-rw-r--r--libXfont/src/fontfile/dirfile.c495
-rw-r--r--libXfont/src/fontfile/ffcheck.c188
-rw-r--r--libXfont/src/fontfile/fileio.c99
-rw-r--r--libXfont/src/fontfile/filewr.c65
-rw-r--r--libXfont/src/fontfile/fontdir.c833
-rw-r--r--libXfont/src/fontfile/fontencc.c77
-rw-r--r--libXfont/src/fontfile/fontfile.c1152
-rw-r--r--libXfont/src/fontfile/fontscale.c447
-rw-r--r--libXfont/src/fontfile/gunzip.c227
-rw-r--r--libXfont/src/fontfile/printerfont.c178
-rw-r--r--libXfont/src/fontfile/register.c124
-rw-r--r--libXfont/src/fontfile/renderers.c117
-rw-r--r--libXfont/src/stubs/Makefile.am27
-rw-r--r--libXfont/src/stubs/Makefile.in491
-rw-r--r--libXfont/src/stubs/cauthgen.c14
-rw-r--r--libXfont/src/stubs/csignal.c14
-rw-r--r--libXfont/src/stubs/delfntcid.c13
-rw-r--r--libXfont/src/stubs/errorf.c13
-rw-r--r--libXfont/src/stubs/fatalerror.c13
-rw-r--r--libXfont/src/stubs/findoldfnt.c14
-rw-r--r--libXfont/src/stubs/fontmod.c14
-rw-r--r--libXfont/src/stubs/getcres.c14
-rw-r--r--libXfont/src/stubs/getdefptsize.c14
-rw-r--r--libXfont/src/stubs/getnewfntcid.c14
-rw-r--r--libXfont/src/stubs/gettime.c14
-rw-r--r--libXfont/src/stubs/initfshdl.c15
-rw-r--r--libXfont/src/stubs/regfpefunc.c28
-rw-r--r--libXfont/src/stubs/rmfshdl.c15
-rw-r--r--libXfont/src/stubs/servclient.c10
-rw-r--r--libXfont/src/stubs/setfntauth.c14
-rw-r--r--libXfont/src/stubs/stfntcfnt.c14
-rw-r--r--libXfont/src/stubs/stubs.h31
-rw-r--r--libXfont/src/stubs/xpstubs.c21
-rw-r--r--libXfont/src/util/Makefile.am19
-rw-r--r--libXfont/src/util/Makefile.in473
-rw-r--r--libXfont/src/util/atom.c246
-rw-r--r--libXfont/src/util/fontaccel.c107
-rw-r--r--libXfont/src/util/fontnames.c123
-rw-r--r--libXfont/src/util/fontutil.c443
-rw-r--r--libXfont/src/util/fontxlfd.c637
-rw-r--r--libXfont/src/util/format.c126
-rw-r--r--libXfont/src/util/miscutil.c109
-rw-r--r--libXfont/src/util/patcache.c221
-rw-r--r--libXfont/src/util/private.c107
-rw-r--r--libXfont/src/util/utilbitmap.c188
171 files changed, 58992 insertions, 0 deletions
diff --git a/libXfont/src/FreeType/Makefile.am b/libXfont/src/FreeType/Makefile.am
new file mode 100644
index 000000000..fa45da120
--- /dev/null
+++ b/libXfont/src/FreeType/Makefile.am
@@ -0,0 +1,15 @@
+INCLUDES = \
+ -I${top_srcdir}/include
+
+noinst_LTLIBRARIES = libft.la
+
+AM_CFLAGS = $(FREETYPE_CFLAGS) $(XFONT_CFLAGS) $(OS_CFLAGS) $(CWARNFLAGS)
+
+libft_la_SOURCES = \
+ ft.h \
+ ftfuncs.h \
+ xttcap.h \
+ ftenc.c \
+ ftfuncs.c \
+ fttools.c \
+ xttcap.c
diff --git a/libXfont/src/FreeType/Makefile.in b/libXfont/src/FreeType/Makefile.in
new file mode 100644
index 000000000..300e3d01f
--- /dev/null
+++ b/libXfont/src/FreeType/Makefile.in
@@ -0,0 +1,461 @@
+# Makefile.in generated by automake 1.10 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
+# 2003, 2004, 2005, 2006 Free Software Foundation, Inc.
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+@SET_MAKE@
+
+VPATH = @srcdir@
+pkgdatadir = $(datadir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+install_sh_DATA = $(install_sh) -c -m 644
+install_sh_PROGRAM = $(install_sh) -c
+install_sh_SCRIPT = $(install_sh) -c
+INSTALL_HEADER = $(INSTALL_DATA)
+transform = $(program_transform_name)
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+build_triplet = @build@
+host_triplet = @host@
+subdir = src/FreeType
+DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/configure.ac
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+ $(ACLOCAL_M4)
+mkinstalldirs = $(install_sh) -d
+CONFIG_HEADER = $(top_builddir)/config.h \
+ $(top_builddir)/include/X11/fonts/fontconf.h
+CONFIG_CLEAN_FILES =
+LTLIBRARIES = $(noinst_LTLIBRARIES)
+libft_la_LIBADD =
+am_libft_la_OBJECTS = ftenc.lo ftfuncs.lo fttools.lo xttcap.lo
+libft_la_OBJECTS = $(am_libft_la_OBJECTS)
+DEFAULT_INCLUDES = -I. -I$(top_builddir) -I$(top_builddir)/include/X11/fonts@am__isrc@
+depcomp = $(SHELL) $(top_srcdir)/depcomp
+am__depfiles_maybe = depfiles
+COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
+ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+LTCOMPILE = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
+ --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \
+ $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+CCLD = $(CC)
+LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
+ --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \
+ $(LDFLAGS) -o $@
+SOURCES = $(libft_la_SOURCES)
+DIST_SOURCES = $(libft_la_SOURCES)
+ETAGS = etags
+CTAGS = ctags
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+ACLOCAL = @ACLOCAL@
+AMTAR = @AMTAR@
+AR = @AR@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+CC = @CC@
+CCDEPMODE = @CCDEPMODE@
+CFLAGS = @CFLAGS@
+CHANGELOG_CMD = @CHANGELOG_CMD@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CWARNFLAGS = @CWARNFLAGS@
+CXX = @CXX@
+CXXCPP = @CXXCPP@
+CXXDEPMODE = @CXXDEPMODE@
+CXXFLAGS = @CXXFLAGS@
+CYGPATH_W = @CYGPATH_W@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+ECHO = @ECHO@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+EGREP = @EGREP@
+ENCODINGSDIR = @ENCODINGSDIR@
+EXEEXT = @EXEEXT@
+F77 = @F77@
+FFLAGS = @FFLAGS@
+FREETYPE_CFLAGS = @FREETYPE_CFLAGS@
+FREETYPE_LIBS = @FREETYPE_LIBS@
+FREETYPE_REQUIRES = @FREETYPE_REQUIRES@
+GREP = @GREP@
+INSTALL = @INSTALL@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+LDFLAGS = @LDFLAGS@
+LIBOBJS = @LIBOBJS@
+LIBS = @LIBS@
+LIBTOOL = @LIBTOOL@
+LN_S = @LN_S@
+LTLIBOBJS = @LTLIBOBJS@
+MAKEINFO = @MAKEINFO@
+MATH_LIBS = @MATH_LIBS@
+MKDIR_P = @MKDIR_P@
+OBJEXT = @OBJEXT@
+OS_CFLAGS = @OS_CFLAGS@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+PKG_CONFIG = @PKG_CONFIG@
+RANLIB = @RANLIB@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+STRIP = @STRIP@
+VERSION = @VERSION@
+XFONT_CFLAGS = @XFONT_CFLAGS@
+XFONT_LIBS = @XFONT_LIBS@
+X_GZIP_FONT_COMPRESSION = @X_GZIP_FONT_COMPRESSION@
+Z_LIBS = @Z_LIBS@
+abs_builddir = @abs_builddir@
+abs_srcdir = @abs_srcdir@
+abs_top_builddir = @abs_top_builddir@
+abs_top_srcdir = @abs_top_srcdir@
+ac_ct_CC = @ac_ct_CC@
+ac_ct_CXX = @ac_ct_CXX@
+ac_ct_F77 = @ac_ct_F77@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+am__tar = @am__tar@
+am__untar = @am__untar@
+bindir = @bindir@
+build = @build@
+build_alias = @build_alias@
+build_cpu = @build_cpu@
+build_os = @build_os@
+build_vendor = @build_vendor@
+builddir = @builddir@
+datadir = @datadir@
+datarootdir = @datarootdir@
+distcleancheck_listfiles = @distcleancheck_listfiles@
+docdir = @docdir@
+dvidir = @dvidir@
+exec_prefix = @exec_prefix@
+ft_config = @ft_config@
+host = @host@
+host_alias = @host_alias@
+host_cpu = @host_cpu@
+host_os = @host_os@
+host_vendor = @host_vendor@
+htmldir = @htmldir@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+libdir = @libdir@
+libexecdir = @libexecdir@
+localedir = @localedir@
+localstatedir = @localstatedir@
+mandir = @mandir@
+mkdir_p = @mkdir_p@
+oldincludedir = @oldincludedir@
+pdfdir = @pdfdir@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+psdir = @psdir@
+sbindir = @sbindir@
+sharedstatedir = @sharedstatedir@
+srcdir = @srcdir@
+sysconfdir = @sysconfdir@
+target_alias = @target_alias@
+top_builddir = @top_builddir@
+top_srcdir = @top_srcdir@
+INCLUDES = \
+ -I${top_srcdir}/include
+
+noinst_LTLIBRARIES = libft.la
+AM_CFLAGS = $(FREETYPE_CFLAGS) $(XFONT_CFLAGS) $(OS_CFLAGS) $(CWARNFLAGS)
+libft_la_SOURCES = \
+ ft.h \
+ ftfuncs.h \
+ xttcap.h \
+ ftenc.c \
+ ftfuncs.c \
+ fttools.c \
+ xttcap.c
+
+all: all-am
+
+.SUFFIXES:
+.SUFFIXES: .c .lo .o .obj
+$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps)
+ @for dep in $?; do \
+ case '$(am__configure_deps)' in \
+ *$$dep*) \
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh \
+ && exit 0; \
+ exit 1;; \
+ esac; \
+ done; \
+ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign src/FreeType/Makefile'; \
+ cd $(top_srcdir) && \
+ $(AUTOMAKE) --foreign src/FreeType/Makefile
+.PRECIOUS: Makefile
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+ @case '$?' in \
+ *config.status*) \
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
+ *) \
+ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
+ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
+ esac;
+
+$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+
+$(top_srcdir)/configure: $(am__configure_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(ACLOCAL_M4): $(am__aclocal_m4_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+
+clean-noinstLTLIBRARIES:
+ -test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES)
+ @list='$(noinst_LTLIBRARIES)'; for p in $$list; do \
+ dir="`echo $$p | sed -e 's|/[^/]*$$||'`"; \
+ test "$$dir" != "$$p" || dir=.; \
+ echo "rm -f \"$${dir}/so_locations\""; \
+ rm -f "$${dir}/so_locations"; \
+ done
+libft.la: $(libft_la_OBJECTS) $(libft_la_DEPENDENCIES)
+ $(LINK) $(libft_la_OBJECTS) $(libft_la_LIBADD) $(LIBS)
+
+mostlyclean-compile:
+ -rm -f *.$(OBJEXT)
+
+distclean-compile:
+ -rm -f *.tab.c
+
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ftenc.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ftfuncs.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fttools.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/xttcap.Plo@am__quote@
+
+.c.o:
+@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
+@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(COMPILE) -c $<
+
+.c.obj:
+@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'`
+@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(COMPILE) -c `$(CYGPATH_W) '$<'`
+
+.c.lo:
+@am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
+@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(LTCOMPILE) -c -o $@ $<
+
+mostlyclean-libtool:
+ -rm -f *.lo
+
+clean-libtool:
+ -rm -rf .libs _libs
+
+ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) ' { files[$$0] = 1; } \
+ END { for (i in files) print i; }'`; \
+ mkid -fID $$unique
+tags: TAGS
+
+TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
+ $(TAGS_FILES) $(LISP)
+ tags=; \
+ here=`pwd`; \
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) ' { files[$$0] = 1; } \
+ END { for (i in files) print i; }'`; \
+ if test -z "$(ETAGS_ARGS)$$tags$$unique"; then :; else \
+ test -n "$$unique" || unique=$$empty_fix; \
+ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+ $$tags $$unique; \
+ fi
+ctags: CTAGS
+CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
+ $(TAGS_FILES) $(LISP)
+ tags=; \
+ here=`pwd`; \
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) ' { files[$$0] = 1; } \
+ END { for (i in files) print i; }'`; \
+ test -z "$(CTAGS_ARGS)$$tags$$unique" \
+ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
+ $$tags $$unique
+
+GTAGS:
+ here=`$(am__cd) $(top_builddir) && pwd` \
+ && cd $(top_srcdir) \
+ && gtags -i $(GTAGS_ARGS) $$here
+
+distclean-tags:
+ -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
+
+distdir: $(DISTFILES)
+ @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ list='$(DISTFILES)'; \
+ dist_files=`for file in $$list; do echo $$file; done | \
+ sed -e "s|^$$srcdirstrip/||;t" \
+ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
+ case $$dist_files in \
+ */*) $(MKDIR_P) `echo "$$dist_files" | \
+ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
+ sort -u` ;; \
+ esac; \
+ for file in $$dist_files; do \
+ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
+ if test -d $$d/$$file; then \
+ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
+ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
+ cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \
+ fi; \
+ cp -pR $$d/$$file $(distdir)$$dir || exit 1; \
+ else \
+ test -f $(distdir)/$$file \
+ || cp -p $$d/$$file $(distdir)/$$file \
+ || exit 1; \
+ fi; \
+ done
+check-am: all-am
+check: check-am
+all-am: Makefile $(LTLIBRARIES)
+installdirs:
+install: install-am
+install-exec: install-exec-am
+install-data: install-data-am
+uninstall: uninstall-am
+
+install-am: all-am
+ @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-am
+install-strip:
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ `test -z '$(STRIP)' || \
+ echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
+mostlyclean-generic:
+
+clean-generic:
+
+distclean-generic:
+ -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
+
+maintainer-clean-generic:
+ @echo "This command is intended for maintainers to use"
+ @echo "it deletes files that may require special tools to rebuild."
+clean: clean-am
+
+clean-am: clean-generic clean-libtool clean-noinstLTLIBRARIES \
+ mostlyclean-am
+
+distclean: distclean-am
+ -rm -rf ./$(DEPDIR)
+ -rm -f Makefile
+distclean-am: clean-am distclean-compile distclean-generic \
+ distclean-tags
+
+dvi: dvi-am
+
+dvi-am:
+
+html: html-am
+
+info: info-am
+
+info-am:
+
+install-data-am:
+
+install-dvi: install-dvi-am
+
+install-exec-am:
+
+install-html: install-html-am
+
+install-info: install-info-am
+
+install-man:
+
+install-pdf: install-pdf-am
+
+install-ps: install-ps-am
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-am
+ -rm -rf ./$(DEPDIR)
+ -rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-am
+
+mostlyclean-am: mostlyclean-compile mostlyclean-generic \
+ mostlyclean-libtool
+
+pdf: pdf-am
+
+pdf-am:
+
+ps: ps-am
+
+ps-am:
+
+uninstall-am:
+
+.MAKE: install-am install-strip
+
+.PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \
+ clean-libtool clean-noinstLTLIBRARIES ctags distclean \
+ distclean-compile distclean-generic distclean-libtool \
+ distclean-tags distdir dvi dvi-am html html-am info info-am \
+ install install-am install-data install-data-am install-dvi \
+ install-dvi-am install-exec install-exec-am install-html \
+ install-html-am install-info install-info-am install-man \
+ install-pdf install-pdf-am install-ps install-ps-am \
+ install-strip installcheck installcheck-am installdirs \
+ maintainer-clean maintainer-clean-generic mostlyclean \
+ mostlyclean-compile mostlyclean-generic mostlyclean-libtool \
+ pdf pdf-am ps ps-am tags uninstall uninstall-am
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/libXfont/src/FreeType/ft.h b/libXfont/src/FreeType/ft.h
new file mode 100644
index 000000000..7560c8dd1
--- /dev/null
+++ b/libXfont/src/FreeType/ft.h
@@ -0,0 +1,95 @@
+/*
+Copyright (c) 1997 by Mark Leisher
+Copyright (c) 1998-2002 by Juliusz Chroboczek
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
+*/
+
+/* $XFree86: xc/lib/font/FreeType/ft.h,v 1.22 2003/06/08 15:41:13 herrb Exp $ */
+
+#ifndef _FT_H_
+#define _FT_H_
+
+#include <X11/Xfuncproto.h>
+
+#define FREETYPE_VERSION (FREETYPE_MAJOR * 1000000 + FREETYPE_MINOR * 1000 + FREETYPE_PATCH)
+
+#undef DEBUG_TRUETYPE
+
+#ifdef DEBUG_TRUETYPE
+#define MUMBLE(s) (ErrorF((s)))
+#define MUMBLE1(s,x) (ErrorF((s),(x)))
+#else
+#define MUMBLE(s)
+#define MUMBLE1(s,x)
+#endif
+
+#undef MAX
+#define MAX(h,i) ((h) > (i) ? (h) : (i))
+#define ADJUSTMAX(m,v) if((v)>(m)) (m)=(v)
+#undef MIN
+#define MIN(l,o) ((l) < (o) ? (l) : (o))
+#define ADJUSTMIN(m,v) if ((v)<(m)) (m)=(v)
+
+/* When comparing floating point values, we want to ignore small errors. */
+#define NEGLIGIBLE ((double)0.001)
+/* Are x and y significantly different? */
+#define DIFFER(x,y) (fabs((x)-(y))>=NEGLIGIBLE*fabs(x))
+/* Is x significantly different from 0 w.r.t. y? */
+#define DIFFER0(x,y) (fabs(x)>=NEGLIGIBLE*fabs(y))
+
+#ifndef ABS
+#define ABS(x) ((x) >= 0 ? (x) : -(x))
+#endif
+
+/* Two to the sixteenth power, as a double. */
+#define TWO_SIXTEENTH ((double)(1<<16))
+#define TWO_SIXTH ((double)(1<<6))
+
+/* Data structures used across files */
+
+typedef struct _FTMapping
+{
+ int named;
+ FT_CharMap cmap;
+ int base;
+ struct _FontMap *mapping; /* allow inclusion without fontenc.h */
+} FTMappingRec, *FTMappingPtr;
+
+/* Prototypes */
+
+/* ftfuncs.c */
+
+#if 0
+void FreeTypeRegisterFontFileFunctions(void);
+#endif
+
+/* ftenc.c */
+
+int FTPickMapping(char*, int, char*, FT_Face, FTMappingPtr);
+unsigned FTRemap(FT_Face face, FTMappingPtr, unsigned code);
+
+/* fttools.c */
+
+int FTtoXReturnCode(int);
+int FTGetEnglishName(FT_Face, int, char *, int);
+
+extern void ErrorF(const char*, ...);
+
+#endif /* _FT_H_ */
diff --git a/libXfont/src/FreeType/ftenc.c b/libXfont/src/FreeType/ftenc.c
new file mode 100644
index 000000000..f6436fc40
--- /dev/null
+++ b/libXfont/src/FreeType/ftenc.c
@@ -0,0 +1,246 @@
+/*
+Copyright (c) 1998-2003 by Juliusz Chroboczek
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
+*/
+/* $XFree86: xc/lib/font/FreeType/ftenc.c,v 1.24 2003/10/19 18:53:49 dawes Exp $ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#ifndef FONTMODULE
+#include <string.h>
+#else
+#include "Xmd.h"
+#include "Xdefs.h"
+#include "xf86_ansic.h"
+#endif
+
+#include <X11/fonts/fntfilst.h>
+#include <X11/fonts/fontutil.h>
+#include <X11/fonts/FSproto.h>
+
+#include <X11/fonts/fontmisc.h>
+#include <X11/fonts/fontenc.h>
+#include <ft2build.h>
+#include FT_FREETYPE_H
+#include FT_TRUETYPE_IDS_H
+#include FT_TRUETYPE_TABLES_H
+#include FT_TYPE1_TABLES_H
+#include FT_BDF_H
+#include FT_XFREE86_H
+#include "ft.h"
+
+static int find_cmap(int, int, int, FT_Face, FT_CharMap *);
+
+static int
+FTEncFontSpecific(char *encoding)
+{
+ char *p = encoding;
+
+ if(strcasecmp(encoding, "microsoft-symbol") == 0)
+ return 1;
+
+ while(*p != '-') {
+ if(*p == '\0')
+ return 0;
+ p++;
+ }
+ p++;
+ return (strcasecmp(p, "fontspecific") == 0);
+}
+
+int
+FTPickMapping(char *xlfd, int length, char *filename, FT_Face face,
+ FTMappingPtr tm)
+{
+ FontEncPtr encoding;
+ FontMapPtr mapping;
+ FT_CharMap cmap;
+ int ftrc;
+ int symbol = 0;
+ const char *enc, *reg;
+ char *encoding_name = 0;
+ char buf[20];
+
+ if(xlfd)
+ encoding_name = FontEncFromXLFD(xlfd, length);
+ if(!encoding_name)
+ encoding_name = "iso8859-1";
+
+ symbol = FTEncFontSpecific(encoding_name);
+
+#if XFONT_BDFFORMAT
+ ftrc = FT_Get_BDF_Charset_ID(face, &enc, &reg);
+#else
+ ftrc = -1;
+#endif
+ if(ftrc == 0) {
+ /* Disable reencoding for non-Unicode fonts. This will
+ currently only work for BDFs. */
+ if(strlen(enc) + strlen(reg) > 18)
+ goto native;
+ strcpy(buf, enc);
+ strcat(buf, "-");
+ strcat(buf, reg);
+ ErrorF("%s %s\n", buf, encoding_name);
+ if(strcasecmp(buf, "iso10646-1") != 0) {
+ if(strcasecmp(buf, encoding_name) == 0)
+ goto native;
+ return BadFontFormat;
+ }
+ } else if(symbol) {
+ ftrc = FT_Select_Charmap(face, ft_encoding_adobe_custom);
+ if(ftrc == 0)
+ goto native;
+ }
+
+ encoding = FontEncFind(encoding_name, filename);
+ if(symbol && encoding == NULL)
+ encoding = FontEncFind("microsoft-symbol", filename);
+ if(encoding == NULL) {
+ ErrorF("FreeType: couldn't find encoding '%s' for '%s'\n",
+ encoding_name, filename);
+ return BadFontName;
+ }
+
+ if(FT_Has_PS_Glyph_Names(face)) {
+ for(mapping = encoding->mappings; mapping; mapping = mapping->next) {
+ if(mapping->type == FONT_ENCODING_POSTSCRIPT) {
+ tm->named = 1;
+ tm->base = 0;
+ tm->mapping = mapping;
+ return Successful;
+ }
+ }
+ }
+
+ for(mapping = encoding->mappings; mapping; mapping = mapping->next) {
+ if(find_cmap(mapping->type, mapping->pid, mapping->eid, face,
+ &cmap)) {
+ tm->named = 0;
+ tm->cmap = cmap;
+ if(symbol) {
+ /* deal with an undocumented ``feature'' of the
+ Microsft-Symbol cmap */
+ TT_OS2 *os2;
+ os2 = FT_Get_Sfnt_Table(face, ft_sfnt_os2);
+ if(os2)
+ tm->base = os2->usFirstCharIndex - 0x20;
+ else
+ tm->base = 0;
+ } else
+ tm->base = 0;
+ tm->mapping = mapping;
+ return Successful;
+ }
+ }
+
+ return BadFontFormat;
+
+ native:
+ tm->named = 0;
+ tm->cmap = face->charmap;
+ tm->base = 0;
+ tm->mapping = NULL;
+ return Successful;
+}
+
+static int
+find_cmap(int type, int pid, int eid, FT_Face face, FT_CharMap *cmap_return)
+{
+ int i, n;
+ FT_CharMap cmap = NULL;
+
+ n = face->num_charmaps;
+
+ switch(type) {
+ case FONT_ENCODING_TRUETYPE: /* specific cmap */
+ for(i=0; i<n; i++) {
+ cmap = face->charmaps[i];
+ if(cmap->platform_id == pid && cmap->encoding_id == eid) {
+ *cmap_return = cmap;
+ return 1;
+ }
+ }
+ break;
+ case FONT_ENCODING_UNICODE: /* any Unicode cmap */
+ /* prefer Microsoft Unicode */
+ for(i=0; i<n; i++) {
+ cmap = face->charmaps[i];
+ if(cmap->platform_id == TT_PLATFORM_MICROSOFT &&
+ cmap->encoding_id == TT_MS_ID_UNICODE_CS) {
+ *cmap_return = cmap;
+ return 1;
+ }
+ }
+ break;
+ /* Try Apple Unicode */
+ for(i=0; i<n; i++) {
+ cmap = face->charmaps[i];
+ if(cmap->platform_id == TT_PLATFORM_APPLE_UNICODE) {
+ *cmap_return = cmap;
+ return 1;
+ }
+ }
+ /* ISO Unicode? */
+ for(i=0; i<n; i++) {
+ cmap = face->charmaps[i];
+ if(cmap->platform_id == TT_PLATFORM_ISO) {
+ *cmap_return = cmap;
+ return 1;
+ }
+ }
+ break;
+ default:
+ return 0;
+ }
+ return 0;
+}
+
+unsigned
+FTRemap(FT_Face face, FTMappingPtr tm, unsigned code)
+{
+ unsigned index;
+ char *name;
+ unsigned glyph_index;
+
+ if(tm->mapping) {
+ if(tm->named) {
+ name = FontEncName(code, tm->mapping);
+ if(!name)
+ return 0;
+ glyph_index = FT_Get_Name_Index(face, name);
+ return glyph_index;
+ } else {
+ index = FontEncRecode(code, tm->mapping) + tm->base;
+ FT_Set_Charmap(face, tm->cmap);
+ glyph_index = FT_Get_Char_Index(face, index);
+ return glyph_index;
+ }
+ } else {
+ if(code < 0x100) {
+ index = code;
+ FT_Set_Charmap(face, tm->cmap);
+ glyph_index = FT_Get_Char_Index(face, index);
+ return glyph_index;
+ } else
+ return 0;
+ }
+}
diff --git a/libXfont/src/FreeType/ftfuncs.c b/libXfont/src/FreeType/ftfuncs.c
new file mode 100644
index 000000000..fff6eec76
--- /dev/null
+++ b/libXfont/src/FreeType/ftfuncs.c
@@ -0,0 +1,3970 @@
+/*
+Copyright (c) 1997 by Mark Leisher
+Copyright (c) 1998-2003 by Juliusz Chroboczek
+Copyright (c) 1998 Go Watanabe, All rights reserved.
+Copyright (c) 1998 Kazushi (Jam) Marukawa, All rights reserved.
+Copyright (c) 1998 Takuya SHIOZAKI, All rights reserved.
+Copyright (c) 1998 X-TrueType Server Project, All rights reserved.
+Copyright (c) 2003-2004 After X-TT Project, All rights reserved.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
+*/
+/* $XdotOrg: xc/lib/font/FreeType/ftfuncs.c,v 1.11 2005/07/03 07:00:58 daniels Exp $ */
+
+/* $XFree86: xc/lib/font/FreeType/ftfuncs.c,v 1.43 2004/02/07 04:37:18 dawes Exp $ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include <X11/fonts/fontmisc.h>
+
+#ifndef FONTMODULE
+#include <string.h>
+#include <math.h>
+#else
+#include "Xmd.h"
+#include "Xdefs.h"
+#include "xf86_ansic.h"
+#endif
+#include <ctype.h>
+
+#include <X11/fonts/fntfilst.h>
+#include <X11/fonts/fontutil.h>
+#include <X11/fonts/FSproto.h>
+#include <ft2build.h>
+#include FT_FREETYPE_H
+#include FT_SIZES_H
+#include FT_TRUETYPE_IDS_H
+#include FT_TRUETYPE_TABLES_H
+#include FT_TYPE1_TABLES_H
+#include FT_XFREE86_H
+#include FT_BBOX_H
+#include FT_TRUETYPE_TAGS_H
+/*
+ * If you want to use FT_Outline_Get_CBox instead of
+ * FT_Outline_Get_BBox, define here.
+ */
+/* #define USE_GET_CBOX */
+#ifdef USE_GET_CBOX
+#include FT_OUTLINE_H
+#endif
+
+#include <X11/fonts/fontenc.h>
+#include "ft.h"
+#include "ftfuncs.h"
+#include "xttcap.h"
+
+/* Work around FreeType bug */
+#define WORK_AROUND_UPM 2048
+
+#ifndef True
+#define True (-1)
+#endif /* True */
+#ifndef False
+#define False (0)
+#endif /* False */
+
+#define FLOOR64(x) ((x) & -64)
+#define CEIL64(x) (((x) + 64 - 1) & -64)
+
+/*
+ * If you want very lazy method(vl=y) AS DEFAULT when
+ * handling large charset, define here.
+ */
+/* #define DEFAULT_VERY_LAZY 1 */ /* Always */
+#define DEFAULT_VERY_LAZY 2 /* Multi-byte only */
+/* #define DEFAULT_VERY_LAZY 256 */ /* Unicode only */
+
+/* Does the X accept noSuchChar? */
+#define X_ACCEPTS_NO_SUCH_CHAR
+/* Does the XAA accept NULL noSuchChar.bits?(dangerous) */
+/* #define XAA_ACCEPTS_NULL_BITS */
+
+#ifdef X_ACCEPTS_NO_SUCH_CHAR
+static CharInfoRec noSuchChar = { /* metrics */{0,0,0,0,0,0},
+ /* bits */ NULL };
+#endif
+
+/* The propery names for all the XLFD properties. */
+
+static char *xlfd_props[] = {
+ "FOUNDRY",
+ "FAMILY_NAME",
+ "WEIGHT_NAME",
+ "SLANT",
+ "SETWIDTH_NAME",
+ "ADD_STYLE_NAME",
+ "PIXEL_SIZE",
+ "POINT_SIZE",
+ "RESOLUTION_X",
+ "RESOLUTION_Y",
+ "SPACING",
+ "AVERAGE_WIDTH",
+ "CHARSET_REGISTRY",
+ "CHARSET_ENCODING",
+};
+
+
+/* read 2-byte value from a SFNT table */
+static FT_UShort
+sfnt_get_ushort( FT_Face face,
+ FT_ULong table_tag,
+ FT_ULong table_offset )
+{
+ FT_Byte buff[2];
+ FT_ULong len = sizeof(buff);
+ FT_UShort result = 0;
+
+ if ( !FT_Load_Sfnt_Table( face, table_tag, table_offset, buff, &len ) );
+ result = (FT_UShort)( (buff[0] << 8) | buff[1] );
+
+ return result;
+}
+
+#define sfnt_get_short(f,t,o) ((FT_Short)sfnt_get_ushort((f),(t),(o)))
+
+
+static int ftypeInitP = 0; /* is the engine initialised? */
+FT_Library ftypeLibrary;
+
+static FTFacePtr faceTable[NUMFACEBUCKETS];
+
+static unsigned
+hash(char *string)
+{
+ int i;
+ unsigned u = 0;
+ for(i = 0; string[i] != '\0'; i++)
+ u = (u<<5) + (u >> (NUMFACEBUCKETS - 5)) + (unsigned char)string[i];
+ return u;
+}
+
+static int
+ifloor(int x, int y)
+{
+ if(x >= 0)
+ return x/y;
+ else
+ return x/y - 1;
+}
+
+static int
+iceil(int x, int y)
+{
+ return ifloor(x + y - 1, y);
+}
+
+static int
+FreeTypeOpenFace(FTFacePtr *facep, char *FTFileName, char *realFileName, int faceNumber)
+{
+ FT_Error ftrc;
+ int bucket;
+ FTFacePtr face, otherFace;
+
+ if (!ftypeInitP) {
+ ftrc = FT_Init_FreeType(&ftypeLibrary);
+ if (ftrc != 0) {
+ ErrorF("FreeType: error initializing ftypeEngine: %d\n", ftrc);
+ return AllocError;
+ }
+ ftypeInitP = 1;
+ }
+
+ /* Try to find a matching face in the hashtable */
+ bucket = hash(FTFileName)%NUMFACEBUCKETS;
+ otherFace = faceTable[bucket];
+ while(otherFace) {
+ if( strcmp(otherFace->filename, FTFileName) == 0 ) break;
+ otherFace = otherFace->next;
+ }
+ if(otherFace) {
+ MUMBLE1("Returning cached face: %s\n", otherFace->filename);
+ *facep = otherFace;
+ return Successful;
+ }
+
+ /* No cached match; need to make a new one */
+ face = (FTFacePtr)xalloc(sizeof(FTFaceRec));
+ if(face == NULL) {
+ return AllocError;
+ }
+ memset(face, 0, sizeof(FTFaceRec));
+
+ face->filename = (char*)xalloc(strlen(FTFileName)+1);
+ if(face->filename == NULL) {
+ xfree(face);
+ return AllocError;
+ }
+ strcpy(face->filename, FTFileName);
+
+ ftrc = FT_New_Face(ftypeLibrary, realFileName, faceNumber, &face->face);
+ if(ftrc != 0) {
+ ErrorF("FreeType: couldn't open face %s: %d\n", FTFileName, ftrc);
+ xfree(face->filename);
+ xfree(face);
+ return BadFontName;
+ }
+
+ face->bitmap = ((face->face->face_flags & FT_FACE_FLAG_SCALABLE) == 0);
+ if(!face->bitmap) {
+ TT_MaxProfile *maxp;
+ maxp = FT_Get_Sfnt_Table(face->face, ft_sfnt_maxp);
+ if(maxp && maxp->maxContours == 0)
+ face->bitmap = 1;
+ }
+
+ face->num_hmetrics = (FT_UInt) sfnt_get_ushort( face->face,
+ TTAG_hhea, 34 );
+
+ /* Insert face in hashtable and return it */
+ face->next = faceTable[bucket];
+ faceTable[bucket] = face;
+ *facep = face;
+ return Successful;
+}
+
+static void
+FreeTypeFreeFace(FTFacePtr face)
+{
+ int bucket;
+ FTFacePtr otherFace;
+
+ if(!face->instances) {
+ bucket = hash(face->filename) % NUMFACEBUCKETS;
+ if(faceTable[bucket] == face)
+ faceTable[bucket] = face->next;
+ else {
+ otherFace = faceTable[bucket];
+ while(otherFace) {
+ if(otherFace->next == face)
+ break;
+ otherFace = otherFace->next;
+ }
+ if(otherFace && otherFace->next)
+ otherFace->next = otherFace->next->next;
+ else
+ ErrorF("FreeType: freeing unknown face\n");
+ }
+ MUMBLE1("Closing face: %s\n", face->filename);
+ FT_Done_Face(face->face);
+ xfree(face->filename);
+ xfree(face);
+ }
+}
+
+static int
+TransEqual(FTNormalisedTransformationPtr t1, FTNormalisedTransformationPtr t2)
+{
+ if(t1->scale != t2->scale)
+ return 0;
+ else if(t1->xres != t2->xres || t1->yres != t2->yres)
+ return 0;
+ else if(t1->nonIdentity != t2->nonIdentity)
+ return 0;
+ else if(t1->nonIdentity && t2->nonIdentity) {
+ return
+ t1->matrix.xx == t2->matrix.xx &&
+ t1->matrix.yx == t2->matrix.yx &&
+ t1->matrix.yy == t2->matrix.yy &&
+ t1->matrix.xy == t2->matrix.xy;
+ } else
+ return 1;
+}
+
+static int
+BitmapFormatEqual(FontBitmapFormatPtr f1, FontBitmapFormatPtr f2)
+{
+ return
+ f1->bit == f2->bit &&
+ f1->byte == f2->byte &&
+ f1->glyph == f2->glyph;
+}
+
+static int
+TTCapEqual(struct TTCapInfo *t1, struct TTCapInfo *t2)
+{
+ return
+ t1->autoItalic == t2->autoItalic &&
+ t1->scaleWidth == t2->scaleWidth &&
+ t1->scaleBBoxWidth == t2->scaleBBoxWidth &&
+ t1->scaleBBoxHeight == t2->scaleBBoxHeight &&
+ t1->doubleStrikeShift == t2->doubleStrikeShift &&
+ t1->adjustBBoxWidthByPixel == t2->adjustBBoxWidthByPixel &&
+ t1->adjustLeftSideBearingByPixel == t2->adjustLeftSideBearingByPixel &&
+ t1->adjustRightSideBearingByPixel == t2->adjustRightSideBearingByPixel &&
+ t1->flags == t2->flags &&
+ t1->scaleBitmap == t2->scaleBitmap &&
+ /*
+ If we use forceConstantSpacing,
+ we *MUST* allocate new instance.
+ */
+ t1->forceConstantSpacingEnd < 0 &&
+ t2->forceConstantSpacingEnd < 0;
+}
+
+static int
+FTInstanceMatch(FTInstancePtr instance,
+ char *FTFileName, FTNormalisedTransformationPtr trans,
+ int spacing, FontBitmapFormatPtr bmfmt,
+ struct TTCapInfo *tmp_ttcap, FT_Int32 load_flags)
+{
+ if(strcmp(instance->face->filename, FTFileName) != 0) {
+ return 0;
+ } else if(!TransEqual(&instance->transformation, trans)) {
+ return 0;
+ } else if( spacing != instance->spacing ) {
+ return 0;
+ } else if( load_flags != instance->load_flags ) {
+ return 0;
+ } else if(!BitmapFormatEqual(&instance->bmfmt, bmfmt)) {
+ return 0;
+ } else if(!TTCapEqual(&instance->ttcap, tmp_ttcap)) {
+ return 0;
+ } else {
+ return 1;
+ }
+}
+
+static int
+FreeTypeActivateInstance(FTInstancePtr instance)
+{
+ FT_Error ftrc;
+ if(instance->face->active_instance == instance)
+ return Successful;
+
+ ftrc = FT_Activate_Size(instance->size);
+ if(ftrc != 0) {
+ instance->face->active_instance = NULL;
+ ErrorF("FreeType: couldn't activate instance: %d\n", ftrc);
+ return FTtoXReturnCode(ftrc);
+ }
+ FT_Set_Transform(instance->face->face,
+ instance->transformation.nonIdentity ?
+ &instance->transformation.matrix : 0,
+ 0);
+
+ instance->face->active_instance = instance;
+ return Successful;
+}
+
+static int
+FTFindSize(FT_Face face, FTNormalisedTransformationPtr trans,
+ int *x_return, int *y_return)
+{
+ int tx, ty, x, y;
+ int i, j;
+ int d, dd;
+
+ if(trans->nonIdentity)
+ return BadFontName;
+
+ tx = (int)(trans->scale * trans->xres / 72.0 + 0.5);
+ ty = (int)(trans->scale * trans->yres / 72.0 + 0.5);
+
+ d = 100;
+ j = -1;
+ for(i = 0; i < face->num_fixed_sizes; i++) {
+ x = face->available_sizes[i].width;
+ y = face->available_sizes[i].height;
+ if(ABS(x - tx) <= 1 && ABS(y - ty) <= 1) {
+ dd = ABS(x - tx) * ABS(x - tx) + ABS(y - ty) * ABS(y - ty);
+ if(dd < d) {
+ j = i;
+ d = dd;
+ }
+ }
+ }
+ if(j < 0)
+ return BadFontName;
+
+ *x_return = face->available_sizes[j].width;
+ *y_return = face->available_sizes[j].height;
+ return Successful;
+}
+
+static int
+FreeTypeOpenInstance(FTInstancePtr *instance_return, FTFacePtr face,
+ char *FTFileName, FTNormalisedTransformationPtr trans,
+ int spacing, FontBitmapFormatPtr bmfmt,
+ struct TTCapInfo *tmp_ttcap, FT_Int32 load_flags)
+{
+ FT_Error ftrc;
+ int xrc;
+ FTInstancePtr instance, otherInstance;
+
+ /* Search for a matching instance */
+ for(otherInstance = face->instances;
+ otherInstance;
+ otherInstance = otherInstance->next) {
+ if(FTInstanceMatch(otherInstance, FTFileName, trans, spacing, bmfmt,
+ tmp_ttcap, load_flags)) break;
+ }
+ if(otherInstance) {
+ MUMBLE("Returning cached instance\n");
+ otherInstance->refcount++;
+ *instance_return = otherInstance;
+ return Successful;
+ }
+
+ /* None matching found */
+ instance = (FTInstancePtr)xalloc(sizeof(FTInstanceRec));
+ if(instance == NULL) {
+ return AllocError;
+ }
+
+ instance->refcount = 1;
+ instance->face = face;
+
+ instance->load_flags = load_flags;
+ instance->spacing = spacing; /* Actual spacing */
+ instance->pixel_size =0;
+ instance->pixel_width_unit_x =0;
+ instance->pixel_width_unit_y =0;
+ instance->charcellMetrics = NULL;
+ instance->averageWidth = 0;
+ instance->rawAverageWidth = 0;
+ instance->forceConstantMetrics = NULL;
+
+ instance->transformation = *trans;
+ instance->bmfmt = *bmfmt;
+ instance->glyphs = NULL;
+ instance->available = NULL;
+
+ if( 0 <= tmp_ttcap->forceConstantSpacingEnd )
+ instance->nglyphs = 2 * instance->face->face->num_glyphs;
+ else
+ instance->nglyphs = instance->face->face->num_glyphs;
+
+ /* Store the TTCap info. */
+ memcpy((char*)&instance->ttcap, (char*)tmp_ttcap,
+ sizeof(struct TTCapInfo));
+
+ ftrc = FT_New_Size(instance->face->face, &instance->size);
+ if(ftrc != 0) {
+ ErrorF("FreeType: couldn't create size object: %d\n", ftrc);
+ xfree(instance);
+ return FTtoXReturnCode(ftrc);
+ }
+ FreeTypeActivateInstance(instance);
+ if(!face->bitmap) {
+ ftrc = FT_Set_Char_Size(instance->face->face,
+ (int)(trans->scale*(1<<6) + 0.5),
+ (int)(trans->scale*(1<<6) + 0.5),
+ trans->xres, trans->yres);
+ } else {
+ int xsize, ysize;
+ xrc = FTFindSize(face->face, trans, &xsize, &ysize);
+ if(xrc != Successful) {
+ xfree(instance);
+ return xrc;
+ }
+ ftrc = FT_Set_Pixel_Sizes(instance->face->face, xsize, ysize);
+ }
+ if(ftrc != 0) {
+ FT_Done_Size(instance->size);
+ xfree(instance);
+ return FTtoXReturnCode(ftrc);
+ }
+
+ if( FT_IS_SFNT( face->face ) ) {
+#if 1
+ FT_F26Dot6 tt_char_width, tt_char_height, tt_dim_x, tt_dim_y;
+ FT_UInt nn;
+
+ instance->strike_index=0xFFFFU;
+
+ tt_char_width = (FT_F26Dot6)(trans->scale*(1<<6) + 0.5);
+ tt_char_height = (FT_F26Dot6)(trans->scale*(1<<6) + 0.5);
+
+ tt_dim_x = FLOOR64( ( tt_char_width * trans->xres + 36 ) / 72 + 32 );
+ tt_dim_y = FLOOR64( ( tt_char_height * trans->yres + 36 ) / 72 + 32 );
+
+ if ( tt_dim_x && !tt_dim_y )
+ tt_dim_y = tt_dim_x;
+ else if ( !tt_dim_x && tt_dim_y )
+ tt_dim_x = tt_dim_y;
+
+ for ( nn = 0; nn < face->face->num_fixed_sizes; nn++ )
+ {
+ FT_Bitmap_Size* sz = &face->face->available_sizes[nn];
+
+ if ( tt_dim_x == FLOOR64(sz->x_ppem + 32) && tt_dim_y == FLOOR64(sz->y_ppem + 32) )
+ {
+ instance->strike_index = nn;
+ break;
+ }
+ }
+#else
+ /* See Set_Char_Sizes() in ttdriver.c */
+ FT_Error err;
+ TT_Face tt_face;
+ FT_Long tt_dim_x, tt_dim_y;
+ FT_UShort tt_x_ppem, tt_y_ppem;
+ FT_F26Dot6 tt_char_width, tt_char_height;
+ SFNT_Service sfnt;
+ tt_face=(TT_Face)face->face;
+ tt_char_width = (int)(trans->scale*(1<<6) + 0.5);
+ tt_char_height = (int)(trans->scale*(1<<6) + 0.5);
+ if ( ( tt_face->header.Flags & 8 ) != 0 ) {
+ tt_dim_x = ( ( tt_char_width * trans->xres + (36+32*72) ) / 72 ) & -64;
+ tt_dim_y = ( ( tt_char_height * trans->yres + (36+32*72) ) / 72 ) & -64;
+ }
+ else{
+ tt_dim_x = ( ( tt_char_width * trans->xres + 36 ) / 72 );
+ tt_dim_y = ( ( tt_char_height * trans->yres + 36 ) / 72 );
+ }
+ tt_x_ppem = (FT_UShort)( tt_dim_x >> 6 );
+ tt_y_ppem = (FT_UShort)( tt_dim_y >> 6 );
+ /* See Reset_SBit_Size() in ttobjs.c */
+ sfnt = (SFNT_Service)tt_face->sfnt;
+ err = sfnt->set_sbit_strike(tt_face,tt_x_ppem,tt_y_ppem,&instance->strike_index);
+ if ( err ) instance->strike_index=0xFFFFU;
+#endif
+ }
+
+ /* maintain a linked list of instances */
+ instance->next = instance->face->instances;
+ instance->face->instances = instance;
+
+ *instance_return = instance;
+ return Successful;
+}
+
+static void
+FreeTypeFreeInstance(FTInstancePtr instance)
+{
+ FTInstancePtr otherInstance;
+
+ if( instance == NULL ) return;
+
+ if(instance->face->active_instance == instance)
+ instance->face->active_instance = NULL;
+ instance->refcount--;
+ if(instance->refcount <= 0) {
+ int i,j;
+
+ if(instance->face->instances == instance)
+ instance->face->instances = instance->next;
+ else {
+ for(otherInstance = instance->face->instances;
+ otherInstance;
+ otherInstance = otherInstance->next)
+ if(otherInstance->next == instance) {
+ otherInstance->next = instance->next;
+ break;
+ }
+ }
+
+ FT_Done_Size(instance->size);
+ FreeTypeFreeFace(instance->face);
+
+ if(instance->charcellMetrics) {
+ xfree(instance->charcellMetrics);
+ }
+ if(instance->forceConstantMetrics) {
+ xfree(instance->forceConstantMetrics);
+ }
+ if(instance->glyphs) {
+ for(i = 0; i < iceil(instance->nglyphs, FONTSEGMENTSIZE); i++) {
+ if(instance->glyphs[i]) {
+ for(j = 0; j < FONTSEGMENTSIZE; j++) {
+ if(instance->available[i][j] ==
+ FT_AVAILABLE_RASTERISED)
+ xfree(instance->glyphs[i][j].bits);
+ }
+ xfree(instance->glyphs[i]);
+ }
+ }
+ xfree(instance->glyphs);
+ }
+ if(instance->available) {
+ for(i = 0; i < iceil(instance->nglyphs, FONTSEGMENTSIZE); i++) {
+ if(instance->available[i])
+ xfree(instance->available[i]);
+ }
+ xfree(instance->available);
+ }
+ xfree(instance);
+ }
+}
+
+static int
+FreeTypeInstanceFindGlyph(unsigned idx_in, int flags, FTInstancePtr instance,
+ CharInfoPtr **glyphs, int ***available,
+ int *found, int *segmentP, int *offsetP)
+{
+ int segment, offset;
+ unsigned idx = idx_in;
+
+ if( 0 <= instance->ttcap.forceConstantSpacingEnd ){
+ if( (flags & FT_FORCE_CONSTANT_SPACING) )
+ idx += instance->nglyphs / 2 ;
+ }
+
+ if(idx > instance->nglyphs) {
+ *found = 0;
+ return Successful;
+ }
+
+ if(*available == NULL) {
+ *available =
+ (int**)xalloc(sizeof(int*) * iceil(instance->nglyphs,
+ FONTSEGMENTSIZE));
+ if(*available == NULL)
+ return AllocError;
+ memset((char*)(*available), 0,
+ sizeof(int*) * iceil(instance->nglyphs, FONTSEGMENTSIZE));
+ }
+
+ segment = ifloor(idx, FONTSEGMENTSIZE);
+ offset = idx - segment * FONTSEGMENTSIZE;
+
+ if((*available)[segment] == NULL) {
+ (*available)[segment] = (int*)xalloc(sizeof(int) * FONTSEGMENTSIZE);
+ if((*available)[segment] == NULL)
+ return AllocError;
+ memset((char*)(*available)[segment], 0, sizeof(int) * FONTSEGMENTSIZE);
+ }
+
+ if(*glyphs == NULL) {
+ *glyphs = (CharInfoPtr*)xalloc(sizeof(CharInfoPtr)*
+ iceil(instance->nglyphs,
+ FONTSEGMENTSIZE));
+ if(*glyphs == NULL)
+ return AllocError;
+ memset((char*)(*glyphs), 0,
+ sizeof(CharInfoPtr)*iceil(instance->nglyphs, FONTSEGMENTSIZE));
+ }
+
+ if((*glyphs)[segment] == NULL) {
+ (*glyphs)[segment]=
+ (CharInfoPtr)xalloc(sizeof(CharInfoRec) * FONTSEGMENTSIZE);
+ if((*glyphs)[segment] == NULL)
+ return AllocError;
+ }
+
+ *found = 1;
+ *segmentP = segment;
+ *offsetP = offset;
+ return Successful;
+}
+
+static int
+FreeTypeInstanceGetGlyph(unsigned idx, int flags, CharInfoPtr *g, FTInstancePtr instance)
+{
+ int found, segment, offset;
+ int xrc;
+ int ***available;
+ CharInfoPtr **glyphs;
+
+ available = &instance->available;
+ glyphs = &instance->glyphs;
+
+ xrc = FreeTypeInstanceFindGlyph(idx, flags, instance, glyphs, available,
+ &found, &segment, &offset);
+ if(xrc != Successful)
+ return xrc;
+
+ if(!found || (*available)[segment][offset] == FT_AVAILABLE_NO) {
+ *g = NULL;
+ return Successful;
+ }
+
+ if((*available)[segment][offset] == FT_AVAILABLE_RASTERISED) {
+ *g = &(*glyphs)[segment][offset];
+ return Successful;
+ }
+
+ flags |= FT_GET_GLYPH_BOTH;
+
+ xrc = FreeTypeRasteriseGlyph(idx, flags,
+ &(*glyphs)[segment][offset], instance,
+ (*available)[segment][offset] >= FT_AVAILABLE_METRICS);
+ if(xrc != Successful && (*available)[segment][offset] >= FT_AVAILABLE_METRICS) {
+ ErrorF("Warning: FreeTypeRasteriseGlyph() returns an error,\n");
+ ErrorF("\tso the backend tries to set a white space.\n");
+ xrc = FreeTypeRasteriseGlyph(idx, flags | FT_GET_DUMMY,
+ &(*glyphs)[segment][offset], instance,
+ (*available)[segment][offset] >= FT_AVAILABLE_METRICS);
+ }
+ if(xrc == Successful) {
+ (*available)[segment][offset] = FT_AVAILABLE_RASTERISED;
+ /* return the glyph */
+ *g = &(*glyphs)[segment][offset];
+ }
+ return xrc;
+}
+
+static int
+FreeTypeInstanceGetGlyphMetrics(unsigned idx, int flags,
+ xCharInfo **metrics, FTInstancePtr instance )
+{
+ int xrc;
+ int found, segment, offset;
+
+ /* Char cell */
+ if(instance->spacing == FT_CHARCELL) {
+ *metrics = instance->charcellMetrics;
+ return Successful;
+ }
+ /* Force constant metrics */
+ if( flags & FT_FORCE_CONSTANT_SPACING) {
+ *metrics = instance->forceConstantMetrics;
+ return Successful;
+ }
+
+ /* Not char cell */
+
+ xrc = FreeTypeInstanceFindGlyph(idx, flags, instance,
+ &instance->glyphs, &instance->available,
+ &found, &segment, &offset);
+ if(xrc != Successful)
+ return xrc;
+ if(!found) {
+ *metrics = NULL;
+ return Successful;
+ }
+ if( instance->available[segment][offset] == FT_AVAILABLE_NO ) {
+ *metrics = NULL;
+ return Successful;
+ }
+
+ if( instance->available[segment][offset] >= FT_AVAILABLE_METRICS ) {
+ *metrics = &instance->glyphs[segment][offset].metrics;
+ return Successful;
+ }
+
+ flags |= FT_GET_GLYPH_METRICS_ONLY;
+
+ xrc = FreeTypeRasteriseGlyph(idx, flags,
+ &instance->glyphs[segment][offset],
+ instance, 0);
+ if(xrc == Successful) {
+ instance->available[segment][offset] = FT_AVAILABLE_METRICS;
+ *metrics = &instance->glyphs[segment][offset].metrics;
+ }
+ return xrc;
+}
+
+/*
+ * Pseudo enbolding similar as Microsoft Windows.
+ * It is useful but poor.
+ */
+static void
+ft_make_up_bold_bitmap( char *raster, int bpr, int ht, int ds_mode)
+{
+ int x, y;
+ unsigned char *p = (unsigned char *)raster;
+ if ( ds_mode & TTCAP_DOUBLE_STRIKE_MKBOLD_EDGE_LEFT ) {
+ for (y=0; y<ht; y++) {
+ unsigned char rev_pat=0;
+ unsigned char lsb = 0;
+ for (x=0; x<bpr; x++) {
+ unsigned char tmp = *p<<7;
+ if ( (rev_pat & 0x01) && (*p & 0x80) ) p[-1] &= 0xfe;
+ rev_pat = ~(*p);
+ *p |= (*p>>1) | lsb;
+ *p &= ~(rev_pat & (*p << 1));
+ lsb = tmp;
+ p++;
+ }
+ }
+ }
+ else {
+ for (y=0; y<ht; y++) {
+ unsigned char lsb = 0;
+ for (x=0; x<bpr; x++) {
+ unsigned char tmp = *p<<7;
+ *p |= (*p>>1) | lsb;
+ lsb = tmp;
+ p++;
+ }
+ }
+ }
+}
+
+static void
+ft_make_up_italic_bitmap( char *raster, int bpr, int ht, int shift,
+ int h_total, int h_offset, double a_italic)
+{
+ int x, y;
+ unsigned char *p = (unsigned char *)raster;
+ if ( a_italic < 0 ) shift = -shift;
+ for (y=0; y<ht; y++) {
+ unsigned char *tmp_p = p + y*bpr;
+ int tmp_shift = shift * (h_total -1 -(y+h_offset)) / h_total;
+ int tmp_byte_shift;
+ if ( 0 <= tmp_shift ) {
+ tmp_byte_shift = tmp_shift/8;
+ tmp_shift %= 8;
+ if ( tmp_shift ) {
+ for (x=bpr-1;0<=x;x--) {
+ if ( x != bpr-1 )
+ tmp_p[x+1] |= tmp_p[x]<<(8-tmp_shift);
+ tmp_p[x]>>=tmp_shift;
+ }
+ }
+ if ( tmp_byte_shift ) {
+ for (x=bpr-1;0<x;x--) {
+ tmp_p[x] = tmp_p[x-1];
+ }
+ tmp_p[x]=0;
+ }
+ }
+ else {
+ tmp_shift = -tmp_shift;
+ tmp_byte_shift = tmp_shift/8;
+ tmp_shift %= 8;
+ if ( tmp_shift ) {
+ for (x=0;x<bpr;x++) {
+ if ( x != 0 )
+ tmp_p[x-1] |= tmp_p[x]>>(8-tmp_shift);
+ tmp_p[x]<<=tmp_shift;
+ }
+ }
+ if ( tmp_byte_shift ) {
+ for (x=0;x<bpr-1;x++) {
+ tmp_p[x] = tmp_p[x+1];
+ }
+ tmp_p[x]=0;
+ }
+ }
+ }
+}
+
+/*
+ * The very lazy method,
+ * parse the htmx field in TrueType font.
+ */
+
+static void
+tt_get_metrics( FT_Face face,
+ FT_UInt idx,
+ FT_UInt num_hmetrics,
+ FT_Short* bearing,
+ FT_UShort* advance )
+{
+ /* read the metrics directly from the horizontal header, we
+ * parse the SFNT table directly through the standard FreeType API.
+ * this works with any version of the library and doesn't need to
+ * peek at its internals. Maybe a bit less
+ */
+ FT_UInt count = num_hmetrics;
+ FT_ULong length = 0;
+ FT_ULong offset = 0;
+ FT_Error error;
+
+ error = FT_Load_Sfnt_Table( face, TTAG_hmtx, 0, NULL, &length );
+
+ if ( count == 0 || error )
+ {
+ *advance = 0;
+ *bearing = 0;
+ }
+ else if ( idx < count )
+ {
+ offset = idx * 4L;
+ if ( offset + 4 > length )
+ {
+ *advance = 0;
+ *bearing = 0;
+ }
+ else
+ {
+ *advance = sfnt_get_ushort( face, TTAG_hmtx, offset );
+ *bearing = sfnt_get_short ( face, TTAG_hmtx, offset+2 );
+ }
+ }
+ else
+ {
+ offset = 4L * (count - 1);
+ if ( offset + 4 > length )
+ {
+ *advance = 0;
+ *bearing = 0;
+ }
+ else
+ {
+ *advance = sfnt_get_ushort ( face, TTAG_hmtx, offset );
+ offset += 4 + 2 * ( idx - count );
+ if ( offset + 2 > length)
+ *bearing = 0;
+ else
+ *bearing = sfnt_get_short ( face, TTAG_hmtx, offset );
+ }
+ }
+}
+
+static int
+ft_get_very_lazy_bbox( FT_UInt index,
+ FT_Face face,
+ FT_Size size,
+ FT_UInt num_hmetrics,
+ double slant,
+ FT_Matrix *matrix,
+ FT_BBox *bbox,
+ FT_Long *horiAdvance,
+ FT_Long *vertAdvance)
+{
+ if ( FT_IS_SFNT( face ) ) {
+ FT_Size_Metrics *smetrics = &size->metrics;
+ FT_Short leftBearing = 0;
+ FT_UShort advance = 0;
+ FT_Vector p0, p1, p2, p3;
+
+ /* horizontal */
+ tt_get_metrics( face, index, num_hmetrics,
+ &leftBearing, &advance );
+
+#if 0
+ fprintf(stderr,"x_scale=%f y_scale=%f\n",
+ (double)smetrics->x_scale,(double)smetrics->y_scale);
+#endif
+ bbox->xMax = *horiAdvance =
+ FT_MulFix( advance, smetrics->x_scale );
+ bbox->xMin =
+ FT_MulFix( leftBearing, smetrics->x_scale );
+ /* vertical */
+ bbox->yMin = FT_MulFix( face->bbox.yMin,
+ smetrics->y_scale );
+ bbox->yMax = FT_MulFix( face->bbox.yMax,
+ smetrics->y_scale );
+ /* slant */
+ if( 0 < slant ) {
+ bbox->xMax += slant * bbox->yMax;
+ bbox->xMin += slant * bbox->yMin;
+ }
+ else if( slant < 0 ) {
+ bbox->xMax += slant * bbox->yMin;
+ bbox->xMin += slant * bbox->yMax;
+ }
+
+ *vertAdvance = -1; /* We don't support */
+
+ p0.x = p2.x = bbox->xMin;
+ p1.x = p3.x = bbox->xMax;
+ p0.y = p1.y = bbox->yMin;
+ p2.y = p3.y = bbox->yMax;
+
+ FT_Vector_Transform(&p0, matrix);
+ FT_Vector_Transform(&p1, matrix);
+ FT_Vector_Transform(&p2, matrix);
+ FT_Vector_Transform(&p3, matrix);
+
+#if 0
+ fprintf(stderr,
+ "->(%.1f %.1f) (%.1f %.1f)"
+ " (%.1f %.1f) (%.1f %.1f)\n",
+ p0.x / 64.0, p0.y / 64.0,
+ p1.x / 64.0, p1.y / 64.0,
+ p2.x / 64.0, p2.y / 64.0,
+ p3.x / 64.0, p3.y / 64.0);
+#endif
+ bbox->xMin = MIN(p0.x, MIN(p1.x, MIN(p2.x, p3.x)));
+ bbox->xMax = MAX(p0.x, MAX(p1.x, MAX(p2.x, p3.x)));
+ bbox->yMin = MIN(p0.y, MIN(p1.y, MIN(p2.y, p3.y)));
+ bbox->yMax = MAX(p0.y, MAX(p1.y, MAX(p2.y, p3.y)));
+ return 0; /* Successful */
+ }
+ return -1;
+}
+
+static FT_Error
+FT_Do_SBit_Metrics( FT_Face ft_face, FT_Size ft_size, FT_ULong strike_index,
+ FT_UShort glyph_index, FT_Glyph_Metrics *metrics_return,
+ int *sbitchk_incomplete_but_exist )
+{
+#if 1
+ if ( strike_index != 0xFFFFU && ft_face->available_sizes != NULL )
+ {
+ FT_Error error;
+ FT_Bitmap_Size* sz = &ft_face->available_sizes[strike_index];
+
+ error = FT_Set_Pixel_Sizes( ft_face, sz->x_ppem/64, sz->y_ppem/64 );
+ if ( !error )
+ {
+ error = FT_Load_Glyph( ft_face, glyph_index, FT_LOAD_SBITS_ONLY );
+ if ( !error )
+ {
+ if ( metrics_return != NULL )
+ *metrics_return = ft_face->glyph->metrics;
+
+ return 0;
+ }
+ }
+ }
+ return -1;
+#elif (FREETYPE_VERSION >= 2001008)
+ SFNT_Service sfnt;
+ TT_Face face;
+ FT_Error error;
+ FT_Stream stream;
+ TT_SBit_Strike strike;
+ TT_SBit_Range range;
+ TT_SBit_MetricsRec elem_metrics;
+ FT_ULong ebdt_pos;
+ FT_ULong glyph_offset;
+ ;
+
+ if ( ! FT_IS_SFNT( ft_face ) )
+ {
+ error=-1;
+ goto Exit;
+ }
+
+ face = (TT_Face)ft_face;
+ sfnt = (SFNT_Service)face->sfnt;
+
+ if (strike_index != 0xFFFFU && sfnt && sfnt->find_sbit_image &&
+ sfnt->load_sbits) {
+ /* Check whether there is a glyph sbit for the current index */
+ error = sfnt->find_sbit_image( face, glyph_index, strike_index,
+ &range, &strike, &glyph_offset );
+ }
+ else error=-1;
+ if ( error ) goto Exit;
+
+ if ( metrics_return == NULL ) goto Exit;
+
+ stream = face->root.stream;
+
+ /* now, find the location of the `EBDT' table in */
+ /* the font file */
+ error = face->goto_table( face, TTAG_EBDT, stream, 0 );
+ if ( error )
+ error = face->goto_table( face, TTAG_bdat, stream, 0 );
+ if (error)
+ goto Exit;
+
+ ebdt_pos = FT_STREAM_POS();
+
+ /* place stream at beginning of glyph data and read metrics */
+ if ( FT_STREAM_SEEK( ebdt_pos + glyph_offset ) )
+ goto Exit;
+
+ error = sfnt->load_sbit_metrics( stream, range, &elem_metrics );
+ if ( error )
+ goto Exit;
+
+ metrics_return->width = (FT_Pos)elem_metrics.width << 6;
+ metrics_return->height = (FT_Pos)elem_metrics.height << 6;
+
+ metrics_return->horiBearingX = (FT_Pos)elem_metrics.horiBearingX << 6;
+ metrics_return->horiBearingY = (FT_Pos)elem_metrics.horiBearingY << 6;
+ metrics_return->horiAdvance = (FT_Pos)elem_metrics.horiAdvance << 6;
+
+ metrics_return->vertBearingX = (FT_Pos)elem_metrics.vertBearingX << 6;
+ metrics_return->vertBearingY = (FT_Pos)elem_metrics.vertBearingY << 6;
+ metrics_return->vertAdvance = (FT_Pos)elem_metrics.vertAdvance << 6;
+
+ Exit:
+ return error;
+#else /* if (FREETYPE_VERSION < 2001008) */
+ TT_Face face;
+ SFNT_Service sfnt;
+ if ( ! FT_IS_SFNT( ft_face ) ) return -1;
+ face = (TT_Face)ft_face;
+ sfnt = (SFNT_Service)face->sfnt;
+ if ( strike_index != 0xFFFFU && sfnt->load_sbits ) {
+ if ( sbitchk_incomplete_but_exist ) *sbitchk_incomplete_but_exist=1;
+ }
+ return -1;
+#endif
+}
+
+int
+FreeTypeRasteriseGlyph(unsigned idx, int flags, CharInfoPtr tgp,
+ FTInstancePtr instance, int hasMetrics)
+{
+ FTFacePtr face;
+ FT_BBox bbox;
+ FT_Long outline_hori_advance, outline_vert_advance;
+ FT_Glyph_Metrics sbit_metrics;
+ FT_Glyph_Metrics *bitmap_metrics=NULL, *metrics = NULL;
+ char *raster;
+ int wd, ht, bpr; /* width, height, bytes per row */
+ int wd_actual, ht_actual;
+ int ftrc, is_outline, correct, b_shift=0;
+ int dx, dy;
+ int leftSideBearing, rightSideBearing, characterWidth, rawCharacterWidth,
+ ascent, descent;
+ int sbitchk_incomplete_but_exist;
+ double bbox_center_raw;
+
+ face = instance->face;
+
+ FreeTypeActivateInstance(instance);
+
+ if(!tgp) return AllocError;
+
+ /*
+ * PREPARE METRICS
+ */
+
+ if(!hasMetrics) {
+ if( instance->spacing == FT_CHARCELL || flags & FT_GET_DUMMY ){
+ memcpy((char*)&tgp->metrics,
+ (char*)instance->charcellMetrics,
+ sizeof(xCharInfo));
+ }
+ else if( flags & FT_FORCE_CONSTANT_SPACING ) {
+ memcpy((char*)&tgp->metrics,
+ (char*)instance->forceConstantMetrics,
+ sizeof(xCharInfo));
+ }
+ /* mono or prop. */
+ else{
+ int new_width;
+ double ratio;
+
+ sbitchk_incomplete_but_exist=0;
+ if( ! (instance->load_flags & FT_LOAD_NO_BITMAP) ) {
+ if( FT_Do_SBit_Metrics(face->face,instance->size,instance->strike_index,
+ idx,&sbit_metrics,&sbitchk_incomplete_but_exist)==0 ) {
+ bitmap_metrics = &sbit_metrics;
+ }
+ }
+ if( bitmap_metrics == NULL ) {
+ if ( sbitchk_incomplete_but_exist==0 && (instance->ttcap.flags & TTCAP_IS_VERY_LAZY) ) {
+ if( ft_get_very_lazy_bbox( idx, face->face, instance->size,
+ face->num_hmetrics,
+ instance->ttcap.vl_slant,
+ &instance->transformation.matrix,
+ &bbox, &outline_hori_advance,
+ &outline_vert_advance ) == 0 ) {
+ goto bbox_ok; /* skip exact calculation */
+ }
+ }
+ ftrc = FT_Load_Glyph(instance->face->face, idx,
+ instance->load_flags);
+ if(ftrc != 0) return FTtoXReturnCode(ftrc);
+ metrics = &face->face->glyph->metrics;
+ if( face->face->glyph->format == FT_GLYPH_FORMAT_BITMAP ) {
+ bitmap_metrics = metrics;
+ }
+ }
+
+ if( bitmap_metrics ) {
+ FT_Pos factor;
+
+ leftSideBearing = bitmap_metrics->horiBearingX / 64;
+ rightSideBearing = (bitmap_metrics->width + bitmap_metrics->horiBearingX) / 64;
+ bbox_center_raw = (2.0 * bitmap_metrics->horiBearingX + bitmap_metrics->width)/2.0/64.0;
+ characterWidth = (int)floor(bitmap_metrics->horiAdvance
+ * instance->ttcap.scaleBBoxWidth / 64.0 + .5);
+ ascent = bitmap_metrics->horiBearingY / 64;
+ descent = (bitmap_metrics->height - bitmap_metrics->horiBearingY) / 64 ;
+ /* */
+ new_width = characterWidth;
+ if( instance->ttcap.flags & TTCAP_DOUBLE_STRIKE_CORRECT_B_BOX_WIDTH )
+ new_width += instance->ttcap.doubleStrikeShift;
+ new_width += instance->ttcap.adjustBBoxWidthByPixel;
+ ratio = (double)new_width/characterWidth;
+ characterWidth = new_width;
+ /* adjustment by pixel unit */
+ if( instance->ttcap.flags & TTCAP_DOUBLE_STRIKE )
+ rightSideBearing += instance->ttcap.doubleStrikeShift;
+ rightSideBearing += instance->ttcap.adjustRightSideBearingByPixel;
+ leftSideBearing += instance->ttcap.adjustLeftSideBearingByPixel;
+ rightSideBearing += instance->ttcap.rsbShiftOfBitmapAutoItalic;
+ leftSideBearing += instance->ttcap.lsbShiftOfBitmapAutoItalic;
+ /* */
+ factor = bitmap_metrics->horiAdvance;
+ rawCharacterWidth = (unsigned short)(short)(floor(1000 * factor
+ * instance->ttcap.scaleBBoxWidth * ratio / 64.
+ / instance->pixel_size));
+ }
+ else {
+ /* Outline */
+#ifdef USE_GET_CBOX
+ /* Very fast?? */
+ FT_Outline_Get_CBox(&face->face->glyph->outline, &bbox);
+ ftrc=0; /* FT_Outline_Get_CBox returns nothing. */
+#else
+ /* Calculate exact metrics */
+ ftrc=FT_Outline_Get_BBox(&face->face->glyph->outline, &bbox);
+#endif
+ if( ftrc != 0 ) return FTtoXReturnCode(ftrc);
+ outline_hori_advance = metrics->horiAdvance;
+ outline_vert_advance = metrics->vertAdvance;
+ bbox_ok:
+ descent = CEIL64(-bbox.yMin - 32) / 64;
+ leftSideBearing = FLOOR64(bbox.xMin + 32) / 64;
+ ascent = FLOOR64(bbox.yMax + 32) / 64;
+ rightSideBearing = FLOOR64(bbox.xMax + 32) / 64;
+ bbox_center_raw = (double)(bbox.xMax + bbox.xMin)/2.0/64.;
+ if ( instance->pixel_width_unit_x != 0 )
+ characterWidth =
+ (int)floor( outline_hori_advance
+ * instance->ttcap.scaleBBoxWidth
+ * instance->pixel_width_unit_x / 64. + .5);
+ else {
+ characterWidth =
+ (int)floor( outline_vert_advance
+ * instance->ttcap.scaleBBoxHeight
+ * instance->pixel_width_unit_y / 64. + .5);
+ if(characterWidth <= 0)
+ characterWidth = instance->charcellMetrics->characterWidth;
+ }
+ /* */
+ new_width = characterWidth;
+ if( instance->ttcap.flags & TTCAP_DOUBLE_STRIKE_CORRECT_B_BOX_WIDTH )
+ new_width += instance->ttcap.doubleStrikeShift;
+ new_width += instance->ttcap.adjustBBoxWidthByPixel;
+ ratio = (double)new_width/characterWidth;
+ characterWidth = new_width;
+ if ( instance->pixel_width_unit_x != 0 )
+ rawCharacterWidth =
+ (unsigned short)(short)(floor(1000 * outline_hori_advance
+ * instance->ttcap.scaleBBoxWidth * ratio
+ * instance->pixel_width_unit_x / 64.));
+ else {
+ rawCharacterWidth =
+ (unsigned short)(short)(floor(1000 * outline_vert_advance
+ * instance->ttcap.scaleBBoxHeight * ratio
+ * instance->pixel_width_unit_y / 64.));
+ if(rawCharacterWidth <= 0)
+ rawCharacterWidth = instance->charcellMetrics->attributes;
+ }
+ /* adjustment by pixel unit */
+ if( instance->ttcap.flags & TTCAP_DOUBLE_STRIKE )
+ rightSideBearing += instance->ttcap.doubleStrikeShift;
+ rightSideBearing += instance->ttcap.adjustRightSideBearingByPixel;
+ leftSideBearing += instance->ttcap.adjustLeftSideBearingByPixel;
+ }
+
+ /* Set the glyph metrics. */
+ tgp->metrics.attributes = (unsigned short)((short)rawCharacterWidth);
+ tgp->metrics.leftSideBearing = leftSideBearing;
+ tgp->metrics.rightSideBearing = rightSideBearing;
+ tgp->metrics.characterWidth = characterWidth;
+ tgp->metrics.ascent = ascent;
+ tgp->metrics.descent = descent;
+ /* Update the width to match the width of the font */
+ if( instance->spacing != FT_PROPORTIONAL )
+ tgp->metrics.characterWidth = instance->charcellMetrics->characterWidth;
+ if(instance->ttcap.flags & TTCAP_MONO_CENTER){
+ b_shift = (int)floor((instance->advance/2.0-bbox_center_raw) + .5);
+ tgp->metrics.leftSideBearing += b_shift;
+ tgp->metrics.rightSideBearing += b_shift;
+ }
+ }
+ }
+
+ if( flags & FT_GET_GLYPH_METRICS_ONLY ) return Successful;
+
+ /*
+ * CHECK THE NECESSITY OF BITMAP POSITION'S CORRECTION
+ */
+
+ correct=0;
+ if( instance->spacing == FT_CHARCELL ) correct=1;
+ else if( flags & FT_FORCE_CONSTANT_SPACING ) correct=1;
+ else{
+ int sbit_available=0;
+ sbitchk_incomplete_but_exist=0;
+ if( !(instance->load_flags & FT_LOAD_NO_BITMAP) ) {
+ if( FT_Do_SBit_Metrics(face->face,instance->size,
+ instance->strike_index,idx,NULL,
+ &sbitchk_incomplete_but_exist)==0 ) {
+ sbit_available=1;
+ }
+ }
+ if( sbit_available == 0 ) {
+ if ( sbitchk_incomplete_but_exist==0 && (instance->ttcap.flags & TTCAP_IS_VERY_LAZY) ) {
+ if( FT_IS_SFNT(face->face) ) correct=1;
+ }
+ }
+ }
+
+ /*
+ * RENDER AND ALLOCATE BUFFER
+ */
+
+ if( flags & FT_GET_DUMMY ) is_outline = -1;
+ else {
+ if( !metrics ) {
+ ftrc = FT_Load_Glyph(instance->face->face, idx,
+ instance->load_flags);
+ metrics = &face->face->glyph->metrics;
+
+ if(ftrc != 0) return FTtoXReturnCode(ftrc);
+ }
+
+ if( face->face->glyph->format != FT_GLYPH_FORMAT_BITMAP ) {
+#ifdef USE_GET_CBOX
+ FT_Outline_Get_CBox(&face->face->glyph->outline, &bbox);
+ ftrc = 0;
+#else
+ ftrc = FT_Outline_Get_BBox(&face->face->glyph->outline, &bbox);
+#endif
+ if( ftrc != 0 ) return FTtoXReturnCode(ftrc);
+ bbox.yMin = FLOOR64( bbox.yMin );
+ bbox.yMax = CEIL64 ( bbox.yMax );
+ ht_actual = ( bbox.yMax - bbox.yMin ) >> 6;
+ /* FreeType think a glyph with 0 height control box is invalid.
+ * So just let X to create a empty bitmap instead. */
+ if ( ht_actual == 0 )
+ is_outline = -1;
+ else
+ {
+ ftrc = FT_Render_Glyph(face->face->glyph,FT_RENDER_MODE_MONO);
+ if( ftrc != 0 ) return FTtoXReturnCode(ftrc);
+ is_outline = 1;
+ }
+ }
+ else{
+ is_outline=0;
+ }
+ }
+
+ /* Spacial case */
+ if( (instance->ttcap.flags & TTCAP_MONO_CENTER) && hasMetrics ) {
+ if( is_outline == 1 ){
+ if( correct ){
+ if( ft_get_very_lazy_bbox( idx, face->face, instance->size,
+ face->num_hmetrics,
+ instance->ttcap.vl_slant,
+ &instance->transformation.matrix,
+ &bbox, &outline_hori_advance,
+ &outline_vert_advance ) != 0 ){
+ is_outline = -1; /* <- error */
+ }
+ }
+ else {
+#ifdef USE_GET_CBOX
+ FT_Outline_Get_CBox(&face->face->glyph->outline, &bbox);
+ ftrc=0;
+#else
+ ftrc=FT_Outline_Get_BBox(&face->face->glyph->outline, &bbox);
+#endif
+ if( ftrc != 0 ) return FTtoXReturnCode(ftrc);
+ }
+ bbox_center_raw = (double)(bbox.xMax + bbox.xMin)/2.0/64.;
+ }
+ else if( is_outline == 0 )
+ bbox_center_raw = (2.0 * metrics->horiBearingX + metrics->width)/2.0/64.0;
+ else
+ bbox_center_raw = 0;
+ b_shift = (int)floor((instance->advance/2.0-bbox_center_raw) + .5);
+ }
+
+ wd_actual = tgp->metrics.rightSideBearing - tgp->metrics.leftSideBearing;
+ ht_actual = tgp->metrics.ascent + tgp->metrics.descent;
+
+ /* The X convention is to consider a character with an empty
+ * bounding box as undefined. This convention is broken. */
+
+ if(wd_actual <= 0) wd = 1;
+ else wd=wd_actual;
+ if(ht_actual <= 0) ht = 1;
+ else ht=ht_actual;
+
+ bpr = (((wd + (instance->bmfmt.glyph<<3) - 1) >> 3) &
+ -instance->bmfmt.glyph);
+ raster = (char*)xalloc(ht * bpr);
+ if(raster == NULL)
+ return AllocError;
+ memset(raster, 0, ht * bpr);
+
+ tgp->bits = raster;
+
+ /* If FT_GET_DUMMY is set, we return white space. */
+ if ( is_outline == -1 ) return Successful;
+
+ if ( wd_actual <= 0 || ht_actual <= 0 ) return Successful;
+
+ /*
+ * CALCULATE OFFSET, dx AND dy.
+ */
+
+ dx = face->face->glyph->bitmap_left - tgp->metrics.leftSideBearing;
+ dy = tgp->metrics.ascent - face->face->glyph->bitmap_top;
+
+ if(instance->ttcap.flags & TTCAP_MONO_CENTER)
+ dx += b_shift;
+
+ /* To prevent chipped bitmap, we correct dx and dy if needed. */
+ if( correct && is_outline==1 ){
+ int lsb, rsb, asc, des;
+ int chip_left,chip_right,chip_top,chip_bot;
+#ifdef USE_GET_CBOX
+ FT_Outline_Get_CBox(&face->face->glyph->outline, &bbox);
+ ftrc=0;
+#else
+ ftrc=FT_Outline_Get_BBox(&face->face->glyph->outline, &bbox);
+#endif
+ if( ftrc != 0 ) return FTtoXReturnCode(ftrc);
+ des = CEIL64(-bbox.yMin - 32) / 64;
+ lsb = FLOOR64(bbox.xMin + 32) / 64;
+ asc = FLOOR64(bbox.yMax + 32) / 64;
+ rsb = FLOOR64(bbox.xMax + 32) / 64;
+ rightSideBearing = tgp->metrics.rightSideBearing;
+ leftSideBearing = tgp->metrics.leftSideBearing;
+ if( instance->ttcap.flags & TTCAP_DOUBLE_STRIKE )
+ rightSideBearing -= instance->ttcap.doubleStrikeShift;
+ /* special case */
+ if(instance->ttcap.flags & TTCAP_MONO_CENTER){
+ leftSideBearing -= b_shift;
+ rightSideBearing -= b_shift;
+ }
+ chip_left = lsb - leftSideBearing;
+ chip_right = rightSideBearing - rsb;
+ if( flags & FT_FORCE_CONSTANT_SPACING ){
+ if( instance->ttcap.force_c_adjust_lsb_by_pixel != 0 ||
+ instance->ttcap.force_c_adjust_rsb_by_pixel != 0 ){
+ chip_left=0;
+ chip_right=0;
+ }
+ }
+ else{
+ if( instance->ttcap.adjustRightSideBearingByPixel != 0 ||
+ instance->ttcap.adjustLeftSideBearingByPixel != 0 ){
+ chip_left=0;
+ chip_right=0;
+ }
+ }
+ chip_top = tgp->metrics.ascent - asc;
+ chip_bot = tgp->metrics.descent - des;
+ if( chip_left < 0 && 0 < chip_right ) dx++;
+ else if( chip_right < 0 && 0 < chip_left ) dx--;
+ if( chip_top < 0 && 0 < chip_bot ) dy++;
+ else if( chip_bot < 0 && 0 < chip_top ) dy--;
+ }
+
+ /*
+ * COPY RASTER
+ */
+
+ {
+ FT_Bitmap *bitmap;
+ int i, j;
+ unsigned char *current_raster;
+ unsigned char *current_buffer;
+ int mod_dx0,mod_dx1;
+ int div_dx;
+ bitmap = &face->face->glyph->bitmap;
+ if( 0 <= dx ){
+ div_dx = dx / 8;
+ mod_dx0 = dx % 8;
+ mod_dx1 = 8-mod_dx0;
+ }
+ else{
+ div_dx = dx / 8 -1;
+ mod_dx1 = -dx % 8;
+ mod_dx0 = 8-mod_dx1;
+ }
+ for( i = MAX(0, dy) ; i<ht ; i++ ){
+ int prev_jj,jj;
+ if( bitmap->rows <= i-dy ) break;
+ current_buffer=(unsigned char *)(bitmap->buffer+bitmap->pitch*(i-dy));
+ current_raster=(unsigned char *)(raster+i*bpr);
+ j = MAX(0,div_dx);
+ jj = j-div_dx;
+ prev_jj = jj-1;
+ if( j<bpr ){
+ if( 0 <= prev_jj && prev_jj < bitmap->pitch )
+ current_raster[j]|=current_buffer[prev_jj]<<mod_dx1;
+ if( 0 <= jj && jj < bitmap->pitch ){
+ current_raster[j]|=current_buffer[jj]>>mod_dx0;
+ j++; prev_jj++; jj++;
+ for( ; j<bpr ; j++,prev_jj++,jj++ ){
+ current_raster[j]|=current_buffer[prev_jj]<<mod_dx1;
+ if( bitmap->pitch <= jj ) break;
+ current_raster[j]|=current_buffer[jj]>>mod_dx0;
+ }
+ }
+ }
+ }
+ }
+
+ /* by TTCap */
+ if ( instance->ttcap.flags & TTCAP_DOUBLE_STRIKE ) {
+ int i;
+ for( i=0 ; i < instance->ttcap.doubleStrikeShift ; i++ )
+ ft_make_up_bold_bitmap( raster, bpr, ht, instance->ttcap.flags);
+ }
+ if ( is_outline == 0 &&
+ ( instance->ttcap.lsbShiftOfBitmapAutoItalic != 0 ||
+ instance->ttcap.rsbShiftOfBitmapAutoItalic != 0 ) ) {
+ ft_make_up_italic_bitmap( raster, bpr, ht,
+ - instance->ttcap.lsbShiftOfBitmapAutoItalic
+ + instance->ttcap.rsbShiftOfBitmapAutoItalic,
+ instance->charcellMetrics->ascent
+ + instance->charcellMetrics->descent,
+ instance->charcellMetrics->ascent
+ - tgp->metrics.ascent,
+ instance->ttcap.autoItalic);
+ }
+
+ if(instance->bmfmt.bit == LSBFirst) {
+ BitOrderInvert((unsigned char*)(tgp->bits), ht*bpr);
+ }
+
+ if(instance->bmfmt.byte != instance->bmfmt.bit) {
+ switch(instance->bmfmt.scan) {
+ case 1:
+ break;
+ case 2:
+ TwoByteSwap((unsigned char*)(tgp->bits), ht*bpr);
+ break;
+ case 4:
+ FourByteSwap((unsigned char*)(tgp->bits), ht*bpr);
+ break;
+ default:
+ ;
+ }
+ }
+
+ return Successful;
+}
+
+static void
+FreeTypeFreeFont(FTFontPtr font)
+{
+ FreeTypeFreeInstance(font->instance);
+ if(font->ranges)
+ xfree(font->ranges);
+ if(font->dummy_char.bits)
+ xfree(font->dummy_char.bits);
+ xfree(font);
+}
+
+/* Free a font. If freeProps is 0, don't free the properties. */
+
+static void
+FreeTypeFreeXFont(FontPtr pFont, int freeProps)
+{
+ FTFontPtr tf;
+
+ if(pFont) {
+ if((tf = (FTFontPtr)pFont->fontPrivate)) {
+ FreeTypeFreeFont(tf);
+ }
+ if(freeProps && pFont->info.nprops>0) {
+ xfree(pFont->info.isStringProp);
+ xfree(pFont->info.props);
+ }
+ DestroyFontRec(pFont);
+ }
+}
+
+
+/* Unload a font */
+
+static void
+FreeTypeUnloadXFont(FontPtr pFont)
+{
+ MUMBLE("Unloading\n");
+ FreeTypeFreeXFont(pFont, 1);
+}
+
+/* Add the font properties, including the Font name, the XLFD
+ properties, some strings from the font, and various typographical
+ data. We only provide data readily available in the tables in the
+ font for now, altough FIGURE_WIDTH would be a good idea as it is
+ used by Xaw. */
+
+static int
+FreeTypeAddProperties(FTFontPtr font, FontScalablePtr vals, FontInfoPtr info,
+ char *fontname, int rawAverageWidth, Bool font_properties)
+{
+ int i, j, maxprops;
+ char *sp, *ep, val[MAXFONTNAMELEN], *vp;
+ FTFacePtr face;
+ FTInstancePtr instance;
+ FTNormalisedTransformationPtr trans;
+ int upm;
+ TT_OS2 *os2;
+ TT_Postscript *post;
+ PS_FontInfoRec t1info_rec, *t1info;
+ int xlfdProps = 0;
+ int ftrc;
+
+ instance = font->instance;
+ face = instance->face;
+ trans = &instance->transformation;
+ upm = face->face->units_per_EM;
+ if(upm == 0) {
+ /* Work around FreeType bug */
+ upm = WORK_AROUND_UPM;
+ }
+
+ os2 = FT_Get_Sfnt_Table(face->face, ft_sfnt_os2);
+ post = FT_Get_Sfnt_Table(face->face, ft_sfnt_post);
+ ftrc = FT_Get_PS_Font_Info(face->face, &t1info_rec);
+ if(ftrc == 0)
+ t1info = &t1info_rec;
+ else
+ t1info = NULL;
+
+ if(t1info) {
+ os2 = NULL;
+ post = NULL;
+ }
+
+ info->nprops = 0; /* in case we abort */
+
+ strcpy(val, fontname);
+ if(FontParseXLFDName(val, vals, FONT_XLFD_REPLACE_VALUE)) {
+ xlfdProps = 1;
+ } else {
+ MUMBLE("Couldn't parse XLFD\n");
+ xlfdProps = 0;
+ }
+
+ maxprops=
+ 1 + /* NAME */
+ (xlfdProps ? 14 : 0) + /* from XLFD */
+ 5 +
+ ( !face->bitmap ? 3 : 0 ) + /* raw_av,raw_asc,raw_dec */
+ ( font_properties ? 2 : 0 ) + /* asc,dec */
+ ( (font_properties && os2) ? 6 : 0 ) +
+ ( (font_properties && (post || t1info)) ? 3 : 0 ) +
+ 2; /* type */
+
+ info->props = (FontPropPtr)xalloc(maxprops * sizeof(FontPropRec));
+ if(info->props == NULL)
+ return AllocError;
+
+ info->isStringProp = (char*)xalloc(maxprops);
+ if(info->isStringProp == NULL) {
+ xfree(info->props);
+ return AllocError;
+ }
+
+ memset((char *)info->isStringProp, 0, maxprops);
+
+ i = 0;
+
+ info->props[i].name = MakeAtom("FONT", 4, TRUE);
+ info->props[i].value = MakeAtom(val, strlen(val), TRUE);
+ info->isStringProp[i] = 1;
+ i++;
+
+ if(*val && *(sp = val + 1)) {
+ for (j = 0, sp = val + 1; j < 14; j++) {
+ if (j == 13)
+ /* Handle the case of the final field containing a subset
+ specification. */
+ for (ep = sp; *ep && *ep != '['; ep++);
+ else
+ for (ep = sp; *ep && *ep != '-'; ep++);
+
+ info->props[i].name =
+ MakeAtom(xlfd_props[j], strlen(xlfd_props[j]), TRUE);
+
+ switch(j) {
+ case 6: /* pixel size */
+ info->props[i].value =
+ (int)(fabs(vals->pixel_matrix[3]) + 0.5);
+ i++;
+ break;
+ case 7: /* point size */
+ info->props[i].value =
+ (int)(fabs(vals->point_matrix[3])*10.0 + 0.5);
+ i++;
+ break;
+ case 8: /* resolution x */
+ info->props[i].value = vals->x;
+ i++;
+ break;
+ case 9: /* resolution y */
+ info->props[i].value = vals->y;
+ i++;
+ break;
+ case 11: /* average width */
+ info->props[i].value = vals->width;
+ i++;
+ break;
+ default: /* a string */
+ info->props[i].value = MakeAtom(sp, ep - sp, TRUE);
+ info->isStringProp[i] = 1;
+ i++;
+ }
+ sp = ++ep;
+ }
+ }
+
+ info->props[i].name = MakeAtom("RAW_PIXEL_SIZE", 14, TRUE);
+ info->props[i].value = 1000;
+ i++;
+
+ info->props[i].name = MakeAtom("RAW_POINT_SIZE", 14, TRUE);
+ info->props[i].value = (long)(72270.0 / (double)vals->y + .5);
+ i++;
+
+ if(!face->bitmap) {
+ info->props[i].name = MakeAtom("RAW_AVERAGE_WIDTH", 17, TRUE);
+ info->props[i].value = rawAverageWidth;
+ i++;
+ }
+
+ if ( font_properties ) {
+ info->props[i].name = MakeAtom("FONT_ASCENT", 11, TRUE);
+ info->props[i].value = info->fontAscent;
+ i++;
+ }
+
+ if(!face->bitmap) {
+ info->props[i].name = MakeAtom("RAW_ASCENT", 10, TRUE);
+ info->props[i].value =
+ ((double)face->face->ascender/(double)upm*1000.0);
+ i++;
+ }
+
+ if ( font_properties ) {
+ info->props[i].name = MakeAtom("FONT_DESCENT", 12, TRUE);
+ info->props[i].value = info->fontDescent;
+ i++;
+ }
+
+ if(!face->bitmap) {
+ info->props[i].name = MakeAtom("RAW_DESCENT", 11, TRUE);
+ info->props[i].value =
+ -((double)face->face->descender/(double)upm*1000.0);
+ i++;
+ }
+
+ j = FTGetEnglishName(face->face, TT_NAME_ID_COPYRIGHT,
+ val, MAXFONTNAMELEN);
+ vp = val;
+ if (j < 0) {
+ if(t1info && t1info->notice) {
+ vp = t1info->notice;
+ j = strlen(vp);
+ }
+ }
+ if(j > 0) {
+ info->props[i].name = MakeAtom("COPYRIGHT", 9, TRUE);
+ info->props[i].value = MakeAtom(vp, j, TRUE);
+ info->isStringProp[i] = 1;
+ i++;
+ }
+
+ j = FTGetEnglishName(face->face, TT_NAME_ID_FULL_NAME,
+ val, MAXFONTNAMELEN);
+ vp = val;
+ if (j < 0) {
+ if(t1info && t1info->full_name) {
+ vp = t1info->full_name;
+ j = strlen(vp);
+ }
+ }
+ if(j > 0) {
+ info->props[i].name = MakeAtom("FACE_NAME", 9, TRUE);
+ info->props[i].value = MakeAtom(vp, j, TRUE);
+ info->isStringProp[i] = 1;
+ i++;
+ }
+
+ vp = (char *)FT_Get_Postscript_Name(face->face);
+ if (vp) {
+ j = strlen(vp);
+ } else {
+ j = -1;
+ }
+ if (j < 0) {
+ j = FTGetEnglishName(face->face, TT_NAME_ID_PS_NAME,
+ val, MAXFONTNAMELEN);
+ vp = val;
+ }
+ if (j < 0) {
+ if(t1info && t1info->full_name) {
+ vp = t1info->full_name;
+ j = strlen(vp);
+ }
+ }
+ if(j > 0) {
+ info->props[i].name = MakeAtom("_ADOBE_POSTSCRIPT_FONTNAME", 26, TRUE);
+ info->props[i].value = MakeAtom(vp, j, TRUE);
+ info->isStringProp[i] = 1;
+ i++;
+ }
+
+ /* These macros handle the case of a diagonal matrix. They convert
+ FUnits into pixels. */
+#define TRANSFORM_FUNITS_X(xval) \
+ ((int) \
+ floor( ((double)(xval)/(double)upm) * (double)vals->pixel_matrix[0] + 0.5 ) )
+
+#define TRANSFORM_FUNITS_Y(yval) \
+ ((int) \
+ floor( ((double)(yval)/(double)upm) * (double)vals->pixel_matrix[3] + 0.5 ) )
+
+ /* In what follows, we assume the matrix is diagonal. In the rare
+ case when it is not, the values will be somewhat wrong. */
+
+ if( font_properties && os2 ) {
+ info->props[i].name = MakeAtom("SUBSCRIPT_SIZE",14,TRUE);
+ info->props[i].value =
+ TRANSFORM_FUNITS_Y(os2->ySubscriptYSize);
+ i++;
+ info->props[i].name = MakeAtom("SUBSCRIPT_X",11,TRUE);
+ info->props[i].value =
+ TRANSFORM_FUNITS_X(os2->ySubscriptXOffset);
+ i++;
+ info->props[i].name = MakeAtom("SUBSCRIPT_Y",11,TRUE);
+ info->props[i].value =
+ TRANSFORM_FUNITS_Y(os2->ySubscriptYOffset);
+ i++;
+ info->props[i].name = MakeAtom("SUPERSCRIPT_SIZE",16,TRUE);
+ info->props[i].value =
+ TRANSFORM_FUNITS_Y(os2->ySuperscriptYSize);
+ i++;
+ info->props[i].name = MakeAtom("SUPERSCRIPT_X",13,TRUE);
+ info->props[i].value =
+ TRANSFORM_FUNITS_X(os2->ySuperscriptXOffset);
+ i++;
+ info->props[i].name = MakeAtom("SUPERSCRIPT_Y",13,TRUE);
+ info->props[i].value =
+ TRANSFORM_FUNITS_Y(os2->ySuperscriptYOffset);
+ i++;
+ }
+
+ if( font_properties && (post || t1info) ) {
+ int underlinePosition, underlineThickness;
+
+ /* Raw underlineposition counts upwards,
+ but UNDERLINE_POSITION counts downwards. */
+ if(post) {
+ underlinePosition = TRANSFORM_FUNITS_Y(-post->underlinePosition);
+ underlineThickness = TRANSFORM_FUNITS_Y(post->underlineThickness);
+ } else {
+ underlinePosition =
+ TRANSFORM_FUNITS_Y(-t1info->underline_position);
+ underlineThickness =
+ TRANSFORM_FUNITS_Y(t1info->underline_thickness);
+ }
+ if(underlineThickness <= 0)
+ underlineThickness = 1;
+
+ info->props[i].name = MakeAtom("UNDERLINE_THICKNESS",19,TRUE);
+ info->props[i].value = underlineThickness;
+ i++;
+
+ info->props[i].name = MakeAtom("UNDERLINE_POSITION",18,TRUE);
+
+ info->props[i].value = underlinePosition;
+
+ i++;
+
+ /* The italic angle is often unreliable for Type 1 fonts */
+ if(post && trans->matrix.xx == trans->matrix.yy) {
+ info->props[i].name = MakeAtom("ITALIC_ANGLE",12,TRUE);
+ info->props[i].value =
+ /* Convert from TT_Fixed to
+ 64th of a degree counterclockwise from 3 o'clock */
+ 90*64+(post->italicAngle >> 10);
+ i++;
+ }
+#undef TRANSFORM_FUNITS_X
+#undef TRANSFORM_FUNITS_Y
+ }
+
+ info->props[i].name = MakeAtom("FONT_TYPE", 9, TRUE);
+ vp = (char *)FT_Get_X11_Font_Format(face->face);
+ info->props[i].value = MakeAtom(vp, strlen(vp), TRUE);
+ info->isStringProp[i] = 1;
+ i++;
+
+ info->props[i].name = MakeAtom("RASTERIZER_NAME", 15, TRUE);
+ info->props[i].value = MakeAtom("FreeType", 10, TRUE);
+ info->isStringProp[i] = 1;
+ i++;
+
+ info->nprops = i;
+ return Successful;
+}
+
+static int
+ft_get_index(unsigned code, FTFontPtr font, unsigned *idx)
+{
+
+ /* As a special case, we pass 0 even when it is not in the ranges;
+ this will allow for the default glyph, which should exist in any
+ TrueType font. */
+
+ /* This is not required...
+ if(code > 0 && font->nranges) {
+ int i;
+ for(i = 0; i < font->nranges; i++)
+ if((code >=
+ font->ranges[i].min_char_low+
+ (font->ranges[i].min_char_high<<8)) &&
+ (code <=
+ font->ranges[i].max_char_low +
+ (font->ranges[i].max_char_high<<8)))
+ break;
+ if(i == font->nranges) {
+ *idx = font->zero_idx;
+ return -1;
+ }
+ }
+ */
+ if( font->info ) {
+ if( !( font->info->firstCol <= (code & 0x000ff) &&
+ (code & 0x000ff) <= font->info->lastCol &&
+ font->info->firstRow <= (code >> 8) &&
+ (code >> 8) <= font->info->lastRow ) ) {
+ *idx = font->zero_idx;
+ /* Error: The code has not been parsed in ft_compute_bounds()!
+ We should not return any metrics. */
+ return -1;
+ }
+ }
+
+ *idx = FTRemap(font->instance->face->face, &font->mapping, code);
+
+ return 0;
+}
+
+static int
+FreeTypeFontGetGlyph(unsigned code, int flags, CharInfoPtr *g, FTFontPtr font)
+{
+ unsigned idx = 0;
+ int xrc;
+
+#ifdef X_ACCEPTS_NO_SUCH_CHAR
+ if( ft_get_index(code,font,&idx) || idx == 0 || idx == font->zero_idx ) {
+ *g = NULL;
+ flags &= ~FT_FORCE_CONSTANT_SPACING;
+ /* if( font->instance->spacing != FT_CHARCELL ) */
+ return Successful;
+ }
+#else
+ if( ft_get_index(code,font,&idx) ) {
+ /* The code has not been parsed! */
+ *g = NULL;
+ flags &= ~FT_FORCE_CONSTANT_SPACING;
+ }
+#endif
+
+ xrc = FreeTypeInstanceGetGlyph(idx, flags, g, font->instance);
+ if( xrc == Successful && *g != NULL )
+ return Successful;
+ if( font->zero_idx != idx ) {
+ xrc = FreeTypeInstanceGetGlyph(font->zero_idx, flags, g, font->instance);
+ if( xrc == Successful && *g != NULL )
+ return Successful;
+ }
+ return FreeTypeInstanceGetGlyph(font->zero_idx, flags|FT_GET_DUMMY, g, font->instance);
+}
+
+static int
+FreeTypeFontGetGlyphMetrics(unsigned code, int flags, xCharInfo **metrics, FTFontPtr font)
+{
+ unsigned idx = 0;
+ int xrc;
+
+#ifdef X_ACCEPTS_NO_SUCH_CHAR
+ if ( ft_get_index(code,font,&idx) || idx == 0 || idx == font->zero_idx ) {
+ *metrics = NULL;
+ flags &= ~FT_FORCE_CONSTANT_SPACING;
+ /* if( font->instance->spacing != FT_CHARCELL ) */
+ return Successful;
+ }
+#else
+ if ( ft_get_index(code,font,&idx) || idx == 0 || idx == font->zero_idx ) {
+ /* The code has not been parsed! */
+ *metrics = NULL;
+ flags &= ~FT_FORCE_CONSTANT_SPACING;
+ }
+#endif
+
+ xrc = FreeTypeInstanceGetGlyphMetrics(idx, flags, metrics, font->instance);
+ if( xrc == Successful && *metrics != NULL )
+ return Successful;
+ if( font->zero_idx != idx ) {
+ xrc = FreeTypeInstanceGetGlyphMetrics(font->zero_idx, flags,
+ metrics, font->instance);
+ if( xrc == Successful && *metrics != NULL )
+ return Successful;
+ }
+ return FreeTypeInstanceGetGlyphMetrics(font->zero_idx, flags|FT_GET_DUMMY, metrics, font->instance);
+}
+
+/*
+ * restrict code range
+ *
+ * boolean for the numeric zone:
+ * results = results & (ranges[0] | ranges[1] | ... ranges[nranges-1])
+ */
+
+static void
+restrict_code_range(unsigned short *refFirstCol,
+ unsigned short *refFirstRow,
+ unsigned short *refLastCol,
+ unsigned short *refLastRow,
+ fsRange const *ranges, int nRanges)
+{
+ if (nRanges) {
+ int minCol = 256, minRow = 256, maxCol = -1, maxRow = -1;
+ fsRange const *r = ranges;
+ int i;
+
+ for (i=0; i<nRanges; i++) {
+ if (r->min_char_high != r->max_char_high) {
+ minCol = 0x00;
+ maxCol = 0xff;
+ } else {
+ if (minCol > r->min_char_low)
+ minCol = r->min_char_low;
+ if (maxCol < r->max_char_low)
+ maxCol = r->max_char_low;
+ }
+ if (minRow > r->min_char_high)
+ minRow = r->min_char_high;
+ if (maxRow < r->max_char_high)
+ maxRow = r->max_char_high;
+ r++;
+ }
+
+ if (minCol > *refLastCol)
+ *refFirstCol = *refLastCol;
+ else if (minCol > *refFirstCol)
+ *refFirstCol = minCol;
+
+ if (maxCol < *refFirstCol)
+ *refLastCol = *refFirstCol;
+ else if (maxCol < *refLastCol)
+ *refLastCol = maxCol;
+
+ if (minRow > *refLastRow) {
+ *refFirstRow = *refLastRow;
+ *refFirstCol = *refLastCol;
+ } else if (minRow > *refFirstRow)
+ *refFirstRow = minRow;
+
+ if (maxRow < *refFirstRow) {
+ *refLastRow = *refFirstRow;
+ *refLastCol = *refFirstCol;
+ } else if (maxRow < *refLastRow)
+ *refLastRow = maxRow;
+ }
+}
+
+
+static int
+restrict_code_range_by_str(int count,unsigned short *refFirstCol,
+ unsigned short *refFirstRow,
+ unsigned short *refLastCol,
+ unsigned short *refLastRow,
+ char const *str)
+{
+ int nRanges = 0;
+ int result = 0;
+ fsRange *ranges = NULL;
+ char const *p, *q;
+
+ p = q = str;
+ for (;;) {
+ int minpoint=0, maxpoint=65535;
+ long val;
+
+ /* skip comma and/or space */
+ while (',' == *p || isspace(*p))
+ p++;
+
+ /* begin point */
+ if ('-' != *p) {
+ val = strtol(p, (char **)&q, 0);
+ if (p == q)
+ /* end or illegal */
+ break;
+ if (val<0 || val>65535) {
+ /* out of zone */
+ break;
+ }
+ minpoint = val;
+ p=q;
+ }
+
+ /* skip space */
+ while (isspace(*p))
+ p++;
+
+ if (',' != *p && '\0' != *p) {
+ /* contiune */
+ if ('-' == *p)
+ /* hyphon */
+ p++;
+ else
+ /* end or illegal */
+ break;
+
+ /* skip space */
+ while (isspace(*p))
+ p++;
+
+ val = strtol(p, (char **)&q, 0);
+ if (p != q) {
+ if (val<0 || val>65535)
+ break;
+ maxpoint = val;
+ } else if (',' != *p && '\0' != *p)
+ /* end or illegal */
+ break;
+ p=q;
+ } else
+ /* comma - single code */
+ maxpoint = minpoint;
+
+ if ( count <= 0 && minpoint>maxpoint ) {
+ int tmp;
+ tmp = minpoint;
+ minpoint = maxpoint;
+ maxpoint = tmp;
+ }
+
+ /* add range */
+#if 0
+ fprintf(stderr, "zone: 0x%04X - 0x%04X\n", minpoint, maxpoint);
+ fflush(stderr);
+#endif
+ nRanges++;
+ ranges = (fsRange *)xrealloc(ranges, nRanges*sizeof(*ranges));
+ if (NULL == ranges)
+ break;
+ {
+ fsRange *r = ranges+nRanges-1;
+
+ r->min_char_low = minpoint & 0xff;
+ r->max_char_low = maxpoint & 0xff;
+ r->min_char_high = (minpoint>>8) & 0xff;
+ r->max_char_high = (maxpoint>>8) & 0xff;
+ }
+ }
+
+ if (ranges) {
+ if ( count <= 0 ) {
+ restrict_code_range(refFirstCol, refFirstRow, refLastCol, refLastRow,
+ ranges, nRanges);
+ }
+ else {
+ int i;
+ fsRange *r;
+ for ( i=0 ; i<nRanges ; i++ ) {
+ if ( count <= i ) break;
+ r = ranges+i;
+ refFirstCol[i] = r->min_char_low;
+ refLastCol[i] = r->max_char_low;
+ refFirstRow[i] = r->min_char_high;
+ refLastRow[i] = r->max_char_high;
+ }
+ result=i;
+ }
+ xfree(ranges);
+ }
+ return result;
+}
+
+/* *face_number and *spacing are initialized but *load_flags is NOT. */
+static int
+FreeTypeSetUpTTCap( char *fileName, FontScalablePtr vals,
+ char **dynStrRealFileName, char **dynStrFTFileName,
+ struct TTCapInfo *ret, int *face_number, FT_Int32 *load_flags,
+ int *spacing, Bool *font_properties, char **dynStrTTCapCodeRange )
+{
+ int result = Successful;
+ SDynPropRecValList listPropRecVal;
+ SPropRecValContainer contRecValue;
+ Bool hinting=True;
+ Bool isEmbeddedBitmap = True;
+ Bool alwaysEmbeddedBitmap = False;
+ int pixel = vals->pixel;
+
+ *font_properties=True;
+ *dynStrRealFileName=NULL;
+ *dynStrFTFileName=NULL;
+ *dynStrTTCapCodeRange=NULL;
+
+ if (SPropRecValList_new(&listPropRecVal)) {
+ return AllocError;
+ }
+
+ {
+ int len = strlen(fileName);
+ char *capHead = NULL;
+ {
+ /* font cap */
+ char *p1=NULL, *p2=NULL;
+
+ p1=strrchr(fileName, '/');
+ if ( p1 == NULL ) p1 = fileName;
+ else p1++;
+ if (NULL != (p2=strrchr(p1, ':'))) {
+ /* colon exist in the right side of slash. */
+ int dirLen = p1-fileName;
+ int baseLen = fileName+len - p2 -1;
+
+ *dynStrRealFileName = (char *)xalloc(dirLen+baseLen+1);
+ if( *dynStrRealFileName == NULL ) {
+ result = AllocError;
+ goto quit;
+ }
+ if ( 0 < dirLen )
+ memcpy(*dynStrRealFileName, fileName, dirLen);
+ strcpy(*dynStrRealFileName+dirLen, p2+1);
+ capHead = p1;
+ } else {
+ *dynStrRealFileName = xstrdup(fileName);
+ if( *dynStrRealFileName == NULL ) {
+ result = AllocError;
+ goto quit;
+ }
+ }
+ }
+
+ /* font cap */
+ if (capHead) {
+ if (SPropRecValList_add_by_font_cap(&listPropRecVal,
+ capHead)) {
+ result = BadFontPath;
+ goto quit;
+ }
+ }
+ }
+
+ *face_number=0;
+ *spacing=0;
+ ret->autoItalic=0.0;
+ ret->scaleWidth=1.0;
+ ret->scaleBBoxWidth = 1.0;
+ ret->scaleBBoxHeight = 1.0;
+ ret->doubleStrikeShift = 1;
+ ret->adjustBBoxWidthByPixel = 0;
+ ret->adjustLeftSideBearingByPixel = 0;
+ ret->adjustRightSideBearingByPixel = 0;
+ ret->flags = 0;
+ ret->scaleBitmap = 0.0;
+ ret->forceConstantSpacingBegin = -1;
+ ret->forceConstantSpacingEnd = -1;
+ ret->force_c_representative_metrics_char_code = -2;
+ ret->force_c_scale_b_box_width = 1.0;
+ ret->force_c_scale_b_box_height = 1.0;
+ ret->force_c_adjust_width_by_pixel = 0;
+ ret->force_c_adjust_lsb_by_pixel = 0;
+ ret->force_c_adjust_rsb_by_pixel = 0;
+ ret->force_c_scale_lsb = 0.0;
+ ret->force_c_scale_rsb = 1.0;
+ /* */
+ ret->vl_slant=0;
+ ret->lsbShiftOfBitmapAutoItalic=0;
+ ret->rsbShiftOfBitmapAutoItalic=0;
+ /* face number */
+ {
+ char *beginptr=NULL,*endptr;
+ if ( SPropRecValList_search_record(&listPropRecVal,
+ &contRecValue,
+ "FaceNumber")) {
+ int lv;
+ beginptr = SPropContainer_value_str(contRecValue);
+ lv=strtol(beginptr, &endptr, 10);
+ if ( *beginptr != '\0' && *endptr == '\0' ) {
+ if ( 0 < lv ) *face_number = lv;
+ }
+ }
+ if( beginptr && 0 < *face_number ) {
+ char *slash;
+ *dynStrFTFileName = /* add -> ':'+strlen0+':'+strlen1+'\0' */
+ (char *)xalloc(1+strlen(beginptr)+1+strlen(*dynStrRealFileName)+1);
+ if( *dynStrFTFileName == NULL ){
+ result = AllocError;
+ goto quit;
+ }
+ **dynStrFTFileName = '\0';
+ slash = strrchr(*dynStrRealFileName,'/');
+ if( slash ) {
+ char *p;
+ strcat(*dynStrFTFileName,*dynStrRealFileName);
+ p = strrchr(*dynStrFTFileName,'/');
+ p[1] = '\0';
+ strcat(*dynStrFTFileName,":");
+ strcat(*dynStrFTFileName,beginptr);
+ strcat(*dynStrFTFileName,":");
+ strcat(*dynStrFTFileName,slash+1);
+ }
+ else{
+ strcat(*dynStrFTFileName,":");
+ strcat(*dynStrFTFileName,beginptr);
+ strcat(*dynStrFTFileName,":");
+ strcat(*dynStrFTFileName,*dynStrRealFileName);
+ }
+ }
+ else{
+ *dynStrFTFileName = (char *)xalloc(strlen(*dynStrRealFileName)+1);
+ if( *dynStrFTFileName == NULL ){
+ result = AllocError;
+ goto quit;
+ }
+ **dynStrFTFileName = '\0';
+ strcat(*dynStrFTFileName,*dynStrRealFileName);
+ }
+ }
+ /*
+ fprintf(stderr,"[Filename:%s]\n",fileName);
+ fprintf(stderr,"[RealFilename:%s]\n",*dynStrRealFileName);
+ fprintf(stderr,"[FTFilename:%s]\n",*dynStrFTFileName);
+ */
+ /* slant control */
+ if (SPropRecValList_search_record(&listPropRecVal,
+ &contRecValue,
+ "AutoItalic"))
+ ret->autoItalic = SPropContainer_value_dbl(contRecValue);
+ /* hinting control */
+ if (SPropRecValList_search_record(&listPropRecVal,
+ &contRecValue,
+ "Hinting"))
+ hinting = SPropContainer_value_bool(contRecValue);
+ /* scaling */
+ if (SPropRecValList_search_record(&listPropRecVal,
+ &contRecValue,
+ "ScaleWidth")) {
+ ret->scaleWidth = SPropContainer_value_dbl(contRecValue);
+ if (ret->scaleWidth<=0.0) {
+ fprintf(stderr, "ScaleWitdh needs plus.\n");
+ result = BadFontName;
+ goto quit;
+ }
+ }
+ /* bbox adjustment */
+ if (SPropRecValList_search_record(&listPropRecVal,
+ &contRecValue,
+ "ScaleBBoxWidth")) {
+ /* Scaling to Bounding Box Width */
+ int lv;
+ char *endptr,*beginptr;
+ double v,scaleBBoxWidth=1.0,scaleBBoxHeight=1.0;
+ beginptr = SPropContainer_value_str(contRecValue);
+ do {
+ if ( strlen(beginptr) < 1 ) break;
+ v=strtod(beginptr, &endptr);
+ if ( endptr!=beginptr ) {
+ scaleBBoxWidth = v;
+ }
+ if ( *endptr != ';' && *endptr != ',' ) break;
+ if ( *endptr == ',' ) {
+ beginptr=endptr+1;
+ v=strtod(beginptr, &endptr);
+ if ( endptr!=beginptr ) {
+ scaleBBoxHeight = v;
+ }
+ }
+ if ( *endptr != ';' && *endptr != ',' ) break;
+ beginptr=endptr+1;
+ lv=strtol(beginptr, &endptr, 10);
+ if ( endptr!=beginptr ) {
+ ret->adjustBBoxWidthByPixel = lv;
+ }
+ if ( *endptr != ',' ) break;
+ beginptr=endptr+1;
+ lv=strtol(beginptr, &endptr, 10);
+ if ( endptr!=beginptr ) {
+ ret->adjustLeftSideBearingByPixel = lv;
+ }
+ if ( *endptr != ',' ) break;
+ beginptr=endptr+1;
+ lv=strtol(beginptr, &endptr, 10);
+ if ( endptr!=beginptr ) {
+ ret->adjustRightSideBearingByPixel = lv;
+ }
+ } while ( 0 );
+ if (scaleBBoxWidth<=0.0) {
+ fprintf(stderr, "ScaleBBoxWitdh needs plus.\n");
+ result = BadFontName;
+ goto quit;
+ }
+ if (scaleBBoxHeight<=0.0) {
+ fprintf(stderr, "ScaleBBoxHeight needs plus.\n");
+ result = BadFontName;
+ goto quit;
+ }
+ ret->scaleBBoxWidth = scaleBBoxWidth;
+ ret->scaleBBoxHeight = scaleBBoxHeight;
+ }
+ /* spacing */
+ if (SPropRecValList_search_record(&listPropRecVal,
+ &contRecValue,
+ "ForceSpacing")) {
+ char *strSpace = SPropContainer_value_str(contRecValue);
+ Bool err = False;
+ if (1 != strlen(strSpace))
+ err = True;
+ else
+ switch (strSpace[0]) {
+ case 'M':
+ ret->flags |= TTCAP_MONO_CENTER;
+ *spacing = 'm';
+ break;
+ case 'm':
+ case 'p':
+ case 'c':
+ *spacing = strSpace[0];
+ break;
+ default:
+ err = True;
+ }
+ if (err) {
+ result = BadFontName;
+ goto quit;
+ }
+ }
+ /* doube striking */
+ if (SPropRecValList_search_record(&listPropRecVal,
+ &contRecValue,
+ "DoubleStrike")) {
+ /* Set or Reset Auto Bold Flag */
+ char *strDoubleStrike = SPropContainer_value_str(contRecValue);
+ Bool err = False;
+ if ( 0 < strlen(strDoubleStrike) ) {
+ switch (strDoubleStrike[0]) {
+ case 'm':
+ case 'M':
+ case 'l':
+ case 'L':
+ ret->flags |= TTCAP_DOUBLE_STRIKE;
+ ret->flags |= TTCAP_DOUBLE_STRIKE_MKBOLD_EDGE_LEFT;
+ break;
+ case 'y':
+ case 'Y':
+ ret->flags |= TTCAP_DOUBLE_STRIKE;
+ break;
+ case 'n':
+ case 'N':
+ ret->flags &= ~TTCAP_DOUBLE_STRIKE;
+ ret->flags &= ~TTCAP_DOUBLE_STRIKE_MKBOLD_EDGE_LEFT;
+ ret->flags &= ~TTCAP_DOUBLE_STRIKE_CORRECT_B_BOX_WIDTH;
+ break;
+ default:
+ err = True;
+ }
+ if ( err != True ) {
+ if ( strDoubleStrike[1] ) {
+ switch (strDoubleStrike[1]) {
+ case 'b':
+ case 'B':
+ case 'p':
+ case 'P':
+ case 'y':
+ case 'Y':
+ ret->flags |= TTCAP_DOUBLE_STRIKE_CORRECT_B_BOX_WIDTH;
+ break;
+ default:
+ break;
+ }
+ }
+ do {
+ char *comma_ptr=strchr(strDoubleStrike,';');
+ if ( !comma_ptr ) comma_ptr=strchr(strDoubleStrike,',');
+ if ( !comma_ptr ) break;
+ if ( comma_ptr[1] ) {
+ char *endptr;
+ int mkboldMaxPixel;
+ mkboldMaxPixel=strtol(comma_ptr+1, &endptr, 10);
+ if ( endptr != comma_ptr+1 && mkboldMaxPixel <= pixel ) {
+ ret->flags &= ~TTCAP_DOUBLE_STRIKE_MKBOLD_EDGE_LEFT;
+ }
+ }
+ comma_ptr=strchr(comma_ptr+1,',');
+ if ( !comma_ptr ) break;
+ if ( comma_ptr[1] ) {
+ char *endptr;
+ int max_pixel;
+ max_pixel=strtol(comma_ptr+1, &endptr, 10);
+ if ( endptr != comma_ptr+1 && max_pixel <= pixel ) {
+ if( ret->flags & TTCAP_DOUBLE_STRIKE )
+ ret->doubleStrikeShift += pixel / max_pixel;
+ }
+ }
+ } while(0);
+ }
+ }
+ else
+ err = True;
+ if (err) {
+ result = BadFontName;
+ goto quit;
+ }
+ }
+ /* very lazy metrics */
+ if (SPropRecValList_search_record(&listPropRecVal,
+ &contRecValue,
+ "VeryLazyMetrics")){
+ Bool isVeryLazy = SPropContainer_value_bool(contRecValue);
+ ret->flags |= TTCAP_DISABLE_DEFAULT_VERY_LAZY;
+ if( isVeryLazy == True )
+ ret->flags |= TTCAP_IS_VERY_LAZY;
+ else
+ ret->flags &= ~TTCAP_IS_VERY_LAZY;
+ }
+ /* embedded bitmap */
+ if (SPropRecValList_search_record(&listPropRecVal,
+ &contRecValue,
+ "EmbeddedBitmap")) {
+ char *strEmbeddedBitmap = SPropContainer_value_str(contRecValue);
+ Bool err = False;
+ if ( 1 == strlen(strEmbeddedBitmap) ) {
+ switch (strEmbeddedBitmap[0]) {
+ case 'y':
+ case 'Y':
+ isEmbeddedBitmap = True;
+ alwaysEmbeddedBitmap = True;
+ break;
+ case 'u':
+ case 'U':
+ isEmbeddedBitmap = True;
+ alwaysEmbeddedBitmap = False;
+ break;
+ case 'n':
+ case 'N':
+ isEmbeddedBitmap = False;
+ break;
+ default:
+ err = True;
+ }
+ }
+ else
+ err = True;
+ if (err) {
+ result = BadFontName;
+ goto quit;
+ }
+ }
+ /* scale bitmap */
+ if((ret->flags & TTCAP_IS_VERY_LAZY) &&
+ SPropRecValList_search_record(&listPropRecVal,
+ &contRecValue,
+ "VeryLazyBitmapWidthScale")) {
+ /* Scaling to Bitmap Bounding Box Width */
+ double scaleBitmapWidth = SPropContainer_value_dbl(contRecValue);
+
+ fprintf(stderr, "Warning: `bs' option is not required in X-TT version 2.\n");
+#if 0
+ if (scaleBitmapWidth<=0.0) {
+ fprintf(stderr, "ScaleBitmapWitdh needs plus.\n");
+ result = BadFontName;
+ goto quit;
+ }
+#endif
+ ret->scaleBitmap = scaleBitmapWidth;
+ }
+ /* restriction of the code range */
+ if (SPropRecValList_search_record(&listPropRecVal,
+ &contRecValue,
+ "CodeRange")) {
+ *dynStrTTCapCodeRange = xstrdup(SPropContainer_value_str(contRecValue));
+ if( *dynStrTTCapCodeRange == NULL ) {
+ result = AllocError;
+ goto quit;
+ }
+ }
+ /* forceConstantSpacing{Begin,End} */
+ if ( 1 /* ft->spacing == 'p' */ ){
+ unsigned short first_col=0,last_col=0x00ff;
+ unsigned short first_row=0,last_row=0x00ff;
+ if (SPropRecValList_search_record(&listPropRecVal,
+ &contRecValue,
+ "ForceConstantSpacingCodeRange")) {
+ if ( restrict_code_range_by_str(1,&first_col, &first_row,
+ &last_col, &last_row,
+ SPropContainer_value_str(contRecValue)) == 1 ) {
+ ret->forceConstantSpacingBegin = (int)( first_row<<8 | first_col );
+ ret->forceConstantSpacingEnd = (int)( last_row<<8 | last_col );
+ if ( ret->forceConstantSpacingBegin <= ret->forceConstantSpacingEnd )
+ ret->flags &= ~TTCAP_FORCE_C_OUTSIDE;
+ else ret->flags |= TTCAP_FORCE_C_OUTSIDE;
+ }
+ }
+ }
+ /* */
+ if ( 1 ){
+ unsigned short first_col=0, last_col=0x0ff;
+ unsigned short first_row=0, last_row=0x0ff;
+ if ( SPropRecValList_search_record(&listPropRecVal,
+ &contRecValue,
+ "ForceConstantSpacingMetrics")) {
+ char *strMetrics;
+ strMetrics = SPropContainer_value_str(contRecValue);
+ if ( strMetrics ) {
+ char *comma_ptr,*period_ptr,*semic_ptr;
+ semic_ptr=strchr(strMetrics,';');
+ comma_ptr=strchr(strMetrics,',');
+ period_ptr=strchr(strMetrics,'.');
+ if ( semic_ptr && comma_ptr )
+ if ( semic_ptr < comma_ptr ) comma_ptr=NULL;
+ if ( semic_ptr && period_ptr )
+ if ( semic_ptr < period_ptr ) period_ptr=NULL;
+ if ( !comma_ptr && !period_ptr && strMetrics != semic_ptr ) {
+ if ( restrict_code_range_by_str(1,&first_col, &first_row,
+ &last_col, &last_row,
+ SPropContainer_value_str(contRecValue)) == 1 ) {
+ ret->force_c_representative_metrics_char_code =
+ (int)( first_row<<8 | first_col );
+ }
+ }
+ else {
+ double v;
+ char *endptr,*beginptr=strMetrics;
+ do {
+ v=strtod(beginptr, &endptr);
+ if ( endptr!=beginptr ) {
+ ret->force_c_scale_b_box_width = v;
+ }
+ if ( *endptr != ',' ) break;
+ beginptr=endptr+1;
+ v=strtod(beginptr, &endptr);
+ if ( endptr!=beginptr ) {
+ ret->force_c_scale_lsb = v;
+ ret->flags |= TTCAP_FORCE_C_LSB_FLAG;
+ }
+ if ( *endptr != ',' ) break;
+ beginptr=endptr+1;
+ v=strtod(beginptr, &endptr);
+ if ( endptr!=beginptr ) {
+ ret->force_c_scale_rsb = v;
+ ret->flags |= TTCAP_FORCE_C_RSB_FLAG;
+ }
+ if ( *endptr != ',' ) break;
+ beginptr=endptr+1;
+ v=strtod(beginptr, &endptr);
+ if ( endptr!=beginptr ) {
+ ret->force_c_scale_b_box_height = v;
+ }
+ } while (0);
+ }
+ if ( semic_ptr ) {
+ int lv;
+ char *endptr,*beginptr=semic_ptr+1;
+ do {
+ lv=strtol(beginptr, &endptr, 10);
+ if ( endptr!=beginptr ) {
+ ret->force_c_adjust_width_by_pixel=lv;
+ }
+ if ( *endptr != ',' ) break;
+ beginptr=endptr+1;
+ lv=strtol(beginptr, &endptr, 10);
+ if ( endptr!=beginptr ) {
+ ret->force_c_adjust_lsb_by_pixel=lv;
+ }
+ if ( *endptr != ',' ) break;
+ beginptr=endptr+1;
+ lv=strtol(beginptr, &endptr, 10);
+ if ( endptr!=beginptr ) {
+ ret->force_c_adjust_rsb_by_pixel=lv;
+ }
+ } while (0);
+ }
+ }
+ }
+ }
+
+ if (SPropRecValList_search_record(&listPropRecVal,
+ &contRecValue,
+ "FontProperties")) {
+ /* Set or Reset the Flag of FontProperties */
+ *font_properties=SPropContainer_value_bool(contRecValue);
+ }
+
+ ret->force_c_scale_b_box_width *= ret->scaleBBoxWidth;
+ ret->force_c_scale_b_box_height *= ret->scaleBBoxHeight;
+
+ ret->force_c_scale_b_box_width *= ret->scaleWidth;
+ ret->scaleBBoxWidth *= ret->scaleWidth;
+
+ ret->force_c_adjust_rsb_by_pixel += ret->adjustRightSideBearingByPixel;
+ ret->force_c_adjust_lsb_by_pixel += ret->adjustLeftSideBearingByPixel;
+
+ /* scaleWidth, scaleBBoxWidth, force_c_scale_b_box_width, force_c_scale_b_box_width */
+
+ /* by TTCap */
+ if( hinting == False ) *load_flags |= FT_LOAD_NO_HINTING;
+ if( isEmbeddedBitmap == False ) *load_flags |= FT_LOAD_NO_BITMAP;
+ if( ret->autoItalic != 0 && alwaysEmbeddedBitmap == False )
+ *load_flags |= FT_LOAD_NO_BITMAP;
+
+ quit:
+ return result;
+}
+
+static int
+ft_get_trans_from_vals( FontScalablePtr vals, FTNormalisedTransformationPtr trans )
+{
+ /* Compute the transformation matrix. We use floating-point
+ arithmetic for simplicity */
+
+ trans->xres = vals->x;
+ trans->yres = vals->y;
+
+ /* This value cannot be 0. */
+ trans->scale = hypot(vals->point_matrix[2], vals->point_matrix[3]);
+ trans->nonIdentity = 0;
+
+ /* Try to round stuff. We want approximate zeros to be exact zeros,
+ and if the elements on the diagonal are approximately equal, we
+ want them equal. We do this to avoid breaking hinting. */
+ if(DIFFER(vals->point_matrix[0], vals->point_matrix[3])) {
+ trans->nonIdentity = 1;
+ trans->matrix.xx =
+ (int)((vals->point_matrix[0]*(double)TWO_SIXTEENTH)/trans->scale);
+ trans->matrix.yy =
+ (int)((vals->point_matrix[3]*(double)TWO_SIXTEENTH)/trans->scale);
+ } else {
+ trans->matrix.xx = trans->matrix.yy =
+ ((vals->point_matrix[0] + vals->point_matrix[3])/2*
+ (double)TWO_SIXTEENTH)/trans->scale;
+ }
+
+ if(DIFFER0(vals->point_matrix[1], trans->scale)) {
+ trans->matrix.yx =
+ (int)((vals->point_matrix[1]*(double)TWO_SIXTEENTH)/trans->scale);
+ trans->nonIdentity = 1;
+ } else
+ trans->matrix.yx = 0;
+
+ if(DIFFER0(vals->point_matrix[2], trans->scale)) {
+ trans->matrix.xy =
+ (int)((vals->point_matrix[2]*(double)TWO_SIXTEENTH)/trans->scale);
+ trans->nonIdentity = 1;
+ } else
+ trans->matrix.xy=0;
+ return 0;
+}
+
+
+static int
+is_fixed_width(FT_Face face)
+{
+ PS_FontInfoRec t1info_rec;
+ int ftrc;
+
+ if(FT_IS_FIXED_WIDTH(face)) {
+ return 1;
+ }
+
+ ftrc = FT_Get_PS_Font_Info(face, &t1info_rec);
+ if(ftrc == 0 && t1info_rec.is_fixed_pitch) {
+ return 1;
+ }
+
+ return 0;
+}
+
+static int
+FreeTypeLoadFont(FTFontPtr font, FontInfoPtr info, FTFacePtr face,
+ char *FTFileName, FontScalablePtr vals, FontEntryPtr entry,
+ FontBitmapFormatPtr bmfmt, FT_Int32 load_flags,
+ struct TTCapInfo *tmp_ttcap, char *dynStrTTCapCodeRange,
+ int ttcap_spacing )
+{
+ int xrc;
+ FTNormalisedTransformationRec trans;
+ int spacing, actual_spacing, zero_code;
+ long lastCode, firstCode;
+ TT_Postscript *post;
+
+ ft_get_trans_from_vals(vals,&trans);
+
+ /* Check for charcell in XLFD */
+ spacing = FT_PROPORTIONAL;
+ if(entry->name.ndashes == 14) {
+ char *p;
+ int dashes = 0;
+ for(p = entry->name.name;
+ p <= entry->name.name + entry->name.length - 2;
+ p++) {
+ if(*p == '-') {
+ dashes++;
+ if(dashes == 11) {
+ if(p[1]=='c' && p[2]=='-')
+ spacing=FT_CHARCELL;
+ else if(p[1]=='m' && p[2]=='-')
+ spacing=FT_MONOSPACED;
+ break;
+ }
+ }
+ }
+ }
+ /* by TTCap */
+ if( ttcap_spacing != 0 ) {
+ if( ttcap_spacing == 'c' ) spacing=FT_CHARCELL;
+ else if( ttcap_spacing == 'm' ) spacing=FT_MONOSPACED;
+ else spacing=FT_PROPORTIONAL;
+ }
+
+ actual_spacing = spacing;
+ if( spacing == FT_PROPORTIONAL ) {
+ if( is_fixed_width(face->face) )
+ actual_spacing = FT_MONOSPACED;
+ }
+
+ if(entry->name.ndashes == 14) {
+ xrc = FTPickMapping(entry->name.name, entry->name.length, FTFileName,
+ face->face, &font->mapping);
+ if (xrc != Successful)
+ return xrc;
+ } else {
+ xrc = FTPickMapping(0, 0, FTFileName,
+ face->face, &font->mapping);
+ if (xrc != Successful)
+ return xrc;
+ }
+
+ font->nranges = vals->nranges;
+ font->ranges = 0;
+ if(font->nranges) {
+ font->ranges = (fsRange*)xalloc(vals->nranges*sizeof(fsRange));
+ if(font->ranges == NULL)
+ return AllocError;
+ memcpy((char*)font->ranges, (char*)vals->ranges,
+ vals->nranges*sizeof(fsRange));
+ }
+
+ zero_code=-1;
+ if(info) {
+ firstCode = 0;
+ lastCode = 0xFFFFL;
+ if(!font->mapping.mapping ||
+ font->mapping.mapping->encoding->row_size == 0) {
+ /* linear indexing */
+ lastCode=MIN(lastCode,
+ font->mapping.mapping ?
+ font->mapping.mapping->encoding->size-1 :
+ 0xFF);
+ if(font->mapping.mapping && font->mapping.mapping->encoding->first)
+ firstCode = font->mapping.mapping->encoding->first;
+ info->firstRow = firstCode/0x100;
+ info->lastRow = lastCode/0x100;
+ info->firstCol =
+ (info->firstRow || info->lastRow) ? 0 : (firstCode & 0xFF);
+ info->lastCol = info->lastRow ? 0xFF : (lastCode & 0xFF);
+ if ( firstCode == 0 ) zero_code=0;
+ } else {
+ /* matrix indexing */
+ info->firstRow = font->mapping.mapping->encoding->first;
+ info->lastRow = MIN(font->mapping.mapping->encoding->size-1,
+ lastCode/0x100);
+ info->firstCol = font->mapping.mapping->encoding->first_col;
+ info->lastCol = MIN(font->mapping.mapping->encoding->row_size-1,
+ lastCode<0x100?lastCode:0xFF);
+ if( info->firstRow == 0 && info->firstCol == 0 ) zero_code=0;
+ }
+
+ /* firstCode and lastCode are not valid in case of a matrix
+ encoding */
+
+ if( dynStrTTCapCodeRange ) {
+ restrict_code_range_by_str(0,&info->firstCol, &info->firstRow,
+ &info->lastCol, &info->lastRow,
+ dynStrTTCapCodeRange);
+ }
+ restrict_code_range(&info->firstCol, &info->firstRow,
+ &info->lastCol, &info->lastRow,
+ font->ranges, font->nranges);
+ }
+ font->info = info;
+
+ /* zero code is frequently used. */
+ if ( zero_code < 0 ) {
+ /* The fontenc should have the information of DefaultCh.
+ But we do not have such a information.
+ So we cannot but set 0. */
+ font->zero_idx = 0;
+ }
+ else
+ font->zero_idx = FTRemap(face->face,
+ &font->mapping, zero_code);
+
+ post = FT_Get_Sfnt_Table(face->face, ft_sfnt_post);
+
+#ifdef DEFAULT_VERY_LAZY
+ if( !( tmp_ttcap->flags & TTCAP_DISABLE_DEFAULT_VERY_LAZY ) )
+ if( DEFAULT_VERY_LAZY <= 1 + info->lastRow - info->firstRow ) {
+ if( post ){
+ tmp_ttcap->flags |= TTCAP_IS_VERY_LAZY;
+ }
+ }
+#endif
+ /* We should always reset. */
+ tmp_ttcap->flags &= ~TTCAP_DISABLE_DEFAULT_VERY_LAZY;
+
+ if ( face->bitmap || actual_spacing == FT_CHARCELL )
+ tmp_ttcap->flags &= ~TTCAP_IS_VERY_LAZY;
+ /* "vl=y" is available when TrueType or OpenType only */
+ if ( !face->bitmap && !(FT_IS_SFNT( face->face )) )
+ tmp_ttcap->flags &= ~TTCAP_IS_VERY_LAZY;
+
+ if( post ) {
+ if( post->italicAngle != 0 )
+ tmp_ttcap->vl_slant = -sin( (post->italicAngle/1024./5760.)*1.57079632679489661923 );
+ /* fprintf(stderr,"angle=%g(%g)\n",tmp_ttcap->vl_slant,(post->italicAngle/1024./5760.)*90); */
+ }
+
+ xrc = FreeTypeOpenInstance(&font->instance, face,
+ FTFileName, &trans, actual_spacing, bmfmt,
+ tmp_ttcap, load_flags );
+ return xrc;
+}
+
+static void
+adjust_min_max(xCharInfo *minc, xCharInfo *maxc, xCharInfo *tmp)
+{
+#define MINMAX(field,ci) \
+ if (minc->field > (ci)->field) \
+ minc->field = (ci)->field; \
+ if (maxc->field < (ci)->field) \
+ maxc->field = (ci)->field;
+
+ MINMAX(ascent, tmp);
+ MINMAX(descent, tmp);
+ MINMAX(leftSideBearing, tmp);
+ MINMAX(rightSideBearing, tmp);
+ MINMAX(characterWidth, tmp);
+
+ if ((INT16)minc->attributes > (INT16)tmp->attributes)
+ minc->attributes = tmp->attributes;
+ if ((INT16)maxc->attributes < (INT16)tmp->attributes)
+ maxc->attributes = tmp->attributes;
+#undef MINMAX
+}
+
+static void
+ft_compute_bounds(FTFontPtr font, FontInfoPtr pinfo, FontScalablePtr vals )
+{
+ FTInstancePtr instance;
+ int row, col;
+ unsigned int c;
+ xCharInfo minchar, maxchar, *tmpchar = NULL;
+ int overlap, maxOverlap;
+ long swidth = 0;
+ long total_width = 0;
+ int num_cols, num_chars = 0;
+ int flags, skip_ok = 0;
+ int force_c_outside ;
+
+ instance = font->instance;
+ force_c_outside = instance->ttcap.flags & TTCAP_FORCE_C_OUTSIDE;
+
+ minchar.ascent = minchar.descent =
+ minchar.leftSideBearing = minchar.rightSideBearing =
+ minchar.characterWidth = minchar.attributes = 32767;
+ maxchar.ascent = maxchar.descent =
+ maxchar.leftSideBearing = maxchar.rightSideBearing =
+ maxchar.characterWidth = maxchar.attributes = -32767;
+ maxOverlap = -32767;
+
+ /* Parse all glyphs */
+ num_cols = 1 + pinfo->lastCol - pinfo->firstCol;
+ for (row = pinfo->firstRow; row <= pinfo->lastRow; row++) {
+ if ( skip_ok && tmpchar ) {
+ if ( !force_c_outside ) {
+ if ( instance->ttcap.forceConstantSpacingBegin < row<<8
+ && row<<8 < (instance->ttcap.forceConstantSpacingEnd & 0x0ff00) ) {
+ if (tmpchar->characterWidth) {
+ num_chars += num_cols;
+ swidth += ABS(tmpchar->characterWidth)*num_cols;
+ total_width += tmpchar->characterWidth*num_cols;
+ continue;
+ }
+ }
+ else skip_ok=0;
+ }
+ else { /* for GB18030 proportional */
+ if ( instance->ttcap.forceConstantSpacingBegin < row<<8
+ || row<<8 < (instance->ttcap.forceConstantSpacingEnd & 0x0ff00) ) {
+ if (tmpchar->characterWidth) {
+ num_chars += num_cols;
+ swidth += ABS(tmpchar->characterWidth)*num_cols;
+ total_width += tmpchar->characterWidth*num_cols;
+ continue;
+ }
+ }
+ else skip_ok=0;
+ }
+ }
+ for (col = pinfo->firstCol; col <= pinfo->lastCol; col++) {
+ c = row<<8|col;
+ flags=0;
+ if ( !force_c_outside ) {
+ if ( c <= instance->ttcap.forceConstantSpacingEnd
+ && instance->ttcap.forceConstantSpacingBegin <= c )
+ flags|=FT_FORCE_CONSTANT_SPACING;
+ }
+ else { /* for GB18030 proportional */
+ if ( c <= instance->ttcap.forceConstantSpacingEnd
+ || instance->ttcap.forceConstantSpacingBegin <= c )
+ flags|=FT_FORCE_CONSTANT_SPACING;
+ }
+#if 0
+ fprintf(stderr, "comp_bounds: %x ->", c);
+#endif
+ if ( skip_ok == 0 || flags == 0 ){
+ tmpchar=NULL;
+#if 0
+ fprintf(stderr, "%x\n", c);
+#endif
+ if( FreeTypeFontGetGlyphMetrics(c, flags, &tmpchar, font) != Successful )
+ continue;
+ }
+ if ( !tmpchar ) continue;
+ adjust_min_max(&minchar, &maxchar, tmpchar);
+ overlap = tmpchar->rightSideBearing - tmpchar->characterWidth;
+ if (maxOverlap < overlap)
+ maxOverlap = overlap;
+
+ if (!tmpchar->characterWidth)
+ continue;
+ num_chars++;
+ swidth += ABS(tmpchar->characterWidth);
+ total_width += tmpchar->characterWidth;
+
+ if ( flags & FT_FORCE_CONSTANT_SPACING ) skip_ok=1;
+ }
+ }
+
+#ifndef X_ACCEPTS_NO_SUCH_CHAR
+ /* Check code 0 */
+ if( FreeTypeInstanceGetGlyphMetrics(font->zero_idx, 0, &tmpchar, font->instance) != Successful || tmpchar == NULL)
+ if( FreeTypeInstanceGetGlyphMetrics(font->zero_idx, FT_GET_DUMMY, &tmpchar, font->instance) != Successful )
+ tmpchar = NULL;
+ if ( tmpchar ) {
+ adjust_min_max(&minchar, &maxchar, tmpchar);
+ overlap = tmpchar->rightSideBearing - tmpchar->characterWidth;
+ if (maxOverlap < overlap)
+ maxOverlap = overlap;
+ }
+#endif
+
+ /* AVERAGE_WIDTH ... 1/10 pixel unit */
+ if (num_chars > 0) {
+ swidth = (swidth * 10.0 + num_chars / 2.0) / num_chars;
+ if (total_width < 0)
+ swidth = -swidth;
+ vals->width = swidth;
+ } else
+ vals->width = 0;
+
+ /*
+ if (char_width.pixel) {
+ maxchar.characterWidth = char_width.pixel;
+ minchar.characterWidth = char_width.pixel;
+ }
+ */
+
+ pinfo->maxbounds = maxchar;
+ pinfo->minbounds = minchar;
+ pinfo->ink_maxbounds = maxchar;
+ pinfo->ink_minbounds = minchar;
+ pinfo->maxOverlap = maxOverlap;
+}
+
+static int
+compute_new_extents( FontScalablePtr vals, double scale, double lsb, double rsb, double desc, double asc,
+ int *lsb_result, int *rsb_result, int *desc_result, int *asc_result )
+{
+#define TRANSFORM_POINT(matrix, x, y, dest) \
+ ((dest)[0] = (matrix)[0] * (x) + (matrix)[2] * (y), \
+ (dest)[1] = (matrix)[1] * (x) + (matrix)[3] * (y))
+
+#define CHECK_EXTENT(lsb, rsb, desc, asc, data) \
+ ((lsb) > (data)[0] ? (lsb) = (data)[0] : 0 , \
+ (rsb) < (data)[0] ? (rsb) = (data)[0] : 0, \
+ (-desc) > (data)[1] ? (desc) = -(data)[1] : 0 , \
+ (asc) < (data)[1] ? (asc) = (data)[1] : 0)
+ double newlsb, newrsb, newdesc, newasc;
+ double point[2];
+
+ /* Compute new extents for this glyph */
+ TRANSFORM_POINT(vals->pixel_matrix, lsb, -desc, point);
+ newlsb = point[0];
+ newrsb = newlsb;
+ newdesc = -point[1];
+ newasc = -newdesc;
+ TRANSFORM_POINT(vals->pixel_matrix, lsb, asc, point);
+ CHECK_EXTENT(newlsb, newrsb, newdesc, newasc, point);
+ TRANSFORM_POINT(vals->pixel_matrix, rsb, -desc, point);
+ CHECK_EXTENT(newlsb, newrsb, newdesc, newasc, point);
+ TRANSFORM_POINT(vals->pixel_matrix, rsb, asc, point);
+ CHECK_EXTENT(newlsb, newrsb, newdesc, newasc, point);
+
+ /* ???: lsb = (int)floor(newlsb * scale); */
+ *lsb_result = (int)floor(newlsb * scale + 0.5);
+ *rsb_result = (int)floor(newrsb * scale + 0.5);
+ *desc_result = (int)ceil(newdesc * scale - 0.5);
+ *asc_result = (int)floor(newasc * scale + 0.5);
+
+ return 0;
+#undef CHECK_EXTENT
+#undef TRANSFORM_POINT
+}
+
+static int
+is_matrix_unit(FontScalablePtr vals)
+{
+ double base_size;
+ FT_Matrix m;
+
+ base_size = hypot(vals->point_matrix[2], vals->point_matrix[3]);
+
+ m.xx = vals->point_matrix[0] / base_size * 65536;
+ m.xy = vals->point_matrix[2] / base_size * 65536;
+ m.yx = vals->point_matrix[1] / base_size * 65536;
+ m.yy = vals->point_matrix[3] / base_size * 65536;
+
+ return (m.xx == 65536) && (m.yx == 0) &&
+ (m.xy == 0) && (m.yy == 65536);
+}
+
+/* Do all the real work for OpenFont or FontInfo */
+/* xf->info is only accessed through info, and xf might be null */
+
+static int
+FreeTypeLoadXFont(char *fileName,
+ FontScalablePtr vals, FontPtr xf, FontInfoPtr info,
+ FontBitmapFormatPtr bmfmt, FontEntryPtr entry)
+{
+ FTFontPtr font = NULL;
+ FTFacePtr face = NULL;
+ FTInstancePtr instance;
+ FT_Size_Metrics *smetrics;
+ int xrc=Successful;
+ int charcell;
+ long rawWidth = 0, rawAverageWidth = 0;
+ int upm, minLsb, maxRsb, ascent, descent, width, averageWidth;
+ double scale, base_width, base_height;
+ Bool orig_is_matrix_unit, font_properties;
+ int face_number, ttcap_spacing;
+ struct TTCapInfo tmp_ttcap;
+ struct TTCapInfo *ins_ttcap;
+ FT_Int32 load_flags = FT_LOAD_DEFAULT; /* orig: FT_LOAD_RENDER | FT_LOAD_MONOCHROME */
+ char *dynStrRealFileName = NULL; /* foo.ttc */
+ char *dynStrFTFileName = NULL; /* :1:foo.ttc */
+ char *dynStrTTCapCodeRange = NULL;
+
+ font = (FTFontPtr)xalloc(sizeof(FTFontRec));
+ if(font == NULL) {
+ xrc = AllocError;
+ goto quit;
+ }
+ memset(font, 0, sizeof(FTFontRec));
+
+ xrc = FreeTypeSetUpTTCap(fileName, vals,
+ &dynStrRealFileName, &dynStrFTFileName,
+ &tmp_ttcap, &face_number,
+ &load_flags, &ttcap_spacing,
+ &font_properties, &dynStrTTCapCodeRange);
+ if ( xrc != Successful ) {
+ goto quit;
+ }
+
+ xrc = FreeTypeOpenFace(&face, dynStrFTFileName, dynStrRealFileName, face_number);
+ if(xrc != Successful) {
+ goto quit;
+ }
+
+ if( is_matrix_unit(vals) )
+ orig_is_matrix_unit = True;
+ else {
+ orig_is_matrix_unit = False;
+ /* Turn off EmbeddedBitmap when original matrix is not diagonal. */
+ load_flags |= FT_LOAD_NO_BITMAP;
+ }
+
+ if( face->bitmap ) load_flags &= ~FT_LOAD_NO_BITMAP;
+
+ /* Slant control by TTCap */
+ if(!face->bitmap) {
+ vals->pixel_matrix[2] +=
+ vals->pixel_matrix[0] * tmp_ttcap.autoItalic;
+ vals->point_matrix[2] +=
+ vals->point_matrix[0] * tmp_ttcap.autoItalic;
+ vals->pixel_matrix[3] +=
+ vals->pixel_matrix[1] * tmp_ttcap.autoItalic;
+ vals->point_matrix[3] +=
+ vals->point_matrix[1] * tmp_ttcap.autoItalic;
+ }
+
+ base_width=hypot(vals->pixel_matrix[0], vals->pixel_matrix[1]);
+ base_height=hypot(vals->pixel_matrix[2], vals->pixel_matrix[3]);
+ if(MAX(base_width, base_height) < 1.0 ) {
+ xrc = BadFontName;
+ goto quit;
+ }
+
+ xrc = FreeTypeLoadFont(font, info, face, dynStrFTFileName, vals, entry, bmfmt,
+ load_flags, &tmp_ttcap, dynStrTTCapCodeRange,
+ ttcap_spacing );
+ if(xrc != Successful) {
+ goto quit;
+ }
+
+ instance = font->instance;
+ smetrics = &instance->size->metrics;
+ ins_ttcap = &instance->ttcap;
+
+ upm = face->face->units_per_EM;
+ if(upm == 0) {
+ /* Work around FreeType bug */
+ upm = WORK_AROUND_UPM;
+ }
+ scale = 1.0 / upm;
+
+ charcell = (instance->spacing == FT_CHARCELL);
+
+ if( instance->charcellMetrics == NULL ) {
+
+ /* New instance */
+
+ long force_c_rawWidth = 0;
+ int force_c_lsb,force_c_rsb,force_c_width;
+ double unit_x=0,unit_y=0,advance;
+ CharInfoPtr tmpglyph;
+
+ /*
+ * CALCULATE HEADER'S METRICS
+ */
+
+ /* for OUTLINE fonts */
+ if(!face->bitmap) {
+ int new_width;
+ double ratio,force_c_ratio;
+ double width_x=0,width_y=0;
+ double force_c_width_x, force_c_rsb_x, force_c_lsb_x;
+ double tmp_rsb,tmp_lsb,tmp_asc,tmp_des;
+ double max_advance_height;
+ tmp_asc = face->face->bbox.yMax;
+ tmp_des = -(face->face->bbox.yMin);
+ if ( tmp_asc < face->face->ascender ) tmp_asc = face->face->ascender;
+ if ( tmp_des < -(face->face->descender) ) tmp_des = -(face->face->descender);
+ tmp_lsb = face->face->bbox.xMin;
+ tmp_rsb = face->face->bbox.xMax;
+ if ( tmp_rsb < face->face->max_advance_width ) tmp_rsb = face->face->max_advance_width;
+ /* apply scaleBBoxWidth */
+ /* we should not ...??? */
+ tmp_lsb *= ins_ttcap->scaleBBoxWidth;
+ tmp_rsb *= ins_ttcap->scaleBBoxWidth;
+ /* transform and rescale */
+ compute_new_extents( vals, scale, tmp_lsb, tmp_rsb, tmp_des, tmp_asc,
+ &minLsb, &maxRsb, &descent, &ascent );
+ /* */
+ /* Consider vertical layouts */
+ if( 0 < face->face->max_advance_height )
+ max_advance_height = face->face->max_advance_height;
+ else
+ max_advance_height = tmp_asc + tmp_des;
+ if( vals->pixel_matrix[1] == 0 ){
+ unit_x = fabs(vals->pixel_matrix[0]);
+ unit_y = 0;
+ width_x = face->face->max_advance_width * ins_ttcap->scaleBBoxWidth * unit_x;
+ }
+ else if( vals->pixel_matrix[3] == 0 ){
+ unit_y = fabs(vals->pixel_matrix[2]);
+ unit_x = 0;
+ width_x = max_advance_height * ins_ttcap->scaleBBoxHeight * unit_y;
+ }
+ else{
+ unit_x = fabs(vals->pixel_matrix[0] -
+ vals->pixel_matrix[1]*vals->pixel_matrix[2]/vals->pixel_matrix[3]);
+ unit_y = fabs(vals->pixel_matrix[2] -
+ vals->pixel_matrix[3]*vals->pixel_matrix[0]/vals->pixel_matrix[1]);
+ width_x = face->face->max_advance_width * ins_ttcap->scaleBBoxWidth * unit_x;
+ width_y = max_advance_height * ins_ttcap->scaleBBoxHeight * unit_y;
+ if( width_y < width_x ){
+ width_x = width_y;
+ unit_x = 0;
+ }
+ else{
+ unit_y = 0;
+ }
+ }
+ /* calculate correction ratio */
+ width = (int)floor( (advance = width_x * scale) + 0.5);
+ new_width = width;
+ if( ins_ttcap->flags & TTCAP_DOUBLE_STRIKE_CORRECT_B_BOX_WIDTH )
+ new_width += ins_ttcap->doubleStrikeShift;
+ new_width += ins_ttcap->adjustBBoxWidthByPixel;
+ ratio = (double)new_width/width;
+ width = new_width;
+ /* force constant */
+ if( unit_x != 0 ) {
+ force_c_width_x = face->face->max_advance_width
+ * ins_ttcap->force_c_scale_b_box_width * unit_x;
+ force_c_lsb_x = face->face->max_advance_width
+ * ins_ttcap->force_c_scale_lsb * unit_x;
+ force_c_rsb_x = face->face->max_advance_width
+ * ins_ttcap->force_c_scale_rsb * unit_x;
+ }
+ else {
+ force_c_width_x = max_advance_height
+ * ins_ttcap->force_c_scale_b_box_height * unit_y;
+ force_c_lsb_x = max_advance_height
+ * ins_ttcap->force_c_scale_lsb * unit_y;
+ force_c_rsb_x = max_advance_height
+ * ins_ttcap->force_c_scale_rsb * unit_y;
+ }
+ /* calculate correction ratio */
+ force_c_width = (int)floor(force_c_width_x * scale + 0.5);
+ new_width = force_c_width;
+ if( ins_ttcap->flags & TTCAP_DOUBLE_STRIKE_CORRECT_B_BOX_WIDTH )
+ force_c_width += ins_ttcap->doubleStrikeShift;
+ new_width += ins_ttcap->force_c_adjust_width_by_pixel;
+ force_c_ratio = (double)new_width/force_c_width;
+ force_c_width = new_width;
+ /* force_c_lsb, force_c_rsb */
+ if( ins_ttcap->flags & TTCAP_FORCE_C_LSB_FLAG )
+ force_c_lsb = (int)floor( force_c_lsb_x * scale + 0.5 );
+ else
+ force_c_lsb = minLsb;
+ if( ins_ttcap->flags & TTCAP_FORCE_C_RSB_FLAG )
+ force_c_rsb = (int)floor( force_c_rsb_x * scale + 0.5 );
+ else
+ force_c_rsb = maxRsb;
+ /* calculate shift of BitmapAutoItalic
+ (when diagonal matrix only) */
+ if( orig_is_matrix_unit == True ) {
+ if( ins_ttcap->autoItalic != 0 ) {
+ double ai;
+ int ai_lsb,ai_rsb,ai_total;
+ if( 0 < ins_ttcap->autoItalic ) ai=ins_ttcap->autoItalic;
+ else ai = -ins_ttcap->autoItalic;
+ ai_total = (int)( (ascent+descent) * ai + 0.5);
+ ai_rsb = (int)((double)ai_total * ascent / ( ascent + descent ) + 0.5 );
+ ai_lsb = -(ai_total - ai_rsb);
+ if( 0 < ins_ttcap->autoItalic ) {
+ ins_ttcap->lsbShiftOfBitmapAutoItalic = ai_lsb;
+ ins_ttcap->rsbShiftOfBitmapAutoItalic = ai_rsb;
+ }
+ else {
+ ins_ttcap->lsbShiftOfBitmapAutoItalic = -ai_rsb;
+ ins_ttcap->rsbShiftOfBitmapAutoItalic = -ai_lsb;
+ }
+ }
+ }
+ /* integer adjustment by TTCap */
+ if( ins_ttcap->flags & TTCAP_DOUBLE_STRIKE )
+ maxRsb += ins_ttcap->doubleStrikeShift;
+ maxRsb += ins_ttcap->adjustRightSideBearingByPixel;
+ minLsb += ins_ttcap->adjustLeftSideBearingByPixel;
+ /* */
+ if( ins_ttcap->flags & TTCAP_DOUBLE_STRIKE )
+ force_c_rsb += ins_ttcap->doubleStrikeShift;
+ force_c_rsb += ins_ttcap->force_c_adjust_rsb_by_pixel;
+ force_c_lsb += ins_ttcap->force_c_adjust_lsb_by_pixel;
+ /* apply to rawWidth */
+ averageWidth = (int)floor(10 * width_x * scale
+ * ratio + 0.5);
+ rawWidth = floor(width_x * scale
+ * ratio * 1000. / base_height + 0.5);
+ rawAverageWidth = floor(width_x * scale * ratio * 10.
+ * 1000. / base_height + 0.5);
+ force_c_rawWidth = floor(force_c_width_x * scale
+ * force_c_ratio * 1000. / base_height + 0.5);
+ /* */
+ }
+ /* for BITMAP fonts [if(face->bitmap)] */
+ else {
+ /* These values differ from actual when outline,
+ so we must use them ONLY FOR BITMAP. */
+ width = (int)floor(smetrics->max_advance * ins_ttcap->scaleBBoxWidth / 64.0 + .5);
+ descent = -smetrics->descender / 64;
+ ascent = smetrics->ascender / 64;
+ /* force constant */
+ force_c_width = (int)floor(smetrics->max_advance
+ * ins_ttcap->force_c_scale_b_box_width / 64.0 + .5);
+ /* Preserve average width for bitmap fonts */
+ if(vals->width != 0)
+ averageWidth = (int)floor(vals->width * ins_ttcap->scaleBBoxWidth +.5);
+ else
+ averageWidth = (int)floor(10.0 * smetrics->max_advance
+ * ins_ttcap->scaleBBoxWidth / 64.0 + .5);
+ rawWidth = 0;
+ rawAverageWidth = 0;
+ force_c_rawWidth = 0;
+ /* We don't consider vertical layouts */
+ advance = (int)floor(smetrics->max_advance / 64.0 +.5);
+ unit_x = vals->pixel_matrix[0];
+ unit_y = 0;
+ /* We can use 'width' only when bitmap.
+ This should not be set when outline. */
+ minLsb = 0;
+ maxRsb = width;
+ /* force constant */
+ if( ins_ttcap->flags & TTCAP_FORCE_C_LSB_FLAG )
+ force_c_lsb = (int)floor(smetrics->max_advance
+ * ins_ttcap->force_c_scale_lsb / 64.0 + .5);
+ else
+ force_c_lsb = minLsb;
+ if( ins_ttcap->flags & TTCAP_FORCE_C_RSB_FLAG )
+ force_c_rsb = (int)floor(smetrics->max_advance
+ * ins_ttcap->force_c_scale_rsb / 64.0 + .5);
+ else
+ force_c_rsb = maxRsb;
+ /* calculate shift of BitmapAutoItalic */
+ if( ins_ttcap->autoItalic != 0 ) {
+ double ai;
+ int ai_lsb,ai_rsb,ai_total;
+ if( 0 < ins_ttcap->autoItalic ) ai=ins_ttcap->autoItalic;
+ else ai = -ins_ttcap->autoItalic;
+ ai_total = (int)( (ascent+descent) * ai + 0.5);
+ ai_rsb = (int)((double)ai_total * ascent / ( ascent + descent ) + 0.5 );
+ ai_lsb = -(ai_total - ai_rsb);
+ if( 0 < ins_ttcap->autoItalic ) {
+ ins_ttcap->lsbShiftOfBitmapAutoItalic = ai_lsb;
+ ins_ttcap->rsbShiftOfBitmapAutoItalic = ai_rsb;
+ }
+ else {
+ ins_ttcap->lsbShiftOfBitmapAutoItalic = -ai_rsb;
+ ins_ttcap->rsbShiftOfBitmapAutoItalic = -ai_lsb;
+ }
+ }
+ /* integer adjustment by TTCap */
+ if( ins_ttcap->flags & TTCAP_DOUBLE_STRIKE_CORRECT_B_BOX_WIDTH )
+ width += ins_ttcap->doubleStrikeShift;
+ if( ins_ttcap->flags & TTCAP_DOUBLE_STRIKE )
+ maxRsb += ins_ttcap->doubleStrikeShift;
+ maxRsb += ins_ttcap->adjustRightSideBearingByPixel;
+ minLsb += ins_ttcap->adjustLeftSideBearingByPixel;
+ /* We have not carried out matrix calculation, so this is done. */
+ maxRsb += ins_ttcap->rsbShiftOfBitmapAutoItalic;
+ minLsb += ins_ttcap->lsbShiftOfBitmapAutoItalic;
+ /* force constant */
+ if( ins_ttcap->flags & TTCAP_DOUBLE_STRIKE )
+ force_c_rsb += ins_ttcap->doubleStrikeShift;
+ force_c_rsb += ins_ttcap->force_c_adjust_rsb_by_pixel;
+ force_c_lsb += ins_ttcap->force_c_adjust_lsb_by_pixel;
+ force_c_rsb += ins_ttcap->rsbShiftOfBitmapAutoItalic;
+ force_c_lsb += ins_ttcap->lsbShiftOfBitmapAutoItalic;
+ }
+
+ /* SET CALCULATED VALUES TO INSTANCE */
+
+ /* Set actual height and cosine */
+ instance->pixel_size = base_height;
+ instance->advance = advance;
+ if ( unit_x != 0 ){
+ instance->pixel_width_unit_x = unit_x/base_height;
+ instance->pixel_width_unit_y = 0;
+ }
+ else{
+ instance->pixel_width_unit_x = 0;
+ instance->pixel_width_unit_y = unit_y/base_height;
+ }
+
+ /* header's metrics */
+ instance->charcellMetrics = (xCharInfo*)xalloc(sizeof(xCharInfo));
+ if(instance->charcellMetrics == NULL) {
+ xrc = AllocError;
+ goto quit;
+ }
+ instance->charcellMetrics->ascent = ascent;
+ instance->charcellMetrics->descent = descent;
+ instance->charcellMetrics->attributes = rawWidth;
+ instance->charcellMetrics->rightSideBearing = maxRsb;
+ instance->charcellMetrics->leftSideBearing = minLsb;
+ instance->charcellMetrics->characterWidth = width;
+ instance->averageWidth = averageWidth;
+ instance->rawAverageWidth = rawAverageWidth;
+
+ /* Check code 0 */
+ if( FreeTypeInstanceGetGlyph(font->zero_idx, 0, &tmpglyph, font->instance) != Successful
+ || tmpglyph == NULL)
+ if( FreeTypeInstanceGetGlyph(font->zero_idx, FT_GET_DUMMY, &tmpglyph, font->instance)
+ != Successful )
+ tmpglyph = NULL;
+ if ( !tmpglyph ) {
+ xrc = AllocError;
+ goto quit;
+ }
+
+ /* FORCE CONSTANT METRICS */
+ if( 0 <= ins_ttcap->forceConstantSpacingEnd ) {
+ xCharInfo *tmpchar = NULL;
+ int c = ins_ttcap->force_c_representative_metrics_char_code;
+ /* header's metrics */
+ if( instance->forceConstantMetrics == NULL ){
+ instance->forceConstantMetrics = (xCharInfo*)xalloc(sizeof(xCharInfo));
+ if(instance->forceConstantMetrics == NULL) {
+ xrc = AllocError;
+ goto quit;
+ }
+ }
+ /* Get Representative Metrics */
+ if ( 0 <= c ) {
+ if( FreeTypeFontGetGlyphMetrics(c, 0, &tmpchar, font) != Successful )
+ tmpchar = NULL;
+ }
+ if ( tmpchar && 0 < tmpchar->characterWidth ) {
+ instance->forceConstantMetrics->leftSideBearing = tmpchar->leftSideBearing;
+ instance->forceConstantMetrics->rightSideBearing = tmpchar->rightSideBearing;
+ instance->forceConstantMetrics->characterWidth = tmpchar->characterWidth;
+ instance->forceConstantMetrics->ascent = tmpchar->ascent;
+ instance->forceConstantMetrics->descent = tmpchar->descent;
+ instance->forceConstantMetrics->attributes = tmpchar->attributes;
+ }
+ else {
+ instance->forceConstantMetrics->leftSideBearing = force_c_lsb;
+ instance->forceConstantMetrics->rightSideBearing = force_c_rsb;
+ instance->forceConstantMetrics->characterWidth = force_c_width;
+ instance->forceConstantMetrics->ascent = ascent;
+ instance->forceConstantMetrics->descent = descent;
+ instance->forceConstantMetrics->attributes = force_c_rawWidth;
+ }
+ /* Check code 0 */
+ if( FreeTypeInstanceGetGlyph(font->zero_idx, FT_FORCE_CONSTANT_SPACING,
+ &tmpglyph, font->instance) != Successful
+ || tmpglyph == NULL)
+ if( FreeTypeInstanceGetGlyph(font->zero_idx, FT_FORCE_CONSTANT_SPACING | FT_GET_DUMMY,
+ &tmpglyph, font->instance)
+ != Successful )
+ tmpglyph = NULL;
+ if ( !tmpglyph ) {
+ xrc = AllocError;
+ goto quit;
+ }
+ }
+ }
+ else{
+
+ /*
+ * CACHED VALUES
+ */
+
+ width = instance->charcellMetrics->characterWidth;
+ ascent = instance->charcellMetrics->ascent;
+ descent = instance->charcellMetrics->descent;
+ rawWidth = instance->charcellMetrics->attributes;
+ maxRsb = instance->charcellMetrics->rightSideBearing;
+ minLsb = instance->charcellMetrics->leftSideBearing;
+ averageWidth = instance->averageWidth;
+ rawAverageWidth = instance->rawAverageWidth;
+
+ }
+
+ /*
+ * SET maxbounds, minbounds ...
+ */
+
+ if( !charcell ) { /* NOT CHARCELL */
+ if( info ){
+ /*
+ Calculate all glyphs' metrics.
+ maxbounds.ascent and maxbounds.descent are quite important values
+ for XAA. If ascent/descent of each glyph exceeds
+ maxbounds.ascent/maxbounds.descent, XAA causes SERVER CRASH.
+ Therefore, THIS MUST BE DONE.
+ */
+ ft_compute_bounds(font,info,vals);
+ }
+ }
+ else{ /* CHARCELL */
+
+ /*
+ * SET CALCULATED OR CACHED VARIABLES
+ */
+
+ vals->width = averageWidth;
+
+ if( info ){
+
+ info->maxbounds.leftSideBearing = minLsb;
+ info->maxbounds.rightSideBearing = maxRsb;
+ info->maxbounds.characterWidth = width;
+ info->maxbounds.ascent = ascent;
+ info->maxbounds.descent = descent;
+ info->maxbounds.attributes =
+ (unsigned short)(short)rawWidth;
+
+ info->minbounds = info->maxbounds;
+ }
+ }
+
+ /* set info */
+
+ if( info ){
+ /*
+ info->fontAscent = ascent;
+ info->fontDescent = descent;
+ */
+ info->fontAscent = info->maxbounds.ascent;
+ info->fontDescent = info->maxbounds.descent;
+ /* Glyph metrics are accurate */
+ info->inkMetrics=1;
+
+ memcpy((char *)&info->ink_maxbounds,
+ (char *)&info->maxbounds, sizeof(xCharInfo));
+ memcpy((char *)&info->ink_minbounds,
+ (char *)&info->minbounds, sizeof(xCharInfo));
+
+ /* XXX - hack */
+ info->defaultCh=0;
+
+ /* Set the pInfo flags */
+ /* Properties set by FontComputeInfoAccelerators:
+ pInfo->noOverlap;
+ pInfo->terminalFont;
+ pInfo->constantMetrics;
+ pInfo->constantWidth;
+ pInfo->inkInside;
+ */
+ /* from lib/font/util/fontaccel.c */
+ FontComputeInfoAccelerators(info);
+ }
+
+ if(xf)
+ xf->fontPrivate = (void*)font;
+
+ if(info) {
+ xrc = FreeTypeAddProperties(font, vals, info, entry->name.name,
+ rawAverageWidth, font_properties);
+ if (xrc != Successful) {
+ goto quit;
+ }
+ }
+
+ quit:
+ if ( dynStrTTCapCodeRange ) xfree(dynStrTTCapCodeRange);
+ if ( dynStrFTFileName ) xfree(dynStrFTFileName);
+ if ( dynStrRealFileName ) xfree(dynStrRealFileName);
+ if ( xrc != Successful ) {
+ if( font ){
+ if( face && font->instance == NULL ) FreeTypeFreeFace(face);
+ FreeTypeFreeFont(font);
+ }
+ }
+ return xrc;
+}
+
+/* Routines used by X11 to get info and glyphs from the font. */
+
+static int
+FreeTypeGetMetrics(FontPtr pFont, unsigned long count, unsigned char *chars,
+ FontEncoding charEncoding, unsigned long *metricCount,
+ xCharInfo **metrics)
+{
+ unsigned int code = 0;
+ int flags = 0;
+ FTFontPtr tf;
+ struct TTCapInfo *ttcap;
+ xCharInfo **mp, *m;
+
+ /* MUMBLE1("Get metrics for %ld characters\n", count);*/
+
+ tf = (FTFontPtr)pFont->fontPrivate;
+ ttcap = &tf->instance->ttcap;
+ mp = metrics;
+
+ while (count-- > 0) {
+ switch (charEncoding) {
+ case Linear8Bit:
+ case TwoD8Bit:
+ code = *chars++;
+ break;
+ case Linear16Bit:
+ case TwoD16Bit:
+ code = (*chars++ << 8);
+ code |= *chars++;
+ /* */
+ if ( !(ttcap->flags & TTCAP_FORCE_C_OUTSIDE) ) {
+ if ( (int)code <= ttcap->forceConstantSpacingEnd
+ && ttcap->forceConstantSpacingBegin <= (int)code )
+ flags|=FT_FORCE_CONSTANT_SPACING;
+ else flags=0;
+ }
+ else { /* for GB18030 proportional */
+ if ( (int)code <= ttcap->forceConstantSpacingEnd
+ || ttcap->forceConstantSpacingBegin <= (int)code )
+ flags|=FT_FORCE_CONSTANT_SPACING;
+ else flags=0;
+ }
+ break;
+ }
+
+ if(FreeTypeFontGetGlyphMetrics(code, flags, &m, tf) == Successful && m!=NULL) {
+ *mp++ = m;
+ }
+#ifdef X_ACCEPTS_NO_SUCH_CHAR
+ else *mp++ = &noSuchChar.metrics;
+#endif
+ }
+
+ *metricCount = mp - metrics;
+ return Successful;
+}
+
+static int
+FreeTypeGetGlyphs(FontPtr pFont, unsigned long count, unsigned char *chars,
+ FontEncoding charEncoding, unsigned long *glyphCount,
+ CharInfoPtr *glyphs)
+{
+ unsigned int code = 0;
+ int flags = 0;
+ FTFontPtr tf;
+ CharInfoPtr *gp;
+ CharInfoPtr g;
+ struct TTCapInfo *ttcap;
+
+ tf = (FTFontPtr)pFont->fontPrivate;
+ ttcap = &tf->instance->ttcap;
+ gp = glyphs;
+
+ while (count-- > 0) {
+ switch (charEncoding) {
+ case Linear8Bit: case TwoD8Bit:
+ code = *chars++;
+ break;
+ case Linear16Bit: case TwoD16Bit:
+ code = *chars++ << 8;
+ code |= *chars++;
+ /* */
+ if ( !(ttcap->flags & TTCAP_FORCE_C_OUTSIDE) ) {
+ if ( (int)code <= ttcap->forceConstantSpacingEnd
+ && ttcap->forceConstantSpacingBegin <= (int)code )
+ flags|=FT_FORCE_CONSTANT_SPACING;
+ else flags=0;
+ }
+ else { /* for GB18030 proportional */
+ if ( (int)code <= ttcap->forceConstantSpacingEnd
+ || ttcap->forceConstantSpacingBegin <= (int)code )
+ flags|=FT_FORCE_CONSTANT_SPACING;
+ else flags=0;
+ }
+ break;
+ }
+
+ if(FreeTypeFontGetGlyph(code, flags, &g, tf) == Successful && g!=NULL) {
+ *gp++ = g;
+ }
+#ifdef X_ACCEPTS_NO_SUCH_CHAR
+ else {
+#ifdef XAA_ACCEPTS_NULL_BITS
+ *gp++ = &noSuchChar;
+#else
+ if ( tf->dummy_char.bits ) {
+ *gp++ = &tf->dummy_char;
+ }
+ else {
+ char *raster = NULL;
+ int wd_actual, ht_actual, wd, ht, bpr;
+ wd_actual = tf->info->maxbounds.rightSideBearing - tf->info->maxbounds.leftSideBearing;
+ ht_actual = tf->info->maxbounds.ascent + tf->info->maxbounds.descent;
+ if(wd_actual <= 0) wd = 1;
+ else wd=wd_actual;
+ if(ht_actual <= 0) ht = 1;
+ else ht=ht_actual;
+ bpr = (((wd + (tf->instance->bmfmt.glyph<<3) - 1) >> 3) &
+ -tf->instance->bmfmt.glyph);
+ raster = (char*)xalloc(ht * bpr);
+ if(raster) {
+ memset(raster, 0, ht * bpr);
+ tf->dummy_char.bits = raster;
+ *gp++ = &tf->dummy_char;
+ }
+ }
+#endif
+ }
+#endif
+ }
+
+ *glyphCount = gp - glyphs;
+ return Successful;
+}
+
+static int
+FreeTypeSetUpFont(FontPathElementPtr fpe, FontPtr xf, FontInfoPtr info,
+ fsBitmapFormat format, fsBitmapFormatMask fmask,
+ FontBitmapFormatPtr bmfmt)
+{
+ int xrc;
+ int image;
+
+ /* Get the default bitmap format information for this X installation.
+ Also update it for the client if running in the font server. */
+ FontDefaultFormat(&bmfmt->bit, &bmfmt->byte, &bmfmt->glyph, &bmfmt->scan);
+ if ((xrc = CheckFSFormat(format, fmask, &bmfmt->bit, &bmfmt->byte,
+ &bmfmt->scan, &bmfmt->glyph,
+ &image)) != Successful) {
+ MUMBLE1("Aborting after checking FS format: %d\n", xrc);
+ return xrc;
+ }
+
+ if(xf) {
+ xf->refcnt = 0;
+ xf->bit = bmfmt->bit;
+ xf->byte = bmfmt->byte;
+ xf->glyph = bmfmt->glyph;
+ xf->scan = bmfmt->scan;
+ xf->format = format;
+ xf->get_glyphs = FreeTypeGetGlyphs;
+ xf->get_metrics = FreeTypeGetMetrics;
+ xf->unload_font = FreeTypeUnloadXFont;
+ xf->unload_glyphs = 0;
+ xf->fpe = fpe;
+ xf->svrPrivate = 0;
+ xf->fontPrivate = 0; /* we'll set it later */
+ xf->fpePrivate = 0;
+ }
+
+ info->defaultCh = 0;
+ info->noOverlap = 0; /* not updated */
+ info->terminalFont = 0; /* not updated */
+ info->constantMetrics = 0; /* we'll set it later */
+ info->constantWidth = 0; /* we'll set it later */
+ info->inkInside = 1;
+ info->inkMetrics = 1;
+ info->allExist=0; /* not updated */
+ info->drawDirection = LeftToRight; /* we'll set it later */
+ info->cachable = 1; /* we don't do licensing */
+ info->anamorphic = 0; /* can hinting lead to anamorphic scaling? */
+ info->maxOverlap = 0; /* we'll set it later. */
+ info->pad = 0; /* ??? */
+ return Successful;
+}
+
+/* Functions exported by the backend */
+
+static int
+FreeTypeOpenScalable(FontPathElementPtr fpe, FontPtr *ppFont, int flags,
+ FontEntryPtr entry, char *fileName, FontScalablePtr vals,
+ fsBitmapFormat format, fsBitmapFormatMask fmask,
+ FontPtr non_cachable_font)
+{
+ int xrc;
+ FontPtr xf;
+ FontBitmapFormatRec bmfmt;
+
+ MUMBLE1("Open Scalable %s, XLFD=",fileName);
+#ifdef DEBUG_TRUETYPE
+ fwrite(entry->name.name, entry->name.length, 1, stdout);
+#endif
+ MUMBLE("\n");
+
+ xf = CreateFontRec();
+ if (xf == NULL)
+ return AllocError;
+
+ xrc = FreeTypeSetUpFont(fpe, xf, &xf->info, format, fmask, &bmfmt);
+ if(xrc != Successful) {
+ DestroyFontRec(xf);
+ return xrc;
+ }
+ xrc = FreeTypeLoadXFont(fileName, vals, xf, &xf->info, &bmfmt, entry);
+ if(xrc != Successful) {
+ MUMBLE1("Error during load: %d\n",xrc);
+ DestroyFontRec(xf);
+ return xrc;
+ }
+
+ *ppFont = xf;
+
+ return xrc;
+}
+
+/* Routine to get requested font info. */
+
+static int
+FreeTypeGetInfoScalable(FontPathElementPtr fpe, FontInfoPtr info,
+ FontEntryPtr entry, FontNamePtr fontName,
+ char *fileName, FontScalablePtr vals)
+{
+ int xrc;
+ FontBitmapFormatRec bmfmt;
+
+ MUMBLE("Get info, XLFD= ");
+#ifdef DEBUG_TRUETYPE
+ fwrite(entry->name.name, entry->name.length, 1, stdout);
+#endif
+ MUMBLE("\n");
+
+ xrc = FreeTypeSetUpFont(fpe, 0, info, 0, 0, &bmfmt);
+ if(xrc != Successful) {
+ return xrc;
+ }
+
+ bmfmt.glyph <<= 3;
+
+ xrc = FreeTypeLoadXFont(fileName, vals, 0, info, &bmfmt, entry);
+ if(xrc != Successful) {
+ MUMBLE1("Error during load: %d\n", xrc);
+ return xrc;
+ }
+
+ return Successful;
+}
+
+/* Renderer registration. */
+
+/* Set the capabilities of this renderer. */
+#define CAPABILITIES (CAP_CHARSUBSETTING | CAP_MATRIX)
+
+/* Set it up so file names with either upper or lower case can be
+ loaded. We don't support compressed fonts. */
+static FontRendererRec renderers[] = {
+ {".ttf", 4, 0, FreeTypeOpenScalable, 0,
+ FreeTypeGetInfoScalable, 0, CAPABILITIES},
+ {".TTF", 4, 0, FreeTypeOpenScalable, 0,
+ FreeTypeGetInfoScalable, 0, CAPABILITIES},
+ {".ttc", 4, 0, FreeTypeOpenScalable, 0,
+ FreeTypeGetInfoScalable, 0, CAPABILITIES},
+ {".TTC", 4, 0, FreeTypeOpenScalable, 0,
+ FreeTypeGetInfoScalable, 0, CAPABILITIES},
+ {".otf", 4, 0, FreeTypeOpenScalable, 0,
+ FreeTypeGetInfoScalable, 0, CAPABILITIES},
+ {".OTF", 4, 0, FreeTypeOpenScalable, 0,
+ FreeTypeGetInfoScalable, 0, CAPABILITIES},
+ {".otc", 4, 0, FreeTypeOpenScalable, 0,
+ FreeTypeGetInfoScalable, 0, CAPABILITIES},
+ {".OTC", 4, 0, FreeTypeOpenScalable, 0,
+ FreeTypeGetInfoScalable, 0, CAPABILITIES},
+ {".pfa", 4, 0, FreeTypeOpenScalable, 0,
+ FreeTypeGetInfoScalable, 0, CAPABILITIES},
+ {".PFA", 4, 0, FreeTypeOpenScalable, 0,
+ FreeTypeGetInfoScalable, 0, CAPABILITIES},
+ {".pfb", 4, 0, FreeTypeOpenScalable, 0,
+ FreeTypeGetInfoScalable, 0, CAPABILITIES},
+ {".PFB", 4, 0, FreeTypeOpenScalable, 0,
+ FreeTypeGetInfoScalable, 0, CAPABILITIES},
+};
+static int num_renderers = sizeof(renderers) / sizeof(renderers[0]);
+
+static FontRendererRec alt_renderers[] = {
+ {".bdf", 4, 0, FreeTypeOpenScalable, 0,
+ FreeTypeGetInfoScalable, 0, CAPABILITIES},
+ {".BDF", 4, 0, FreeTypeOpenScalable, 0,
+ FreeTypeGetInfoScalable, 0, CAPABILITIES},
+ {".pcf", 4, 0, FreeTypeOpenScalable, 0,
+ FreeTypeGetInfoScalable, 0, CAPABILITIES},
+ {".PCF", 4, 0, FreeTypeOpenScalable, 0,
+ FreeTypeGetInfoScalable, 0, CAPABILITIES},
+};
+
+static int num_alt_renderers =
+sizeof(alt_renderers) / sizeof(alt_renderers[0]);
+
+
+void
+FreeTypeRegisterFontFileFunctions(void)
+{
+ int i;
+
+ for (i = 0; i < num_renderers; i++)
+ FontFileRegisterRenderer(&renderers[i]);
+
+ for (i = 0; i < num_alt_renderers; i++)
+ FontFilePriorityRegisterRenderer(&alt_renderers[i], -10);
+}
diff --git a/libXfont/src/FreeType/ftfuncs.h b/libXfont/src/FreeType/ftfuncs.h
new file mode 100644
index 000000000..e522dded8
--- /dev/null
+++ b/libXfont/src/FreeType/ftfuncs.h
@@ -0,0 +1,190 @@
+/*
+Copyright (c) 1998-2002 by Juliusz Chroboczek
+Copyright (c) 2003 After X-TT Project, All rights reserved.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
+*/
+/* $XFree86: xc/lib/font/FreeType/ftfuncs.h,v 1.17 2003/12/21 04:02:07 dawes Exp $ */
+
+/* Number of buckets in the hashtable holding faces */
+#define NUMFACEBUCKETS 32
+
+/* Glyphs are held in segments of this size */
+#define FONTSEGMENTSIZE 16
+
+/* A structure that holds bitmap order and padding info. */
+
+typedef struct {
+ int bit; /* bit order */
+ int byte; /* byte order */
+ int glyph; /* glyph pad size */
+ int scan; /* machine word size */
+} FontBitmapFormatRec, *FontBitmapFormatPtr;
+
+struct FTSize_s;
+
+/* At the lowest level, there is face; FTFaces are in one-to-one
+ correspondence with TrueType faces. Multiple instance may share
+ the same face. */
+
+typedef struct _FTFace {
+ char *filename;
+ FT_Face face;
+ int bitmap;
+ FT_UInt num_hmetrics;
+ struct _FTInstance *instances;
+ struct _FTInstance *active_instance;
+ struct _FTFace *next; /* link to next face in bucket */
+} FTFaceRec, *FTFacePtr;
+
+/* A transformation matrix with resolution information */
+typedef struct _FTNormalisedTransformation {
+ double scale;
+ int nonIdentity; /* if 0, matrix is the identity */
+ FT_Matrix matrix;
+ int xres, yres;
+} FTNormalisedTransformationRec, *FTNormalisedTransformationPtr;
+
+#define FT_PROPORTIONAL 0
+#define FT_MONOSPACED 1
+#define FT_CHARCELL 2
+
+#define FT_AVAILABLE_UNKNOWN 0
+#define FT_AVAILABLE_NO 1
+#define FT_AVAILABLE_METRICS 2
+#define FT_AVAILABLE_RASTERISED 3
+
+#define FT_GET_GLYPH_BOTH 0x01
+#define FT_GET_GLYPH_METRICS_ONLY 0x02
+#define FT_GET_DUMMY 0x04
+#define FT_FORCE_CONSTANT_SPACING 0x08
+
+#define TTCAP_DOUBLE_STRIKE 0x0001
+#define TTCAP_DOUBLE_STRIKE_MKBOLD_EDGE_LEFT 0x0002
+#define TTCAP_DOUBLE_STRIKE_CORRECT_B_BOX_WIDTH 0x0008
+#define TTCAP_IS_VERY_LAZY 0x0010
+#define TTCAP_DISABLE_DEFAULT_VERY_LAZY 0x0020
+#define TTCAP_FORCE_C_LSB_FLAG 0x0100
+#define TTCAP_FORCE_C_RSB_FLAG 0x0200
+#define TTCAP_FORCE_C_OUTSIDE 0x0400
+#define TTCAP_MONO_CENTER 0x0800
+
+/* TTCap */
+struct TTCapInfo {
+ long flags;
+ double autoItalic;
+ double scaleWidth;
+ double scaleBBoxWidth;
+ double scaleBBoxHeight;
+ int doubleStrikeShift;
+ int adjustBBoxWidthByPixel;
+ int adjustLeftSideBearingByPixel;
+ int adjustRightSideBearingByPixel;
+ double scaleBitmap;
+ int forceConstantSpacingBegin;
+ int forceConstantSpacingEnd;
+ /* We don't compare */
+ int force_c_adjust_width_by_pixel;
+ int force_c_adjust_lsb_by_pixel;
+ int force_c_adjust_rsb_by_pixel;
+ int force_c_representative_metrics_char_code;
+ double force_c_scale_b_box_width;
+ double force_c_scale_b_box_height;
+ double force_c_scale_lsb;
+ double force_c_scale_rsb;
+ double vl_slant;
+ int lsbShiftOfBitmapAutoItalic;
+ int rsbShiftOfBitmapAutoItalic;
+};
+
+/* An instance builds on a face by specifying the transformation
+ matrix. Multiple fonts may share the same instance. */
+
+/* This structure caches bitmap data */
+typedef struct _FTInstance {
+ FTFacePtr face; /* the associated face */
+ FT_Size size;
+ FTNormalisedTransformationRec transformation;
+ FT_Int32 load_flags;
+ FT_ULong strike_index;
+ int spacing; /* actual spacing */
+ double pixel_size; /* to calc attributes (actual height) */
+ double pixel_width_unit_x; /* to calc horiz. width (cosine) */
+ double pixel_width_unit_y; /* to calc vert. width (cosine) */
+ xCharInfo *charcellMetrics; /* the header's metrics */
+ int averageWidth; /* the header's metrics */
+ long rawAverageWidth; /* the header's metrics */
+ double advance; /* the header's metrics */
+ xCharInfo *forceConstantMetrics;
+ FontBitmapFormatRec bmfmt;
+ unsigned nglyphs;
+ CharInfoPtr *glyphs; /* glyphs and available are used in parallel */
+ int **available;
+ struct TTCapInfo ttcap;
+ int refcount;
+ struct _FTInstance *next; /* link to next instance */
+} FTInstanceRec, *FTInstancePtr;
+
+/* A font is an instance with coding information; fonts are in
+ one-to-one correspondence with X fonts */
+typedef struct _FTFont{
+ FTInstancePtr instance;
+ FTMappingRec mapping;
+ unsigned zero_idx;
+ FontInfoPtr info;
+ int nranges;
+ CharInfoRec dummy_char;
+ fsRange *ranges;
+} FTFontRec, *FTFontPtr;
+
+#ifndef NOT_IN_FTFUNCS
+
+/* Prototypes for some local functions */
+
+static int FreeTypeOpenFace(FTFacePtr *facep, char *FTFileName, char *realFileName, int faceNumber);
+static void FreeTypeFreeFace(FTFacePtr face);
+static int
+FreeTypeOpenInstance(FTInstancePtr *instancep, FTFacePtr face,
+ char *FTFileName, FTNormalisedTransformationPtr trans,
+ int spacing, FontBitmapFormatPtr bmfmt,
+ struct TTCapInfo *tmp_ttcap, FT_Int32 load_flags);
+static void FreeTypeFreeInstance(FTInstancePtr instance);
+static int
+FreeTypeInstanceGetGlyph(unsigned idx, int flags, CharInfoPtr *g, FTInstancePtr instance);
+static int
+FreeTypeInstanceGetGlyphMetrics(unsigned idx, int flags,
+ xCharInfo **metrics, FTInstancePtr instance );
+static int
+FreeTypeRasteriseGlyph(unsigned idx, int flags, CharInfoPtr tgp,
+ FTInstancePtr instance, int hasMetrics );
+static void FreeTypeFreeFont(FTFontPtr font);
+static void FreeTypeFreeXFont(FontPtr pFont, int freeProps);
+static void FreeTypeUnloadXFont(FontPtr pFont);
+static int
+FreeTypeAddProperties(FTFontPtr font, FontScalablePtr vals, FontInfoPtr info,
+ char *fontname, int rawAverageWidth, Bool font_properties);
+static int FreeTypeFontGetGlyph(unsigned code, int flags, CharInfoPtr *g, FTFontPtr font);
+static int
+FreeTypeLoadFont(FTFontPtr font, FontInfoPtr info, FTFacePtr face,
+ char *FTFileName, FontScalablePtr vals, FontEntryPtr entry,
+ FontBitmapFormatPtr bmfmt, FT_Int32 load_flags,
+ struct TTCapInfo *tmp_ttcap, char *dynStrTTCapCodeRange,
+ int ttcap_spacing );
+
+#endif /* NOT_IN_FTFUNCS */
diff --git a/libXfont/src/FreeType/fttools.c b/libXfont/src/FreeType/fttools.c
new file mode 100644
index 000000000..10604b1f6
--- /dev/null
+++ b/libXfont/src/FreeType/fttools.c
@@ -0,0 +1,148 @@
+/*
+ Copyright (c) 1997 by Mark Leisher
+ Copyright (c) 1998-2002 by Juliusz Chroboczek
+
+ Permission is hereby granted, free of charge, to any person obtaining a copy
+ of this software and associated documentation files (the "Software"), to deal
+ in the Software without restriction, including without limitation the rights
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ copies of the Software, and to permit persons to whom the Software is
+ furnished to do so, subject to the following conditions:
+
+ The above copyright notice and this permission notice shall be included in
+ all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ THE SOFTWARE.
+*/
+
+/* $XFree86: xc/lib/font/FreeType/fttools.c,v 1.6 2003/06/08 15:41:13 herrb Exp $ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include <X11/fonts/fontmisc.h>
+#ifndef FONTMODULE
+#include <ctype.h>
+#include <string.h>
+#else
+#include "Xmd.h"
+#include "Xdefs.h"
+#include "xf86_ansic.h"
+#endif
+
+#include <X11/fonts/font.h>
+#include <ft2build.h>
+#include FT_FREETYPE_H
+#include FT_SFNT_NAMES_H
+#include FT_TRUETYPE_IDS_H
+#include "ft.h"
+
+#ifndef LSBFirst
+#define LSBFirst 0
+#define MSBFirst 1
+#endif
+
+#define LOBYTE(s,byte) ((byte)==LSBFirst?*(char*)(s):*((char*)(s)+1))
+#define HIBYTE(s,byte) ((byte)==LSBFirst?*((char*)(s)+1):*(char*)(s))
+
+int FTtoXReturnCode(int rc)
+{
+ if(rc == 0x40)
+ return AllocError;
+ /* Anything else stops the font matching mechanism */
+ else return BadFontName;
+
+}
+
+/* Convert slen bytes from UCS-2 to ISO 8859-1. Byte specifies the
+ endianness of the string, max the maximum number of bytes written into
+ to. */
+static int
+FTu2a(int slen, FT_Byte *from, char *to, int byte, int max)
+{
+ int i, n;
+
+ n = 0;
+ for (i = 0; i < slen; i += 2) {
+ if(n >= max - 1)
+ break;
+ if(HIBYTE(from+i, byte)!=0)
+ *to++='?';
+ else
+ *to++ = LOBYTE(from+i,byte);
+ n++;
+ }
+ *to = 0;
+ return n;
+}
+
+static int
+FTGetName(FT_Face face, int nid, int pid, int eid, FT_SfntName *name_return)
+{
+ FT_SfntName name;
+ int n, i;
+
+ n = FT_Get_Sfnt_Name_Count(face);
+ if(n <= 0)
+ return 0;
+
+ for(i = 0; i < n; i++) {
+ if(FT_Get_Sfnt_Name(face, i, &name))
+ continue;
+ if(name.name_id == nid &&
+ name.platform_id == pid &&
+ (eid < 0 || name.encoding_id == eid)) {
+ switch(name.platform_id) {
+ case TT_PLATFORM_APPLE_UNICODE:
+ case TT_PLATFORM_MACINTOSH:
+ if(name.language_id != TT_MAC_LANGID_ENGLISH)
+ continue;
+ break;
+ case TT_PLATFORM_MICROSOFT:
+ if(name.language_id != TT_MS_LANGID_ENGLISH_UNITED_STATES &&
+ name.language_id != TT_MS_LANGID_ENGLISH_UNITED_KINGDOM)
+ break;
+ continue;
+ break;
+ default:
+ break;
+ }
+ *name_return = name;
+ return 1;
+ }
+ }
+ return 0;
+}
+
+int
+FTGetEnglishName(FT_Face face, int nid, char *name_return, int name_len)
+{
+ FT_SfntName name;
+ int len;
+
+ if(FTGetName(face, nid,
+ TT_PLATFORM_MICROSOFT, TT_MS_ID_UNICODE_CS, &name) ||
+ FTGetName(face, nid,
+ TT_PLATFORM_APPLE_UNICODE, -1, &name))
+ return FTu2a(name.string_len, name.string, name_return,
+ MSBFirst, name_len);
+
+ /* Pretend that Apple Roman is ISO 8859-1. */
+ if(FTGetName(face, nid, TT_PLATFORM_MACINTOSH, TT_MAC_ID_ROMAN, &name)) {
+ len = name.string_len;
+ if(len > name_len - 1)
+ len = name_len - 1;
+ memcpy(name_return, name.string, len);
+ name_return[len] = '\0'; /* ensure nul terminaison */
+ return len;
+ }
+
+ /* Must be some font that can only be named in Polish or something. */
+ return -1;
+}
diff --git a/libXfont/src/FreeType/xttcap.c b/libXfont/src/FreeType/xttcap.c
new file mode 100644
index 000000000..507da80d6
--- /dev/null
+++ b/libXfont/src/FreeType/xttcap.c
@@ -0,0 +1,731 @@
+/* ===EmacsMode: -*- Mode: C; tab-width:4; c-basic-offset: 4; -*- === */
+/* ===FileName: ===
+ Copyright (c) 1998 Takuya SHIOZAKI, All Rights reserved.
+ Copyright (c) 1998 X-TrueType Server Project, All rights reserved.
+ Copyright (c) 2003 After X-TT Project, All rights reserved.
+
+===Notice
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions
+ are met:
+ 1. Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ 2. Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+
+ THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ SUCH DAMAGE.
+
+ Major Release ID: X-TrueType Server Version 1.4 [Charles's Wain Release 0]
+
+Notice===
+ */
+/* $XFree86: xc/lib/font/FreeType/xttcap.c,v 1.1 2003/10/19 18:53:50 dawes Exp $ */
+
+/*
+#include "xttversion.h"
+
+static char const * const releaseID =
+ _XTT_RELEASE_NAME;
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include <X11/fonts/fontmisc.h>
+#include <string.h>
+#ifndef FONTMODULE
+#include <ctype.h>
+#include <math.h>
+#else
+#include "Xmd.h"
+#include "Xdefs.h"
+#include "xf86_ansic.h"
+#endif
+/*
+#include <X11/X.h>
+#include <X11/Xmd.h>
+#include <X11/Xfuncproto.h>
+#include "xf86Module.h"
+#include "xf86_ansic.h"
+*/
+
+#ifndef True
+#define True (-1)
+#endif /* True */
+#ifndef False
+#define False (0)
+#endif /* False */
+
+#include "xttcap.h"
+
+#if 0
+/*
+ Prototypes for obsoleted OS (e.g. SunOS4)
+ */
+
+#if (defined(sun) && !(defined(SVR4) || defined(__SVR4)))
+double strtod(char *str, char **ptr);
+double strtol(char *str, char **ptr, int base);
+#endif
+#endif
+
+
+/**************************************************************************
+ Private Data Types
+ */
+
+/* Property Record List */
+/* List Node */
+typedef struct TagSPropRecValListNodeP
+{
+ SPropRecValContainerEntityP containerE;
+ struct TagSPropRecValListNodeP *nextNode;
+} SPropRecValListNodeP;
+
+
+/**************************************************************************
+ Tables
+ */
+
+/* valid record field */
+static SPropertyRecord const validRecords[] =
+{
+ { "FontFile", eRecTypeString },
+ { "FaceNumber", eRecTypeString },
+ { "AutoItalic", eRecTypeDouble },
+ { "DoubleStrike", eRecTypeString },
+ { "FontProperties", eRecTypeBool },
+ { "ForceSpacing", eRecTypeString },
+ { "ScaleBBoxWidth", eRecTypeString },
+ { "ScaleWidth", eRecTypeDouble },
+ { "EncodingOptions", eRecTypeString },
+ { "Hinting", eRecTypeBool },
+ { "VeryLazyMetrics", eRecTypeBool },
+ { "CodeRange", eRecTypeString },
+ { "EmbeddedBitmap", eRecTypeString },
+ { "VeryLazyBitmapWidthScale", eRecTypeDouble },
+ { "ForceConstantSpacingCodeRange", eRecTypeString },
+ { "ForceConstantSpacingMetrics", eRecTypeString },
+ { "Dummy", eRecTypeVoid }
+};
+static int const
+numOfValidRecords = sizeof(validRecords)/sizeof(validRecords[0]);
+
+/* correspondence between record name and cap variable name */
+static struct {
+ char const * capVariable;
+ char const * recordName;
+} const correspondRelations[] = {
+ { "fn", "FaceNumber" },
+ { "ai", "AutoItalic" },
+ { "ds", "DoubleStrike" },
+ { "fp", "FontProperties" },
+ { "fs", "ForceSpacing" },
+ { "bw", "ScaleBBoxWidth" },
+ { "sw", "ScaleWidth" },
+ { "eo", "EncodingOptions" },
+ { "vl", "VeryLazyMetrics" },
+ { "bs", "VeryLazyBitmapWidthScale" },
+ { "cr", "CodeRange" },
+ { "eb", "EmbeddedBitmap" },
+ { "hi", "Hinting" },
+ { "fc", "ForceConstantSpacingCodeRange" },
+ { "fm", "ForceConstantSpacingMetrics" }
+};
+static int const
+numOfCorrespondRelations
+= sizeof(correspondRelations)/sizeof(correspondRelations[0]);
+
+/**************************************************************************
+ Functions
+ */
+
+/* get property record type by record name */
+static Bool /* True == Found, False == Not Found */
+get_record_type_by_name(SPropertyRecord const ** const refRefRecord, /*result*/
+ char const *strName)
+{
+ Bool result = False;
+ int i;
+
+ *refRefRecord = NULL;
+ for (i=0; i<numOfValidRecords; i++) {
+ if (!strcasecmp(validRecords[i].strRecordName, strName)) {
+ result = True;
+ *refRefRecord = &validRecords[i];
+ break;
+ }
+ }
+
+ return result;
+}
+
+/* Add Property Record Value */
+static Bool /* True == Error, False == Success */
+SPropRecValList_add_record(SDynPropRecValList *pThisList,
+ char const * const recordName,
+ char const * const strValue)
+{
+ Bool result = False;
+ SPropRecValContainerEntityP tmpContainerE;
+
+ if (get_record_type_by_name(&tmpContainerE.refRecordType, recordName)) {
+ switch (tmpContainerE.refRecordType->recordType) {
+ case eRecTypeInteger:
+ {
+ int val;
+ char *endPtr;
+
+ val = strtol(strValue, &endPtr, 0);
+ if ('\0' != *endPtr) {
+ fprintf(stderr,
+ "truetype font property : "
+ "%s record needs integer value.\n",
+ recordName);
+ result = True;
+ goto quit;
+ }
+ SPropContainer_value_int(&tmpContainerE) = val;
+ }
+ break;
+ case eRecTypeDouble:
+ {
+ double val;
+ char *endPtr;
+
+ val = strtod(strValue, &endPtr);
+ if ('\0' != *endPtr) {
+ fprintf(stderr,
+ "truetype font property : "
+ "%s record needs floating point value.\n",
+ recordName);
+ result = True;
+ goto quit;
+ }
+ SPropContainer_value_dbl(&tmpContainerE) = val;
+ }
+ break;
+ case eRecTypeBool:
+ {
+ Bool val;
+
+ if (!strcasecmp(strValue, "yes"))
+ val = True;
+ else if (!strcasecmp(strValue, "y"))
+ val = True;
+ else if (!strcasecmp(strValue, "on"))
+ val = True;
+ else if (!strcasecmp(strValue, "true"))
+ val = True;
+ else if (!strcasecmp(strValue, "t"))
+ val = True;
+ else if (!strcasecmp(strValue, "ok"))
+ val = True;
+ else if (!strcasecmp(strValue, "no"))
+ val = False;
+ else if (!strcasecmp(strValue, "n"))
+ val = False;
+ else if (!strcasecmp(strValue, "off"))
+ val = False;
+ else if (!strcasecmp(strValue, "false"))
+ val = False;
+ else if (!strcasecmp(strValue, "f"))
+ val = False;
+ else if (!strcasecmp(strValue, "bad"))
+ val = False;
+ else {
+ fprintf(stderr,
+ "truetype font property : "
+ "%s record needs boolean value.\n",
+ recordName);
+ result = True;
+ goto quit;
+ }
+ SPropContainer_value_bool(&tmpContainerE) = val;
+ }
+ break;
+ case eRecTypeString:
+ {
+ char *p;
+
+ if (NULL == (p = (char *)xalloc(strlen(strValue)+1))) {
+ fprintf(stderr,
+ "truetype font property : "
+ "cannot allocate memory.\n");
+ result = True;
+ goto quit;
+ }
+ strcpy(p, strValue);
+ SPropContainer_value_str(&tmpContainerE) = p;
+ }
+ break;
+ case eRecTypeVoid:
+ if ('\0' != *strValue) {
+ fprintf(stderr,
+ "truetype font property : "
+ "%s record needs void.\n", recordName);
+ result = True;
+ }
+ break;
+ }
+ {
+ /* add to list */
+ SPropRecValListNodeP *newNode;
+
+ if (NULL == (newNode =
+ (SPropRecValListNodeP *)xalloc(sizeof(*newNode)))) {
+ fprintf(stderr,
+ "truetype font property : "
+ "cannot allocate memory.\n");
+ result = True;
+ goto quit;
+ }
+ newNode->nextNode = pThisList->headNode;
+ newNode->containerE = tmpContainerE;
+ tmpContainerE.refRecordType = NULL; /* invalidate --
+ disown value handle. */
+ pThisList->headNode = newNode;
+ }
+ } else {
+ /* invalid record name */
+ fprintf(stderr,
+ "truetype font : "
+ "invalid record name \"%s.\"\n", recordName);
+ result = True;
+ }
+
+ quit:
+ return result;
+}
+
+#ifdef USE_TTP_FILE
+
+#ifndef LEN_LINEBUF
+#define LEN_LINEBUF 2048
+#endif /* !def LEN_LINEBUF */
+
+/* get one line */
+static Bool /* True == Error, False == Success */
+get_one_line(FILE *is, char *buf)
+{
+ Bool result = False;
+ int count = 0;
+ Bool flHead = True;
+ Bool flSpace = False;
+ Bool flInSingleQuote = False;
+ Bool flInDoubleQuote = False;
+ Bool flBackSlash = False;
+ Bool flFirstElement = True;
+
+ *buf = '\0';
+ for (;;) {
+ int c = fgetc(is);
+
+ if (ferror(is)) {
+ fprintf(stderr, "truetype font property file : read error.\n");
+ result = True;
+ break;
+ }
+
+ if (EOF == c) {
+ if (flInSingleQuote || flInDoubleQuote) {
+ fprintf(stderr,
+ "truetype font property file : unmatched quote.\n");
+ result = True;
+ }
+ break;
+ }
+ if (flInSingleQuote) {
+ if ('\'' == c) {
+ /* end of single quoted string */
+ flInSingleQuote = False;
+ c = -1; /* NOT extract to buffer. */
+ } else
+ /* others, extract all character to buffer unconditionally. */
+ ;
+ goto trans;
+ }
+ if (flBackSlash) {
+ /* escape --- when just before character is backslash,
+ next character is escaped. */
+ flBackSlash = False;
+ if ('n' == c)
+ /* newline */
+ c = '\n';
+ if ('\n' == c)
+ /* ignore newline */
+ c = -1;
+ else
+ /* others, extract all character to buffer unconditionally. */
+ ;
+ goto trans;
+ }
+ if ('\\' == c) {
+ /* set flag to escape next character. */
+ flBackSlash = True;
+ c = -1; /* NOT extract to buffer. */
+ goto trans;
+ }
+ if (flInDoubleQuote) {
+ if ('"' == c) {
+ /* end of double quoted string */
+ flInDoubleQuote = False;
+ c = -1; /* NOT extract to buffer. */
+ } else
+ /* others, extract all character to buffer unconditionally. */
+ ;
+ goto trans;
+ }
+ if ('#' == c) {
+ /* skip comment till end of line. */
+ while ('\n' != c) {
+ c = fgetc(is);
+ if (ferror(is)) {
+ fprintf(stderr,
+ "truetype font property file : read error.\n");
+ result = True;
+ break;
+ }
+ if (EOF == c) {
+ break;
+ }
+ }
+ break;
+ }
+ if ('\'' == c) {
+ /* into single quoted string */
+ flInSingleQuote = True;
+ c = -1; /* NOT extract to buffer. */
+ goto trans;
+ }
+ if ('"' == c) {
+ /* into double quoted string */
+ flInDoubleQuote = True;
+ c = -1; /* NOT extract to buffer. */
+ goto trans;
+ }
+ if ('\n' == c)
+ /* End of Line */
+ break;
+ if (isspace(c)) {
+ /* convine multiple spaces */
+ if (!flHead)
+ /* except space at the head of line */
+ flSpace = True;
+ continue;
+ }
+ trans:
+ /* set flHead to False, since current character is not white space
+ when reaches here. */
+ flHead = False;
+ do {
+ if (count>=LEN_LINEBUF-1) {
+ /* overflow */
+ fprintf(stderr,
+ "truetype font property file : too long line.\n");
+ result = True;
+ goto quit;
+ }
+ if (flSpace) {
+ /* just before characters is white space, but
+ current character is not WS. */
+ if (flFirstElement) {
+ /* this spaces is the first cell(?) of white spaces. */
+ flFirstElement = False;
+ /* separate record name and record value */
+ *buf = (char)0xff;
+ } else
+ *buf = ' ';
+ flSpace = False;
+ } else
+ if (-1 != c) {
+ *buf = c;
+ c = -1; /* invalidate */
+ } else
+ /* skip */
+ buf--;
+ buf++;
+ } while (-1 != c); /* when 'c' is not -1, it means
+ that 'c' contains an untreated character. */
+ }
+ *buf = '\0';
+
+ quit:
+ return result;
+}
+
+/* parse one line */
+static Bool /* True == Error, False == Success */
+parse_one_line(SDynPropRecValList *pThisList, FILE *is)
+{
+ Bool result = False;
+ char *buf = NULL;
+ char *recordHead, *valueHead = NULL;
+
+ if (NULL == (buf = xalloc(LEN_LINEBUF))) {
+ fprintf(stderr,
+ "truetype font property file : cannot allocate memory.\n");
+ result = True;
+ goto abort;
+ }
+ {
+ recordHead = buf;
+/* refRecordValue->refRecordType = NULL;*/
+ do {
+ if (get_one_line(is, buf)) {
+ result = True;
+ goto quit;
+ }
+ if (feof(is)) {
+ if ('\0' == *buf)
+ goto quit;
+ break;
+ }
+ } while ('\0' == *buf);
+
+ if (NULL != (valueHead = strchr(buf, 0xff))) {
+ *valueHead = '\0';
+ valueHead++;
+ } else
+ valueHead = buf+strlen(buf);
+#if 0
+ fprintf(stderr,
+ "truetype font property file : \n"
+ "recName:\"%s\"\nvalue:\"%s\"\n",
+ recordHead, valueHead);
+#endif
+ result = SPropRecValList_add_record(pThisList, recordHead, valueHead);
+ }
+ quit:
+ xfree(buf);
+ abort:
+ return result;
+}
+
+/* Read Property File */
+Bool /* True == Error, False == Success */
+SPropRecValList_read_prop_file(SDynPropRecValList *pThisList,
+ char const * const strFileName)
+{
+ Bool result = False;
+ FILE *is;
+
+#if 1
+ if (!strcmp(strFileName, "-"))
+ is = stdin;
+ else
+#endif
+ is = fopen(strFileName, "r");
+ if (NULL == is) {
+ fprintf(stderr, "truetype font property : cannot open file %s.\n",
+ strFileName);
+ result = True;
+ goto abort;
+ }
+ {
+ for (;;) {
+ if (False != (result = parse_one_line(pThisList, is)))
+ goto quit;
+ if (feof(is))
+ break;
+ }
+ }
+ quit:
+#if 1
+ if (strcmp(strFileName, "-"))
+#endif
+ fclose(is);
+ abort:
+ return result;
+}
+#endif /* USE_TTP_FILE */
+
+/* Constructor for Container Node */
+Bool /* True == Error, False == Success */
+SPropRecValList_new(SDynPropRecValList *pThisList)
+{
+ Bool result = False;
+
+ pThisList->headNode = NULL;
+
+ return result;
+}
+
+#ifdef DUMP
+void
+SPropRecValList_dump(SRefPropRecValList *pThisList)
+{
+ SPropRecValListNodeP *p;
+ for (p=pThisList->headNode; NULL!=p; p=p->nextNode) {
+ switch (p->containerE.refRecordType->recordType) {
+ case eRecTypeInteger:
+ fprintf(stderr, "%s = %d\n",
+ p->containerE.refRecordType->strRecordName,
+ p->containerE.uValue.integerValue);
+ break;
+ case eRecTypeDouble:
+ fprintf(stderr, "%s = %f\n",
+ p->containerE.refRecordType->strRecordName,
+ p->containerE.uValue.doubleValue);
+ break;
+ case eRecTypeBool:
+ fprintf(stderr, "%s = %s\n",
+ p->containerE.refRecordType->strRecordName,
+ p->containerE.uValue.boolValue
+ ? "True":"False");
+ break;
+ case eRecTypeString:
+ fprintf(stderr, "%s = \"%s\"\n",
+ p->containerE.refRecordType->strRecordName,
+ p->containerE.uValue.dynStringValue);
+ break;
+ case eRecTypeVoid:
+ fprintf(stderr, "%s = void\n",
+ p->containerE.refRecordType->strRecordName);
+ break;
+ }
+ }
+}
+#endif
+
+
+/* Search Property Record */
+Bool /* True == Hit, False == Miss */
+SPropRecValList_search_record(SRefPropRecValList *pThisList,
+ SPropRecValContainer *refRecValue,
+ char const * const recordName)
+{
+ Bool result = False;
+ SPropRecValListNodeP *p;
+
+ *refRecValue = NULL;
+ for (p=pThisList->headNode; NULL!=p; p=p->nextNode) {
+ if (!strcasecmp(p->containerE.refRecordType->strRecordName,
+ recordName)) {
+ *refRecValue = &p->containerE;
+ result = True;
+ break;
+ }
+ }
+
+ return result;
+}
+
+
+/* Parse TTCap */
+Bool /* True == Error, False == Success */
+SPropRecValList_add_by_font_cap(SDynPropRecValList *pThisList,
+ char const *strCapHead)
+{
+ Bool result = False;
+ /* SPropertyRecord const *refRecordType; */
+ char const *term;
+
+ if (NULL == (term = strrchr(strCapHead, ':')))
+ goto abort;
+
+ {
+ /* for xfsft compatible */
+ char const *p;
+ for (p=term-1; p>=strCapHead; p--) {
+ if ( ':'==*p ) {
+ /*
+ * :num:filename
+ * ^p ^term
+ */
+ if ( p!=term ) {
+ int len = term-p-1;
+ char *value;
+
+ len = term-p-1;
+ value=(char *)xalloc(len+1);
+ memcpy(value, p+1, len);
+ value[len]='\0';
+ SPropRecValList_add_record(pThisList,
+ "FaceNumber",
+ value);
+ xfree(value);
+ term=p;
+ }
+ break;
+ }
+ if ( !isdigit(*p) )
+ break;
+ }
+ }
+
+ while (strCapHead<term) {
+ int i;
+ char const *nextColon = strchr(strCapHead, ':');
+ if (0<nextColon-strCapHead) {
+ char *duplicated = (char *)xalloc((nextColon-strCapHead)+1);
+ {
+ char *value;
+
+ memcpy(duplicated, strCapHead, nextColon-strCapHead);
+ duplicated[nextColon-strCapHead] = '\0';
+ if (NULL != (value=strchr(duplicated, '='))) {
+ *value = '\0';
+ value++;
+ } else
+ value = &duplicated[nextColon-strCapHead];
+
+ for (i=0; i<numOfCorrespondRelations; i++) {
+ if (!strcasecmp(correspondRelations[i].capVariable,
+ duplicated)) {
+ if (SPropRecValList_add_record(pThisList,
+ correspondRelations[i]
+ .recordName,
+ value))
+ break;
+ goto next;
+ }
+ }
+ fprintf(stderr, "truetype font : Illegal Font Cap.\n");
+ result = True;
+ break;
+ next:
+ ;
+ }
+ xfree(duplicated);
+ }
+ strCapHead = nextColon+1;
+ }
+
+ /* quit: */
+ abort:
+ return result;
+}
+
+
+/**************************************************************************
+ Functions (xttmisc)
+ */
+
+/* strdup clone with using the allocator of X server */
+char *
+XttXstrdup(char const *str)
+{
+ char *result;
+
+ result = (char *)xalloc(strlen(str)+1);
+
+ if (result)
+ strcpy(result, str);
+
+ return result;
+}
+
+
+/* end of file */
diff --git a/libXfont/src/FreeType/xttcap.h b/libXfont/src/FreeType/xttcap.h
new file mode 100644
index 000000000..9da3c961c
--- /dev/null
+++ b/libXfont/src/FreeType/xttcap.h
@@ -0,0 +1,135 @@
+/* ===EmacsMode: -*- Mode: C; tab-width:4; c-basic-offset: 4; -*- === */
+/* ===FileName: ===
+ Copyright (c) 1998 Takuya SHIOZAKI, All Rights reserved.
+ Copyright (c) 1998 X-TrueType Server Project, All rights reserved.
+ Copyright (c) 2003 After X-TT Project, All rights reserved.
+
+===Notice
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions
+ are met:
+ 1. Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ 2. Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+
+ THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ SUCH DAMAGE.
+
+ Major Release ID: X-TrueType Server Version 1.3 [Aoi MATSUBARA Release 3]
+
+Notice===
+ */
+/* $XFree86: xc/extras/X-TrueType/xttcap.h,v 1.2 2001/08/01 00:44:33 tsi Exp $ */
+
+#ifndef _XTTCAP_H_
+#define _XTTCAP_H_ (1)
+
+#include <X11/Xdefs.h>
+
+/*******************************************************************
+ Data Types
+ */
+
+/* Record Type */
+typedef enum
+{
+ eRecTypeInteger,
+ eRecTypeDouble,
+ eRecTypeBool,
+ eRecTypeString,
+ eRecTypeVoid=-1
+} ERecType;
+
+/* Record Name vs Record Type */
+typedef struct
+{
+ char const *strRecordName;
+ ERecType const recordType;
+} SPropertyRecord;
+
+/* Record Value Container */
+typedef struct
+{
+ SPropertyRecord const *refRecordType;
+ union {
+ int integerValue;
+ double doubleValue;
+ Bool boolValue;
+ char *dynStringValue;
+ } uValue;
+} SPropRecValContainerEntityP, *SPropRecValContainer;
+
+/* Record Value List */
+typedef struct TagSPropRecValListNodeP SPropRecValListNode;
+typedef struct
+{
+ SPropRecValListNode *headNode;
+} SDynPropRecValList;
+typedef SDynPropRecValList const SRefPropRecValList;
+
+
+/*******************************************************************
+ Functions
+ */
+
+/* Constructor for Rec Val List */
+extern Bool /* True == Error, False == Success */
+SPropRecValList_new(SDynPropRecValList *pThisList);
+/* Destructor for Rec Val List */
+extern Bool /* True == Error, False == Success */
+SPropRecValList_delete(SDynPropRecValList *pThisList);
+/* Read Property File */
+extern Bool /* True == Error, False == Success */
+SPropRecValList_read_prop_file(SDynPropRecValList *pThisList,
+ char const * const strFileName);
+/* Search Property Record */
+extern Bool /* True == Hit, False == Miss */
+SPropRecValList_search_record(SRefPropRecValList *pThisList,
+ SPropRecValContainer *refContRecVal,
+ char const * const recordName);
+/* Add by Font Cap */
+extern Bool /* True == Error, False == Success */
+SPropRecValList_add_by_font_cap(SDynPropRecValList *pThisList,
+ char const *strCapHead);
+
+#ifdef DUMP
+void
+SPropRecValList_dump(SRefPropRecValList *refList);
+#endif
+
+#define SPropContainer_value_int(contRecVal)\
+ ((contRecVal)->uValue.integerValue)
+#define SPropContainer_value_dbl(contRecVal)\
+ ((contRecVal)->uValue.doubleValue)
+#define SPropContainer_value_bool(contRecVal)\
+ ((contRecVal)->uValue.boolValue)
+#define SPropContainer_value_str(contRecVal)\
+ ((contRecVal)->uValue.dynStringValue)
+
+/******************************************************
+ Prototypes (xttmisc)
+ */
+
+/* compare strings with ignoring case */
+ /* False == equal, True == not equal */
+Bool mystrcasecmp(char const *s1, char const *s2);
+
+/* strdup clone */
+char * XttXstrdup(char const *str);
+#undef xstrdup
+#define xstrdup(s) XttXstrdup((char const*)s)
+
+#endif /* !def _XTTCAP_H_ */
+
+/* end of file */
diff --git a/libXfont/src/Makefile.am b/libXfont/src/Makefile.am
new file mode 100644
index 000000000..3e0cbfae0
--- /dev/null
+++ b/libXfont/src/Makefile.am
@@ -0,0 +1,78 @@
+#
+# Copyright © 2003 Keith Packard, Noah Levitt
+#
+# Permission to use, copy, modify, distribute, and sell this software and its
+# documentation for any purpose is hereby granted without fee, provided that
+# the above copyright notice appear in all copies and that both that
+# copyright notice and this permission notice appear in supporting
+# documentation, and that the name of Keith Packard not be used in
+# advertising or publicity pertaining to distribution of the software without
+# specific, written prior permission. Keith Packard makes no
+# representations about the suitability of this software for any purpose. It
+# is provided "as is" without express or implied warranty.
+#
+# KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+# INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+# EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+# CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+# DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+# TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+# PERFORMANCE OF THIS SOFTWARE.
+
+lib_LTLIBRARIES = libXfont.la
+
+if XFONT_FONTFILE
+FONTFILE_DIR = fontfile
+FONTFILE_LIB = fontfile/libfontfile.la
+endif
+
+if XFONT_FREETYPE
+FREETYPE_DIR = FreeType
+FREETYPE_LIB = FreeType/libft.la
+endif
+
+if XFONT_BITMAP
+BITMAP_DIR = bitmap
+BITMAP_LIB = bitmap/libbitmap.la
+endif
+
+if XFONT_BUILTINS
+BUILTINS_DIR = builtins
+BUILTINS_LIB = builtins/libbuiltins.la
+endif
+
+if XFONT_FC
+FC_DIR = fc
+FC_LIB = fc/libfc.la
+endif
+
+if XFONT_TYPE1
+TYPE1_DIR = Type1
+TYPE1_LIB = Type1/libtype1.la
+endif
+
+if XFONT_SPEEDO
+SPEEDO_DIR = Speedo
+SPEEDO_LIB = Speedo/libspeedo.la
+endif
+
+UTIL_DIR = util
+UTIL_LIB = util/libutil.la
+
+STUBS_LIB = stubs/libstubs.la
+STUBS_DIR = stubs
+
+SUBDIRS=\
+ $(FONTFILE_DIR) $(FREETYPE_DIR) $(BITMAP_DIR) \
+ $(BUILTINS_DIR) $(FC_DIR) $(UTIL_DIR) $(STUBS_DIR) \
+ $(TYPE1_DIR) $(SPEEDO_DIR)
+
+libXfont_la_LIBADD = \
+ $(FONTFILE_LIB) $(FREETYPE_LIB) $(BITMAP_LIB) \
+ $(BUILTINS_LIB) $(FC_LIB) $(UTIL_LIB) $(STUBS_LIB) \
+ $(TYPE1_LIB) $(SPEEDO_LIB) \
+ $(FREETYPE_LIBS) $(Z_LIBS) $(MATH_LIBS) $(XFONT_LIBS)
+
+libXfont_la_SOURCES = dummy.c
+
+libXfont_la_LDFLAGS = -version-number 1:4:1 -no-undefined
diff --git a/libXfont/src/Makefile.in b/libXfont/src/Makefile.in
new file mode 100644
index 000000000..b285616c0
--- /dev/null
+++ b/libXfont/src/Makefile.in
@@ -0,0 +1,650 @@
+# Makefile.in generated by automake 1.10 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
+# 2003, 2004, 2005, 2006 Free Software Foundation, Inc.
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+@SET_MAKE@
+
+#
+# Copyright © 2003 Keith Packard, Noah Levitt
+#
+# Permission to use, copy, modify, distribute, and sell this software and its
+# documentation for any purpose is hereby granted without fee, provided that
+# the above copyright notice appear in all copies and that both that
+# copyright notice and this permission notice appear in supporting
+# documentation, and that the name of Keith Packard not be used in
+# advertising or publicity pertaining to distribution of the software without
+# specific, written prior permission. Keith Packard makes no
+# representations about the suitability of this software for any purpose. It
+# is provided "as is" without express or implied warranty.
+#
+# KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+# INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+# EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+# CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+# DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+# TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+# PERFORMANCE OF THIS SOFTWARE.
+
+VPATH = @srcdir@
+pkgdatadir = $(datadir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+install_sh_DATA = $(install_sh) -c -m 644
+install_sh_PROGRAM = $(install_sh) -c
+install_sh_SCRIPT = $(install_sh) -c
+INSTALL_HEADER = $(INSTALL_DATA)
+transform = $(program_transform_name)
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+build_triplet = @build@
+host_triplet = @host@
+subdir = src
+DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/configure.ac
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+ $(ACLOCAL_M4)
+mkinstalldirs = $(install_sh) -d
+CONFIG_HEADER = $(top_builddir)/config.h \
+ $(top_builddir)/include/X11/fonts/fontconf.h
+CONFIG_CLEAN_FILES =
+am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
+am__vpath_adj = case $$p in \
+ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \
+ *) f=$$p;; \
+ esac;
+am__strip_dir = `echo $$p | sed -e 's|^.*/||'`;
+am__installdirs = "$(DESTDIR)$(libdir)"
+libLTLIBRARIES_INSTALL = $(INSTALL)
+LTLIBRARIES = $(lib_LTLIBRARIES)
+am__DEPENDENCIES_1 =
+libXfont_la_DEPENDENCIES = $(FONTFILE_LIB) $(FREETYPE_LIB) \
+ $(BITMAP_LIB) $(BUILTINS_LIB) $(FC_LIB) $(UTIL_LIB) \
+ $(STUBS_LIB) $(TYPE1_LIB) $(SPEEDO_LIB) $(am__DEPENDENCIES_1) \
+ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \
+ $(am__DEPENDENCIES_1)
+am_libXfont_la_OBJECTS = dummy.lo
+libXfont_la_OBJECTS = $(am_libXfont_la_OBJECTS)
+libXfont_la_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
+ $(libXfont_la_LDFLAGS) $(LDFLAGS) -o $@
+DEFAULT_INCLUDES = -I. -I$(top_builddir) -I$(top_builddir)/include/X11/fonts@am__isrc@
+depcomp = $(SHELL) $(top_srcdir)/depcomp
+am__depfiles_maybe = depfiles
+COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
+ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+LTCOMPILE = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
+ --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \
+ $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+CCLD = $(CC)
+LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
+ --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \
+ $(LDFLAGS) -o $@
+SOURCES = $(libXfont_la_SOURCES)
+DIST_SOURCES = $(libXfont_la_SOURCES)
+RECURSIVE_TARGETS = all-recursive check-recursive dvi-recursive \
+ html-recursive info-recursive install-data-recursive \
+ install-dvi-recursive install-exec-recursive \
+ install-html-recursive install-info-recursive \
+ install-pdf-recursive install-ps-recursive install-recursive \
+ installcheck-recursive installdirs-recursive pdf-recursive \
+ ps-recursive uninstall-recursive
+RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \
+ distclean-recursive maintainer-clean-recursive
+ETAGS = etags
+CTAGS = ctags
+DIST_SUBDIRS = fontfile FreeType bitmap builtins fc util stubs Type1 \
+ Speedo
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+ACLOCAL = @ACLOCAL@
+AMTAR = @AMTAR@
+AR = @AR@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+CC = @CC@
+CCDEPMODE = @CCDEPMODE@
+CFLAGS = @CFLAGS@
+CHANGELOG_CMD = @CHANGELOG_CMD@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CWARNFLAGS = @CWARNFLAGS@
+CXX = @CXX@
+CXXCPP = @CXXCPP@
+CXXDEPMODE = @CXXDEPMODE@
+CXXFLAGS = @CXXFLAGS@
+CYGPATH_W = @CYGPATH_W@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+ECHO = @ECHO@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+EGREP = @EGREP@
+ENCODINGSDIR = @ENCODINGSDIR@
+EXEEXT = @EXEEXT@
+F77 = @F77@
+FFLAGS = @FFLAGS@
+FREETYPE_CFLAGS = @FREETYPE_CFLAGS@
+FREETYPE_LIBS = @FREETYPE_LIBS@
+FREETYPE_REQUIRES = @FREETYPE_REQUIRES@
+GREP = @GREP@
+INSTALL = @INSTALL@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+LDFLAGS = @LDFLAGS@
+LIBOBJS = @LIBOBJS@
+LIBS = @LIBS@
+LIBTOOL = @LIBTOOL@
+LN_S = @LN_S@
+LTLIBOBJS = @LTLIBOBJS@
+MAKEINFO = @MAKEINFO@
+MATH_LIBS = @MATH_LIBS@
+MKDIR_P = @MKDIR_P@
+OBJEXT = @OBJEXT@
+OS_CFLAGS = @OS_CFLAGS@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+PKG_CONFIG = @PKG_CONFIG@
+RANLIB = @RANLIB@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+STRIP = @STRIP@
+VERSION = @VERSION@
+XFONT_CFLAGS = @XFONT_CFLAGS@
+XFONT_LIBS = @XFONT_LIBS@
+X_GZIP_FONT_COMPRESSION = @X_GZIP_FONT_COMPRESSION@
+Z_LIBS = @Z_LIBS@
+abs_builddir = @abs_builddir@
+abs_srcdir = @abs_srcdir@
+abs_top_builddir = @abs_top_builddir@
+abs_top_srcdir = @abs_top_srcdir@
+ac_ct_CC = @ac_ct_CC@
+ac_ct_CXX = @ac_ct_CXX@
+ac_ct_F77 = @ac_ct_F77@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+am__tar = @am__tar@
+am__untar = @am__untar@
+bindir = @bindir@
+build = @build@
+build_alias = @build_alias@
+build_cpu = @build_cpu@
+build_os = @build_os@
+build_vendor = @build_vendor@
+builddir = @builddir@
+datadir = @datadir@
+datarootdir = @datarootdir@
+distcleancheck_listfiles = @distcleancheck_listfiles@
+docdir = @docdir@
+dvidir = @dvidir@
+exec_prefix = @exec_prefix@
+ft_config = @ft_config@
+host = @host@
+host_alias = @host_alias@
+host_cpu = @host_cpu@
+host_os = @host_os@
+host_vendor = @host_vendor@
+htmldir = @htmldir@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+libdir = @libdir@
+libexecdir = @libexecdir@
+localedir = @localedir@
+localstatedir = @localstatedir@
+mandir = @mandir@
+mkdir_p = @mkdir_p@
+oldincludedir = @oldincludedir@
+pdfdir = @pdfdir@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+psdir = @psdir@
+sbindir = @sbindir@
+sharedstatedir = @sharedstatedir@
+srcdir = @srcdir@
+sysconfdir = @sysconfdir@
+target_alias = @target_alias@
+top_builddir = @top_builddir@
+top_srcdir = @top_srcdir@
+lib_LTLIBRARIES = libXfont.la
+@XFONT_FONTFILE_TRUE@FONTFILE_DIR = fontfile
+@XFONT_FONTFILE_TRUE@FONTFILE_LIB = fontfile/libfontfile.la
+@XFONT_FREETYPE_TRUE@FREETYPE_DIR = FreeType
+@XFONT_FREETYPE_TRUE@FREETYPE_LIB = FreeType/libft.la
+@XFONT_BITMAP_TRUE@BITMAP_DIR = bitmap
+@XFONT_BITMAP_TRUE@BITMAP_LIB = bitmap/libbitmap.la
+@XFONT_BUILTINS_TRUE@BUILTINS_DIR = builtins
+@XFONT_BUILTINS_TRUE@BUILTINS_LIB = builtins/libbuiltins.la
+@XFONT_FC_TRUE@FC_DIR = fc
+@XFONT_FC_TRUE@FC_LIB = fc/libfc.la
+@XFONT_TYPE1_TRUE@TYPE1_DIR = Type1
+@XFONT_TYPE1_TRUE@TYPE1_LIB = Type1/libtype1.la
+@XFONT_SPEEDO_TRUE@SPEEDO_DIR = Speedo
+@XFONT_SPEEDO_TRUE@SPEEDO_LIB = Speedo/libspeedo.la
+UTIL_DIR = util
+UTIL_LIB = util/libutil.la
+STUBS_LIB = stubs/libstubs.la
+STUBS_DIR = stubs
+SUBDIRS = \
+ $(FONTFILE_DIR) $(FREETYPE_DIR) $(BITMAP_DIR) \
+ $(BUILTINS_DIR) $(FC_DIR) $(UTIL_DIR) $(STUBS_DIR) \
+ $(TYPE1_DIR) $(SPEEDO_DIR)
+
+libXfont_la_LIBADD = \
+ $(FONTFILE_LIB) $(FREETYPE_LIB) $(BITMAP_LIB) \
+ $(BUILTINS_LIB) $(FC_LIB) $(UTIL_LIB) $(STUBS_LIB) \
+ $(TYPE1_LIB) $(SPEEDO_LIB) \
+ $(FREETYPE_LIBS) $(Z_LIBS) $(MATH_LIBS) $(XFONT_LIBS)
+
+libXfont_la_SOURCES = dummy.c
+libXfont_la_LDFLAGS = -version-number 1:4:1 -no-undefined
+all: all-recursive
+
+.SUFFIXES:
+.SUFFIXES: .c .lo .o .obj
+$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps)
+ @for dep in $?; do \
+ case '$(am__configure_deps)' in \
+ *$$dep*) \
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh \
+ && exit 0; \
+ exit 1;; \
+ esac; \
+ done; \
+ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign src/Makefile'; \
+ cd $(top_srcdir) && \
+ $(AUTOMAKE) --foreign src/Makefile
+.PRECIOUS: Makefile
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+ @case '$?' in \
+ *config.status*) \
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
+ *) \
+ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
+ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
+ esac;
+
+$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+
+$(top_srcdir)/configure: $(am__configure_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(ACLOCAL_M4): $(am__aclocal_m4_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+install-libLTLIBRARIES: $(lib_LTLIBRARIES)
+ @$(NORMAL_INSTALL)
+ test -z "$(libdir)" || $(MKDIR_P) "$(DESTDIR)$(libdir)"
+ @list='$(lib_LTLIBRARIES)'; for p in $$list; do \
+ if test -f $$p; then \
+ f=$(am__strip_dir) \
+ echo " $(LIBTOOL) --mode=install $(libLTLIBRARIES_INSTALL) $(INSTALL_STRIP_FLAG) '$$p' '$(DESTDIR)$(libdir)/$$f'"; \
+ $(LIBTOOL) --mode=install $(libLTLIBRARIES_INSTALL) $(INSTALL_STRIP_FLAG) "$$p" "$(DESTDIR)$(libdir)/$$f"; \
+ else :; fi; \
+ done
+
+uninstall-libLTLIBRARIES:
+ @$(NORMAL_UNINSTALL)
+ @list='$(lib_LTLIBRARIES)'; for p in $$list; do \
+ p=$(am__strip_dir) \
+ echo " $(LIBTOOL) --mode=uninstall rm -f '$(DESTDIR)$(libdir)/$$p'"; \
+ $(LIBTOOL) --mode=uninstall rm -f "$(DESTDIR)$(libdir)/$$p"; \
+ done
+
+clean-libLTLIBRARIES:
+ -test -z "$(lib_LTLIBRARIES)" || rm -f $(lib_LTLIBRARIES)
+ @list='$(lib_LTLIBRARIES)'; for p in $$list; do \
+ dir="`echo $$p | sed -e 's|/[^/]*$$||'`"; \
+ test "$$dir" != "$$p" || dir=.; \
+ echo "rm -f \"$${dir}/so_locations\""; \
+ rm -f "$${dir}/so_locations"; \
+ done
+libXfont.la: $(libXfont_la_OBJECTS) $(libXfont_la_DEPENDENCIES)
+ $(libXfont_la_LINK) -rpath $(libdir) $(libXfont_la_OBJECTS) $(libXfont_la_LIBADD) $(LIBS)
+
+mostlyclean-compile:
+ -rm -f *.$(OBJEXT)
+
+distclean-compile:
+ -rm -f *.tab.c
+
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dummy.Plo@am__quote@
+
+.c.o:
+@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
+@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(COMPILE) -c $<
+
+.c.obj:
+@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'`
+@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(COMPILE) -c `$(CYGPATH_W) '$<'`
+
+.c.lo:
+@am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
+@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(LTCOMPILE) -c -o $@ $<
+
+mostlyclean-libtool:
+ -rm -f *.lo
+
+clean-libtool:
+ -rm -rf .libs _libs
+
+# This directory's subdirectories are mostly independent; you can cd
+# into them and run `make' without going through this Makefile.
+# To change the values of `make' variables: instead of editing Makefiles,
+# (1) if the variable is set in `config.status', edit `config.status'
+# (which will cause the Makefiles to be regenerated when you run `make');
+# (2) otherwise, pass the desired values on the `make' command line.
+$(RECURSIVE_TARGETS):
+ @failcom='exit 1'; \
+ for f in x $$MAKEFLAGS; do \
+ case $$f in \
+ *=* | --[!k]*);; \
+ *k*) failcom='fail=yes';; \
+ esac; \
+ done; \
+ dot_seen=no; \
+ target=`echo $@ | sed s/-recursive//`; \
+ list='$(SUBDIRS)'; for subdir in $$list; do \
+ echo "Making $$target in $$subdir"; \
+ if test "$$subdir" = "."; then \
+ dot_seen=yes; \
+ local_target="$$target-am"; \
+ else \
+ local_target="$$target"; \
+ fi; \
+ (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \
+ || eval $$failcom; \
+ done; \
+ if test "$$dot_seen" = "no"; then \
+ $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \
+ fi; test -z "$$fail"
+
+$(RECURSIVE_CLEAN_TARGETS):
+ @failcom='exit 1'; \
+ for f in x $$MAKEFLAGS; do \
+ case $$f in \
+ *=* | --[!k]*);; \
+ *k*) failcom='fail=yes';; \
+ esac; \
+ done; \
+ dot_seen=no; \
+ case "$@" in \
+ distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \
+ *) list='$(SUBDIRS)' ;; \
+ esac; \
+ rev=''; for subdir in $$list; do \
+ if test "$$subdir" = "."; then :; else \
+ rev="$$subdir $$rev"; \
+ fi; \
+ done; \
+ rev="$$rev ."; \
+ target=`echo $@ | sed s/-recursive//`; \
+ for subdir in $$rev; do \
+ echo "Making $$target in $$subdir"; \
+ if test "$$subdir" = "."; then \
+ local_target="$$target-am"; \
+ else \
+ local_target="$$target"; \
+ fi; \
+ (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \
+ || eval $$failcom; \
+ done && test -z "$$fail"
+tags-recursive:
+ list='$(SUBDIRS)'; for subdir in $$list; do \
+ test "$$subdir" = . || (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) tags); \
+ done
+ctags-recursive:
+ list='$(SUBDIRS)'; for subdir in $$list; do \
+ test "$$subdir" = . || (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) ctags); \
+ done
+
+ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) ' { files[$$0] = 1; } \
+ END { for (i in files) print i; }'`; \
+ mkid -fID $$unique
+tags: TAGS
+
+TAGS: tags-recursive $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
+ $(TAGS_FILES) $(LISP)
+ tags=; \
+ here=`pwd`; \
+ if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \
+ include_option=--etags-include; \
+ empty_fix=.; \
+ else \
+ include_option=--include; \
+ empty_fix=; \
+ fi; \
+ list='$(SUBDIRS)'; for subdir in $$list; do \
+ if test "$$subdir" = .; then :; else \
+ test ! -f $$subdir/TAGS || \
+ tags="$$tags $$include_option=$$here/$$subdir/TAGS"; \
+ fi; \
+ done; \
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) ' { files[$$0] = 1; } \
+ END { for (i in files) print i; }'`; \
+ if test -z "$(ETAGS_ARGS)$$tags$$unique"; then :; else \
+ test -n "$$unique" || unique=$$empty_fix; \
+ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+ $$tags $$unique; \
+ fi
+ctags: CTAGS
+CTAGS: ctags-recursive $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
+ $(TAGS_FILES) $(LISP)
+ tags=; \
+ here=`pwd`; \
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) ' { files[$$0] = 1; } \
+ END { for (i in files) print i; }'`; \
+ test -z "$(CTAGS_ARGS)$$tags$$unique" \
+ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
+ $$tags $$unique
+
+GTAGS:
+ here=`$(am__cd) $(top_builddir) && pwd` \
+ && cd $(top_srcdir) \
+ && gtags -i $(GTAGS_ARGS) $$here
+
+distclean-tags:
+ -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
+
+distdir: $(DISTFILES)
+ @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ list='$(DISTFILES)'; \
+ dist_files=`for file in $$list; do echo $$file; done | \
+ sed -e "s|^$$srcdirstrip/||;t" \
+ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
+ case $$dist_files in \
+ */*) $(MKDIR_P) `echo "$$dist_files" | \
+ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
+ sort -u` ;; \
+ esac; \
+ for file in $$dist_files; do \
+ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
+ if test -d $$d/$$file; then \
+ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
+ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
+ cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \
+ fi; \
+ cp -pR $$d/$$file $(distdir)$$dir || exit 1; \
+ else \
+ test -f $(distdir)/$$file \
+ || cp -p $$d/$$file $(distdir)/$$file \
+ || exit 1; \
+ fi; \
+ done
+ list='$(DIST_SUBDIRS)'; for subdir in $$list; do \
+ if test "$$subdir" = .; then :; else \
+ test -d "$(distdir)/$$subdir" \
+ || $(MKDIR_P) "$(distdir)/$$subdir" \
+ || exit 1; \
+ distdir=`$(am__cd) $(distdir) && pwd`; \
+ top_distdir=`$(am__cd) $(top_distdir) && pwd`; \
+ (cd $$subdir && \
+ $(MAKE) $(AM_MAKEFLAGS) \
+ top_distdir="$$top_distdir" \
+ distdir="$$distdir/$$subdir" \
+ am__remove_distdir=: \
+ am__skip_length_check=: \
+ distdir) \
+ || exit 1; \
+ fi; \
+ done
+check-am: all-am
+check: check-recursive
+all-am: Makefile $(LTLIBRARIES)
+installdirs: installdirs-recursive
+installdirs-am:
+ for dir in "$(DESTDIR)$(libdir)"; do \
+ test -z "$$dir" || $(MKDIR_P) "$$dir"; \
+ done
+install: install-recursive
+install-exec: install-exec-recursive
+install-data: install-data-recursive
+uninstall: uninstall-recursive
+
+install-am: all-am
+ @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-recursive
+install-strip:
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ `test -z '$(STRIP)' || \
+ echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
+mostlyclean-generic:
+
+clean-generic:
+
+distclean-generic:
+ -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
+
+maintainer-clean-generic:
+ @echo "This command is intended for maintainers to use"
+ @echo "it deletes files that may require special tools to rebuild."
+clean: clean-recursive
+
+clean-am: clean-generic clean-libLTLIBRARIES clean-libtool \
+ mostlyclean-am
+
+distclean: distclean-recursive
+ -rm -rf ./$(DEPDIR)
+ -rm -f Makefile
+distclean-am: clean-am distclean-compile distclean-generic \
+ distclean-tags
+
+dvi: dvi-recursive
+
+dvi-am:
+
+html: html-recursive
+
+info: info-recursive
+
+info-am:
+
+install-data-am:
+
+install-dvi: install-dvi-recursive
+
+install-exec-am: install-libLTLIBRARIES
+
+install-html: install-html-recursive
+
+install-info: install-info-recursive
+
+install-man:
+
+install-pdf: install-pdf-recursive
+
+install-ps: install-ps-recursive
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-recursive
+ -rm -rf ./$(DEPDIR)
+ -rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-recursive
+
+mostlyclean-am: mostlyclean-compile mostlyclean-generic \
+ mostlyclean-libtool
+
+pdf: pdf-recursive
+
+pdf-am:
+
+ps: ps-recursive
+
+ps-am:
+
+uninstall-am: uninstall-libLTLIBRARIES
+
+.MAKE: $(RECURSIVE_CLEAN_TARGETS) $(RECURSIVE_TARGETS) install-am \
+ install-strip
+
+.PHONY: $(RECURSIVE_CLEAN_TARGETS) $(RECURSIVE_TARGETS) CTAGS GTAGS \
+ all all-am check check-am clean clean-generic \
+ clean-libLTLIBRARIES clean-libtool ctags ctags-recursive \
+ distclean distclean-compile distclean-generic \
+ distclean-libtool distclean-tags distdir dvi dvi-am html \
+ html-am info info-am install install-am install-data \
+ install-data-am install-dvi install-dvi-am install-exec \
+ install-exec-am install-html install-html-am install-info \
+ install-info-am install-libLTLIBRARIES install-man install-pdf \
+ install-pdf-am install-ps install-ps-am install-strip \
+ installcheck installcheck-am installdirs installdirs-am \
+ maintainer-clean maintainer-clean-generic mostlyclean \
+ mostlyclean-compile mostlyclean-generic mostlyclean-libtool \
+ pdf pdf-am ps ps-am tags tags-recursive uninstall uninstall-am \
+ uninstall-libLTLIBRARIES
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/libXfont/src/Speedo/Makefile.am b/libXfont/src/Speedo/Makefile.am
new file mode 100644
index 000000000..99d972d1c
--- /dev/null
+++ b/libXfont/src/Speedo/Makefile.am
@@ -0,0 +1,34 @@
+INCLUDES = \
+ -I${top_srcdir}/include
+
+AM_CFLAGS = $(XFONT_CFLAGS) $(OS_CFLAGS) $(CWARNFLAGS)
+
+noinst_LTLIBRARIES = libspeedo.la
+
+libspeedo_la_SOURCES = \
+ adobe-iso.h \
+ bics-iso.h \
+ bics-unicode.c \
+ bics-unicode.h \
+ do_char.c \
+ do_trns.c \
+ keys.h \
+ out_bl2d.c \
+ out_blk.c \
+ out_outl.c \
+ out_scrn.c \
+ out_util.c \
+ reset.c \
+ set_spcs.c \
+ set_trns.c \
+ spdo_prv.h \
+ speedo.h \
+ spencode.c \
+ sperr.c \
+ spfile.c \
+ spfont.c \
+ spfuncs.c \
+ spglyph.c \
+ spinfo.c \
+ spint.h \
+ useropt.h
diff --git a/libXfont/src/Speedo/Makefile.in b/libXfont/src/Speedo/Makefile.in
new file mode 100644
index 000000000..b55b517a1
--- /dev/null
+++ b/libXfont/src/Speedo/Makefile.in
@@ -0,0 +1,497 @@
+# Makefile.in generated by automake 1.10 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
+# 2003, 2004, 2005, 2006 Free Software Foundation, Inc.
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+@SET_MAKE@
+
+VPATH = @srcdir@
+pkgdatadir = $(datadir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+install_sh_DATA = $(install_sh) -c -m 644
+install_sh_PROGRAM = $(install_sh) -c
+install_sh_SCRIPT = $(install_sh) -c
+INSTALL_HEADER = $(INSTALL_DATA)
+transform = $(program_transform_name)
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+build_triplet = @build@
+host_triplet = @host@
+subdir = src/Speedo
+DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/configure.ac
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+ $(ACLOCAL_M4)
+mkinstalldirs = $(install_sh) -d
+CONFIG_HEADER = $(top_builddir)/config.h \
+ $(top_builddir)/include/X11/fonts/fontconf.h
+CONFIG_CLEAN_FILES =
+LTLIBRARIES = $(noinst_LTLIBRARIES)
+libspeedo_la_LIBADD =
+am_libspeedo_la_OBJECTS = bics-unicode.lo do_char.lo do_trns.lo \
+ out_bl2d.lo out_blk.lo out_outl.lo out_scrn.lo out_util.lo \
+ reset.lo set_spcs.lo set_trns.lo spencode.lo sperr.lo \
+ spfile.lo spfont.lo spfuncs.lo spglyph.lo spinfo.lo
+libspeedo_la_OBJECTS = $(am_libspeedo_la_OBJECTS)
+DEFAULT_INCLUDES = -I. -I$(top_builddir) -I$(top_builddir)/include/X11/fonts@am__isrc@
+depcomp = $(SHELL) $(top_srcdir)/depcomp
+am__depfiles_maybe = depfiles
+COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
+ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+LTCOMPILE = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
+ --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \
+ $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+CCLD = $(CC)
+LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
+ --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \
+ $(LDFLAGS) -o $@
+SOURCES = $(libspeedo_la_SOURCES)
+DIST_SOURCES = $(libspeedo_la_SOURCES)
+ETAGS = etags
+CTAGS = ctags
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+ACLOCAL = @ACLOCAL@
+AMTAR = @AMTAR@
+AR = @AR@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+CC = @CC@
+CCDEPMODE = @CCDEPMODE@
+CFLAGS = @CFLAGS@
+CHANGELOG_CMD = @CHANGELOG_CMD@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CWARNFLAGS = @CWARNFLAGS@
+CXX = @CXX@
+CXXCPP = @CXXCPP@
+CXXDEPMODE = @CXXDEPMODE@
+CXXFLAGS = @CXXFLAGS@
+CYGPATH_W = @CYGPATH_W@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+ECHO = @ECHO@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+EGREP = @EGREP@
+ENCODINGSDIR = @ENCODINGSDIR@
+EXEEXT = @EXEEXT@
+F77 = @F77@
+FFLAGS = @FFLAGS@
+FREETYPE_CFLAGS = @FREETYPE_CFLAGS@
+FREETYPE_LIBS = @FREETYPE_LIBS@
+FREETYPE_REQUIRES = @FREETYPE_REQUIRES@
+GREP = @GREP@
+INSTALL = @INSTALL@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+LDFLAGS = @LDFLAGS@
+LIBOBJS = @LIBOBJS@
+LIBS = @LIBS@
+LIBTOOL = @LIBTOOL@
+LN_S = @LN_S@
+LTLIBOBJS = @LTLIBOBJS@
+MAKEINFO = @MAKEINFO@
+MATH_LIBS = @MATH_LIBS@
+MKDIR_P = @MKDIR_P@
+OBJEXT = @OBJEXT@
+OS_CFLAGS = @OS_CFLAGS@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+PKG_CONFIG = @PKG_CONFIG@
+RANLIB = @RANLIB@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+STRIP = @STRIP@
+VERSION = @VERSION@
+XFONT_CFLAGS = @XFONT_CFLAGS@
+XFONT_LIBS = @XFONT_LIBS@
+X_GZIP_FONT_COMPRESSION = @X_GZIP_FONT_COMPRESSION@
+Z_LIBS = @Z_LIBS@
+abs_builddir = @abs_builddir@
+abs_srcdir = @abs_srcdir@
+abs_top_builddir = @abs_top_builddir@
+abs_top_srcdir = @abs_top_srcdir@
+ac_ct_CC = @ac_ct_CC@
+ac_ct_CXX = @ac_ct_CXX@
+ac_ct_F77 = @ac_ct_F77@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+am__tar = @am__tar@
+am__untar = @am__untar@
+bindir = @bindir@
+build = @build@
+build_alias = @build_alias@
+build_cpu = @build_cpu@
+build_os = @build_os@
+build_vendor = @build_vendor@
+builddir = @builddir@
+datadir = @datadir@
+datarootdir = @datarootdir@
+distcleancheck_listfiles = @distcleancheck_listfiles@
+docdir = @docdir@
+dvidir = @dvidir@
+exec_prefix = @exec_prefix@
+ft_config = @ft_config@
+host = @host@
+host_alias = @host_alias@
+host_cpu = @host_cpu@
+host_os = @host_os@
+host_vendor = @host_vendor@
+htmldir = @htmldir@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+libdir = @libdir@
+libexecdir = @libexecdir@
+localedir = @localedir@
+localstatedir = @localstatedir@
+mandir = @mandir@
+mkdir_p = @mkdir_p@
+oldincludedir = @oldincludedir@
+pdfdir = @pdfdir@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+psdir = @psdir@
+sbindir = @sbindir@
+sharedstatedir = @sharedstatedir@
+srcdir = @srcdir@
+sysconfdir = @sysconfdir@
+target_alias = @target_alias@
+top_builddir = @top_builddir@
+top_srcdir = @top_srcdir@
+INCLUDES = \
+ -I${top_srcdir}/include
+
+AM_CFLAGS = $(XFONT_CFLAGS) $(OS_CFLAGS) $(CWARNFLAGS)
+noinst_LTLIBRARIES = libspeedo.la
+libspeedo_la_SOURCES = \
+ adobe-iso.h \
+ bics-iso.h \
+ bics-unicode.c \
+ bics-unicode.h \
+ do_char.c \
+ do_trns.c \
+ keys.h \
+ out_bl2d.c \
+ out_blk.c \
+ out_outl.c \
+ out_scrn.c \
+ out_util.c \
+ reset.c \
+ set_spcs.c \
+ set_trns.c \
+ spdo_prv.h \
+ speedo.h \
+ spencode.c \
+ sperr.c \
+ spfile.c \
+ spfont.c \
+ spfuncs.c \
+ spglyph.c \
+ spinfo.c \
+ spint.h \
+ useropt.h
+
+all: all-am
+
+.SUFFIXES:
+.SUFFIXES: .c .lo .o .obj
+$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps)
+ @for dep in $?; do \
+ case '$(am__configure_deps)' in \
+ *$$dep*) \
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh \
+ && exit 0; \
+ exit 1;; \
+ esac; \
+ done; \
+ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign src/Speedo/Makefile'; \
+ cd $(top_srcdir) && \
+ $(AUTOMAKE) --foreign src/Speedo/Makefile
+.PRECIOUS: Makefile
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+ @case '$?' in \
+ *config.status*) \
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
+ *) \
+ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
+ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
+ esac;
+
+$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+
+$(top_srcdir)/configure: $(am__configure_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(ACLOCAL_M4): $(am__aclocal_m4_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+
+clean-noinstLTLIBRARIES:
+ -test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES)
+ @list='$(noinst_LTLIBRARIES)'; for p in $$list; do \
+ dir="`echo $$p | sed -e 's|/[^/]*$$||'`"; \
+ test "$$dir" != "$$p" || dir=.; \
+ echo "rm -f \"$${dir}/so_locations\""; \
+ rm -f "$${dir}/so_locations"; \
+ done
+libspeedo.la: $(libspeedo_la_OBJECTS) $(libspeedo_la_DEPENDENCIES)
+ $(LINK) $(libspeedo_la_OBJECTS) $(libspeedo_la_LIBADD) $(LIBS)
+
+mostlyclean-compile:
+ -rm -f *.$(OBJEXT)
+
+distclean-compile:
+ -rm -f *.tab.c
+
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/bics-unicode.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/do_char.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/do_trns.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/out_bl2d.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/out_blk.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/out_outl.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/out_scrn.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/out_util.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/reset.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/set_spcs.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/set_trns.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/spencode.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sperr.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/spfile.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/spfont.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/spfuncs.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/spglyph.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/spinfo.Plo@am__quote@
+
+.c.o:
+@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
+@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(COMPILE) -c $<
+
+.c.obj:
+@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'`
+@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(COMPILE) -c `$(CYGPATH_W) '$<'`
+
+.c.lo:
+@am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
+@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(LTCOMPILE) -c -o $@ $<
+
+mostlyclean-libtool:
+ -rm -f *.lo
+
+clean-libtool:
+ -rm -rf .libs _libs
+
+ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) ' { files[$$0] = 1; } \
+ END { for (i in files) print i; }'`; \
+ mkid -fID $$unique
+tags: TAGS
+
+TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
+ $(TAGS_FILES) $(LISP)
+ tags=; \
+ here=`pwd`; \
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) ' { files[$$0] = 1; } \
+ END { for (i in files) print i; }'`; \
+ if test -z "$(ETAGS_ARGS)$$tags$$unique"; then :; else \
+ test -n "$$unique" || unique=$$empty_fix; \
+ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+ $$tags $$unique; \
+ fi
+ctags: CTAGS
+CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
+ $(TAGS_FILES) $(LISP)
+ tags=; \
+ here=`pwd`; \
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) ' { files[$$0] = 1; } \
+ END { for (i in files) print i; }'`; \
+ test -z "$(CTAGS_ARGS)$$tags$$unique" \
+ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
+ $$tags $$unique
+
+GTAGS:
+ here=`$(am__cd) $(top_builddir) && pwd` \
+ && cd $(top_srcdir) \
+ && gtags -i $(GTAGS_ARGS) $$here
+
+distclean-tags:
+ -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
+
+distdir: $(DISTFILES)
+ @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ list='$(DISTFILES)'; \
+ dist_files=`for file in $$list; do echo $$file; done | \
+ sed -e "s|^$$srcdirstrip/||;t" \
+ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
+ case $$dist_files in \
+ */*) $(MKDIR_P) `echo "$$dist_files" | \
+ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
+ sort -u` ;; \
+ esac; \
+ for file in $$dist_files; do \
+ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
+ if test -d $$d/$$file; then \
+ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
+ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
+ cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \
+ fi; \
+ cp -pR $$d/$$file $(distdir)$$dir || exit 1; \
+ else \
+ test -f $(distdir)/$$file \
+ || cp -p $$d/$$file $(distdir)/$$file \
+ || exit 1; \
+ fi; \
+ done
+check-am: all-am
+check: check-am
+all-am: Makefile $(LTLIBRARIES)
+installdirs:
+install: install-am
+install-exec: install-exec-am
+install-data: install-data-am
+uninstall: uninstall-am
+
+install-am: all-am
+ @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-am
+install-strip:
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ `test -z '$(STRIP)' || \
+ echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
+mostlyclean-generic:
+
+clean-generic:
+
+distclean-generic:
+ -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
+
+maintainer-clean-generic:
+ @echo "This command is intended for maintainers to use"
+ @echo "it deletes files that may require special tools to rebuild."
+clean: clean-am
+
+clean-am: clean-generic clean-libtool clean-noinstLTLIBRARIES \
+ mostlyclean-am
+
+distclean: distclean-am
+ -rm -rf ./$(DEPDIR)
+ -rm -f Makefile
+distclean-am: clean-am distclean-compile distclean-generic \
+ distclean-tags
+
+dvi: dvi-am
+
+dvi-am:
+
+html: html-am
+
+info: info-am
+
+info-am:
+
+install-data-am:
+
+install-dvi: install-dvi-am
+
+install-exec-am:
+
+install-html: install-html-am
+
+install-info: install-info-am
+
+install-man:
+
+install-pdf: install-pdf-am
+
+install-ps: install-ps-am
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-am
+ -rm -rf ./$(DEPDIR)
+ -rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-am
+
+mostlyclean-am: mostlyclean-compile mostlyclean-generic \
+ mostlyclean-libtool
+
+pdf: pdf-am
+
+pdf-am:
+
+ps: ps-am
+
+ps-am:
+
+uninstall-am:
+
+.MAKE: install-am install-strip
+
+.PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \
+ clean-libtool clean-noinstLTLIBRARIES ctags distclean \
+ distclean-compile distclean-generic distclean-libtool \
+ distclean-tags distdir dvi dvi-am html html-am info info-am \
+ install install-am install-data install-data-am install-dvi \
+ install-dvi-am install-exec install-exec-am install-html \
+ install-html-am install-info install-info-am install-man \
+ install-pdf install-pdf-am install-ps install-ps-am \
+ install-strip installcheck installcheck-am installdirs \
+ maintainer-clean maintainer-clean-generic mostlyclean \
+ mostlyclean-compile mostlyclean-generic mostlyclean-libtool \
+ pdf pdf-am ps ps-am tags uninstall uninstall-am
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/libXfont/src/Speedo/adobe-iso.h b/libXfont/src/Speedo/adobe-iso.h
new file mode 100644
index 000000000..e1eeef1c5
--- /dev/null
+++ b/libXfont/src/Speedo/adobe-iso.h
@@ -0,0 +1,200 @@
+/* $Xorg: adobe-iso.h,v 1.3 2000/08/17 19:46:24 cpqbld Exp $ */
+
+/*
+ * Latin 1 format from masterset format 11 (ps)
+ * 0 implies no valid mapping
+ */
+
+int adobe_map[] = {
+ 32, 32,
+ 33, 33,
+ 34, 34,
+ 35, 35,
+ 36, 36,
+ 37, 37,
+ 38, 38,
+ 39, 169,
+ 40, 40,
+ 41, 41,
+ 42, 42,
+ 43, 43,
+ 44, 44,
+ 45, 45,
+ 46, 46,
+ 47, 47,
+ 48, 48,
+ 49, 49,
+ 50, 50,
+ 51, 51,
+ 52, 52,
+ 53, 53,
+ 54, 54,
+ 55, 55,
+ 56, 56,
+ 57, 57,
+ 58, 58,
+ 59, 59,
+ 60, 60,
+ 61, 61,
+ 62, 62,
+ 63, 63,
+ 64, 64,
+ 65, 65,
+ 66, 66,
+ 67, 67,
+ 68, 68,
+ 69, 69,
+ 70, 70,
+ 71, 71,
+ 72, 72,
+ 73, 73,
+ 74, 74,
+ 75, 75,
+ 76, 76,
+ 77, 77,
+ 78, 78,
+ 79, 79,
+ 80, 80,
+ 81, 81,
+ 82, 82,
+ 83, 83,
+ 84, 84,
+ 85, 85,
+ 86, 86,
+ 87, 87,
+ 88, 88,
+ 89, 89,
+ 90, 90,
+ 91, 91,
+ 92, 92,
+ 93, 93,
+ 94, 195,
+ 95, 95,
+ 96, 193,
+ 97, 97,
+ 98, 98,
+ 99, 99,
+ 100, 100,
+ 101, 101,
+ 102, 102,
+ 103, 103,
+ 104, 104,
+ 105, 105,
+ 106, 106,
+ 107, 107,
+ 108, 108,
+ 109, 109,
+ 110, 110,
+ 111, 111,
+ 112, 112,
+ 113, 113,
+ 114, 114,
+ 115, 115,
+ 116, 116,
+ 117, 117,
+ 118, 118,
+ 119, 119,
+ 120, 120,
+ 121, 121,
+ 122, 122,
+ 123, 123,
+ 124, 124,
+ 125, 125,
+ 126, 196, /* lc tilde */
+ 127, 0, /* */
+ 161, 161, /* invert exclamation */
+ 162, 162, /* cent */
+ 163, 163, /* pound sterling */
+ 164, 168, /* intl currency */
+ 165, 165, /* yen */
+ 166, 320, /* split vert bar */
+ 167, 167, /* section mark */
+ 168, 200, /* dierisis */
+ 169, 0, /* superior copyright */
+ 170, 0, /* feminine ordinal */
+ 171, 171, /* dbl left guillemot */
+ 172, 314, /* math not */
+ 173, 0, /* hyphen ? */
+ 174, 0, /* superior registered */
+ 175, 0, /* overscore */
+ 176, 321, /* degree */
+ 177, 329, /* math +- */
+ 178, 333, /* superior 2 */
+ 179, 332, /* superior 3 */
+ 180, 194, /* lc acute */
+ 181, 324, /* greek lc mu */
+ 182, 182, /* Paragraph */
+ 183, 180, /* center dot */
+ 184, 203, /* cedilla lc */
+ 185, 328, /* superior 1 */
+ 186, 0, /* masculine ordinal(using superior o) */
+ 187, 187, /* right dbl guillemot */
+ 188, 327, /* 1/4 */
+ 189, 326, /* 1/2 */
+ 190, 331, /* 3/4 */
+ 191, 191, /* invert question */
+ 192, 259, /* A grave */
+ 193, 256, /* A acute */
+ 194, 257, /* A circumflex */
+ 195, 261, /* A tilde */
+ 196, 258, /* A dierisis */
+ 197, 260, /* A angstrom */
+ 198, 225, /* AE ligature */
+ 199, 262, /* C cedilla */
+ 200, 266, /* E grave */
+ 201, 263, /* E acute */
+ 202, 264, /* E circumflex */
+ 203, 265, /* E dierisis */
+ 204, 270, /* I grave */
+ 205, 267, /* I acute */
+ 206, 268, /* I circumflex */
+ 207, 269, /* I dierisis */
+ 208, 317, /* D bar */
+ 209, 271, /* N tilde */
+ 210, 275, /* O grave */
+ 211, 272, /* O acute */
+ 212, 273, /* O circumflex */
+ 213, 276, /* O tilde */
+ 214, 274, /* O dierisis */
+ 215, 325, /* math multiply */
+ 216, 233, /* O bar */
+ 217, 281, /* U grave */
+ 218, 278, /* U acute */
+ 219, 279, /* U circumflex */
+ 220, 280, /* U dierisis */
+ 221, 319, /* Y acute */
+ 222, 318, /* icelandic thorn lc */
+ 223, 251, /* German dbl s */
+ 224, 287, /* a grave */
+ 225, 284, /* a acute */
+ 226, 285, /* a circumflex */
+ 227, 289, /* a tilde */
+ 228, 286, /* a dierisis */
+ 229, 288, /* a angstrom */
+ 230, 241, /* ae ligature */
+ 231, 290, /* c cedilla */
+ 232, 294, /* e grave */
+ 233, 291, /* e acute */
+ 234, 292, /* e circumflex */
+ 235, 293, /* e dierisis */
+ 236, 298, /* i grave */
+ 237, 295, /* i acute */
+ 238, 296, /* i circumflex */
+ 239, 297, /* i dierisis */
+ 240, 323, /* icelandic eth lc */
+ 241, 299, /* n tilde */
+ 242, 303, /* o grave */
+ 243, 300, /* o acute */
+ 244, 301, /* o circumflex */
+ 245, 304, /* o tilde */
+ 246, 302, /* o dierisis */
+ 247, 322, /* math divide */
+ 248, 249, /* o bar */
+ 249, 309, /* u grave */
+ 250, 306, /* u acute */
+ 251, 307, /* u circumflex */
+ 252, 308, /* u dierisis */
+ 253, 334, /* y acute */
+ 254, 330, /* icelandic thorn uc */
+ 255, 310, /* y dierisis */
+};
diff --git a/libXfont/src/Speedo/bics-iso.h b/libXfont/src/Speedo/bics-iso.h
new file mode 100644
index 000000000..4964fa34e
--- /dev/null
+++ b/libXfont/src/Speedo/bics-iso.h
@@ -0,0 +1,224 @@
+/* $Xorg: bics-iso.h,v 1.4 2001/02/09 02:04:00 xorgcvs Exp $ */
+/*
+
+Copyright 1993, 1998 The Open Group
+
+Permission to use, copy, modify, distribute, and sell this software and its
+documentation for any purpose is hereby granted without fee, provided that
+the above copyright notice appear in all copies and that both that
+copyright notice and this permission notice appear in supporting
+documentation.
+
+The above copyright notice and this permission notice shall be included
+in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+IN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR
+OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of The Open Group shall
+not be used in advertising or otherwise to promote the sale, use or
+other dealings in this Software without prior written authorization
+from The Open Group.
+
+*/
+/* $XFree86: xc/lib/font/Speedo/bics-iso.h,v 1.6 2001/01/17 19:43:17 dawes Exp $ */
+
+int sp_bics_map[] = {
+ 32, 0,
+ 33, 1,
+ 34, 2,
+ 35, 3,
+ 36, 4,
+ 37, 5,
+ 38, 6,
+ 39, 264,
+ 40, 8,
+ 41, 9,
+ 42, 10,
+ 43, 11,
+ 44, 12,
+ 45, 13,
+ 46, 14,
+ 47, 15,
+ 48, 16,
+ 49, 17,
+ 50, 18,
+ 51, 19,
+ 52, 20,
+ 53, 21,
+ 54, 22,
+ 55, 23,
+ 56, 24,
+ 57, 25,
+ 58, 26,
+ 59, 27,
+ 60, 28,
+ 61, 29,
+ 62, 30,
+ 63, 31,
+ 64, 32,
+ 65, 33,
+ 66, 34,
+ 67, 35,
+ 68, 36,
+ 69, 37,
+ 70, 38,
+ 71, 39,
+ 72, 40,
+ 73, 41,
+ 74, 42,
+ 75, 43,
+ 76, 44,
+ 77, 45,
+ 78, 46,
+ 79, 47,
+ 80, 48,
+ 81, 49,
+ 82, 50,
+ 83, 51,
+ 84, 52,
+ 85, 53,
+ 86, 54,
+ 87, 55,
+ 88, 56,
+ 89, 57,
+ 90, 58,
+ 91, 59,
+ 92, 60,
+ 93, 61,
+ 94, 133,
+ 95, 63,
+ 96, 131,
+ 97, 65,
+ 98, 66,
+ 99, 67,
+ 100, 68,
+ 101, 69,
+ 102, 70,
+ 103, 71,
+ 104, 72,
+ 105, 73,
+ 106, 74,
+ 107, 75,
+ 108, 76,
+ 109, 77,
+ 110, 78,
+ 111, 79,
+ 112, 80,
+ 113, 81,
+ 114, 82,
+ 115, 83,
+ 116, 84,
+ 117, 85,
+ 118, 86,
+ 119, 87,
+ 120, 88,
+ 121, 89,
+ 122, 90,
+ 123, 91,
+ 124, 92,
+ 125, 93,
+ 126, 137,
+ 127, 358,
+ 161, 128,
+ 162, 98,
+ 163, 97,
+ 164, 278,
+ 165, 274,
+ 166, 277,
+ 167, 110,
+ 168, 135,
+ 169, 503,
+ 170, 538,
+ 171, 125,
+ 172, 309,
+ 173, 191,
+ 174, 504,
+ 175, 230,
+ 176, 339,
+ 177, 286,
+ 178, 160,
+ 179, 161,
+ 180, 129,
+ 181, 325,
+ 182, 279,
+ 183, 102,
+ 184, 141,
+ 185, 159,
+ 186, 544,
+ 187, 126,
+ 188, 151,
+ 189, 153,
+ 190, 155,
+ 191, 127,
+ 192, 259,
+ 193, 261,
+ 194, 257,
+ 195, 253,
+ 196, 255,
+ 197, 113,
+ 198, 114,
+ 199, 148,
+ 200, 249,
+ 201, 251,
+ 202, 247,
+ 203, 245,
+ 204, 239,
+ 205, 241,
+ 206, 237,
+ 207, 235,
+ 208, 169,
+ 209, 196,
+ 210, 202,
+ 211, 200,
+ 212, 204,
+ 213, 208,
+ 214, 206,
+ 215, 284,
+ 216, 115,
+ 217, 212,
+ 218, 210,
+ 219, 214,
+ 220, 216,
+ 221, 224,
+ 222, 271,
+ 223, 121,
+ 224, 260,
+ 225, 262,
+ 226, 258,
+ 227, 254,
+ 228, 256,
+ 229, 117,
+ 230, 118,
+ 231, 149,
+ 232, 250,
+ 233, 252,
+ 234, 248,
+ 235, 246,
+ 236, 240,
+ 237, 242,
+ 238, 238,
+ 239, 236,
+ 240, 273,
+ 241, 195,
+ 242, 201,
+ 243, 199,
+ 244, 203,
+ 245, 207,
+ 246, 205,
+ 247, 285,
+ 248, 119,
+ 249, 211,
+ 250, 209,
+ 251, 213,
+ 252, 215,
+ 253, 223,
+ 254, 272,
+ 255, 221,
+};
+
diff --git a/libXfont/src/Speedo/bics-unicode.c b/libXfont/src/Speedo/bics-unicode.c
new file mode 100644
index 000000000..735508268
--- /dev/null
+++ b/libXfont/src/Speedo/bics-unicode.c
@@ -0,0 +1,138 @@
+/*
+Copyright (c) 1998 by Juliusz Chroboczek
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
+*/
+
+/* $XFree86$ */
+
+/* These data are very dodgy. */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "bics-unicode.h"
+
+static short table_160[]=
+{0, 128, 98, 97, 278, 274, 277, 110, 135, 503, 538, 125, 309, 191, 504,
+ 230, 339, 286, 160, 161, 129, 325, 279, 102, 141, 159, 544, 126, 151,
+ 153, 155, 127, 259, 261, 257, 253, 255, 113, 114, 148, 249, 251, 247,
+ 245, 239, 241, 237, 235, 169, 196, 202, 200, 204, 208, 206, 284, 115,
+ 212, 210, 214, 216, 224, 271, 121, 260, 262, 258, 254, 256, 117, 118,
+ 149, 250, 252, 248, 246, 240, 242, 238, 236, 273, 195, 201, 199, 203,
+ 207, 205, 285, 119, 211, 209, 213, 215, 223, 272, 221, 477, 476, 374,
+ 373, 171, 177, 376, 375, -1, -1, -1, -1, 378, 377, 379, -1, 169, 173,
+ 383, 382, -1, -1, -1, -1, 172, 178, 243, 244, -1, -1, -1, -1, -1, -1,
+ 385, -1, -1, -1, -1, -1, 233, 234, 387, 386, -1, -1, 391, 390, 389,
+ 122, 276, 275, -1, -1, 393, 392, -1, 395, 394, 399, 398, -1, -1, -1,
+ -1, 170, 174, 194, 193, 402, 401, 198, 197, 263, -1, -1, -1, -1, -1,
+ -1, 404, 403, 116, 120, -1, -1, 408, 407, 406, 405, 410, 409, -1, -1,
+ 486, 485, 412, 411, 419, 418, 364, 363, -1, -1, 218, 217, 421, 420, -1,
+ -1, 220, 219, 423, 422, -1, 268, 425, 424, -1, -1, 222, 368, 367, 372,
+ 371, 370, 369};
+
+static short table_728[]={144, 181, 146, 731, 137, 183};
+
+static short table_915[]=
+{313, 314, -1, -1, -1, 315, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ 316, -1, -1, 317, -1, -1, 318, -1, -1, -1, -1, -1, -1, -1, 319, 320,
+ -1, 321, 322, -1, 323, 324, -1, -1, -1, 325, -1, -1, -1, 326, -1, -1,
+ 327, 328, -1, 329};
+
+static short table_8211[]=
+{111, 112, -1, -1, -1, -1, -1, 106, -1, 103, 105, 107, 104, 108, 109,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 100, -1, -1,
+ -1, -1, -1, -1, -1, -1, 123, 124, -1, 265};
+
+static short table_8319[]=
+{543, 475, 466, 467, 468, 469, 470, 471, 472, 473, 474, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, 491, -1, -1, -1, 266};
+
+static short table_8592[]={293, 295, 294, 292, 297, 296};
+
+static short table_8712[]=
+{298, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 492, -1, -1, -1, -1, -1,
+ -1, 302, -1, -1, -1, 303, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 299,
+ -1, -1, -1, -1, 428};
+
+
+static short table_8800[]={288, -1, -1, -1, 291, 290};
+
+static short table_9600[]=
+{304, -1, -1, -1, 305, -1, -1, -1, 308, -1, -1, -1, 306, -1, -1, -1,
+ 307, 357, 358, 359, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ 335, 336, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, 348, -1, -1, -1, 345, -1, -1, -1, -1, -1, 347, -1, -1, -1, 346,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 339, -1, -1, -1, 342, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, 344};
+
+static short table_9784[]={360, -1, 361, 362, -1, -1, -1, -1, 350, -1, 349};
+
+static short table_9824[]=
+{354, -1, -1, 352, -1, 351, 353, -1, -1, -1, 330, 331};
+
+static short table_64256[]={282, 95, 96, 281};
+
+int
+unicode_to_bics(unsigned code)
+{
+ if(code<32) return -1;
+ else if(code<127) return code-32;
+ else if(code<160) return -1;
+ else if(code<383) return table_160[code-160];
+ else if(code==402) return 99;
+ else if(code==486) return 480;
+ else if(code==487) return 379;
+ else if(code==501) return 384;
+ else if(code==711) return 139;
+ else if(code<728) return -1;
+ else if(code<734) return table_728[code-728];
+ else if(code<915) return -1;
+ else if(code<967) return table_915[code-915];
+ else if(code<8211) return -1;
+ else if(code<8253) return table_8211[code-8211];
+ else if(code<8319) return -1;
+ else if(code<8360) return table_8319[code-8319];
+ else if(code<8592) return -1;
+ else if(code<8598) return table_8592[code-8592];
+ else if(code==8616) return 340;
+ else if(code<8712) return -1;
+ else if(code<8751) return table_8712[code-8712];
+ else if(code<8800) return -1;
+ else if(code<8806) return table_8800[code-8800];
+ else if(code==8976) return 310;
+ else if(code==8992) return 300;
+ else if(code==8993) return 301;
+ else if(code==9400) return 332;
+ else if(code==9415) return 333;
+ else if(code==9473) return 355;
+ else if(code==9475) return 356;
+ else if(code<9600) return -1;
+ else if(code<9690) return table_9600[code-9600];
+ else if(code==9711) return 343;
+ else if(code<9784) return -1;
+ else if(code<9795) return table_9784[code-9784];
+ else if(code<9824) return -1;
+ else if(code<9836) return table_9824[code-9824];
+ else if(code<64256) return -1;
+ else if(code<64261) return table_64256[code-64256];
+ else return -1;
+}
+
diff --git a/libXfont/src/Speedo/bics-unicode.h b/libXfont/src/Speedo/bics-unicode.h
new file mode 100644
index 000000000..90fa1885b
--- /dev/null
+++ b/libXfont/src/Speedo/bics-unicode.h
@@ -0,0 +1,3 @@
+/* $XFree86$ */
+
+int unicode_to_bics(unsigned);
diff --git a/libXfont/src/Speedo/do_char.c b/libXfont/src/Speedo/do_char.c
new file mode 100644
index 000000000..076b41366
--- /dev/null
+++ b/libXfont/src/Speedo/do_char.c
@@ -0,0 +1,809 @@
+/* $Xorg: do_char.c,v 1.3 2000/08/17 19:46:24 cpqbld Exp $ */
+
+/*
+
+Copyright 1989-1991, Bitstream Inc., Cambridge, MA.
+You are hereby granted permission under all Bitstream propriety rights to
+use, copy, modify, sublicense, sell, and redistribute the Bitstream Speedo
+software and the Bitstream Charter outline font for any purpose and without
+restrictions; provided, that this notice is left intact on all copies of such
+software or font and that Bitstream's trademark is acknowledged as shown below
+on all unmodified copies of such font.
+
+BITSTREAM CHARTER is a registered trademark of Bitstream Inc.
+
+
+BITSTREAM INC. DISCLAIMS ANY AND ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING
+WITHOUT LIMITATION THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+PARTICULAR PURPOSE. BITSTREAM SHALL NOT BE LIABLE FOR ANY DIRECT OR INDIRECT
+DAMAGES, INCLUDING BUT NOT LIMITED TO LOST PROFITS, LOST DATA, OR ANY OTHER
+INCIDENTAL OR CONSEQUENTIAL DAMAGES, ARISING OUT OF OR IN ANY WAY CONNECTED
+WITH THE SPEEDO SOFTWARE OR THE BITSTREAM CHARTER OUTLINE FONT.
+
+*/
+/* $XFree86: xc/lib/font/Speedo/do_char.c,v 1.3 2001/01/17 19:43:17 dawes Exp $ */
+
+/***************************** D O - C H A R . C *****************************
+ * *
+ * This is the top level module for processing one simple or composite *
+ * character.
+ * *
+ ****************************************************************************/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "spdo_prv.h" /* General definitions for Speedo */
+
+#define DEBUG 0
+
+#if DEBUG
+#include <stdio.h>
+#define SHOW(X) printf("X = %d\n", X)
+#else
+#define SHOW(X)
+#endif
+
+/***** GLOBAL VARIABLES *****/
+
+/***** GLOBAL FUNCTIONS *****/
+
+/***** EXTERNAL VARIABLES *****/
+
+/***** EXTERNAL FUNCTIONS *****/
+
+/***** STATIC VARIABLES *****/
+
+/***** STATIC FUNCTIONS *****/
+
+static boolean sp_make_simp_char(PROTO_DECL2 ufix8 FONTFAR *pointer,ufix8 format);
+static boolean sp_make_comp_char(PROTO_DECL2 ufix8 FONTFAR *pointer);
+static ufix8 FONTFAR *sp_get_char_org(PROTO_DECL2 ufix16 char_index,boolean top_level);
+static fix15 sp_get_posn_arg(PROTO_DECL2 ufix8 FONTFAR *STACKFAR *ppointer,ufix8 format);
+static fix15 sp_get_scale_arg(PROTO_DECL2 ufix8 FONTFAR *STACKFAR *ppointer,ufix8 format);
+
+
+#if INCL_METRICS
+FUNCTION fix31 get_char_width(
+GDECL
+ufix16 char_index) /* Index to character in char directory */
+/*
+ * Returns character set width for specified character index in currently
+ * selected font in units of 1/65536 em.
+ * Reports Error 10 and returns 0 if no font selected.
+ * Reports Error 12 and returns 0 if character data not available.
+ */
+{
+ufix8 FONTFAR *pointer; /* Pointer to character data */
+fix31 set_width; /* Set width of character */
+
+if (!sp_globals.specs_valid) /* Font specs not defined? */
+ {
+ report_error(10); /* Report font not specified */
+ return (fix31)0; /* Return zero character width */
+ }
+
+pointer = sp_get_char_org(char_index, TRUE); /* Get pointer to character data */
+if (pointer == NULL) /* Character data not available? */
+ {
+ report_error(12); /* Report character data not avail */
+ return (fix31)0; /* Return zero character width */
+ }
+
+pointer += 2; /* Skip over character id */
+set_width = (fix31)NEXT_WORD(pointer); /* Read set width and Convert units */
+set_width = ((set_width << 16) + (sp_globals.metric_resolution >> 1)) / sp_globals.metric_resolution;
+return set_width; /* Return in 1/65536 em units */
+}
+#endif
+
+#if INCL_METRICS
+#ifdef old
+FUNCTION boolean get_char_bbox(
+GDECL
+ufix16 char_index,
+bbox_t *bbox)
+{
+/*
+ * returns true if character exists, false if it doesn't
+ * provides transformed character bounding box in 1/65536 pixels
+ * in the provided bbox_t structure. Bounding box may be
+ * conservative in the event that the transformation is not
+ * normal or the character is compound.
+ */
+
+ufix8 FONTFAR *pointer;
+fix15 tmp;
+point_t Pmin, Pmax;
+
+#if REENTRANT_ALLOC
+plaid_t plaid;
+sp_globals.plaid = &plaid;
+#endif
+
+if (!sp_globals.specs_valid) /* Font specs not defined? */
+ {
+ report_error(10); /* Report font not specified */
+ return FALSE; /* Error return */
+ }
+
+init_tcb(); /* Initialize transformation control block */
+
+pointer = sp_get_char_org(char_index, TRUE); /* Point to start of character data */
+if (pointer == NULL) /* Character data not available? */
+ {
+ report_error(12); /* Report character data not avail */
+ return FALSE; /* Error return */
+ }
+
+pointer += 2; /* Skip over character id */
+tmp = NEXT_WORD(pointer); /* Read set width */
+
+tmp = NEXT_BYTE(pointer);
+if (tmp & BIT1) /* Optional data in header? */
+ {
+ tmp = (ufix8)NEXT_BYTE(pointer); /* Read size of optional data */
+ pointer += tmp; /* Skip optional data */
+ }
+
+pointer = plaid_tcb(pointer, tmp); /* Process plaid data */
+pointer = read_bbox(pointer, &Pmin, &Pmax,(boolean)FALSE); /* Read bounding box */
+bbox->xmin = (fix31)Pmin.x << sp_globals.poshift;
+bbox->xmax = (fix31)Pmax.x << sp_globals.poshift;
+bbox->ymin = (fix31)Pmin.y << sp_globals.poshift;
+bbox->ymax = (fix31)Pmax.y << sp_globals.poshift;
+return TRUE;
+}
+
+#else /* new code, 4/25/91 */
+
+FUNCTION boolean get_char_bbox(
+GDECL
+ufix16 char_index,
+bbox_t *bbox)
+{
+/*
+ * returns true if character exists, false if it doesn't
+ * provides transformed character bounding box in 1/65536 pixels
+ * in the provided bbox_t structure. Bounding box may be
+ * conservative in the event that the transformation is not
+ * normal or the character is compound.
+ */
+
+ufix8 FONTFAR *pointer;
+fix15 tmp;
+fix15 format;
+ufix16 pix_adj;
+point_t Pmin, Pmax;
+
+#if REENTRANT_ALLOC
+plaid_t plaid;
+sp_globals.plaid = &plaid;
+#endif
+
+if (!sp_globals.specs_valid) /* Font specs not defined? */
+ {
+ report_error(10); /* Report font not specified */
+ return FALSE; /* Error return */
+ }
+
+init_tcb(); /* Initialize transformation control block */
+
+pointer = sp_get_char_org(char_index, TRUE); /* Point to start of character data */
+if (pointer == NULL) /* Character data not available? */
+ {
+ report_error(12); /* Report character data not avail */
+ return FALSE; /* Error return */
+ }
+
+pointer += 2; /* Skip over character id */
+tmp = NEXT_WORD(pointer); /* Read set width */
+
+format = NEXT_BYTE(pointer);
+if (format & BIT1) /* Optional data in header? */
+ {
+ tmp = (ufix8)NEXT_BYTE(pointer); /* Read size of optional data */
+ pointer += tmp; /* Skip optional data */
+ }
+
+if (format & BIT0)
+ {
+ pix_adj = sp_globals.onepix << 1; /* Allow 2 pixel expansion ... */
+ }
+else
+ {
+ pix_adj = 0;
+ }
+
+pointer = plaid_tcb(pointer, format); /* Process plaid data */
+pointer = read_bbox(pointer, &Pmin, &Pmax,(boolean)FALSE); /* Read bounding box */
+
+Pmin.x -= pix_adj; /* ... of components of ... */
+Pmin.y -= pix_adj; /* ... compound ... */
+Pmax.x += pix_adj; /* ... character ... */
+Pmax.y += pix_adj; /* ... bounding box. */
+
+
+bbox->xmin = (fix31)Pmin.x << sp_globals.poshift;
+bbox->xmax = (fix31)Pmax.x << sp_globals.poshift;
+bbox->ymin = (fix31)Pmin.y << sp_globals.poshift;
+bbox->ymax = (fix31)Pmax.y << sp_globals.poshift;
+return TRUE;
+}
+#endif /* new code */
+
+#endif
+
+
+#if INCL_ISW
+FUNCTION boolean make_char_isw(
+GDECL
+ufix16 char_index,
+ufix32 imported_setwidth)
+{
+fix15 xmin; /* Minimum X ORU value in font */
+fix15 xmax; /* Maximum X ORU value in font */
+fix15 ymin; /* Minimum Y ORU value in font */
+fix15 ymax; /* Maximum Y ORU value in font */
+ufix16 return_value;
+
+sp_globals.import_setwidth_act = TRUE;
+/* convert imported width to orus */
+sp_globals.imported_width = (sp_globals.metric_resolution *
+ imported_setwidth) >> 16;
+return_value = do_make_char(char_index);
+
+if (sp_globals.isw_modified_constants)
+ {
+ /* reset fixed point constants */
+ xmin = read_word_u(sp_globals.font_org + FH_FXMIN);
+ ymin = read_word_u(sp_globals.font_org + FH_FYMIN);
+ ymax = read_word_u(sp_globals.font_org + FH_FYMAX);
+ sp_globals.constr.data_valid = FALSE;
+ xmax = read_word_u(sp_globals.font_org + FH_FXMAX);
+ if (!setup_consts(xmin,xmax,ymin,ymax))
+ {
+ report_error(3); /* Requested specs out of range */
+ return FALSE;
+ }
+ }
+return (return_value);
+}
+
+FUNCTION boolean make_char(
+GDECL
+ufix16 char_index) /* Index to character in char directory */
+{
+sp_globals.import_setwidth_act = FALSE;
+return (do_make_char(char_index));
+}
+
+FUNCTION static boolean do_make_char(GDECL ufix16 char_index)
+#else
+FUNCTION boolean make_char(GDECL ufix16 char_index)
+#endif
+/*
+ * Outputs specified character using the currently selected font and
+ * scaling and output specifications.
+ * Reports Error 10 and returns FALSE if no font specifications
+ * previously set.
+ * Reports Error 12 and returns FALSE if character data not available.
+ */
+{
+ufix8 FONTFAR *pointer; /* Pointer to character data */
+fix15 x_orus;
+fix15 tmpfix15;
+ufix8 format;
+
+#if INCL_ISW
+sp_globals.isw_modified_constants = FALSE;
+#endif
+
+#if REENTRANT_ALLOC
+
+plaid_t plaid;
+
+#if INCL_BLACK || INCL_SCREEN || INCL_2D
+intercepts_t intercepts;
+sp_globals.intercepts = &intercepts;
+#endif
+
+sp_globals.plaid = &plaid;
+#endif
+
+if (!sp_globals.specs_valid) /* Font specs not defined? */
+ {
+ report_error(10); /* Report font not specified */
+ return FALSE; /* Error return */
+ }
+
+#if INCL_MULTIDEV
+#if INCL_OUTLINE
+if (sp_globals.output_mode == MODE_OUTLINE && !sp_globals.outline_device_set)
+ {
+ report_error(2);
+ return FALSE;
+ }
+else
+#endif
+ if (!sp_globals.bitmap_device_set)
+ {
+ report_error(2);
+ return FALSE;
+ }
+#endif
+
+
+init_tcb(); /* Initialize transformation control block */
+
+pointer = sp_get_char_org(char_index, TRUE); /* Point to start of character data */
+SHOW(pointer);
+if (pointer == NULL) /* Character data not available? */
+ {
+ report_error(12); /* Report character data not avail */
+ return FALSE; /* Error return */
+ }
+
+pointer += 2; /* Skip over character id */
+x_orus = NEXT_WORD(pointer); /* Read set width */
+#if INCL_SQUEEZING || INCL_ISW
+sp_globals.setwidth_orus = x_orus;
+#endif
+
+#if INCL_ISW
+if (sp_globals.import_setwidth_act)
+ x_orus = sp_globals.imported_width;
+#endif
+sp_globals.Psw.x = (fix15)((fix31)
+ (((fix31)x_orus * (sp_globals.specs.xxmult>>16) +
+ ( ((fix31)x_orus * (sp_globals.specs.xxmult&0xffffL) )>>16)
+ ) << sp_globals.pixshift) / sp_globals.metric_resolution);
+
+sp_globals.Psw.y = (fix15)(
+ (fix31)(
+ ((fix31)x_orus * (sp_globals.specs.yxmult>>16) +
+ ( ((fix31)x_orus * (sp_globals.specs.yxmult&0xffffL) )>>16)
+ ) << sp_globals.pixshift) / sp_globals.metric_resolution);
+
+format = NEXT_BYTE(pointer);
+if (format & BIT1) /* Optional data in header? */
+ {
+ tmpfix15 = (ufix8)NEXT_BYTE(pointer); /* Read size of optional data */
+ pointer += tmpfix15; /* Skip optional data */
+ }
+if (format & BIT0)
+ {
+ return sp_make_comp_char(pointer); /* Output compound character */
+ }
+else
+ {
+ return sp_make_simp_char(pointer, format); /* Output simple character */
+ }
+}
+
+FUNCTION static boolean sp_make_simp_char(
+GDECL
+ufix8 FONTFAR *pointer, /* Pointer to first byte of position argument */
+ufix8 format) /* Character format byte */
+/*
+ * Called by sp_make_char() to output a simple (non-compound) character.
+ * Returns TRUE on completion.
+ */
+{
+point_t Pmin, Pmax; /* Transformed corners of bounding box */
+#if INCL_SQUEEZING || INCL_ISW
+ufix8 FONTFAR *save_pointer;
+#endif
+#if INCL_ISW
+fix31 char_width;
+fix31 isw_scale;
+#endif
+
+#if INCL_SQUEEZING
+sp_globals.squeezing_compound = FALSE;
+if ((sp_globals.pspecs->flags & SQUEEZE_LEFT) ||
+ (sp_globals.pspecs->flags & SQUEEZE_RIGHT) ||
+ (sp_globals.pspecs->flags & SQUEEZE_TOP) ||
+ (sp_globals.pspecs->flags & SQUEEZE_BOTTOM) )
+ {
+ /* get the bounding box data before processing the character */
+ save_pointer = pointer;
+ preview_bounding_box (pointer, format);
+ pointer = save_pointer;
+ }
+#endif
+#if (INCL_ISW)
+if (sp_globals.import_setwidth_act)
+ {
+ save_pointer = pointer;
+ preview_bounding_box (pointer, format);
+ pointer = save_pointer;
+ /* make sure I'm not going to get fixed point overflow */
+ isw_scale = compute_isw_scale();
+ if (sp_globals.bbox_xmin_orus < 0)
+ char_width = SQUEEZE_MULT((sp_globals.bbox_xmax_orus - sp_globals.bbox_xmin_orus), isw_scale);
+ else
+ char_width = SQUEEZE_MULT(sp_globals.bbox_xmax_orus, isw_scale);
+ if (char_width >= sp_globals.isw_xmax)
+ if (!reset_xmax(char_width))
+ return FALSE;
+ }
+#endif
+pointer = plaid_tcb(pointer, format); /* Process plaid data */
+pointer = read_bbox(pointer, &Pmin, &Pmax, FALSE); /* Read bounding box */
+if (fn_begin_char(sp_globals.Psw, Pmin, Pmax)) /* Signal start of character output */
+ {
+ do
+ {
+ proc_outl_data(pointer); /* Process outline data */
+ }
+ while (!fn_end_char()); /* Repeat if not done */
+ }
+return TRUE;
+}
+
+FUNCTION static boolean sp_make_comp_char(
+GDECL
+ufix8 FONTFAR *pointer) /* Pointer to first byte of position argument */
+/*
+ * Called by sp_make_char() to output a compound character.
+ * Returns FALSE if data for any sub-character is not available.
+ * Returns TRUE if output completed with no error.
+ */
+{
+point_t Pmin, Pmax; /* Transformed corners of bounding box */
+point_t Pssw; /* Transformed escapement vector */
+ufix8 FONTFAR *pointer_sav; /* Saved pointer to compound character data */
+ufix8 FONTFAR *sub_pointer; /* Pointer to sub-character data */
+ufix8 format; /* Format of DOCH instruction */
+ufix16 sub_char_index; /* Index to sub-character in character directory */
+fix15 x_posn; /* X position of sub-character (outline res units) */
+fix15 y_posn; /* Y position of sub-character (outline res units) */
+fix15 x_scale; /* X scale factor of sub-character (scale units) */
+fix15 y_scale; /* Y scale factor of sub-character (scale units) */
+fix15 tmpfix15; /* Temporary workspace */
+fix15 x_orus; /* Set width in outline resolution units */
+fix15 pix_adj; /* Pixel adjustment to compound char bounding box */
+#if INCL_SQUEEZING
+fix31 x_factor, x_offset, top_scale, bottom_scale;
+boolean squeezed_x, squeezed_y;
+#endif
+#if INCL_SQUEEZING || INCL_ISW
+fix15 x_offset_pix;
+#endif
+#if INCL_ISW
+fix31 char_width;
+fix31 isw_scale;
+#endif
+
+
+#if INCL_SQUEEZING
+sp_globals.squeezing_compound = TRUE;
+#endif
+pointer = read_bbox(pointer, &Pmin, &Pmax, TRUE); /* Read bounding box data */
+pix_adj = sp_globals.onepix << 1; /* Allow 2 pixel expansion ... */
+Pmin.x -= pix_adj; /* ... of components of ... */
+Pmin.y -= pix_adj; /* ... compound ... */
+Pmax.x += pix_adj; /* ... character ... */
+Pmax.y += pix_adj; /* ... bounding box. */
+
+#if INCL_SQUEEZING
+/* scale the bounding box if necessary before calling begin_char */
+squeezed_x = calculate_x_scale(&x_factor, &x_offset, 0);
+squeezed_y = calculate_y_scale(&top_scale, &bottom_scale,0,0);
+
+if (squeezed_x)
+ { /* scale the x coordinates of the bbox */
+ x_offset_pix = (fix15)(((x_offset >> 16) * sp_globals.tcb0.xppo)
+ >> sp_globals.mpshift);
+ if ((x_offset_pix >0) && (x_offset_pix < sp_globals.onepix))
+ x_offset_pix = sp_globals.onepix;
+ Pmin.x = SQUEEZE_MULT (x_factor, Pmin.x) + x_offset_pix - pix_adj;
+ Pmax.x = SQUEEZE_MULT (x_factor, Pmax.x) + x_offset_pix + pix_adj;
+ }
+if (squeezed_y)
+ { /* scale the y coordinates of the bbox */
+ if ((Pmin.y) < 0)
+ Pmin.y = SQUEEZE_MULT (bottom_scale, Pmin.y) - pix_adj;
+ else
+ Pmin.y = SQUEEZE_MULT (top_scale, Pmin.y) - pix_adj;
+ if ((Pmax.y) < 0)
+ Pmax.y = SQUEEZE_MULT (bottom_scale, Pmax.y) + pix_adj;
+ else
+ Pmax.y = SQUEEZE_MULT (top_scale, Pmax.y) + pix_adj;
+ }
+#endif
+#if (INCL_ISW)
+if (sp_globals.import_setwidth_act)
+ {
+ /* make sure I'm not going to get fixed point overflow */
+ isw_scale = ((fix31)sp_globals.imported_width << 16)/
+ (fix31)sp_globals.setwidth_orus;
+ char_width = SQUEEZE_MULT((sp_globals.bbox_xmax_orus -
+ sp_globals.bbox_xmin_orus),
+isw_scale);
+ if (char_width >= sp_globals.isw_xmax)
+ if (!reset_xmax(char_width))
+ return FALSE;
+ }
+#endif
+
+if (fn_begin_char(sp_globals.Psw, Pmin, Pmax)) /* Signal start of character data */
+ {
+ pointer_sav = pointer;
+ do
+ {
+ pointer = pointer_sav; /* Point to next DOCH or END instruction */
+ while ((format = NEXT_BYTE(pointer))) /* DOCH instruction? */
+ {
+ init_tcb(); /* Initialize transformation control block */
+ x_posn = sp_get_posn_arg(&pointer, format);
+ y_posn = sp_get_posn_arg(&pointer, (ufix8)(format >> 2));
+ x_scale = sp_get_scale_arg(&pointer, (ufix8)(format & BIT4));
+ y_scale = sp_get_scale_arg(&pointer, (ufix8)(format & BIT5));
+ scale_tcb(&sp_globals.tcb, x_posn, y_posn, x_scale, y_scale); /* Scale for sub-char */
+ sub_char_index = (format & BIT6)? /* Read sub-char index */
+ 0xffff & NEXT_WORD(pointer):
+ 0xffff & NEXT_BYTE(pointer);
+ sub_pointer = sp_get_char_org(sub_char_index, FALSE); /* Point to start of sub-char */
+ if (sub_pointer == NULL) /* Character data not available? */
+ {
+ return FALSE; /* Abort character output */
+ }
+ sub_pointer += 2; /* Skip over character id */
+ x_orus = NEXT_WORD(sub_pointer); /* Read set_width of sub-character */
+
+ Pssw.x = (fix15)(
+ (fix31)(
+ ((fix31)x_orus * (sp_globals.specs.xxmult>>16) +
+ ( ((fix31)x_orus * (sp_globals.specs.xxmult&0xffffL) )>>16)
+ ) << sp_globals.pixshift) / sp_globals.metric_resolution);
+ Pssw.y = (fix15)(
+ (fix31)(
+ ((fix31)x_orus * (sp_globals.specs.yxmult>>16) +
+ ( ((fix31)x_orus * (sp_globals.specs.yxmult&0xffffL) )>>16)
+ ) << sp_globals.pixshift) / sp_globals.metric_resolution);
+
+ format = NEXT_BYTE(sub_pointer); /* Read sub-character format */
+ if (format & BIT1) /* Optional data in header? */
+ {
+ tmpfix15 = (ufix8)NEXT_BYTE(sub_pointer); /* Read size of optional data */
+ sub_pointer += tmpfix15; /* Skip optional data */
+ }
+ sub_pointer = plaid_tcb(sub_pointer, format); /* Process sub-character plaid data */
+ sub_pointer = read_bbox(sub_pointer, &Pmin, &Pmax, FALSE); /* Read bounding box */
+ fn_begin_sub_char(Pssw, Pmin, Pmax); /* Signal start of sub-character data */
+ proc_outl_data(sub_pointer); /* Process sub-character data */
+ fn_end_sub_char(); /* Signal end of sub-character data */
+ }
+ }
+ while (!fn_end_char()); /* Signal end of character; repeat if required */
+ }
+return TRUE;
+}
+
+#if INCL_LCD /* Dynamic load character data supported? */
+FUNCTION static ufix8 FONTFAR *sp_get_char_org(
+GDECL
+ufix16 char_index, /* Index of character to be accessed */
+boolean top_level) /* Not a compound character element */
+/*
+ * Called by sp_get_char_id(), sp_get_char_width(), sp_make_char() and
+ * sp_make_comp_char() to get a pointer to the start of the character data
+ * for the specified character index.
+ * Version for configuration supporting dynamic character data loading.
+ * Calls load_char_data() to load character data if not already loaded
+ * as part of the original font buffer.
+ * Returns NULL if character data not available
+ */
+{
+buff_t *pchar_data; /* Buffer descriptor requested */
+ufix8 FONTFAR *pointer; /* Pointer into character directory */
+ufix8 format; /* Character directory format byte */
+fix31 char_offset; /* Offset of char data from start of font file */
+fix31 next_char_offset; /* Offset of char data from start of font file */
+fix15 no_bytes; /* Number of bytes required for char data */
+
+if (top_level) /* Not element of compound char? */
+ {
+ if (char_index < sp_globals.first_char_idx) /* Before start of character set? */
+ return NULL;
+ char_index -= sp_globals.first_char_idx;
+ if (char_index >= sp_globals.no_chars_avail) /* Beyond end of character set? */
+ return NULL;
+ sp_globals.cb_offset = 0; /* Reset char buffer offset */
+ }
+
+pointer = sp_globals.pchar_dir;
+format = NEXT_BYTE(pointer); /* Read character directory format byte */
+pointer += char_index << 1; /* Point to indexed character entry */
+if (format) /* 3-byte entries in char directory? */
+ {
+ pointer += char_index; /* Adjust for 3-byte entries */
+ char_offset = read_long(pointer); /* Read file offset to char data */
+ next_char_offset = read_long(pointer + 3); /* Read offset to next char */
+ }
+else
+ {
+ char_offset = (fix31)(0xffff & NEXT_WORD(pointer)); /* Read file offset to char data */
+ next_char_offset = (fix31)(0xffff & NEXT_WORD(pointer)); /* Read offset to next char */
+ }
+
+no_bytes = next_char_offset - char_offset;
+if (no_bytes == 0) /* Character not in directory? */
+ return NULL;
+
+if (next_char_offset <= sp_globals.font_buff_size)/* Character data already in font buffer? */
+ return sp_globals.pfont->org + char_offset; /* Return pointer into font buffer */
+
+pchar_data = load_char_data(char_offset, no_bytes, sp_globals.cb_offset); /* Request char data load */
+if (pchar_data->no_bytes < no_bytes) /* Correct number of bytes loaded? */
+ return NULL;
+
+if (top_level) /* Not element of compound char? */
+ {
+ sp_globals.cb_offset = no_bytes;
+ }
+
+return pchar_data->org; /* Return pointer into character data buffer */
+}
+#endif
+
+#if INCL_LCD
+#else /* Dynamic load character data not supported? */
+FUNCTION static ufix8 FONTFAR *sp_get_char_org(
+GDECL
+ufix16 char_index, /* Index of character to be accessed */
+boolean top_level) /* Not a compound character element */
+/*
+ * Called by sp_get_char_id(), sp_get_char_width(), sp_make_char() and
+ * sp_make_comp_char() to get a pointer to the start of the character data
+ * for the specified character index.
+ * Version for configuration not supporting dynamic character data loading.
+ * Returns NULL if character data not available
+ */
+{
+ufix8 FONTFAR *pointer; /* Pointer into character directory */
+ufix8 format; /* Character directory format byte */
+fix31 char_offset; /* Offset of char data from start of font file */
+fix31 next_char_offset; /* Offset of char data from start of font file */
+fix15 no_bytes; /* Number of bytes required for char data */
+
+if (top_level) /* Not element of compound char? */
+ {
+ if (char_index < sp_globals.first_char_idx) /* Before start of character set? */
+ return NULL;
+ char_index -= sp_globals.first_char_idx;
+ if (char_index >= sp_globals.no_chars_avail) /* Beyond end of character set? */
+ return NULL;
+ }
+
+pointer = sp_globals.pchar_dir;
+format = NEXT_BYTE(pointer); /* Read character directory format byte */
+pointer += char_index << 1; /* Point to indexed character entry */
+if (format) /* 3-byte entries in char directory? */
+ {
+ pointer += char_index; /* Adjust for 3-byte entries */
+ char_offset = read_long(pointer); /* Read file offset to char data */
+ next_char_offset = read_long(pointer + 3); /* Read offset to next char */
+ }
+else
+ {
+ char_offset = (fix31)(0xffff & NEXT_WORD(pointer)); /* Read file offset to char data */
+ next_char_offset = (fix31)(0xffff & NEXT_WORD(pointer)); /* Read offset to next char */
+ }
+
+no_bytes = next_char_offset - char_offset;
+if (no_bytes == 0) /* Character not in directory? */
+ return NULL;
+
+return sp_globals.pfont->org + char_offset; /* Return pointer into font buffer */
+}
+#endif
+
+
+FUNCTION static fix15 sp_get_posn_arg(
+GDECL
+ufix8 FONTFAR * STACKFAR *ppointer, /* Pointer to first byte of position argument */
+ufix8 format) /* Format of DOCH arguments */
+/*
+ * Called by sp_make_comp_char() to read a position argument from the
+ * specified point in the font/char buffer.
+ * Updates pointer to byte following position argument.
+ * Returns value of position argument in outline resolution units
+ */
+{
+switch (format & 0x03)
+ {
+case 1:
+ return NEXT_WORD(*ppointer);
+
+case 2:
+ return (fix15)((fix7)NEXT_BYTE(*ppointer));
+
+default:
+ return (fix15)0;
+ }
+}
+
+FUNCTION static fix15 sp_get_scale_arg(
+GDECL
+ufix8 FONTFAR *STACKFAR *ppointer, /* Pointer to first byte of position argument */
+ufix8 format) /* Format of DOCH arguments */
+/*
+ * Called by sp_make_comp_char() to read a scale argument from the
+ * specified point in the font/char buffer.
+ * Updates pointer to byte following scale argument.
+ * Returns value of scale argument in scale units (normally 1/4096)
+ */
+{
+if (format)
+ return NEXT_WORD(*ppointer);
+else
+ return (fix15)ONE_SCALE;
+}
+#if INCL_ISW || INCL_SQUEEZING
+FUNCTION static void preview_bounding_box(
+GDECL
+ufix8 FONTFAR *pointer, /* Pointer to first byte of position argument */
+ufix8 format) /* Character format byte */
+{
+point_t Pmin, Pmax; /* Transformed corners of bounding box */
+
+ sp_globals.no_X_orus = (format & BIT2)?
+ (fix15)NEXT_BYTE(pointer):
+ 0;
+ sp_globals.no_Y_orus = (format & BIT3)?
+ (fix15)NEXT_BYTE(pointer):
+ 0;
+ pointer = read_oru_table(pointer);
+
+ /* Skip over control zone table */
+ pointer = skip_control_zone(pointer,format);
+
+ /* Skip over interpolation table */
+ pointer = skip_interpolation_table(pointer,format);
+ /* get_args has a pathological need for this value to be set */
+ sp_globals.Y_edge_org = sp_globals.no_X_orus;
+ pointer = read_bbox(pointer, &Pmin, &Pmax, TRUE); /* Read bounding bo
+x */
+
+}
+#endif
+#if INCL_ISW
+FUNCTION static boolean reset_xmax(
+GDECL
+fix31 xmax)
+
+{
+fix15 xmin; /* Minimum X ORU value in font */
+fix15 ymin; /* Minimum Y ORU value in font */
+fix15 ymax; /* Maximum Y ORU value in font */
+
+
+sp_globals.isw_modified_constants = TRUE;
+xmin = read_word_u(sp_globals.font_org + FH_FXMIN);
+ymin = read_word_u(sp_globals.font_org + FH_FYMIN);
+ymax = read_word_u(sp_globals.font_org + FH_FYMAX);
+
+if (!setup_consts(xmin,xmax,ymin,ymax))
+ {
+ report_error(3); /* Requested specs out of range */
+ return FALSE;
+ }
+sp_globals.constr.data_valid = FALSE;
+/* recompute setwidth */
+sp_globals.Psw.x = (fix15)((fix31)(
+ ((fix31)sp_globals.imported_width * (sp_globals.specs.xxmult>>16) +
+ ( ((fix31)sp_globals.imported_width *
+ (sp_globals.specs.xxmult&0xffffL) )>>16)
+ ) << sp_globals.pixshift) / sp_globals.metric_resolution);
+sp_globals.Psw.y = (fix15)(
+ (fix31)(
+ ((fix31)sp_globals.imported_width * (sp_globals.specs.yxmult>>16) +
+ ( ((fix31)sp_globals.imported_width * (sp_globals.specs.yxmult&0xffffL) )>>16)
+ ) << sp_globals.pixshift) / sp_globals.metric_resolution);
+
+return TRUE;
+}
+#endif
diff --git a/libXfont/src/Speedo/do_trns.c b/libXfont/src/Speedo/do_trns.c
new file mode 100644
index 000000000..95ab102df
--- /dev/null
+++ b/libXfont/src/Speedo/do_trns.c
@@ -0,0 +1,498 @@
+/* $Xorg: do_trns.c,v 1.3 2000/08/17 19:46:25 cpqbld Exp $ */
+
+/*
+
+Copyright 1989-1991, Bitstream Inc., Cambridge, MA.
+You are hereby granted permission under all Bitstream propriety rights to
+use, copy, modify, sublicense, sell, and redistribute the Bitstream Speedo
+software and the Bitstream Charter outline font for any purpose and without
+restrictions; provided, that this notice is left intact on all copies of such
+software or font and that Bitstream's trademark is acknowledged as shown below
+on all unmodified copies of such font.
+
+BITSTREAM CHARTER is a registered trademark of Bitstream Inc.
+
+
+BITSTREAM INC. DISCLAIMS ANY AND ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING
+WITHOUT LIMITATION THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+PARTICULAR PURPOSE. BITSTREAM SHALL NOT BE LIABLE FOR ANY DIRECT OR INDIRECT
+DAMAGES, INCLUDING BUT NOT LIMITED TO LOST PROFITS, LOST DATA, OR ANY OTHER
+INCIDENTAL OR CONSEQUENTIAL DAMAGES, ARISING OUT OF OR IN ANY WAY CONNECTED
+WITH THE SPEEDO SOFTWARE OR THE BITSTREAM CHARTER OUTLINE FONT.
+
+*/
+/* $XFree86: xc/lib/font/Speedo/do_trns.c,v 1.3 2001/01/17 19:43:17 dawes Exp $ */
+
+/**************************** D O _ T R N S . C ******************************
+ * *
+ * This module is responsible for executing all intelligent transformation *
+ * for bounding box and outline data *
+ * *
+ ****************************************************************************/
+
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "spdo_prv.h" /* General definitions for Speedo */
+
+#define DEBUG 0
+
+#if DEBUG
+#include <stdio.h>
+#define SHOW(X) printf("X = %d\n", X)
+#else
+#define SHOW(X)
+#endif
+
+/***** GLOBAL VARIABLES *****/
+
+/***** GLOBAL FUNCTIONS *****/
+
+/***** EXTERNAL VARIABLES *****/
+
+/***** EXTERNAL FUNCTIONS *****/
+
+/***** STATIC VARIABLES *****/
+
+/***** STATIC FUNCTIONS *****/
+
+static void sp_split_curve(PROTO_DECL2 point_t P1,point_t P2,point_t P3,fix15 depth);
+static ufix8 FONTFAR *sp_get_args(PROTO_DECL2 ufix8 FONTFAR *pointer,ufix8 format,point_t STACKFAR *pP);
+
+
+FUNCTION ufix8 FONTFAR *read_bbox(
+GDECL
+ufix8 FONTFAR *pointer, /* Pointer to next byte in char data */
+point_t STACKFAR *pPmin, /* Lower left corner of bounding box */
+point_t STACKFAR *pPmax, /* Upper right corner of bounding box */
+boolean set_flag) /* flag to indicate whether global oru bbox should be saved */
+/*
+ * Called by make_simp_char() and make_comp_char() to read the
+ * bounding box data from the font.
+ * Sets Pmin and Pmax to the bottom left and top right corners
+ * of the bounding box after transformation into device space.
+ * The units of Pmin and Pmax are sub-pixels.
+ * Updates *ppointer to point to the byte following the
+ * bounding box data.
+ */
+{
+ufix8 format1;
+ufix8 format = 0;
+fix15 i;
+point_t P;
+
+sp_globals.x_int = 0;
+sp_globals.y_int = sp_globals.Y_int_org;
+sp_globals.x_orus = sp_globals.y_orus = 0;
+format1 = NEXT_BYTE(pointer);
+pointer = sp_get_args(pointer, format1, pPmin);
+#if INCL_SQUEEZING || INCL_ISW
+if (set_flag)
+ {
+ sp_globals.bbox_xmin_orus = sp_globals.x_orus;
+ sp_globals.bbox_ymin_orus = sp_globals.y_orus;
+ }
+#endif
+*pPmax = *pPmin;
+for (i = 1; i < 4; i++)
+ {
+ switch(i)
+ {
+ case 1:
+ if (format1 & BIT6) /* Xmax requires X int zone 1? */
+ sp_globals.x_int++;
+ format = (format1 >> 4) | 0x0c;
+ break;
+
+ case 2:
+ if (format1 & BIT7) /* Ymax requires Y int zone 1? */
+ sp_globals.y_int++;
+ format = NEXT_BYTE(pointer);
+ break;
+
+ case 3:
+ sp_globals.x_int = 0;
+ format >>= 4;
+ break;
+
+ default:
+ break;
+ }
+
+ pointer = sp_get_args(pointer, format, &P);
+#if INCL_SQUEEZING || INCL_ISW
+ if (set_flag && (i==2))
+ {
+ sp_globals.bbox_xmax_orus = sp_globals.x_orus;
+ sp_globals.bbox_ymax_orus = sp_globals.y_orus;
+ }
+#endif
+ if ((i == 2) || (!sp_globals.normal))
+ {
+ if (P.x < pPmin->x)
+ pPmin->x = P.x;
+ if (P.y < pPmin->y)
+ pPmin->y = P.y;
+ if (P.x > pPmax->x)
+ pPmax->x = P.x;
+ if (P.y > pPmax->y)
+ pPmax->y = P.y;
+ }
+ }
+
+#if DEBUG
+printf("BBOX %6.1f(Xint 0), %6.1f(Yint 0), %6.1f(Xint %d), %6.1f(Yint %d)\n",
+ (real)pPmin->x / (real)sp_globals.onepix,
+ (real)pPmin->y / (real)sp_globals.onepix,
+ (real)pPmax->x / (real)sp_globals.onepix,
+ (format1 >> 6) & 0x01,
+ (real)pPmax->y / (real)sp_globals.onepix,
+ (format1 >> 7) & 0x01);
+
+#endif
+return pointer;
+}
+
+FUNCTION void proc_outl_data(
+GDECL
+ufix8 FONTFAR *pointer) /* Pointer to next byte in char data */
+/*
+ * Called by make_simp_char() and make_comp_char() to read the
+ * outline data from the font.
+ * The outline data is parsed, transformed into device coordinates
+ * and passed to an output module for further processing.
+ * Note that pointer is not updated to facilitate repeated
+ * processing of the outline data when banding mode is in effect.
+ */
+{
+ufix8 format1, format2;
+point_t P0, P1, P2, P3;
+fix15 depth;
+fix15 curve_count;
+
+sp_globals.x_int = 0;
+sp_globals.y_int = sp_globals.Y_int_org;
+#if INCL_PLAID_OUT /* Plaid data monitoring included? */
+record_xint((fix15)sp_globals.x_int); /* Record xint data */
+record_yint((fix15)(sp_globals.y_int - sp_globals.Y_int_org)); /* Record yint data */
+#endif
+
+sp_globals.x_orus = sp_globals.y_orus = 0;
+curve_count = 0;
+while(TRUE)
+ {
+ format1 = NEXT_BYTE(pointer);
+ switch(format1 >> 4)
+ {
+ case 0: /* LINE */
+ pointer = sp_get_args(pointer, format1, &P1);
+#if DEBUG
+ printf("LINE %6.1f, %6.1f\n",
+ (real)P1.x / (real)sp_globals.onepix, (real)P1.y / (real)sp_globals.onepix);
+#endif
+ fn_line(P1);
+ sp_globals.P0 = P1;
+ continue;
+
+ case 1: /* Short XINT */
+ sp_globals.x_int = format1 & 0x0f;
+#if DEBUG
+ printf("XINT %d\n", sp_globals.x_int);
+#endif
+#if INCL_PLAID_OUT /* Plaid data monitoring included? */
+record_xint((fix15)sp_globals.x_int); /* Record xint data */
+#endif
+ continue;
+
+ case 2: /* Short YINT */
+ sp_globals.y_int = sp_globals.Y_int_org + (format1 & 0x0f);
+#if DEBUG
+ printf("YINT %d\n", sp_globals.y_int - sp_globals.Y_int_org);
+#endif
+#if INCL_PLAID_OUT /* Plaid data monitoring included? */
+record_yint((fix15)(sp_globals.y_int - sp_globals.Y_int_org)); /* Record yint data */
+#endif
+ continue;
+
+ case 3: /* Miscellaneous */
+ switch(format1 & 0x0f)
+ {
+ case 0: /* END */
+ if (curve_count)
+ {
+ fn_end_contour();
+ }
+ return;
+
+ case 1: /* Long XINT */
+ sp_globals.x_int = NEXT_BYTE(pointer);
+#if DEBUG
+ printf("XINT %d\n", sp_globals.x_int);
+#endif
+#if INCL_PLAID_OUT /* Plaid data monitoring included? */
+record_xint((fix15)sp_globals.x_int); /* Record xint data */
+#endif
+ continue;
+
+ case 2: /* Long YINT */
+ sp_globals.y_int = sp_globals.Y_int_org + NEXT_BYTE(pointer);
+#if DEBUG
+ printf("YINT %d\n", sp_globals.y_int - sp_globals.Y_int_org);
+#endif
+#if INCL_PLAID_OUT /* Plaid data monitoring included? */
+record_yint((fix15)(sp_globals.y_int - sp_globals.Y_int_org)); /* Record yint data */
+#endif
+ continue;
+
+ default: /* Not used */
+ continue;
+ }
+
+ case 4: /* MOVE Inside */
+ case 5: /* MOVE Outside */
+ if (curve_count++)
+ {
+ fn_end_contour();
+ }
+
+ pointer = sp_get_args(pointer, format1, &P0);
+ sp_globals.P0 = P0;
+#if DEBUG
+ printf("MOVE %6.1f, %6.1f\n",
+ (real)sp_globals.P0.x / (real)sp_globals.onepix, (real)sp_globals.P0.y / (real)sp_globals.onepix);
+#endif
+ fn_begin_contour(sp_globals.P0, (boolean)(format1 & BIT4));
+ continue;
+
+ case 6: /* Undefined */
+#if DEBUG
+ printf("*** Undefined instruction (Hex %4x)\n", format1);
+#endif
+ continue;
+
+ case 7: /* Undefined */
+#if DEBUG
+ printf("*** Undefined instruction (Hex %4x)\n", format1);
+#endif
+ continue;
+
+ default: /* CRVE */
+ format2 = NEXT_BYTE(pointer);
+ pointer = sp_get_args(pointer, format1, &P1);
+ pointer = sp_get_args(pointer, format2, &P2);
+ pointer = sp_get_args(pointer, (ufix8)(format2 >> 4), &P3);
+ depth = (format1 >> 4) & 0x07;
+#if DEBUG
+ printf("CRVE %6.1f, %6.1f, %6.1f, %6.1f, %6.1f, %6.1f, %d\n",
+ (real)P1.x / (real)sp_globals.onepix, (real)P1.y / (real)sp_globals.onepix,
+ (real)P2.x / (real)sp_globals.onepix, (real)P2.y / (real)sp_globals.onepix,
+ (real)P3.x / (real)sp_globals.onepix, (real)P3.y / (real)sp_globals.onepix,
+ depth);
+#endif
+ depth += sp_globals.depth_adj;
+ if (sp_globals.curves_out)
+ {
+ fn_curve(P1, P2, P3, depth);
+ sp_globals.P0 = P3;
+ continue;
+ }
+ if (depth <= 0)
+ {
+ fn_line(P3);
+ sp_globals.P0 = P3;
+ continue;
+ }
+ sp_split_curve(P1, P2, P3, depth);
+ continue;
+ }
+ }
+}
+
+FUNCTION static void sp_split_curve(
+GDECL
+point_t P1, /* First control point of Bezier curve */
+point_t P2, /* Second control point of Bezier curve */
+point_t P3, /* End point of Bezier curve */
+fix15 depth) /* Levels of recursive subdivision required */
+/*
+ * Called by proc_outl_data() to subdivide Bezier curves into an
+ * appropriate number of vectors, whenever curves are not enabled
+ * for output to the currently selected output module.
+ * sp_split_curve() calls itself recursively to the depth specified
+ * at which point it calls line() to deliver each vector resulting
+ * from the spliting process.
+ */
+{
+fix31 X0 = (fix31)sp_globals.P0.x;
+fix31 Y0 = (fix31)sp_globals.P0.y;
+fix31 X1 = (fix31)P1.x;
+fix31 Y1 = (fix31)P1.y;
+fix31 X2 = (fix31)P2.x;
+fix31 Y2 = (fix31)P2.y;
+fix31 X3 = (fix31)P3.x;
+fix31 Y3 = (fix31)P3.y;
+point_t Pmid;
+point_t Pctrl1;
+point_t Pctrl2;
+
+#if DEBUG
+printf("CRVE(%3.1f, %3.1f, %3.1f, %3.1f, %3.1f, %3.1f)\n",
+ (real)P1.x / (real)sp_globals.onepix, (real)P1.y / (real)sp_globals.onepix,
+ (real)P2.x / (real)sp_globals.onepix, (real)P2.y / (real)sp_globals.onepix,
+ (real)P3.x / (real)sp_globals.onepix, (real)P3.y / (real)sp_globals.onepix);
+#endif
+
+
+Pmid.x = (X0 + (X1 + X2) * 3 + X3 + 4) >> 3;
+Pmid.y = (Y0 + (Y1 + Y2) * 3 + Y3 + 4) >> 3;
+if ((--depth) <= 0)
+ {
+ fn_line(Pmid);
+ sp_globals.P0 = Pmid;
+ fn_line(P3);
+ sp_globals.P0 = P3;
+ }
+else
+ {
+ Pctrl1.x = (X0 + X1 + 1) >> 1;
+ Pctrl1.y = (Y0 + Y1 + 1) >> 1;
+ Pctrl2.x = (X0 + (X1 << 1) + X2 + 2) >> 2;
+ Pctrl2.y = (Y0 + (Y1 << 1) + Y2 + 2) >> 2;
+ sp_split_curve(Pctrl1, Pctrl2, Pmid, depth);
+ Pctrl1.x = (X1 + (X2 << 1) + X3 + 2) >> 2;
+ Pctrl1.y = (Y1 + (Y2 << 1) + Y3 + 2) >> 2;
+ Pctrl2.x = (X2 + X3 + 1) >> 1;
+ Pctrl2.y = (Y2 + Y3 + 1) >> 1;
+ sp_split_curve(Pctrl1, Pctrl2, P3, depth);
+ }
+}
+
+FUNCTION static ufix8 FONTFAR *sp_get_args(
+GDECL
+ufix8 FONTFAR *pointer, /* Pointer to next byte in char data */
+ufix8 format, /* Format specifiaction of argument pair */
+point_t STACKFAR *pP) /* Resulting transformed point */
+/*
+ * Called by read_bbox() and proc_outl_data() to read an X Y argument
+ * pair from the font.
+ * The format is specified as follows:
+ * Bits 0-1: Type of X argument.
+ * Bits 2-3: Type of Y argument.
+ * where the 4 possible argument types are:
+ * Type 0: Controlled coordinate represented by one byte
+ * index into the X or Y controlled coordinate table.
+ * Type 1: Interpolated coordinate represented by a two-byte
+ * signed integer.
+ * Type 2: Interpolated coordinate represented by a one-byte
+ * signed increment/decrement relative to the
+ * proceding X or Y coordinate.
+ * Type 3: Repeat of preceding X or Y argument value and type.
+ * The units of P are sub-pixels.
+ * Updates *ppointer to point to the byte following the
+ * argument pair.
+ */
+{
+ufix8 edge;
+
+/* Read X argument */
+switch(format & 0x03)
+ {
+case 0: /* Index to controlled oru */
+ edge = NEXT_BYTE(pointer);
+ sp_globals.x_orus = sp_plaid.orus[edge];
+ sp_globals.x_pix = sp_plaid.pix[edge];
+ break;
+
+case 1: /* 2 byte interpolated oru value */
+ sp_globals.x_orus = NEXT_WORD(pointer);
+ goto L1;
+
+case 2: /* 1 byte signed oru increment */
+ sp_globals.x_orus += (fix15)((fix7)NEXT_BYTE(pointer));
+L1:
+ sp_globals.x_pix = TRANS(sp_globals.x_orus, sp_plaid.mult[sp_globals.x_int], sp_plaid.offset[sp_globals.x_int], sp_globals.mpshift);
+ break;
+
+default: /* No change in X value */
+ break;
+ }
+
+/* Read Y argument */
+switch((format >> 2) & 0x03)
+ {
+case 0: /* Index to controlled oru */
+ edge = sp_globals.Y_edge_org + NEXT_BYTE(pointer);
+ sp_globals.y_orus = sp_plaid.orus[edge];
+ sp_globals.y_pix = sp_plaid.pix[edge];
+ break;
+
+case 1: /* 2 byte interpolated oru value */
+ sp_globals.y_orus = NEXT_WORD(pointer);
+ goto L2;
+
+case 2: /* 1 byte signed oru increment */
+ sp_globals.y_orus += (fix15)((fix7)NEXT_BYTE(pointer));
+L2:
+ sp_globals.y_pix = TRANS(sp_globals.y_orus, sp_plaid.mult[sp_globals.y_int], sp_plaid.offset[sp_globals.y_int], sp_globals.mpshift);
+ break;
+
+default: /* No change in X value */
+ break;
+ }
+
+switch(sp_globals.tcb.xmode)
+ {
+case 0: /* X mode 0 */
+ pP->x = sp_globals.x_pix;
+ break;
+
+case 1: /* X mode 1 */
+ pP->x = -sp_globals.x_pix;
+ break;
+
+case 2: /* X mode 2 */
+ pP->x = sp_globals.y_pix;
+ break;
+
+case 3: /* X mode 3 */
+ pP->x = -sp_globals.y_pix;
+ break;
+
+default: /* X mode 4 */
+ pP->x = (MULT16(sp_globals.x_orus, sp_globals.tcb.xxmult) +
+ MULT16(sp_globals.y_orus, sp_globals.tcb.xymult) +
+ sp_globals.tcb.xoffset) >> sp_globals.mpshift;
+ break;
+ }
+
+switch(sp_globals.tcb.ymode)
+ {
+case 0: /* Y mode 0 */
+ pP->y = sp_globals.y_pix;
+ break;
+
+case 1: /* Y mode 1 */
+ pP->y = -sp_globals.y_pix;
+ break;
+
+case 2: /* Y mode 2 */
+ pP->y = sp_globals.x_pix;
+ break;
+
+case 3: /* Y mode 3 */
+ pP->y = -sp_globals.x_pix;
+ break;
+
+default: /* Y mode 4 */
+ pP->y = (MULT16(sp_globals.x_orus, sp_globals.tcb.yxmult) +
+ MULT16(sp_globals.y_orus, sp_globals.tcb.yymult) +
+ sp_globals.tcb.yoffset) >> sp_globals.mpshift;
+ break;
+ }
+
+return pointer;
+}
+
+
+
diff --git a/libXfont/src/Speedo/keys.h b/libXfont/src/Speedo/keys.h
new file mode 100644
index 000000000..dd9d0bff7
--- /dev/null
+++ b/libXfont/src/Speedo/keys.h
@@ -0,0 +1,56 @@
+/* $Xorg: keys.h,v 1.3 2000/08/17 19:46:25 cpqbld Exp $ */
+
+/*
+
+Copyright 1989-1991, Bitstream Inc., Cambridge, MA.
+You are hereby granted permission under all Bitstream propriety rights to
+use, copy, modify, sublicense, sell, and redistribute the Bitstream Speedo
+software and the Bitstream Charter outline font for any purpose and without
+restrictions; provided, that this notice is left intact on all copies of such
+software or font and that Bitstream's trademark is acknowledged as shown below
+on all unmodified copies of such font.
+
+BITSTREAM CHARTER is a registered trademark of Bitstream Inc.
+
+
+BITSTREAM INC. DISCLAIMS ANY AND ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING
+WITHOUT LIMITATION THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+PARTICULAR PURPOSE. BITSTREAM SHALL NOT BE LIABLE FOR ANY DIRECT OR INDIRECT
+DAMAGES, INCLUDING BUT NOT LIMITED TO LOST PROFITS, LOST DATA, OR ANY OTHER
+INCIDENTAL OR CONSEQUENTIAL DAMAGES, ARISING OUT OF OR IN ANY WAY CONNECTED
+WITH THE SPEEDO SOFTWARE OR THE BITSTREAM CHARTER OUTLINE FONT.
+
+*/
+
+
+/***** DECRYPTION KEY CONSTANTS (PC Platform) *****/
+
+#define CUS0 432 /* Customer number */
+
+#define KEY0 0 /* Decryption key 0 */
+#define KEY1 72 /* Decryption key 1 */
+#define KEY2 123 /* Decryption key 2 */
+#define KEY3 1 /* Decryption key 3 */
+#define KEY4 222 /* Decryption key 4 */
+#define KEY5 194 /* Decryption key 5 */
+#define KEY6 113 /* Decryption key 6 */
+#define KEY7 119 /* Decryption key 7 */
+#define KEY8 52 /* Decryption key 8 */
+
+/***** DECRYPTION KEY CONSTANTS (Sample) *****/
+
+#define XSAMPLEFONTS
+
+#define XCUS0 0 /* Customer number */
+
+#define XKEY0 0 /* Decryption key 0 */
+#define XKEY1 0 /* Decryption key 1 */
+#define XKEY2 0 /* Decryption key 2 */
+#define XKEY3 0 /* Decryption key 3 */
+#define XKEY4 0 /* Decryption key 4 */
+#define XKEY5 0 /* Decryption key 5 */
+#define XKEY6 0 /* Decryption key 6 */
+#define XKEY7 0 /* Decryption key 7 */
+#define XKEY8 0 /* Decryption key 8 */
+
+
diff --git a/libXfont/src/Speedo/out_bl2d.c b/libXfont/src/Speedo/out_bl2d.c
new file mode 100644
index 000000000..6c38cb30d
--- /dev/null
+++ b/libXfont/src/Speedo/out_bl2d.c
@@ -0,0 +1,772 @@
+/* $Xorg: out_bl2d.c,v 1.3 2000/08/17 19:46:26 cpqbld Exp $ */
+
+/*
+
+Copyright 1989-1991, Bitstream Inc., Cambridge, MA.
+You are hereby granted permission under all Bitstream propriety rights to
+use, copy, modify, sublicense, sell, and redistribute the Bitstream Speedo
+software and the Bitstream Charter outline font for any purpose and without
+restrictions; provided, that this notice is left intact on all copies of such
+software or font and that Bitstream's trademark is acknowledged as shown below
+on all unmodified copies of such font.
+
+BITSTREAM CHARTER is a registered trademark of Bitstream Inc.
+
+
+BITSTREAM INC. DISCLAIMS ANY AND ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING
+WITHOUT LIMITATION THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+PARTICULAR PURPOSE. BITSTREAM SHALL NOT BE LIABLE FOR ANY DIRECT OR INDIRECT
+DAMAGES, INCLUDING BUT NOT LIMITED TO LOST PROFITS, LOST DATA, OR ANY OTHER
+INCIDENTAL OR CONSEQUENTIAL DAMAGES, ARISING OUT OF OR IN ANY WAY CONNECTED
+WITH THE SPEEDO SOFTWARE OR THE BITSTREAM CHARTER OUTLINE FONT.
+
+*/
+/* $XFree86: xc/lib/font/Speedo/out_bl2d.c,v 1.3 1999/02/07 11:47:14 dawes Exp $ */
+
+/*************************** O U T _ B L 2 D . C *****************************
+ * *
+ * This is an output module for screen writer using two dimensional scanning *
+ ****************************************************************************/
+
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "spdo_prv.h" /* General definitions for speedo */
+
+#define CLOCKWISE 1
+#define DEBUG 0
+#define ABS(X) ( (X < 0) ? -X : X)
+
+#if DEBUG
+#include <stdio.h>
+#define SHOW(X) printf("X = %d\n", X)
+#else
+#define SHOW(X)
+#endif
+
+/***** GLOBAL VARIABLES *****/
+
+/***** GLOBAL FUNCTIONS *****/
+
+/***** EXTERNAL VARIABLES *****/
+
+/***** EXTERNAL FUNCTIONS *****/
+
+/***** STATIC VARIABLES *****/
+
+/***** STATIC FUNCTIONS *****/
+
+#if INCL_2D
+static void sp_draw_vector_to_2d(PROTO_DECL2 fix15 x0,fix15 y0,fix15 x1,fix15 y1,band_t GLOBALFAR *band);
+static void sp_add_intercept_2d(PROTO_DECL2 fix15 y,fix15 x);
+static void sp_proc_intercepts_2d(PROTO_DECL1);
+#endif
+
+#if INCL_2D
+FUNCTION boolean init_2d(
+GDECL
+specs_t GLOBALFAR *specsarg)
+/*
+ * init_out_2d() is called by sp_set_specs() to initialize the output module.
+ * Returns TRUE if output module can accept requested specifications.
+ * Returns FALSE otherwise.
+ */
+{
+
+if (specsarg->flags & CURVES_OUT)
+ return FALSE; /* Curves out, clipping not supported */
+
+#if DEBUG
+printf("INIT_OUT__2d()\n");
+#endif
+return TRUE;
+}
+#endif
+
+#if INCL_2D
+FUNCTION boolean begin_char_2d(
+GDECL
+point_t Psw,
+point_t Pmin,
+point_t Pmax)
+/* Called once at the start of the character generation process
+ * Initializes intercept table, either calculates pixel maxima or
+ * decides that they need to be collected
+ */
+{
+#if DEBUG
+printf("BEGIN_CHAR__2d(%3.1f, %3.1f, %3.1f, %3.1f, %3.1f, %3.1f\n",
+ (real)Psw.x / (real)sp_globals.onepix, (real)Psw.y / (real)sp_globals.onepix,
+ (real)Pmin.x / (real)sp_globals.onepix, (real)Pmin.y / (real)sp_globals.onepix,
+ (real)Pmax.x / (real)sp_globals.onepix, (real)Pmax.y / (real)sp_globals.onepix);
+#endif
+/* Convert PIX.FRAC to 16.16 form */
+sp_globals.x_scan_active = TRUE; /* Assume x-scanning from the start */
+
+init_char_out(Psw,Pmin,Pmax);
+return TRUE;
+}
+#endif
+
+
+#if INCL_2D
+FUNCTION void begin_contour_2d(
+GDECL
+point_t P1,
+boolean outside)
+/* Called at the start of each contour
+ */
+{
+
+#if DEBUG
+printf("BEGIN_CONTOUR__2d(%3.4f, %3.4f, %s)\n",
+ (real)P1.x / (real)sp_globals.onepix,
+ (real)P1.y / (real)sp_globals.onepix,
+ outside? "outside": "inside");
+#endif
+sp_globals.x0_spxl = P1.x;
+sp_globals.y0_spxl = P1.y;
+}
+#endif
+
+#if INCL_2D
+FUNCTION void line_2d(
+GDECL
+point_t P1)
+/*
+ * Called for each vector in the transformed character
+ * "draws" vector into intercept table
+ */
+{
+
+#if DEBUG
+printf("LINE_0(%3.4f, %3.4f)\n",
+ (real)P1.x / (real)sp_globals.onepix,
+ (real)P1.y / (real)sp_globals.onepix);
+#endif
+
+if (sp_globals.extents_running)
+ {
+ if (sp_globals.x0_spxl > sp_globals.bmap_xmax)
+ sp_globals.bmap_xmax = sp_globals.x0_spxl;
+ if (sp_globals.x0_spxl < sp_globals.bmap_xmin)
+ sp_globals.bmap_xmin = sp_globals.x0_spxl;
+ if (sp_globals.y0_spxl > sp_globals.bmap_ymax)
+ sp_globals.bmap_ymax = sp_globals.y0_spxl;
+ if (sp_globals.y0_spxl < sp_globals.bmap_ymin)
+ sp_globals.bmap_ymin = sp_globals.y0_spxl;
+ }
+
+if (!sp_globals.intercept_oflo)
+ {
+ sp_draw_vector_to_2d(sp_globals.x0_spxl,
+ sp_globals.y0_spxl,
+ P1.x,
+ P1.y,
+ &sp_globals.y_band); /* y-scan */
+
+ if (sp_globals.x_scan_active)
+ sp_draw_vector_to_2d(sp_globals.y0_spxl,
+ sp_globals.x0_spxl,
+ P1.y,
+ P1.x,
+ &sp_globals.x_band); /* x-scan if selected */
+ }
+
+sp_globals.x0_spxl = P1.x;
+sp_globals.y0_spxl = P1.y; /* update endpoint */
+}
+
+FUNCTION static void sp_draw_vector_to_2d(
+GDECL
+fix15 x0, /* X coordinate */
+fix15 y0, /* Y coordinate */
+fix15 x1,
+fix15 y1,
+band_t GLOBALFAR *band)
+{
+register fix15 how_many_y; /* # of intercepts at y = n + 1/2 */
+register fix15 yc; /* Current scan-line */
+ fix15 temp1; /* various uses */
+ fix15 temp2; /* various uses */
+register fix31 dx_dy; /* slope of line in 16.16 form */
+register fix31 xc; /* high-precision (16.16) x coordinate */
+ fix15 y_pxl;
+
+yc = (y0 + sp_globals.pixrnd) >> sp_globals.pixshift; /* current scan line = end of last line */
+y_pxl = (y1 + sp_globals.pixrnd) >> sp_globals.pixshift; /* calculate new end-scan line */
+
+if ((how_many_y = y_pxl - yc) == 0) return; /* Don't draw a null line */
+
+if (how_many_y < 0) yc--; /* Predecrment downward lines */
+
+if (yc > band->band_max) /* Is start point above band? */
+ {
+ if (y_pxl > band->band_max) return; /* line has to go down! */
+ how_many_y = y_pxl - (yc = band->band_max) - 1; /* Yes, limit it */
+ }
+
+if (yc < band->band_min) /* Is start point below band? */
+ {
+ if (y_pxl < band->band_min) return; /* line has to go up! */
+ how_many_y = y_pxl - (yc = band->band_min); /* Yes, limit it */
+ }
+
+xc = (fix31)(x0 + sp_globals.pixrnd) << 16; /* Original x coordinate with built in */
+ /* rounding. int.16 + pixshift form */
+
+if ( (temp1 = (x1 - x0)) == 0) /* check for vertical line */
+ {
+ dx_dy = 0L; /* Zero slope, leave xc alone */
+ goto skip_calc;
+ }
+
+/* calculate dx_dy at 16.16 fixed point */
+
+dx_dy = ( (fix31)temp1 << 16 )/(fix31)(y1 - y0);
+
+/* We have to check for a @#$%@# possible multiply overflow */
+/* by doing another @#$*& multiply. In assembly language, */
+/* the program could just check the OVerflow flag or whatever*/
+/* works on the particular processor. This C code is meant */
+/* to be processor independent. */
+
+temp1 = (yc << sp_globals.pixshift) - y0 + sp_globals.pixrnd;
+/* This sees if the sign bits start at bit 15 */
+/* if they do, no overflow has occurred */
+
+temp2 = (fix15)(MULT16(temp1,(fix15)(dx_dy >> 16)) >> 15);
+
+if ( (temp2 != (fix15)0xFFFF) &&
+ (temp2 != 0x0000) )
+ { /* Overflow. Pick point closest to yc + .5 */
+ if (ABS(temp1) < ABS((yc << sp_globals.pixshift) - y1 + sp_globals.pixrnd))
+ { /* use x1 instead of x0 */
+ xc = (fix31)(x1 + sp_globals.pixrnd) << (16 - sp_globals.pixshift);
+ }
+ goto skip_calc;
+ }
+/* calculate new xc at the center of the *current* scan line */
+/* due to banding, yc may be several lines away from y0 */
+/* xc += (yc + .5 - y0) * dx_dy */
+/* This multiply generates a subpixel delta. */
+/* So we leave it as an int.pixshift + 16 delta */
+
+xc += (fix31)temp1 * dx_dy;
+dx_dy <<= sp_globals.pixshift;
+skip_calc:
+
+yc -= band->band_array_offset; /* yc is now an offset relative to the band */
+
+if (how_many_y < 0)
+ { /* Vector down */
+ if ((how_many_y += yc + 1) < band->band_floor)
+ how_many_y = band->band_floor; /* can't go below floor */
+ while(yc >= how_many_y)
+ {
+ temp1 = (fix15)(xc >> 16);
+ sp_add_intercept_2d(yc--,temp1);
+ xc -= dx_dy;
+ }
+ }
+ else
+ { /* Vector up */
+ /* check to see that line doesn't extend beyond top of band */
+ if ((how_many_y += yc) > band->band_ceiling)
+ how_many_y = band->band_ceiling;
+ while(yc < how_many_y)
+ {
+ temp1 = (fix15)(xc >> 16);
+ sp_add_intercept_2d(yc++,temp1);
+ xc += dx_dy;
+ }
+ }
+}
+
+#endif
+
+#if INCL_2D
+FUNCTION boolean end_char_2d()
+/* Called when all character data has been output
+ * Return TRUE if output process is complete
+ * Return FALSE to repeat output of the transformed data beginning
+ * with the first contour
+ */
+{
+
+fix31 xorg;
+fix31 yorg;
+#if INCL_CLIPPING
+fix31 em_max, em_min, bmap_max, bmap_min;
+#endif
+
+#if DEBUG
+printf("END_CHAR__2d()\n");
+#endif
+
+if (sp_globals.first_pass)
+ {
+ if (sp_globals.bmap_xmax >= sp_globals.bmap_xmin)
+ {
+ sp_globals.xmin = (sp_globals.bmap_xmin + sp_globals.pixrnd + 1) >> sp_globals.pixshift;
+ sp_globals.xmax = (sp_globals.bmap_xmax + sp_globals.pixrnd) >> sp_globals.pixshift;
+ }
+ else
+ {
+ sp_globals.xmin = sp_globals.xmax = 0;
+ }
+ if (sp_globals.bmap_ymax >= sp_globals.bmap_ymin)
+ {
+
+#if INCL_CLIPPING
+ switch(sp_globals.tcb0.xtype)
+ {
+ case 1: /* 180 degree rotation */
+ if (sp_globals.specs.flags & CLIP_TOP)
+ {
+ sp_globals.clip_ymin = (fix31)((fix31)EM_TOP * sp_globals.tcb0.yppo + ((1<<sp_globals.multshift)/2));
+ sp_globals.clip_ymin = sp_globals.clip_ymin >> sp_globals.multshift;
+ bmap_min = (sp_globals.bmap_ymin + sp_globals.pixrnd + 1) >> sp_globals.pixshift;
+ sp_globals.clip_ymin = -1 * sp_globals.clip_ymin;
+ if (bmap_min < sp_globals.clip_ymin)
+ sp_globals.ymin = sp_globals.clip_ymin;
+ else
+ sp_globals.ymin = bmap_min;
+ }
+ if (sp_globals.specs.flags & CLIP_BOTTOM)
+ {
+ sp_globals.clip_ymax = (fix31)((fix31)(-1 * EM_BOT) * sp_globals.tcb0.yppo + ((1<<sp_globals.multshift)/2));
+ sp_globals.clip_ymax = sp_globals.clip_ymax >> sp_globals.multshift;
+ bmap_max = (sp_globals.bmap_ymax + sp_globals.pixrnd) >> sp_globals.pixshift;
+ if (bmap_max < sp_globals.clip_ymax)
+ sp_globals.ymax = bmap_max;
+ else
+ sp_globals.ymax = sp_globals.clip_ymax;
+ }
+ sp_globals.clip_xmax = -sp_globals.xmin;
+ sp_globals.clip_xmin = ((sp_globals.set_width.x+32768L) >> 16) -
+ sp_globals.xmin;
+ break;
+ case 2: /* 90 degree rotation */
+ if (sp_globals.specs.flags & CLIP_TOP)
+ {
+ sp_globals.clip_xmin = (fix31)((fix31)(-1 * EM_BOT) * sp_globals.tcb0.yppo + ((1<<sp_globals.multshift)/2));
+ sp_globals.clip_xmin = sp_globals.clip_xmin >> sp_globals.multshift;
+ sp_globals.clip_xmin = -1 * sp_globals.clip_xmin;
+ bmap_min = (sp_globals.bmap_xmin + sp_globals.pixrnd + 1) >> sp_globals.pixshift;
+ if (bmap_min > sp_globals.clip_xmin)
+ sp_globals.clip_xmin = bmap_min;
+
+ /* normalize to x origin */
+ sp_globals.clip_xmin -= sp_globals.xmin;
+ }
+ if (sp_globals.specs.flags & CLIP_BOTTOM)
+ {
+ sp_globals.clip_xmax = (fix31)((fix31)EM_TOP * sp_globals.tcb0.yppo + ((1<<sp_globals.multshift)/2));
+ sp_globals.clip_xmax = sp_globals.clip_xmax >> sp_globals.multshift;
+ bmap_max = (sp_globals.bmap_xmax + sp_globals.pixrnd) >> sp_globals.pixshift;
+ if (bmap_max < sp_globals.clip_xmax)
+ sp_globals.xmax = bmap_max;
+ else
+ sp_globals.xmax = sp_globals.clip_xmax;
+ sp_globals.clip_ymax = 0;
+ if ((sp_globals.specs.flags & CLIP_TOP) &&
+ (sp_globals.ymax > sp_globals.clip_ymax))
+ sp_globals.ymax = sp_globals.clip_ymax;
+ sp_globals.clip_ymin = ((sp_globals.set_width.y+32768L) >> 16);
+ if ((sp_globals.specs.flags & CLIP_BOTTOM) &&
+ (sp_globals.ymin < sp_globals.clip_ymin))
+ sp_globals.ymin = sp_globals.clip_ymin;
+ /* normalize to x origin */
+ sp_globals.clip_xmax -= sp_globals.xmin;
+ }
+ break;
+ case 3: /* 270 degree rotation */
+ if (sp_globals.specs.flags & CLIP_TOP)
+ {
+ sp_globals.clip_xmin = (fix31)((fix31)EM_TOP * sp_globals.tcb0.yppo + ((1<<sp_globals.multshift)/2));
+ sp_globals.clip_xmin = sp_globals.clip_xmin >> sp_globals.multshift;
+ sp_globals.clip_xmin = -1 * sp_globals.clip_xmin;
+ bmap_min = (sp_globals.bmap_xmin + sp_globals.pixrnd + 1) >> sp_globals.pixshift;
+
+ /* let the minimum be the larger of these two values */
+ if (bmap_min > sp_globals.clip_xmin)
+ sp_globals.clip_xmin = bmap_min;
+
+ /* normalize the x value to new xorgin */
+ sp_globals.clip_xmin -= sp_globals.xmin;
+ }
+ if (sp_globals.specs.flags & CLIP_BOTTOM)
+ {
+ sp_globals.clip_xmax = (fix31)((fix31)(-1 * EM_BOT) * sp_globals.tcb0.yppo + ((1<<sp_globals.multshift)/2));
+ sp_globals.clip_xmax = sp_globals.clip_xmax >> sp_globals.multshift;
+ bmap_max = (sp_globals.bmap_xmax + sp_globals.pixrnd) >> sp_globals.pixshift;
+
+ /* let the max be the lesser of these two values */
+ if (bmap_max < sp_globals.clip_xmax)
+ {
+ sp_globals.xmax = bmap_max;
+ sp_globals.clip_xmax = bmap_max;
+ }
+ else
+ sp_globals.xmax = sp_globals.clip_xmax;
+
+ /* normalize the x value to new x origin */
+ sp_globals.clip_xmax -= sp_globals.xmin;
+ }
+ /* compute y clip values */
+ sp_globals.clip_ymax = ((sp_globals.set_width.y+32768L) >> 16);
+ if ((sp_globals.specs.flags & CLIP_TOP) &&
+ (sp_globals.ymax > sp_globals.clip_ymax))
+ sp_globals.ymax = sp_globals.clip_ymax;
+ sp_globals.clip_ymin = 0;
+ if ((sp_globals.specs.flags & CLIP_BOTTOM) &&
+ (sp_globals.ymin < sp_globals.clip_ymin))
+ sp_globals.ymin = sp_globals.clip_ymin;
+ break;
+ default: /* this is for zero degree rotation and arbitrary rotation */
+ if (sp_globals.specs.flags & CLIP_TOP)
+ {
+ sp_globals.clip_ymax = (fix31)((fix31)EM_TOP * sp_globals.tcb0.yppo + ((1<<sp_globals.multshift)/2));
+ sp_globals.clip_ymax = sp_globals.clip_ymax >> sp_globals.multshift;
+ bmap_max = (sp_globals.bmap_ymax + sp_globals.pixrnd) >> sp_globals.pixshift;
+ if (bmap_max > sp_globals.clip_ymax)
+ sp_globals.ymax = bmap_max;
+ else
+ sp_globals.ymax = sp_globals.clip_ymax;
+ }
+ if (sp_globals.specs.flags & CLIP_BOTTOM)
+ {
+ sp_globals.clip_ymin = (fix31)((fix31)(-1 * EM_BOT) * sp_globals.tcb0.yppo + ((1<<sp_globals.multshift)/2));
+ sp_globals.clip_ymin = sp_globals.clip_ymin >> sp_globals.multshift;
+ sp_globals.clip_ymin = - sp_globals.clip_ymin;
+ bmap_min = (sp_globals.bmap_ymin + sp_globals.pixrnd + 1) >> sp_globals.pixshift;
+ if (bmap_min < sp_globals.clip_ymin)
+ sp_globals.ymin = sp_globals.clip_ymin;
+ else
+ sp_globals.ymin = bmap_min;
+ }
+ sp_globals.clip_xmin = -sp_globals.xmin;
+ sp_globals.clip_xmax = ((sp_globals.set_width.x+32768L) >> 16) -
+ sp_globals.xmin;
+ break;
+ }
+if ( !(sp_globals.specs.flags & CLIP_TOP))
+#endif
+ sp_globals.ymax = (sp_globals.bmap_ymax + sp_globals.pixrnd) >> sp_globals.pixshift;
+
+#if INCL_CLIPPING
+if ( !(sp_globals.specs.flags & CLIP_BOTTOM))
+#endif
+ sp_globals.ymin = (sp_globals.bmap_ymin + sp_globals.pixrnd + 1) >> sp_globals.pixshift;
+ }
+ else
+ {
+ sp_globals.ymin = sp_globals.ymax = 0;
+ }
+
+ /* add in the rounded out part (from xform.) of the left edge */
+ if (sp_globals.tcb.xmode == 0) /* for X pix is function of X orus only add the round */
+ xorg = (((fix31)sp_globals.xmin << 16) + (sp_globals.rnd_xmin << sp_globals.poshift));
+ else
+ if (sp_globals.tcb.xmode == 1) /* for X pix is function of -X orus only, subtr. round */
+ xorg = (((fix31)sp_globals.xmin << 16) - (sp_globals.rnd_xmin << sp_globals.poshift)) ;
+ else
+ xorg = (fix31)sp_globals.xmin << 16; /* for other cases don't use round on x */
+
+ if (sp_globals.tcb.ymode == 2) /* for Y pix is function of X orus only, add round error */
+ yorg = (((fix31)sp_globals.ymin << 16) + (sp_globals.rnd_xmin << sp_globals.poshift));
+ else
+ if (sp_globals.tcb.ymode == 3) /* for Y pix is function of -X orus only, sub round */
+ yorg = (((fix31)sp_globals.ymin << 16) - (sp_globals.rnd_xmin << sp_globals.poshift));
+ else /* all other cases have no round error on yorg */
+ yorg = (fix31)sp_globals.ymin << 16;
+
+ open_bitmap(sp_globals.set_width.x, sp_globals.set_width.y, xorg, yorg,
+ sp_globals.xmax - sp_globals.xmin, sp_globals.ymax - sp_globals.ymin);
+ if (sp_globals.intercept_oflo)
+ {
+ sp_globals.y_band.band_min = sp_globals.ymin;
+ sp_globals.y_band.band_max = sp_globals.ymax;
+ sp_globals.x_scan_active = FALSE;
+ sp_globals.no_x_lists = 0;
+ init_intercepts_out();
+ sp_globals.first_pass = FALSE;
+ sp_globals.extents_running = FALSE;
+ return FALSE;
+ }
+ else
+ {
+ sp_proc_intercepts_2d();
+ close_bitmap();
+ return TRUE;
+ }
+ }
+else
+ {
+ if (sp_globals.intercept_oflo)
+ {
+ reduce_band_size_out();
+ init_intercepts_out();
+ return FALSE;
+ }
+ else
+ {
+ sp_proc_intercepts_2d();
+ if (next_band_out())
+ {
+ init_intercepts_out();
+ return FALSE;
+ }
+ close_bitmap();
+ return TRUE;
+ }
+ }
+}
+#endif
+
+#if INCL_2D
+FUNCTION static void sp_add_intercept_2d(
+GDECL
+fix15 y, /* Y coordinate in relative pixel units */
+ /* (0 is lowest sample in band) */
+fix15 x) /* X coordinate of intercept in subpixel units */
+
+/* Called by line() to add an intercept to the intercept list structure
+ */
+
+{
+register fix15 from; /* Insertion pointers for the linked list sort */
+register fix15 to;
+
+#if DEBUG
+/* Bounds checking IS done in debug mode */
+if ((y >= MAX_INTERCEPTS) || (y < 0))
+ {
+ printf("Intercept out of table!!!!! (%d)\n",y);
+ return;
+ }
+
+if (y >= sp_globals.no_y_lists)
+ {
+ printf(" Add x intercept(%2d, %f)\n",
+ y + sp_globals.x_band.band_min - sp_globals.no_y_lists,
+ (real)x/(real)sp_globals.onepix);
+ if (y > (sp_globals.no_x_lists + sp_globals.no_y_lists))
+ {
+ printf(" Intercept too big for band!!!!!\007\n");
+ return;
+ }
+ }
+ else
+ {
+ printf(" Add y intercept(%2d, %f)\n", y + sp_globals.y_band.band_min,(real)x/(real)sp_globals.onepix);
+ }
+
+if (y < 0) /* Y value below bottom of current band? */
+ {
+ printf(" Intecerpt less than 0!!!\007\n");
+ return;
+ }
+#endif
+
+/* Store new values */
+
+sp_intercepts.car[sp_globals.next_offset] = x;
+
+/* Find slot to insert new element (between from and to) */
+
+from = y; /* Start at list head */
+
+while( (to = sp_intercepts.cdr[from]) >= sp_globals.first_offset) /* Until to == end of list */
+ {
+ if (x <= sp_intercepts.car[to]) /* If next item is larger than or same as this one... */
+ goto insert_element; /* ... drop out and insert here */
+ from = to; /* move forward in list */
+ }
+
+insert_element: /* insert element "next_offset" between elements "from" */
+ /* and "to" */
+
+sp_intercepts.cdr[from] = sp_globals.next_offset;
+sp_intercepts.cdr[sp_globals.next_offset] = to;
+
+if (++sp_globals.next_offset >= MAX_INTERCEPTS) /* Intercept buffer full? */
+ {
+ sp_globals.intercept_oflo = TRUE;
+/* There may be a few more calls to "add_intercept" from the current line */
+/* To avoid problems, we set next_offset to a safe value. We don't care */
+/* if the intercept table gets trashed at this point */
+ sp_globals.next_offset = sp_globals.first_offset;
+ }
+}
+
+#endif
+
+#if INCL_2D
+FUNCTION static void sp_proc_intercepts_2d()
+/* Called by sp_make_char to output accumulated intercept lists
+ * Clips output to xmin, xmax, sp_globals.ymin, ymax boundaries
+ */
+{
+register fix15 i;
+register fix15 from, to; /* Start and end of run in pixel units
+ relative to left extent of character */
+register fix15 y;
+register fix15 scan_line;
+ fix15 local_bmap_xmin;
+ fix15 local_bmap_xmax;
+ fix15 first_y, last_y;
+ fix15 j,k;
+
+#if INCL_CLIPPING
+if ((sp_globals.specs.flags & CLIP_LEFT) != 0)
+ clipleft = TRUE;
+else
+ clipleft = FALSE;
+if ((sp_globals.specs.flags & CLIP_RIGHT) != 0)
+ clipright = TRUE;
+else
+ clipright = FALSE;
+if (clipleft || clipright)
+ {
+ xmax = sp_globals.clip_xmax << sp_globals.pixshift;
+ xmin = sp_globals.clip_xmin << sp_globals.pixshift;
+ }
+if (!clipright)
+ xmax = ((sp_globals.set_width.x+32768L) >> 16);
+#endif
+
+if (sp_globals.x_scan_active) /* If xscanning, we need to make sure we don't miss any important pixels */
+ {
+ first_y = sp_globals.x_band.band_floor; /* start of x lists */
+ last_y = sp_globals.x_band.band_ceiling; /* end of x lists */
+ for (y = first_y; y != last_y; y++) /* scan all xlists */
+ {
+ i = sp_intercepts.cdr[y]; /* Index head of intercept list */
+ while (i != 0) /* Link to next intercept if present */
+ {
+ from = sp_intercepts.car[i];
+ j = i;
+ i = sp_intercepts.cdr[i]; /* Link to next intercept */
+ if (i == 0) /* End of list? */
+ {
+#if DEBUG
+ printf("****** proc_intercepts: odd number of intercepts in x list\n");
+#endif
+ break;
+ }
+ to = sp_intercepts.car[i];
+ k = sp_intercepts.cdr[i];
+ if (((to >> sp_globals.pixshift) >= (from >> sp_globals.pixshift)) &&
+ ((to - from) < (sp_globals.onepix + 1)))
+ {
+ from = ((fix31)to + (fix31)from - (fix31)sp_globals.onepix) >> (sp_globals.pixshift + 1);
+ if (from > sp_globals.y_band.band_max)
+ from = sp_globals.y_band.band_max;
+ if ((from -= sp_globals.y_band.band_min) < 0)
+ from = 0;
+ to = ((y - sp_globals.x_band.band_floor + sp_globals.x_band.band_min)
+ << sp_globals.pixshift)
+ + sp_globals.pixrnd;
+ sp_intercepts.car[j] = to;
+ sp_intercepts.car[i] = to + sp_globals.onepix;
+ sp_intercepts.cdr[i] = sp_intercepts.cdr[from];
+ sp_intercepts.cdr[from] = j;
+ }
+ i = k;
+ }
+ }
+ }
+#if DEBUG
+printf("\nIntercept lists:\n");
+#endif
+
+if ((first_y = sp_globals.y_band.band_max) >= sp_globals.ymax)
+ first_y = sp_globals.ymax - 1; /* Clip to ymax boundary */
+
+if ((last_y = sp_globals.y_band.band_min) < sp_globals.ymin)
+ last_y = sp_globals.ymin; /* Clip to sp_globals.ymin boundary */
+
+last_y -= sp_globals.y_band.band_array_offset;
+
+local_bmap_xmin = sp_globals.xmin << sp_globals.pixshift;
+local_bmap_xmax = (sp_globals.xmax << sp_globals.pixshift) + sp_globals.pixrnd;
+
+#if DEBUG
+/* Print out all of the intercept info */
+scan_line = sp_globals.ymax - first_y - 1;
+
+for (y = first_y - sp_globals.y_band.band_min; y >= last_y; y--, scan_line++)
+ {
+ i = y; /* Index head of intercept list */
+ while ((i = sp_intercepts.cdr[i]) != 0) /* Link to next intercept if present */
+ {
+ if ((from = sp_intercepts.car[i] - local_bmap_xmin) < 0)
+ from = 0; /* Clip to xmin boundary */
+ i = sp_intercepts.cdr[i]; /* Link to next intercept */
+ if (i == 0) /* End of list? */
+ {
+ printf("****** proc_intercepts: odd number of intercepts\n");
+ break;
+ }
+ if ((to = sp_intercepts.car[i]) > sp_globals.bmap_xmax)
+ to = sp_globals.bmap_xmax - local_bmap_xmin; /* Clip to xmax boundary */
+ else
+ to -= local_bmap_xmin;
+ printf(" Y = %2d (scanline %2d): %3.4f %3.4f:\n",
+ y + sp_globals.y_band.band_min,
+ scan_line,
+ (real)from / (real)sp_globals.onepix,
+ (real)to / (real)sp_globals.onepix);
+ }
+ }
+#endif
+
+/* Draw the image */
+scan_line = sp_globals.ymax - first_y - 1;
+
+for (y = first_y - sp_globals.y_band.band_min; y >= last_y; y--, scan_line++)
+ {
+ i = y; /* Index head of intercept list */
+ while ((i = sp_intercepts.cdr[i]) != 0) /* Link to next intercept if present */
+ {
+ if ((from = sp_intercepts.car[i] - local_bmap_xmin) < 0)
+ from = 0; /* Clip to xmin boundary */
+ i = sp_intercepts.cdr[i]; /* Link to next intercept */
+
+ if ((to = sp_intercepts.car[i]) > local_bmap_xmax)
+ to = sp_globals.bmap_xmax - local_bmap_xmin; /* Clip to xmax boundary */
+ else
+ to -= local_bmap_xmin;
+#if INCL_CLIPPING
+ if (clipleft)
+ {
+ if (to <= xmin)
+ continue;
+ if (from < xmin)
+ from = xmin;
+ }
+ if (clipright)
+ {
+ if (from >= xmax)
+ continue;
+ if (to > xmax)
+ to = xmax;
+ }
+#endif
+ if ( (to - from) <= sp_globals.onepix)
+ {
+ from = (to + from - sp_globals.onepix) >> (sp_globals.pixshift + 1);
+ set_bitmap_bits(scan_line, from, from + 1);
+ }
+ else
+ {
+ set_bitmap_bits(scan_line, from >> sp_globals.pixshift, to >> sp_globals.pixshift);
+ }
+ }
+ }
+}
+
+#endif
diff --git a/libXfont/src/Speedo/out_blk.c b/libXfont/src/Speedo/out_blk.c
new file mode 100644
index 000000000..a5b669b2a
--- /dev/null
+++ b/libXfont/src/Speedo/out_blk.c
@@ -0,0 +1,706 @@
+/* $Xorg: out_blk.c,v 1.3 2000/08/17 19:46:26 cpqbld Exp $ */
+
+/*
+
+Copyright 1989-1991, Bitstream Inc., Cambridge, MA.
+You are hereby granted permission under all Bitstream propriety rights to
+use, copy, modify, sublicense, sell, and redistribute the Bitstream Speedo
+software and the Bitstream Charter outline font for any purpose and without
+restrictions; provided, that this notice is left intact on all copies of such
+software or font and that Bitstream's trademark is acknowledged as shown below
+on all unmodified copies of such font.
+
+BITSTREAM CHARTER is a registered trademark of Bitstream Inc.
+
+
+BITSTREAM INC. DISCLAIMS ANY AND ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING
+WITHOUT LIMITATION THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+PARTICULAR PURPOSE. BITSTREAM SHALL NOT BE LIABLE FOR ANY DIRECT OR INDIRECT
+DAMAGES, INCLUDING BUT NOT LIMITED TO LOST PROFITS, LOST DATA, OR ANY OTHER
+INCIDENTAL OR CONSEQUENTIAL DAMAGES, ARISING OUT OF OR IN ANY WAY CONNECTED
+WITH THE SPEEDO SOFTWARE OR THE BITSTREAM CHARTER OUTLINE FONT.
+
+*/
+/* $XFree86: xc/lib/font/Speedo/out_blk.c,v 1.2 1999/02/07 06:18:16 dawes Exp $ */
+
+
+/*************************** O U T _ B L K . C *********************************
+ * *
+ * This is an output module for black-writer mode. *
+ * *
+ *****************************************************************************/
+
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "spdo_prv.h" /* General definitions for Speedo */
+
+#define DEBUG 0
+#define LOCAL static
+#define ABS(X) ( (X < 0) ? -X : X)
+
+#if DEBUG
+#include <stdio.h>
+#define SHOW(X) printf("X = %d\n", X)
+#else
+#define SHOW(X)
+#endif
+
+
+/***** GLOBAL VARIABLES *****/
+
+/***** GLOBAL FUNCTIONS *****/
+
+/***** EXTERNAL VARIABLES *****/
+
+/***** EXTERNAL FUNCTIONS *****/
+
+/***** STATIC VARIABLES *****/
+
+/***** STATIC FUNCTIONS *****/
+
+#if INCL_BLACK
+static void sp_add_intercept_black(PROTO_DECL2 fix15 y, fix15 x);
+static void sp_proc_intercepts_black(PROTO_DECL1);
+#endif
+
+
+#if INCL_BLACK
+FUNCTION boolean init_black(
+GDECL
+specs_t GLOBALFAR *specsarg)
+/*
+ * init_out0() is called by sp_set_specs() to initialize the output module.
+ * Returns TRUE if output module can accept requested specifications.
+ * Returns FALSE otherwise.
+ */
+{
+#if DEBUG
+printf("INIT_BLK()\n");
+#endif
+if (specsarg->flags & CURVES_OUT)
+ return FALSE; /* Curves out not supported */
+return (TRUE);
+}
+#endif
+
+
+#if INCL_BLACK
+FUNCTION boolean begin_char_black(
+GDECL
+point_t Psw,
+point_t Pmin,
+point_t Pmax)
+/* Called once at the start of the character generation process
+ */
+{
+#if DEBUG
+printf("BEGIN_CHAR_BLACK(%3.1f, %3.1f, %3.1f, %3.1f, %3.1f, %3.1f\n",
+ (real)Psw.x / (real)sp_globals.onepix, (real)Psw.y / (real)sp_globals.onepix,
+ (real)Pmin.x / (real)sp_globals.onepix, (real)Pmin.y / (real)sp_globals.onepix,
+ (real)Pmax.x / (real)sp_globals.onepix, (real)Pmax.y / (real)sp_globals.onepix);
+#endif
+init_char_out(Psw,Pmin,Pmax);
+return TRUE;
+}
+#endif
+
+
+#if INCL_BLACK
+FUNCTION void begin_contour_black(
+GDECL
+point_t P1,
+boolean outside)
+/* Called at the start of each contour
+ */
+{
+
+#if DEBUG
+printf("BEGIN_CONTOUR_BLACK(%3.1f, %3.1f, %s)\n",
+ (real)P1.x / (real)sp_globals.onepix, (real)P1.y / (real)sp_globals.onepix, outside? "outside": "inside");
+#endif
+sp_globals.x0_spxl = P1.x;
+sp_globals.y0_spxl = P1.y;
+sp_globals.y_pxl = (sp_globals.y0_spxl + sp_globals.pixrnd) >> sp_globals.pixshift;
+}
+#endif
+
+#if INCL_BLACK
+FUNCTION void line_black(
+GDECL
+point_t P1)
+/* Called for each vector in the transformed character
+ */
+{
+register fix15 how_many_y; /* # of intercepts at y = n + 1/2 */
+register fix15 yc, i; /* Current scan-line */
+ fix15 temp1; /* various uses */
+ fix15 temp2; /* various uses */
+register fix31 dx_dy; /* slope of line in 16.16 form */
+register fix31 xc; /* high-precision (16.16) x coordinate */
+ fix15 x0,y0,x1,y1; /* PIX.FRAC start and endpoints */
+
+x0 = sp_globals.x0_spxl; /* get start of line (== current point) */
+y0 = sp_globals.y0_spxl;
+sp_globals.x0_spxl = x1 = P1.x; /* end of line */
+sp_globals.y0_spxl = y1 = P1.y; /* (also update current point to end of line) */
+
+yc = sp_globals.y_pxl; /* current scan line = end of last line */
+sp_globals.y_pxl = (y1 + sp_globals.pixrnd) >> sp_globals.pixshift; /* calculate new end-scan sp_globals.line */
+
+
+#if DEBUG
+printf("LINE_BLACK(%3.4f, %3.4f)\n",
+ (real)P1.x/(real)sp_globals.onepix,
+ (real)P1.y/(real)sp_globals.onepix);
+#endif
+
+if (sp_globals.extents_running)
+ {
+ if (sp_globals.x0_spxl > sp_globals.bmap_xmax)
+ sp_globals.bmap_xmax = sp_globals.x0_spxl;
+ if (sp_globals.x0_spxl < sp_globals.bmap_xmin)
+ sp_globals.bmap_xmin = sp_globals.x0_spxl;
+ if (sp_globals.y0_spxl > sp_globals.bmap_ymax)
+ sp_globals.bmap_ymax = sp_globals.y0_spxl;
+ if (sp_globals.y0_spxl < sp_globals.bmap_ymin)
+ sp_globals.bmap_ymin = sp_globals.y0_spxl;
+ }
+
+if (sp_globals.intercept_oflo) return;
+
+if ((how_many_y = sp_globals.y_pxl - yc) == 0) return; /* Don't draw a null line */
+
+if (how_many_y < 0) yc--; /* Predecrment downward lines */
+
+if (yc > sp_globals.y_band.band_max) /* Is start point above band? */
+ {
+ if (sp_globals.y_pxl > sp_globals.y_band.band_max) return; /* line has to go down! */
+ how_many_y = sp_globals.y_pxl - (yc = sp_globals.y_band.band_max) - 1; /* Yes, limit it */
+ }
+
+if (yc < sp_globals.y_band.band_min) /* Is start point below band? */
+ {
+ if (sp_globals.y_pxl < sp_globals.y_band.band_min) return; /* line has to go up! */
+ how_many_y = sp_globals.y_pxl - (yc = sp_globals.y_band.band_min); /* Yes, limit it */
+ }
+
+xc = (fix31)(x0 + sp_globals.pixrnd) << (16 - sp_globals.pixshift); /* Original x coordinate with built in */
+ /* rounding. 16.16 form */
+
+
+if ( (temp1 = (x1 - x0)) == 0) /* check for vertical line */
+ {
+ yc -= sp_globals.y_band.band_min; /* yc is now an offset relative to the band */
+ temp1 = (fix15)(xc >> 16);
+ if (how_many_y < 0)
+ { /* Vector down */
+ if ((how_many_y += yc + 1) < 0) how_many_y = 0; /* can't go below 0 */
+ for (i = yc; i >= how_many_y; i--)
+ sp_add_intercept_black(i,temp1);
+ }
+ else
+ { /* Vector up */
+ /* check to see that line doesn't extend beyond top of band */
+ if ((how_many_y += yc) > sp_globals.no_y_lists) how_many_y = sp_globals.no_y_lists;
+ for (i = yc; i != how_many_y; i++)
+ sp_add_intercept_black(i,temp1);
+ }
+ return;
+ }
+
+/* calculate dx_dy at 16.16 fixed point */
+
+dx_dy = ( (fix31)temp1 << 16 )/(fix31)(y1 - y0);
+
+/* We have to check for a @#$%@# possible multiply overflow */
+/* by doing another @#$*& multiply. In assembly language, */
+/* the program could just check the OVerflow flag or whatever*/
+/* works on the particular processor. This C code is meant */
+/* to be processor independant. */
+
+temp1 = (yc << sp_globals.pixshift) - y0 + sp_globals.pixrnd;
+/* This sees if the sign bits start at bit 15 */
+/* if they do, no overflow has occurred */
+
+temp2 = (fix15)(MULT16(temp1,(fix15)(dx_dy >> 16)) >> 15);
+
+if ( (temp2 != (fix15)0xFFFF) &&
+ (temp2 != 0x0000) &&
+ /* Overflow. Pick point closest to yc + .5 */
+ (ABS(temp1) < ABS((yc << sp_globals.pixshift) - y1 + sp_globals.pixrnd)) )
+ { /* use x1 instead of x0 */
+ xc = (fix31)(x1 + sp_globals.pixrnd) << (16 - sp_globals.pixshift);
+ }
+else
+ {
+/* calculate new xc at the center of the *current* scan line */
+/* due to banding, yc may be several lines away from y0 */
+/* xc += (yc + .5 - y0) * dx_dy */
+/* This multiply generates a subpixel delta. */
+/* So we shift it to be a 16.16 delta */
+
+ xc += ((fix31)temp1 * dx_dy) >> sp_globals.pixshift;
+ }
+
+yc -= sp_globals.y_band.band_min; /* yc is now an offset relative to the band */
+
+if (how_many_y < 0)
+ { /* Vector down */
+ if (how_many_y == -1)
+ sp_add_intercept_black(yc, (fix15) (xc >> 16));
+ else
+ {
+ if ((how_many_y += yc + 1) < 0) how_many_y = 0; /* can't go below 0 */
+ for (i = yc; i >= how_many_y; i--)
+ {
+ temp1 = (fix15)(xc >> 16);
+ sp_add_intercept_black(i,temp1);
+ xc -= dx_dy;
+ }
+ }
+ }
+ else
+ { /* Vector up */
+ /* check to see that line doesn't extend beyond top of band */
+ if (how_many_y == 1)
+ sp_add_intercept_black(yc, (fix15) (xc >> 16));
+ else
+ {
+ if ((how_many_y += yc) > sp_globals.no_y_lists) how_many_y = sp_globals.no_y_lists;
+ for (i = yc; i != how_many_y; i++)
+ {
+ temp1 = (fix15)(xc >> 16);
+ sp_add_intercept_black(i,temp1);
+ xc += dx_dy;
+ }
+ }
+ }
+}
+#endif
+#if INCL_BLACK
+FUNCTION boolean end_char_black()
+GDECL
+/* Called when all character data has been output
+ * Return TRUE if output process is complete
+ * Return FALSE to repeat output of the transformed data beginning
+ * with the first contour
+ */
+{
+
+fix31 xorg;
+fix31 yorg;
+#if INCL_CLIPPING
+fix31 bmap_max, bmap_min;
+#endif
+
+#if DEBUG
+printf("END_CHAR_BLACK()\n");
+#endif
+
+if (sp_globals.first_pass)
+ {
+ if (sp_globals.bmap_xmax >= sp_globals.bmap_xmin)
+ {
+ sp_globals.xmin = (sp_globals.bmap_xmin + sp_globals.pixrnd + 1) >> sp_globals.pixshift;
+ sp_globals.xmax = (sp_globals.bmap_xmax + sp_globals.pixrnd) >> sp_globals.pixshift;
+ }
+ else
+ {
+ sp_globals.xmin = sp_globals.xmax = 0;
+ }
+ if (sp_globals.bmap_ymax >= sp_globals.bmap_ymin)
+ {
+
+#if INCL_CLIPPING
+ switch(sp_globals.tcb0.xtype)
+ {
+ case 1: /* 180 degree rotation */
+ if (sp_globals.specs.flags & CLIP_TOP)
+ {
+ sp_globals.clip_ymin = (fix31)((fix31)EM_TOP * sp_globals.tcb0.yppo + ((1<<sp_globals.multshift)/2));
+ sp_globals.clip_ymin = sp_globals.clip_ymin >> sp_globals.multshift;
+ bmap_min = (sp_globals.bmap_ymin + sp_globals.pixrnd + 1) >> sp_globals.pixshift;
+ sp_globals.clip_ymin = -1 * sp_globals.clip_ymin;
+ if (bmap_min < sp_globals.clip_ymin)
+ sp_globals.ymin = sp_globals.clip_ymin;
+ else
+ sp_globals.ymin = bmap_min;
+ }
+ if (sp_globals.specs.flags & CLIP_BOTTOM)
+ {
+ sp_globals.clip_ymax = (fix31)((fix31)(-1 * EM_BOT) * sp_globals.tcb0.yppo + ((1<<sp_globals.multshift)/2));
+ sp_globals.clip_ymax = sp_globals.clip_ymax >> sp_globals.multshift;
+ bmap_max = (sp_globals.bmap_ymax + sp_globals.pixrnd) >> sp_globals.pixshift;
+ if (bmap_max < sp_globals.clip_ymax)
+ sp_globals.ymax = bmap_max;
+ else
+ sp_globals.ymax = sp_globals.clip_ymax;
+ }
+ sp_globals.clip_xmax = -sp_globals.xmin;
+ sp_globals.clip_xmin = ((sp_globals.set_width.x+32768L) >> 16) -
+ sp_globals.xmin;
+ break;
+ case 2: /* 90 degree rotation */
+ if (sp_globals.specs.flags & CLIP_TOP)
+ {
+ sp_globals.clip_xmin = (fix31)((fix31)(-1 * EM_BOT) * sp_globals.tcb0.yppo + ((1<<sp_globals.multshift)/2));
+ sp_globals.clip_xmin = sp_globals.clip_xmin >> sp_globals.multshift;
+ sp_globals.clip_xmin = -1 * sp_globals.clip_xmin;
+ bmap_min = (sp_globals.bmap_xmin + sp_globals.pixrnd + 1) >> sp_globals.pixshift;
+ if (bmap_min > sp_globals.clip_xmin)
+ sp_globals.clip_xmin = bmap_min;
+
+ /* normalize to x origin */
+ sp_globals.clip_xmin -= sp_globals.xmin;
+ }
+ if (sp_globals.specs.flags & CLIP_BOTTOM)
+ {
+ sp_globals.clip_xmax = (fix31)((fix31)EM_TOP * sp_globals.tcb0.yppo + ((1<<sp_globals.multshift)/2));
+ sp_globals.clip_xmax = sp_globals.clip_xmax >> sp_globals.multshift;
+ bmap_max = (sp_globals.bmap_xmax + sp_globals.pixrnd) >> sp_globals.pixshift;
+ if (bmap_max < sp_globals.clip_xmax)
+ sp_globals.xmax = bmap_max;
+ else
+ sp_globals.xmax = sp_globals.clip_xmax;
+ sp_globals.clip_ymax = 0;
+ if ((sp_globals.specs.flags & CLIP_TOP) &&
+ (sp_globals.ymax > sp_globals.clip_ymax))
+ sp_globals.ymax = sp_globals.clip_ymax;
+ sp_globals.clip_ymin = ((sp_globals.set_width.y+32768L) >> 16);
+ if ((sp_globals.specs.flags & CLIP_BOTTOM) &&
+ (sp_globals.ymin < sp_globals.clip_ymin))
+ sp_globals.ymin = sp_globals.clip_ymin;
+ /* normalize to x origin */
+ sp_globals.clip_xmax -= sp_globals.xmin;
+ }
+ break;
+ case 3: /* 270 degree rotation */
+ if (sp_globals.specs.flags & CLIP_TOP)
+ {
+ sp_globals.clip_xmin = (fix31)((fix31)EM_TOP * sp_globals.tcb0.yppo + ((1<<sp_globals.multshift)/2));
+ sp_globals.clip_xmin = sp_globals.clip_xmin >> sp_globals.multshift;
+ sp_globals.clip_xmin = -1 * sp_globals.clip_xmin;
+ bmap_min = (sp_globals.bmap_xmin + sp_globals.pixrnd + 1) >> sp_globals.pixshift;
+
+ /* let the minimum be the larger of these two values */
+ if (bmap_min > sp_globals.clip_xmin)
+ sp_globals.clip_xmin = bmap_min;
+
+ /* normalize the x value to new xorgin */
+ sp_globals.clip_xmin -= sp_globals.xmin;
+ }
+ if (sp_globals.specs.flags & CLIP_BOTTOM)
+ {
+ sp_globals.clip_xmax = (fix31)((fix31)(-1 * EM_BOT) * sp_globals.tcb0.yppo + ((1<<sp_globals.multshift)/2));
+ sp_globals.clip_xmax = sp_globals.clip_xmax >> sp_globals.multshift;
+ bmap_max = (sp_globals.bmap_xmax + sp_globals.pixrnd) >> sp_globals.pixshift;
+
+ /* let the max be the lesser of these two values */
+ if (bmap_max < sp_globals.clip_xmax)
+ {
+ sp_globals.xmax = bmap_max;
+ sp_globals.clip_xmax = bmap_max;
+ }
+ else
+ sp_globals.xmax = sp_globals.clip_xmax;
+
+ /* normalize the x value to new x origin */
+ sp_globals.clip_xmax -= sp_globals.xmin;
+ }
+ /* compute y clip values */
+ sp_globals.clip_ymax = ((sp_globals.set_width.y+32768L) >> 16);
+ if ((sp_globals.specs.flags & CLIP_TOP) &&
+ (sp_globals.ymax > sp_globals.clip_ymax))
+ sp_globals.ymax = sp_globals.clip_ymax;
+ sp_globals.clip_ymin = 0;
+ if ((sp_globals.specs.flags & CLIP_BOTTOM) &&
+ (sp_globals.ymin < sp_globals.clip_ymin))
+ sp_globals.ymin = sp_globals.clip_ymin;
+ break;
+ default: /* this is for zero degree rotation and arbitrary rotation */
+ if (sp_globals.specs.flags & CLIP_TOP)
+ {
+ sp_globals.clip_ymax = (fix31)((fix31)EM_TOP * sp_globals.tcb0.yppo + ((1<<sp_globals.multshift)/2));
+ sp_globals.clip_ymax = sp_globals.clip_ymax >> sp_globals.multshift;
+ bmap_max = (sp_globals.bmap_ymax + sp_globals.pixrnd) >> sp_globals.pixshift;
+ if (bmap_max > sp_globals.clip_ymax)
+ sp_globals.ymax = bmap_max;
+ else
+ sp_globals.ymax = sp_globals.clip_ymax;
+ }
+ if (sp_globals.specs.flags & CLIP_BOTTOM)
+ {
+ sp_globals.clip_ymin = (fix31)((fix31)(-1 * EM_BOT) * sp_globals.tcb0.yppo + ((1<<sp_globals.multshift)/2));
+ sp_globals.clip_ymin = sp_globals.clip_ymin >> sp_globals.multshift;
+ sp_globals.clip_ymin = - sp_globals.clip_ymin;
+ bmap_min = (sp_globals.bmap_ymin + sp_globals.pixrnd + 1) >> sp_globals.pixshift;
+ if (bmap_min < sp_globals.clip_ymin)
+ sp_globals.ymin = sp_globals.clip_ymin;
+ else
+ sp_globals.ymin = bmap_min;
+ }
+ sp_globals.clip_xmin = -sp_globals.xmin;
+ sp_globals.clip_xmax = ((sp_globals.set_width.x+32768L) >> 16) -
+ sp_globals.xmin;
+ break;
+ }
+if ( !(sp_globals.specs.flags & CLIP_TOP))
+#endif
+ sp_globals.ymax = (sp_globals.bmap_ymax + sp_globals.pixrnd) >> sp_globals.pixshift;
+
+#if INCL_CLIPPING
+if ( !(sp_globals.specs.flags & CLIP_BOTTOM))
+#endif
+
+ sp_globals.ymin = (sp_globals.bmap_ymin + sp_globals.pixrnd + 1) >> sp_globals.pixshift;
+ }
+ else
+ {
+ sp_globals.ymin = sp_globals.ymax = 0;
+ }
+
+ /* add in the rounded out part (from xform.) of the left edge */
+ if (sp_globals.tcb.xmode == 0) /* for X pix is function of X orus only add the round */
+ xorg = (((fix31)sp_globals.xmin << 16) + (sp_globals.rnd_xmin << sp_globals.poshift));
+ else
+ if (sp_globals.tcb.xmode == 1) /* for X pix is function of -X orus only, subtr. round */
+ xorg = (((fix31)sp_globals.xmin << 16) - (sp_globals.rnd_xmin << sp_globals.poshift)) ;
+ else
+ xorg = (fix31)sp_globals.xmin << 16; /* for other cases don't use round on x */
+
+ if (sp_globals.tcb.ymode == 2) /* for Y pix is function of X orus only, add round error */
+ yorg = (((fix31)sp_globals.ymin << 16) + (sp_globals.rnd_xmin << sp_globals.poshift));
+ else
+ if (sp_globals.tcb.ymode == 3) /* for Y pix is function of -X orus only, sub round */
+ yorg = (((fix31)sp_globals.ymin << 16) - (sp_globals.rnd_xmin << sp_globals.poshift));
+ else /* all other cases have no round error on yorg */
+ yorg = (fix31)sp_globals.ymin << 16;
+
+ open_bitmap(sp_globals.set_width.x, sp_globals.set_width.y, xorg, yorg,
+ sp_globals.xmax - sp_globals.xmin, sp_globals.ymax - sp_globals.ymin);
+ if (sp_globals.intercept_oflo)
+ {
+ sp_globals.y_band.band_min = sp_globals.ymin;
+ sp_globals.y_band.band_max = sp_globals.ymax;
+ init_intercepts_out();
+ sp_globals.first_pass = FALSE;
+ sp_globals.extents_running = FALSE;
+ return FALSE;
+ }
+ else
+ {
+ sp_proc_intercepts_black();
+ close_bitmap();
+ return TRUE;
+ }
+ }
+else
+ {
+ if (sp_globals.intercept_oflo)
+ {
+ reduce_band_size_out();
+ init_intercepts_out();
+ return FALSE;
+ }
+ else
+ {
+ sp_proc_intercepts_black();
+ if (next_band_out())
+ {
+ init_intercepts_out();
+ return FALSE;
+ }
+ close_bitmap();
+ return TRUE;
+ }
+ }
+}
+#endif
+
+#if INCL_BLACK
+FUNCTION LOCAL void sp_add_intercept_black(
+GDECL
+fix15 y, /* Y coordinate in relative pixel units */
+ /* (0 is lowest sample in band) */
+fix15 x) /* X coordinate of intercept in subpixel units */
+
+/* Called by line() to add an intercept to the intercept list structure
+ */
+
+{
+register fix15 from; /* Insertion pointers for the linked list sort */
+register fix15 to;
+
+#if DEBUG
+printf(" Add intercept(%2d, %d)\n", y + sp_globals.y_band.band_min,x);
+
+/* Bounds checking IS done in debug mode */
+if (y < 0) /* Y value below bottom of current band? */
+ {
+ printf(" Intecerpt less than 0!!!\007\n");
+ return;
+ }
+
+if (y > (sp_globals.no_y_lists - 1)) /* Y value above top of current band? */
+ {
+ printf(" Intercept too big for band!!!!!\007\n");
+ return;
+ }
+#endif
+
+/* Store new values */
+
+sp_intercepts.car[sp_globals.next_offset] = x;
+
+/* Find slot to insert new element (between from and to) */
+
+from = y; /* Start at list head */
+
+while( (to = sp_intercepts.cdr[from]) >= sp_globals.first_offset) /* Until to == end of list */
+ {
+ if (x <= sp_intercepts.car[to]) /* If next item is larger than or same as this one... */
+ goto insert_element; /* ... drop out and insert here */
+ from = to; /* move forward in list */
+ }
+
+insert_element: /* insert element "sp_globals.next_offset" between elements "from" */
+ /* and "to" */
+
+sp_intercepts.cdr[from] = sp_globals.next_offset;
+sp_intercepts.cdr[sp_globals.next_offset] = to;
+
+if (++sp_globals.next_offset >= MAX_INTERCEPTS) /* Intercept buffer full? */
+ {
+ sp_globals.intercept_oflo = TRUE;
+/* There may be a few more calls to "add_intercept" from the current line */
+/* To avoid problems, we set next_offset to a safe value. We don't care */
+/* if the intercept table gets trashed at this point */
+ sp_globals.next_offset = sp_globals.first_offset;
+ }
+}
+
+#endif
+
+#if INCL_BLACK
+FUNCTION LOCAL void sp_proc_intercepts_black()
+GDECL
+
+/* Called by sp_make_char to output accumulated intercept lists
+ * Clips output to sp_globals.xmin, sp_globals.xmax, sp_globals.ymin, sp_globals.ymax boundaries
+ */
+{
+register fix15 i;
+register fix15 from, to; /* Start and end of run in pixel units
+ relative to left extent of character */
+register fix15 y;
+register fix15 scan_line;
+ fix15 first_y, last_y;
+
+#if DEBUG
+printf("\nIntercept lists:\n");
+#endif
+
+#if INCL_CLIPPING
+if ((sp_globals.specs.flags & CLIP_LEFT) != 0)
+ clipleft = TRUE;
+else
+ clipleft = FALSE;
+if ((sp_globals.specs.flags & CLIP_RIGHT) != 0)
+ clipright = TRUE;
+else
+ clipright = FALSE;
+if (clipleft || clipright)
+ {
+ xmax = sp_globals.clip_xmax;
+ xmin = sp_globals.clip_xmin;
+ }
+if (!clipright)
+ xmax = ((sp_globals.set_width.x+32768L) >> 16);
+#endif
+
+if ((first_y = sp_globals.y_band.band_max) >= sp_globals.ymax)
+ first_y = sp_globals.ymax - 1; /* Clip to sp_globals.ymax boundary */
+
+if ((last_y = sp_globals.y_band.band_min) < sp_globals.ymin)
+ last_y = sp_globals.ymin; /* Clip to sp_globals.ymin boundary */
+
+last_y -= sp_globals.y_band.band_min;
+#if DEBUG
+/* Print out all of the intercept info */
+scan_line = sp_globals.ymax - first_y - 1;
+
+for (y = first_y - sp_globals.y_band.band_min; y >= last_y; y--, scan_line++)
+ {
+ i = y; /* Index head of intercept list */
+ while ((i = sp_intercepts.cdr[i]) != 0) /* Link to next intercept if present */
+ {
+ if ((from = sp_intercepts.car[i] - sp_globals.xmin) < 0)
+ from = 0; /* Clip to sp_globals.xmin boundary */
+ i = sp_intercepts.cdr[i]; /* Link to next intercept */
+ if (i == 0) /* End of list? */
+ {
+ printf("****** proc_intercepts: odd number of intercepts\n");
+ break;
+ }
+ if ((to = sp_intercepts.car[i]) > sp_globals.xmax)
+ to = sp_globals.xmax - sp_globals.xmin; /* Clip to sp_globals.xmax boundary */
+ else
+ to -= sp_globals.xmin;
+ printf(" Y = %2d (scanline %2d): %d %d:\n",
+ y + sp_globals.y_band.band_min, scan_line, from, to);
+ }
+ }
+#endif
+
+/* Draw the image */
+scan_line = sp_globals.ymax - first_y - 1;
+
+for (y = first_y - sp_globals.y_band.band_min; y >= last_y; y--, scan_line++)
+ {
+ i = y; /* Index head of intercept list */
+ while ((i = sp_intercepts.cdr[i]) != 0) /* Link to next intercept if present */
+ {
+ if ((from = sp_intercepts.car[i] - sp_globals.xmin) < 0)
+ from = 0; /* Clip to sp_globals.xmin boundary */
+ i = sp_intercepts.cdr[i]; /* Link to next intercept */
+
+ if ((to = sp_intercepts.car[i]) > sp_globals.xmax)
+ to = sp_globals.xmax - sp_globals.xmin; /* Clip to sp_globals.xmax boundary */
+ else
+ to -= sp_globals.xmin;
+ if (from >= to)
+ {
+ if (from >= sp_globals.xmax - sp_globals.xmin)
+ {
+ --from ;
+ }
+ to = from+1;
+ }
+#if INCL_CLIPPING
+ if (clipleft)
+ {
+ if (to <= xmin)
+ continue;
+ if (from < xmin)
+ from = xmin;
+ }
+ if (clipright)
+ {
+ if (from >= xmax)
+ continue;
+ if (to > xmax)
+ to = xmax;
+ }
+#endif
+ set_bitmap_bits(scan_line, from, to);
+ }
+ }
+}
+
+#endif
+
+
+
+
diff --git a/libXfont/src/Speedo/out_outl.c b/libXfont/src/Speedo/out_outl.c
new file mode 100644
index 000000000..013901092
--- /dev/null
+++ b/libXfont/src/Speedo/out_outl.c
@@ -0,0 +1,290 @@
+/* $Xorg: out_outl.c,v 1.3 2000/08/17 19:46:26 cpqbld Exp $ */
+
+/*
+
+Copyright 1989-1991, Bitstream Inc., Cambridge, MA.
+You are hereby granted permission under all Bitstream propriety rights to
+use, copy, modify, sublicense, sell, and redistribute the Bitstream Speedo
+software and the Bitstream Charter outline font for any purpose and without
+restrictions; provided, that this notice is left intact on all copies of such
+software or font and that Bitstream's trademark is acknowledged as shown below
+on all unmodified copies of such font.
+
+BITSTREAM CHARTER is a registered trademark of Bitstream Inc.
+
+
+BITSTREAM INC. DISCLAIMS ANY AND ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING
+WITHOUT LIMITATION THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+PARTICULAR PURPOSE. BITSTREAM SHALL NOT BE LIABLE FOR ANY DIRECT OR INDIRECT
+DAMAGES, INCLUDING BUT NOT LIMITED TO LOST PROFITS, LOST DATA, OR ANY OTHER
+INCIDENTAL OR CONSEQUENTIAL DAMAGES, ARISING OUT OF OR IN ANY WAY CONNECTED
+WITH THE SPEEDO SOFTWARE OR THE BITSTREAM CHARTER OUTLINE FONT.
+
+*/
+
+
+/**************************** O U T _ 2 _ 1 . C ******************************
+ * *
+ * This is the standard output module for vector output mode. *
+ * *
+ ****************************************************************************/
+
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "spdo_prv.h" /* General definitions for Speedo */
+
+
+#define DEBUG 0
+
+#if DEBUG
+#include <stdio.h>
+#define SHOW(X) printf("X = %d\n", X)
+#else
+#define SHOW(X)
+#endif
+
+/* the following macro is used to limit points on the outline to the bounding box */
+
+#define RANGECHECK(value,min,max) (((value) >= (min) ? (value) : (min)) < (max) ? (value) : (max))
+/***** GLOBAL VARIABLES *****/
+
+/***** GLOBAL FUNCTIONS *****/
+
+/***** EXTERNAL VARIABLES *****/
+
+/***** EXTERNAL FUNCTIONS *****/
+
+/***** STATIC VARIABLES *****/
+
+/***** STATIC FUNCTIONS *****/
+
+
+#if INCL_OUTLINE
+FUNCTION boolean init_outline(specsarg)
+GDECL
+specs_t GLOBALFAR *specsarg;
+/*
+ * init_out2() is called by sp_set_specs() to initialize the output module.
+ * Returns TRUE if output module can accept requested specifications.
+ * Returns FALSE otherwise.
+ */
+{
+#if DEBUG
+printf("INIT_OUT_2()\n");
+#endif
+if (specsarg->flags & (CLIP_LEFT + CLIP_RIGHT + CLIP_TOP + CLIP_BOTTOM))
+ return FALSE; /* Clipping not supported */
+return (TRUE);
+}
+#endif
+
+#if INCL_OUTLINE
+FUNCTION boolean begin_char_outline(Psw, Pmin, Pmax)
+GDECL
+point_t Psw; /* End of escapement vector (sub-pixels) */
+point_t Pmin; /* Bottom left corner of bounding box */
+point_t Pmax; /* Top right corner of bounding box */
+/*
+ * If two or more output modules are included in the configuration, begin_char2()
+ * is called by begin_char() to signal the start of character output data.
+ * If only one output module is included in the configuration, begin_char() is
+ * called by make_simp_char() and make_comp_char().
+ */
+{
+fix31 set_width_x;
+fix31 set_width_y;
+fix31 xmin;
+fix31 xmax;
+fix31 ymin;
+fix31 ymax;
+
+#if DEBUG
+printf("BEGIN_CHAR_2(%3.1f, %3.1f, %3.1f, %3.1f, %3.1f, %3.1f\n",
+ (real)Psw.x / (real)onepix, (real)Psw.y / (real)onepix,
+ (real)Pmin.x / (real)onepix, (real)Pmin.y / (real)onepix,
+ (real)Pmax.x / (real)onepix, (real)Pmax.y / (real)onepix);
+#endif
+sp_globals.poshift = 16 - sp_globals.pixshift;
+set_width_x = (fix31)Psw.x << sp_globals.poshift;
+set_width_y = (fix31)Psw.y << sp_globals.poshift;
+xmin = (fix31)Pmin.x << sp_globals.poshift;
+xmax = (fix31)Pmax.x << sp_globals.poshift;
+ymin = (fix31)Pmin.y << sp_globals.poshift;
+ymax = (fix31)Pmax.y << sp_globals.poshift;
+sp_globals.xmin = Pmin.x;
+sp_globals.xmax = Pmax.x;
+sp_globals.ymin = Pmin.y;
+sp_globals.ymax = Pmax.y;
+open_outline(set_width_x, set_width_y, xmin, xmax, ymin, ymax);
+return TRUE;
+}
+#endif
+
+#if INCL_OUTLINE
+FUNCTION void begin_sub_char_outline(Psw, Pmin, Pmax)
+GDECL
+point_t Psw; /* End of sub-char escapement vector */
+point_t Pmin; /* Bottom left corner of sub-char bounding box */
+point_t Pmax; /* Top right corner of sub-char bounding box */
+/*
+ * If two or more output modules are included in the configuration, begin_sub_char2()
+ * is called by begin_sub_char() to signal the start of sub-character output data.
+ * If only one output module is included in the configuration, begin_sub_char() is
+ * called by make_comp_char().
+ */
+{
+#if DEBUG
+printf("BEGIN_SUB_CHAR_2(%3.1f, %3.1f, %3.1f, %3.1f, %3.1f, %3.1f\n",
+ (real)Psw.x / (real)onepix, (real)Psw.y / (real)onepix,
+ (real)Pmin.x / (real)onepix, (real)Pmin.y / (real)onepix,
+ (real)Pmax.x / (real)onepix, (real)Pmax.y / (real)onepix);
+#endif
+start_new_char();
+}
+#endif
+
+
+#if INCL_OUTLINE
+FUNCTION void begin_contour_outline(P1, outside)
+GDECL
+point_t P1; /* Start point of contour */
+boolean outside; /* TRUE if outside (counter-clockwise) contour */
+/*
+ * If two or more output modules are included in the configuration, begin_contour2()
+ * is called by begin_contour() to define the start point of a new contour
+ * and to indicate whether it is an outside (counter-clockwise) contour
+ * or an inside (clockwise) contour.
+ * If only one output module is included in the configuration, begin_sub_char() is
+ * called by proc_outl_data().
+ */
+{
+fix15 x,y;
+#if DEBUG
+printf("BEGIN_CONTOUR_2(%3.1f, %3.1f, %s)\n",
+ (real)P1.x / (real)onepix, (real)P1.y / (real)onepix, outside? "outside": "inside");
+#endif
+x = RANGECHECK(P1.x,sp_globals.xmin,sp_globals.xmax);
+y = RANGECHECK(P1.y,sp_globals.ymin,sp_globals.ymax);
+
+start_contour((fix31)x << sp_globals.poshift, (fix31)y << sp_globals.poshift, outside);
+}
+#endif
+
+#if INCL_OUTLINE
+FUNCTION void curve_outline(P1, P2, P3,depth)
+GDECL
+point_t P1; /* First control point of Bezier curve */
+point_t P2; /* Second control point of Bezier curve */
+point_t P3; /* End point of Bezier curve */
+fix15 depth;
+/*
+ * If two or more output modules are included in the configuration, curve2()
+ * is called by curve() to output one curve segment.
+ * If only one output module is included in the configuration, curve() is
+ * called by proc_outl_data().
+ * This function is only called when curve output is enabled.
+ */
+{
+fix15 x1,y1,x2,y2,x3,y3;
+#if DEBUG
+printf("CURVE_2(%3.1f, %3.1f, %3.1f, %3.1f, %3.1f, %3.1f)\n",
+ (real)P1.x / (real)onepix, (real)P1.y / (real)onepix,
+ (real)P2.x / (real)onepix, (real)P2.y / (real)onepix,
+ (real)P3.x / (real)onepix, (real)P3.y / (real)onepix);
+#endif
+x1= RANGECHECK(P1.x,sp_globals.xmin,sp_globals.xmax);
+y1= RANGECHECK(P1.y,sp_globals.ymin,sp_globals.ymax);
+
+x2= RANGECHECK(P2.x,sp_globals.xmin,sp_globals.xmax);
+y2= RANGECHECK(P2.y,sp_globals.ymin,sp_globals.ymax);
+
+x3= RANGECHECK(P3.x,sp_globals.xmin,sp_globals.xmax);
+y3= RANGECHECK(P3.y,sp_globals.ymin,sp_globals.ymax);
+
+curve_to((fix31)x1 << sp_globals.poshift, (fix31)y1 << sp_globals.poshift,
+ (fix31)x2<< sp_globals.poshift, (fix31)y2 << sp_globals.poshift,
+ (fix31)x3 << sp_globals.poshift, (fix31)y3 << sp_globals.poshift);
+}
+#endif
+
+#if INCL_OUTLINE
+FUNCTION void line_outline(P1)
+GDECL
+point_t P1; /* End point of vector */
+/*
+ * If two or more output modules are included in the configuration, line2()
+ * is called by line() to output one vector.
+ * If only one output module is included in the configuration, line() is
+ * called by proc_outl_data(). If curve output is enabled, line() is also
+ * called by split_curve().
+ */
+{
+fix15 x1,y1;
+#if DEBUG
+printf("LINE_2(%3.1f, %3.1f)\n", (real)P1.x / (real)onepix, (real)P1.y / (real)onepix);
+#endif
+x1= RANGECHECK(P1.x,sp_globals.xmin,sp_globals.xmax);
+y1= RANGECHECK(P1.y,sp_globals.ymin,sp_globals.ymax);
+
+line_to((fix31)x1 << sp_globals.poshift, (fix31)y1 << sp_globals.poshift);
+}
+#endif
+
+#if INCL_OUTLINE
+FUNCTION void end_contour_outline()
+GDECL
+/*
+ * If two or more output modules are included in the configuration, end_contour2()
+ * is called by end_contour() to signal the end of a contour.
+ * If only one output module is included in the configuration, end_contour() is
+ * called by proc_outl_data().
+ */
+{
+#if DEBUG
+printf("END_CONTOUR_2()\n");
+#endif
+close_contour();
+}
+#endif
+
+
+#if INCL_OUTLINE
+FUNCTION void end_sub_char_outline()
+GDECL
+/*
+ * If two or more output modules are included in the configuration, end_sub_char2()
+ * is called by end_sub_char() to signal the end of sub-character data.
+ * If only one output module is included in the configuration, end_sub_char() is
+ * called by make_comp_char().
+ */
+{
+#if DEBUG
+printf("END_SUB_CHAR_2()\n");
+#endif
+}
+#endif
+
+
+#if INCL_OUTLINE
+FUNCTION boolean end_char_outline()
+GDECL
+/*
+ * If two or more output modules are included in the configuration, end_char2()
+ * is called by end_char() to signal the end of the character data.
+ * If only one output module is included in the configuration, end_char() is
+ * called by make_simp_char() and make_comp_char().
+ * Returns TRUE if output process is complete
+ * Returns FALSE to repeat output of the transformed data beginning
+ * with the first contour (of the first sub-char if compound).
+ */
+{
+#if DEBUG
+printf("END_CHAR_2()\n");
+#endif
+close_outline();
+return TRUE;
+}
+#endif
+
diff --git a/libXfont/src/Speedo/out_scrn.c b/libXfont/src/Speedo/out_scrn.c
new file mode 100644
index 000000000..172386ac7
--- /dev/null
+++ b/libXfont/src/Speedo/out_scrn.c
@@ -0,0 +1,1090 @@
+/* $Xorg: out_scrn.c,v 1.3 2000/08/17 19:46:26 cpqbld Exp $ */
+
+/*
+
+Copyright 1989-1991, Bitstream Inc., Cambridge, MA.
+You are hereby granted permission under all Bitstream propriety rights to
+use, copy, modify, sublicense, sell, and redistribute the Bitstream Speedo
+software and the Bitstream Charter outline font for any purpose and without
+restrictions; provided, that this notice is left intact on all copies of such
+software or font and that Bitstream's trademark is acknowledged as shown below
+on all unmodified copies of such font.
+
+BITSTREAM CHARTER is a registered trademark of Bitstream Inc.
+
+
+BITSTREAM INC. DISCLAIMS ANY AND ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING
+WITHOUT LIMITATION THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+PARTICULAR PURPOSE. BITSTREAM SHALL NOT BE LIABLE FOR ANY DIRECT OR INDIRECT
+DAMAGES, INCLUDING BUT NOT LIMITED TO LOST PROFITS, LOST DATA, OR ANY OTHER
+INCIDENTAL OR CONSEQUENTIAL DAMAGES, ARISING OUT OF OR IN ANY WAY CONNECTED
+WITH THE SPEEDO SOFTWARE OR THE BITSTREAM CHARTER OUTLINE FONT.
+
+*/
+/* $XFree86: xc/lib/font/Speedo/out_scrn.c,v 1.4 1999/12/27 00:39:25 robin Exp $ */
+
+
+/*************************** O U T _ S C R N . C *****************************
+ * *
+ * This is an output module for screen-writer mode. *
+ * *
+ *****************************************************************************/
+
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "spdo_prv.h" /* General definitions for Speedo */
+
+#define DEBUG 0
+#define LOCAL static
+#define ABS(X) ( (X < 0) ? -X : X)
+
+#if DEBUG
+#include <stdio.h>
+#define SHOW(X) printf("X = %d\n", X)
+#else
+#define SHOW(X)
+#endif
+
+
+/***** GLOBAL VARIABLES *****/
+
+/***** GLOBAL FUNCTIONS *****/
+
+/***** EXTERNAL VARIABLES *****/
+
+/***** EXTERNAL FUNCTIONS *****/
+
+/***** STATIC VARIABLES *****/
+
+/***** STATIC FUNCTIONS *****/
+
+static void sp_add_intercept_screen(PROTO_DECL2 fix15 y,fix31 x);
+static void sp_proc_intercepts_screen(PROTO_DECL1);
+
+
+#if INCL_SCREEN
+FUNCTION boolean init_screen(
+GDECL
+specs_t FONTFAR *specsarg)
+/*
+ * init_out0() is called by sp_set_specs() to initialize the output module.
+ * Returns TRUE if output module can accept requested specifications.
+ * Returns FALSE otherwise.
+ */
+{
+#if DEBUG
+printf("INIT_SCREEN()\n");
+#endif
+return (TRUE);
+}
+#endif
+
+
+#if INCL_SCREEN
+FUNCTION boolean begin_char_screen(
+GDECL
+point_t Psw,
+point_t Pmin,
+point_t Pmax)
+/* Called once at the start of the character generation process
+ */
+{
+#if DEBUG
+printf("BEGIN_CHAR_SCREEN(%3.1f, %3.1f, %3.1f, %3.1f, %3.1f, %3.1f\n",
+ (real)Psw.x / (real)sp_globals.onepix, (real)Psw.y / (real)sp_globals.onepix,
+ (real)Pmin.x / (real)sp_globals.onepix, (real)Pmin.y / (real)sp_globals.onepix,
+ (real)Pmax.x / (real)sp_globals.onepix, (real)Pmax.y / (real)sp_globals.onepix);
+#endif
+if (sp_globals.pixshift > 8)
+ sp_intercepts.fracpix = sp_globals.onepix << (8 - sp_globals.pixshift);
+else
+ sp_intercepts.fracpix = sp_globals.onepix >> (sp_globals.pixshift - 8);
+
+init_char_out(Psw,Pmin,Pmax);
+
+return TRUE;
+}
+#endif
+
+
+#if INCL_SCREEN
+FUNCTION void begin_contour_screen(
+GDECL
+point_t P1,
+boolean outside)
+/* Called at the start of each contour
+ */
+{
+
+#if DEBUG
+printf("BEGIN_CONTOUR_SCREEN(%3.1f, %3.1f, %s)\n",
+ (real)P1.x / (real)sp_globals.onepix, (real)P1.y / (real)sp_globals.onepix, outside? "outside": "inside");
+#endif
+sp_globals.x0_spxl = P1.x;
+sp_globals.y0_spxl = P1.y;
+sp_globals.y_pxl = (sp_globals.y0_spxl + sp_globals.pixrnd) >> sp_globals.pixshift;
+}
+#endif
+
+#if INCL_SCREEN
+
+static FUNCTION void vert_line_screen(
+GDECL
+fix31 x,
+fix15 y1, fix15 y2)
+{
+
+#ifdef DBGCRV
+printf("VERT_LINE_SCREEN(%6.4f, %6.4f, %6.4f)\n",
+ (real)(x - 32768) / 65536.0,
+ (real)(y1 - 32768) / 65536.0,
+ (real)(y2 - 32768) / 65536.0);
+#endif
+
+if (sp_globals.intercept_oflo)
+ return;
+
+if (y1 > y2) /* Line goes downwards ? */
+ {
+ if (y1 > (sp_globals.y_band.band_max + 1)) /* Start point above top of band? */
+ y1 = sp_globals.y_band.band_max + 1; /* Adjust start point to top of band */
+ if (y2 < sp_globals.y_band.band_min) /* End point below bottom of band? */
+ y2 = sp_globals.y_band.band_min; /* Adjust end point bottom of band */
+
+ y1 -= sp_globals.y_band.band_min; /* Translate start point to band origin */
+ y2 -= sp_globals.y_band.band_min; /* Translate end point to band origin */
+
+ while (y2 < y1) /* At least one intercept left? */
+ {
+ sp_add_intercept_screen(--y1, x); /* Add intercept */
+ }
+ }
+else if (y2 > y1) /* Line goes upwards ? */
+ {
+ if (y1 < sp_globals.y_band.band_min) /* Start point below bottom of band? */
+ y1 = sp_globals.y_band.band_min; /* Adjust start point to bottom of band */
+ if (y2 > (sp_globals.y_band.band_max + 1)) /* End point above top of band? */
+ y2 = sp_globals.y_band.band_max + 1; /* Adjust end point to top of band */
+
+ y1 -= sp_globals.y_band.band_min; /* Translate start point to band origin */
+ y2 -= sp_globals.y_band.band_min; /* Translate end point to band origin */
+
+ while (y1 < y2) /* At least one intercept left? */
+ {
+ sp_add_intercept_screen(y1++, x); /* Add intercept */
+ }
+ }
+
+
+}
+
+static FUNCTION void scan_curve_screen(
+GDECL
+fix31 X0, fix31 Y0, fix31 X1, fix31 Y1, fix31 X2, fix31 Y2, fix31 X3, fix31 Y3)
+/* Called for each curve in the transformed character if curves out enabled
+ */
+{
+fix31 Pmidx;
+fix31 Pmidy;
+fix31 Pctrl1x;
+fix31 Pctrl1y;
+fix31 Pctrl2x;
+fix31 Pctrl2y;
+
+#ifdef DBGCRV
+printf("SCAN_CURVE_SCREEN(%6.4f, %6.4f, %6.4f, %6.4f, %6.4f, %6.4f, %6.4f, %6.4f)\n",
+ (real)(X0-32768) / 65536.0, (real)(Y0-32768) / 65536.0,
+ (real)(X1-32768) / 65536.0, (real)(Y1-32768) / 65536.0,
+ (real)(X2-32768) / 65536.0, (real)(Y2-32768) / 65536.0,
+ (real)(X3-32768) / 65536.0, (real)(Y3-32768) / 65536.0);
+#endif
+
+if (((Y3 >> 16)) == (Y0 >> 16) || (Y3+1) == Y0 || Y3 == (Y0+1))
+ {
+ return;
+ }
+if ((X3 >> 16) == (X0 >> 16))
+ {
+ vert_line_screen(X3,(fix15)(Y0>>16),(fix15)(Y3>>16));
+ return;
+ }
+Pmidx = (X0 + (X1 + X2) * 3 + X3 + 4 ) >> 3;
+Pmidy = (Y0 + (Y1 + Y2) * 3 + Y3 + 4 ) >> 3;
+
+Pctrl1x = (X0 + X1 + 1 ) >> 1;
+Pctrl1y = (Y0 + Y1 + 1) >> 1;
+Pctrl2x = (X0 + (X1 << 1) + X2 + 2 ) >> 2;
+Pctrl2y = (Y0 + (Y1 << 1) + Y2 + 2 ) >> 2;
+scan_curve_screen(X0,Y0, Pctrl1x, Pctrl1y, Pctrl2x,Pctrl2y, Pmidx,Pmidy);
+
+Pctrl1x = (X1 + (X2 << 1) + X3 + 2 ) >> 2;
+Pctrl1y = (Y1 + (Y2 << 1) + Y3 + 2 ) >> 2;
+Pctrl2x = (X2 + X3 + 1 ) >> 1;
+Pctrl2y = (Y2 + Y3 + 1 ) >> 1;
+scan_curve_screen(Pmidx,Pmidy, Pctrl1x,Pctrl1y, Pctrl2x,Pctrl2y, X3,Y3);
+}
+
+FUNCTION void curve_screen(
+GDECL
+point_t P1, point_t P2, point_t P3,
+fix15 depth)
+{
+fix31 X0;
+fix31 Y0;
+fix31 X1;
+fix31 Y1;
+fix31 X2;
+fix31 Y2;
+fix31 X3;
+fix31 Y3;
+#if DEBUG
+printf("CURVE_SCREEN(%6.4f, %6.4f, %6.4f, %6.4f, %6.4f, %6.4f)\n",
+ (real)P1.x / (real)sp_globals.onepix, (real)P1.y / (real)sp_globals.onepix,
+ (real)P2.x / (real)sp_globals.onepix, (real)P2.y / (real)sp_globals.onepix,
+ (real)P3.x / (real)sp_globals.onepix, (real)P3.y / (real)sp_globals.onepix);
+#endif
+
+
+if (sp_globals.extents_running) /* Accumulate actual character extents if required */
+ {
+ if (P3.x > sp_globals.bmap_xmax)
+ sp_globals.bmap_xmax = P3.x;
+ if (P3.x < sp_globals.bmap_xmin)
+ sp_globals.bmap_xmin = P3.x;
+ if (P3.y > sp_globals.bmap_ymax)
+ sp_globals.bmap_ymax = P3.y;
+ if (P3.y < sp_globals.bmap_ymin)
+ sp_globals.bmap_ymin = P3.y;
+ }
+
+X0 = ((fix31)sp_globals.x0_spxl << sp_globals.poshift) + (fix31)32768;
+Y0 = ((fix31)sp_globals.y0_spxl << sp_globals.poshift) + (fix31)32768;
+X1 = ((fix31)P1.x << sp_globals.poshift) + (fix31)32768;
+Y1 = ((fix31)P1.y << sp_globals.poshift) + (fix31)32768;
+X2 = ((fix31)P2.x << sp_globals.poshift) + (fix31)32768;
+Y2 = ((fix31)P2.y << sp_globals.poshift) + (fix31)32768;
+X3 = ((fix31)P3.x << sp_globals.poshift) + (fix31)32768;
+Y3 = ((fix31)P3.y << sp_globals.poshift) + (fix31)32768;
+
+if (((Y0 - Y3) * sp_globals.tcb.mirror) > 0)
+ {
+ sp_intercepts.leftedge = LEFT_INT;
+ }
+else
+ {
+ sp_intercepts.leftedge = 0;
+ }
+
+scan_curve_screen(X0,Y0,X1,Y1,X2,Y2,X3,Y3);
+sp_globals.x0_spxl = P3.x;
+sp_globals.y0_spxl = P3.y;
+sp_globals.y_pxl = (P3.y + sp_globals.pixrnd) >> sp_globals.pixshift; /* calculate new end-scan sp_globals.line */
+}
+#endif
+
+
+#if INCL_SCREEN
+FUNCTION void line_screen(
+GDECL
+point_t P1)
+/* Called for each vector in the transformed character
+ */
+{
+register fix15 how_many_y; /* # of intercepts at y = n + 1/2 */
+register fix15 yc; /* Current scan-line */
+ fix15 temp1; /* various uses */
+ fix15 temp2; /* various uses */
+register fix31 dx_dy; /* slope of line in 16.16 form */
+register fix31 xc; /* high-precision (16.16) x coordinate */
+ fix15 x0,y0,x1,y1; /* PIX.FRAC start and endpoints */
+
+x0 = sp_globals.x0_spxl; /* get start of line (== current point) */
+y0 = sp_globals.y0_spxl;
+sp_globals.x0_spxl = x1 = P1.x; /* end of line */
+sp_globals.y0_spxl = y1 = P1.y; /* (also update current point to end of line) */
+
+yc = sp_globals.y_pxl; /* current scan line = end of last line */
+sp_globals.y_pxl = (y1 + sp_globals.pixrnd) >> sp_globals.pixshift; /* calculate new end-scan sp_globals.line */
+
+
+#if DEBUG
+printf("LINE_SCREEN(%3.4f, %3.4f)\n",
+ (real)P1.x/(real)sp_globals.onepix,
+ (real)P1.y/(real)sp_globals.onepix);
+#endif
+
+if (sp_globals.extents_running)
+ {
+ if (sp_globals.x0_spxl > sp_globals.bmap_xmax)
+ sp_globals.bmap_xmax = sp_globals.x0_spxl;
+ if (sp_globals.x0_spxl < sp_globals.bmap_xmin)
+ sp_globals.bmap_xmin = sp_globals.x0_spxl;
+ if (sp_globals.y0_spxl > sp_globals.bmap_ymax)
+ sp_globals.bmap_ymax = sp_globals.y0_spxl;
+ if (sp_globals.y0_spxl < sp_globals.bmap_ymin)
+ sp_globals.bmap_ymin = sp_globals.y0_spxl;
+ }
+
+if (sp_globals.intercept_oflo) return;
+
+if ((how_many_y = sp_globals.y_pxl - yc) == 0) return; /* Don't draw a null line */
+
+xc = (fix31)(x0 + sp_globals.pixrnd) << (16 - sp_globals.pixshift); /* Original x coordinate with built in */
+ /* rounding. 16.16 form */
+
+if (how_many_y < 0)
+ {
+ yc--; /* Predecrment downward lines */
+ }
+
+if ((how_many_y * sp_globals.tcb.mirror) < 0)
+ {
+ sp_intercepts.leftedge = LEFT_INT;
+ }
+else
+ {
+ sp_intercepts.leftedge = 0;
+ }
+
+if (yc > sp_globals.y_band.band_max) /* Is start point above band? */
+ {
+ if (sp_globals.y_pxl > sp_globals.y_band.band_max) return; /* line has to go down! */
+ how_many_y = sp_globals.y_pxl - (yc = sp_globals.y_band.band_max) - 1; /* Yes, limit it */
+ }
+
+if (yc < sp_globals.y_band.band_min) /* Is start point below band? */
+ {
+ if (sp_globals.y_pxl < sp_globals.y_band.band_min) return; /* line has to go up! */
+ how_many_y = sp_globals.y_pxl - (yc = sp_globals.y_band.band_min); /* Yes, limit it */
+ }
+
+if ( (temp1 = (x1 - x0)) == 0) /* check for vertical line */
+ {
+ dx_dy = 0L; /* Zero slope, leave xc alone */
+ goto skip_calc;
+ }
+
+/* calculate dx_dy at 16.16 fixed point */
+
+dx_dy = ( (fix31)temp1 << 16 )/(fix31)(y1 - y0);
+
+/* We have to check for a @#$%@# possible multiply overflow */
+/* by doing another @#$*& multiply. In assembly language, */
+/* the program could just check the OVerflow flag or whatever*/
+/* works on the particular processor. This C code is meant */
+/* to be processor independant. */
+
+temp1 = (yc << sp_globals.pixshift) - y0 + sp_globals.pixrnd;
+/* This sees if the sign bits start at bit 15 */
+/* if they do, no overflow has occurred */
+
+temp2 = (fix15)(MULT16(temp1,(fix15)(dx_dy >> 16)) >> 15);
+
+if ( (temp2 != (fix15)-1) &&
+ (temp2 != 0x0000) )
+ { /* Overflow. Pick point closest to yc + .5 */
+ if (ABS(temp1) < ABS((yc << sp_globals.pixshift) - y1 + sp_globals.pixrnd))
+ { /* use x1 instead of x0 */
+ xc = (fix31)(x1 + sp_globals.pixrnd) << (16 - sp_globals.pixshift);
+ }
+ goto skip_calc;
+ }
+/* calculate new xc at the center of the *current* scan line */
+/* due to banding, yc may be several lines away from y0 */
+/* xc += (yc + .5 - y0) * dx_dy */
+/* This multiply generates a subpixel delta. */
+/* So we shift it to be a 16.16 delta */
+
+xc += ((fix31)temp1 * dx_dy) >> sp_globals.pixshift;
+
+skip_calc:
+
+yc -= sp_globals.y_band.band_min; /* yc is now an offset relative to the band */
+
+if (how_many_y < 0)
+ { /* Vector down */
+ if ((how_many_y += yc + 1) < 0) how_many_y = 0; /* can't go below 0 */
+ while(yc >= how_many_y)
+ {
+ sp_add_intercept_screen(yc--,xc);
+ xc -= dx_dy;
+ }
+ }
+ else
+ { /* Vector up */
+ /* check to see that line doesn't extend beyond top of band */
+ if ((how_many_y += yc) > sp_globals.no_y_lists) how_many_y = sp_globals.no_y_lists;
+ while(yc != how_many_y)
+ {
+ sp_add_intercept_screen(yc++,xc);
+ xc += dx_dy;
+ }
+ }
+}
+#endif
+
+#if INCL_SCREEN
+FUNCTION void end_contour_screen()
+GDECL
+/* Called after the last vector in each contour
+ */
+{
+#if DEBUG
+printf("END_CONTOUR_SCREEN()\n");
+#endif
+sp_intercepts.inttype[sp_globals.next_offset-1] |= END_INT;
+}
+#endif
+
+
+
+#if INCL_SCREEN
+FUNCTION boolean end_char_screen()
+GDECL
+/* Called when all character data has been output
+ * Return TRUE if output process is complete
+ * Return FALSE to repeat output of the transformed data beginning
+ * with the first contour
+ */
+{
+
+fix31 xorg;
+fix31 yorg;
+
+#if INCL_CLIPPING
+fix31 em_max, em_min, bmap_max, bmap_min;
+#endif
+
+#if DEBUG
+printf("END_CHAR_SCREEN()\n");
+#endif
+
+if (sp_globals.first_pass)
+ {
+ if (sp_globals.bmap_xmax >= sp_globals.bmap_xmin)
+ {
+ sp_globals.xmin = (sp_globals.bmap_xmin + sp_globals.pixrnd + 1) >> sp_globals.pixshift;
+ sp_globals.xmax = (sp_globals.bmap_xmax + sp_globals.pixrnd) >> sp_globals.pixshift;
+ }
+ else
+ {
+ sp_globals.xmin = sp_globals.xmax = 0;
+ }
+ if (sp_globals.bmap_ymax >= sp_globals.bmap_ymin)
+ {
+
+#if INCL_CLIPPING
+ switch(sp_globals.tcb0.xtype)
+ {
+ case 1: /* 180 degree rotation */
+ if (sp_globals.specs.flags & CLIP_TOP)
+ {
+ sp_globals.clip_ymin = (fix31)((fix31)EM_TOP * sp_globals.tcb0.yppo + ((1<<sp_globals.multshift)/2));
+ sp_globals.clip_ymin = sp_globals.clip_ymin >> sp_globals.multshift;
+ bmap_min = (sp_globals.bmap_ymin + sp_globals.pixrnd + 1) >> sp_globals.pixshift;
+ sp_globals.clip_ymin = -1 * sp_globals.clip_ymin;
+ if (bmap_min < sp_globals.clip_ymin)
+ sp_globals.ymin = sp_globals.clip_ymin;
+ else
+ sp_globals.ymin = bmap_min;
+ }
+ if (sp_globals.specs.flags & CLIP_BOTTOM)
+ {
+ sp_globals.clip_ymax = (fix31)((fix31)(-1 * EM_BOT) * sp_globals.tcb0.yppo + ((1<<sp_globals.multshift)/2));
+ sp_globals.clip_ymax = sp_globals.clip_ymax >> sp_globals.multshift;
+ bmap_max = (sp_globals.bmap_ymax + sp_globals.pixrnd) >> sp_globals.pixshift;
+ if (bmap_max < sp_globals.clip_ymax)
+ sp_globals.ymax = bmap_max;
+ else
+ sp_globals.ymax = sp_globals.clip_ymax;
+ }
+ sp_globals.clip_xmax = -sp_globals.xmin;
+ sp_globals.clip_xmin = ((sp_globals.set_width.x+32768L) >> 16) -
+ sp_globals.xmin;
+ break;
+ case 2: /* 90 degree rotation */
+ if (sp_globals.specs.flags & CLIP_TOP)
+ {
+ sp_globals.clip_xmin = (fix31)((fix31)(-1 * EM_BOT) * sp_globals.tcb0.yppo + ((1<<sp_globals.multshift)/2));
+ sp_globals.clip_xmin = sp_globals.clip_xmin >> sp_globals.multshift;
+ sp_globals.clip_xmin = -1 * sp_globals.clip_xmin;
+ bmap_min = (sp_globals.bmap_xmin + sp_globals.pixrnd + 1) >> sp_globals.pixshift;
+ if (bmap_min > sp_globals.clip_xmin)
+ sp_globals.clip_xmin = bmap_min;
+
+ /* normalize to x origin */
+ sp_globals.clip_xmin -= sp_globals.xmin;
+ }
+ if (sp_globals.specs.flags & CLIP_BOTTOM)
+ {
+ sp_globals.clip_xmax = (fix31)((fix31)EM_TOP * sp_globals.tcb0.yppo + ((1<<sp_globals.multshift)/2));
+ sp_globals.clip_xmax = sp_globals.clip_xmax >> sp_globals.multshift;
+ bmap_max = (sp_globals.bmap_xmax + sp_globals.pixrnd) >> sp_globals.pixshift;
+ if (bmap_max < sp_globals.clip_xmax)
+ sp_globals.xmax = bmap_max;
+ else
+ sp_globals.xmax = sp_globals.clip_xmax;
+ sp_globals.clip_ymax = 0;
+ if ((sp_globals.specs.flags & CLIP_TOP) &&
+ (sp_globals.ymax > sp_globals.clip_ymax))
+ sp_globals.ymax = sp_globals.clip_ymax;
+ sp_globals.clip_ymin = ((sp_globals.set_width.y+32768L) >> 16);
+ if ((sp_globals.specs.flags & CLIP_BOTTOM) &&
+ (sp_globals.ymin < sp_globals.clip_ymin))
+ sp_globals.ymin = sp_globals.clip_ymin;
+ /* normalize to x origin */
+ sp_globals.clip_xmax -= sp_globals.xmin;
+ }
+ break;
+ case 3: /* 270 degree rotation */
+ if (sp_globals.specs.flags & CLIP_TOP)
+ {
+ sp_globals.clip_xmin = (fix31)((fix31)EM_TOP * sp_globals.tcb0.yppo + ((1<<sp_globals.multshift)/2));
+ sp_globals.clip_xmin = sp_globals.clip_xmin >> sp_globals.multshift;
+ sp_globals.clip_xmin = -1 * sp_globals.clip_xmin;
+ bmap_min = (sp_globals.bmap_xmin + sp_globals.pixrnd + 1) >> sp_globals.pixshift;
+
+ /* let the minimum be the larger of these two values */
+ if (bmap_min > sp_globals.clip_xmin)
+ sp_globals.clip_xmin = bmap_min;
+
+ /* normalize the x value to new xorgin */
+ sp_globals.clip_xmin -= sp_globals.xmin;
+ }
+ if (sp_globals.specs.flags & CLIP_BOTTOM)
+ {
+ sp_globals.clip_xmax = (fix31)((fix31)(-1 * EM_BOT) * sp_globals.tcb0.yppo + ((1<<sp_globals.multshift)/2));
+ sp_globals.clip_xmax = sp_globals.clip_xmax >> sp_globals.multshift;
+ bmap_max = (sp_globals.bmap_xmax + sp_globals.pixrnd) >> sp_globals.pixshift;
+
+ /* let the max be the lesser of these two values */
+ if (bmap_max < sp_globals.clip_xmax)
+ {
+ sp_globals.xmax = bmap_max;
+ sp_globals.clip_xmax = bmap_max;
+ }
+ else
+ sp_globals.xmax = sp_globals.clip_xmax;
+
+ /* normalize the x value to new x origin */
+ sp_globals.clip_xmax -= sp_globals.xmin;
+ }
+ /* compute y clip values */
+ sp_globals.clip_ymax = ((sp_globals.set_width.y+32768L) >> 16);
+ if ((sp_globals.specs.flags & CLIP_TOP) &&
+ (sp_globals.ymax > sp_globals.clip_ymax))
+ sp_globals.ymax = sp_globals.clip_ymax;
+ sp_globals.clip_ymin = 0;
+ if ((sp_globals.specs.flags & CLIP_BOTTOM) &&
+ (sp_globals.ymin < sp_globals.clip_ymin))
+ sp_globals.ymin = sp_globals.clip_ymin;
+ break;
+ default: /* this is for zero degree rotation and arbitrary rotation */
+ if (sp_globals.specs.flags & CLIP_TOP)
+ {
+ sp_globals.clip_ymax = (fix31)((fix31)EM_TOP * sp_globals.tcb0.yppo + ((1<<sp_globals.multshift)/2));
+ sp_globals.clip_ymax = sp_globals.clip_ymax >> sp_globals.multshift;
+ bmap_max = (sp_globals.bmap_ymax + sp_globals.pixrnd) >> sp_globals.pixshift;
+ if (bmap_max > sp_globals.clip_ymax)
+ sp_globals.ymax = bmap_max;
+ else
+ sp_globals.ymax = sp_globals.clip_ymax;
+ }
+ if (sp_globals.specs.flags & CLIP_BOTTOM)
+ {
+ sp_globals.clip_ymin = (fix31)((fix31)(-1 * EM_BOT) * sp_globals.tcb0.yppo + ((1<<sp_globals.multshift)/2));
+ sp_globals.clip_ymin = sp_globals.clip_ymin >> sp_globals.multshift;
+ sp_globals.clip_ymin = - sp_globals.clip_ymin;
+ bmap_min = (sp_globals.bmap_ymin + sp_globals.pixrnd + 1) >> sp_globals.pixshift;
+ if (bmap_min < sp_globals.clip_ymin)
+ sp_globals.ymin = sp_globals.clip_ymin;
+ else
+ sp_globals.ymin = bmap_min;
+ }
+ sp_globals.clip_xmin = -sp_globals.xmin;
+ sp_globals.clip_xmax = ((sp_globals.set_width.x+32768L) >> 16) -
+ sp_globals.xmin;
+ break;
+ }
+if ( !(sp_globals.specs.flags & CLIP_TOP))
+#endif
+ sp_globals.ymax = (sp_globals.bmap_ymax + sp_globals.pixrnd) >> sp_globals.pixshift;
+
+#if INCL_CLIPPING
+if ( !(sp_globals.specs.flags & CLIP_BOTTOM))
+#endif
+
+ sp_globals.ymin = (sp_globals.bmap_ymin + sp_globals.pixrnd + 1) >> sp_globals.pixshift;
+ }
+ else
+ {
+ sp_globals.ymin = sp_globals.ymax = 0;
+ }
+
+ /* add in the rounded out part (from xform.) of the left edge */
+ if (sp_globals.tcb.xmode == 0) /* for X pix is function of X orus only add the round */
+ xorg = (((fix31)sp_globals.xmin << 16) + (sp_globals.rnd_xmin << sp_globals.poshift));
+ else
+ if (sp_globals.tcb.xmode == 1) /* for X pix is function of -X orus only, subtr. round */
+ xorg = (((fix31)sp_globals.xmin << 16) - (sp_globals.rnd_xmin << sp_globals.poshift)) ;
+ else
+ xorg = (fix31)sp_globals.xmin << 16; /* for other cases don't use round on x */
+
+ if (sp_globals.tcb.ymode == 2) /* for Y pix is function of X orus only, add round error */
+ yorg = (((fix31)sp_globals.ymin << 16) + (sp_globals.rnd_xmin << sp_globals.poshift));
+ else
+ if (sp_globals.tcb.ymode == 3) /* for Y pix is function of -X orus only, sub round */
+ yorg = (((fix31)sp_globals.ymin << 16) - (sp_globals.rnd_xmin << sp_globals.poshift));
+ else /* all other cases have no round error on yorg */
+ yorg = (fix31)sp_globals.ymin << 16;
+
+ open_bitmap(sp_globals.set_width.x, sp_globals.set_width.y, xorg, yorg,
+ sp_globals.xmax - sp_globals.xmin, sp_globals.ymax - sp_globals.ymin);
+ if (sp_globals.intercept_oflo)
+ {
+ sp_globals.y_band.band_min = sp_globals.ymin;
+ sp_globals.y_band.band_max = sp_globals.ymax;
+ init_intercepts_out();
+ sp_globals.first_pass = FALSE;
+ sp_globals.extents_running = FALSE;
+ return FALSE;
+ }
+ else
+ {
+ sp_proc_intercepts_screen();
+ close_bitmap();
+ return TRUE;
+ }
+ }
+else
+ {
+ if (sp_globals.intercept_oflo)
+ {
+ reduce_band_size_out();
+ init_intercepts_out();
+ return FALSE;
+ }
+ else
+ {
+ sp_proc_intercepts_screen();
+ if (next_band_out())
+ {
+ init_intercepts_out();
+ return FALSE;
+ }
+ close_bitmap();
+ return TRUE;
+ }
+ }
+}
+#endif
+
+#if INCL_SCREEN
+FUNCTION LOCAL void sp_add_intercept_screen(
+GDECL
+fix15 y, /* Y coordinate in relative pixel units */
+ /* (0 is lowest sample in band) */
+fix31 x) /* X coordinate of intercept in subpixel units */
+
+/* Called by line() to add an intercept to the intercept list structure
+ */
+
+{
+register fix15 from; /* Insertion pointers for the linked list sort */
+register fix15 to;
+register fix15 xloc;
+register fix15 xfrac;
+
+#if DEBUG
+printf(" Add intercept(%2d, %x)\n", y + sp_globals.y_band.band_min, x);
+
+/* Bounds checking IS done in debug mode */
+if (y < 0) /* Y value below bottom of current band? */
+ {
+ printf(" Intecerpt less than 0!!!\007\n");
+ return;
+ }
+
+if (y > (sp_globals.no_y_lists - 1)) /* Y value above top of current band? */
+ {
+ printf(" Intercept too big for band!!!!!\007\n");
+ return;
+ }
+#endif
+
+/* Store new values */
+
+sp_intercepts.car[sp_globals.next_offset] = xloc = (fix15)(x >> 16);
+sp_intercepts.inttype[sp_globals.next_offset] = sp_intercepts.leftedge | (xfrac = ((x >> 8) & FRACTION));
+
+/* Find slot to insert new element (between from and to) */
+
+from = y; /* Start at list head */
+
+while( (to = sp_intercepts.cdr[from]) != 0) /* Until to == end of list */
+ {
+ if (xloc < sp_intercepts.car[to]) /* If next item is larger than or same as this one... */
+ goto insert_element; /* ... drop out and insert here */
+ else if (xloc == sp_intercepts.car[to] && xfrac < (sp_intercepts.inttype[to] & FRACTION))
+ goto insert_element; /* ... drop out and insert here */
+ from = to; /* move forward in list */
+ }
+
+insert_element: /* insert element "sp_globals.next_offset" between elements "from" */
+ /* and "to" */
+
+sp_intercepts.cdr[from] = sp_globals.next_offset;
+sp_intercepts.cdr[sp_globals.next_offset] = to;
+
+if (++sp_globals.next_offset >= MAX_INTERCEPTS) /* Intercept buffer full? */
+ {
+ sp_globals.intercept_oflo = TRUE;
+/* There may be a few more calls to "add_intercept" from the current line */
+/* To avoid problems, we set next_offset to a safe value. We don't care */
+/* if the intercept table gets trashed at this point */
+ sp_globals.next_offset = sp_globals.first_offset;
+ }
+}
+
+#endif
+
+#if INCL_SCREEN
+FUNCTION LOCAL void sp_proc_intercepts_screen()
+GDECL
+
+/* Called by sp_make_char to output accumulated intercept lists
+ * Clips output to sp_globals.xmin, sp_globals.xmax, sp_globals.ymin, sp_globals.ymax boundaries
+ */
+{
+register fix15 i,j, jplus1, iminus1;
+fix15 k,nextk, previ;
+register fix15 from, to; /* Start and end of run in pixel units
+ relative to left extent of character */
+register fix15 y;
+register fix15 scan_line;
+ fix15 first_y, last_y;
+ fix15 xsave;
+
+
+fix15 diff;
+
+#if DEBUG
+printf("\nPROC_INTERCEPTS_SCREEN: Intercept lists before:\n");
+#endif
+
+#if INCL_CLIPPING
+if ((sp_globals.specs.flags & CLIP_LEFT) != 0)
+ clipleft = TRUE;
+else
+ clipleft = FALSE;
+if ((sp_globals.specs.flags & CLIP_RIGHT) != 0)
+ clipright = TRUE;
+else
+ clipright = FALSE;
+if (clipleft || clipright)
+ {
+ xmax = sp_globals.clip_xmax + sp_globals.xmin;
+ xmin = sp_globals.clip_xmin + sp_globals.xmin;
+ }
+if (!clipright)
+ xmax = ((sp_globals.set_width.x+32768L) >> 16);
+#endif
+
+if ((first_y = sp_globals.y_band.band_max) >= sp_globals.ymax)
+ first_y = sp_globals.ymax - 1; /* Clip to sp_globals.ymax boundary */
+
+if ((last_y = sp_globals.y_band.band_min) < sp_globals.ymin)
+ last_y = sp_globals.ymin; /* Clip to sp_globals.ymin boundary */
+
+last_y -= sp_globals.y_band.band_min;
+
+#if DEBUG
+/* Print out all of the intercept info */
+scan_line = sp_globals.ymax - first_y - 1;
+
+for (y = first_y - sp_globals.y_band.band_min; y >= last_y; y--, scan_line++)
+ {
+ i = y; /* Index head of intercept list */
+ while ((i = sp_intercepts.cdr[i]) != 0) /* Link to next intercept if present */
+ {
+ if ((from = sp_intercepts.car[i] - sp_globals.xmin) < 0)
+ from = 0; /* Clip to sp_globals.xmin boundary */
+ i = sp_intercepts.cdr[i]; /* Link to next intercept */
+ if (i == 0) /* End of list? */
+ {
+ printf("****** proc_intercepts: odd number of intercepts\n");
+ break;
+ }
+ if ((to = sp_intercepts.car[i]) > sp_globals.xmax)
+ to = sp_globals.xmax - sp_globals.xmin; /* Clip to sp_globals.xmax boundary */
+ else
+ to -= sp_globals.xmin;
+ printf(" Y = %2d (scanline %2d): %d %d:\n",
+ y + sp_globals.y_band.band_min, scan_line, from, to);
+ }
+ }
+#endif
+
+/* CHECK INTERCEPT LIST FOR DROPOUT AND WINDING, FIX IF NECESSARY */
+
+for (y = first_y - sp_globals.y_band.band_min; y >= last_y; y--)
+ {
+ previ = y;
+ i = sp_intercepts.cdr[y]; /* Index head of intercept list */
+ while (i != 0) /* Link to next intercept if present */
+ {
+ j = i;
+ i = sp_intercepts.cdr[i]; /* Link to next intercept */
+ if (sp_intercepts.inttype[i] & LEFT_INT)
+ {
+ if (sp_intercepts.inttype[j] & LEFT_INT)
+ {
+ do { i = sp_intercepts.cdr[i]; } while (sp_intercepts.inttype[i] & LEFT_INT);
+ do { i = sp_intercepts.cdr[i]; } while (sp_intercepts.cdr[i] && !(sp_intercepts.inttype[sp_intercepts.cdr[i]] & LEFT_INT));
+ sp_intercepts.cdr[j] = i;
+ }
+ else
+ {
+ xsave = sp_intercepts.car[j];
+ sp_intercepts.car[j] = sp_intercepts.car[i];
+ sp_intercepts.car[i] = xsave;
+
+ xsave = sp_intercepts.inttype[j];
+ sp_intercepts.inttype[j] = sp_intercepts.inttype[i] & FRACTION;
+ sp_intercepts.inttype[i] = xsave | LEFT_INT;
+
+ sp_intercepts.cdr[previ] = i;
+ sp_intercepts.cdr[j] = sp_intercepts.cdr[i];
+ sp_intercepts.cdr[i] = j;
+ i = j;
+ j = sp_intercepts.cdr[previ];
+ }
+ }
+
+ if (sp_intercepts.car[j] < sp_globals.xmin)
+ sp_intercepts.car[j] = sp_globals.xmin; /* Clip to sp_globals.xmin boundary */
+
+ if (sp_intercepts.car[i] > sp_globals.xmax)
+ sp_intercepts.car[i] = sp_globals.xmax;
+
+ if (sp_intercepts.car[j] >= sp_intercepts.car[i])
+ {
+ if ((ufix16)(sp_intercepts.inttype[j] & FRACTION) + (ufix16)(sp_intercepts.inttype[i] & FRACTION) > sp_intercepts.fracpix)
+ ++sp_intercepts.car[i];
+ else
+ --sp_intercepts.car[j];
+ }
+ if (sp_globals.first_pass)
+ {
+ if (sp_intercepts.inttype[i-1] & END_INT)
+ {
+ for (iminus1 = i+1; !(sp_intercepts.inttype[iminus1] & END_INT); iminus1++)
+ ;
+ }
+ else
+ iminus1 = i-1;
+
+ if (sp_intercepts.inttype[j] & END_INT)
+ {
+ for (jplus1 = j-1; !(sp_intercepts.inttype[jplus1] & END_INT); jplus1--)
+ ;
+ jplus1++;
+ }
+ else
+ jplus1 = j+1;
+
+ if ((sp_intercepts.inttype[iminus1] & LEFT_INT))
+ {
+ if ( sp_intercepts.car[jplus1] > sp_intercepts.car[i])
+ {
+ diff = sp_intercepts.car[jplus1] - sp_intercepts.car[i];
+ sp_intercepts.car[i] += diff/2;
+ sp_intercepts.car[jplus1] -= diff/2;
+ if (diff & 1)
+ {
+ if ((ufix16)(sp_intercepts.inttype[i] & FRACTION) + (ufix16)(sp_intercepts.inttype[jplus1] & FRACTION) > sp_intercepts.fracpix)
+ sp_intercepts.car[i] ++;
+ else
+ sp_intercepts.car[jplus1]--;
+ }
+ }
+ }
+ else if (!(sp_intercepts.inttype[jplus1] & LEFT_INT))
+ {
+ if (sp_intercepts.car[iminus1] < sp_intercepts.car[j])
+ {
+ diff = sp_intercepts.car[j] - sp_intercepts.car[iminus1];
+ sp_intercepts.car[j] -= diff/2;
+ sp_intercepts.car[iminus1] += diff/2;
+ if (diff & 1)
+ {
+ if ((ufix16)(sp_intercepts.inttype[j] & FRACTION) +
+ (ufix16)(sp_intercepts.inttype[iminus1] & FRACTION) > sp_intercepts.fracpix)
+ sp_intercepts.car[iminus1]++;
+ else
+ sp_intercepts.car[j]--;
+ }
+ }
+ }
+ if (sp_globals.tcb.mirror == -1)
+ {
+ if (sp_intercepts.inttype[j-1] & END_INT)
+ {
+ for (jplus1 = j+1; !(sp_intercepts.inttype[jplus1] & END_INT); jplus1++)
+ ;
+ }
+ else
+ {
+ jplus1 = j-1;
+ }
+ }
+
+ if (!(sp_intercepts.inttype[jplus1] & LEFT_INT) &&
+ sp_intercepts.car[j] > sp_intercepts.car[jplus1])
+ {
+ k = sp_intercepts.cdr[y - 1];
+ while (k > 0)
+ {
+ nextk = sp_intercepts.cdr[k];
+ if (!(sp_intercepts.inttype[k] & LEFT_INT) &&
+ (sp_intercepts.inttype[nextk] & LEFT_INT) &&
+ sp_intercepts.car[nextk] > sp_intercepts.car[jplus1])
+ {
+ if ((diff=sp_intercepts.car[j] - sp_intercepts.car[k]) > 0)
+ {
+ if (diff <= (sp_intercepts.car[nextk] - sp_intercepts.car[jplus1]))
+ {
+ sp_intercepts.car[j] -= diff/2;
+ sp_intercepts.car[k] += diff/2;
+ if (diff & 1)
+ {
+ if ((ufix16)(sp_intercepts.inttype[j] & FRACTION) +
+ (ufix16)(sp_intercepts.inttype[k] & FRACTION) > sp_intercepts.fracpix)
+ sp_intercepts.car[j]--;
+ else
+ sp_intercepts.car[k]++;
+ }
+ }
+ else
+ {
+ diff = sp_intercepts.car[nextk] - sp_intercepts.car[jplus1];
+ sp_intercepts.car[nextk] -= diff/2;
+ sp_intercepts.car[jplus1] += diff/2;
+ if (diff & 1)
+ {
+ if ((ufix16)(sp_intercepts.inttype[jplus1] & FRACTION) +
+ (ufix16)(sp_intercepts.inttype[nextk] & FRACTION) > sp_intercepts.fracpix)
+ sp_intercepts.car[nextk]--;
+ else
+ sp_intercepts.car[jplus1]++;
+ }
+ }
+ }
+ break;
+ }
+ k = nextk;
+ }
+ }
+ if (j > 0 && sp_intercepts.car[j-1] > sp_intercepts.car[i] && !(sp_intercepts.inttype[j-1] & END_INT))
+ {
+ diff = sp_intercepts.car[j-1] - sp_intercepts.car[i];
+ sp_intercepts.car[i] += diff/2;
+ sp_intercepts.car[j-1] -= diff/2;
+ if (diff & 1)
+ {
+ if ((ufix16)(sp_intercepts.inttype[i] & FRACTION) + (ufix16)(sp_intercepts.inttype[j-1] & FRACTION) > sp_intercepts.fracpix)
+ sp_intercepts.car[i]++;
+ else
+ sp_intercepts.car[j-1]--;
+ }
+ }
+ if (sp_intercepts.car[i+1] < sp_intercepts.car[j] && !(sp_intercepts.inttype[i] & END_INT))
+ {
+ diff = sp_intercepts.car[j] - sp_intercepts.car[i+1];
+ sp_intercepts.car[j] -= diff/2;
+ sp_intercepts.car[i+1] += diff/2;
+ if (diff & 1)
+ {
+ if ((ufix16)(sp_intercepts.inttype[j] & FRACTION) + (ufix16)(sp_intercepts.inttype[i+1] & FRACTION) > sp_intercepts.fracpix)
+ sp_intercepts.car[i+1]++;
+ else
+ sp_intercepts.car[j]--;
+ }
+
+ }
+ previ = i;
+ }
+ i = sp_intercepts.cdr[i];
+ }
+ }
+
+#if DEBUG
+printf("\nPROC_INTERCEPTS_SCREEN: Intercept lists after:\n");
+/* Print out all of the intercept info */
+scan_line = sp_globals.ymax - first_y - 1;
+
+for (y = first_y - sp_globals.y_band.band_min; y >= last_y; y--, scan_line++)
+ {
+ i = y; /* Index head of intercept list */
+ while ((i = sp_intercepts.cdr[i]) != 0) /* Link to next intercept if present */
+ {
+ if ((from = sp_intercepts.car[i] - sp_globals.xmin) < 0)
+ from = 0; /* Clip to sp_globals.xmin boundary */
+ i = sp_intercepts.cdr[i]; /* Link to next intercept */
+ if (i == 0) /* End of list? */
+ {
+ printf("****** proc_intercepts: odd number of intercepts\n");
+ break;
+ }
+ if ((to = sp_intercepts.car[i]) > sp_globals.xmax)
+ to = sp_globals.xmax - sp_globals.xmin; /* Clip to sp_globals.xmax boundary */
+ else
+ to -= sp_globals.xmin;
+ printf(" Y = %2d (scanline %2d): %d %d:\n",
+ y + sp_globals.y_band.band_min, scan_line, from, to);
+ }
+ }
+#endif
+
+/* INTERCEPTS ALL PATCHED, NOW DRAW THE IMAGE */
+scan_line = sp_globals.ymax - first_y - 1;
+
+for (y = first_y - sp_globals.y_band.band_min; y >= last_y; y--, scan_line++)
+ {
+ i = sp_intercepts.cdr[y]; /* Index head of intercept list */
+ while (i != 0) /* Link to next intercept if present */
+ {
+ from = sp_intercepts.car[i];
+ i = sp_intercepts.cdr[i]; /* Link to next intercept */
+ to = sp_intercepts.car[i];
+#if INCL_CLIPPING
+ if (clipleft)
+ {
+ if (to <= xmin)
+ {
+ i = sp_intercepts.cdr[i];
+ continue;
+ }
+ if (from < xmin)
+ from = xmin;
+ }
+ if (clipright)
+ {
+ if (from >= xmax)
+ {
+ i = sp_intercepts.cdr[i];
+ continue;
+ }
+ if (to > xmax)
+ to = xmax;
+ }
+#endif
+ set_bitmap_bits(scan_line, from-sp_globals.xmin, to-sp_globals.xmin);
+ i = sp_intercepts.cdr[i];
+ }
+ }
+}
+
+#endif
diff --git a/libXfont/src/Speedo/out_util.c b/libXfont/src/Speedo/out_util.c
new file mode 100644
index 000000000..baf942747
--- /dev/null
+++ b/libXfont/src/Speedo/out_util.c
@@ -0,0 +1,339 @@
+/* $Xorg: out_util.c,v 1.3 2000/08/17 19:46:26 cpqbld Exp $ */
+
+/*
+
+Copyright 1989-1991, Bitstream Inc., Cambridge, MA.
+You are hereby granted permission under all Bitstream propriety rights to
+use, copy, modify, sublicense, sell, and redistribute the Bitstream Speedo
+software and the Bitstream Charter outline font for any purpose and without
+restrictions; provided, that this notice is left intact on all copies of such
+software or font and that Bitstream's trademark is acknowledged as shown below
+on all unmodified copies of such font.
+
+BITSTREAM CHARTER is a registered trademark of Bitstream Inc.
+
+
+BITSTREAM INC. DISCLAIMS ANY AND ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING
+WITHOUT LIMITATION THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+PARTICULAR PURPOSE. BITSTREAM SHALL NOT BE LIABLE FOR ANY DIRECT OR INDIRECT
+DAMAGES, INCLUDING BUT NOT LIMITED TO LOST PROFITS, LOST DATA, OR ANY OTHER
+INCIDENTAL OR CONSEQUENTIAL DAMAGES, ARISING OUT OF OR IN ANY WAY CONNECTED
+WITH THE SPEEDO SOFTWARE OR THE BITSTREAM CHARTER OUTLINE FONT.
+
+*/
+/* $XFree86: xc/lib/font/Speedo/out_util.c,v 1.2 1999/02/07 06:18:17 dawes Exp $ */
+
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#define DEBUG 0
+
+/*************************** O U T _ U T I L . C *****************************
+ * *
+ * This is a utility module share by all bitmap output modules *
+ * *
+ *****************************************************************************/
+
+
+#include "spdo_prv.h" /* General definitions for Speedo */
+/* absolute value function */
+#define ABS(X) ( (X < 0) ? -X : X)
+#if INCL_BLACK || INCL_2D || INCL_SCREEN
+
+static FUNCTION void restart_intercepts_out(void)
+GDECL
+/* Called by sp_make_char when a new sub character is started
+ * Freezes current sorted lists
+ */
+{
+#if DEBUG
+printf(" Restart intercepts:\n");
+#endif
+sp_globals.first_offset = sp_globals.next_offset;
+}
+
+static FUNCTION void set_first_band_out(
+GDECL
+point_t Pmin,
+point_t Pmax)
+{
+
+sp_globals.ymin = Pmin.y;
+sp_globals.ymax = Pmax.y;
+
+sp_globals.ymin = (sp_globals.ymin - sp_globals.onepix + 1) >> sp_globals.pixshift;
+sp_globals.ymax = (sp_globals.ymax + sp_globals.onepix - 1) >> sp_globals.pixshift;
+
+#if INCL_CLIPPING
+ switch(sp_globals.tcb0.xtype)
+ {
+ case 1: /* 180 degree rotation */
+ if (sp_globals.specs.flags & CLIP_TOP)
+ {
+ sp_globals.clip_ymin = (fix31)((fix31)EM_TOP * sp_globals.tcb0.yppo + ((1<<sp_globals.multshift)/2));
+ sp_globals.clip_ymin = sp_globals.clip_ymin >> sp_globals.multshift;
+ sp_globals.clip_ymin = -1* sp_globals.clip_ymin;
+ if (sp_globals.ymin < sp_globals.clip_ymin)
+ sp_globals.ymin = sp_globals.clip_ymin;
+ }
+ if (sp_globals.specs.flags & CLIP_BOTTOM)
+ {
+ sp_globals.clip_ymax = (fix31)((fix31)(-1 * EM_BOT) * sp_globals.tcb0.yppo + ((1<<sp_globals.multshift)/2));
+ sp_globals.clip_ymax = sp_globals.clip_ymax >> sp_globals.multshift;
+ if (sp_globals.ymax > sp_globals.clip_ymax)
+ sp_globals.ymax = sp_globals.clip_ymax;
+ }
+ break;
+ case 2: /* 90 degree rotation */
+ sp_globals.clip_ymax = 0;
+ if ((sp_globals.specs.flags & CLIP_TOP) &&
+ (sp_globals.ymax > sp_globals.clip_ymax))
+ sp_globals.ymax = sp_globals.clip_ymax;
+ sp_globals.clip_ymin = ((sp_globals.set_width.y+32768L) >> 16);
+ if ((sp_globals.specs.flags & CLIP_BOTTOM) &&
+ (sp_globals.ymin < sp_globals.clip_ymin))
+ sp_globals.ymin = sp_globals.clip_ymin;
+ break;
+ case 3: /* 270 degree rotation */
+ sp_globals.clip_ymax = ((sp_globals.set_width.y+32768L) >> 16);
+ if ((sp_globals.specs.flags & CLIP_TOP) &&
+ (sp_globals.ymax > sp_globals.clip_ymax))
+ sp_globals.ymax = sp_globals.clip_ymax;
+ sp_globals.clip_ymin = 0;
+ if ((sp_globals.specs.flags & CLIP_BOTTOM) &&
+ (sp_globals.ymin < sp_globals.clip_ymin))
+ sp_globals.ymin = sp_globals.clip_ymin;
+ break;
+ default: /* this is for zero degree rotation and arbitrary rotation */
+ if (sp_globals.specs.flags & CLIP_TOP)
+ {
+ sp_globals.clip_ymax = (fix31)((fix31)EM_TOP * sp_globals.tcb0.yppo + ((1<<sp_globals.multshift)/2));
+ sp_globals.clip_ymax = sp_globals.clip_ymax >> sp_globals.multshift;
+ if (sp_globals.ymax > sp_globals.clip_ymax)
+ sp_globals.ymax = sp_globals.clip_ymax;
+ }
+ if (sp_globals.specs.flags & CLIP_BOTTOM)
+ {
+ sp_globals.clip_ymin = (fix31)((fix31)(-1 * EM_BOT) * sp_globals.tcb0.yppo + ((1<<sp_globals.multshift)/2));
+ sp_globals.clip_ymin = sp_globals.clip_ymin >> sp_globals.multshift;
+ sp_globals.clip_ymin = - sp_globals.clip_ymin;
+ if (sp_globals.ymin < sp_globals.clip_ymin)
+ sp_globals.ymin = sp_globals.clip_ymin;
+ }
+ break;
+ }
+#endif
+sp_globals.y_band.band_min = sp_globals.ymin;
+sp_globals.y_band.band_max = sp_globals.ymax - 1;
+
+sp_globals.xmin = (Pmin.x + sp_globals.pixrnd) >> sp_globals.pixshift;
+sp_globals.xmax = (Pmax.x + sp_globals.pixrnd) >> sp_globals.pixshift;
+
+
+#if INCL_2D
+sp_globals.x_band.band_min = sp_globals.xmin - 1; /* subtract one pixel of "safety margin" */
+sp_globals.x_band.band_max = sp_globals.xmax /* - 1 + 1 */; /* Add one pixel of "safety margin" */
+#endif
+}
+
+FUNCTION void init_char_out(
+GDECL
+point_t Psw, point_t Pmin, point_t Pmax)
+{
+sp_globals.set_width.x = (fix31)Psw.x << sp_globals.poshift;
+sp_globals.set_width.y = (fix31)Psw.y << sp_globals.poshift;
+set_first_band_out(Pmin, Pmax);
+init_intercepts_out();
+if (sp_globals.normal)
+ {
+ sp_globals.bmap_xmin = Pmin.x;
+ sp_globals.bmap_xmax = Pmax.x;
+ sp_globals.bmap_ymin = Pmin.y;
+ sp_globals.bmap_ymax = Pmax.y;
+ sp_globals.extents_running = FALSE;
+ }
+else
+ {
+ sp_globals.bmap_xmin = 32000;
+ sp_globals.bmap_xmax = -32000;
+ sp_globals.bmap_ymin = 32000;
+ sp_globals.bmap_ymax = -32000;
+ sp_globals.extents_running = TRUE;
+ }
+sp_globals.first_pass = TRUE;
+}
+
+FUNCTION void begin_sub_char_out(
+GDECL
+point_t Psw,
+point_t Pmin,
+point_t Pmax)
+/* Called at the start of each sub-character in a composite character
+ */
+{
+#if DEBUG
+printf("BEGIN_SUB_CHAR_out(%3.1f, %3.1f, %3.1f, %3.1f, %3.1f, %3.1f\n",
+ (real)Psw.x / (real)sp_globals.onepix, (real)Psw.y / (real)sp_globals.onepix,
+ (real)Pmin.x / (real)sp_globals.onepix, (real)Pmin.y / (real)sp_globals.onepix,
+ (real)Pmax.x / (real)sp_globals.onepix, (real)Pmax.y / (real)sp_globals.onepix);
+#endif
+restart_intercepts_out();
+if (!sp_globals.extents_running)
+ {
+ sp_globals.bmap_xmin = 32000;
+ sp_globals.bmap_xmax = -32000;
+ sp_globals.bmap_ymin = 32000;
+ sp_globals.bmap_ymax = -32000;
+ sp_globals.extents_running = TRUE;
+ }
+}
+
+FUNCTION void curve_out(
+GDECL
+point_t P1, point_t P2, point_t P3,
+fix15 depth)
+/* Called for each curve in the transformed character if curves out enabled
+ */
+{
+#if DEBUG
+printf("CURVE_OUT(%3.1f, %3.1f, %3.1f, %3.1f, %3.1f, %3.1f)\n",
+ (real)P1.x / (real)sp_globals.onepix, (real)P1.y / (real)sp_globals.onepix,
+ (real)P2.x / (real)sp_globals.onepix, (real)P2.y / (real)sp_globals.onepix,
+ (real)P3.x / (real)sp_globals.onepix, (real)P3.y / (real)sp_globals.onepix);
+#endif
+}
+
+
+
+FUNCTION void end_contour_out()
+GDECL
+/* Called after the last vector in each contour
+ */
+{
+#if DEBUG
+printf("END_CONTOUR_OUT()\n");
+#endif
+}
+
+
+FUNCTION void end_sub_char_out()
+GDECL
+/* Called after the last contour in each sub-character in a compound character
+ */
+{
+#if DEBUG
+printf("END_SUB_CHAR_OUT()\n");
+#endif
+}
+
+
+FUNCTION void init_intercepts_out()
+GDECL
+/* Called to initialize intercept storage data structure
+ */
+
+{
+fix15 i;
+fix15 no_lists;
+
+#if DEBUG
+printf(" Init intercepts (Y band from %d to %d)\n", sp_globals.y_band.band_min, sp_globals.y_band.band_max);
+if (sp_globals.x_scan_active)
+ printf(" (X band from %d to %d)\n", sp_globals.x_band.band_min, sp_globals.x_band.band_max);
+#endif
+
+sp_globals.intercept_oflo = FALSE;
+
+sp_globals.no_y_lists = sp_globals.y_band.band_max - sp_globals.y_band.band_min + 1;
+#if INCL_2D
+if (sp_globals.output_mode == MODE_2D)
+ {
+ sp_globals.no_x_lists = sp_globals.x_scan_active ?
+ sp_globals.x_band.band_max - sp_globals.x_band.band_min + 1 : 0;
+ no_lists = sp_globals.no_y_lists + sp_globals.no_x_lists;
+ }
+else
+#endif
+ no_lists = sp_globals.no_y_lists;
+
+#if INCL_2D
+sp_globals.y_band.band_floor = 0;
+sp_globals.y_band.band_ceiling = sp_globals.no_y_lists;
+#endif
+
+if (no_lists >= MAX_INTERCEPTS) /* Not enough room for list table? */
+ {
+ no_lists = sp_globals.no_y_lists = MAX_INTERCEPTS;
+ sp_globals.intercept_oflo = TRUE;
+ sp_globals.y_band.band_min = sp_globals.y_band.band_max - sp_globals.no_y_lists + 1;
+#if INCL_2D
+ sp_globals.y_band.band_array_offset = sp_globals.y_band.band_min;
+ sp_globals.y_band.band_ceiling = sp_globals.no_y_lists;
+ sp_globals.no_x_lists = 0;
+ sp_globals.x_scan_active = FALSE;
+#endif
+ }
+
+for (i = 0; i < no_lists; i++) /* For each active value... */
+ {
+#if INCL_SCREEN
+ if (sp_globals.output_mode == MODE_SCREEN)
+ sp_intercepts.inttype[i]=0;
+#endif
+ sp_intercepts.cdr[i] = 0; /* Mark each intercept list empty */
+ }
+
+sp_globals.first_offset = sp_globals.next_offset = no_lists;
+
+#if INCL_2D
+sp_globals.y_band.band_array_offset = sp_globals.y_band.band_min;
+sp_globals.x_band.band_array_offset = sp_globals.x_band.band_min - sp_globals.no_y_lists;
+sp_globals.x_band.band_floor = sp_globals.no_y_lists;
+sp_globals.x_band.band_ceiling = no_lists;
+#endif
+#if INCL_SCREEN
+sp_intercepts.inttype[sp_globals.no_y_lists-1] = END_INT;
+#endif
+
+}
+
+
+
+
+
+
+
+
+
+
+
+FUNCTION void reduce_band_size_out()
+GDECL
+{
+sp_globals.y_band.band_min = sp_globals.y_band.band_max - ((sp_globals.y_band.band_max - sp_globals.y_band.band_min) >> 1);
+#if INCL_2D
+sp_globals.y_band.band_array_offset = sp_globals.y_band.band_min;
+#endif
+}
+
+
+FUNCTION boolean next_band_out()
+GDECL
+{
+fix15 tmpfix15;
+
+if (sp_globals.y_band.band_min <= sp_globals.ymin)
+ return FALSE;
+tmpfix15 = sp_globals.y_band.band_max - sp_globals.y_band.band_min;
+sp_globals.y_band.band_max = sp_globals.y_band.band_min - 1;
+sp_globals.y_band.band_min = sp_globals.y_band.band_max - tmpfix15;
+if (sp_globals.y_band.band_min < sp_globals.ymin)
+ sp_globals.y_band.band_min = sp_globals.ymin;
+#if INCL_2D
+sp_globals.y_band.band_array_offset = sp_globals.y_band.band_min;
+#endif
+return TRUE;
+}
+#endif
+
diff --git a/libXfont/src/Speedo/reset.c b/libXfont/src/Speedo/reset.c
new file mode 100644
index 000000000..215349473
--- /dev/null
+++ b/libXfont/src/Speedo/reset.c
@@ -0,0 +1,129 @@
+/* $Xorg: reset.c,v 1.3 2000/08/17 19:46:26 cpqbld Exp $ */
+
+/*
+
+Copyright 1989-1991, Bitstream Inc., Cambridge, MA.
+You are hereby granted permission under all Bitstream propriety rights to
+use, copy, modify, sublicense, sell, and redistribute the Bitstream Speedo
+software and the Bitstream Charter outline font for any purpose and without
+restrictions; provided, that this notice is left intact on all copies of such
+software or font and that Bitstream's trademark is acknowledged as shown below
+on all unmodified copies of such font.
+
+BITSTREAM CHARTER is a registered trademark of Bitstream Inc.
+
+
+BITSTREAM INC. DISCLAIMS ANY AND ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING
+WITHOUT LIMITATION THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+PARTICULAR PURPOSE. BITSTREAM SHALL NOT BE LIABLE FOR ANY DIRECT OR INDIRECT
+DAMAGES, INCLUDING BUT NOT LIMITED TO LOST PROFITS, LOST DATA, OR ANY OTHER
+INCIDENTAL OR CONSEQUENTIAL DAMAGES, ARISING OUT OF OR IN ANY WAY CONNECTED
+WITH THE SPEEDO SOFTWARE OR THE BITSTREAM CHARTER OUTLINE FONT.
+
+*/
+/* $XFree86: xc/lib/font/Speedo/reset.c,v 1.2 1999/02/07 06:18:17 dawes Exp $ */
+
+
+
+/******************************* R E S E T . C *******************************
+ * *
+ * This module provides initialization functions. *
+ * *
+ ****************************************************************************/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "spdo_prv.h" /* General definitions for Speedo */
+#include "keys.h" /* Font decryption keys */
+
+#define DEBUG 0
+
+#if DEBUG
+#include <stdio.h>
+#define SHOW(X) printf("X = %d\n", X)
+#else
+#define SHOW(X)
+#endif
+
+/***** GLOBAL VARIABLES *****/
+
+/***** GLOBAL FUNCTIONS *****/
+
+/***** EXTERNAL VARIABLES *****/
+
+/***** EXTERNAL FUNCTIONS *****/
+
+/***** STATIC VARIABLES *****/
+
+/***** STATIC FUNCTIONS *****/
+
+
+FUNCTION void reset()
+GDECL
+/*
+ * Called by the host software to intialize the Speedo mechanism
+ */
+{
+sp_globals.specs_valid = FALSE; /* Flag specs not valid */
+
+/* Reset decryption key */
+sp_globals.key32 = (KEY3 << 8) | KEY2;
+sp_globals.key4 = KEY4;
+sp_globals.key6 = KEY6;
+sp_globals.key7 = KEY7;
+sp_globals.key8 = KEY8;
+
+sp_globals.constr.font_id_valid = FALSE;
+
+#if INCL_MULTIDEV
+#if INCL_BLACK || INCL_SCREEN || INCL_2D
+sp_globals.bitmap_device_set = FALSE;
+#endif
+#if INCL_OUTLINE
+sp_globals.outline_device_set = FALSE;
+#endif
+#endif
+}
+
+#if INCL_KEYS
+FUNCTION void set_key(
+GDECL
+ufix8 key[]) /* Specified decryption key */
+/*
+ * Dynamically sets font decryption key.
+ */
+{
+sp_globals.key32 = ((ufix16)key[3] << 8) | key[2];
+sp_globals.key4 = key[4];
+sp_globals.key6 = key[6];
+sp_globals.key7 = key[7];
+sp_globals.key8 = key[8];
+}
+#endif
+
+
+
+FUNCTION ufix16 get_cust_no(
+GDECL
+buff_t font_buff)
+/*
+ returns customer number from font
+*/
+{
+ufix8 FONTFAR *hdr2_org;
+ufix16 private_off;
+
+private_off = read_word_u(font_buff.org + FH_HEDSZ);
+if (private_off + FH_CUSNR > font_buff.no_bytes)
+ {
+ report_error(1); /* Insufficient font data loaded */
+ return FALSE;
+ }
+
+hdr2_org = font_buff.org + private_off;
+
+return (read_word_u(hdr2_org + FH_CUSNR));
+}
+
+
diff --git a/libXfont/src/Speedo/set_spcs.c b/libXfont/src/Speedo/set_spcs.c
new file mode 100644
index 000000000..8fbdf1fd2
--- /dev/null
+++ b/libXfont/src/Speedo/set_spcs.c
@@ -0,0 +1,763 @@
+/* $Xorg: set_spcs.c,v 1.3 2000/08/17 19:46:26 cpqbld Exp $ */
+
+/*
+
+Copyright 1989-1991, Bitstream Inc., Cambridge, MA.
+You are hereby granted permission under all Bitstream propriety rights to
+use, copy, modify, sublicense, sell, and redistribute the Bitstream Speedo
+software and the Bitstream Charter outline font for any purpose and without
+restrictions; provided, that this notice is left intact on all copies of such
+software or font and that Bitstream's trademark is acknowledged as shown below
+on all unmodified copies of such font.
+
+BITSTREAM CHARTER is a registered trademark of Bitstream Inc.
+
+
+BITSTREAM INC. DISCLAIMS ANY AND ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING
+WITHOUT LIMITATION THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+PARTICULAR PURPOSE. BITSTREAM SHALL NOT BE LIABLE FOR ANY DIRECT OR INDIRECT
+DAMAGES, INCLUDING BUT NOT LIMITED TO LOST PROFITS, LOST DATA, OR ANY OTHER
+INCIDENTAL OR CONSEQUENTIAL DAMAGES, ARISING OUT OF OR IN ANY WAY CONNECTED
+WITH THE SPEEDO SOFTWARE OR THE BITSTREAM CHARTER OUTLINE FONT.
+
+*/
+/* $XFree86: xc/lib/font/Speedo/set_spcs.c,v 1.3 2001/01/17 19:43:17 dawes Exp $ */
+
+
+/*************************** S E T _ S P C S . C *****************************
+ * *
+ * This module implements all sp_set_specs() functionality. *
+ * *
+ ****************************************************************************/
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#define SET_SPCS
+#include "spdo_prv.h" /* General definitions for Speedo */
+#include "keys.h"
+
+#define DEBUG 0
+
+#if DEBUG
+#include <stdio.h>
+#define SHOW(X) printf("X = %d\n", X)
+#else
+#define SHOW(X)
+#endif
+
+/***** GLOBAL VARIABLES *****/
+
+/***** GLOBAL FUNCTIONS *****/
+
+/****** EXTERNAL VARIABLES *****/
+
+/***** STATIC VARIABLES *****/
+
+
+/****** STATIC FUNCTIONS *****/
+
+static boolean sp_setup_consts(PROTO_DECL2 fix15 xmin, fix15 xmax,
+ fix15 ymin, fix15 ymax);
+static void sp_setup_tcb(PROTO_DECL2 tcb_t GLOBALFAR *ptcb);
+static fix15 sp_setup_mult(PROTO_DECL2 fix31 input_mult);
+static fix31 sp_setup_offset(PROTO_DECL2 fix31 input_offset);
+
+
+
+FUNCTION boolean set_specs(
+GDECL
+specs_t STACKFAR *specsarg) /* Bundle of conversion specifications */
+/*
+ * Called by host software to set character generation specifications
+ */
+{
+fix31 offcd; /* Offset to start of character directory */
+fix31 ofcns; /* Offset to start of constraint data */
+fix31 cd_size; /* Size of character directory */
+fix31 no_bytes_min; /* Min number of bytes in font buffer */
+ufix16 font_id; /* Font ID */
+ufix16 private_off; /* offset to private header */
+fix15 xmin; /* Minimum X ORU value in font */
+fix15 xmax; /* Maximum X ORU value in font */
+fix15 ymin; /* Minimum Y ORU value in font */
+fix15 ymax; /* Maximum Y ORU value in font */
+
+sp_globals.specs_valid = FALSE; /* Flag specs not valid */
+
+sp_globals.specs = *specsarg; /* copy specs structure into sp_globals */
+sp_globals.pspecs = &sp_globals.specs;
+sp_globals.font = *sp_globals.pspecs->pfont;
+sp_globals.pfont = &sp_globals.font;
+sp_globals.font_org = sp_globals.font.org;
+
+if (read_word_u(sp_globals.font_org + FH_FMVER + 4) != 0x0d0a)
+ {
+ report_error(4); /* Font format error */
+ return FALSE;
+ }
+if (read_word_u(sp_globals.font_org + FH_FMVER + 6) != 0x0000)
+ {
+ report_error(4); /* Font format error */
+ return FALSE;
+ }
+
+if (get_cust_no(*specsarg->pfont) == 0)
+ {
+ sp_globals.key32 = 0;
+ sp_globals.key4 = 0;
+ sp_globals.key6 = 0;
+ sp_globals.key7 = 0;
+ sp_globals.key8 = 0;
+ }
+else
+ {
+ sp_globals.key32 = (KEY3 << 8) | KEY2;
+ sp_globals.key4 = KEY4;
+ sp_globals.key6 = KEY6;
+ sp_globals.key7 = KEY7;
+ sp_globals.key8 = KEY8;
+ }
+
+
+sp_globals.no_chars_avail = read_word_u(sp_globals.font_org + FH_NCHRF);
+
+/* Read sp_globals.orus per em from font header */
+sp_globals.orus_per_em = read_word_u(sp_globals.font_org + FH_ORUPM);
+
+/* compute address of private header */
+private_off = read_word_u(sp_globals.font_org + FH_HEDSZ);
+sp_globals.hdr2_org = sp_globals.font_org + private_off;
+
+/* set metric resolution if specified, default to outline res otherwise */
+if (private_off > EXP_FH_METRES)
+ {
+ sp_globals.metric_resolution = read_word_u(sp_globals.font_org + EXP_FH_METRES);
+ }
+else
+ {
+ sp_globals.metric_resolution = sp_globals.orus_per_em;
+ }
+
+#if INCL_METRICS
+sp_globals.kern.tkorg = sp_globals.font_org + read_long(sp_globals.hdr2_org + FH_OFFTK);
+sp_globals.kern.pkorg = sp_globals.font_org + read_long(sp_globals.hdr2_org + FH_OFFPK);
+sp_globals.kern.no_tracks = read_word_u(sp_globals.font_org + FH_NKTKS);
+sp_globals.kern.no_pairs = read_word_u(sp_globals.font_org + FH_NKPRS);
+#endif
+
+offcd = read_long(sp_globals.hdr2_org + FH_OFFCD); /* Read offset to character directory */
+ofcns = read_long(sp_globals.hdr2_org + FH_OFCNS); /* Read offset to constraint data */
+cd_size = ofcns - offcd;
+if ((((sp_globals.no_chars_avail << 1) + 3) != cd_size) &&
+ (((sp_globals.no_chars_avail * 3) + 4) != cd_size))
+ {
+ report_error(4); /* Font format error */
+ return FALSE;
+ }
+
+#if INCL_LCD /* Dynamic character data load suppoorted? */
+#if INCL_METRICS
+no_bytes_min = read_long(sp_globals.hdr2_org + FH_OCHRD); /* Offset to character data */
+#else /* Dynamic character data load not supported? */
+no_bytes_min = read_long(sp_globals.hdr2_org + FH_OFFTK); /* Offset to track kerning data */
+#endif
+#else /* Dynamic character data load not supported? */
+no_bytes_min = read_long(sp_globals.hdr2_org + FH_NBYTE); /* Offset to EOF + 1 */
+#endif
+
+sp_globals.font_buff_size = sp_globals.pfont->no_bytes;
+if (sp_globals.font_buff_size < no_bytes_min) /* Minimum data not loaded? */
+ {
+ report_error(1); /* Insufficient font data loaded */
+ return FALSE;
+ }
+
+sp_globals.pchar_dir = sp_globals.font_org + offcd;
+sp_globals.first_char_idx = read_word_u(sp_globals.font_org + FH_FCHRF);
+
+/* Register font name with sp_globals.constraint mechanism */
+font_id = read_word_u(sp_globals.font_org + FH_FNTID);
+if (!(sp_globals.constr.font_id_valid) || (sp_globals.constr.font_id != font_id))
+ {
+ sp_globals.constr.font_id = font_id;
+ sp_globals.constr.font_id_valid = TRUE;
+ sp_globals.constr.data_valid = FALSE;
+ }
+sp_globals.constr.org = sp_globals.font_org + ofcns;
+sp_globals.constr.active = ((sp_globals.pspecs->flags & CONSTR_OFF) == 0);
+
+/* Set up sliding point constants */
+/* Set pixel shift to accomodate largest transformed pixel value */
+xmin = read_word_u(sp_globals.font_org + FH_FXMIN);
+xmax = read_word_u(sp_globals.font_org + FH_FXMAX);
+ymin = read_word_u(sp_globals.font_org + FH_FYMIN);
+ymax = read_word_u(sp_globals.font_org + FH_FYMAX);
+
+if (!sp_setup_consts(xmin,xmax,ymin,ymax))
+ {
+ report_error(3); /* Requested specs out of range */
+ return FALSE;
+ }
+#if INCL_ISW
+/* save the value of the max x oru that the fixed point constants are based on*/
+sp_globals.isw_xmax = xmax;
+#endif
+
+/* Setup transformation control block */
+sp_setup_tcb(&sp_globals.tcb0);
+
+
+/* Select output module */
+sp_globals.output_mode = sp_globals.pspecs->flags & 0x0007;
+
+#if INCL_USEROUT
+if (!init_userout(sp_globals.pspecs))
+#endif
+
+switch (sp_globals.output_mode)
+ {
+#if INCL_BLACK
+case MODE_BLACK: /* Output mode 0 (Black writer) */
+ sp_globals.init_out = sp_init_black;
+ sp_globals.begin_char = sp_begin_char_black;
+ sp_globals.begin_sub_char = sp_begin_sub_char_out;
+ sp_globals.begin_contour = sp_begin_contour_black;
+ sp_globals.curve = sp_curve_out;
+ sp_globals.line = sp_line_black;
+ sp_globals.end_contour = sp_end_contour_out;
+ sp_globals.end_sub_char = sp_end_sub_char_out;
+ sp_globals.end_char = sp_end_char_black;
+ break;
+#endif
+
+#if INCL_SCREEN
+case MODE_SCREEN: /* Output mode 1 (Screen writer) */
+ sp_globals.init_out = sp_init_screen;
+ sp_globals.begin_char = sp_begin_char_screen;
+ sp_globals.begin_sub_char = sp_begin_sub_char_out;
+ sp_globals.begin_contour = sp_begin_contour_screen;
+ sp_globals.curve = sp_curve_screen;
+ sp_globals.line = sp_line_screen;
+ sp_globals.end_contour = sp_end_contour_screen;
+ sp_globals.end_sub_char = sp_end_sub_char_out;
+ sp_globals.end_char = sp_end_char_screen;
+ break;
+#endif
+
+#if INCL_OUTLINE
+case MODE_OUTLINE: /* Output mode 2 (Vector) */
+ sp_globals.init_out = sp_init_outline;
+ sp_globals.begin_char = sp_begin_char_outline;
+ sp_globals.begin_sub_char = sp_begin_sub_char_outline;
+ sp_globals.begin_contour = sp_begin_contour_outline;
+ sp_globals.curve = sp_curve_outline;
+ sp_globals.line = sp_line_outline;
+ sp_globals.end_contour = sp_end_contour_outline;
+ sp_globals.end_sub_char = sp_end_sub_char_outline;
+ sp_globals.end_char = sp_end_char_outline;
+ break;
+#endif
+
+#if INCL_2D
+case MODE_2D: /* Output mode 3 */
+ sp_globals.init_out = sp_init_2d;
+ sp_globals.begin_char = sp_begin_char_2d;
+ sp_globals.begin_sub_char = sp_begin_sub_char_out;
+ sp_globals.begin_contour = sp_begin_contour_2d;
+ sp_globals.curve = sp_curve_out;
+ sp_globals.line = sp_line_2d;
+ sp_globals.end_contour = sp_end_contour_out;
+ sp_globals.end_sub_char = sp_end_sub_char_out;
+ sp_globals.end_char = sp_end_char_2d;
+ break;
+#endif
+
+default:
+ report_error(8); /* Unsupported mode requested */
+ return FALSE;
+ }
+
+ if (!fn_init_out(sp_globals.pspecs))
+ {
+ report_error(5);
+ return FALSE;
+ }
+
+
+sp_globals.curves_out = sp_globals.pspecs->flags & CURVES_OUT;
+
+if (sp_globals.pspecs->flags & BOGUS_MODE) /* Linear transformation requested? */
+ {
+ sp_globals.tcb0.xtype = sp_globals.tcb0.ytype = 4;
+ }
+
+if ((sp_globals.pspecs->flags & SQUEEZE_LEFT) ||
+ (sp_globals.pspecs->flags & SQUEEZE_RIGHT) ||
+ (sp_globals.pspecs->flags & SQUEEZE_TOP) ||
+ (sp_globals.pspecs->flags & SQUEEZE_BOTTOM) )
+ {
+#if (INCL_SQUEEZING)
+#else
+ report_error(11);
+ return FALSE;
+#endif
+ }
+
+if ((sp_globals.pspecs->flags & CLIP_LEFT) ||
+ (sp_globals.pspecs->flags & CLIP_RIGHT) ||
+ (sp_globals.pspecs->flags & CLIP_TOP) ||
+ (sp_globals.pspecs->flags & CLIP_BOTTOM) )
+ {
+#if (INCL_CLIPPING)
+#else
+ report_error(11);
+ return FALSE;
+#endif
+ }
+
+sp_globals.specs_valid = TRUE;
+return TRUE;
+}
+
+
+
+#if INCL_MULTIDEV
+#if INCL_BLACK || INCL_SCREEN || INCL_2D
+FUNCTION boolean set_bitmap_device(
+GDECL
+bitmap_t *bfuncs,
+ufix16 size)
+{
+
+if (size != sizeof(sp_globals.bitmap_device))
+ return FALSE;
+
+sp_globals.bitmap_device = *bfuncs;
+sp_globals.bitmap_device_set = TRUE;
+}
+#endif
+
+#if INCL_OUTLINE
+FUNCTION boolean set_outline_device(
+GDECL
+outline_t *ofuncs,
+ufix16 size)
+{
+
+if (size != sizeof(sp_globals.outline_device))
+ return FALSE;
+
+sp_globals.outline_device = *ofuncs;
+sp_globals.outline_device_set = TRUE;
+}
+#endif
+#endif
+
+
+#ifdef old
+FUNCTION boolean sp_setup_consts(
+GDECL
+fix15 xmin, /* Minimum X ORU value in font */
+fix15 xmax, /* Maximum X ORU value in font */
+fix15 ymin, /* Minimum Y ORU value in font */
+fix15 ymax) /* Maximum Y ORU value in font */
+#else
+static FUNCTION boolean sp_setup_consts(
+GDECL
+fix15 xmin, /* Minimum X ORU value in font */
+fix15 xmax, /* Maximum X ORU value in font */
+fix15 ymin, /* Minimum Y ORU value in font */
+fix15 ymax) /* Maximum Y ORU value in font */
+#endif
+/*
+ * Sets the following constants used for fixed point arithmetic:
+ * sp_globals.multshift multipliers and products; range is 14 to 8
+ * sp_globals.pixshift pixels: range is 0 to 8
+ * sp_globals.mpshift shift from product to sub-pixels (sp_globals.multshift - sp_globals.pixshift)
+ * sp_globals.multrnd rounding for products
+ * sp_globals.pixrnd rounding for pixels
+ * sp_globals.mprnd rounding for sub-pixels
+ * sp_globals.onepix 1 pixel in shifted pixel units
+ * sp_globals.pixfix mask to eliminate fractional bits of shifted pixels
+ * sp_globals.depth_adj curve splitting depth adjustment
+ * Returns FALSE if specs are out of range
+ */
+{
+fix31 mult; /* Successive multiplier values */
+ufix32 num; /* Numerator of largest multiplier value */
+ufix32 numcopy; /* Copy of numerator */
+ufix32 denom; /* Denominator of largest multiplier value */
+ufix32 denomcopy; /* Copy of denominator */
+ufix32 pix_max; /* Maximum pixel rounding error */
+fix31 xmult; /* Coefficient of X oru value in transformation */
+fix31 ymult; /* Coefficient of Y oru value in transformation */
+fix31 offset; /* Constant in transformation */
+fix15 i; /* Loop counter */
+fix15 x, y; /* Successive corners of bounding box in ORUs */
+fix31 pixval; /* Successive pixel values multiplied by orus per em */
+fix15 xx = 0, yy = 0;/* Bounding box corner that produces max pixel value */
+
+/* Determine numerator and denominator of largest multiplier value */
+mult = sp_globals.pspecs->xxmult >> 16;
+if (mult < 0)
+ mult = -mult;
+num = mult;
+
+mult = sp_globals.pspecs->xymult >> 16;
+if (mult < 0)
+ mult = -mult;
+if (mult > num)
+ num = mult;
+
+mult = sp_globals.pspecs->yxmult >> 16;
+if (mult < 0)
+ mult = -mult;
+if (mult > num)
+ num = mult;
+
+mult = sp_globals.pspecs->yymult >> 16;
+if (mult < 0)
+ mult = -mult;
+if (mult > num)
+ num = mult;
+num++; /* Max absolute pixels per em (rounded up) */
+denom = (ufix32)sp_globals.orus_per_em;
+
+/* Set curve splitting depth adjustment to accomodate largest multiplier value */
+sp_globals.depth_adj = 0; /* 0 = 0.5 pel, 1 = 0.13 pel, 2 = 0.04 pel accuracy */
+denomcopy = denom;
+/* The following two occurances of a strange method of shifting twice by 1
+ are intentional and should not be changed to a single shift by 2.
+ It prevents MicroSoft C 5.1 from generating functions calls to do the shift.
+ Worse, using the REENTRANT_ALLOC option in conjunction with the /AC compiler
+ option, the function appears to be called incorrectly, causing depth_adj to always
+ be set to -7, causing very angular characters. */
+
+while ((num > denomcopy) && (sp_globals.depth_adj < 5)) /* > 1, 4, 16, ... pixels per oru? */
+ {
+ denomcopy <<= 1;
+ denomcopy <<= 1;
+ sp_globals.depth_adj++; /* Add 1, 2, 3, ... to depth adjustment */
+ }
+numcopy = num << 2;
+while ((numcopy <= denom) && (sp_globals.depth_adj > -4)) /* <= 1/4, 1/16, 1/64 pix per oru? */
+ {
+ numcopy <<= 1;
+ numcopy <<= 1;
+ sp_globals.depth_adj--; /* Subtract 1, 2, 3, ... from depth adjustment */
+ }
+SHOW(sp_globals.depth_adj);
+
+/* Set multiplier shift to accomodate largest multiplier value */
+sp_globals.multshift = 14;
+numcopy = num;
+while (numcopy >= denom) /* More than 1, 2, 4, ... pix per oru? */
+ {
+ numcopy >>= 1;
+ sp_globals.multshift--; /* sp_globals.multshift is 13, 12, 11, ... */
+ }
+
+sp_globals.multrnd = ((fix31)1 << sp_globals.multshift) >> 1;
+SHOW(sp_globals.multshift);
+
+
+pix_max = (ufix32)( 0xffff & read_word_u(sp_globals.hdr2_org + FH_PIXMX));
+
+num = 0;
+xmult = ((sp_globals.pspecs->xxmult >> 16) + 1) >> 1;
+ymult = ((sp_globals.pspecs->xymult >> 16) + 1) >> 1;
+offset = ((sp_globals.pspecs->xoffset >> 16) + 1) >> 1;
+for (i = 0; i < 8; i++)
+ {
+ if (i == 4)
+ {
+ xmult = ((sp_globals.pspecs->yxmult >> 16) + 1) >> 1;
+ ymult = ((sp_globals.pspecs->yymult >> 16) + 1) >> 1;
+ offset = ((sp_globals.pspecs->yoffset >> 16) + 1) >> 1;
+ }
+ x = (i & BIT1)? xmin: xmax;
+ y = (i & BIT0)? ymin: ymax;
+ pixval = (fix31)x * xmult + (fix31)y * ymult + offset * denom;
+ if (pixval < 0)
+ pixval = -pixval;
+ if (pixval > num)
+ {
+ num = pixval;
+ xx = x;
+ yy = y;
+ }
+ }
+if (xx < 0)
+ xx = -xx;
+if (yy < 0)
+ yy = -yy;
+num += xx + yy + ((pix_max + 2) * denom);
+ /* Allow (with 2:1 safety margin) for 1 pixel rounding errors in */
+ /* xmult, ymult and offset values, pix_max pixel expansion */
+ /* due to intelligent scaling, and */
+ /* 1 pixel rounding of overall character position */
+denom = denom << 14; /* Note num is in units of half pixels times orus per em */
+
+sp_globals.pixshift = -1;
+while ((num <= denom) && (sp_globals.pixshift < 8)) /* Max pixels <= 32768, 16384, 8192, ... pixels? */
+ {
+ num <<= 1;
+ sp_globals.pixshift++; /* sp_globals.pixshift = 0, 1, 2, ... */
+ }
+if (sp_globals.pixshift < 0)
+ return FALSE;
+
+SHOW(sp_globals.pixshift);
+sp_globals.poshift = 16 - sp_globals.pixshift;
+
+sp_globals.onepix = (fix15)1 << sp_globals.pixshift;
+sp_globals.pixrnd = sp_globals.onepix >> 1;
+sp_globals.pixfix = ~0 << sp_globals.pixshift;
+
+sp_globals.mpshift = sp_globals.multshift - sp_globals.pixshift;
+if (sp_globals.mpshift < 0)
+ return FALSE;
+sp_globals.mprnd = ((fix31)1 << sp_globals.mpshift) >> 1;
+
+return TRUE;
+}
+
+#ifdef old
+FUNCTION void sp_setup_tcb(
+GDECL
+tcb_t GLOBALFAR *ptcb) /* Pointer to transformation control bloxk */
+#else
+static FUNCTION void sp_setup_tcb(
+GDECL
+tcb_t GLOBALFAR *ptcb) /* Pointer to transformation control bloxk */
+#endif
+/*
+ * Convert transformation coeffs to internal form
+ */
+{
+
+ptcb->xxmult = sp_setup_mult(sp_globals.pspecs->xxmult);
+ptcb->xymult = sp_setup_mult(sp_globals.pspecs->xymult);
+ptcb->xoffset = sp_setup_offset(sp_globals.pspecs->xoffset);
+ptcb->yxmult = sp_setup_mult(sp_globals.pspecs->yxmult);
+ptcb->yymult = sp_setup_mult(sp_globals.pspecs->yymult);
+ptcb->yoffset = sp_setup_offset(sp_globals.pspecs->yoffset);
+
+SHOW(ptcb->xxmult);
+SHOW(ptcb->xymult);
+SHOW(ptcb->xoffset);
+SHOW(ptcb->yxmult);
+SHOW(ptcb->yymult);
+SHOW(ptcb->yoffset);
+
+type_tcb(ptcb); /* Classify transformation type */
+}
+
+FUNCTION static fix15 sp_setup_mult(
+GDECL
+fix31 input_mult) /* Multiplier in input format */
+/*
+ * Called by sp_setup_tcb() to convert multiplier in transformation
+ * matrix from external to internal form.
+ */
+{
+fix15 imshift; /* Right shift to internal format */
+fix31 imdenom; /* Divisor to internal format */
+fix31 imrnd; /* Rounding for division operation */
+
+imshift = 15 - sp_globals.multshift;
+imdenom = (fix31)sp_globals.orus_per_em << imshift;
+imrnd = imdenom >> 1;
+
+input_mult >>= 1;
+if (input_mult >= 0)
+ return (fix15)((input_mult + imrnd) / imdenom);
+else
+ return -(fix15)((-input_mult + imrnd) / imdenom);
+}
+
+FUNCTION static fix31 sp_setup_offset(
+GDECL
+fix31 input_offset) /* Multiplier in input format */
+/*
+ * Called by sp_setup_tcb() to convert offset in transformation
+ * matrix from external to internal form.
+ */
+{
+fix15 imshift; /* Right shift to internal format */
+fix31 imrnd; /* Rounding for right shift operation */
+
+imshift = 15 - sp_globals.multshift;
+imrnd = ((fix31)1 << imshift) >> 1;
+
+return (((input_offset >> 1) + imrnd) >> imshift) + sp_globals.mprnd;
+}
+
+FUNCTION void type_tcb(
+GDECL
+tcb_t GLOBALFAR *ptcb) /* Pointer to transformation control bloxk */
+{
+fix15 x_trans_type;
+fix15 y_trans_type;
+fix15 xx_mult;
+fix15 xy_mult;
+fix15 yx_mult;
+fix15 yy_mult;
+fix15 h_pos;
+fix15 v_pos;
+fix15 x_ppo;
+fix15 y_ppo;
+fix15 x_pos;
+fix15 y_pos;
+
+/* check for mirror image transformations */
+xx_mult = ptcb->xxmult;
+xy_mult = ptcb->xymult;
+yx_mult = ptcb->yxmult;
+yy_mult = ptcb->yymult;
+
+ptcb->mirror = ((((fix31)xx_mult*(fix31)yy_mult)-
+ ((fix31)xy_mult*(fix31)yx_mult)) < 0) ? -1 : 1;
+
+if (sp_globals.pspecs->flags & BOGUS_MODE) /* Linear transformation requested? */
+ {
+ ptcb->xtype = 4;
+ ptcb->ytype = 4;
+
+ ptcb->xppo = 0;
+ ptcb->yppo = 0;
+ ptcb->xpos = 0;
+ ptcb->ypos = 0;
+ }
+else /* Intelligent tranformation requested? */
+ {
+ h_pos = ((ptcb->xoffset >> sp_globals.mpshift) + sp_globals.pixrnd) & sp_globals.pixfix;
+ v_pos = ((ptcb->yoffset >> sp_globals.mpshift) + sp_globals.pixrnd) & sp_globals.pixfix;
+
+ x_trans_type = 4;
+ x_ppo = 0;
+ x_pos = 0;
+
+ y_trans_type = 4;
+ y_ppo = 0;
+ y_pos = 0;
+
+ if (xy_mult == 0)
+ {
+ if (xx_mult >= 0)
+ {
+ x_trans_type = 0; /* X pix is function of X orus only */
+ x_ppo = xx_mult;
+ x_pos = h_pos;
+ }
+ else
+ {
+ x_trans_type = 1; /* X pix is function of -X orus only */
+ x_ppo = -xx_mult;
+ x_pos = -h_pos;
+ }
+ }
+
+ else if (xx_mult == 0)
+ {
+ if (xy_mult >= 0)
+ {
+ x_trans_type = 2; /* X pix is function of Y orus only */
+ y_ppo = xy_mult;
+ y_pos = h_pos;
+ }
+ else
+ {
+ x_trans_type = 3; /* X pix is function of -Y orus only */
+ y_ppo = -xy_mult;
+ y_pos = -h_pos;
+ }
+ }
+
+ if (yx_mult == 0)
+ {
+ if (yy_mult >= 0)
+ {
+ y_trans_type = 0; /* Y pix is function of Y orus only */
+ y_ppo = yy_mult;
+ y_pos = v_pos;
+ }
+ else
+ {
+ y_trans_type = 1; /* Y pix is function of -Y orus only */
+ y_ppo = -yy_mult;
+ y_pos = -v_pos;
+ }
+ }
+ else if (yy_mult == 0)
+ {
+ if (yx_mult >= 0)
+ {
+ y_trans_type = 2; /* Y pix is function of X orus only */
+ x_ppo = yx_mult;
+ x_pos = v_pos;
+ }
+ else
+ {
+ y_trans_type = 3; /* Y pix is function of -X orus only */
+ x_ppo = -yx_mult;
+ x_pos = -v_pos;
+ }
+ }
+
+ ptcb->xtype = x_trans_type;
+ ptcb->ytype = y_trans_type;
+
+ ptcb->xppo = x_ppo;
+ ptcb->yppo = y_ppo;
+ ptcb->xpos = x_pos;
+ ptcb->ypos = y_pos;
+ }
+
+sp_globals.normal = (ptcb->xtype != 4) && (ptcb->ytype != 4);
+
+ptcb->xmode = 4;
+ptcb->ymode = 4;
+
+SHOW(ptcb->xtype);
+SHOW(ptcb->ytype);
+SHOW(ptcb->xppo);
+SHOW(ptcb->yppo);
+SHOW(ptcb->xpos);
+SHOW(ptcb->ypos);
+}
+
+FUNCTION fix31 read_long(
+GDECL
+ufix8 FONTFAR *pointer) /* Pointer to first byte of encrypted 3-byte integer */
+/*
+ * Reads a 3-byte encrypted integer from the byte string starting at
+ * the specified point.
+ * Returns the decrypted value read as a signed integer.
+ */
+{
+fix31 tmpfix31;
+
+tmpfix31 = (fix31)((*pointer++) ^ sp_globals.key4) << 8; /* Read middle byte */
+tmpfix31 += (fix31)(*pointer++) << 16; /* Read most significant byte */
+tmpfix31 += (fix31)((*pointer) ^ sp_globals.key6); /* Read least significant byte */
+return tmpfix31;
+}
+
+FUNCTION fix15 read_word_u(
+GDECL
+ufix8 FONTFAR *pointer) /* Pointer to first byte of unencrypted 2-byte integer */
+/*
+ * Reads a 2-byte unencrypted integer from the byte string starting at
+ * the specified point.
+ * Returns the decrypted value read as a signed integer.
+ */
+{
+fix15 tmpfix15;
+
+tmpfix15 = (fix15)(*pointer++) << 8; /* Read most significant byte */
+tmpfix15 += (fix15)(*pointer); /* Add least significant byte */
+return tmpfix15;
+}
+
+
diff --git a/libXfont/src/Speedo/set_trns.c b/libXfont/src/Speedo/set_trns.c
new file mode 100644
index 000000000..35c2e33cf
--- /dev/null
+++ b/libXfont/src/Speedo/set_trns.c
@@ -0,0 +1,1214 @@
+/* $Xorg: set_trns.c,v 1.3 2000/08/17 19:46:27 cpqbld Exp $ */
+
+/*
+
+Copyright 1989-1991, Bitstream Inc., Cambridge, MA.
+You are hereby granted permission under all Bitstream propriety rights to
+use, copy, modify, sublicense, sell, and redistribute the Bitstream Speedo
+software and the Bitstream Charter outline font for any purpose and without
+restrictions; provided, that this notice is left intact on all copies of such
+software or font and that Bitstream's trademark is acknowledged as shown below
+on all unmodified copies of such font.
+
+BITSTREAM CHARTER is a registered trademark of Bitstream Inc.
+
+
+BITSTREAM INC. DISCLAIMS ANY AND ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING
+WITHOUT LIMITATION THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+PARTICULAR PURPOSE. BITSTREAM SHALL NOT BE LIABLE FOR ANY DIRECT OR INDIRECT
+DAMAGES, INCLUDING BUT NOT LIMITED TO LOST PROFITS, LOST DATA, OR ANY OTHER
+INCIDENTAL OR CONSEQUENTIAL DAMAGES, ARISING OUT OF OR IN ANY WAY CONNECTED
+WITH THE SPEEDO SOFTWARE OR THE BITSTREAM CHARTER OUTLINE FONT.
+
+*/
+/* $XFree86: xc/lib/font/Speedo/set_trns.c,v 1.5tsi Exp $ */
+
+
+
+/*************************** S E T _ T R N S . C *****************************
+ * *
+ * This module is called from do_char.c to set up the intelligent *
+ * transformation for one character (or sub-character of a composite *
+ * character.
+ * *
+ ****************************************************************************/
+
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "spdo_prv.h" /* General definitions for Speedo */
+
+#define DEBUG 0
+
+#if DEBUG
+#include <stdio.h>
+#define SHOW(X) printf("X = %d\n", X)
+#else
+#define SHOW(X)
+#endif
+/***** LOCAL MACROS *****/
+
+#define SQUEEZE_X_ORU(A,B,C) ((((fix31)A * (fix31)B) + C) >> 16)
+#define ABS(A) ((A < 0)? -A:A) /* absolute value */
+#define IMPORT_FACTOR \
+ shift = 16;\
+ while (*x_factor > (0x7fffffffL / (isw_scale >> (16 - shift))))\
+ shift--;\
+ *x_factor = (*x_factor * (isw_scale>>(16-shift))) >> shift;
+
+/***** GLOBAL VARIABLES *****/
+
+/***** GLOBAL FUNCTIONS *****/
+
+/***** EXTERNAL VARIABLES *****/
+
+/***** EXTERNAL FUNCTIONS *****/
+
+/***** STATIC VARIABLES *****/
+
+/***** STATIC FUNCTIONS *****/
+
+static void sp_constr_update(PROTO_DECL1);
+static ufix8 FONTFAR *sp_setup_pix_table(PROTO_DECL2 ufix8 FONTFAR *pointer,boolean short_form,fix15 no_X_ctrl_zones,fix15 no_Y_ctrl_zones);
+static ufix8 FONTFAR *sp_setup_int_table(PROTO_DECL2 ufix8 FONTFAR *pointer,fix15 no_X_int_zones,fix15 no_Y_int_zones);
+
+
+FUNCTION void init_tcb()
+GDECL
+/*
+ * Called by sp_make_char() and make_comp_char() to initialize the current
+ * transformation control block to the top level transformation.
+ */
+{
+sp_globals.tcb = sp_globals.tcb0;
+}
+
+FUNCTION void scale_tcb(
+GDECL
+tcb_t GLOBALFAR *ptcb, /* Transformation control block */
+fix15 x_pos, /* X position (outline res units) */
+fix15 y_pos, /* Y position (outline res units) */
+fix15 x_scale, /* X scale factor * ONE_SCALE */
+fix15 y_scale) /* Y scale factor * ONE_SCALE */
+/*
+ * Called by make_comp_char() to apply position and scale for each of the
+ * components of a compound character.
+ */
+{
+fix15 xx_mult = ptcb->xxmult;
+fix15 xy_mult = ptcb->xymult;
+fix31 x_offset = ptcb->xoffset;
+fix15 yx_mult = ptcb->yxmult;
+fix15 yy_mult = ptcb->yymult;
+fix31 y_offset = ptcb->yoffset;
+
+ptcb->xxmult = TRANS(xx_mult, x_scale, (fix31)SCALE_RND, SCALE_SHIFT);
+ptcb->xymult = TRANS(xy_mult, y_scale, (fix31)SCALE_RND, SCALE_SHIFT);
+ptcb->xoffset = MULT16(xx_mult, x_pos) + MULT16(xy_mult, y_pos) + x_offset;
+ptcb->yxmult = TRANS(yx_mult, x_scale, (fix31)SCALE_RND, SCALE_SHIFT);
+ptcb->yymult = TRANS(yy_mult, y_scale, (fix31)SCALE_RND, SCALE_SHIFT);
+ptcb->yoffset = MULT16(yx_mult, x_pos) + MULT16(yy_mult, y_pos) + y_offset;
+
+type_tcb(ptcb); /* Reclassify transformation types */
+}
+
+
+static FUNCTION ufix8 FONTFAR *read_oru_table(
+GDECL
+ufix8 FONTFAR *pointer) /* Pointer to first byte in controlled coord table */
+/*
+ * Called by plaid_tcb() to read the controlled coordinate table from the
+ * character data in the font.
+ * Updates the pointer to the byte following the controlled coordinate
+ * data.
+ */
+{
+fix15 i, j, k, n;
+boolean zero_not_in;
+boolean zero_added;
+fix15 oru;
+
+fix15 pos;
+
+i = 0;
+n = sp_globals.no_X_orus;
+pos = sp_globals.tcb.xpos;
+for (j = 0; ; j++)
+ {
+ zero_not_in = TRUE;
+ zero_added = FALSE;
+ for (k = 0; k < n; k++)
+ {
+ oru = NEXT_WORD(pointer);
+ if (zero_not_in && (oru >= 0)) /* First positive oru value? */
+ {
+ sp_plaid.pix[i] = pos; /* Insert position in pix array */
+ if (oru != 0) /* Zero oru value omitted? */
+ {
+ sp_plaid.orus[i++] = 0; /* Insert zero value in oru array */
+ zero_added = TRUE; /* Remember to increment size of array */
+ }
+ zero_not_in = FALSE; /* Inhibit further testing for zero ins */
+ }
+ sp_plaid.orus[i++] = oru; /* Add specified oru value to array */
+ }
+ if (zero_not_in) /* All specified oru values negative? */
+ {
+ sp_plaid.pix[i] = pos; /* Insert position in pix array */
+ sp_plaid.orus[i++] = 0; /* Add zero oru value */
+ zero_added = TRUE; /* Remember to increment size of array */
+ }
+ if (j) /* Both X and Y orus read? */
+ break;
+ if (zero_added)
+ sp_globals.no_X_orus++; /* Increment X array size */
+ n = sp_globals.no_Y_orus; /* Prepare to read Y oru values */
+ pos = sp_globals.tcb.ypos;
+ }
+if (zero_added) /* Zero Y oru value added to array? */
+ sp_globals.no_Y_orus++; /* Increment Y array size */
+
+#if DEBUG
+printf("\nX ORUS\n");
+n = sp_globals.no_X_orus;
+for (i = 0; i < n; i++)
+ {
+ printf("%2d %4d\n", i, sp_plaid.orus[i]);
+ }
+printf("\nY ORUS\n");
+n = sp_globals.no_Y_orus;
+for (i = 0; i < n; i++)
+ {
+ printf("%2d %4d\n", i, sp_plaid.orus[i + sp_globals.no_X_orus]);
+ }
+#endif
+
+return pointer; /* Update pointer */
+}
+
+FUNCTION ufix8 FONTFAR *plaid_tcb(
+GDECL
+ufix8 FONTFAR *pointer, /* Pointer to next byte in char data */
+ufix8 format) /* Character format byte */
+/*
+ * Called by make_simp_char() and make_comp_char() to set up the controlled
+ * coordinate table and process all intelligent scaling rules embedded
+ * in the character data.
+ * Updates pointer to first byte after plaid data.
+ * This is used only if intelligent scaling is enabled in the
+ * configuration definitions.
+ */
+{
+fix15 no_X_ctrl_zones;
+fix15 no_Y_ctrl_zones;
+fix15 no_X_int_zones;
+fix15 no_Y_int_zones;
+
+#if INCL_PLAID_OUT /* Plaid data monitoring included? */
+begin_plaid_data();
+#endif
+
+sp_constr_update(); /* Update constraint table if required */
+
+sp_globals.no_X_orus = (format & BIT2)?
+ (fix15)NEXT_BYTE(pointer):
+ 0;
+sp_globals.no_Y_orus = (format & BIT3)?
+ (fix15)NEXT_BYTE(pointer):
+ 0;
+pointer = read_oru_table(pointer); /* Updates no_X/Y/orus to include zero values */
+sp_globals.Y_edge_org = sp_globals.no_X_orus;
+if (sp_globals.no_X_orus > 1) /* 2 or more controlled X coordinates? */
+ sp_globals.tcb.xmode = sp_globals.tcb.xtype; /* Enable intelligent scaling in X */
+
+if (sp_globals.no_Y_orus > 1) /* 2 or more controlled Y coordinates? */
+ sp_globals.tcb.ymode = sp_globals.tcb.ytype; /* Enable intelligent scaling in Y */
+
+no_X_ctrl_zones = sp_globals.no_X_orus - 1;
+no_Y_ctrl_zones = sp_globals.no_Y_orus - 1;
+pointer = sp_setup_pix_table(pointer, (boolean)(format & BIT4),
+ no_X_ctrl_zones, no_Y_ctrl_zones);
+
+no_X_int_zones = (format & BIT6)?
+ (fix15)NEXT_BYTE(pointer):
+ 0;
+no_Y_int_zones = (format & BIT7)?
+ (fix15)NEXT_BYTE(pointer):
+ 0;
+sp_globals.Y_int_org = no_X_int_zones;
+pointer = sp_setup_int_table(pointer, no_X_int_zones, no_Y_int_zones);
+
+#if INCL_PLAID_OUT /* Plaid data monitoring included? */
+end_plaid_data();
+#endif
+
+return pointer;
+}
+
+FUNCTION static void sp_constr_update()
+GDECL
+/*
+ * Called by plaid_tcb() to update the constraint table for the current
+ * transformation.
+ * This is always carried out whenever a character is generated following
+ * a change of font or scale factor or after initialization.
+ */
+{
+fix31 ppo;
+fix15 xppo;
+fix15 yppo;
+ufix8 FONTFAR *pointer;
+fix15 no_X_constr;
+fix15 no_Y_constr;
+fix15 i, j, k, l, n;
+fix15 ppm;
+ufix8 format;
+ufix8 format1;
+fix15 limit;
+ufix16 constr_org;
+fix15 constr_nr;
+fix15 size;
+fix31 off;
+fix15 min;
+fix15 orus;
+fix15 pix;
+ufix16 tmpufix16; /* in extended mode, macro uses secnd term */
+
+if (sp_globals.constr.data_valid && /* Constr table already done and ... */
+ (sp_globals.tcb.xppo == sp_globals.constr.xppo) && /* ... X pix per oru unchanged and ... */
+ (sp_globals.tcb.yppo == sp_globals.constr.yppo)) /* ... Y pix per oru unchanged? */
+ {
+ return; /* No need to update constraint table */
+ }
+
+sp_globals.constr.xppo = xppo = sp_globals.tcb.xppo; /* Update X pixels per oru indicator */
+sp_globals.constr.yppo = yppo = sp_globals.tcb.yppo; /* Update Y pixels per oru indicator */
+sp_globals.constr.data_valid = TRUE; /* Mark constraint table valid */
+
+pointer = sp_globals.constr.org; /* Point to first byte of constraint data */
+no_X_constr = NEXT_BYTES(pointer, tmpufix16); /* Read nmbr of X constraints */
+no_Y_constr = NEXT_BYTES(pointer, tmpufix16); /* Read nmbr of Y constraints */
+
+i = 0;
+constr_org = 0;
+n = no_X_constr;
+ppo = xppo;
+for (j = 0; ; j++)
+ {
+ sp_globals.c_act[i] = FALSE; /* Flag constraint 0 not active */
+ sp_globals.c_pix[i++] = 0; /* Constraint 0 implies no minimum */
+ sp_globals.c_act[i] = FALSE; /* Flag constraint 1 not active */
+ sp_globals.c_pix[i++] = sp_globals.onepix; /* Constraint 1 implies min 1 pixel*/
+ ppm = (ppo * (fix31)sp_globals.orus_per_em) >> sp_globals.multshift;
+ for (k = 0; k < n; k++)
+ {
+ format = NEXT_BYTE(pointer); /* Read format byte */
+ limit = (fix15)NEXT_BYTE(pointer); /* Read limit field */
+ sp_globals.c_act[i] =
+ ((ppm < limit) || (limit == 255)) &&
+ sp_globals.constr.active;
+ if (sp_globals.c_act[i]) /* Constraint active? */
+ {
+ if ((format & BIT1) && /* Constraint specified and ... */
+ (constr_nr = constr_org +
+ ((format & BIT0)? /* Read unsigned constraint value */
+ NEXT_WORD(pointer):
+ (fix15)NEXT_BYTE(pointer)),
+ sp_globals.c_act[constr_nr])) /* ... and specified constraint active? */
+ {
+ pix = sp_globals.c_pix[constr_nr]; /* Use constrained pixel value */
+ format1 = format;
+ for (l = 2; l > 0; l--) /* Skip 2 arguments */
+ {
+ format1 >>= 2;
+ if ((size = format1 & 0x03))
+ pointer += size - 1;
+ }
+ }
+ else /* Constraint absent or inactive? */
+ {
+ orus = (format & BIT2)? /* Read unsigned oru value */
+ NEXT_WORD(pointer):
+ (fix15)NEXT_BYTE(pointer);
+
+ if (format & BIT5) /* Specified offset value? */
+ {
+ off = (fix31)((format & BIT4)? /* Read offset value */
+ NEXT_WORD(pointer):
+ (fix7)NEXT_BYTE(pointer));
+ off = (off << (sp_globals.multshift - 6)) + sp_globals.multrnd;
+ }
+ else /* Unspecified (zero) offset value? */
+ {
+ off = sp_globals.multrnd;
+ }
+
+ pix = (fix15)(((fix31)orus * ppo + off) / (1 << sp_globals.mpshift)) & sp_globals.pixfix;
+ }
+ }
+ else /* Constraint inactive? */
+ {
+ format1 = format;
+ for (l = 3; l > 0; l--) /* Skip over 3 arguments */
+ {
+ if ((size = format1 & 0x03))
+ pointer += size - 1;
+ format1 >>= 2;
+ }
+ pix = 0;
+ }
+
+ if (format & 0xc0) /* Specified minimum value? */
+ {
+ min = (format & BIT7)? /* Read unsigned minimum value */
+ (fix15)NEXT_BYTE(pointer) << sp_globals.pixshift:
+ sp_globals.onepix;
+ }
+ else /* Unspecified (zero) minimum value? */
+ {
+ min = 0;
+ }
+
+ sp_globals.c_pix[i] = (pix < min)? min: pix;
+ i++;
+ }
+ if (j) break; /* Finished if second time around loop */
+ constr_org = sp_globals.Y_constr_org = i;
+ n = no_Y_constr;
+ ppo = yppo;
+ }
+
+#if DEBUG
+printf("\nCONSTRAINT TABLE\n");
+n = no_X_constr + 2;
+for (i = 0; i < n; i++)
+ {
+ printf("%3d ", i);
+ if (sp_globals.c_act[i])
+ {
+ printf("T ");
+ }
+ else
+ {
+ printf("F ");
+ }
+ printf("%5.1f\n", ((real)sp_globals.c_pix[i] / (real)sp_globals.onepix));
+ }
+printf("--------------\n");
+n = no_Y_constr + 2;
+for (i = 0; i < n; i++)
+ {
+ j = i + sp_globals.Y_constr_org;
+ printf("%3d ", i);
+ if (sp_globals.c_act[j])
+ {
+ printf("T ");
+ }
+ else
+ {
+ printf("F ");
+ }
+ printf("%5.1f\n", ((real)sp_globals.c_pix[j] / (real)sp_globals.onepix));
+ }
+#endif
+
+}
+
+#if INCL_SQUEEZING || INCL_ISW
+FUNCTION static void calculate_x_pix(
+GDECL
+ufix8 start_edge, ufix8 end_edge,
+ufix16 constr_nr,
+fix31 x_scale,
+fix31 x_offset,
+fix31 ppo,
+fix15 setwidth_pix)
+/*
+ * Called by sp_setup_pix_table() when X squeezing is necessary
+ * to insert the correct edge in the global pix array
+ */
+{
+fix15 zone_pix;
+fix15 start_oru, end_oru;
+
+/* compute scaled oru coordinates */
+start_oru= (fix15)(SQUEEZE_X_ORU(sp_plaid.orus[start_edge], x_scale, x_offset));
+end_oru = (fix15)(SQUEEZE_X_ORU(sp_plaid.orus[end_edge], x_scale, x_offset));
+
+if (!sp_globals.c_act[constr_nr]) /* constraint inactive */
+ {
+ /* calculate zone width */
+ zone_pix = (fix15)(((((fix31)end_oru - (fix31)start_oru) * ppo) /
+ (1<<sp_globals.mpshift)) + sp_globals.pixrnd) & sp_globals.pixfix;
+ /* check for overflow */
+ if (((end_oru-start_oru) > 0) && (zone_pix < 0))
+ zone_pix = 0x7ffff;
+ /* check for minimum */
+ if ((ABS(zone_pix)) >= sp_globals.c_pix[constr_nr])
+ goto Lx;
+ }
+/* use the zone size from the constr table - scale it */
+zone_pix = (fix15)(((SQUEEZE_MULT(x_scale,sp_globals.c_pix[constr_nr]))
+ + sp_globals.pixrnd) & sp_globals.pixfix);
+
+/* look for overflow */
+if ((sp_globals.c_pix[constr_nr] > 0) && (zone_pix < 0))
+ zone_pix = 0x7fff;
+
+if (start_edge > end_edge)
+ {
+ zone_pix = -zone_pix;
+ }
+Lx:
+/* assign pixel value to global pix array */
+sp_plaid.pix[end_edge]=sp_plaid.pix[start_edge] + zone_pix;
+
+/* check for overflow */
+if (((sp_plaid.pix[start_edge] >0) && (zone_pix >0)) &&
+ (sp_plaid.pix[end_edge] < 0))
+ sp_plaid.pix[end_edge] = 0x7fff; /* set it to the max */
+
+/* be sure to be in the setwidth !*/
+#if INCL_ISW
+if (!sp_globals.import_setwidth_act) /* only check left edge if not isw only */
+#endif
+if ((sp_globals.pspecs->flags & SQUEEZE_LEFT) && (sp_plaid.pix[end_edge] < 0))
+ sp_plaid.pix[end_edge] = 0;
+if ((sp_globals.pspecs->flags & SQUEEZE_RIGHT) &&
+ (sp_plaid.pix[end_edge] > setwidth_pix))
+ sp_plaid.pix[end_edge] = setwidth_pix;
+
+}
+#endif
+
+#if INCL_SQUEEZING
+FUNCTION static void calculate_y_pix(
+GDECL
+ufix8 start_edge, ufix8 end_edge,
+ufix16 constr_nr,
+fix31 top_scale, fix31 bottom_scale,
+fix31 ppo,
+fix15 em_top_pix, fix15 em_bot_pix)
+
+/*
+ * Called by sp_setup_pix_table() when Y squeezing is necessary
+ * to insert the correct edge in the global pix array
+ */
+{
+fix15 zone_pix;
+fix15 start_oru, end_oru;
+fix31 zone_width, above_base, below_base;
+
+/* check whether edge is above or below the baseline */
+/* and apply appropriate scale factor to get scaled oru coordinates */
+if (sp_plaid.orus[start_edge] < 0)
+ start_oru =(fix15)(SQUEEZE_MULT(sp_plaid.orus[start_edge], bottom_scale));
+else
+ start_oru =(fix15)(SQUEEZE_MULT(sp_plaid.orus[start_edge], top_scale));
+
+if (sp_plaid.orus[end_edge] < 0)
+ end_oru =(fix15)(SQUEEZE_MULT(sp_plaid.orus[end_edge], bottom_scale));
+else
+ end_oru =(fix15)(SQUEEZE_MULT(sp_plaid.orus[end_edge], top_scale));
+
+if (!sp_globals.c_act[constr_nr]) /* Constraint inactive? */
+ {
+ /* calculate zone width */
+ zone_pix = (fix15)(((((fix31)end_oru - (fix31)start_oru) * ppo)
+ >> sp_globals.mpshift)+ sp_globals.pixrnd) & sp_globals.pixfix;
+ /* check minimum */
+ if ((ABS(zone_pix)) >= sp_globals.c_pix[constr_nr])
+ goto Ly;
+ }
+
+/* Use zone size from constr table */
+if ((end_oru >= 0) && (start_oru >=0))
+ /* all above baseline */
+ zone_pix = (fix15)(SQUEEZE_MULT(top_scale, sp_globals.c_pix[constr_nr]));
+else if ((end_oru <= 0) && (start_oru <=0))
+ /* all below baseline */
+ zone_pix = (fix15)(SQUEEZE_MULT(bottom_scale, sp_globals.c_pix[constr_nr]));
+else
+ {
+ /* mixture */
+ if (start_oru > 0)
+ {
+ zone_width = start_oru - end_oru;
+ /* get % above baseline in 16.16 fixed point */
+ above_base = (((fix31)start_oru) << 16) /
+ ((fix31)zone_width) ;
+ /* get % below baseline in 16.16 fixed point */
+ below_base = (((fix31)-end_oru) << 16) /
+ ((fix31)zone_width) ;
+ }
+ else
+ {
+ zone_width = end_oru - start_oru;
+ /* get % above baseline in 16.16 fixed point */
+ above_base = (((fix31)-start_oru) << 16) /
+ ((fix31)zone_width) ;
+ /* get % below baseline in 16.16 fixed point */
+ below_base = (((fix31)end_oru) << 16) /
+ ((fix31)zone_width) ;
+ }
+ /* % above baseline * total zone * top_scale + */
+ /* % below baseline * total zone * bottom_scale */
+ zone_pix = ((((above_base * (fix31)sp_globals.c_pix[constr_nr]) >> 16) *
+ top_scale) +
+ (((below_base * (fix31)sp_globals.c_pix[constr_nr]) >> 16) *
+ bottom_scale)) >> 16;
+ }
+
+/* make this zone pix fall on a pixel boundary */
+zone_pix = (zone_pix + sp_globals.pixrnd) & sp_globals.pixfix;
+
+/* if minimum is in effect make the zone one pixel */
+if ((sp_globals.c_pix[constr_nr] != 0) && (zone_pix < sp_globals.onepix))
+ zone_pix = sp_globals.onepix;
+
+if (start_edge > end_edge)
+ {
+ zone_pix = -zone_pix; /* Use negatve zone size */
+ }
+Ly:
+/* assign global pix value */
+sp_plaid.pix[end_edge] = sp_plaid.pix[start_edge] + zone_pix; /* Insert end pixels */
+
+/* make sure it is in the EM !*/
+if ((sp_globals.pspecs->flags & SQUEEZE_TOP) &&
+ (sp_plaid.pix[end_edge] > em_top_pix))
+ sp_plaid.pix[end_edge] = em_top_pix;
+if ((sp_globals.pspecs->flags & SQUEEZE_BOTTOM) &&
+ (sp_plaid.pix[end_edge] < em_bot_pix))
+ sp_plaid.pix[end_edge] = em_bot_pix;
+}
+
+FUNCTION boolean calculate_x_scale(x_factor, x_offset, no_X_ctrl_zones)
+GDECL
+fix31 *x_factor,
+fix31 *x_offset,
+fix15 no_X_ctrl_zones) /* Number of X control zones */
+/*
+ * Called by sp_setup_pix_table() when squeezing is included
+ * to determine whether X scaling is necessary. If it is, the
+ * scale factor and offset are computed. This function returns
+ * a boolean value TRUE = X squeezind is necessary, FALSE = no
+ * X squeezing is necessary.
+ */
+{
+boolean squeeze_left, squeeze_right;
+boolean out_on_right, out_on_left;
+fix15 bbox_width,set_width;
+fix15 bbox_xmin, bbox_xmax;
+fix15 x_offset_pix;
+fix15 i;
+#if INCL_ISW
+fix31 isw_scale;
+fix15 shift;
+#endif
+
+
+/* set up some flags and common calculations */
+squeeze_left = (sp_globals.pspecs->flags & SQUEEZE_LEFT)? TRUE:FALSE;
+squeeze_right = (sp_globals.pspecs->flags & SQUEEZE_RIGHT)? TRUE:FALSE;
+bbox_xmin = sp_globals.bbox_xmin_orus;
+bbox_xmax = sp_globals.bbox_xmax_orus;
+set_width = sp_globals.setwidth_orus;
+
+if (bbox_xmax > set_width)
+ out_on_right = TRUE;
+else
+ out_on_right = FALSE;
+if (bbox_xmin < 0)
+ out_on_left = TRUE;
+else
+ out_on_left = FALSE;
+bbox_width =bbox_xmax - bbox_xmin;
+
+/*
+ * don't need X squeezing if:
+ * - X squeezing not enabled
+ * - bbox doesn't violate on left or right
+ * - left squeezing only is enabled and char isn't out on left
+ * - right squeezing only is enabled and char isn't out on right
+ */
+
+if ((!squeeze_left && !squeeze_right) ||
+ (!out_on_right && !out_on_left) ||
+ (squeeze_left && !squeeze_right && !out_on_left) ||
+ (squeeze_right && !squeeze_left && !out_on_right))
+ return FALSE;
+
+#if INCL_ISW
+if (sp_globals.import_setwidth_act)
+ {
+ /* if both isw and squeezing is going on - let the imported */
+ /* setwidth factor be factored in with the squeeze */
+ isw_scale = compute_isw_scale();
+ /*sp_globals.setwidth_orus = sp_globals.imported_width;*/
+ }
+else
+ isw_scale = 0x10000L; /* 1 in 16.16 notation */
+#endif
+
+/* squeezing on left and right ? */
+if (squeeze_left && squeeze_right)
+ {
+ /* calculate scale factor */
+ if (bbox_width < set_width)
+ *x_factor = 0x10000L; /* 1 in 16.16 notation */
+ else
+ *x_factor = ((fix31)set_width<<16)/(fix31)bbox_width;
+#if INCL_ISW
+ IMPORT_FACTOR
+#endif
+ /* calculate offset */
+ if (out_on_left) /* fall out on left ? */
+ *x_offset = -(fix31)*x_factor * (fix31)bbox_xmin;
+ /* fall out on right and I am shifting only ? */
+ else if (out_on_right && (*x_factor == 0x10000L))
+ *x_offset = -(fix31)*x_factor * (fix31)(bbox_xmax - set_width);
+ else
+ *x_offset = 0x0L; /* 0 in 16.16 notation */
+ }
+/* squeezing on left only and violates left */
+else if (squeeze_left)
+ {
+ if (bbox_width < set_width) /* will it fit if I shift it ? */
+ *x_factor = 0x10000L; /* 1 in 16.16 notation */
+ else if (out_on_right)
+ *x_factor = ((fix31)set_width<<16)/(fix31)bbox_width;
+ else
+ *x_factor = ((fix31)set_width<<16)/
+ (fix31)(bbox_width - (bbox_xmax-set_width));
+#if INCL_ISW
+ IMPORT_FACTOR
+#endif
+ *x_offset = (fix31)-*x_factor * (fix31)bbox_xmin;
+ }
+
+/* I must be squeezing on right, and violates right */
+else
+ {
+ if (bbox_width < set_width) /* will it fit if I shift it ? */
+ { /* just shift it left - it will fit in the bbox */
+ *x_factor = 0x10000L; /* 1 in 16.16 notation */
+#if INCL_ISW
+ IMPORT_FACTOR
+#endif
+ *x_offset = (fix31)-*x_factor * (fix31)bbox_xmin;
+ }
+ else if (out_on_left)
+ {
+ *x_factor = ((fix31)set_width<<16)/(fix31)bbox_width;
+#if INCL_ISW
+ IMPORT_FACTOR
+#endif
+ *x_offset = 0x0L; /* 0 in 16.16 notation */
+ }
+ else
+ {
+ *x_factor = ((fix31)set_width<<16)/(fix31)bbox_xmax;
+#if INCL_ISW
+ IMPORT_FACTOR
+#endif
+ *x_offset = 0x0L; /* 0 in 16.16 notation */
+ }
+ }
+
+x_offset_pix = (fix15)(((*x_offset >> 16) * sp_globals.tcb0.xppo)
+ / (1<<sp_globals.mpshift));
+
+if ((x_offset_pix >0) && (x_offset_pix < sp_globals.onepix))
+ x_offset_pix = sp_globals.onepix;
+
+/* look for the first non-negative oru value, scale and add the offset */
+/* to the corresponding pixel value - note that the pixel value */
+/* is set in read_oru_table. */
+
+/* look at all the X edges */
+for (i=0; i < (no_X_ctrl_zones+1); i++)
+ if (sp_plaid.orus[i] >= 0)
+ {
+ sp_plaid.pix[i] = (SQUEEZE_MULT(sp_plaid.pix[i], *x_factor)
+ +sp_globals.pixrnd + x_offset_pix) & sp_globals.pixfix;
+ break;
+ }
+
+return TRUE;
+}
+
+FUNCTION boolean calculate_y_scale(
+GDECL
+fix31 *top_scale, fix31 *bottom_scale,
+fix15 first_Y_zone,
+fix15 no_Y_ctrl_zones)
+/*
+ * Called by sp_setup_pix_table() when squeezing is included
+ * to determine whether Y scaling is necessary. If it is,
+ * two scale factors are computed, one for above the baseline,
+ * and one for below the basline.
+ * This function returns a boolean value TRUE = Y squeezind is necessary,
+ * FALSE = no Y squeezing is necessary.
+ */
+{
+boolean squeeze_top, squeeze_bottom;
+boolean out_on_top, out_on_bottom;
+fix15 bbox_top, bbox_bottom;
+fix15 bbox_height;
+fix15 i;
+
+/* set up some flags and common calculations */
+squeeze_top = (sp_globals.pspecs->flags & SQUEEZE_TOP)? TRUE:FALSE;
+squeeze_bottom = (sp_globals.pspecs->flags & SQUEEZE_BOTTOM)? TRUE:FALSE;
+bbox_top = sp_globals.bbox_ymax_orus;
+bbox_bottom = sp_globals.bbox_ymin_orus;
+bbox_height = bbox_top - bbox_bottom;
+
+if (bbox_top > EM_TOP)
+ out_on_top = TRUE;
+else
+ out_on_top = FALSE;
+
+if (bbox_bottom < EM_BOT)
+ out_on_bottom = TRUE;
+else
+ out_on_bottom = FALSE;
+
+/*
+ * don't need Y squeezing if:
+ * - Y squeezing not enabled
+ * - bbox doesn't violate on top or bottom
+ * - top squeezing only is enabled and char isn't out on top
+ * - bottom squeezing only is enabled and char isn't out on bottom
+ */
+if ((!squeeze_top && !squeeze_bottom) ||
+ (!out_on_top && !out_on_bottom) ||
+ (squeeze_top && !squeeze_bottom && !out_on_top) ||
+ (squeeze_bottom && !squeeze_top && !out_on_bottom))
+ return FALSE;
+
+if (squeeze_top && (bbox_top > EM_TOP))
+ *top_scale = ((fix31)EM_TOP << 16)/(fix31)(bbox_top);
+else
+ *top_scale = 0x10000L; /* 1 in 16.16 fixed point */
+
+if (squeeze_bottom && (bbox_bottom < EM_BOT))
+ *bottom_scale = ((fix31)-(EM_BOT) << 16)/(fix31)-bbox_bottom;
+else
+ *bottom_scale = 0x10000L;
+
+if (sp_globals.squeezing_compound)
+ {
+ for (i=first_Y_zone; i < (first_Y_zone + no_Y_ctrl_zones + 1); i++)
+ {
+ if (sp_plaid.orus[i] >= 0)
+ sp_plaid.pix[i] = (SQUEEZE_MULT(sp_plaid.pix[i], *top_scale)
+ +sp_globals.pixrnd) & sp_globals.pixfix;
+ else
+ sp_plaid.pix[i] = (SQUEEZE_MULT(sp_plaid.pix[i], *bottom_scale)
+ +sp_globals.pixrnd) & sp_globals.pixfix;
+ }
+ }
+return TRUE;
+}
+#endif
+
+FUNCTION static ufix8 FONTFAR *sp_setup_pix_table(
+GDECL
+ufix8 FONTFAR *pointer, /* Pointer to first byte in control zone table */
+boolean short_form, /* TRUE if 1 byte from/to specification */
+fix15 no_X_ctrl_zones, /* Number of X control zones */
+fix15 no_Y_ctrl_zones) /* Number of Y control zones */
+/*
+ * Called by plaid_tcb() to read the control zone table from the
+ * character data in the font.
+ * Sets up a table of pixel values for all controlled coordinates.
+ * Updates the pointer to the byte following the control zone
+ * data.
+ */
+{
+fix15 i, j, n;
+fix31 ppo;
+#if INCL_SQUEEZING || INCL_ISW
+fix31 xppo0; /* top level pixels per oru */
+fix31 yppo0; /* top level pixels per oru */
+#endif
+ufix8 edge_org;
+ufix8 edge;
+ufix8 start_edge;
+ufix8 end_edge;
+ufix16 constr_org;
+fix15 constr_nr;
+fix15 zone_pix;
+fix31 whole_zone; /* non-transformed value of the first X zone */
+ufix16 tmpufix16; /* in extended mode, macro uses secnd term */
+#if INCL_SQUEEZING
+fix31 x_scale;
+fix31 y_top_scale, y_bottom_scale;
+fix31 x_offset;
+boolean squeezed_y;
+fix15 setwidth_pix, em_top_pix, em_bot_pix;
+#endif
+
+#if INCL_ISW
+boolean imported_width;
+fix31 isw_scale;
+fix15 isw_setwidth_pix;
+#endif
+
+#if INCL_ISW || INCL_SQUEEZING
+boolean squeezed_x;
+#endif
+
+#if INCL_PLAID_OUT /* Plaid data monitoring included? */
+begin_ctrl_zones(no_X_ctrl_zones, no_Y_ctrl_zones);
+#endif
+
+
+edge_org = 0;
+constr_org = 0;
+sp_globals.rnd_xmin = 0; /* initialize the error for chars with no zone */
+n = no_X_ctrl_zones;
+ppo = sp_globals.tcb.xppo;
+#if INCL_SQUEEZING || INCL_ISW
+xppo0 = sp_globals.tcb0.xppo;
+yppo0 = sp_globals.tcb0.yppo;
+squeezed_x = FALSE;
+#endif
+
+#if INCL_SQUEEZING
+squeezed_x = calculate_x_scale (&x_scale, &x_offset, no_X_ctrl_zones);
+squeezed_y = calculate_y_scale(&y_top_scale,&y_bottom_scale,(n+1),
+ no_Y_ctrl_zones);
+#if INCL_ISW
+if (sp_globals.import_setwidth_act == TRUE)
+setwidth_pix = ((fix15)(((fix31)sp_globals.imported_width * xppo0) >>
+ sp_globals.mpshift) + sp_globals.pixrnd) & sp_globals.pixfix;
+
+else
+#endif
+setwidth_pix = ((fix15)(((fix31)sp_globals.setwidth_orus * xppo0) >>
+ sp_globals.mpshift) + sp_globals.pixrnd) & sp_globals.pixfix;
+/* check for overflow */
+if (setwidth_pix < 0)
+ setwidth_pix = 0x7fff; /* set to maximum */
+em_bot_pix = ((fix15)(((fix31)EM_BOT * yppo0) >>
+ sp_globals.mpshift) + sp_globals.pixrnd) & sp_globals.pixfix;
+em_top_pix = ((fix15)(((fix31)EM_TOP * yppo0) >>
+ sp_globals.mpshift) + sp_globals.pixrnd) & sp_globals.pixfix;
+#endif
+
+#if INCL_ISW
+/* convert to pixels */
+isw_setwidth_pix = ((fix15)(((fix31)sp_globals.imported_width * xppo0) >>
+ sp_globals.mpshift) + sp_globals.pixrnd) & sp_globals.pixfix;
+/* check for overflow */
+if (isw_setwidth_pix < 0)
+ isw_setwidth_pix = 0x7fff; /* set to maximum */
+if (!squeezed_x && ((imported_width = sp_globals.import_setwidth_act) == TRUE))
+ {
+ isw_scale = compute_isw_scale();
+
+ /* look for the first non-negative oru value, scale and add the offset */
+ /* to the corresponding pixel value - note that the pixel value */
+ /* is set in read_oru_table. */
+
+ /* look at all the X edges */
+ for (i=0; i < (no_X_ctrl_zones+1); i++)
+ if (sp_plaid.orus[i] >= 0)
+ {
+ sp_plaid.pix[i] = (SQUEEZE_MULT(sp_plaid.pix[i], isw_scale)
+ +sp_globals.pixrnd) & sp_globals.pixfix;
+ break;
+ }
+
+ }
+#endif
+
+for (i = 0; ; i++) /* For X and Y control zones... */
+ {
+ for (j = 0; j < n; j++) /* For each zone in X or Y... */
+ {
+ if (short_form) /* 1 byte from/to specification? */
+ {
+ edge = NEXT_BYTE(pointer); /* Read packed from/to spec */
+ start_edge = edge_org + (edge & 0x0f); /* Extract start edge */
+ end_edge = edge_org + (edge >> 4); /* Extract end edge */
+ }
+ else /* 2 byte from/to specification? */
+ {
+ start_edge = edge_org + NEXT_BYTE(pointer); /* Read start edge */
+ end_edge = edge_org + NEXT_BYTE(pointer); /* read end edge */
+ }
+ constr_nr = constr_org +
+ NEXT_BYTES(pointer, tmpufix16); /* Read constraint number */
+#if INCL_SQUEEZING
+ if (i == 0 && squeezed_x)
+ calculate_x_pix(start_edge, end_edge, constr_nr,
+ x_scale, x_offset, ppo, setwidth_pix);
+ else if (i == 1 && squeezed_y)
+ calculate_y_pix(start_edge, end_edge,constr_nr,
+ y_top_scale, y_bottom_scale, ppo, em_top_pix, em_bot_pix);
+ else
+ {
+#endif
+#if INCL_ISW
+ if (i==0 && imported_width)
+ calculate_x_pix(start_edge, end_edge, constr_nr,
+ isw_scale, 0, ppo, isw_setwidth_pix);
+ else
+ {
+#endif
+ if (!sp_globals.c_act[constr_nr]) /* Constraint inactive? */
+ {
+ zone_pix = ((fix15)((((fix31)sp_plaid.orus[end_edge] -
+ (fix31)sp_plaid.orus[start_edge]) * ppo) /
+ (1<<sp_globals.mpshift)) + sp_globals.pixrnd) &
+ sp_globals.pixfix;
+ if ((ABS(zone_pix)) >= sp_globals.c_pix[constr_nr])
+ goto L1;
+ }
+ zone_pix = sp_globals.c_pix[constr_nr]; /* Use zone size from constr table */
+ if (start_edge > end_edge) /* sp_plaid.orus[start_edge] > sp_plaid.orus[end_edge]? */
+ {
+ zone_pix = -zone_pix; /* Use negatve zone size */
+ }
+ L1:
+ /* inter-character spacing fix */
+ if ((j == 0) && (i == 0)) /* if this is the 1st X zone, save rounding error */
+ { /* get the non-xformed - xformed zone, in right direction */
+ whole_zone = (((fix31)sp_plaid.orus[end_edge] -
+ (fix31)sp_plaid.orus[start_edge]) *
+ ppo) / (1<<sp_globals.mpshift);
+ sp_globals.rnd_xmin = whole_zone - zone_pix;
+ }
+ sp_plaid.pix[end_edge] = sp_plaid.pix[start_edge] + zone_pix; /* Insert end pixels */
+#if INCL_SQUEEZING
+ if (i == 0) /* in the x direction */
+ { /* brute force squeeze */
+ if ((sp_globals.pspecs->flags & SQUEEZE_LEFT) &&
+ (sp_plaid.pix[end_edge] < 0))
+ sp_plaid.pix[end_edge] = 0;
+ if ((sp_globals.pspecs->flags & SQUEEZE_RIGHT) &&
+ (sp_plaid.pix[end_edge] > setwidth_pix))
+ sp_plaid.pix[end_edge] = setwidth_pix;
+ }
+ if (i == 1) /* in the y direction */
+ { /* brute force squeeze */
+ if ((sp_globals.pspecs->flags & SQUEEZE_TOP) &&
+ (sp_plaid.pix[end_edge] > em_top_pix))
+ sp_plaid.pix[end_edge] = em_top_pix;
+ if ((sp_globals.pspecs->flags & SQUEEZE_BOTTOM) &&
+ (sp_plaid.pix[end_edge] < em_bot_pix))
+ sp_plaid.pix[end_edge] = em_bot_pix;
+ }
+#endif
+#if INCL_SQUEEZING
+ }
+#endif
+#if INCL_ISW
+ }
+#endif
+#if INCL_PLAID_OUT /* Plaid data monitoring included? */
+ record_ctrl_zone(
+ (fix31)sp_plaid.pix[start_edge] << (16 - sp_globals.pixshift),
+ (fix31)sp_plaid.pix[end_edge] << (16 - sp_globals.pixshift),
+ (fix15)(constr_nr - constr_org));
+#endif
+ }
+ if (i) /* Y pixels done? */
+ break;
+ edge_org = sp_globals.Y_edge_org; /* Prepare to process Y ctrl zones */
+ constr_org = sp_globals.Y_constr_org;
+ n = no_Y_ctrl_zones;
+ ppo = sp_globals.tcb.yppo;
+ }
+
+#if DEBUG
+printf("\nX PIX TABLE\n");
+n = no_X_ctrl_zones + 1;
+for (i = 0; i < n; i++)
+ printf("%2d %6.1f\n", i, (real)sp_plaid.pix[i] / (real)sp_globals.onepix);
+printf("\nY PIX TABLE\n");
+n = no_Y_ctrl_zones + 1;
+for (i = 0; i < n; i++)
+ {
+ j = i + no_X_ctrl_zones + 1;
+ printf("%2d %6.1f\n", i, (real)sp_plaid.pix[j] / (real)sp_globals.onepix);
+ }
+#endif
+
+return pointer;
+}
+
+
+FUNCTION static ufix8 FONTFAR *sp_setup_int_table(
+GDECL
+ufix8 FONTFAR *pointer, /* Pointer to first byte in interpolation zone table */
+fix15 no_X_int_zones, /* Number of X interpolation zones */
+fix15 no_Y_int_zones) /* Number of X interpolation zones */
+/*
+ * Called by plaid_tcb() to read the interpolation zone table from the
+ * character data in the font.
+ * Sets up a table of interpolation coefficients with one entry for
+ * every X or Y interpolation zone.
+ * Updates the pointer to the byte following the interpolation zone
+ * data.
+ */
+{
+fix15 i, j, k, l, n;
+ufix8 format;
+ufix8 format_copy;
+ufix8 tmpufix8;
+fix15 start_orus = 0;
+ufix8 edge_org;
+ufix8 edge;
+ufix16 adj_factor;
+fix15 adj_orus;
+fix15 end_orus = 0;
+fix31 zone_orus;
+fix15 start_pix = 0;
+fix15 end_pix = 0;
+
+
+#if INCL_PLAID_OUT /* Plaid data monitoring included? */
+begin_int_zones(no_X_int_zones, no_Y_int_zones);
+#endif
+
+i = 0;
+edge_org = 0;
+n = no_X_int_zones;
+for (j = 0; ; j++)
+ {
+ for (k = 0; k < n; k++)
+ {
+ format = NEXT_BYTE(pointer);
+ if (format & BIT7) /* Short start/end point spec? */
+ {
+ tmpufix8 = NEXT_BYTE(pointer);
+ edge = edge_org + (tmpufix8 & 0xf);
+ start_orus = sp_plaid.orus[edge];
+ start_pix = sp_plaid.pix[edge];
+ edge = edge_org + (tmpufix8 >> 4);
+ end_orus = sp_plaid.orus[edge];
+ end_pix = sp_plaid.pix[edge];
+ }
+ else /* Standard start and end point spec? */
+ {
+ format_copy = format;
+ for (l = 0; ; l++) /* Loop for start and end point */
+ {
+ switch (format_copy & 0x7) /* Decode start/end point format */
+ {
+
+ case 0: /* Index to control edge */
+ edge = edge_org + NEXT_BYTE(pointer);
+ end_orus = sp_plaid.orus[edge];
+ end_pix = sp_plaid.pix[edge];
+ break;
+
+ case 1: /* 1 byte fractional distance to next edge */
+ adj_factor = 0xffff & NEXT_BYTE(pointer) << 8;
+ goto L1;
+
+
+ case 2: /* 2 byte fractional distance to next edge */
+ adj_factor = 0xffff & NEXT_WORD(pointer);
+ L1: edge = edge_org + NEXT_BYTE(pointer);
+ end_orus = sp_plaid.orus[edge] +
+ ((((fix31)sp_plaid.orus[edge + 1] - (fix31)sp_plaid.orus[edge]) *
+ (ufix32)adj_factor + (fix31)32768) >> 16);
+ end_pix = sp_plaid.pix[edge] +
+ ((((fix31)sp_plaid.pix[edge + 1] - (fix31)sp_plaid.pix[edge]) *
+ (ufix32)adj_factor + (fix31)32768) >> 16);
+ break;
+
+ case 3: /* 1 byte delta orus before first edge */
+ adj_orus = -(fix15)NEXT_BYTE(pointer);
+ goto L2;
+
+ case 4: /* 2 byte delta orus before first edge */
+ adj_orus = -NEXT_WORD(pointer);
+ L2: edge = edge_org;
+ goto L4;
+
+ case 5: /* 1 byte delta orus after last edge */
+ adj_orus = (fix15)NEXT_BYTE(pointer);
+ goto L3;
+
+ case 6: /* 2 byte delta orus after last edge */
+ adj_orus = NEXT_WORD(pointer);
+ L3: edge = j? sp_globals.Y_edge_org + sp_globals.no_Y_orus - 1: sp_globals.no_X_orus - 1;
+ L4: end_orus = sp_plaid.orus[edge] + adj_orus;
+ end_pix = sp_plaid.pix[edge] +
+ (((fix31)adj_orus * (fix31)(j? sp_globals.tcb.yppo: sp_globals.tcb.xppo) +
+ sp_globals.mprnd) / (1<<sp_globals.mpshift));
+ break;
+
+ }
+
+ if (l) /* Second time round loop? */
+ break;
+ format_copy >>= 3; /* Adj format to decode end point format */
+ start_orus = end_orus; /* Save start point oru value */
+ start_pix = end_pix; /* Save start point pixel value */
+ }
+ }
+#if INCL_PLAID_OUT /* Plaid data monitoring included? */
+ record_int_zone(
+ (fix31)start_pix << (16 - sp_globals.pixshift),
+ (fix31)end_pix << (16 - sp_globals.pixshift));
+#endif
+ zone_orus = (fix31)end_orus - (fix31)start_orus;
+ sp_plaid.mult[i] = ((((fix31)end_pix - (fix31)start_pix) << sp_globals.mpshift) +
+ (zone_orus / 2)) / zone_orus;
+ sp_plaid.offset[i] =
+ (((((fix31)start_pix + (fix31)end_pix) << sp_globals.mpshift) -
+ ((fix31)sp_plaid.mult[i] * ((fix31)start_orus + (fix31)end_orus))) / 2) +
+ sp_globals.mprnd;
+ i++;
+ }
+ if (j) /* Finished? */
+ break;
+ edge_org = sp_globals.Y_edge_org; /* Prepare to process Y ctrl zones */
+ n = no_Y_int_zones;
+ }
+
+#if DEBUG
+printf("\nX INT TABLE\n");
+n = no_X_int_zones;
+for (i = 0; i < n; i++)
+ {
+ printf("%2d %7.4f %7.4f\n", i,
+ (real)sp_plaid.mult[i] / (real)(1 << sp_globals.multshift),
+ (real)sp_plaid.offset[i] / (real)(1 << sp_globals.multshift));
+ }
+printf("\nY INT TABLE\n");
+n = no_Y_int_zones;
+for (i = 0; i < n; i++)
+ {
+ j = i + no_X_int_zones;
+ printf("%2d %7.4f %7.4f\n", i,
+ (real)sp_plaid.mult[j] / (real)(1 << sp_globals.multshift),
+ (real)sp_plaid.offset[j] / (real)(1 << sp_globals.multshift));
+ }
+#endif
+
+return pointer;
+}
+#if INCL_ISW
+FUNCTION fix31 compute_isw_scale()
+GDECL
+{
+fix31 isw_scale;
+
+if (sp_globals.setwidth_orus == 0)
+ isw_scale = 0x00010000;
+else
+ isw_scale = ((fix31)sp_globals.imported_width << 16)/
+ (fix31)sp_globals.setwidth_orus;
+return isw_scale;
+}
+#endif
diff --git a/libXfont/src/Speedo/spdo_prv.h b/libXfont/src/Speedo/spdo_prv.h
new file mode 100644
index 000000000..2b3882c22
--- /dev/null
+++ b/libXfont/src/Speedo/spdo_prv.h
@@ -0,0 +1,262 @@
+/* $Xorg: spdo_prv.h,v 1.3 2000/08/17 19:46:27 cpqbld Exp $ */
+
+/*
+
+Copyright 1989-1991, Bitstream Inc., Cambridge, MA.
+You are hereby granted permission under all Bitstream propriety rights to
+use, copy, modify, sublicense, sell, and redistribute the Bitstream Speedo
+software and the Bitstream Charter outline font for any purpose and without
+restrictions; provided, that this notice is left intact on all copies of such
+software or font and that Bitstream's trademark is acknowledged as shown below
+on all unmodified copies of such font.
+
+BITSTREAM CHARTER is a registered trademark of Bitstream Inc.
+
+
+BITSTREAM INC. DISCLAIMS ANY AND ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING
+WITHOUT LIMITATION THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+PARTICULAR PURPOSE. BITSTREAM SHALL NOT BE LIABLE FOR ANY DIRECT OR INDIRECT
+DAMAGES, INCLUDING BUT NOT LIMITED TO LOST PROFITS, LOST DATA, OR ANY OTHER
+INCIDENTAL OR CONSEQUENTIAL DAMAGES, ARISING OUT OF OR IN ANY WAY CONNECTED
+WITH THE SPEEDO SOFTWARE OR THE BITSTREAM CHARTER OUTLINE FONT.
+
+*/
+/* $XFree86: xc/lib/font/Speedo/spdo_prv.h,v 1.4 1999/03/14 03:21:17 dawes Exp $ */
+
+
+
+/***************************** S P D O _ P R V . H *******************************/
+
+#include "speedo.h" /* include public definitions */
+
+/***** CONFIGURATION DEFINITIONS *****/
+
+
+/***** PRIVATE FONT HEADER OFFSET CONSTANTS *****/
+#define FH_ORUMX 0 /* U Max ORU value 2 bytes */
+#define FH_PIXMX 2 /* U Max Pixel value 2 bytes */
+#define FH_CUSNR 4 /* U Customer Number 2 bytes */
+#define FH_OFFCD 6 /* E Offset to Char Directory 3 bytes */
+#define FH_OFCNS 9 /* E Offset to Constraint Data 3 bytes */
+#define FH_OFFTK 12 /* E Offset to Track Kerning 3 bytes */
+#define FH_OFFPK 15 /* E Offset to Pair Kerning 3 bytes */
+#define FH_OCHRD 18 /* E Offset to Character Data 3 bytes */
+#define FH_NBYTE 21 /* E Number of Bytes in File 3 bytes */
+
+
+/***** MODE FLAGS CONSTANTS *****/
+#define CURVES_OUT 0X0008 /* Output module accepts curves */
+#define BOGUS_MODE 0X0010 /* Linear scaling mode */
+#define CONSTR_OFF 0X0020 /* Inhibit constraint table */
+#define IMPORT_WIDTHS 0X0040 /* Imported width mode */
+#define SQUEEZE_LEFT 0X0100 /* Squeeze left mode */
+#define SQUEEZE_RIGHT 0X0200 /* Squeeze right mode */
+#define SQUEEZE_TOP 0X0400 /* Squeeze top mode */
+#define SQUEEZE_BOTTOM 0X0800 /* Squeeze bottom mode */
+#define CLIP_LEFT 0X1000 /* Clip left mode */
+#define CLIP_RIGHT 0X2000 /* Clip right mode */
+#define CLIP_TOP 0X4000 /* Clip top mode */
+#define CLIP_BOTTOM 0X8000 /* Clip bottom mode */
+
+
+/***** MACRO DEFINITIONS *****/
+
+#define SQUEEZE_MULT(A,B) (((fix31)A * (fix31)B) / (1 << 16))
+
+#define NEXT_BYTE(A) (*(A)++)
+
+#define NEXT_WORD(A) \
+ ((fix15)(sp_globals.key32 ^ ((A) += 2, \
+ ((fix15)((A)[-1]) << 8) | (fix15)((A)[-2]) | \
+ ((A)[-1] & 0x80? ~0xFFFF : 0))))
+
+#if INCL_EXT /* Extended fonts supported? */
+
+#define NEXT_BYTES(A, B) \
+ (((B = (ufix16)(*(A)++) ^ sp_globals.key7) >= 248)? \
+ ((ufix16)(B & 0x07) << 8) + ((*(A)++) ^ sp_globals.key8) + 248: \
+ B)
+
+#else /* Compact fonts only supported? */
+
+#define NEXT_BYTES(A, B) ((*(A)++) ^ sp_globals.key7)
+
+#endif
+
+
+#define NEXT_BYTE_U(A) (*(A)++)
+
+#define NEXT_WORD_U(A, B) \
+ (fix15)(B = (*(A)++) << 8, (fix15)(*(A)++) + B)
+
+#define NEXT_CHNDX(A, B) \
+ ((B)? (ufix16)NEXT_WORD(A): (ufix16)NEXT_BYTE(A))
+
+/* Multiply (fix15)X by (fix15)Y to produce (fix31)product */
+#define MULT16(X, Y) \
+ ((fix31)X * (fix31)Y)
+
+/* Multiply (fix15)X by (fix15)MULT, add (fix31)OFFSET,
+ * shift right SHIFT bits to produce (fix15)result */
+#define TRANS(X, MULT, OFFSET, SHIFT) \
+ ((fix15)((((fix31)X * (fix31)MULT) + OFFSET) / (1 << SHIFT)))
+
+/******************************************************************************
+ *
+ * the following block of definitions redefines every function
+ * reference to be prefixed with an "sp_". In addition, if this
+ * is a reentrant version, the parameter sp_globals will be added
+ * as the first parameter.
+ *
+ *****************************************************************************/
+
+#define GDECL
+
+#define get_char_id(char_index) sp_get_char_id(char_index)
+#define get_char_width(char_index) sp_get_char_width(char_index)
+#define get_track_kern(track,point_size) sp_get_track_kern(track,point_size)
+#define get_pair_kern(char_index1,char_index2) sp_get_pair_kern(char_index1,char_index2)
+#define get_char_bbox(char_index,bbox) sp_get_char_bbox(char_index,bbox)
+#define make_char(char_index) sp_make_char(char_index)
+#if INCL_ISW
+#define compute_isw_scale() sp_compute_isw_scale()
+#define do_make_char(char_index) sp_do_make_char(char_index)
+#define make_char_isw(char_index,imported_width) sp_make_char_isw(char_index,imported_width)
+#define reset_xmax(xmax) sp_reset_xmax(xmax)
+#endif
+#if INCL_ISW || INCL_SQUEEZING
+#define preview_bounding_box(pointer,format) sp_preview_bounding_box(pointer,format)
+#endif
+#define make_simp_char(pointer,format) sp_make_simp_char(pointer,format)
+#define make_comp_char(pointer) sp_make_comp_char(pointer)
+#define get_char_org(char_index,top_level) sp_get_char_org(char_index,top_level)
+#define get_posn_arg(ppointer,format) sp_get_posn_arg(ppointer,format)
+#define get_scale_arg(ppointer,format) sp_get_scale_arg(ppointer,format)
+#define read_bbox(ppointer,pPmin,pPmax,set_flag) sp_read_bbox(ppointer,pPmin,pPmax,set_flag)
+#define proc_outl_data(pointer) sp_proc_outl_data(pointer)
+#define split_curve(P1,P2,P3,depth) sp_split_curve(P1,P2,P3,depth)
+#define get_args(ppointer,format,pP) sp_get_args(ppointer,format,pP)
+
+#define init_black(specsarg) sp_init_black(specsarg)
+#define begin_char_black(Psw,Pmin,Pmax) sp_begin_char_black(Psw,Pmin,Pmax)
+#define begin_contour_black(P1,outside) sp_begin_contour_black(P1,outside)
+#define line_black(P1) sp_line_black(P1)
+#define end_char_black() sp_end_char_black()
+#define add_intercept_black(y,x) sp_add_intercept_black(y,x)
+#define proc_intercepts_black() sp_proc_intercepts_black()
+
+#define init_screen(specsarg) sp_init_screen(specsarg)
+#define begin_char_screen(Psw,Pmin,Pmax) sp_begin_char_screen(Psw,Pmin,Pmax)
+#define begin_contour_screen(P1,outside) sp_begin_contour_screen(P1,outside)
+#define curve_screen(P1,P2,P3,depth) sp_curve_screen(P1,P2,P3,depth)
+#define scan_curve_screen(X0,Y0,X1,Y1,X2,Y2,X3,Y3) sp_scan_curve_screen(X0,Y0,X1,Y1,X2,Y2,X3,Y3)
+#define vert_line_screen(x,y1,y2) sp_vert_line_screen(x,y1,y2)
+#define line_screen(P1) sp_line_screen(P1)
+#define end_contour_screen() sp_end_contour_screen()
+#define end_char_screen() sp_end_char_screen()
+#define add_intercept_screen(y,x) sp_add_intercept_screen(y,x)
+#define proc_intercepts_screen() sp_proc_intercepts_screen()
+
+#define init_outline(specsarg) sp_init_outline(specsarg)
+#define begin_char_outline(Psw,Pmin,Pmax) sp_begin_char_outline(Psw,Pmin,Pmax)
+#define begin_sub_char_outline(Psw,Pmin,Pmax) sp_begin_sub_char_outline(Psw,Pmin,Pmax)
+#define begin_contour_outline(P1,outside) sp_begin_contour_outline(P1,outside)
+#define curve_outline(P1,P2,P3,depth) sp_curve_outline(P1,P2,P3,depth)
+#define line_outline(P1) sp_line_outline(P1)
+#define end_contour_outline() sp_end_contour_outline()
+#define end_sub_char_outline() sp_end_sub_char_outline()
+#define end_char_outline() sp_end_char_outline()
+
+#define init_2d(specsarg) sp_init_2d(specsarg)
+#define begin_char_2d(Psw, Pmin, Pmax) sp_begin_char_2d(Psw, Pmin, Pmax)
+#define begin_contour_2d(P1, outside) sp_begin_contour_2d(P1, outside)
+#define line_2d(P1) sp_line_2d(P1)
+#define end_char_2d() sp_end_char_2d()
+#define add_intercept_2d(y, x) sp_add_intercept_2d(y, x)
+#define proc_intercepts_2d() sp_proc_intercepts_2d()
+#define draw_vector_to_2d(x0, y0, x1, y1, band) sp_draw_vector_to_2d(x0, y0, x1, y1, band)
+
+#define init_char_out(Psw,Pmin,Pmax) sp_init_char_out(Psw,Pmin,Pmax)
+#define begin_sub_char_out(Psw,Pmin,Pmax) sp_begin_sub_char_out(Psw,Pmin,Pmax)
+#define curve_out(P1,P2,P3,depth) sp_curve_out(P1,P2,P3,depth)
+#define end_contour_out() sp_end_contour_out()
+#define end_sub_char_out() sp_end_sub_char_out()
+#define init_intercepts_out() sp_init_intercepts_out()
+#define restart_intercepts_out sp_restart_intercepts_out
+#define set_first_band_out(Pmin,Pmax) sp_set_first_band_out(Pmin,Pmax)
+#define reduce_band_size_out() sp_reduce_band_size_out()
+#define next_band_out() sp_next_band_out()
+
+#define init_userout(specsarg) sp_init_userout(specsarg)
+
+#define reset() sp_reset()
+#define set_key(key) sp_set_key(key)
+#define get_cust_no(font_buff) sp_get_cust_no(font_buff)
+#define set_specs(specsarg) sp_set_specs(specsarg)
+#define setup_consts(xmin,xmax,ymin,ymax) sp_setup_consts(xmin,xmax,ymin,ymax)
+#define setup_tcb(ptcb) sp_setup_tcb(ptcb)
+#define setup_mult(input_mult) sp_setup_mult(input_mult)
+#define setup_offset(input_offset) sp_setup_offset(input_offset)
+#define type_tcb(ptcb) sp_type_tcb(ptcb)
+#define read_long(pointer) sp_read_long(pointer)
+#define read_word_u(pointer) sp_read_word_u(pointer)
+#define init_tcb() sp_init_tcb()
+#define scale_tcb(ptcb,x_pos,y_pos,x_scale,y_scale) sp_scale_tcb(ptcb,x_pos,y_pos,x_scale,y_scale)
+#define plaid_tcb(ppointer,format) sp_plaid_tcb(ppointer,format)
+#define skip_orus(ppointer,short_form,no_ctrl_zones) sp_skip_orus(ppointer,short_form,no_ctrl_zones)
+#define skip_interpolation_table(ppointer,format) sp_skip_interpolation_table(ppointer,format)
+#define skip_control_zone(ppointer,format) sp_skip_control_zone(ppointer,format)
+#define constr_update() sp_constr_update()
+#define read_oru_table(ppointer) sp_read_oru_table(ppointer)
+#define calculate_x_pix(start_edge,end_edge,constr_nr,x_scale,x_offset,ppo,setwidth_pix) sp_calculate_x_pix(start_edge,end_edge,constr_nr,x_scale,x_offset,ppo,setwidth_pix)
+#define calculate_y_pix(start_edge,end_edge,constr_nr,top_scale,bottom_scale,ppo,emtop_pix,embot_pix) sp_calculate_y_pix(start_edge,end_edge,constr_nr,top_scale,bottom_scale,ppo,emtop_pix,embot_pix)
+#define calculate_x_scale(x_factor,x_offset,no_x_ctrl_zones) sp_calculate_x_scale(x_factor,x_offset,no_x_ctrl_zones)
+#define calculate_y_scale(top_scale,bottom_scale,first_y_zone,no_Y_ctrl_zones) sp_calculate_y_scale(top_scale,bottom_scale,first_y_zone,no_Y_ctrl_zones)
+#define setup_pix_table(ppointer,short_form,no_X_ctrl_zones,no_Y_ctrl_zones) sp_setup_pix_table(ppointer,short_form,no_X_ctrl_zones,no_Y_ctrl_zones)
+#define setup_int_table(ppointer,no_X_int_zones, no_Y_int_zones) sp_setup_int_table(ppointer,no_X_int_zones, no_Y_int_zones)
+
+#define fn_init_out(specsarg) (*sp_globals.init_out)(specsarg)
+#define fn_begin_char(Psw,Pmin,Pmax) (*sp_globals.begin_char)(Psw,Pmin,Pmax)
+#define fn_begin_sub_char(Psw,Pmin,Pmax) (*sp_globals.begin_sub_char)(Psw,Pmin,Pmax)
+#define fn_end_sub_char() (*sp_globals.end_sub_char)()
+#define fn_end_char() (*sp_globals.end_char)()
+#define fn_line(P1) (*sp_globals.line)(P1)
+#define fn_end_contour() (*sp_globals.end_contour)()
+#define fn_begin_contour(P0,fmt) (*sp_globals.begin_contour)(P0,fmt)
+#define fn_curve(P1,P2,P3,depth) (*sp_globals.curve)(P1,P2,P3,depth)
+
+#define load_char_data(offset, no_bytes, buff_off) sp_load_char_data(offset, no_bytes, buff_off)
+#define report_error(n) sp_report_error(n)
+
+#if INCL_MULTIDEV
+
+#define set_bitmap_device(bfuncs,size) sp_set_bitmap_device(bfuncs,size)
+#define set_outline_device(ofuncs,size) sp_set_outline_device(ofuncs,size)
+
+#define open_bitmap(x_set_width, y_set_width, xmin, xmax, ymin, ymax) (*sp_globals.bitmap_device.p_open_bitmap)(x_set_width, y_set_width, xmin, xmax, ymin, ymax)
+#define set_bitmap_bits(y, xbit1, xbit2) (*sp_globals.bitmap_device.p_set_bits)(y, xbit1, xbit2)
+#define close_bitmap() (*sp_globals.bitmap_device.p_close_bitmap)()
+
+#define open_outline(x_set_width, y_set_width, xmin, xmax, ymin, ymax) (*sp_globals.outline_device.p_open_outline)(x_set_width, y_set_width, xmin, xmax, ymin, ymax)
+#define start_new_char() (*sp_globals.outline_device.p_start_char)()
+#define start_contour(x,y,outside) (*sp_globals.outline_device.p_start_contour)(x,y,outside)
+#define curve_to(x1,y1,x2,y2,x3,y3) (*sp_globals.outline_device.p_curve)(x1,y1,x2,y2,x3,y3)
+#define line_to(x,y) (*sp_globals.outline_device.p_line)(x,y)
+#define close_contour() (*sp_globals.outline_device.p_close_contour)()
+#define close_outline() (*sp_globals.outline_device.p_close_outline)()
+
+#else
+
+#define open_bitmap(x_set_width, y_set_width, xmin, xmax, ymin, ymax) sp_open_bitmap(x_set_width, y_set_width, xmin, xmax, ymin, ymax)
+#define set_bitmap_bits(y, xbit1, xbit2) sp_set_bitmap_bits(y, xbit1, xbit2)
+#define close_bitmap() sp_close_bitmap()
+
+#define open_outline(x_set_width, y_set_width, xmin, xmax, ymin, ymax) sp_open_outline(x_set_width, y_set_width, xmin, xmax, ymin, ymax)
+#define start_new_char() sp_start_new_char()
+#define start_contour(x,y,outside) sp_start_contour(x,y,outside)
+#define curve_to(x1,y1,x2,y2,x3,y3) sp_curve_to(x1,y1,x2,y2,x3,y3)
+#define line_to(x,y) sp_line_to(x,y)
+#define close_contour() sp_close_contour()
+#define close_outline() sp_close_outline()
+
+#endif
diff --git a/libXfont/src/Speedo/speedo.h b/libXfont/src/Speedo/speedo.h
new file mode 100644
index 000000000..a5ba3a06a
--- /dev/null
+++ b/libXfont/src/Speedo/speedo.h
@@ -0,0 +1,874 @@
+/* $Xorg: speedo.h,v 1.3 2000/08/17 19:46:27 cpqbld Exp $ */
+
+/*
+
+Copyright 1989-1991, Bitstream Inc., Cambridge, MA.
+You are hereby granted permission under all Bitstream propriety rights to
+use, copy, modify, sublicense, sell, and redistribute the Bitstream Speedo
+software and the Bitstream Charter outline font for any purpose and without
+restrictions; provided, that this notice is left intact on all copies of such
+software or font and that Bitstream's trademark is acknowledged as shown below
+on all unmodified copies of such font.
+
+BITSTREAM CHARTER is a registered trademark of Bitstream Inc.
+
+
+BITSTREAM INC. DISCLAIMS ANY AND ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING
+WITHOUT LIMITATION THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+PARTICULAR PURPOSE. BITSTREAM SHALL NOT BE LIABLE FOR ANY DIRECT OR INDIRECT
+DAMAGES, INCLUDING BUT NOT LIMITED TO LOST PROFITS, LOST DATA, OR ANY OTHER
+INCIDENTAL OR CONSEQUENTIAL DAMAGES, ARISING OUT OF OR IN ANY WAY CONNECTED
+WITH THE SPEEDO SOFTWARE OR THE BITSTREAM CHARTER OUTLINE FONT.
+
+*/
+/* $XFree86: xc/lib/font/Speedo/speedo.h,v 3.5 2001/01/17 19:43:18 dawes Exp $ */
+
+#ifndef _SPEEDO_H_
+#define _SPEEDO_H_
+
+#include <X11/Xmd.h>
+
+/***************************** S P E E D O . H *******************************
+ ****************************************************************************/
+
+/***** USER OPTIONS OVERRIDE DEFAULTS ******/
+#include "useropt.h"
+
+/***** CONFIGURATION DEFINITIONS *****/
+
+#ifndef INCL_CLIPPING
+#define INCL_CLIPPING 0 /* 0 indicates CLIPPING code is not compiled in*/
+#endif
+
+#ifndef INCL_SQUEEZING
+#define INCL_SQUEEZING 0 /* 0 indicates SQUEEZE code is not compiled in*/
+#endif
+
+#ifndef INCL_EXT
+#define INCL_EXT 1 /* 1 to include extended font support */
+#endif /* 0 to omit extended font support */
+
+#ifndef INCL_RULES
+#define INCL_RULES 1 /* 1 to include intelligent scaling support */
+#endif /* 0 to omit intelligent scaling support */
+
+#ifndef INCL_BLACK
+#define INCL_BLACK 1 /* 1 to include blackwriter output support */
+#endif /* 0 to omit output mode 0 support */
+
+#ifndef INCL_SCREEN
+#define INCL_SCREEN 0 /* 1 to include screen writeroutput support */
+#endif /* 0 to omit support */
+
+#ifndef INCL_OUTLINE
+#define INCL_OUTLINE 0 /* 1 to include outline output support */
+#endif /* 0 to omit output mode 2 support */
+
+#ifndef INCL_2D
+#define INCL_2D 0 /* 1 to include 2d blackwriter output support */
+#endif /* 0 to omit output mode 3 support */
+
+#ifndef INCL_USEROUT
+#define INCL_USEROUT 0 /* 1 to include user defined output module support */
+#endif /* 0 to omit user defined output module support */
+
+#ifndef INCL_LCD
+#define INCL_LCD 1 /* 1 to include load char data support*/
+#endif /* 0 to omit load char data support */
+#ifndef INCL_ISW
+#define INCL_ISW 0 /* 1 to include imported width support */
+#endif /* 0 to omit imported width support */
+
+#ifndef INCL_METRICS
+#define INCL_METRICS 1 /* 1 to include metrics support */
+#endif /* 0 to omit metrics support */
+
+#ifndef INCL_KEYS
+#define INCL_KEYS 0 /* 1 to include multi key support */
+#endif /* 0 to omit multi key support */
+
+#ifndef INCL_MULTIDEV
+#define INCL_MULTIDEV 0 /* 1 to include multiple output device support */
+#endif /* 0 to omit multi device support */
+
+#ifndef SHORT_LISTS
+#define SHORT_LISTS 1 /* 1 to allocate small intercept lists */
+#endif
+
+#ifndef INCL_PLAID_OUT
+#define INCL_PLAID_OUT 0 /* 1 to include plaid data monitoring */
+#endif /* 0 to omit plaid data monitoring */
+
+#ifndef FONTFAR /* if Intel mixed memory model implementation */
+#define FONTFAR /* pointer type modifier for font buffer */
+#endif
+
+#ifndef STACKFAR /* if Intel mixed memory model implementation */
+#define STACKFAR /* pointer type modifier for font buffer */
+#endif
+
+#ifndef GLOBALFAR
+#define GLOBALFAR
+#endif
+
+#define MODE_BLACK 0
+#define MODE_SCREEN MODE_BLACK + INCL_BLACK
+#define MODE_OUTLINE MODE_SCREEN + INCL_SCREEN
+#define MODE_2D MODE_OUTLINE + INCL_OUTLINE
+
+#ifdef DYNAMIC_ALLOC
+#if DYNAMIC_ALLOC
+#define STATIC_ALLOC 0
+#endif
+#endif
+
+#ifdef REENTRANT_ALLOC
+#if REENTRANT_ALLOC
+#define STATIC_ALLOC 0
+#endif
+#endif
+
+#ifndef STATIC_ALLOC
+#define STATIC_ALLOC 1
+#endif
+
+#ifndef DYNAMIC_ALLOC
+#define DYNAMIC_ALLOC 0
+#endif
+
+#ifndef REENTRANT_ALLOC
+#define REENTRANT_ALLOC 0
+#endif
+
+/***** TYPE DEFINITIONS *****/
+
+#ifndef STDEF
+#ifndef SPD_BMAP
+
+typedef INT8 fix7;
+
+typedef double real;
+
+typedef CARD8 ufix8;
+#ifndef VFONT
+typedef CARD8 boolean;
+#endif
+#endif
+
+typedef INT16 fix15;
+
+typedef CARD16 ufix16;
+
+typedef INT32 fix31;
+
+typedef CARD32 ufix32;
+#endif
+
+/***** GENERAL CONSTANTS *****/
+
+#ifndef FALSE
+#define FALSE 0
+#define TRUE 1
+#endif
+
+#ifndef NULL
+#include <stddef.h>
+#endif
+
+#define FUNCTION
+
+#define BIT0 0x01
+#define BIT1 0x02
+#define BIT2 0x04
+#define BIT3 0x08
+#define BIT4 0x10
+#define BIT5 0x20
+#define BIT6 0x40
+#define BIT7 0x80
+
+#if INCL_EXT /* Extended fonts supported? */
+
+#define MAX_CONSTR 750 /* Max constraints (incl 4 dummies) */
+#define MAX_CTRL_ZONES 256 /* Max number of controlled orus */
+#define MAX_INT_ZONES 256 /* Max number of interpolation zones */
+
+#else /* Compact fonts only supported */
+
+#define MAX_CONSTR 512 /* Max constraints (incl 4 dummies) */
+#define MAX_CTRL_ZONES 64 /* Max number of controlled orus */
+#define MAX_INT_ZONES 64 /* Max number of interpolation zones */
+
+#endif
+
+#define SCALE_SHIFT 12 /* Binary point positiion for scale values */
+#define SCALE_RND 2048 /* Rounding bit for scaling transformation */
+#define ONE_SCALE 4096 /* Unity scale value */
+
+#ifdef INCL_SCREEN /* constants used by Screenwriter module */
+#define LEFT_INT 1 /* left intercept */
+#define END_INT 2 /* last intercept */
+#define FRACTION 0xFC /* fractional portion of intercept type list */
+#endif
+
+#if INCL_SQUEEZING || INCL_CLIPPING /* constants used by SQUEEZEing code */
+#define EM_TOP 764
+#define EM_BOT -236
+#endif
+
+/***** STRUCTURE DEFINITIONS *****/
+#if REENTRANT_ALLOC
+#define PROTO_DECL1 struct speedo_global_data GLOBALFAR *sp_global_ptr
+#define PROTO_DECL2 PROTO_DECL1 ,
+#else
+#define PROTO_DECL1 void
+#define PROTO_DECL2
+#endif
+
+typedef
+struct buff_tag
+ {
+ ufix8 FONTFAR *org; /* Pointer to start of buffer */
+ ufix32 no_bytes; /* Size of buffer in bytes */
+ }
+buff_t; /* Buffer descriptor */
+
+typedef struct constr_tag
+ {
+ ufix8 FONTFAR *org; /* Pointer to first byte in constr data */
+ ufix16 font_id; /* Font id for calculated data */
+ fix15 xppo; /* X pixels per oru for calculated data */
+ fix15 yppo; /* Y pixels per oru for calculated data */
+ boolean font_id_valid; /* TRUE if font id valid */
+ boolean data_valid; /* TRUE if calculated data valid */
+ boolean active; /* TRUE if constraints enabled */
+ }
+constr_t; /* Constraint data state */
+
+typedef struct kern_tag
+ {
+ ufix8 FONTFAR *tkorg; /* First byte of track kerning data */
+ ufix8 FONTFAR *pkorg; /* First byte of pair kerning data */
+ fix15 no_tracks; /* Number of kerning tracks */
+ fix15 no_pairs; /* Number of kerning pairs */
+ }
+kern_t; /* Kerning control block */
+
+typedef struct specs_tag
+ {
+ buff_t STACKFAR *pfont; /* Pointer to font data */
+ fix31 xxmult; /* Coeff of X orus to compute X pix */
+ fix31 xymult; /* Coeff of Y orus to compute X pix */
+ fix31 xoffset; /* Constant to compute X pix */
+ fix31 yxmult; /* Coeff of X orus to compute Y pix */
+ fix31 yymult; /* Coeff of Y orus to compute Y pix */
+ fix31 yoffset; /* Constant to compute Y pix */
+ ufix32 flags; /* Mode flags: */
+ /* Bit 0 - 2: Output module selector: */
+ /* Bit 3: Send curves to output module*/
+ /* Bit 4: Use linear scaling if set */
+ /* Bit 5: Inhibit constraint table */
+ /* Bit 6: Import set width if set */
+ /* Bit 7: not used */
+ /* Bit 8: Squeeze left if set */
+ /* Bit 9: Squeeze right if set */
+ /* Bit 10: Squeeze top if set */
+ /* Bit 11: Squeeze bottom if set */
+ /* Bit 12: Clip left if set */
+ /* Bit 13: Clip right if set */
+ /* Bit 14: Clip top if set */
+ /* Bit 15: Clip bottom if set */
+ /* Bits 16-31 not used */
+ void *out_info; /* information for output module */
+ }
+specs_t; /* Specs structure for fw_set_specs */
+
+typedef struct tcb_tag
+ {
+ fix15 xxmult; /* Linear coeff of Xorus to compute Xpix */
+ fix15 xymult; /* Linear coeff of Yorus to compute Xpix */
+ fix31 xoffset; /* Linear constant to compute Xpix */
+ fix15 yxmult; /* Linear coeff of Xorus to compute Ypix */
+ fix15 yymult; /* Linear coeff of Yorus to compute Ypix */
+ fix31 yoffset; /* Linear constant to compute Ypix */
+ fix15 xppo; /* Pixels per oru in X dimension of char */
+ fix15 yppo; /* Pixels per oru in Y dimension of char */
+ fix15 xpos; /* Origin in X dimension of character */
+ fix15 ypos; /* Origin in Y dimension of character */
+ ufix16 xtype; /* Transformation type for X oru coords */
+ ufix16 ytype; /* Transformation type for Y oru coords */
+ ufix16 xmode; /* Transformation mode for X oru coords */
+ ufix16 ymode; /* Transformation mode for Y oru coords */
+ fix15 mirror; /* Transformation creates mirror image */
+ }
+tcb_t; /* Transformation control block */
+
+typedef struct point_tag
+ {
+ fix15 x; /* X coord of point (shifted pixels) */
+ fix15 y; /* Y coord of point (shifted pixels) */
+ }
+point_t; /* Point in device space */
+
+typedef struct band_tag
+ {
+ fix15 band_max;
+ fix15 band_min;
+ fix15 band_array_offset;
+ fix15 band_floor;
+ fix15 band_ceiling;
+ } band_t;
+
+typedef struct bbox_tag
+ {
+ fix31 xmin;
+ fix31 xmax;
+ fix31 ymin;
+ fix31 ymax;
+ } bbox_t;
+
+#if SHORT_LISTS
+#define MAX_INTERCEPTS 256 /* Max storage for intercepts */
+typedef ufix8 cdr_t; /* 8 bit links in intercept chains */
+#else
+#define MAX_INTERCEPTS 1000 /* Max storage for intercepts */
+typedef ufix16 cdr_t; /* 16 bit links in intercept chains */
+#endif
+
+#if REENTRANT_ALLOC
+
+typedef struct intercepts_tag
+ {
+ fix15 car[MAX_INTERCEPTS];
+ fix15 cdr[MAX_INTERCEPTS];
+#if INCL_SCREEN
+ ufix8 inttype[MAX_INTERCEPTS];
+ ufix8 leftedge;
+ ufix16 fracpix;
+#endif
+ } intercepts_t;
+
+typedef struct plaid_tag
+ {
+ fix15 orus[MAX_CTRL_ZONES]; /* Controlled coordinate table (orus) */
+ fix15 pix[MAX_CTRL_ZONES]; /* Controlled coordinate table (sub-pixels) */
+ fix15 mult[MAX_INT_ZONES]; /* Interpolation multiplier table */
+ fix31 offset[MAX_INT_ZONES]; /* Interpolation offset table */
+ } plaid_t;
+#endif
+
+#if INCL_MULTIDEV
+typedef struct bitmap_tag
+ {
+ void (*p_open_bitmap)(PROTO_DECL2 fix31 x_set_width, fix31 y_set_width, fix31 xorg, fix31 yorg, fix15 xsize,fix15 ysize);
+ void (*p_set_bits)(PROTO_DECL2 fix15 y, fix15 xbit1, fix15 xbit2);
+ void (*p_close_bitmap)(PROTO_DECL1);
+ } bitmap_t;
+
+typedef struct outline_tag
+ {
+ void (*p_open_outline)(PROTO_DECL2 fix31 x_set_width, fix31 y_set_width, fix31 xmin, fix31 xmax, fix31 ymin,fix31 ymax);
+ void (*p_start_char)(PROTO_DECL1);
+ void (*p_start_contour)(PROTO_DECL2 fix31 x,fix31 y,boolean outside);
+ void (*p_curve)(PROTO_DECL2 fix31 x1, fix31 y1, fix31 x2, fix31 y2, fix31 x3, fix31 y3);
+ void (*p_line)(PROTO_DECL2 fix31 x, fix31 y);
+ void (*p_close_contour)(PROTO_DECL1);
+ void (*p_close_outline)(PROTO_DECL1);
+ } outline_t;
+#endif
+
+/* ---------------------------------------------------*/
+/**** MAIN GLOBAL DATA STRUCTURE, SPEEDO_GLOBALS *****/
+
+typedef struct speedo_global_data
+ {
+/* do_char.c data definitions */
+#if INCL_METRICS /* Metrics functions supported? */
+ kern_t kern; /* Kerning control block */
+#endif /* endif incl_metrics */
+ point_t Psw; /* End of escapement vector (1/65536 pixel units) */
+
+#if INCL_LCD /* Dynamic load character data supported? */
+ fix15 cb_offset; /* Offset to sub-char data in char buffer */
+#endif /* endif incl_lcd */
+
+/* do_trns.c data definitions */
+ point_t P0; /* Current point (sub-pixels) */
+ fix15 x_orus; /* Current X argument (orus) */
+ fix15 y_orus; /* Current Y argument (orus) */
+ fix15 x_pix; /* Current X argument (sub-pixels) */
+ fix15 y_pix; /* Current Y argument (sub-pixels) */
+ ufix8 x_int; /* Current X interpolation zone */
+ ufix8 y_int; /* Current Y interpolation zone */
+
+#if INCL_MULTIDEV && INCL_OUTLINE
+ outline_t outline_device;
+ boolean outline_device_set;
+#endif
+
+#if INCL_BLACK || INCL_SCREEN || INCL_2D
+#if INCL_MULTIDEV
+ bitmap_t bitmap_device;
+ boolean bitmap_device_set;
+#endif
+ band_t y_band; /* Y current band(whole pixels) */
+
+ struct set_width_tag
+ {
+ fix31 x;
+ fix31 y;
+ } set_width; /* Character escapement vector */
+
+ boolean first_pass; /* TRUE during first pass thru outline data */
+ boolean extents_running; /* T if extent accumulation for each vector */
+ fix15 x0_spxl; /* X coord of current point (sub pixels) */
+ fix15 y0_spxl; /* Y coord of current point (sub pixels) */
+ fix15 y_pxl; /* Y coord of current point (whole pixels) */
+#if REENTRANT_ALLOC
+ intercepts_t STACKFAR *intercepts;
+#else /* else if not reentrant */
+ fix15 car[MAX_INTERCEPTS]; /* Data field of intercept storage */
+ cdr_t cdr[MAX_INTERCEPTS]; /* Link field of intercept storage */
+#if INCL_SCREEN
+ ufix8 inttype[MAX_INTERCEPTS];
+ ufix8 leftedge;
+ ufix16 fracpix;
+#endif /* endif incl_screen */
+#endif /* endif reentrant */
+ fix15 bmap_xmin; /* Min X value (sub-pixel units) */
+ fix15 bmap_xmax; /* Max X value (sub-pixel units) */
+ fix15 bmap_ymin; /* Min Y value (sub-pixel units) */
+ fix15 bmap_ymax; /* Max Y value (sub-pixel units) */
+ fix15 no_y_lists; /* Number of active intercept lists */
+ fix15 first_offset; /* Index of first active list cell */
+ fix15 next_offset; /* Index of next free list cell */
+ boolean intercept_oflo; /* TRUE if intercepts data lost */
+#endif /* endif incl_black, incl_screen, incl_2d */
+
+/* bounding box now used by all output modules, including outline */
+ fix15 xmin; /* Min X value in whole character */
+ fix15 xmax; /* Max X value in whole character */
+ fix15 ymin; /* Min Y value in whole character */
+ fix15 ymax; /* Max Y value in whole character */
+
+#if INCL_2D
+ fix15 no_x_lists; /* Number of active x intercept lists */
+ band_t x_band; /* X current band(whole pixels) */
+ boolean x_scan_active; /* X scan flag during scan conversion */
+#endif
+
+/* reset.c data definitions */
+ ufix16 key32; /* Decryption keys 3,2 combined */
+ ufix8 key4; /* Decryption key 4 */
+ ufix8 key6; /* Decryption key 6 */
+ ufix8 key7; /* Decryption key 7 */
+ ufix8 key8; /* Decryption key 8 */
+
+/* set_spcs.c data definitions */
+ buff_t font;
+ buff_t GLOBALFAR *pfont; /* Pointer to font buffer structure */
+ fix31 font_buff_size; /* Number of bytes loaded in font buffer */
+ ufix8 FONTFAR *pchar_dir; /* Pointer to character directory */
+ fix15 first_char_idx; /* Index to first character in font */
+ fix15 no_chars_avail; /* Total characters in font layout */
+ fix15 orus_per_em; /* Outline resolution */
+ fix15 metric_resolution; /* metric resolution for setwidths, kerning pairs
+ (defaults to orus_per_em) */
+ tcb_t tcb0; /* Top level transformation control block */
+
+ boolean specs_valid; /* TRUE if fw_set_specs() successful */
+
+ fix15 depth_adj; /* Curve splitting depth adjustment */
+ boolean curves_out; /* Allow curves to output module */
+ fix15 output_mode; /* Output module selector */
+ fix15 thresh; /* Scan conversion threshold (sub-pixels) */
+ boolean normal; /* TRUE if 0 obl and mult of 90 deg rot */
+
+ fix15 multshift; /* Fixed point shift for multipliers */
+ fix15 pixshift; /* Fixed point shift for sub-pixels */
+ fix15 poshift; /* Left shift from pixel to output format */
+ fix15 mpshift; /* Fixed point shift for mult to sub-pixels */
+ fix31 multrnd; /* 0.5 in multiplier units */
+ fix15 pixrnd; /* 0.5 in sub-pixel units */
+ fix31 mprnd; /* 0.5 sub-pixels in multiplier units */
+ fix15 pixfix; /* Mask to remove fractional pixels */
+ fix15 onepix; /* 1.0 pixels in sub-pixel units */
+
+ boolean (*init_out)(PROTO_DECL2 specs_t GLOBALFAR *specsarg);
+ boolean (*begin_char)(PROTO_DECL2 point_t Psw,point_t Pmin,point_t Pmax);
+ void (*begin_sub_char)(PROTO_DECL2 point_t Psw,point_t Pmin,point_t Pmax);
+ void (*begin_contour)(PROTO_DECL2 point_t P1,boolean outside);
+ void (*curve)(PROTO_DECL2 point_t P1, point_t P2, point_t P3, fix15 depth);
+ void (*line)(PROTO_DECL2 point_t P1);
+ void (*end_contour)(PROTO_DECL1);
+ void (*end_sub_char)(PROTO_DECL1);
+ boolean (*end_char)(PROTO_DECL1);
+ specs_t GLOBALFAR *pspecs; /* Pointer to specifications bundle */
+ specs_t specs; /* copy specs onto stack */
+ ufix8 FONTFAR *font_org; /* Pointer to start of font data */
+ ufix8 FONTFAR *hdr2_org; /* Pointer to start of private header data */
+
+/* set_trns.c data definitions */
+ tcb_t tcb; /* Current transformation control block */
+ ufix8 Y_edge_org; /* Index to first Y controlled coordinate */
+ ufix8 Y_int_org; /* Index to first Y interpolation zone */
+ fix31 rnd_xmin; /* rounded out value of xmin for int-char spac. fix */
+
+#if REENTRANT_ALLOC
+ plaid_t STACKFAR *plaid;
+#else /* if not reentrant */
+ fix15 orus[MAX_CTRL_ZONES]; /* Controlled coordinate table (orus) */
+ fix15 pix[MAX_CTRL_ZONES]; /* Controlled coordinate table (sub-pixels) */
+ fix15 mult[MAX_INT_ZONES]; /* Interpolation multiplier table */
+ fix31 offset[MAX_INT_ZONES]; /* Interpolation offset table */
+#endif /* endif not reentrant */
+
+ fix15 no_X_orus; /* Number of X controlled coordinates */
+ fix15 no_Y_orus; /* Number of Y controlled coordinates */
+ ufix16 Y_constr_org; /* Origin of constraint table in font data */
+
+ constr_t constr; /* Constraint data state */
+ boolean c_act[MAX_CONSTR]; /* TRUE if constraint currently active */
+ fix15 c_pix[MAX_CONSTR]; /* Size of constrained zone if active */
+#if INCL_ISW
+ boolean import_setwidth_act; /* boolean to indicate imported setwidth */
+ boolean isw_modified_constants;
+ ufix32 imported_width; /* value of imported setwidth */
+ fix15 isw_xmax; /* maximum oru value for constants*/
+#endif
+#if INCL_SQUEEZING || INCL_ISW
+ fix15 setwidth_orus; /* setwidth value in orus */
+ /* bounding box in orus for squeezing */
+ fix15 bbox_xmin_orus; /* X minimum in orus */
+ fix15 bbox_xmax_orus; /* X maximum in orus */
+ fix15 bbox_ymin_orus; /* Y minimum in orus */
+ fix15 bbox_ymax_orus; /* Y maximum in orus */
+#endif
+#ifdef INCL_SQUEEZING
+ boolean squeezing_compound; /* flag to indicate a compound character*/
+#endif
+#ifdef INCL_CLIPPING
+ fix31 clip_xmax;
+ fix31 clip_ymax;
+ fix31 clip_xmin;
+ fix31 clip_ymin;
+#endif
+ } SPEEDO_GLOBALS;
+
+/***********************************************************************************
+ *
+ * Speedo global data structure allocation
+ *
+ ***********************************************************************************/
+
+#ifdef SET_SPCS
+#define EXTERN
+#else
+#define EXTERN extern
+#endif
+#if STATIC_ALLOC
+EXTERN SPEEDO_GLOBALS GLOBALFAR sp_globals;
+#define sp_intercepts sp_globals
+#define sp_plaid sp_globals
+#else
+#if DYNAMIC_ALLOC
+EXTERN SPEEDO_GLOBALS GLOBALFAR *sp_global_ptr;
+#define sp_globals (*sp_global_ptr)
+#define sp_intercepts (*sp_global_ptr)
+#define sp_plaid (*sp_global_ptr)
+#else
+#if REENTRANT_ALLOC
+#define sp_globals (*sp_global_ptr)
+#define sp_intercepts (*(*sp_global_ptr).intercepts)
+#define sp_plaid (*(*sp_global_ptr).plaid)
+#endif
+#endif
+#endif
+#ifdef EXTERN
+#undef EXTERN
+#endif
+
+
+/***** PUBLIC FONT HEADER OFFSET CONSTANTS *****/
+#define FH_FMVER 0 /* U D4.0 CR LF NULL NULL 8 bytes */
+#define FH_FNTSZ 8 /* U Font size (bytes) 4 bytes */
+#define FH_FBFSZ 12 /* U Min font buffer size (bytes) 4 bytes */
+#define FH_CBFSZ 16 /* U Min char buffer size (bytes) 2 bytes */
+#define FH_HEDSZ 18 /* U Header size (bytes) 2 bytes */
+#define FH_FNTID 20 /* U Source Font ID 2 bytes */
+#define FH_SFVNR 22 /* U Source Font Version Number 2 bytes */
+#define FH_FNTNM 24 /* U Source Font Name 70 bytes */
+#define FH_MDATE 94 /* U Manufacturing Date 10 bytes */
+#define FH_LAYNM 104 /* U Layout Name 70 bytes */
+#define FH_CPYRT 174 /* U Copyright Notice 78 bytes */
+#define FH_NCHRL 252 /* U Number of Chars in Layout 2 bytes */
+#define FH_NCHRF 254 /* U Total Number of Chars in Font 2 bytes */
+#define FH_FCHRF 256 /* U Index of first char in Font 2 bytes */
+#define FH_NKTKS 258 /* U Number of kerning tracks in font 2 bytes */
+#define FH_NKPRS 260 /* U Number of kerning pairs in font 2 bytes */
+#define FH_FLAGS 262 /* U Font flags 1 byte: */
+ /* Bit 0: Extended font */
+ /* Bit 1: not used */
+ /* Bit 2: not used */
+ /* Bit 3: not used */
+ /* Bit 4: not used */
+ /* Bit 5: not used */
+ /* Bit 6: not used */
+ /* Bit 7: not used */
+#define FH_CLFGS 263 /* U Classification flags 1 byte: */
+ /* Bit 0: Italic */
+ /* Bit 1: Monospace */
+ /* Bit 2: Serif */
+ /* Bit 3: Display */
+ /* Bit 4: not used */
+ /* Bit 5: not used */
+ /* Bit 6: not used */
+ /* Bit 7: not used */
+#define FH_FAMCL 264 /* U Family Classification 1 byte: */
+ /* 0: Don't care */
+ /* 1: Serif */
+ /* 2: Sans serif */
+ /* 3: Monospace */
+ /* 4: Script or calligraphic */
+ /* 5: Decorative */
+ /* 6-255: not used */
+#define FH_FRMCL 265 /* U Font form Classification 1 byte: */
+ /* Bits 0-3 (width type): */
+ /* 0-3: not used */
+ /* 4: Condensed */
+ /* 5: not used */
+ /* 6: Semi-condensed */
+ /* 7: not used */
+ /* 8: Normal */
+ /* 9: not used */
+ /* 10: Semi-expanded */
+ /* 11: not used */
+ /* 12: Expanded */
+ /* 13-15: not used */
+ /* Bits 4-7 (Weight): */
+ /* 0: not used */
+ /* 1: Thin */
+ /* 2: Ultralight */
+ /* 3: Extralight */
+ /* 4: Light */
+ /* 5: Book */
+ /* 6: Normal */
+ /* 7: Medium */
+ /* 8: Semibold */
+ /* 9: Demibold */
+ /* 10: Bold */
+ /* 11: Extrabold */
+ /* 12: Ultrabold */
+ /* 13: Heavy */
+ /* 14: Black */
+ /* 15-16: not used */
+#define FH_SFNTN 266 /* U Short Font Name 32 bytes */
+#define FH_SFACN 298 /* U Short Face Name 16 bytes */
+#define FH_FNTFM 314 /* U Font form 14 bytes */
+#define FH_ITANG 328 /* U Italic angle 2 bytes (1/256th deg) */
+#define FH_ORUPM 330 /* U Number of ORUs per em 2 bytes */
+#define FH_WDWTH 332 /* U Width of Wordspace 2 bytes */
+#define FH_EMWTH 334 /* U Width of Emspace 2 bytes */
+#define FH_ENWTH 336 /* U Width of Enspace 2 bytes */
+#define FH_TNWTH 338 /* U Width of Thinspace 2 bytes */
+#define FH_FGWTH 340 /* U Width of Figspace 2 bytes */
+#define FH_FXMIN 342 /* U Font-wide min X value 2 bytes */
+#define FH_FYMIN 344 /* U Font-wide min Y value 2 bytes */
+#define FH_FXMAX 346 /* U Font-wide max X value 2 bytes */
+#define FH_FYMAX 348 /* U Font-wide max Y value 2 bytes */
+#define FH_ULPOS 350 /* U Underline position 2 bytes */
+#define FH_ULTHK 352 /* U Underline thickness 2 bytes */
+#define FH_SMCTR 354 /* U Small caps transformation 6 bytes */
+#define FH_DPSTR 360 /* U Display sups transformation 6 bytes */
+#define FH_FNSTR 366 /* U Footnote sups transformation 6 bytes */
+#define FH_ALSTR 372 /* U Alpha sups transformation 6 bytes */
+#define FH_CMITR 378 /* U Chemical infs transformation 6 bytes */
+#define FH_SNMTR 384 /* U Small nums transformation 6 bytes */
+#define FH_SDNTR 390 /* U Small denoms transformation 6 bytes */
+#define FH_MNMTR 396 /* U Medium nums transformation 6 bytes */
+#define FH_MDNTR 402 /* U Medium denoms transformation 6 bytes */
+#define FH_LNMTR 408 /* U Large nums transformation 6 bytes */
+#define FH_LDNTR 414 /* U Large denoms transformation 6 bytes */
+ /* Transformation data format: */
+ /* Y position 2 bytes */
+ /* X scale 2 bytes (1/4096ths) */
+ /* Y scale 2 bytes (1/4096ths) */
+#define SIZE_FW FH_LDNTR + 6 /* size of nominal font header */
+#define EXP_FH_METRES SIZE_FW /* offset to expansion field metric resolution (optional) */
+
+
+
+/***** MODE FLAGS CONSTANTS *****/
+#define CURVES_OUT 0X0008 /* Output module accepts curves */
+#define BOGUS_MODE 0X0010 /* Linear scaling mode */
+#define CONSTR_OFF 0X0020 /* Inhibit constraint table */
+#define IMPORT_WIDTHS 0X0040 /* Imported width mode */
+#define SQUEEZE_LEFT 0X0100 /* Squeeze left mode */
+#define SQUEEZE_RIGHT 0X0200 /* Squeeze right mode */
+#define SQUEEZE_TOP 0X0400 /* Squeeze top mode */
+#define SQUEEZE_BOTTOM 0X0800 /* Squeeze bottom mode */
+#define CLIP_LEFT 0X1000 /* Clip left mode */
+#define CLIP_RIGHT 0X2000 /* Clip right mode */
+#define CLIP_TOP 0X4000 /* Clip top mode */
+#define CLIP_BOTTOM 0X8000 /* Clip bottom mode */
+
+/***********************************************************************************
+ *
+ * Speedo function declarations - use prototypes if available
+ *
+ ***********************************************************************************/
+
+/* do_char.c functions */
+boolean sp_make_char(PROTO_DECL2 ufix16 char_index);
+#if INCL_ISW
+fix31 sp_compute_isw_scale(PROTO_DECL2);
+static boolean sp_do_make_char(PROTO_DECL2 ufix16 char_index);
+boolean sp_make_char_isw(PROTO_DECL2 ufix16 char_index, ufix32 imported_width);
+static boolean sp_reset_xmax(PROTO_DECL2 fix31 xmax);
+#endif
+#if INCL_ISW || INCL_SQUEEZING
+static void sp_preview_bounding_box(PROTO_DECL2 ufix8 FONTFAR *pointer,ufix8 format);
+#endif
+
+#if INCL_METRICS /* Metrics functions supported? */
+fix31 sp_get_char_width(PROTO_DECL2 ufix16 char_index);
+boolean sp_get_char_bbox(PROTO_DECL2 ufix16 char_index, bbox_t *bbox);
+#endif
+
+/* do_trns.c functions */
+ufix8 FONTFAR *sp_read_bbox(PROTO_DECL2 ufix8 FONTFAR *pointer,point_t STACKFAR *pPmin,point_t STACKFAR *pPmax,boolean set_flag);
+void sp_proc_outl_data(PROTO_DECL2 ufix8 FONTFAR *pointer);
+
+/* out_blk.c functions */
+#if INCL_BLACK
+boolean sp_init_black(PROTO_DECL2 specs_t GLOBALFAR *specsarg);
+boolean sp_begin_char_black(PROTO_DECL2 point_t Psw,point_t Pmin,point_t Pmax);
+void sp_begin_contour_black(PROTO_DECL2 point_t P1,boolean outside);
+void sp_line_black(PROTO_DECL2 point_t P1);
+boolean sp_end_char_black(PROTO_DECL1);
+#endif
+
+/* out_scrn.c functions */
+#if INCL_SCREEN
+boolean sp_init_screen(PROTO_DECL2 specs_t GLOBALFAR *specsarg);
+boolean sp_begin_char_screen(PROTO_DECL2 point_t Psw,point_t Pmin,point_t Pmax);
+void sp_begin_contour_screen(PROTO_DECL2 point_t P1,boolean outside);
+void sp_curve_screen(PROTO_DECL2 point_t P1,point_t P2,point_t P3, fix15 depth);
+void sp_line_screen(PROTO_DECL2 point_t P1);
+void sp_end_contour_screen(PROTO_DECL1);
+boolean sp_end_char_screen(PROTO_DECL1);
+#endif
+
+/* out_outl.c functions */
+#if INCL_OUTLINE
+#if INCL_MULTIDEV
+boolean sp_set_outline_device(PROTO_DECL2 outline_t *ofuncs, ufix16 size);
+#endif
+
+
+boolean sp_init_outline(PROTO_DECL2 specs_t GLOBALFAR *specsarg);
+boolean sp_begin_char_outline(PROTO_DECL2 point_t Psw,point_t Pmin,point_t Pmax);
+void sp_begin_sub_char_outline(PROTO_DECL2 point_t Psw,point_t Pmin,point_t Pmax);
+void sp_begin_contour_outline(PROTO_DECL2 point_t P1,boolean outside);
+void sp_curve_outline(PROTO_DECL2 point_t P1,point_t P2,point_t P3, fix15 depth);
+void sp_line_outline(PROTO_DECL2 point_t P1);
+void sp_end_contour_outline(PROTO_DECL1);
+void sp_end_sub_char_outline(PROTO_DECL1);
+boolean sp_end_char_outline(PROTO_DECL1);
+#endif
+
+/* out_bl2d.c functions */
+#if INCL_2D
+boolean sp_init_2d(PROTO_DECL2 specs_t GLOBALFAR *specsarg);
+boolean sp_begin_char_2d(PROTO_DECL2 point_t Psw,point_t Pmin,point_t Pmax);
+void sp_begin_contour_2d(PROTO_DECL2 point_t P1,boolean outside);
+void sp_line_2d(PROTO_DECL2 point_t P1);
+boolean sp_end_char_2d(PROTO_DECL1);
+#endif
+
+/* out_util.c functions */
+#if INCL_BLACK || INCL_SCREEN || INCL_2D
+
+#if INCL_MULTIDEV
+boolean sp_set_bitmap_device(PROTO_DECL2 bitmap_t *bfuncs, ufix16 size);
+#endif
+
+void sp_init_char_out(PROTO_DECL2 point_t Psw, point_t Pmin, point_t Pmax);
+void sp_begin_sub_char_out(PROTO_DECL2 point_t Psw, point_t Pmin, point_t Pmax);
+void sp_curve_out(PROTO_DECL2 point_t P1, point_t P2, point_t P3, fix15 depth);
+void sp_end_contour_out(PROTO_DECL1);
+void sp_end_sub_char_out(PROTO_DECL1);
+void sp_init_intercepts_out(PROTO_DECL1);
+void sp_reduce_band_size_out(PROTO_DECL1);
+boolean sp_next_band_out(PROTO_DECL1);
+#endif
+
+#if INCL_USEROUT
+boolean sp_init_userout(specs_t *specsarg);
+#endif
+
+
+/* reset.c functions */
+void sp_reset(PROTO_DECL1);
+#if INCL_KEYS
+void sp_set_key(PROTO_DECL2 ufix8 key[]);
+#endif
+ufix16 sp_get_cust_no(PROTO_DECL2 buff_t font_buff);
+
+/* set_spcs.c functions */
+boolean sp_set_specs(PROTO_DECL2 specs_t STACKFAR *specsarg);
+void sp_type_tcb(PROTO_DECL2 tcb_t GLOBALFAR *ptcb);
+
+fix31 sp_read_long(PROTO_DECL2 ufix8 FONTFAR *pointer);
+fix15 sp_read_word_u(PROTO_DECL2 ufix8 FONTFAR *pointer);
+
+/* set_trns.c functions */
+void sp_init_tcb(PROTO_DECL1);
+void sp_scale_tcb(PROTO_DECL2 tcb_t GLOBALFAR *ptcb,fix15 x_pos,fix15 y_pos,fix15 x_scale,fix15 y_scale);
+ufix8 FONTFAR *sp_plaid_tcb(PROTO_DECL2 ufix8 FONTFAR *pointer,ufix8 format);
+
+#if INCL_SQUEEZING || INCL_ISW
+static void sp_calculate_x_pix(PROTO_DECL2 ufix8 start_edge,ufix8 end_edge,ufix16 constr_nr,fix31 x_scale,fix31 x_offset,fix31 ppo,fix15 setwidth_pix);
+#endif
+#if INCL_SQUEEZING
+static void sp_calculate_y_pix(PROTO_DECL2 ufix8 start_edge,ufix8 end_edge,ufix16 constr_nr,fix31 top_scale,fix31 bottom_scale,fix31 ppo,fix15 emtop_pix,fix15 embot_pix);
+boolean sp_calculate_x_scale(PROTO_DECL2 fix31 *x_factor,fix31 *x_offset,fix15 no_x_ctrl_zones);
+boolean sp_calculate_y_scale(PROTO_DECL2 fix31 *top_scale,fix31 *bottom_scale,fix15 first_y_zone, fix15 no_Y_ctrl_zones);
+#endif
+
+
+/* user defined functions */
+
+void sp_report_error(PROTO_DECL2 fix15 n);
+
+#if INCL_BLACK || INCL_SCREEN || INCL_2D
+void sp_open_bitmap(PROTO_DECL2 fix31 x_set_width, fix31 y_set_width, fix31 xorg, fix31 yorg, fix15 xsize,fix15 ysize);
+void sp_set_bitmap_bits(PROTO_DECL2 fix15 y, fix15 xbit1, fix15 xbit2);
+void sp_close_bitmap(PROTO_DECL1);
+#endif
+
+#if INCL_OUTLINE
+void sp_open_outline(PROTO_DECL2 fix31 x_set_width, fix31 y_set_width, fix31 xmin, fix31 xmax, fix31 ymin,fix31 ymax);
+void sp_start_new_char(PROTO_DECL1);
+void sp_start_contour(PROTO_DECL2 fix31 x,fix31 y,boolean outside);
+void sp_curve_to(PROTO_DECL2 fix31 x1, fix31 y1, fix31 x2, fix31 y2, fix31 x3, fix31 y3);
+void sp_line_to(PROTO_DECL2 fix31 x, fix31 y);
+void sp_close_contour(PROTO_DECL1);
+void sp_close_outline(PROTO_DECL1);
+#endif
+
+#if INCL_LCD /* Dynamic load character data supported? */
+buff_t *sp_load_char_data(PROTO_DECL2 fix31 file_offset,fix15 no_bytes,fix15 cb_offset); /* Load character data from font file */
+#endif
+
+#if INCL_PLAID_OUT /* Plaid data monitoring included? */
+void sp_record_xint(PROTO_DECL2 fix15 int_num); /* Record xint data */
+void sp_record_yint(PROTO_DECL2 fix15 int_num); /* Record yint data */
+void sp_begin_plaid_data(PROTO_DECL1); /* Signal start of plaid data */
+void sp_begin_ctrl_zones(PROTO_DECL2 fix15, no_X_zones, fix15 no_Y_zones); /* Signal start of control zones */
+void sp_record_ctrl_zone(PROTO_DECL2 fix31 start, fix31 end, fix15 constr); /* Record control zone data */
+void sp_begin_int_zones(PROTO_DECL2 fix15 no_X_int_zones, fix15 no_Y_int_zones); /* Signal start of interpolation zones */
+void sp_record_int_zone(PROTO_DECL2 fix31 start, fix31 end); /* Record interpolation zone data */
+void sp_end_plaid_data(PROTO_DECL1); /* Signal end of plaid data */
+#endif
+
+#endif /* _SPEEDO_H_ */
diff --git a/libXfont/src/Speedo/spencode.c b/libXfont/src/Speedo/spencode.c
new file mode 100644
index 000000000..96a13504a
--- /dev/null
+++ b/libXfont/src/Speedo/spencode.c
@@ -0,0 +1,67 @@
+/* $Xorg: spencode.c,v 1.4 2001/02/09 02:04:00 xorgcvs Exp $ */
+/*
+ * Copyright 1990, 1991 Network Computing Devices;
+ * Portions Copyright 1987 by Digital Equipment Corporation
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and
+ * its documentation for any purpose is hereby granted without fee, provided
+ * that the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the names of Network Computing Devices or Digital
+ * not be used in advertising or publicity pertaining to distribution of
+ * the software without specific, written prior permission.
+ *
+ * NETWORK COMPUTING DEVICES AND DIGITAL DISCLAIM ALL WARRANTIES WITH
+ * REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS, IN NO EVENT SHALL NETWORK COMPUTING DEVICES OR DIGITAL BE
+ * LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/*
+
+Copyright 1987, 1998 The Open Group
+
+Permission to use, copy, modify, distribute, and sell this software and its
+documentation for any purpose is hereby granted without fee, provided that
+the above copyright notice appear in all copies and that both that
+copyright notice and this permission notice appear in supporting
+documentation.
+
+The above copyright notice and this permission notice shall be included
+in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+IN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR
+OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of The Open Group shall
+not be used in advertising or otherwise to promote the sale, use or
+other dealings in this Software without prior written authorization
+from The Open Group.
+
+*/
+/* $XFree86: xc/lib/font/Speedo/spencode.c,v 1.6 2001/01/17 19:43:18 dawes Exp $ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "spint.h"
+
+/* No longer needed with new encoding code */
+/* #include "bics-iso.h"
+
+int sp_bics_map_size = (sizeof(sp_bics_map) / (sizeof(int) * 2));*/
+
+#ifdef EXTRAFONTS
+#include "adobe-iso.h"
+
+int adobe_map_size = (sizeof(adobe_map) / (sizeof(int) * 2));
+
+#endif /* EXTRAFONTS */
diff --git a/libXfont/src/Speedo/sperr.c b/libXfont/src/Speedo/sperr.c
new file mode 100644
index 000000000..36ce51125
--- /dev/null
+++ b/libXfont/src/Speedo/sperr.c
@@ -0,0 +1,127 @@
+/* $Xorg: sperr.c,v 1.4 2001/02/09 02:04:00 xorgcvs Exp $ */
+/*
+ * Copyright 1990, 1991 Network Computing Devices;
+ * Portions Copyright 1987 by Digital Equipment Corporation
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the names of M.I.T., Network Computing Devices,
+ * or Digital not be used in advertising or
+ * publicity pertaining to distribution of the software without specific,
+ * written prior permission. M.I.T. Network Computing Devices, or Digital
+ * make no representations about the
+ * suitability of this software for any purpose. It is provided "as is"
+ * without express or implied warranty.
+ *
+ * NETWORK COMPUTING DEVICES, DIGITAL AND MIT DISCLAIM ALL WARRANTIES WITH
+ * REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS, IN NO EVENT SHALL NETWORK COMPUTING DEVICES, DIGITAL OR MIT BE
+ * LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ */
+
+/*
+
+Copyright 1994, 1998 The Open Group
+
+Permission to use, copy, modify, distribute, and sell this software and its
+documentation for any purpose is hereby granted without fee, provided that
+the above copyright notice appear in all copies and that both that
+copyright notice and this permission notice appear in supporting
+documentation.
+
+The above copyright notice and this permission notice shall be included
+in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+IN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR
+OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of The Open Group shall
+not be used in advertising or otherwise to promote the sale, use or
+other dealings in this Software without prior written authorization
+from The Open Group.
+
+*/
+/* $XFree86: xc/lib/font/Speedo/sperr.c,v 1.6 2001/12/14 19:56:41 dawes Exp $ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "spint.h"
+
+#ifndef FONTMODULE
+#include <stdarg.h>
+#endif
+
+extern void ErrorF(const char* f, ...);
+
+void
+SpeedoErr(char *str, ...)
+{
+ va_list v;
+ int a1;
+
+ va_start(v, str);
+ ErrorF("Speedo: ");
+ a1 = va_arg(v, int);
+ ErrorF(str, a1);
+ va_end(v);
+}
+
+/*
+ * Called by Speedo character generator to report an error.
+ *
+ * Since character data not available is one of those errors
+ * that happens many times, don't report it to user
+ */
+void
+sp_report_error(fix15 n)
+{
+ switch (n) {
+ case 1:
+ SpeedoErr("Insufficient font data loaded\n");
+ break;
+ case 3:
+ SpeedoErr("Transformation matrix out of range\n");
+ break;
+ case 4:
+ SpeedoErr("Font format error\n");
+ break;
+ case 5:
+ SpeedoErr("Requested specs not compatible with output module\n");
+ break;
+ case 7:
+ SpeedoErr("Intelligent transformation requested but not supported\n");
+ break;
+ case 8:
+ SpeedoErr("Unsupported output mode requested\n");
+ break;
+ case 9:
+ SpeedoErr("Extended font loaded but only compact fonts supported\n");
+ break;
+ case 10:
+ SpeedoErr("Font specs not set prior to use of font\n");
+ break;
+ case 12:
+ break;
+ case 13:
+ SpeedoErr("Track kerning data not available()\n");
+ break;
+ case 14:
+ SpeedoErr("Pair kerning data not available()\n");
+ break;
+ default:
+ SpeedoErr("report_error(%d)\n", n);
+ break;
+ }
+}
diff --git a/libXfont/src/Speedo/spfile.c b/libXfont/src/Speedo/spfile.c
new file mode 100644
index 000000000..c58c0e471
--- /dev/null
+++ b/libXfont/src/Speedo/spfile.c
@@ -0,0 +1,460 @@
+/* $Xorg: spfile.c,v 1.4 2001/02/09 02:04:00 xorgcvs Exp $ */
+/*
+ * Copyright 1990, 1991 Network Computing Devices;
+ * Portions Copyright 1987 by Digital Equipment Corporation
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and
+ * its documentation for any purpose is hereby granted without fee, provided
+ * that the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the names of Network Computing Devices or Digital
+ * not be used in advertising or publicity pertaining to distribution of
+ * the software without specific, written prior permission.
+ *
+ * NETWORK COMPUTING DEVICES AND DIGITAL DISCLAIM ALL WARRANTIES WITH
+ * REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS, IN NO EVENT SHALL NETWORK COMPUTING DEVICES OR DIGITAL
+ * LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Author: Dave Lemke, Network Computing Devices Inc
+ */
+
+/*
+
+Copyright 1987, 1998 The Open Group
+
+Permission to use, copy, modify, distribute, and sell this software and its
+documentation for any purpose is hereby granted without fee, provided that
+the above copyright notice appear in all copies and that both that
+copyright notice and this permission notice appear in supporting
+documentation.
+
+The above copyright notice and this permission notice shall be included
+in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+IN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR
+OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of The Open Group shall
+not be used in advertising or otherwise to promote the sale, use or
+other dealings in this Software without prior written authorization
+from The Open Group.
+
+*/
+/* $XFree86: xc/lib/font/Speedo/spfile.c,v 1.13 2001/08/13 21:46:47 dawes Exp $ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include <X11/fonts/fntfilst.h>
+#include <X11/fonts/fontenc.h>
+#ifndef FONTMODULE
+#include <stdio.h>
+#else
+#include "xf86_ansic.h"
+#endif
+
+#include "spint.h"
+#include "bics-unicode.h"
+
+SpeedoFontPtr sp_fp_cur = (SpeedoFontPtr) 0;
+
+#ifdef EXTRAFONTS
+#include "ncdkeys.h"
+#endif
+
+#include "keys.h"
+
+#ifdef EXTRAFONTS
+static ufix8 skey[] =
+{
+ SKEY0,
+ SKEY1,
+ SKEY2,
+ SKEY3,
+ SKEY4,
+ SKEY5,
+ SKEY6,
+ SKEY7,
+ SKEY8
+}; /* Sample Font decryption key */
+
+static ufix8 rkey[] =
+{
+ RKEY0,
+ RKEY1,
+ RKEY2,
+ RKEY3,
+ RKEY4,
+ RKEY5,
+ RKEY6,
+ RKEY7,
+ RKEY8
+}; /* Retail Font decryption key */
+
+#endif /* EXTRAFONTS */
+
+#ifdef XSAMPLEFONTS
+static ufix8 xkey[] =
+{
+ XKEY0,
+ XKEY1,
+ XKEY2,
+ XKEY3,
+ XKEY4,
+ XKEY5,
+ XKEY6,
+ XKEY7,
+ XKEY8
+}; /* Sample Font decryption key */
+#endif
+
+static ufix8 mkey[] =
+{
+ KEY0,
+ KEY1,
+ KEY2,
+ KEY3,
+ KEY4,
+ KEY5,
+ KEY6,
+ KEY7,
+ KEY8
+}; /* Font decryption key */
+
+
+static fix15
+read_2b(ufix8 *ptr)
+{
+ fix15 tmp;
+
+ tmp = *ptr++;
+ tmp = (tmp << 8) + *ptr;
+ return tmp;
+}
+
+static fix31
+read_4b(ufix8 *ptr)
+{
+ fix31 tmp;
+
+ tmp = *ptr++;
+ tmp = (tmp << 8) + *ptr++;
+ tmp = (tmp << 8) + *ptr++;
+ tmp = (tmp << 8) + *ptr;
+ return tmp;
+}
+
+/*
+ * loads the specified char's data
+ */
+buff_t *
+sp_load_char_data(fix31 file_offset, fix15 num, fix15 cb_offset)
+{
+ SpeedoMasterFontPtr master = sp_fp_cur->master;
+
+ if (fseek(master->fp, (long) file_offset, (int) 0)) {
+ SpeedoErr("can't seek to char\n");
+ }
+ if ((num + cb_offset) > master->mincharsize) {
+ SpeedoErr("char buf overflow\n");
+ }
+ if (fread((master->c_buffer + cb_offset), sizeof(ufix8), num,
+ master->fp) != num) {
+ SpeedoErr("can't get char data\n");
+ }
+ master->char_data.org = (ufix8 *) master->c_buffer + cb_offset;
+ master->char_data.no_bytes = num;
+
+ return &master->char_data;
+}
+
+struct speedo_encoding {
+ char *name;
+ int *enc;
+ int enc_size;
+};
+
+/* Takes care of caching encodings already referenced */
+static int
+find_encoding(const char *fontname, const char *filename,
+ int **enc, int *enc_size)
+{
+ static struct speedo_encoding *known_encodings=0;
+ static int number_known_encodings=0;
+ static int known_encodings_size=0;
+
+ char *encoding_name;
+ int iso8859_1;
+ FontMapPtr mapping;
+ int i, j, k, size;
+ struct speedo_encoding *temp;
+ int *new_enc;
+ char *new_name;
+
+ iso8859_1 = 0;
+
+ encoding_name = FontEncFromXLFD(fontname, strlen(fontname));
+ if(!encoding_name) {
+ encoding_name="iso8859-1";
+ iso8859_1=1;
+ }
+ /* We don't go through the font library if asked for Latin-1 */
+ iso8859_1 = iso8859_1 || !strcmp(encoding_name, "iso8859-1");
+
+ for(i=0; i<number_known_encodings; i++) {
+ if(!strcmp(encoding_name, known_encodings[i].name)) {
+ *enc=known_encodings[i].enc;
+ *enc_size=known_encodings[i].enc_size;
+ return Successful;
+ }
+ }
+
+ /* it hasn't been cached yet, need to compute it */
+
+ /* ensure we've got enough storage first */
+
+ if(known_encodings==0) {
+ if((known_encodings=
+ (struct speedo_encoding*)xalloc(2*sizeof(struct speedo_encoding)))
+ ==0)
+ return AllocError;
+ number_known_encodings=0;
+ known_encodings_size=2;
+ }
+
+ if(number_known_encodings >= known_encodings_size) {
+ if((temp=
+ (struct speedo_encoding*)xrealloc(known_encodings,
+ 2*sizeof(struct speedo_encoding)*
+ known_encodings_size))==0)
+ return AllocError;
+ known_encodings=temp;
+ known_encodings_size*=2;
+ }
+
+ mapping=0;
+ if(!iso8859_1) {
+ mapping = FontEncMapFind(encoding_name,
+ FONT_ENCODING_UNICODE, -1, -1,
+ filename);
+ }
+#define SPEEDO_RECODE(c) \
+ (mapping? \
+ unicode_to_bics(FontEncRecode(c, mapping)): \
+ unicode_to_bics(c))
+
+ if((new_name = (char*)xalloc(strlen(encoding_name)))==0)
+ return AllocError;
+ strcpy(new_name, encoding_name);
+
+ /* For now, we limit ourselves to 256 glyphs */
+ size=0;
+ for(i=0; i < (mapping?mapping->encoding->size:256) && i < 256; i++)
+ if(SPEEDO_RECODE(i)>=0)
+ size++;
+ new_enc = (int*)xalloc(2*size*sizeof(int));
+ if(!new_enc) {
+ xfree(new_name);
+ return AllocError;
+ }
+ for(i=j=0; i < (mapping?mapping->encoding->size:256) && i < 256; i++)
+ if((k = SPEEDO_RECODE(i))>=0) {
+ new_enc[2*j] = i;
+ new_enc[2*j+1] = k;
+ j++;
+ }
+ known_encodings[number_known_encodings].name = new_name;
+ known_encodings[number_known_encodings].enc = new_enc;
+ known_encodings[number_known_encodings].enc_size = size;
+ number_known_encodings++;
+
+ *enc = new_enc;
+ *enc_size = size;
+ return Successful;
+#undef SPEEDO_RECODE
+}
+
+int
+sp_open_master(const char *fontname, const char *filename,
+ SpeedoMasterFontPtr *master)
+{
+ SpeedoMasterFontPtr spmf;
+ ufix8 tmp[16];
+ ufix16 cust_no;
+ FILE *fp;
+ ufix32 minbufsize;
+ ufix16 mincharsize;
+ ufix8 *f_buffer;
+ ufix8 *c_buffer;
+ int ret;
+ ufix8 *key;
+
+ spmf = (SpeedoMasterFontPtr) xalloc(sizeof(SpeedoMasterFontRec));
+ if (!spmf)
+ return AllocError;
+ bzero(spmf, sizeof(SpeedoMasterFontRec));
+ spmf->entry = NULL;
+ spmf->f_buffer = NULL;
+ spmf->c_buffer = NULL;
+
+ /* open font */
+ spmf->fname = (char *) xalloc(strlen(filename) + 1);
+ if (!spmf->fname)
+ return AllocError;
+ fp = fopen(filename, "r");
+ if (!fp) {
+ ret = BadFontName;
+ goto cleanup;
+ }
+ strcpy(spmf->fname, filename);
+ spmf->fp = fp;
+ spmf->state |= MasterFileOpen;
+
+ if (fread(tmp, sizeof(ufix8), 16, fp) != 16) {
+ ret = BadFontName;
+ goto cleanup;
+ }
+ minbufsize = (ufix32) read_4b(tmp + FH_FBFSZ);
+ f_buffer = (ufix8 *) xalloc(minbufsize);
+ if (!f_buffer) {
+ ret = AllocError;
+ goto cleanup;
+ }
+ spmf->f_buffer = f_buffer;
+
+ fseek(fp, (ufix32) 0, 0);
+
+ /* read in the font */
+ if (fread(f_buffer, sizeof(ufix8), (ufix16) minbufsize, fp) != minbufsize) {
+ ret = BadFontName;
+ goto cleanup;
+ }
+ spmf->copyright = (char *) (f_buffer + FH_CPYRT);
+ spmf->mincharsize = mincharsize = read_2b(f_buffer + FH_CBFSZ);
+
+ c_buffer = (ufix8 *) xalloc(mincharsize);
+ if (!c_buffer) {
+ ret = AllocError;
+ goto cleanup;
+ }
+ spmf->c_buffer = c_buffer;
+
+ spmf->font.org = spmf->f_buffer;
+ spmf->font.no_bytes = minbufsize;
+
+ cust_no = sp_get_cust_no(spmf->font);
+
+ /* XXX add custom encryption stuff here */
+
+#ifdef EXTRAFONTS
+ if (cust_no == SCUS0) {
+ key = skey;
+ } else if (cust_no == RCUS0) {
+ key = rkey;
+ } else
+#endif
+
+#ifdef XSAMPLEFONTS
+ if (cust_no == XCUS0) {
+ key = xkey;
+ } else
+#endif
+
+ if (cust_no == CUS0) {
+ key = mkey;
+ } else {
+ SpeedoErr("Non - standard encryption for \"%s\"\n", filename);
+ ret = BadFontName;
+ goto cleanup;
+ }
+ spmf->key = key;
+ sp_set_key(key);
+
+ spmf->first_char_id = read_2b(f_buffer + FH_FCHRF);
+ spmf->num_chars = read_2b(f_buffer + FH_NCHRL);
+
+
+ spmf->enc = 0;
+ spmf->enc_size = 0;
+
+#ifdef EXTRAFONTS
+ { /* choose the proper encoding */
+ char *f;
+
+ f = strrchr(filename, '/');
+ if (f) {
+ f++;
+ if (strncmp(f, "bx113", 5) == 0) {
+ spmf->enc = adobe_map;
+ spmf->enc_size = adobe_map_size;
+ }
+ }
+ }
+#endif
+
+ if(!spmf->enc)
+ if((ret=find_encoding(fontname, filename, &spmf->enc, &spmf->enc_size))
+ !=Successful)
+ goto cleanup;
+
+ spmf->first_char_id = spmf->enc[0];
+ /* size of extents array */
+ spmf->max_id = spmf->enc[(spmf->enc_size - 1) * 2];
+ spmf->num_chars = spmf->enc_size;
+
+ *master = spmf;
+
+ return Successful;
+
+cleanup:
+ *master = (SpeedoMasterFontPtr) 0;
+ sp_close_master_font(spmf);
+ return ret;
+}
+
+void
+sp_close_master_font(SpeedoMasterFontPtr spmf)
+{
+ if (!spmf)
+ return;
+ if (spmf->state & MasterFileOpen)
+ fclose(spmf->fp);
+ if (spmf->entry)
+ spmf->entry->u.scalable.extra->private = NULL;
+ xfree(spmf->fname);
+ xfree(spmf->f_buffer);
+ xfree(spmf->c_buffer);
+ xfree(spmf);
+}
+
+void
+sp_close_master_file(SpeedoMasterFontPtr spmf)
+{
+ (void) fclose(spmf->fp);
+ spmf->state &= ~MasterFileOpen;
+}
+
+
+/*
+ * reset the encryption key, and make sure the file is opened
+ */
+void
+sp_reset_master(SpeedoMasterFontPtr spmf)
+{
+ sp_set_key(spmf->key);
+ if (!(spmf->state & MasterFileOpen)) {
+ spmf->fp = fopen(spmf->fname, "r");
+ /* XXX -- what to do if we can't open the file? */
+ spmf->state |= MasterFileOpen;
+ }
+ fseek(spmf->fp, 0, 0);
+}
diff --git a/libXfont/src/Speedo/spfont.c b/libXfont/src/Speedo/spfont.c
new file mode 100644
index 000000000..c209d5a51
--- /dev/null
+++ b/libXfont/src/Speedo/spfont.c
@@ -0,0 +1,453 @@
+/* $Xorg: spfont.c,v 1.4 2001/02/09 02:04:00 xorgcvs Exp $ */
+/*
+ * Copyright 1990, 1991 Network Computing Devices;
+ * Portions Copyright 1987 by Digital Equipment Corporation
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and
+ * its documentation for any purpose is hereby granted without fee, provided
+ * that the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the names of Network Computing Devices or Digital
+ * not be used in advertising or publicity pertaining to distribution of
+ * the software without specific, written prior permission.
+ *
+ * NETWORK COMPUTING DEVICES AND DIGITAL DISCLAIM ALL WARRANTIES WITH
+ * REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS, IN NO EVENT SHALL NETWORK COMPUTING DEVICES OR DIGITAL BE
+ * LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Author: Dave Lemke, Network Computing Devices Inc
+ */
+/* $XFree86: xc/lib/font/Speedo/spfont.c,v 3.12tsi Exp $ */
+
+/*
+
+Copyright 1987, 1998 The Open Group
+
+Permission to use, copy, modify, distribute, and sell this software and its
+documentation for any purpose is hereby granted without fee, provided that
+the above copyright notice appear in all copies and that both that
+copyright notice and this permission notice appear in supporting
+documentation.
+
+The above copyright notice and this permission notice shall be included
+in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+IN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR
+OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of The Open Group shall
+not be used in advertising or otherwise to promote the sale, use or
+other dealings in this Software without prior written authorization
+from The Open Group.
+
+*/
+
+/*
+ * Speedo font loading
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include <X11/fonts/FSproto.h>
+#include "spint.h"
+#include <X11/fonts/fontutil.h>
+#ifndef FONTMODULE
+#ifdef _XOPEN_SOURCE
+#include <math.h>
+#else
+#define _XOPEN_SOURCE /* to get prototype for hypot on some systems */
+#include <math.h>
+#undef _XOPEN_SOURCE
+#endif
+#else
+#include "servermd.h"
+#include "xf86_ansic.h"
+#endif
+
+#ifndef M_PI
+#define M_PI 3.14159
+#endif /* M_PI */
+#ifndef DEFAULT_BIT_ORDER
+
+#ifdef BITMAP_BIT_ORDER
+#define DEFAULT_BIT_ORDER BITMAP_BIT_ORDER
+#else
+#define DEFAULT_BIT_ORDER UNKNOWN_BIT_ORDER
+#endif
+
+#endif
+
+static void SpeedoCloseFont(FontPtr pfont);
+
+static int
+sp_get_glyphs(
+ FontPtr pFont,
+ unsigned long count,
+ register unsigned char *chars,
+ FontEncoding charEncoding,
+ unsigned long *glyphCount, /* RETURN */
+ CharInfoPtr *glyphs) /* RETURN */
+{
+ SpeedoFontPtr spf;
+ unsigned int firstCol;
+ register unsigned int numCols;
+ unsigned int firstRow;
+ unsigned int numRows;
+ CharInfoPtr *glyphsBase;
+ register unsigned int c;
+ register CharInfoPtr pci;
+ unsigned int r;
+ CharInfoPtr encoding;
+ CharInfoPtr pDefault;
+#ifdef notyet
+ int itemSize;
+#endif
+ int err = Successful;
+
+ spf = (SpeedoFontPtr) pFont->fontPrivate;
+ encoding = spf->encoding;
+ pDefault = spf->pDefault;
+ firstCol = pFont->info.firstCol;
+ numCols = pFont->info.lastCol - firstCol + 1;
+ glyphsBase = glyphs;
+
+
+ /* XXX - this should be much smarter */
+ /* make sure the glyphs are there */
+#ifdef notyet
+ if (charEncoding == Linear8Bit || charEncoding == TwoD8Bit)
+ itemSize = 1;
+ else
+ itemSize = 2;
+
+ if (!fsd->complete)
+ err = fs_load_glyphs(NULL, pFont, count, itemSize, chars);
+#endif
+
+ if (err != Successful)
+ return err;
+
+ switch (charEncoding) {
+
+ case Linear8Bit:
+ case TwoD8Bit:
+ if (pFont->info.firstRow > 0)
+ break;
+ if (pFont->info.allExist && pDefault) {
+ while (count--) {
+ c = (*chars++) - firstCol;
+ if (c < numCols)
+ *glyphs++ = &encoding[c];
+ else
+ *glyphs++ = pDefault;
+ }
+ } else {
+ while (count--) {
+ c = (*chars++) - firstCol;
+ if (c < numCols && (pci = &encoding[c])->bits)
+ *glyphs++ = pci;
+ else if (pDefault)
+ *glyphs++ = pDefault;
+ }
+ }
+ break;
+ case Linear16Bit:
+ if (pFont->info.allExist && pDefault) {
+ while (count--) {
+ c = *chars++ << 8;
+ c = (c | *chars++) - firstCol;
+ if (c < numCols)
+ *glyphs++ = &encoding[c];
+ else
+ *glyphs++ = pDefault;
+ }
+ } else {
+ while (count--) {
+ c = *chars++ << 8;
+ c = (c | *chars++) - firstCol;
+ if (c < numCols && (pci = &encoding[c])->bits)
+ *glyphs++ = pci;
+ else if (pDefault)
+ *glyphs++ = pDefault;
+ }
+ }
+ break;
+
+ case TwoD16Bit:
+ firstRow = pFont->info.firstRow;
+ numRows = pFont->info.lastRow - firstRow + 1;
+ while (count--) {
+ r = (*chars++) - firstRow;
+ c = (*chars++) - firstCol;
+ if (r < numRows && c < numCols &&
+ (pci = &encoding[r * numCols + c])->bits)
+ *glyphs++ = pci;
+ else if (pDefault)
+ *glyphs++ = pDefault;
+ }
+ break;
+ }
+ *glyphCount = glyphs - glyphsBase;
+ return Successful;
+}
+
+static CharInfoRec nonExistantChar;
+
+static int
+sp_get_metrics(
+ FontPtr pFont,
+ unsigned long count,
+ register unsigned char *chars,
+ FontEncoding charEncoding,
+ unsigned long *glyphCount, /* RETURN */
+ xCharInfo **glyphs) /* RETURN */
+{
+ int ret;
+ SpeedoFontPtr spf;
+ CharInfoPtr oldDefault;
+
+ spf = (SpeedoFontPtr) pFont->fontPrivate;
+ oldDefault = spf->pDefault;
+ spf->pDefault = &nonExistantChar;
+ ret = sp_get_glyphs(pFont, count, chars, charEncoding,
+ glyphCount, (CharInfoPtr *) glyphs);
+
+ spf->pDefault = oldDefault;
+ return ret;
+}
+
+int
+sp_open_font(
+ char *fontname,
+ char *filename,
+ FontEntryPtr entry,
+ FontScalablePtr vals,
+ fsBitmapFormat format,
+ fsBitmapFormatMask fmask,
+ Mask flags,
+ SpeedoFontPtr *spfont)
+{
+ SpeedoFontPtr spf;
+ SpeedoMasterFontPtr spmf;
+ int ret;
+ specs_t specs;
+ int xx8, xy8, yx8, yy8;
+
+ /* find a master (create it if necessary) */
+ spmf = (SpeedoMasterFontPtr) entry->u.scalable.extra->private;
+ if (!spmf)
+ {
+ ret = sp_open_master(fontname, filename, &spmf);
+ if (ret != Successful)
+ return ret;
+ entry->u.scalable.extra->private = (pointer) spmf;
+ spmf->entry = entry;
+ }
+
+ spf = (SpeedoFontPtr) xalloc(sizeof(SpeedoFontRec));
+ if (!spf)
+ return AllocError;
+ bzero((char *) spf, sizeof(SpeedoFontRec));
+
+ *spfont = spf;
+
+ /* clobber everything -- this may be leaking, but other wise evil
+ * stuff is left behind -- succesive transformed fonts get mangled */
+ bzero((char *)&sp_globals, sizeof(sp_globals));
+
+ spf->master = spmf;
+ spf->entry = entry;
+ spmf->refcount++;
+ sp_reset_master(spmf);
+ /* now we've done enough that if we bail out we must call sp_close_font */
+
+ spf->vals = *vals;
+
+ /* set up specs */
+
+ specs.pfont = &spmf->font;
+
+ specs.xxmult = (int)(vals->pixel_matrix[0] * (double)(1L << 16));
+ specs.xymult = (int)(vals->pixel_matrix[2] * (double)(1L << 16));
+ specs.yxmult = (int)(vals->pixel_matrix[1] * (double)(1L << 16));
+ specs.yymult = (int)(vals->pixel_matrix[3] * (double)(1L << 16));
+
+ specs.xoffset = 0L << 16; /* XXX tweak? */
+ specs.yoffset = 0L << 16; /* XXX tweak? */
+
+ specs.flags = MODE_SCREEN;
+ specs.out_info = NULL;
+
+ /* When Speedo tries to generate a very small font bitmap, it
+ often crashes or goes into an infinite loop.
+ Don't know why this is so, but until we can fix it properly,
+ return BadFontName for anything smaller than 4 pixels.
+ */
+#define TINY_FACTOR (16 << 16)
+ xx8 = specs.xxmult >> 8;
+ xy8 = specs.xymult >> 8;
+ yx8 = specs.yxmult >> 8;
+ yy8 = specs.yymult >> 8;
+ if (xx8 * xx8 + xy8 * xy8 < TINY_FACTOR ||
+ yx8 * yx8 + yy8 * yy8 < TINY_FACTOR)
+ {
+ sp_close_font(spf);
+ return BadFontName;
+ }
+
+ /* clobber global state to avoid wrecking future transformed fonts */
+ bzero ((char *) &sp_globals, sizeof(sp_globals));
+
+ if (!sp_set_specs(&specs))
+ {
+ sp_close_font(spf);
+ return BadFontName;
+ }
+
+ spf->specs = specs;
+ spf->master = spmf;
+
+ *spfont = spf;
+ return Successful;
+}
+
+static int
+sp_load_font(
+ char *fontname,
+ char *filename,
+ FontEntryPtr entry,
+ FontScalablePtr vals,
+ fsBitmapFormat format,
+ fsBitmapFormatMask fmask,
+ FontPtr pfont,
+ Mask flags)
+{
+ SpeedoFontPtr spf;
+ SpeedoMasterFontPtr spmf;
+ int esize;
+ int ret;
+ long sWidth;
+
+ ret = sp_open_font(fontname, filename, entry, vals, format, fmask,
+ flags, &spf);
+
+ if (ret != Successful)
+ return ret;
+
+ spmf = spf->master;
+ sp_reset_master(spmf);
+ esize = sizeof(CharInfoRec) * (spmf->max_id - spmf->first_char_id + 1);
+
+ spf->encoding = (CharInfoPtr) xalloc(esize);
+ if (!spf->encoding) {
+ sp_close_font(spf);
+ return AllocError;
+ }
+ bzero((char *) spf->encoding, esize);
+
+ sp_fp_cur = spf;
+
+ sp_make_header(spf, &pfont->info);
+
+ sp_compute_bounds(spf, &pfont->info, SaveMetrics, &sWidth);
+
+ sp_compute_props(spf, fontname, &pfont->info, sWidth);
+
+ pfont->fontPrivate = (pointer) spf;
+
+/* XXX */
+ flags |= FontLoadBitmaps;
+
+ if (flags & FontLoadBitmaps) {
+ sp_fp_cur = spf;
+ ret = sp_build_all_bitmaps(pfont, format, fmask);
+ }
+ if (ret != Successful)
+ return ret;
+
+ /* compute remaining accelerators */
+ FontComputeInfoAccelerators(&pfont->info);
+
+ pfont->format = format;
+
+ pfont->get_metrics = sp_get_metrics;
+ pfont->get_glyphs = sp_get_glyphs;
+ pfont->unload_font = SpeedoCloseFont;
+ pfont->unload_glyphs = NULL;
+ pfont->refcnt = 0;
+
+ /* have to hold on to master for min/max id */
+ sp_close_master_file(spmf);
+
+ return ret;
+}
+
+int
+SpeedoFontLoad(
+ FontPtr *ppfont,
+ char *fontname,
+ char *filename,
+ FontEntryPtr entry,
+ FontScalablePtr vals,
+ fsBitmapFormat format,
+ fsBitmapFormatMask fmask,
+ Mask flags)
+{
+ FontPtr pfont;
+ int ret;
+
+ /* Reject ridiculously small sizes that will blow up the math */
+ if (hypot(vals->pixel_matrix[0], vals->pixel_matrix[1]) < 1.0 ||
+ hypot(vals->pixel_matrix[2], vals->pixel_matrix[3]) < 1.0)
+ return BadFontName;
+
+ if (!(pfont = CreateFontRec()))
+ return AllocError;
+
+ ret = sp_load_font(fontname, filename, entry, vals, format, fmask,
+ pfont, flags);
+
+ if (ret == Successful)
+ *ppfont = pfont;
+ else
+ DestroyFontRec (pfont);
+
+ return ret;
+}
+
+void
+sp_close_font(SpeedoFontPtr spf)
+{
+ SpeedoMasterFontPtr spmf;
+
+ spmf = spf->master;
+ --spmf->refcount;
+ if (spmf->refcount == 0)
+ sp_close_master_font (spmf);
+ xfree(spf->encoding);
+ xfree(spf->bitmaps);
+ xfree(spf);
+}
+
+static void
+SpeedoCloseFont(FontPtr pfont)
+{
+ SpeedoFontPtr spf;
+
+ spf = (SpeedoFontPtr) pfont->fontPrivate;
+ sp_close_font(spf);
+ xfree(pfont->info.isStringProp);
+ xfree(pfont->info.props);
+ DestroyFontRec(pfont);
+
+}
diff --git a/libXfont/src/Speedo/spfuncs.c b/libXfont/src/Speedo/spfuncs.c
new file mode 100644
index 000000000..da4d5c55e
--- /dev/null
+++ b/libXfont/src/Speedo/spfuncs.c
@@ -0,0 +1,167 @@
+/* $Xorg: spfuncs.c,v 1.4 2001/02/09 02:04:00 xorgcvs Exp $ */
+/*
+ * Copyright 1990, 1991 Network Computing Devices;
+ * Portions Copyright 1987 by Digital Equipment Corporation
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and
+ * its documentation for any purpose is hereby granted without fee, provided
+ * that the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the names of Network Computing Devices or Digital
+ * not be used in advertising or publicity pertaining to distribution of
+ * the software without specific, written prior permission.
+ *
+ * NETWORK COMPUTING DEVICES AND DIGITAL DISCLAIM ALL WARRANTIES WITH
+ * REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS, IN NO EVENT SHALL NETWORK COMPUTING DEVICES OR DIGITAL BE
+ * LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Author: Dave Lemke, Network Computing Devices, Inc
+ */
+
+/*
+
+Copyright 1987, 1998 The Open Group
+
+Permission to use, copy, modify, distribute, and sell this software and its
+documentation for any purpose is hereby granted without fee, provided that
+the above copyright notice appear in all copies and that both that
+copyright notice and this permission notice appear in supporting
+documentation.
+
+The above copyright notice and this permission notice shall be included
+in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+IN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR
+OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of The Open Group shall
+not be used in advertising or otherwise to promote the sale, use or
+other dealings in this Software without prior written authorization
+from The Open Group.
+
+*/
+/* $XFree86: xc/lib/font/Speedo/spfuncs.c,v 1.7 2001/08/27 19:49:51 dawes Exp $ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#ifndef FONTMODULE
+#include <X11/Xos.h>
+#endif
+#include <X11/fonts/fntfilst.h>
+#include <X11/fonts/fontutil.h>
+#include "spint.h"
+
+/* ARGSUSED */
+static int
+SpeedoOpenScalable (
+ FontPathElementPtr fpe,
+ FontPtr *pFont,
+ int flags,
+ FontEntryPtr entry,
+ char *fileName,
+ FontScalablePtr vals,
+ fsBitmapFormat format,
+ fsBitmapFormatMask fmask,
+ FontPtr non_cachable_font) /* We don't do licensing */
+{
+ char fullName[MAXFONTNAMELEN];
+
+ strcpy (fullName, entry->name.name);
+ return SpeedoFontLoad (pFont, fullName, fileName, entry, vals,
+ format, fmask, flags);
+}
+
+/*
+ * XXX
+ *
+ * this does a lot more then i'd like, but it has to get the bitmaps
+ * in order to get accurate metrics (which it *must* have).
+ *
+ * a possible optimization is to avoid allocating the glyph memory
+ * and to simply save the values without doing the work.
+ */
+static int
+get_font_info(
+ FontInfoPtr pinfo,
+ char *fontname,
+ char *filename,
+ FontEntryPtr entry,
+ FontScalablePtr vals,
+ SpeedoFontPtr *spfont)
+{
+ SpeedoFontPtr spf;
+ int err;
+ long sWidth;
+
+ err = sp_open_font(fontname, filename, entry, vals,
+ (fsBitmapFormat) 0, (fsBitmapFormatMask) 0, (unsigned long) 0,
+ &spf);
+
+ if (err != Successful)
+ return err;
+
+ sp_fp_cur = spf;
+ sp_reset_master(spf->master);
+
+ sp_make_header(spf, pinfo);
+
+ sp_compute_bounds(spf, pinfo, (unsigned long) 0, &sWidth);
+
+ sp_compute_props(spf, fontname, pinfo, sWidth);
+
+ /* compute remaining accelerators */
+ FontComputeInfoAccelerators (pinfo);
+
+ *spfont = spf;
+
+ return Successful;
+}
+
+/* ARGSUSED */
+static int
+SpeedoGetInfoScaleable(
+ FontPathElementPtr fpe,
+ FontInfoPtr pFontInfo,
+ FontEntryPtr entry,
+ FontNamePtr fontName,
+ char *fileName,
+ FontScalablePtr vals)
+{
+ SpeedoFontPtr spf = NULL;
+ char fullName[MAXFONTNAMELEN];
+ int err;
+
+ strcpy(fullName, entry->name.name);
+ FontParseXLFDName(fullName, vals, FONT_XLFD_REPLACE_VALUE);
+
+ err = get_font_info(pFontInfo, fullName, fileName, entry, vals, &spf);
+
+ if (spf)
+ sp_close_font(spf);
+
+ return err;
+}
+
+static FontRendererRec renderer = {
+ ".spd", 4, NULL, SpeedoOpenScalable,
+ NULL, SpeedoGetInfoScaleable, 0
+ , CAP_MATRIX | CAP_CHARSUBSETTING
+};
+
+void
+SpeedoRegisterFontFileFunctions()
+{
+ sp_make_standard_props();
+ sp_reset();
+ FontFileRegisterRenderer(&renderer);
+}
diff --git a/libXfont/src/Speedo/spglyph.c b/libXfont/src/Speedo/spglyph.c
new file mode 100644
index 000000000..113f37882
--- /dev/null
+++ b/libXfont/src/Speedo/spglyph.c
@@ -0,0 +1,399 @@
+/* $Xorg: spglyph.c,v 1.4 2001/02/09 02:04:00 xorgcvs Exp $ */
+/*
+ * Copyright 1990, 1991 Network Computing Devices;
+ * Portions Copyright 1987 by Digital Equipment Corporation
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and
+ * its documentation for any purpose is hereby granted without fee, provided
+ * that the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the names of Network Computing Devices or Digital
+ * not be used in advertising or publicity pertaining to distribution of
+ * the software without specific, written prior permission.
+ *
+ * NETWORK COMPUTING DEVICES AND DIGITAL DISCLAIM ALL WARRANTIES WITH
+ * REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS, IN NO EVENT SHALL NETWORK COMPUTING DEVICES OR DIGITAL BE
+ * LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Author: Dave Lemke, Network Computing Devices Inc
+ */
+
+/*
+
+Copyright 1987, 1998 The Open Group
+
+Permission to use, copy, modify, distribute, and sell this software and its
+documentation for any purpose is hereby granted without fee, provided that
+the above copyright notice appear in all copies and that both that
+copyright notice and this permission notice appear in supporting
+documentation.
+
+The above copyright notice and this permission notice shall be included
+in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+IN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR
+OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of The Open Group shall
+not be used in advertising or otherwise to promote the sale, use or
+other dealings in this Software without prior written authorization
+from The Open Group.
+
+*/
+/* $XFree86: xc/lib/font/Speedo/spglyph.c,v 1.6 2001/01/17 19:43:20 dawes Exp $ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include <X11/X.h> /* for bit order #defines */
+#include "spint.h"
+#include <X11/fonts/fontutil.h>
+
+#undef CLIP_BBOX_NOISE
+
+static CurrentFontValuesRec current_font_values;
+static CurrentFontValuesPtr cfv = &current_font_values;
+static int bit_order,
+ byte_order,
+ scan;
+
+static unsigned long
+sp_compute_data_size(
+ FontPtr pfont,
+ int mappad,
+ int scanlinepad,
+ unsigned long start,
+ unsigned long end)
+{
+ unsigned long ch;
+ unsigned long size = 0;
+ int bpr;
+ SpeedoFontPtr spf = (SpeedoFontPtr) pfont->fontPrivate;
+ FontInfoPtr pinfo = &pfont->info;
+ int firstChar;
+
+ firstChar = spf->master->first_char_id;
+
+ /* allocate the space */
+ switch (mappad) {
+ int charsize;
+ CharInfoPtr ci;
+ xCharInfo *cim;
+
+ case BitmapFormatImageRectMin:
+ cfv->bpr = 0;
+ for (ch = start; ch <= end; ch++) {
+ ci = &spf->encoding[ch - firstChar];
+ if (!ci)
+ ci = spf->pDefault;
+ cim = &ci->metrics;
+ charsize = GLYPH_SIZE(ci, scanlinepad);
+ charsize *= cim->ascent + cim->descent;
+ size += charsize;
+ }
+ break;
+ case BitmapFormatImageRectMaxWidth:
+ bpr = GLWIDTHBYTESPADDED(FONT_MAX_WIDTH(pinfo), scanlinepad);
+ cfv->bpr = bpr;
+ for (ch = start; ch <= end; ch++) {
+ ci = &spf->encoding[ch - firstChar];
+ if (!ci)
+ ci = spf->pDefault;
+ cim = &ci->metrics;
+ charsize = bpr * (cim->ascent + cim->descent);
+ size += charsize;
+ }
+ break;
+ case BitmapFormatImageRectMax:
+ bpr = GLWIDTHBYTESPADDED(FONT_MAX_WIDTH(pinfo), scanlinepad);
+ cfv->bpr = bpr;
+ size = (end - start + 1) * bpr * FONT_MAX_HEIGHT(pinfo);
+ break;
+ default:
+ assert(0);
+ }
+
+ return size;
+}
+
+static void
+finish_line(SpeedoFontPtr spf)
+{
+ int bpr = cfv->bpr;
+ CharInfoPtr ci = &spf->encoding[cfv->char_id - spf->master->first_char_id];
+
+ if (bpr == 0) {
+ bpr = GLYPH_SIZE(ci, cfv->scanpad);
+ }
+ if (bpr) { /* char may not have any metrics... */
+ cfv->bp = (char *)cfv->bp + bpr;
+ }
+ assert(cfv->bp - sp_fp_cur->bitmaps <= sp_fp_cur->bitmap_size);
+}
+
+
+void
+sp_set_bitmap_bits(fix15 y, fix15 xbit1, fix15 xbit2)
+{
+ int nmiddle;
+ CARD8 startmask,
+ endmask;
+ CARD8 *dst;
+
+ if (xbit1 > cfv->bit_width) {
+
+#ifdef CLIP_BBOX_NOISE
+ SpeedoErr("Run wider than bitmap width -- truncated\n");
+#endif
+
+ xbit1 = cfv->bit_width;
+ }
+ if (xbit2 > cfv->bit_width) {
+
+#ifdef CLIP_BBOX_NOISE
+ SpeedoErr("Run wider than bitmap width -- truncated\n");
+#endif
+
+ xbit2 = cfv->bit_width;
+ }
+
+ if (xbit2 < xbit1) {
+ xbit2 = xbit1;
+ }
+
+ while (cfv->cur_y != y) {
+ finish_line(sp_fp_cur);
+ cfv->cur_y++;
+ }
+
+ cfv->last_y = y;
+ if (y >= cfv->bit_height) {
+
+#ifdef CLIP_BBOX_NOISE
+ SpeedoErr("Y larger than bitmap height -- truncated\n");
+#endif
+
+ cfv->trunc = 1;
+ return;
+ }
+ if (xbit1 < 0) /* XXX this is more than a little bit rude... */
+ xbit1 = 0;
+
+ nmiddle = (xbit1 >> 3);
+ dst = (CARD8 *)cfv->bp + nmiddle;
+ xbit2 -= (xbit1 & ~7);
+ nmiddle = (xbit2 >> 3);
+ xbit1 &= 7;
+ xbit2 &= 7;
+ if (bit_order == MSBFirst) {
+ startmask = ((CARD8) ~0) >> xbit1;
+ endmask = ~(((CARD8) ~0) >> xbit2);
+ } else {
+ startmask = ((CARD8) ~0) << xbit1;
+ endmask = ~(((CARD8) ~0) << xbit2);
+ }
+ if (nmiddle == 0)
+ *dst |= endmask & startmask;
+ else {
+ *dst++ |= startmask;
+ while (--nmiddle)
+ *dst++ = (CARD8)~0;
+ *dst |= endmask;
+ }
+}
+
+/* ARGSUSED */
+void
+sp_open_bitmap(fix31 x_set_width, fix31 y_set_width, fix31 xorg, fix31 yorg,
+ fix15 xsize, fix15 ysize)
+{
+ CharInfoPtr ci = &sp_fp_cur->encoding[cfv->char_id - sp_fp_cur->master->first_char_id];
+
+/*-
+ * this is set to provide better quality bitmaps. since the Speedo
+ * sp_get_bbox() function returns an approximate (but guarenteed to contain)
+ * set of metrics, some of the bitmaps can be place poorly inside and
+ * look bad.
+ *
+ * with this set, the actual bitmap values are used instead of the bboxes.
+ * it makes things look better, but causes two possible problems:
+ *
+ * 1 - the reported min & max bounds may not correspond to the extents
+ * reported
+ * 2 - if the extents are reported before the character is generated,
+ * a client could see them change. this currently never happens,
+ * but will when a desired enhancement (don't reneder till needed)
+ * is made.
+ */
+
+#define BBOX_FIXUP 1
+
+#ifdef BBOX_FIXUP
+ int off_horz;
+ int off_vert;
+
+ if (xorg < 0)
+ off_horz = (fix15) ((xorg - 32768L) / 65536);
+ else
+ off_horz = (fix15) ((xorg + 32768L) / 65536);
+ if (yorg < 0)
+ off_vert = (fix15) ((yorg - 32768L) / 65536);
+ else
+ off_vert = (fix15) ((yorg + 32768L) / 65536);
+ if (xsize != 0 || ysize != 0 || ci->metrics.characterWidth)
+ {
+ ci->metrics.leftSideBearing = off_horz;
+ ci->metrics.descent = -off_vert;
+ ci->metrics.rightSideBearing = xsize + off_horz;
+ ci->metrics.ascent = ysize + off_vert;
+ }
+ else
+ {
+ /* If setting the proper size would cause the character to appear to
+ be non-existent, fudge things by giving it a pixel to occupy. */
+ xsize = ysize = 1;
+ ci->metrics.leftSideBearing = ci->metrics.descent = 0;
+ ci->metrics.rightSideBearing = ci->metrics.ascent = 1;
+ }
+
+ cfv->bit_width = xsize;
+ cfv->bit_height = ysize;
+#else
+ cfv->bit_width = ci->metrics.rightSideBearing -
+ ci->metrics.leftSideBearing;
+ cfv->bit_height = ci->metrics.ascent + ci->metrics.descent;
+#endif
+
+ assert(cfv->bp - sp_fp_cur->bitmaps <= sp_fp_cur->bitmap_size);
+ ci->bits = (char *) cfv->bp;
+
+ cfv->cur_y = 0;
+}
+
+void
+sp_close_bitmap()
+{
+ CharInfoPtr ci = &sp_fp_cur->encoding[cfv->char_id - sp_fp_cur->master->first_char_id];
+ int bpr = cfv->bpr;
+
+ if (bpr == 0)
+ bpr = GLYPH_SIZE(ci, cfv->scanpad);
+ if (!cfv->trunc)
+ finish_line(sp_fp_cur);
+ cfv->trunc = 0;
+ cfv->last_y++;
+ while (cfv->last_y < cfv->bit_height) {
+ finish_line(sp_fp_cur);
+ cfv->last_y++;
+ }
+ if (byte_order != bit_order) {
+ switch (scan) {
+ case 1:
+ break;
+ case 2:
+ TwoByteSwap(cfv->bp, bpr * cfv->bit_height);
+ break;
+ case 4:
+ FourByteSwap(cfv->bp, bpr * cfv->bit_height);
+ break;
+ }
+ }
+}
+
+int
+sp_build_all_bitmaps(
+ FontPtr pfont,
+ fsBitmapFormat format,
+ fsBitmapFormatMask fmask)
+{
+ int ret,
+ glyph = 1,
+ image = BitmapFormatImageRectMin;
+ unsigned long glyph_size;
+ SpeedoFontPtr spf = (SpeedoFontPtr) pfont->fontPrivate;
+ SpeedoMasterFontPtr spmf = spf->master;
+ pointer bitmaps;
+ int start,
+ end,
+ i;
+
+ scan = 1;
+ ret = CheckFSFormat(format, fmask,
+ &bit_order, &byte_order, &scan, &glyph, &image);
+
+ pfont->bit = bit_order;
+ pfont->byte = byte_order;
+ pfont->glyph = glyph;
+ pfont->scan = scan;
+ if (ret != Successful)
+ return BadFontFormat;
+
+ start = spmf->first_char_id;
+ end = spmf->max_id;
+ glyph_size = sp_compute_data_size(pfont, image, glyph, start, end);
+
+ /* XXX -- MONDO KLUDGE -- add some slop */
+ /*
+ * not sure why this is wanted, but it keeps the packer from going off the
+ * end and toasting us down the line
+ */
+ glyph_size += 20;
+
+#ifdef DEBUG
+ spf->bitmap_size = glyph_size;
+#endif
+
+ bitmaps = (pointer) xalloc(glyph_size);
+ if (!bitmaps)
+ return AllocError;
+ bzero((char *) bitmaps, glyph_size);
+
+ /* set up some state */
+ sp_fp_cur = spf;
+ spf->bitmaps = bitmaps;
+ cfv->format = format;
+ cfv->scanpad = glyph;
+ cfv->bp = bitmaps;
+
+ for (i = 0; i < spmf->num_chars; i++) {
+ int j;
+ cfv->char_index = spmf->enc[i * 2 + 1];
+ cfv->char_id = spmf->enc[i * 2];
+#ifdef DEBUG
+fprintf(stderr, "build_all_sp_bitmaps:i = %d, Char ID = %d\n", i, cfv->char_id);
+#endif
+ if (!cfv->char_id)
+ continue;
+
+ /*
+ * See if this character is in the list of ranges specified in the
+ * XLFD name
+ */
+ for (j = 0; j < spf->vals.nranges; j++)
+ if (cfv->char_id >= mincharno(spf->vals.ranges[j]) &&
+ cfv->char_id <= maxcharno(spf->vals.ranges[j]))
+ break;
+
+ /* If not, don't realize it. */
+ if (spf->vals.nranges && j == spf->vals.nranges)
+ continue;
+
+ if (!sp_make_char(cfv->char_index)) {
+
+#ifdef DEBUG /* can be very common with some encodings */
+ SpeedoErr("Can't make char %d\n", cfv->char_index);
+#endif
+ }
+ }
+
+ return Successful;
+}
diff --git a/libXfont/src/Speedo/spinfo.c b/libXfont/src/Speedo/spinfo.c
new file mode 100644
index 000000000..d7a1edd98
--- /dev/null
+++ b/libXfont/src/Speedo/spinfo.c
@@ -0,0 +1,462 @@
+/* $Xorg: spinfo.c,v 1.4 2001/02/09 02:04:00 xorgcvs Exp $ */
+/*
+ * Copyright 1990, 1991 Network Computing Devices;
+ * Portions Copyright 1987 by Digital Equipment Corporation
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and
+ * its documentation for any purpose is hereby granted without fee, provided
+ * that the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the names of Network Computing Devices or Digital
+ * not be used in advertising or publicity pertaining to distribution of
+ * the software without specific, written prior permission.
+ *
+ * NETWORK COMPUTING DEVICES AND DIGITAL DISCLAIM ALL WARRANTIES WITH
+ * REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS, IN NO EVENT SHALL NETWORK COMPUTING DEVICES OR DIGITAL BE
+ * LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Author: Dave Lemke, Network Computing Devices, Inc
+ */
+
+/*
+
+Copyright 1987, 1998 The Open Group
+
+Permission to use, copy, modify, distribute, and sell this software and its
+documentation for any purpose is hereby granted without fee, provided that
+the above copyright notice appear in all copies and that both that
+copyright notice and this permission notice appear in supporting
+documentation.
+
+The above copyright notice and this permission notice shall be included
+in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+IN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR
+OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of The Open Group shall
+not be used in advertising or otherwise to promote the sale, use or
+other dealings in this Software without prior written authorization
+from The Open Group.
+
+*/
+/* $XFree86: xc/lib/font/Speedo/spinfo.c,v 1.12 2001/12/14 19:56:42 dawes Exp $ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include <X11/fonts/fntfilst.h>
+#include <X11/fonts/fontutil.h>
+#include "spint.h"
+#ifndef FONTMODULE
+#include <math.h>
+#else
+#include "xf86_ansic.h"
+#endif
+
+/* percentage of pointsize used to specify ascent & descent */
+#define STRETCH_FACTOR 120
+
+enum scaleType {
+ atom, truncate_atom, pixel_size, point_size, resolution_x,
+ resolution_y, average_width
+};
+
+typedef struct _fontProp {
+ char *name;
+ long atom;
+ enum scaleType type;
+} fontProp;
+
+static fontProp fontNamePropTable[] = {
+ { "FOUNDRY", 0, atom },
+ { "FAMILY_NAME", 0, atom },
+ { "WEIGHT_NAME", 0, atom },
+ { "SLANT", 0, atom },
+ { "SETWIDTH_NAME", 0, atom },
+ { "ADD_STYLE_NAME", 0, atom },
+ { "PIXEL_SIZE", 0, pixel_size },
+ { "POINT_SIZE", 0, point_size },
+ { "RESOLUTION_X", 0, resolution_x },
+ { "RESOLUTION_Y", 0, resolution_y },
+ { "SPACING", 0, atom },
+ { "AVERAGE_WIDTH", 0, average_width },
+ { "CHARSET_REGISTRY", 0, atom },
+ { "CHARSET_ENCODING", 0, truncate_atom }
+};
+
+/* Warning: following array is closely related to the sequence of
+ defines after it. */
+
+static fontProp extraProps[] = {
+ { "FONT", 0, },
+ { "COPYRIGHT", 0, },
+ { "RAW_PIXEL_SIZE", 0, },
+ { "RAW_POINT_SIZE", 0, },
+ { "RAW_ASCENT", 0, },
+ { "RAW_DESCENT", 0, },
+ { "RAW_AVERAGE_WIDTH", 0, },
+ { "FONT_TYPE", 0, },
+ { "RASTERIZER_NAME", 0, }
+};
+
+/* this is a bit kludgy */
+#define FONTPROP 0
+#define COPYRIGHTPROP 1
+#define RAWPIXELPROP 2
+#define RAWPOINTPROP 3
+#define RAWASCENTPROP 4
+#define RAWDESCENTPROP 5
+#define RAWWIDTHPROP 6
+#define FONT_TYPEPROP 7
+#define RASTERIZER_NAMEPROP 8
+
+#define NNAMEPROPS (sizeof(fontNamePropTable) / sizeof(fontProp))
+#define NEXTRAPROPS (sizeof(extraProps) / sizeof(fontProp))
+
+#define NPROPS (NNAMEPROPS + NEXTRAPROPS)
+
+void
+sp_make_standard_props()
+{
+ int i;
+ fontProp *t;
+
+ i = sizeof(fontNamePropTable) / sizeof(fontProp);
+ for (t = fontNamePropTable; i; i--, t++)
+ t->atom = MakeAtom(t->name, (unsigned) strlen(t->name), TRUE);
+ i = sizeof(extraProps) / sizeof(fontProp);
+ for (t = extraProps; i; i--, t++)
+ t->atom = MakeAtom(t->name, (unsigned) strlen(t->name), TRUE);
+}
+
+void
+sp_make_header(
+ SpeedoFontPtr spf,
+ FontInfoPtr pinfo)
+{
+ int pixel_size;
+ SpeedoMasterFontPtr spmf = spf->master;
+
+ pinfo->firstCol = spmf->first_char_id & 0xff;
+ pinfo->firstRow = spmf->first_char_id >> 8;
+ pinfo->lastCol = spmf->max_id & 0xff;
+ pinfo->lastRow = spmf->max_id >> 8;
+
+ /* XXX -- hackery here */
+ pinfo->defaultCh = 0;
+/* computed by FontComputeInfoAccelerators:
+ * noOverlap
+ * constantMetrics
+ * terminalFont
+ * constantWidth
+ * inkInside
+ */
+ pinfo->inkMetrics = 0;
+ pinfo->allExist = 0;
+ pinfo->drawDirection = LeftToRight;
+ pinfo->cachable = 1;
+ if (spf->specs.xxmult != spf->specs.yymult)
+ pinfo->anamorphic = TRUE;
+ else
+ pinfo->anamorphic = FALSE;
+/* computed by sp_compute_bounds:
+ * maxOverlap
+ * maxbounds
+ * minbounds
+ * ink_maxbounds
+ * ink_minbounds
+ */
+ pixel_size = spf->vals.pixel_matrix[3] * STRETCH_FACTOR / 100;
+ pinfo->fontAscent = pixel_size * 764 / 1000; /* 764 == EM_TOP */
+ pinfo->fontDescent = pixel_size - pinfo->fontAscent;
+}
+
+static void
+adjust_min_max(
+ xCharInfo *minc,
+ xCharInfo *maxc,
+ xCharInfo *tmp)
+{
+#define MINMAX(field,ci) \
+ if (minc->field > (ci)->field) \
+ minc->field = (ci)->field; \
+ if (maxc->field < (ci)->field) \
+ maxc->field = (ci)->field;
+
+ MINMAX(ascent, tmp);
+ MINMAX(descent, tmp);
+ MINMAX(leftSideBearing, tmp);
+ MINMAX(rightSideBearing, tmp);
+ MINMAX(characterWidth, tmp);
+
+ if ((INT16)minc->attributes > (INT16)tmp->attributes)
+ minc->attributes = tmp->attributes;
+ if ((INT16)maxc->attributes < (INT16)tmp->attributes)
+ maxc->attributes = tmp->attributes;
+
+#undef MINMAX
+}
+
+
+void
+sp_compute_bounds(
+ SpeedoFontPtr spf,
+ FontInfoPtr pinfo,
+ unsigned long flags,
+ long *sWidth)
+{
+ int i,
+ id,
+ index,
+ maxOverlap,
+ overlap,
+ total_width = 0;
+ xCharInfo minchar,
+ maxchar,
+ tmpchar;
+ bbox_t bbox;
+ fix31 width;
+ double pix_width;
+ SpeedoMasterFontPtr spmf = spf->master;
+ int firstChar;
+ int num_chars = 0;
+
+ firstChar = spmf->first_char_id;
+ minchar.ascent = minchar.descent =
+ minchar.leftSideBearing = minchar.rightSideBearing =
+ minchar.characterWidth = minchar.attributes = 32767;
+ maxchar.ascent = maxchar.descent =
+ maxchar.leftSideBearing = maxchar.rightSideBearing =
+ maxchar.characterWidth = maxchar.attributes = -32767;
+ maxOverlap = -32767;
+ *sWidth = 0;
+ for (i = 0; i < spmf->num_chars; i++) {
+ int j;
+ int char_id;
+
+ index = spmf->enc[i * 2 + 1];
+ char_id = spmf->enc[i * 2];
+ /*
+ * See if this character is in the list of ranges specified in the
+ * XLFD name
+ */
+ for (j = 0; j < spf->vals.nranges; j++)
+ if (char_id >= mincharno(spf->vals.ranges[j]) &&
+ char_id <= maxcharno(spf->vals.ranges[j]))
+ break;
+ if (spf->vals.nranges && j == spf->vals.nranges)
+ continue;
+ num_chars++;
+
+ if (!(flags & ComputeBoundsOnly)) {
+
+ width = sp_get_char_width(index);
+
+ /* convert to pixel coords */
+ pix_width = (int)width * (spf->specs.xxmult / 65536L) +
+ ((int) width * (spf->specs.xxmult % 65536L))
+ / 65536L;
+ pix_width /= 65536L;
+
+ (void) sp_get_char_bbox(index, &bbox);
+ bbox.ymax = (bbox.ymax + 32768L) >> 16;
+ bbox.ymin = (bbox.ymin + 32768L) >> 16;
+ bbox.xmin = (bbox.xmin + 32768L) >> 16;
+ bbox.xmax = (bbox.xmax + 32768L) >> 16;
+ tmpchar.ascent = bbox.ymax;
+ tmpchar.descent = -bbox.ymin;
+ tmpchar.characterWidth = (int)(pix_width + /* round */
+ (pix_width > 0 ? 0.5 : -0.5));
+ tmpchar.rightSideBearing = bbox.xmax;
+ tmpchar.leftSideBearing = bbox.xmin;
+
+ if (!tmpchar.characterWidth &&
+ tmpchar.ascent == -tmpchar.descent &&
+ tmpchar.rightSideBearing == tmpchar.leftSideBearing)
+ {
+ /* Character appears non-existent, probably as a result
+ of the transformation. Let's give it one pixel in
+ the universe so it's not mistaken for non-existent. */
+ tmpchar.leftSideBearing = tmpchar.descent = 0;
+ tmpchar.rightSideBearing = tmpchar.ascent = 1;
+ }
+
+ tmpchar.attributes = (int)((double)(int)width / 65.536 + .5);
+ }
+ else
+ tmpchar = spf->encoding[char_id - firstChar].metrics;
+
+ adjust_min_max(&minchar, &maxchar, &tmpchar);
+ overlap = tmpchar.rightSideBearing - tmpchar.characterWidth;
+ if (maxOverlap < overlap)
+ maxOverlap = overlap;
+
+ total_width += ((int)(INT16)tmpchar.attributes);
+ *sWidth += abs((int)(INT16)tmpchar.attributes);
+
+ if (flags & SaveMetrics) {
+ id = spmf->enc[i * 2] - firstChar;
+ assert(id <= spmf->max_id - firstChar);
+ spf->encoding[id].metrics = tmpchar;
+ }
+ }
+
+
+ if (num_chars > 0)
+ {
+ *sWidth = (int)(((double)*sWidth * 10.0 + (double)num_chars / 2.0) /
+ num_chars);
+ if (total_width < 0)
+ {
+ /* Predominant direction is R->L */
+ *sWidth = -*sWidth;
+ }
+ spf->vals.width = (int)((double)*sWidth * spf->vals.pixel_matrix[0] /
+ 1000.0 +
+ (spf->vals.pixel_matrix[0] > 0 ? .5 : -.5));
+ }
+ else
+ {
+ spf->vals.width = 0;
+ }
+ pinfo->maxbounds = maxchar;
+ pinfo->minbounds = minchar;
+ pinfo->ink_maxbounds = maxchar;
+ pinfo->ink_minbounds = minchar;
+ pinfo->maxOverlap = maxOverlap;
+}
+
+void
+sp_compute_props(
+ SpeedoFontPtr spf,
+ char *fontname,
+ FontInfoPtr pinfo,
+ long sWidth)
+{
+ FontPropPtr pp;
+ int i,
+ nprops;
+ fontProp *fpt;
+ char *is_str;
+ char *ptr1 = NULL,
+ *ptr2;
+ char *ptr3;
+ char tmpname[1024];
+ FontScalableRec tmpvals;
+
+ nprops = pinfo->nprops = NPROPS;
+ pinfo->isStringProp = (char *) xalloc(sizeof(char) * nprops);
+ pinfo->props = (FontPropPtr) xalloc(sizeof(FontPropRec) * nprops);
+ if (!pinfo->isStringProp || !pinfo->props) {
+ xfree(pinfo->isStringProp);
+ pinfo->isStringProp = (char *) 0;
+ xfree(pinfo->props);
+ pinfo->props = (FontPropPtr) 0;
+ pinfo->nprops = 0;
+ return;
+ }
+ bzero(pinfo->isStringProp, (sizeof(char) * nprops));
+
+ ptr2 = fontname;
+ for (i = NNAMEPROPS, pp = pinfo->props, fpt = fontNamePropTable,
+ is_str = pinfo->isStringProp;
+ i;
+ i--, pp++, fpt++, is_str++) {
+
+ if (*ptr2)
+ {
+ ptr1 = ptr2 + 1;
+ if (!(ptr2 = strchr(ptr1, '-'))) ptr2 = strchr(ptr1, '\0');
+ }
+
+ pp->name = fpt->atom;
+ switch (fpt->type) {
+ case atom:
+ *is_str = TRUE;
+ pp->value = MakeAtom(ptr1, ptr2 - ptr1, TRUE);
+ break;
+ case truncate_atom:
+ *is_str = TRUE;
+ for (ptr3 = ptr1; *ptr3; ptr3++)
+ if (*ptr3 == '[')
+ break;
+ pp->value = MakeAtom(ptr1, ptr3 - ptr1, TRUE);
+ break;
+ case pixel_size:
+ pp->value = (int)(spf->vals.pixel_matrix[3] +
+ (spf->vals.pixel_matrix[3] > 0 ? .5 : -.5));
+ break;
+ case point_size:
+ pp->value = (int)(spf->vals.point_matrix[3] * 10.0 +
+ (spf->vals.point_matrix[3] > 0 ? .5 : -.5));
+ break;
+ case resolution_x:
+ pp->value = spf->vals.x;
+ break;
+ case resolution_y:
+ pp->value = spf->vals.y;
+ break;
+ case average_width:
+ pp->value = spf->vals.width;
+ break;
+ }
+ }
+
+ for (i = 0, fpt = extraProps; i < NEXTRAPROPS; i++, is_str++, pp++, fpt++) {
+ pp->name = fpt->atom;
+ switch (i) {
+ case FONTPROP:
+ *is_str = TRUE;
+ strcpy(tmpname, fontname);
+ FontParseXLFDName(tmpname, &tmpvals, FONT_XLFD_REPLACE_ZERO);
+ FontParseXLFDName(tmpname, &spf->vals, FONT_XLFD_REPLACE_VALUE);
+ pp->value = MakeAtom(tmpname, strlen(tmpname), TRUE);
+ break;
+ case COPYRIGHTPROP:
+ *is_str = TRUE;
+ pp->value = MakeAtom(spf->master->copyright,
+ strlen(spf->master->copyright), TRUE);
+ break;
+ case FONT_TYPEPROP:
+ *is_str = TRUE;
+ pp->value = MakeAtom("Speedo", strlen("Speedo"), TRUE);
+ break;
+ case RASTERIZER_NAMEPROP:
+ *is_str = TRUE;
+ pp->value = MakeAtom("X Consortium Speedo Rasterizer",
+ strlen("X Consortium Speedo Rasterizer"),
+ TRUE);
+ break;
+ case RAWPIXELPROP:
+ *is_str = FALSE;
+ pp->value = 1000;
+ break;
+ case RAWPOINTPROP:
+ *is_str = FALSE;
+ pp->value = (long)(72270.0 / (double)spf->vals.y + .5);
+ break;
+ case RAWASCENTPROP:
+ *is_str = FALSE;
+ pp->value = STRETCH_FACTOR * 764 / 100;
+ break;
+ case RAWDESCENTPROP:
+ *is_str = FALSE;
+ pp->value = STRETCH_FACTOR * 236 / 100;
+ break;
+ case RAWWIDTHPROP:
+ *is_str = FALSE;
+ pp->value = sWidth;
+ break;
+ }
+ }
+}
diff --git a/libXfont/src/Speedo/spint.h b/libXfont/src/Speedo/spint.h
new file mode 100644
index 000000000..299882c96
--- /dev/null
+++ b/libXfont/src/Speedo/spint.h
@@ -0,0 +1,178 @@
+/* $Xorg: spint.h,v 1.4 2001/02/09 02:04:00 xorgcvs Exp $ */
+/*
+ * Copyright 1990, 1991 Network Computing Devices;
+ * Portions Copyright 1987 by Digital Equipment Corporation
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and
+ * its documentation for any purpose is hereby granted without fee, provided
+ * that the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the names of Network Computing Devices or Digital
+ * not be used in advertising or publicity pertaining to distribution of
+ * the software without specific, written prior permission.
+ *
+ * NETWORK COMPUTING DEVICES AND DIGITAL DISCLAIM ALL WARRANTIES WITH
+ * REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS, IN NO EVENT SHALL NETWORK COMPUTING DEVICES OR DIGITAL BE
+ * LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/*
+
+Copyright 1987, 1998 The Open Group
+
+Permission to use, copy, modify, distribute, and sell this software and its
+documentation for any purpose is hereby granted without fee, provided that
+the above copyright notice appear in all copies and that both that
+copyright notice and this permission notice appear in supporting
+documentation.
+
+The above copyright notice and this permission notice shall be included
+in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+IN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR
+OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of The Open Group shall
+not be used in advertising or otherwise to promote the sale, use or
+other dealings in this Software without prior written authorization
+from The Open Group.
+
+*/
+/* $XFree86: xc/lib/font/Speedo/spint.h,v 1.9 2001/01/17 19:43:20 dawes Exp $ */
+
+#ifndef _SPINT_H_
+#define _SPINT_H_
+
+#include <X11/fonts/fntfilst.h>
+#ifndef XFree86LOADER
+#include <stdio.h>
+#else
+#include <xf86_ansic.h>
+#endif
+#include <X11/Xfuncproto.h>
+#include "speedo.h"
+
+#define SaveMetrics 0x1
+#define ComputeBoundsOnly 0x2
+
+#define GLWIDTHBYTESPADDED(bits,nbytes) \
+ ((nbytes) == 1 ? (((bits)+7)>>3) /* pad to 1 byte */ \
+ :(nbytes) == 2 ? ((((bits)+15)>>3)&~1) /* pad to 2 bytes */ \
+ :(nbytes) == 4 ? ((((bits)+31)>>3)&~3) /* pad to 4 bytes */ \
+ :(nbytes) == 8 ? ((((bits)+63)>>3)&~7) /* pad to 8 bytes */ \
+ : 0)
+
+#define GLYPH_SIZE(ch, nbytes) \
+ GLWIDTHBYTESPADDED((ch)->metrics.rightSideBearing - \
+ (ch)->metrics.leftSideBearing, (nbytes))
+
+#define mincharno(p) ((p).min_char_low + ((p).min_char_high << 8))
+#define maxcharno(p) ((p).max_char_low + ((p).max_char_high << 8))
+
+#define MasterFileOpen 0x1
+
+typedef struct _sp_master {
+ FontEntryPtr entry; /* back pointer */
+ FILE *fp;
+ char *fname;
+ ufix8 *f_buffer;
+ ufix8 *c_buffer;
+ char *copyright;
+ ufix8 *key;
+ buff_t font;
+ buff_t char_data;
+ ufix16 mincharsize;
+ int first_char_id;
+ int num_chars;
+ int max_id;
+ int state; /* open, closed */
+ int refcount; /* number of instances */
+ int *enc;
+ int enc_size;
+} SpeedoMasterFontRec, *SpeedoMasterFontPtr;
+
+typedef struct _cur_font_stats {
+ fsBitmapFormat format;
+ /* current glyph info */
+ ufix16 char_index;
+ ufix16 char_id;
+
+ fix15 bit_width,
+ bit_height;
+ fix15 cur_y;
+ int bpr;
+
+ /*
+ * since Speedo returns extents that are not identical to what it feeds to
+ * the bitmap builder, and we want to be able to use the extents for
+ * preformance reasons, some of the bitmaps require padding out. the next
+ * two flags keep track of this.
+ */
+ fix15 last_y;
+ int trunc;
+
+ pointer bp;
+ int scanpad;
+} CurrentFontValuesRec, *CurrentFontValuesPtr;
+
+
+typedef struct _sp_font {
+ struct _sp_master *master;
+ specs_t specs;
+
+ FontEntryPtr entry;
+
+ FontScalableRec vals;
+
+ /* char & metric data */
+ CharInfoPtr encoding;
+ CharInfoPtr pDefault;
+ pointer bitmaps;
+
+#ifdef DEBUG
+ unsigned long bitmap_size;
+#endif
+
+} SpeedoFontRec, *SpeedoFontPtr;
+
+extern SpeedoFontPtr sp_fp_cur;
+
+extern int sp_open_font(char *, char *, FontEntryPtr, FontScalablePtr,
+ fsBitmapFormat, fsBitmapFormatMask, Mask,
+ SpeedoFontPtr *);
+extern int sp_open_master(const char *, const char *, SpeedoMasterFontPtr *);
+extern void sp_close_font(SpeedoFontPtr);
+extern void sp_close_master_font(SpeedoMasterFontPtr);
+extern void sp_close_master_file(SpeedoMasterFontPtr);
+extern void sp_reset_master(SpeedoMasterFontPtr);
+extern void SpeedoErr(char *fmt, ...);
+
+extern void sp_make_standard_props(void);
+extern void sp_make_header(SpeedoFontPtr, FontInfoPtr);
+extern void sp_compute_bounds(SpeedoFontPtr, FontInfoPtr, unsigned long, long *);
+extern void sp_compute_props(SpeedoFontPtr, char *, FontInfoPtr, long);
+extern int sp_build_all_bitmaps(FontPtr, fsBitmapFormat, fsBitmapFormatMask);
+
+extern int SpeedoFontLoad(FontPtr *, char *, char *, FontEntryPtr,
+ FontScalablePtr, fsBitmapFormat, fsBitmapFormatMask,
+ Mask);
+
+extern int sp_bics_map[];
+extern int sp_bics_map_size;
+
+#ifdef EXTRAFONTS
+extern int adobe_map[];
+extern int adobe_map_size;
+
+#endif
+
+#endif /* _SPINT_H_ */
diff --git a/libXfont/src/Speedo/useropt.h b/libXfont/src/Speedo/useropt.h
new file mode 100644
index 000000000..e879aae96
--- /dev/null
+++ b/libXfont/src/Speedo/useropt.h
@@ -0,0 +1,41 @@
+/* $Xorg: useropt.h,v 1.4 2001/02/09 02:04:00 xorgcvs Exp $ */
+/*
+
+Copyright 1993, 1994, 1998 The Open Group
+
+Permission to use, copy, modify, distribute, and sell this software and its
+documentation for any purpose is hereby granted without fee, provided that
+the above copyright notice appear in all copies and that both that
+copyright notice and this permission notice appear in supporting
+documentation.
+
+The above copyright notice and this permission notice shall be included
+in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+IN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR
+OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of The Open Group shall
+not be used in advertising or otherwise to promote the sale, use or
+other dealings in this Software without prior written authorization
+from The Open Group.
+
+*/
+
+#define INCL_LCD 1
+#define STATIC_ALLOC 1
+
+#define INCL_BLACK 1
+#define INCL_SCREEN 1
+#define INCL_2D 1
+#define SHORT_LISTS 0
+
+#define INCL_RULES 1
+#define INCL_METRICS 1
+
+#define INCL_KEYS 1
diff --git a/libXfont/src/Type1/Makefile.am b/libXfont/src/Type1/Makefile.am
new file mode 100644
index 000000000..cf5eb7d4f
--- /dev/null
+++ b/libXfont/src/Type1/Makefile.am
@@ -0,0 +1,52 @@
+INCLUDES = \
+ -I${top_srcdir}/include
+
+AM_CFLAGS = $(XFONT_CFLAGS) $(OS_CFLAGS) $(CWARNFLAGS)
+
+noinst_LTLIBRARIES = libtype1.la
+
+libtype1_la_SOURCES = \
+ arith.c \
+ arith.h \
+ blues.h \
+ cluts.h \
+ curves.c \
+ curves.h \
+ digit.h \
+ fontfcn.c \
+ fontfcn.h \
+ fonts.h \
+ hdigit.h \
+ hints.c \
+ hints.h \
+ lines.c \
+ lines.h \
+ objects.c \
+ objects.h \
+ paths.c \
+ paths.h \
+ pictures.h \
+ regions.c \
+ regions.h \
+ scanfont.c \
+ spaces.c \
+ spaces.h \
+ strokes.h \
+ t1funcs.c \
+ t1hdigit.h \
+ t1imager.h \
+ t1info.c \
+ t1intf.h \
+ t1io.c \
+ t1malloc.c \
+ t1snap.c \
+ t1stdio.h \
+ t1unicode.c \
+ t1unicode.h \
+ token.c \
+ token.h \
+ tokst.h \
+ trig.h \
+ type1.c \
+ util.c \
+ util.h
diff --git a/libXfont/src/Type1/Makefile.in b/libXfont/src/Type1/Makefile.in
new file mode 100644
index 000000000..c4da78f47
--- /dev/null
+++ b/libXfont/src/Type1/Makefile.in
@@ -0,0 +1,516 @@
+# Makefile.in generated by automake 1.10 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
+# 2003, 2004, 2005, 2006 Free Software Foundation, Inc.
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+@SET_MAKE@
+
+VPATH = @srcdir@
+pkgdatadir = $(datadir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+install_sh_DATA = $(install_sh) -c -m 644
+install_sh_PROGRAM = $(install_sh) -c
+install_sh_SCRIPT = $(install_sh) -c
+INSTALL_HEADER = $(INSTALL_DATA)
+transform = $(program_transform_name)
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+build_triplet = @build@
+host_triplet = @host@
+subdir = src/Type1
+DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/configure.ac
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+ $(ACLOCAL_M4)
+mkinstalldirs = $(install_sh) -d
+CONFIG_HEADER = $(top_builddir)/config.h \
+ $(top_builddir)/include/X11/fonts/fontconf.h
+CONFIG_CLEAN_FILES =
+LTLIBRARIES = $(noinst_LTLIBRARIES)
+libtype1_la_LIBADD =
+am_libtype1_la_OBJECTS = arith.lo curves.lo fontfcn.lo hints.lo \
+ lines.lo objects.lo paths.lo regions.lo scanfont.lo spaces.lo \
+ t1funcs.lo t1info.lo t1io.lo t1malloc.lo t1snap.lo \
+ t1unicode.lo token.lo type1.lo util.lo
+libtype1_la_OBJECTS = $(am_libtype1_la_OBJECTS)
+DEFAULT_INCLUDES = -I. -I$(top_builddir) -I$(top_builddir)/include/X11/fonts@am__isrc@
+depcomp = $(SHELL) $(top_srcdir)/depcomp
+am__depfiles_maybe = depfiles
+COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
+ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+LTCOMPILE = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
+ --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \
+ $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+CCLD = $(CC)
+LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
+ --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \
+ $(LDFLAGS) -o $@
+SOURCES = $(libtype1_la_SOURCES)
+DIST_SOURCES = $(libtype1_la_SOURCES)
+ETAGS = etags
+CTAGS = ctags
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+ACLOCAL = @ACLOCAL@
+AMTAR = @AMTAR@
+AR = @AR@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+CC = @CC@
+CCDEPMODE = @CCDEPMODE@
+CFLAGS = @CFLAGS@
+CHANGELOG_CMD = @CHANGELOG_CMD@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CWARNFLAGS = @CWARNFLAGS@
+CXX = @CXX@
+CXXCPP = @CXXCPP@
+CXXDEPMODE = @CXXDEPMODE@
+CXXFLAGS = @CXXFLAGS@
+CYGPATH_W = @CYGPATH_W@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+ECHO = @ECHO@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+EGREP = @EGREP@
+ENCODINGSDIR = @ENCODINGSDIR@
+EXEEXT = @EXEEXT@
+F77 = @F77@
+FFLAGS = @FFLAGS@
+FREETYPE_CFLAGS = @FREETYPE_CFLAGS@
+FREETYPE_LIBS = @FREETYPE_LIBS@
+FREETYPE_REQUIRES = @FREETYPE_REQUIRES@
+GREP = @GREP@
+INSTALL = @INSTALL@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+LDFLAGS = @LDFLAGS@
+LIBOBJS = @LIBOBJS@
+LIBS = @LIBS@
+LIBTOOL = @LIBTOOL@
+LN_S = @LN_S@
+LTLIBOBJS = @LTLIBOBJS@
+MAKEINFO = @MAKEINFO@
+MATH_LIBS = @MATH_LIBS@
+MKDIR_P = @MKDIR_P@
+OBJEXT = @OBJEXT@
+OS_CFLAGS = @OS_CFLAGS@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+PKG_CONFIG = @PKG_CONFIG@
+RANLIB = @RANLIB@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+STRIP = @STRIP@
+VERSION = @VERSION@
+XFONT_CFLAGS = @XFONT_CFLAGS@
+XFONT_LIBS = @XFONT_LIBS@
+X_GZIP_FONT_COMPRESSION = @X_GZIP_FONT_COMPRESSION@
+Z_LIBS = @Z_LIBS@
+abs_builddir = @abs_builddir@
+abs_srcdir = @abs_srcdir@
+abs_top_builddir = @abs_top_builddir@
+abs_top_srcdir = @abs_top_srcdir@
+ac_ct_CC = @ac_ct_CC@
+ac_ct_CXX = @ac_ct_CXX@
+ac_ct_F77 = @ac_ct_F77@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+am__tar = @am__tar@
+am__untar = @am__untar@
+bindir = @bindir@
+build = @build@
+build_alias = @build_alias@
+build_cpu = @build_cpu@
+build_os = @build_os@
+build_vendor = @build_vendor@
+builddir = @builddir@
+datadir = @datadir@
+datarootdir = @datarootdir@
+distcleancheck_listfiles = @distcleancheck_listfiles@
+docdir = @docdir@
+dvidir = @dvidir@
+exec_prefix = @exec_prefix@
+ft_config = @ft_config@
+host = @host@
+host_alias = @host_alias@
+host_cpu = @host_cpu@
+host_os = @host_os@
+host_vendor = @host_vendor@
+htmldir = @htmldir@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+libdir = @libdir@
+libexecdir = @libexecdir@
+localedir = @localedir@
+localstatedir = @localstatedir@
+mandir = @mandir@
+mkdir_p = @mkdir_p@
+oldincludedir = @oldincludedir@
+pdfdir = @pdfdir@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+psdir = @psdir@
+sbindir = @sbindir@
+sharedstatedir = @sharedstatedir@
+srcdir = @srcdir@
+sysconfdir = @sysconfdir@
+target_alias = @target_alias@
+top_builddir = @top_builddir@
+top_srcdir = @top_srcdir@
+INCLUDES = \
+ -I${top_srcdir}/include
+
+AM_CFLAGS = $(XFONT_CFLAGS) $(OS_CFLAGS) $(CWARNFLAGS)
+noinst_LTLIBRARIES = libtype1.la
+libtype1_la_SOURCES = \
+ arith.c \
+ arith.h \
+ blues.h \
+ cluts.h \
+ curves.c \
+ curves.h \
+ digit.h \
+ fontfcn.c \
+ fontfcn.h \
+ fonts.h \
+ hdigit.h \
+ hints.c \
+ hints.h \
+ lines.c \
+ lines.h \
+ objects.c \
+ objects.h \
+ paths.c \
+ paths.h \
+ pictures.h \
+ regions.c \
+ regions.h \
+ scanfont.c \
+ spaces.c \
+ spaces.h \
+ strokes.h \
+ t1funcs.c \
+ t1hdigit.h \
+ t1imager.h \
+ t1info.c \
+ t1intf.h \
+ t1io.c \
+ t1malloc.c \
+ t1snap.c \
+ t1stdio.h \
+ t1unicode.c \
+ t1unicode.h \
+ token.c \
+ token.h \
+ tokst.h \
+ trig.h \
+ type1.c \
+ util.c \
+ util.h
+
+all: all-am
+
+.SUFFIXES:
+.SUFFIXES: .c .lo .o .obj
+$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps)
+ @for dep in $?; do \
+ case '$(am__configure_deps)' in \
+ *$$dep*) \
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh \
+ && exit 0; \
+ exit 1;; \
+ esac; \
+ done; \
+ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign src/Type1/Makefile'; \
+ cd $(top_srcdir) && \
+ $(AUTOMAKE) --foreign src/Type1/Makefile
+.PRECIOUS: Makefile
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+ @case '$?' in \
+ *config.status*) \
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
+ *) \
+ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
+ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
+ esac;
+
+$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+
+$(top_srcdir)/configure: $(am__configure_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(ACLOCAL_M4): $(am__aclocal_m4_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+
+clean-noinstLTLIBRARIES:
+ -test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES)
+ @list='$(noinst_LTLIBRARIES)'; for p in $$list; do \
+ dir="`echo $$p | sed -e 's|/[^/]*$$||'`"; \
+ test "$$dir" != "$$p" || dir=.; \
+ echo "rm -f \"$${dir}/so_locations\""; \
+ rm -f "$${dir}/so_locations"; \
+ done
+libtype1.la: $(libtype1_la_OBJECTS) $(libtype1_la_DEPENDENCIES)
+ $(LINK) $(libtype1_la_OBJECTS) $(libtype1_la_LIBADD) $(LIBS)
+
+mostlyclean-compile:
+ -rm -f *.$(OBJEXT)
+
+distclean-compile:
+ -rm -f *.tab.c
+
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/arith.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/curves.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fontfcn.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/hints.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/lines.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/objects.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/paths.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/regions.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/scanfont.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/spaces.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/t1funcs.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/t1info.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/t1io.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/t1malloc.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/t1snap.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/t1unicode.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/token.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/type1.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/util.Plo@am__quote@
+
+.c.o:
+@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
+@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(COMPILE) -c $<
+
+.c.obj:
+@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'`
+@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(COMPILE) -c `$(CYGPATH_W) '$<'`
+
+.c.lo:
+@am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
+@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(LTCOMPILE) -c -o $@ $<
+
+mostlyclean-libtool:
+ -rm -f *.lo
+
+clean-libtool:
+ -rm -rf .libs _libs
+
+ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) ' { files[$$0] = 1; } \
+ END { for (i in files) print i; }'`; \
+ mkid -fID $$unique
+tags: TAGS
+
+TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
+ $(TAGS_FILES) $(LISP)
+ tags=; \
+ here=`pwd`; \
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) ' { files[$$0] = 1; } \
+ END { for (i in files) print i; }'`; \
+ if test -z "$(ETAGS_ARGS)$$tags$$unique"; then :; else \
+ test -n "$$unique" || unique=$$empty_fix; \
+ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+ $$tags $$unique; \
+ fi
+ctags: CTAGS
+CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
+ $(TAGS_FILES) $(LISP)
+ tags=; \
+ here=`pwd`; \
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) ' { files[$$0] = 1; } \
+ END { for (i in files) print i; }'`; \
+ test -z "$(CTAGS_ARGS)$$tags$$unique" \
+ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
+ $$tags $$unique
+
+GTAGS:
+ here=`$(am__cd) $(top_builddir) && pwd` \
+ && cd $(top_srcdir) \
+ && gtags -i $(GTAGS_ARGS) $$here
+
+distclean-tags:
+ -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
+
+distdir: $(DISTFILES)
+ @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ list='$(DISTFILES)'; \
+ dist_files=`for file in $$list; do echo $$file; done | \
+ sed -e "s|^$$srcdirstrip/||;t" \
+ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
+ case $$dist_files in \
+ */*) $(MKDIR_P) `echo "$$dist_files" | \
+ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
+ sort -u` ;; \
+ esac; \
+ for file in $$dist_files; do \
+ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
+ if test -d $$d/$$file; then \
+ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
+ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
+ cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \
+ fi; \
+ cp -pR $$d/$$file $(distdir)$$dir || exit 1; \
+ else \
+ test -f $(distdir)/$$file \
+ || cp -p $$d/$$file $(distdir)/$$file \
+ || exit 1; \
+ fi; \
+ done
+check-am: all-am
+check: check-am
+all-am: Makefile $(LTLIBRARIES)
+installdirs:
+install: install-am
+install-exec: install-exec-am
+install-data: install-data-am
+uninstall: uninstall-am
+
+install-am: all-am
+ @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-am
+install-strip:
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ `test -z '$(STRIP)' || \
+ echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
+mostlyclean-generic:
+
+clean-generic:
+
+distclean-generic:
+ -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
+
+maintainer-clean-generic:
+ @echo "This command is intended for maintainers to use"
+ @echo "it deletes files that may require special tools to rebuild."
+clean: clean-am
+
+clean-am: clean-generic clean-libtool clean-noinstLTLIBRARIES \
+ mostlyclean-am
+
+distclean: distclean-am
+ -rm -rf ./$(DEPDIR)
+ -rm -f Makefile
+distclean-am: clean-am distclean-compile distclean-generic \
+ distclean-tags
+
+dvi: dvi-am
+
+dvi-am:
+
+html: html-am
+
+info: info-am
+
+info-am:
+
+install-data-am:
+
+install-dvi: install-dvi-am
+
+install-exec-am:
+
+install-html: install-html-am
+
+install-info: install-info-am
+
+install-man:
+
+install-pdf: install-pdf-am
+
+install-ps: install-ps-am
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-am
+ -rm -rf ./$(DEPDIR)
+ -rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-am
+
+mostlyclean-am: mostlyclean-compile mostlyclean-generic \
+ mostlyclean-libtool
+
+pdf: pdf-am
+
+pdf-am:
+
+ps: ps-am
+
+ps-am:
+
+uninstall-am:
+
+.MAKE: install-am install-strip
+
+.PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \
+ clean-libtool clean-noinstLTLIBRARIES ctags distclean \
+ distclean-compile distclean-generic distclean-libtool \
+ distclean-tags distdir dvi dvi-am html html-am info info-am \
+ install install-am install-data install-data-am install-dvi \
+ install-dvi-am install-exec install-exec-am install-html \
+ install-html-am install-info install-info-am install-man \
+ install-pdf install-pdf-am install-ps install-ps-am \
+ install-strip installcheck installcheck-am installdirs \
+ maintainer-clean maintainer-clean-generic mostlyclean \
+ mostlyclean-compile mostlyclean-generic mostlyclean-libtool \
+ pdf pdf-am ps ps-am tags uninstall uninstall-am
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/libXfont/src/Type1/arith.c b/libXfont/src/Type1/arith.c
new file mode 100644
index 000000000..92a372a17
--- /dev/null
+++ b/libXfont/src/Type1/arith.c
@@ -0,0 +1,212 @@
+/* $Xorg: arith.c,v 1.3 2000/08/17 19:46:29 cpqbld Exp $ */
+/* Copyright International Business Machines, Corp. 1991
+ * All Rights Reserved
+ * Copyright Lexmark International, Inc. 1991
+ * All Rights Reserved
+ *
+ * License to use, copy, modify, and distribute this software and its
+ * documentation for any purpose and without fee is hereby granted,
+ * provided that the above copyright notice appear in all copies and that
+ * both that copyright notice and this permission notice appear in
+ * supporting documentation, and that the name of IBM or Lexmark not be
+ * used in advertising or publicity pertaining to distribution of the
+ * software without specific, written prior permission.
+ *
+ * IBM AND LEXMARK PROVIDE THIS SOFTWARE "AS IS", WITHOUT ANY WARRANTIES OF
+ * ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING, BUT NOT LIMITED TO ANY
+ * IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE,
+ * AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. THE ENTIRE RISK AS TO THE
+ * QUALITY AND PERFORMANCE OF THE SOFTWARE, INCLUDING ANY DUTY TO SUPPORT
+ * OR MAINTAIN, BELONGS TO THE LICENSEE. SHOULD ANY PORTION OF THE
+ * SOFTWARE PROVE DEFECTIVE, THE LICENSEE (NOT IBM OR LEXMARK) ASSUMES THE
+ * ENTIRE COST OF ALL SERVICING, REPAIR AND CORRECTION. IN NO EVENT SHALL
+ * IBM OR LEXMARK BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
+ * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
+ * THIS SOFTWARE.
+ */
+/* $XFree86: xc/lib/font/Type1/arith.c,v 1.6tsi Exp $ */
+
+ /* ARITH CWEB V0006 ******** */
+/*
+:h1.ARITH Module - Portable Module for Multiple Precision Fixed Point Arithmetic
+
+This module provides division and multiplication of 64-bit fixed point
+numbers. (To be more precise, the module works on numbers that take
+two 'longs' to store. That is almost always equivalent to saying 64-bit
+numbers.)
+
+Note: it is frequently easy and desirable to recode these functions in
+assembly language for the particular processor being used, because
+assembly language, unlike C, will have 64-bit multiply products and
+64-bit dividends. This module is offered as a portable version.
+
+&author. Jeffrey B. Lotspiech (lotspiech@almaden.ibm.com) and Sten F. Andler
+
+
+:h3.Include Files
+
+The included files are:
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#ifdef FONTMODULE
+# include "os.h"
+#endif
+#include "objects.h"
+#include "spaces.h"
+#include "arith.h"
+
+
+/*
+:h3.
+*/
+/*SHARED LINE(S) ORIGINATED HERE*/
+/*
+Reference for all algorithms: Donald E. Knuth, "The Art of Computer
+Programming, Volume 2, Semi-Numerical Algorithms," Addison-Wesley Co.,
+Massachusetts, 1969, pp. 229-279.
+
+Knuth talks about a 'digit' being an arbitrary sized unit and a number
+being a sequence of digits. We'll take a digit to be a 'short'.
+The following assumption must be valid for these algorithms to work:
+:ol.
+:li.A 'long' is two 'short's.
+:eol.
+The following code is INDEPENDENT of:
+:ol.
+:li.The actual size of a short.
+:li.Whether shorts and longs are stored most significant byte
+first or least significant byte first.
+:eol.
+
+SHORTSIZE is the number of bits in a short; LONGSIZE is the number of
+bits in a long; MAXSHORT is the maximum unsigned short:
+*/
+/*SHARED LINE(S) ORIGINATED HERE*/
+/*
+ASSEMBLE concatenates two shorts to form a long:
+*/
+#define ASSEMBLE(hi,lo) ((((unsigned long)hi)<<SHORTSIZE)+(lo))
+/*
+HIGHDIGIT extracts the most significant short from a long; LOWDIGIT
+extracts the least significant short from a long:
+*/
+#define HIGHDIGIT(u) ((u)>>SHORTSIZE)
+#define LOWDIGIT(u) ((u)&MAXSHORT)
+
+/*
+SIGNBITON tests the high order bit of a long 'w':
+*/
+#define SIGNBITON(w) (((long)w)<0)
+
+/*SHARED LINE(S) ORIGINATED HERE*/
+
+/*
+:h2.Double Long Arithmetic
+
+:h3.DLmult() - Multiply Two Longs to Yield a Double Long
+
+The two multiplicands must be positive.
+*/
+
+static void
+DLmult(doublelong *product, unsigned long u, unsigned long v)
+{
+#ifdef LONG64
+/* printf("DLmult(? ?, %lx, %lx)\n", u, v); */
+ *product = u*v;
+/* printf("DLmult returns %lx\n", *product); */
+#else
+ register unsigned long u1, u2; /* the digits of u */
+ register unsigned long v1, v2; /* the digits of v */
+ register unsigned int w1, w2, w3, w4; /* the digits of w */
+ register unsigned long t; /* temporary variable */
+/* printf("DLmult(? ?, %x, %x)\n", u, v); */
+ u1 = HIGHDIGIT(u);
+ u2 = LOWDIGIT(u);
+ v1 = HIGHDIGIT(v);
+ v2 = LOWDIGIT(v);
+
+ if (v2 == 0) w4 = w3 = w2 = 0;
+ else
+ {
+ t = u2 * v2;
+ w4 = LOWDIGIT(t);
+ t = u1 * v2 + HIGHDIGIT(t);
+ w3 = LOWDIGIT(t);
+ w2 = HIGHDIGIT(t);
+ }
+
+ if (v1 == 0) w1 = 0;
+ else
+ {
+ t = u2 * v1 + w3;
+ w3 = LOWDIGIT(t);
+ t = u1 * v1 + w2 + HIGHDIGIT(t);
+ w2 = LOWDIGIT(t);
+ w1 = HIGHDIGIT(t);
+ }
+
+ product->high = ASSEMBLE(w1, w2);
+ product->low = ASSEMBLE(w3, w4);
+#endif /* LONG64 else */
+}
+
+/*
+:h3.DLrightshift() - Macro to Shift Double Long Right by N
+*/
+
+/*SHARED LINE(S) ORIGINATED HERE*/
+
+/*
+:h2.Fractional Pel Arithmetic
+*/
+/*
+:h3.FPmult() - Multiply Two Fractional Pel Values
+
+This funtion first calculates w = u * v to "doublelong" precision.
+It then shifts w right by FRACTBITS bits, and checks that no
+overflow will occur when the resulting value is passed back as
+a fractpel.
+*/
+
+fractpel
+FPmult(fractpel u, fractpel v)
+{
+ doublelong w;
+ register int negative = FALSE; /* sign flag */
+#ifdef LONG64
+ register fractpel ret;
+#endif
+
+ if ((u == 0) || (v == 0)) return (0);
+
+
+ if (u < 0) {u = -u; negative = TRUE;}
+ if (v < 0) {v = -v; negative = !negative;}
+
+ if (u == TOFRACTPEL(1)) return ((negative) ? -v : v);
+ if (v == TOFRACTPEL(1)) return ((negative) ? -u : u);
+
+ DLmult(&w, u, v);
+ DLrightshift(w, FRACTBITS);
+#ifndef LONG64
+ if (w.high != 0 || SIGNBITON(w.low)) {
+ w.low = TOFRACTPEL(MAXSHORT);
+ }
+
+ return ((negative) ? -w.low : w.low);
+#else
+ if (w & 0xffffffff80000000L ) {
+ ret = TOFRACTPEL(MAXSHORT);
+ }
+ else
+ ret = (fractpel)w;
+
+ return ((negative) ? -ret : ret);
+#endif
+}
diff --git a/libXfont/src/Type1/arith.h b/libXfont/src/Type1/arith.h
new file mode 100644
index 000000000..73b84a7c3
--- /dev/null
+++ b/libXfont/src/Type1/arith.h
@@ -0,0 +1,71 @@
+/* $Xorg: arith.h,v 1.3 2000/08/17 19:46:29 cpqbld Exp $ */
+/* Copyright International Business Machines, Corp. 1991
+ * All Rights Reserved
+ * Copyright Lexmark International, Inc. 1991
+ * All Rights Reserved
+ *
+ * License to use, copy, modify, and distribute this software and its
+ * documentation for any purpose and without fee is hereby granted,
+ * provided that the above copyright notice appear in all copies and that
+ * both that copyright notice and this permission notice appear in
+ * supporting documentation, and that the name of IBM or Lexmark not be
+ * used in advertising or publicity pertaining to distribution of the
+ * software without specific, written prior permission.
+ *
+ * IBM AND LEXMARK PROVIDE THIS SOFTWARE "AS IS", WITHOUT ANY WARRANTIES OF
+ * ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING, BUT NOT LIMITED TO ANY
+ * IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE,
+ * AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. THE ENTIRE RISK AS TO THE
+ * QUALITY AND PERFORMANCE OF THE SOFTWARE, INCLUDING ANY DUTY TO SUPPORT
+ * OR MAINTAIN, BELONGS TO THE LICENSEE. SHOULD ANY PORTION OF THE
+ * SOFTWARE PROVE DEFECTIVE, THE LICENSEE (NOT IBM OR LEXMARK) ASSUMES THE
+ * ENTIRE COST OF ALL SERVICING, REPAIR AND CORRECTION. IN NO EVENT SHALL
+ * IBM OR LEXMARK BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
+ * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
+ * THIS SOFTWARE.
+ */
+/* $XFree86: xc/lib/font/Type1/arith.h,v 1.4 1999/08/21 13:47:39 dawes Exp $ */
+
+/*SHARED*/
+
+#include <X11/Xmd.h> /* LONG64 */
+
+/*END SHARED*/
+/*SHARED*/
+
+#undef SHORTSIZE
+#define SHORTSIZE (sizeof(short)*8)
+#undef LONGSIZE
+#define LONGSIZE (SHORTSIZE*2)
+#undef MAXSHORT
+#define MAXSHORT ((1<<SHORTSIZE)-1)
+
+/*END SHARED*/
+/*SHARED*/
+
+#ifdef LONG64
+typedef long doublelong;
+#else
+typedef struct {
+ long high;
+ unsigned long low;
+} doublelong;
+#endif /* LONG64 else */
+
+/*END SHARED*/
+/*SHARED*/
+
+#ifdef LONG64
+#define DLrightshift(dl,N) ((dl) >>= (N))
+#else
+#define DLrightshift(dl,N) { \
+ dl.low = (dl.low >> N) + (((unsigned long) dl.high) << (LONGSIZE - N)); \
+ dl.high >>= N; \
+}
+#endif
+
+extern fractpel FPmult ( fractpel u, fractpel v );
+
+/*END SHARED*/
diff --git a/libXfont/src/Type1/blues.h b/libXfont/src/Type1/blues.h
new file mode 100644
index 000000000..88602f79e
--- /dev/null
+++ b/libXfont/src/Type1/blues.h
@@ -0,0 +1,95 @@
+/* $Xorg: blues.h,v 1.3 2000/08/17 19:46:29 cpqbld Exp $ */
+/* Copyright International Business Machines, Corp. 1991
+ * All Rights Reserved
+ * Copyright Lexmark International, Inc. 1991
+ * All Rights Reserved
+ * Portions Copyright (c) 1990 Adobe Systems Incorporated.
+ * All Rights Reserved
+ *
+ * License to use, copy, modify, and distribute this software and its
+ * documentation for any purpose and without fee is hereby granted,
+ * provided that the above copyright notice appear in all copies and that
+ * both that copyright notice and this permission notice appear in
+ * supporting documentation, and that the name of IBM or Lexmark or Adobe
+ * not be used in advertising or publicity pertaining to distribution of
+ * the software without specific, written prior permission.
+ *
+ * IBM, LEXMARK, AND ADOBE PROVIDE THIS SOFTWARE "AS IS", WITHOUT ANY
+ * WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING, BUT NOT
+ * LIMITED TO ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
+ * PARTICULAR PURPOSE, AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. THE
+ * ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE SOFTWARE, INCLUDING
+ * ANY DUTY TO SUPPORT OR MAINTAIN, BELONGS TO THE LICENSEE. SHOULD ANY
+ * PORTION OF THE SOFTWARE PROVE DEFECTIVE, THE LICENSEE (NOT IBM,
+ * LEXMARK, OR ADOBE) ASSUMES THE ENTIRE COST OF ALL SERVICING, REPAIR AND
+ * CORRECTION. IN NO EVENT SHALL IBM, LEXMARK, OR ADOBE BE LIABLE FOR ANY
+ * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
+ * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF
+ * CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+/* $XFree86: xc/lib/font/Type1/blues.h,v 1.3 1999/08/22 08:58:49 dawes Exp $ */
+
+
+extern psobj *GetType1CharString ( psfont *fontP, unsigned char code );
+
+#define TOPLEFT 1
+#define BOTTOMRIGHT 2
+
+#define NUMBLUEVALUES 14
+#define NUMOTHERBLUES 10
+#define NUMFAMILYBLUES 14
+#define NUMFAMILYOTHERBLUES 10
+#define NUMSTEMSNAPH 12
+#define NUMSTEMSNAPV 12
+#define NUMSTDHW 1
+#define NUMSTDVW 1
+
+#define DEFAULTBOLDSTEMWIDTH 2.0
+
+#define MAXALIGNMENTZONES ((NUMBLUEVALUES+NUMOTHERBLUES)/2)
+#define DEFAULTBLUESCALE 0.039625
+#define DEFAULTBLUESHIFT 7
+#define DEFAULTBLUEFUZZ 1
+#define DEFAULTSTDHW 0
+#define DEFAULTSTDVW 0
+#define DEFAULTFORCEBOLD FALSE
+#define DEFAULTLANGUAGEGROUP 0
+#define DEFAULTRNDSTEMUP FALSE
+#define DEFAULTLENIV 4
+#define DEFAULTEXPANSIONFACTOR 0.06
+
+/* see Type 1 Font Format book for explanations of these values */
+/* Note that we're currently doing nothing for minfeature and password. */
+struct blues_struct {
+ struct blues_struct *next; /* ptr to next Blues structure in list */
+ int numBlueValues; /* # of BlueValues in following array */
+ int BlueValues[NUMBLUEVALUES];
+ int numOtherBlues; /* # of OtherBlues values in following array */
+ int OtherBlues[NUMOTHERBLUES];
+ int numFamilyBlues; /* # of FamilyBlues values in following array */
+ int FamilyBlues[NUMFAMILYBLUES];
+ int numFamilyOtherBlues; /* # of FamilyOtherBlues values in */
+ int FamilyOtherBlues[NUMFAMILYOTHERBLUES]; /* this array */
+ double BlueScale;
+ int BlueShift;
+ int BlueFuzz;
+ double StdHW;
+ double StdVW;
+ int numStemSnapH; /* # of StemSnapH values in following array */
+ double StemSnapH[NUMSTEMSNAPH];
+ int numStemSnapV; /* # of StemSnapV values in following array */
+ double StemSnapV[NUMSTEMSNAPV];
+ int ForceBold;
+ int LanguageGroup;
+ int RndStemUp;
+ int lenIV;
+ double ExpansionFactor;
+};
+
+/* the alignment zone structure -- somewhat similar to the stem structure */
+/* see Adobe Type1 Font Format book about the terms used in this structure */
+struct alignmentzone {
+ int topzone; /* TRUE if a topzone, FALSE if a bottom zone */
+ double bottomy, topy; /* interval of this alignment zone */
+};
diff --git a/libXfont/src/Type1/cluts.h b/libXfont/src/Type1/cluts.h
new file mode 100644
index 000000000..67d930324
--- /dev/null
+++ b/libXfont/src/Type1/cluts.h
@@ -0,0 +1,35 @@
+/* $Xorg: cluts.h,v 1.3 2000/08/17 19:46:29 cpqbld Exp $ */
+/* Copyright International Business Machines,Corp. 1991
+ * All Rights Reserved
+ *
+ * License to use, copy, modify, and distribute this software
+ * and its documentation for any purpose and without fee is
+ * hereby granted, provided that the above copyright notice
+ * appear in all copies and that both that copyright notice and
+ * this permission notice appear in supporting documentation,
+ * and that the name of IBM not be used in advertising or
+ * publicity pertaining to distribution of the software without
+ * specific, written prior permission.
+ *
+ * IBM PROVIDES THIS SOFTWARE "AS IS", WITHOUT ANY WARRANTIES
+ * OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING, BUT NOT
+ * LIMITED TO ANY IMPLIED WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE, AND NONINFRINGEMENT OF
+ * THIRD PARTY RIGHTS. THE ENTIRE RISK AS TO THE QUALITY AND
+ * PERFORMANCE OF THE SOFTWARE, INCLUDING ANY DUTY TO SUPPORT
+ * OR MAINTAIN, BELONGS TO THE LICENSEE. SHOULD ANY PORTION OF
+ * THE SOFTWARE PROVE DEFECTIVE, THE LICENSEE (NOT IBM) ASSUMES
+ * THE ENTIRE COST OF ALL SERVICING, REPAIR AND CORRECTION. IN
+ * NO EVENT SHALL IBM BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING
+ * FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF
+ * CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
+ * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+ * SOFTWARE.
+ */
+/* STUB */
+
+#define KillCLUT(T)
+#define CopyCLUT(T) T
+#define UniqueCLUT(T)
+
diff --git a/libXfont/src/Type1/curves.c b/libXfont/src/Type1/curves.c
new file mode 100644
index 000000000..9d0c3f8cc
--- /dev/null
+++ b/libXfont/src/Type1/curves.c
@@ -0,0 +1,228 @@
+/* $Xorg: curves.c,v 1.3 2000/08/17 19:46:29 cpqbld Exp $ */
+/* Copyright International Business Machines,Corp. 1991 */
+/* All Rights Reserved */
+
+/* License to use, copy, modify, and distribute this software */
+/* and its documentation for any purpose and without fee is */
+/* hereby granted, provided that licensee provides a license to */
+/* IBM, Corp. to use, copy, modify, and distribute derivative */
+/* works and their documentation for any purpose and without */
+/* fee, that the above copyright notice appear in all copies */
+/* and that both that copyright notice and this permission */
+/* notice appear in supporting documentation, and that the name */
+/* of IBM not be used in advertising or publicity pertaining to */
+/* distribution of the software without specific, written prior */
+/* permission. */
+
+/* IBM PROVIDES THIS SOFTWARE "AS IS", WITHOUT ANY WARRANTIES */
+/* OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING, BUT NOT */
+/* LIMITED TO ANY IMPLIED WARRANTIES OF MERCHANTABILITY, */
+/* FITNESS FOR A PARTICULAR PURPOSE, AND NONINFRINGEMENT OF */
+/* THIRD PARTY RIGHTS. THE ENTIRE RISK AS TO THE QUALITY AND */
+/* PERFORMANCE OF THE SOFTWARE, INCLUDING ANY DUTY TO SUPPORT */
+/* OR MAINTAIN, BELONGS TO THE LICENSEE. SHOULD ANY PORTION OF */
+/* THE SOFTWARE PROVE DEFECTIVE, THE LICENSEE (NOT IBM) ASSUMES */
+/* THE ENTIRE COST OF ALL SERVICING, REPAIR AND CORRECTION. IN */
+/* NO EVENT SHALL IBM BE LIABLE FOR ANY SPECIAL, INDIRECT OR */
+/* CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING */
+/* FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF */
+/* CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT */
+/* OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS */
+/* SOFTWARE. */
+/* $XFree86: xc/lib/font/Type1/curves.c,v 1.7 2001/08/27 19:49:52 dawes Exp $ */
+
+/*
+:h1.CURVES Module - Stepping Beziers
+
+This module is responsible for "rasterizing"
+third order curves. That is, it changes the high level curve
+specification into a list of pels that that curve travels
+through.
+
+:h3.Include Files
+
+Include files needed:
+*/
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#ifdef FONTMODULE
+# include "os.h"
+#endif
+#include "objects.h"
+#include "spaces.h"
+#include "paths.h"
+#include "regions.h"
+#include "curves.h"
+#include "lines.h"
+#include "arith.h"
+
+
+/*
+:h3.Functions Provided to Other Modules
+
+External entry points:
+*/
+/*SHARED LINE(S) ORIGINATED HERE*/
+
+/*
+Note that "stepping" and "flattening" are so similiar that they use the
+same routine. When the "region" parameter is NULL, that is a flag that
+we are flattening instead of stepping.
+*/
+/*
+:h2.Bezier Third Order Curves
+*/
+/*
+:h3.The "bezierinfo" Structure
+
+This structure is used to store information used when we subdivide
+Bezier curves.
+*/
+
+struct bezierinfo {
+ struct region *region; /* the region being built or NULL */
+ struct fractpoint last; /* not used yet; maybe could save some work */
+ struct fractpoint origin; /* the origin of the bezier */
+} ;
+
+/*
+ Checking for termination of the subdivision process:
+ This is the stupidest test in the world, just check if the coordinatewise
+ distance from an end control point to the next control point is less than
+ one half pel. If so, we must be done.
+ This returns 1 if the subdivision is terminated and 0 if you still need
+ to subdivide.
+*/
+
+static int
+BezierTerminationTest(fractpel xa, fractpel ya,
+ fractpel xb, fractpel yb,
+ fractpel xc, fractpel yc,
+ fractpel xd, fractpel yd)
+{
+ fractpel dmax;
+ dmax = ABS(xa - xb);
+ dmax = MAX(dmax,ABS(ya - yb));
+ dmax = MAX(dmax,ABS(xd - xc));
+ dmax = MAX(dmax,ABS(yd - yc));
+ if(dmax > FPHALF)
+ return(0); /* not done yet */
+ else
+ return(1); /* done */
+}
+
+/*
+:h3.StepBezierRecurse() - The Recursive Logic in StepBezier()
+
+The recursion involves dividing the control polygon into two smaller
+control polygons by finding the midpoints of the lines. This idea is
+described in any graphics text book and its simplicity is what caused
+Bezier to define his curves as he did. If the input region 'R' is NULL,
+the result is a path that is the 'flattened' curve; otherwise StepBezier
+returns nothing special.
+*/
+static struct segment *
+StepBezierRecurse(struct bezierinfo *I, /* Region under construction or NULL */
+ fractpel xA, fractpel yA, /* A control point */
+ fractpel xB, fractpel yB, /* B control point */
+ fractpel xC, fractpel yC, /* C control point */
+ fractpel xD, fractpel yD) /* D control point */
+{
+ if (BezierTerminationTest(xA,yA,xB,yB,xC,yC,xD,yD))
+ {
+ if (I->region == NULL)
+ return(PathSegment(LINETYPE, xD - xA, yD - yA));
+ else
+ StepLine(I->region, I->origin.x + xA, I->origin.y + yA,
+ I->origin.x + xD, I->origin.y + yD);
+ }
+ else
+ {
+ fractpel xAB,yAB;
+ fractpel xBC,yBC;
+ fractpel xCD,yCD;
+ fractpel xABC,yABC;
+ fractpel xBCD,yBCD;
+ fractpel xABCD,yABCD;
+
+ xAB = xA + xB; yAB = yA + yB;
+ xBC = xB + xC; yBC = yB + yC;
+ xCD = xC + xD; yCD = yC + yD;
+
+ xABC = xAB + xBC; yABC = yAB + yBC;
+ xBCD = xBC + xCD; yBCD = yBC + yCD;
+
+ xABCD = xABC + xBCD; yABCD = yABC + yBCD;
+
+ xAB >>= 1; yAB >>= 1;
+ xBC >>= 1; yBC >>= 1;
+ xCD >>= 1; yCD >>= 1;
+ xABC >>= 2; yABC >>= 2;
+ xBCD >>= 2; yBCD >>= 2;
+ xABCD >>= 3; yABCD >>= 3;
+
+ if (I->region == NULL)
+ {
+ return( Join(
+ StepBezierRecurse(I, xA, yA, xAB, yAB, xABC, yABC, xABCD, yABCD),
+ StepBezierRecurse(I, xABCD, yABCD, xBCD, yBCD, xCD, yCD, xD, yD)
+ )
+ );
+ }
+ else
+ {
+ StepBezierRecurse(I, xA, yA, xAB, yAB, xABC, yABC, xABCD, yABCD);
+ StepBezierRecurse(I, xABCD, yABCD, xBCD, yBCD, xCD, yCD, xD, yD);
+ }
+ }
+ return NULL;
+ /*NOTREACHED*/
+}
+
+/*
+:h3.TOOBIG() - Macro to Test if a Coordinate is Too Big to Bezier SubDivide Normally
+
+Intermediate values in the Bezier subdivision are 8 times bigger than
+the starting values. If this overflows, a 'long', we are in trouble:
+*/
+
+#undef BITS
+#define BITS (sizeof(long)*8)
+#define HIGHTEST(p) (((p)>>(BITS-4)) != 0) /* includes sign bit */
+#define TOOBIG(xy) ((xy < 0) ? HIGHTEST(-xy) : HIGHTEST(xy))
+
+/*
+:h3.StepBezier() - Produce Run Ends for a Bezier Curve
+
+This is the entry point called from outside the module.
+*/
+
+struct segment *
+StepBezier(struct region *R, /* Region under construction or NULL */
+ fractpel xA, fractpel yA, /* A control point */
+ fractpel xB, fractpel yB, /* B control point */
+ fractpel xC, fractpel yC, /* C control point */
+ fractpel xD, fractpel yD) /* D control point */
+{
+ struct bezierinfo Info;
+
+ Info.region = R;
+ Info.origin.x = xA;
+ Info.origin.y = yA;
+
+ xB -= xA;
+ xC -= xA;
+ xD -= xA;
+ yB -= yA;
+ yC -= yA;
+ yD -= yA;
+
+ if ( TOOBIG(xB) || TOOBIG(yB) || TOOBIG(xC) || TOOBIG(yC)
+ || TOOBIG(xD) || TOOBIG(yD) )
+ Abort("Beziers this big not yet supported");
+
+ return(StepBezierRecurse(&Info,
+ (fractpel) 0, (fractpel) 0, xB, yB, xC, yC, xD, yD));
+}
+
diff --git a/libXfont/src/Type1/curves.h b/libXfont/src/Type1/curves.h
new file mode 100644
index 000000000..ca54bad62
--- /dev/null
+++ b/libXfont/src/Type1/curves.h
@@ -0,0 +1,44 @@
+/* $Xorg: curves.h,v 1.3 2000/08/17 19:46:29 cpqbld Exp $ */
+/* Copyright International Business Machines, Corp. 1991
+ * All Rights Reserved
+ * Copyright Lexmark International, Inc. 1991
+ * All Rights Reserved
+ *
+ * License to use, copy, modify, and distribute this software and its
+ * documentation for any purpose and without fee is hereby granted,
+ * provided that the above copyright notice appear in all copies and that
+ * both that copyright notice and this permission notice appear in
+ * supporting documentation, and that the name of IBM or Lexmark not be
+ * used in advertising or publicity pertaining to distribution of the
+ * software without specific, written prior permission.
+ *
+ * IBM AND LEXMARK PROVIDE THIS SOFTWARE "AS IS", WITHOUT ANY WARRANTIES OF
+ * ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING, BUT NOT LIMITED TO ANY
+ * IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE,
+ * AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. THE ENTIRE RISK AS TO THE
+ * QUALITY AND PERFORMANCE OF THE SOFTWARE, INCLUDING ANY DUTY TO SUPPORT
+ * OR MAINTAIN, BELONGS TO THE LICENSEE. SHOULD ANY PORTION OF THE
+ * SOFTWARE PROVE DEFECTIVE, THE LICENSEE (NOT IBM OR LEXMARK) ASSUMES THE
+ * ENTIRE COST OF ALL SERVICING, REPAIR AND CORRECTION. IN NO EVENT SHALL
+ * IBM OR LEXMARK BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
+ * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
+ * THIS SOFTWARE.
+ */
+/* $XFree86: xc/lib/font/Type1/curves.h,v 1.3 1999/08/22 08:58:50 dawes Exp $ */
+
+/*SHARED*/
+
+#define StepConic(R,xA,yA,xB,yB,xC,yC,r) t1_StepConic(R,xA,yA,xB,yB,xC,yC,r)
+#define StepBezier(R,xA,yA,xB,yB,xC,yC,xD,yD) t1_StepBezier(R,xA,yA,xB,yB,xC,yC,xD,yD)
+
+#define FlattenConic(xM,yM,xC,yC,r) t1_StepConic(NULL,(fractpel)0,(fractpel)0,xM,yM,xC,yC,r)
+#define FlattenBezier(xB,yB,xC,yC,xD,yD) t1_StepBezier(NULL,(fractpel)0,(fractpel)0,xB,yB,xC,yC,xD,yD)
+
+#if 0
+struct segment *t1_StepConic();
+#endif
+extern struct segment *t1_StepBezier ( struct region *R, fractpel xA, fractpel yA, fractpel xB, fractpel yB, fractpel xC, fractpel yC, fractpel xD, fractpel yD );
+
+/*END SHARED*/
diff --git a/libXfont/src/Type1/digit.h b/libXfont/src/Type1/digit.h
new file mode 100644
index 000000000..44e418c8c
--- /dev/null
+++ b/libXfont/src/Type1/digit.h
@@ -0,0 +1,64 @@
+/* $Xorg: digit.h,v 1.3 2000/08/17 19:46:29 cpqbld Exp $ */
+/* Copyright International Business Machines,Corp. 1991
+ * All Rights Reserved
+ *
+ * License to use, copy, modify, and distribute this software
+ * and its documentation for any purpose and without fee is
+ * hereby granted, provided that the above copyright notice
+ * appear in all copies and that both that copyright notice and
+ * this permission notice appear in supporting documentation,
+ * and that the name of IBM not be used in advertising or
+ * publicity pertaining to distribution of the software without
+ * specific, written prior permission.
+ *
+ * IBM PROVIDES THIS SOFTWARE "AS IS", WITHOUT ANY WARRANTIES
+ * OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING, BUT NOT
+ * LIMITED TO ANY IMPLIED WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE, AND NONINFRINGEMENT OF
+ * THIRD PARTY RIGHTS. THE ENTIRE RISK AS TO THE QUALITY AND
+ * PERFORMANCE OF THE SOFTWARE, INCLUDING ANY DUTY TO SUPPORT
+ * OR MAINTAIN, BELONGS TO THE LICENSEE. SHOULD ANY PORTION OF
+ * THE SOFTWARE PROVE DEFECTIVE, THE LICENSEE (NOT IBM) ASSUMES
+ * THE ENTIRE COST OF ALL SERVICING, REPAIR AND CORRECTION. IN
+ * NO EVENT SHALL IBM BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING
+ * FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF
+ * CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
+ * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+ * SOFTWARE.
+ */
+/* -------------------------------------- */
+/* --- MACHINE GENERATED, DO NOT EDIT --- */
+/* -------------------------------------- */
+
+#ifndef DIGIT
+#define DIGIT 1
+
+/*
+ * Digit Value Table --
+ *
+ * The entries in the Digit Value Table map character
+ * codes in the set {0-9,a-z,A-Z} to their numeric
+ * values as part of numbers of radix 2-36.
+ *
+ */
+static const unsigned char digit_value[256] = {
+0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
+ 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
+ 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
+ 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
+ 0xFF,0x0A,0x0B,0x0C,0x0D,0x0E,0x0F,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,
+ 0x19,0x1A,0x1B,0x1C,0x1D,0x1E,0x1F,0x20,0x21,0x22,0x23,0xFF,0xFF,0xFF,0xFF,0xFF,
+ 0xFF,0x0A,0x0B,0x0C,0x0D,0x0E,0x0F,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,
+ 0x19,0x1A,0x1B,0x1C,0x1D,0x1E,0x1F,0x20,0x21,0x22,0x23,0xFF,0xFF,0xFF,0xFF,0xFF,
+ 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
+ 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
+ 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
+ 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
+ 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
+ 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
+ 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
+ 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF
+};
+
+#endif
diff --git a/libXfont/src/Type1/fontfcn.c b/libXfont/src/Type1/fontfcn.c
new file mode 100644
index 000000000..ba5db0e67
--- /dev/null
+++ b/libXfont/src/Type1/fontfcn.c
@@ -0,0 +1,317 @@
+/* $Xorg: fontfcn.c,v 1.4 2000/08/17 19:46:30 cpqbld Exp $ */
+/* Copyright International Business Machines,Corp. 1991
+ * All Rights Reserved
+ *
+ * License to use, copy, modify, and distribute this software
+ * and its documentation for any purpose and without fee is
+ * hereby granted, provided that the above copyright notice
+ * appear in all copies and that both that copyright notice and
+ * this permission notice appear in supporting documentation,
+ * and that the name of IBM not be used in advertising or
+ * publicity pertaining to distribution of the software without
+ * specific, written prior permission.
+ *
+ * IBM PROVIDES THIS SOFTWARE "AS IS", WITHOUT ANY WARRANTIES
+ * OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING, BUT NOT
+ * LIMITED TO ANY IMPLIED WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE, AND NONINFRINGEMENT OF
+ * THIRD PARTY RIGHTS. THE ENTIRE RISK AS TO THE QUALITY AND
+ * PERFORMANCE OF THE SOFTWARE, INCLUDING ANY DUTY TO SUPPORT
+ * OR MAINTAIN, BELONGS TO THE LICENSEE. SHOULD ANY PORTION OF
+ * THE SOFTWARE PROVE DEFECTIVE, THE LICENSEE (NOT IBM) ASSUMES
+ * THE ENTIRE COST OF ALL SERVICING, REPAIR AND CORRECTION. IN
+ * NO EVENT SHALL IBM BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING
+ * FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF
+ * CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
+ * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+ * SOFTWARE.
+ */
+/* Author: Katherine A. Hitchcock IBM Almaden Research Laboratory */
+/* $XFree86: xc/lib/font/Type1/fontfcn.c,v 1.10 2001/04/05 17:42:27 dawes Exp $ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#ifndef FONTMODULE
+#include <stdio.h>
+#include <string.h>
+#else
+#include "Xmd.h" /* For INT32 declaration */
+#include "Xdefs.h" /* For Bool */
+#include "xf86_ansic.h"
+#endif
+#include "t1imager.h"
+#include "util.h"
+#include <X11/fonts/fntfilst.h>
+#include "fontfcn.h"
+
+extern struct segment *Type1Char ( char *env, XYspace S,
+ psobj *charstrP, psobj *subrsP,
+ psobj *osubrsP,
+ struct blues_struct *bluesP, int *modeP );
+
+
+/***================================================================***/
+/* GLOBALS */
+/***================================================================***/
+static char CurFontName[120];
+static char *vm_base = NULL;
+psfont *FontP = NULL;
+static psfont TheCurrentFont;
+
+/***================================================================***/
+/* SearchDict - look for name */
+/* - compare for match on len and string */
+/* return 0 - not found. */
+/* return n - nth element in dictionary. */
+/***================================================================***/
+int
+SearchDictName(psdict *dictP, psobj *keyP)
+{
+ int i,n;
+
+
+ n = dictP[0].key.len;
+ for (i=1;i<=n;i++) { /* scan the intire dictionary */
+ if (
+ (dictP[i].key.len == keyP->len )
+ &&
+ (strncmp(dictP[i].key.data.valueP,
+ keyP->data.valueP,
+ keyP->len) == 0
+ )
+ ) return(i);
+ }
+ return(0);
+}
+
+static boolean
+initFont(int cnt)
+{
+
+ if (!(vm_init(cnt))) return(FALSE);
+ vm_base = vm_next_byte();
+ if (!(Init_BuiltInEncoding())) return(FALSE);
+ strcpy(CurFontName, ""); /* iniitialize to none */
+ FontP = &TheCurrentFont;
+ FontP->vm_start = vm_next_byte();
+ FontP->FontFileName.len = 0;
+ FontP->FontFileName.data.valueP = CurFontName;
+ return(TRUE);
+}
+/***================================================================***/
+static void
+resetFont(char *env)
+{
+
+ vm_next = FontP->vm_start;
+ vm_free = vm_size - ( vm_next - vm_base);
+ FontP->Subrs.len = 0;
+ FontP->Subrs.data.stringP = NULL;
+ FontP->CharStringsP = NULL;
+ FontP->Private = NULL;
+ FontP->fontInfoP = NULL;
+ FontP->BluesP = NULL;
+ /* This will load the font into the FontP */
+ strcpy(CurFontName,env);
+ FontP->FontFileName.len = strlen(CurFontName);
+ FontP->FontFileName.data.valueP = CurFontName;
+
+}
+
+static int
+readFont(char *env)
+{
+ int rcode;
+
+ /* restore the virtual memory and eliminate old font */
+ resetFont(env);
+ /* This will load the font into the FontP */
+ rcode = scan_font(FontP);
+ if (rcode == SCAN_OUT_OF_MEMORY) {
+ if (!(initFont(vm_size * 2))) {
+ /* we are really out of memory */
+ return(SCAN_OUT_OF_MEMORY);
+ }
+ resetFont(env);
+ rcode = scan_font(FontP);
+ /* only double the memory once, then report error */
+ }
+ return(rcode);
+}
+/***================================================================***/
+struct xobject *
+fontfcnB(struct XYspace *S, unsigned char *code, int *lenP, int *mode)
+{
+ psobj *charnameP; /* points to psobj that is name of character*/
+ int N;
+ psdict *CharStringsDictP; /* dictionary with char strings */
+ psobj CodeName; /* used to store the translation of the name*/
+ psobj *SubrsArrayP;
+ psobj *theStringP;
+
+ struct xobject *charpath; /* the path for this character */
+
+ charnameP = &CodeName;
+ charnameP->len = *lenP;
+ charnameP->data.stringP = code;
+
+ CharStringsDictP = FontP->CharStringsP;
+
+ /* search the chars string for this charname as key */
+ N = SearchDictName(CharStringsDictP,charnameP);
+ if (N<=0) {
+ *mode = FF_PARSE_ERROR;
+ return(NULL);
+ }
+ /* ok, the nth item is the psobj that is the string for this char */
+ theStringP = &(CharStringsDictP[N].value);
+
+ /* get the dictionary pointers to the Subrs */
+
+ SubrsArrayP = &(FontP->Subrs);
+ /* scale the Adobe fonts to 1 unit high */
+ /* call the type 1 routine to rasterize the character */
+ charpath = (struct xobject *)Type1Char((char *)FontP,S,theStringP,
+ SubrsArrayP,NULL,
+ FontP->BluesP , mode);
+ /* if Type1Char reported an error, then return */
+ if ( *mode == FF_PARSE_ERROR) return(NULL);
+ /* fill with winding rule unless path was requested */
+ if (*mode != FF_PATH) {
+ charpath = (struct xobject *)Interior((struct segment *)charpath,
+ WINDINGRULE+CONTINUITY);
+ }
+ return(charpath);
+}
+
+
+/***================================================================***/
+/* fontfcnA(env, mode) */
+/* */
+/* env is a pointer to a string that contains the fontname. */
+/* */
+/* 1) initialize the font - global indicates it has been done */
+/* 2) load the font */
+/***================================================================***/
+Bool
+fontfcnA(char *env, int *mode)
+{
+ int rc;
+
+ /* Has the FontP initialized? If not, then */
+ /* Initialize */
+ if (FontP == NULL) {
+ InitImager();
+ if (!(initFont(VM_SIZE))) {
+ /* we are really out of memory */
+ *mode = SCAN_OUT_OF_MEMORY;
+ return(FALSE);
+ }
+ }
+
+ /* if the env is null, then use font already loaded */
+
+ /* if the not same font name */
+ if ( (env) && (strcmp(env,CurFontName) != 0 ) ) {
+ /* restore the virtual memory and eliminate old font, read new one */
+ rc = readFont(env);
+ if (rc != 0 ) {
+ strcpy(CurFontName, ""); /* no font loaded */
+ *mode = rc;
+ return(FALSE);
+ }
+ }
+ return(TRUE);
+
+}
+
+/***================================================================***/
+/* QueryFontLib(env, infoName,infoValue,rcodeP) */
+/* */
+/* env is a pointer to a string that contains the fontname. */
+/* */
+/* 1) initialize the font - global indicates it has been done */
+/* 2) load the font */
+/* 3) use the font to call getInfo for that value. */
+/***================================================================***/
+
+void
+QueryFontLib(char *env, char *infoName,
+ pointer infoValue, /* parameter returned here */
+ int *rcodeP)
+{
+ int rc,N,i;
+ psdict *dictP;
+ psobj nameObj;
+ psobj *valueP;
+
+ /* Has the FontP initialized? If not, then */
+ /* Initialize */
+ if (FontP == NULL) {
+ InitImager();
+ if (!(initFont(VM_SIZE))) {
+ *rcodeP = 1;
+ return;
+ }
+ }
+ /* if the env is null, then use font already loaded */
+ /* if the not same font name, reset and load next font */
+ if ( (env) && (strcmp(env,CurFontName) != 0 ) ) {
+ /* restore the virtual memory and eliminate old font */
+ rc = readFont(env);
+ if (rc != 0 ) {
+ strcpy(CurFontName, ""); /* no font loaded */
+ *rcodeP = 1;
+ return;
+ }
+ }
+ dictP = FontP->fontInfoP;
+ objFormatName(&nameObj,strlen(infoName),infoName);
+ N = SearchDictName(dictP,&nameObj);
+ /* if found */
+ if ( N > 0 ) {
+ *rcodeP = 0;
+ switch (dictP[N].value.type) {
+ case OBJ_ARRAY:
+ valueP = dictP[N].value.data.arrayP;
+ /* Just double check valueP. H.J. */
+ if (valueP == NULL) break;
+ if (strcmp(infoName,"FontMatrix") == 0) {
+ /* 6 elments, return them as floats */
+ for (i=0;i<6;i++) {
+ if (valueP->type == OBJ_INTEGER )
+ ((float *)infoValue)[i] = valueP->data.integer;
+ else
+ ((float *)infoValue)[i] = valueP->data.real;
+ valueP++;
+ }
+ }
+ if (strcmp(infoName,"FontBBox") == 0) {
+ /* 4 elments for Bounding Box. all integers */
+ for (i=0;i<4;i++) {
+ ((int *)infoValue)[i] = valueP->data.integer;
+ valueP++;
+ }
+ break;
+ case OBJ_INTEGER:
+ case OBJ_BOOLEAN:
+ *((int *)infoValue) = dictP[N].value.data.integer;
+ break;
+ case OBJ_REAL:
+ *((float *)infoValue) = dictP[N].value.data.real;
+ break;
+ case OBJ_NAME:
+ case OBJ_STRING:
+ *((char **)infoValue) = dictP[N].value.data.valueP;
+ break;
+ default:
+ *rcodeP = 1;
+ break;
+ }
+ }
+ }
+ else *rcodeP = 1;
+}
diff --git a/libXfont/src/Type1/fontfcn.h b/libXfont/src/Type1/fontfcn.h
new file mode 100644
index 000000000..023302f3a
--- /dev/null
+++ b/libXfont/src/Type1/fontfcn.h
@@ -0,0 +1,114 @@
+/* $Xorg: fontfcn.h,v 1.3 2000/08/17 19:46:30 cpqbld Exp $ */
+/* Copyright International Business Machines,Corp. 1991
+ * All Rights Reserved
+ *
+ * License to use, copy, modify, and distribute this software
+ * and its documentation for any purpose and without fee is
+ * hereby granted, provided that the above copyright notice
+ * appear in all copies and that both that copyright notice and
+ * this permission notice appear in supporting documentation,
+ * and that the name of IBM not be used in advertising or
+ * publicity pertaining to distribution of the software without
+ * specific, written prior permission.
+ *
+ * IBM PROVIDES THIS SOFTWARE "AS IS", WITHOUT ANY WARRANTIES
+ * OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING, BUT NOT
+ * LIMITED TO ANY IMPLIED WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE, AND NONINFRINGEMENT OF
+ * THIRD PARTY RIGHTS. THE ENTIRE RISK AS TO THE QUALITY AND
+ * PERFORMANCE OF THE SOFTWARE, INCLUDING ANY DUTY TO SUPPORT
+ * OR MAINTAIN, BELONGS TO THE LICENSEE. SHOULD ANY PORTION OF
+ * THE SOFTWARE PROVE DEFECTIVE, THE LICENSEE (NOT IBM) ASSUMES
+ * THE ENTIRE COST OF ALL SERVICING, REPAIR AND CORRECTION. IN
+ * NO EVENT SHALL IBM BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING
+ * FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF
+ * CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
+ * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+ * SOFTWARE.
+ */
+/* $XFree86: xc/lib/font/Type1/fontfcn.h,v 1.4 1999/08/22 08:58:50 dawes Exp $ */
+
+
+/* modular config.h defines VERSION as libXfont version */
+#ifdef VERSION
+#undef VERSION
+#endif
+
+#include "util.h"
+
+/* Definition of a PostScript FONT */
+typedef struct ps_font {
+ char *vm_start;
+ psobj FontFileName;
+ psobj Subrs;
+ psdict *CharStringsP;
+ psdict *Private;
+ psdict *fontInfoP;
+struct blues_struct *BluesP;
+} psfont;
+/***================================================================***/
+/* Routines in scan_font */
+/***================================================================***/
+
+extern boolean Init_BuiltInEncoding ( void );
+extern int scan_font ( psfont *FontP );
+/***================================================================***/
+/* Return codes from scan_font */
+/***================================================================***/
+#define SCAN_OK 0
+#define SCAN_FILE_EOF -1
+#define SCAN_ERROR -2
+#define SCAN_OUT_OF_MEMORY -3
+#define SCAN_FILE_OPEN_ERROR -4
+#define SCAN_TRUE -5
+#define SCAN_FALSE -6
+#define SCAN_END -7
+
+/***================================================================***/
+/* Name of FontInfo fields */
+/***================================================================***/
+
+#define FONTNAME 1
+#define PAINTTYPE 2
+#define FONTTYPENUM 3
+#define FONTMATRIX 4
+#define FONTBBOX 5
+#define UNIQUEID 6
+#define STROKEWIDTH 7
+#define VERSION 8
+#define NOTICE 9
+#define FULLNAME 10
+#define FAMILYNAME 11
+#define WEIGHT 12
+#define ITALICANGLE 13
+#define ISFIXEDPITCH 14
+#define UNDERLINEPOSITION 15
+#define UNDERLINETHICKNESS 16
+#define ENCODING 17
+/***================================================================***/
+/* Name of Private values */
+/***================================================================***/
+#define BLUEVALUES 1
+#define OTHERBLUES 2
+#define FAMILYBLUES 3
+#define FAMILYOTHERBLUES 4
+#define BLUESCALE 5
+#define BLUESHIFT 6
+#define BLUEFUZZ 7
+#define STDHW 8
+#define STDVW 9
+#define STEMSNAPH 10
+#define STEMSNAPV 11
+#define FORCEBOLD 12
+#define LANGUAGEGROUP 13
+#define LENIV 14
+#define RNDSTEMUP 15
+#define EXPANSIONFACTOR 16
+
+extern int SearchDictName ( psdict *dictP, psobj *keyP );
+extern struct xobject *fontfcnB ( struct XYspace *S, unsigned char *code,
+ int *lenP, int *mode );
+extern Bool fontfcnA ( char *env, int *mode );
+extern void QueryFontLib ( char *env, char *infoName, pointer infoValue,
+ int *rcodeP );
diff --git a/libXfont/src/Type1/fonts.h b/libXfont/src/Type1/fonts.h
new file mode 100644
index 000000000..7215e0f7a
--- /dev/null
+++ b/libXfont/src/Type1/fonts.h
@@ -0,0 +1,49 @@
+/* $Xorg: fonts.h,v 1.3 2000/08/17 19:46:30 cpqbld Exp $ */
+/* Copyright International Business Machines,Corp. 1991
+ * All Rights Reserved
+ *
+ * License to use, copy, modify, and distribute this software
+ * and its documentation for any purpose and without fee is
+ * hereby granted, provided that the above copyright notice
+ * appear in all copies and that both that copyright notice and
+ * this permission notice appear in supporting documentation,
+ * and that the name of IBM not be used in advertising or
+ * publicity pertaining to distribution of the software without
+ * specific, written prior permission.
+ *
+ * IBM PROVIDES THIS SOFTWARE "AS IS", WITHOUT ANY WARRANTIES
+ * OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING, BUT NOT
+ * LIMITED TO ANY IMPLIED WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE, AND NONINFRINGEMENT OF
+ * THIRD PARTY RIGHTS. THE ENTIRE RISK AS TO THE QUALITY AND
+ * PERFORMANCE OF THE SOFTWARE, INCLUDING ANY DUTY TO SUPPORT
+ * OR MAINTAIN, BELONGS TO THE LICENSEE. SHOULD ANY PORTION OF
+ * THE SOFTWARE PROVE DEFECTIVE, THE LICENSEE (NOT IBM) ASSUMES
+ * THE ENTIRE COST OF ALL SERVICING, REPAIR AND CORRECTION. IN
+ * NO EVENT SHALL IBM BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING
+ * FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF
+ * CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
+ * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+ * SOFTWARE.
+ */
+
+/* STUB */
+
+#define CopyFont(f) f
+#define UniqueFont(f) f
+#define KillFont(f)
+#define KillText(t)
+#define CopyText(t) t
+#define I_DumpText(t)
+#define CoerceText(t) t
+#define TextDelta(t,pt)
+#define XformText(p,s)
+#define GimeSpace() FALSE
+
+#define LibInit()
+#define InitFonts()
+#define InitFiles()
+#define TraceClose()
+
+#define FF_PARSE_ERROR -1
diff --git a/libXfont/src/Type1/hdigit.h b/libXfont/src/Type1/hdigit.h
new file mode 100644
index 000000000..fbaa9c1db
--- /dev/null
+++ b/libXfont/src/Type1/hdigit.h
@@ -0,0 +1,94 @@
+/* $Xorg: hdigit.h,v 1.3 2000/08/17 19:46:30 cpqbld Exp $ */
+/* Copyright International Business Machines,Corp. 1991
+ * All Rights Reserved
+ *
+ * License to use, copy, modify, and distribute this software
+ * and its documentation for any purpose and without fee is
+ * hereby granted, provided that the above copyright notice
+ * appear in all copies and that both that copyright notice and
+ * this permission notice appear in supporting documentation,
+ * and that the name of IBM not be used in advertising or
+ * publicity pertaining to distribution of the software without
+ * specific, written prior permission.
+ *
+ * IBM PROVIDES THIS SOFTWARE "AS IS", WITHOUT ANY WARRANTIES
+ * OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING, BUT NOT
+ * LIMITED TO ANY IMPLIED WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE, AND NONINFRINGEMENT OF
+ * THIRD PARTY RIGHTS. THE ENTIRE RISK AS TO THE QUALITY AND
+ * PERFORMANCE OF THE SOFTWARE, INCLUDING ANY DUTY TO SUPPORT
+ * OR MAINTAIN, BELONGS TO THE LICENSEE. SHOULD ANY PORTION OF
+ * THE SOFTWARE PROVE DEFECTIVE, THE LICENSEE (NOT IBM) ASSUMES
+ * THE ENTIRE COST OF ALL SERVICING, REPAIR AND CORRECTION. IN
+ * NO EVENT SHALL IBM BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING
+ * FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF
+ * CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
+ * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+ * SOFTWARE.
+ */
+/* -------------------------------------- */
+/* --- MACHINE GENERATED, DO NOT EDIT --- */
+/* -------------------------------------- */
+
+#ifndef HDIGIT
+#define HDIGIT 1
+
+/*
+ * Hex Digit Value Table --
+ *
+ * The entries in the Digit Value Table map character codes in the set
+ * {0-9,a-f,A-F} to their numeric values for readhexstring
+ * (00 10...F0 for the high hex digit and 00 01...0F for the low).
+ * The white-space and hex string termination characters are.
+ * mapped to codes > 0xf0 to enable usage by several modules.
+ * 2 tables are build HighHex and LowHex.
+ *
+ */
+
+/* Indicators for special characters in these tables */
+#define HERROR (0xfe)
+#define HWHITE_SPACE (0xfd)
+#define HRIGHT_ANGLE (0xfc)
+#define LAST_HDIGIT (0xf0)
+
+#define HighHexP (HighHex+1)
+unsigned char HighHex[257] = { 0xFF,
+ 0xFD,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFD,0xFD,0xFE,0xFE,0xFE,0xFE,0xFE,
+ 0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,
+ 0xFD,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,
+ 0x00,0x10,0x20,0x30,0x40,0x50,0x60,0x70,0x80,0x90,0xFE,0xFE,0xFE,0xFE,0xFC,0xFE,
+ 0xFE,0xA0,0xB0,0xC0,0xD0,0xE0,0xF0,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,
+ 0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,
+ 0xFE,0xA0,0xB0,0xC0,0xD0,0xE0,0xF0,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,
+ 0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,
+ 0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,
+ 0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,
+ 0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,
+ 0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,
+ 0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,
+ 0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,
+ 0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,
+ 0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE
+};
+#define LowHexP (LowHex+1)
+unsigned char LowHex[257] = { 0xFF,
+ 0xFD,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFD,0xFD,0xFE,0xFE,0xFE,0xFE,0xFE,
+ 0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,
+ 0xFD,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,
+ 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0xFE,0xFE,0xFE,0xFE,0xFC,0xFE,
+ 0xFE,0x0A,0x0B,0x0C,0x0D,0x0E,0x0F,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,
+ 0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,
+ 0xFE,0x0A,0x0B,0x0C,0x0D,0x0E,0x0F,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,
+ 0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,
+ 0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,
+ 0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,
+ 0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,
+ 0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,
+ 0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,
+ 0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,
+ 0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,
+ 0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE
+};
+
+#endif
diff --git a/libXfont/src/Type1/hints.c b/libXfont/src/Type1/hints.c
new file mode 100644
index 000000000..14deac229
--- /dev/null
+++ b/libXfont/src/Type1/hints.c
@@ -0,0 +1,890 @@
+/* $Xorg: hints.c,v 1.3 2000/08/17 19:46:30 cpqbld Exp $ */
+/* Copyright International Business Machines, Corp. 1991
+ * All Rights Reserved
+ * Copyright Lexmark International, Inc. 1991
+ * All Rights Reserved
+ *
+ * License to use, copy, modify, and distribute this software and its
+ * documentation for any purpose and without fee is hereby granted,
+ * provided that the above copyright notice appear in all copies and that
+ * both that copyright notice and this permission notice appear in
+ * supporting documentation, and that the name of IBM or Lexmark not be
+ * used in advertising or publicity pertaining to distribution of the
+ * software without specific, written prior permission.
+ *
+ * IBM AND LEXMARK PROVIDE THIS SOFTWARE "AS IS", WITHOUT ANY WARRANTIES OF
+ * ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING, BUT NOT LIMITED TO ANY
+ * IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE,
+ * AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. THE ENTIRE RISK AS TO THE
+ * QUALITY AND PERFORMANCE OF THE SOFTWARE, INCLUDING ANY DUTY TO SUPPORT
+ * OR MAINTAIN, BELONGS TO THE LICENSEE. SHOULD ANY PORTION OF THE
+ * SOFTWARE PROVE DEFECTIVE, THE LICENSEE (NOT IBM OR LEXMARK) ASSUMES THE
+ * ENTIRE COST OF ALL SERVICING, REPAIR AND CORRECTION. IN NO EVENT SHALL
+ * IBM OR LEXMARK BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
+ * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
+ * THIS SOFTWARE.
+ */
+/* $XFree86: xc/lib/font/Type1/hints.c,v 1.7tsi Exp $ */
+
+ /* HINTS CWEB V0006 ******** */
+/*
+:h1.HINTS Module - Processing Rasterization Hints
+
+&author. Sten F. Andler; continuity by Jeffrey B. Lotspiech (lotspiech@almaden.ibm.com) and Duaine
+W. Pryor, Jr.
+
+
+:h3.Include Files
+
+The included files are:
+*/
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#ifdef FONTMODULE
+# include "os.h"
+#endif
+#include "objects.h"
+#include "spaces.h"
+#include "paths.h"
+#include "regions.h"
+#include "hints.h"
+
+/*
+:h3.Functions Provided to the TYPE1IMAGER User
+
+None.
+*/
+
+/*
+:h3.Functions Provided to Other Modules
+
+This module provides the following entry point to other modules:
+*/
+
+
+/*SHARED LINE(S) ORIGINATED HERE*/
+
+/*
+:h3.Macros Provided to Other Modules
+
+None.
+*/
+
+/*
+:h2.InitHints() - Initialize hint data structure
+*/
+
+#define MAXLABEL 20
+static struct {
+ int inuse;
+ int computed;
+ struct fractpoint hint;
+} oldHint[MAXLABEL];
+
+#define ODD(x) (((int)(x)) & 01)
+#define FPFLOOR(fp) TOFRACTPEL((fp) >> FRACTBITS)
+#define FPROUND(fp) FPFLOOR((fp) + FPHALF)
+
+void
+InitHints(void)
+{
+ int i;
+
+ for (i = 0; i < MAXLABEL; i++)
+ {
+ oldHint[i].inuse = FALSE;
+ oldHint[i].computed = FALSE;
+ }
+}
+
+/*
+:h3.CloseHints(hintP) - Reverse hints that are still open
+*/
+
+void
+CloseHints(struct fractpoint *hintP)
+{
+ int i;
+
+ for (i = 0; i < MAXLABEL; i++)
+ {
+ if (oldHint[i].inuse)
+ {
+ hintP->x -= oldHint[i].hint.x;
+ hintP->y -= oldHint[i].hint.y;
+
+ oldHint[i].inuse = FALSE;
+ }
+ }
+}
+
+/*
+:h3.ComputeHint(hP, currX, currY, hintP) - Compute the value of a hint
+*/
+
+static void
+ComputeHint(struct hintsegment *hP,
+ fractpel currX, fractpel currY,
+ struct fractpoint *hintP)
+{
+ fractpel currRef, currWidth;
+ int idealWidth;
+ fractpel hintValue;
+ char orientation;
+
+/*
+By construction, width is never zero. Therefore we can use the
+width value to determine if the hint has been rotated by a
+multiple of 90 degrees.
+*/
+
+ if (hP->width.y == 0)
+ {
+ orientation = 'v'; /* vertical */
+ }
+ else if (hP->width.x == 0)
+ {
+ orientation = 'h'; /* horizontal */
+ }
+ else
+ {
+ hintP->x = hintP->y = 0;
+ return;
+ }
+
+ /* Compute currRef and currWidth with a unit of 1 pel */
+ if (orientation == 'v') /* vertical */
+ {
+ currRef = hP->ref.x + currX;
+ currWidth = ABS(hP->width.x);
+ }
+ else if (orientation == 'h') /* horizontal */
+ {
+ currRef = hP->ref.y + currY;
+ currWidth = ABS(hP->width.y);
+ }
+ else /* error */
+ {
+ Abort("ComputeHint: invalid orientation");
+ }
+
+ if ((hP->hinttype == 'b') /* Bar or stem */
+ || (hP->hinttype == 's')) /* Serif */
+ {
+ idealWidth = NEARESTPEL(currWidth);
+ if (idealWidth == 0) idealWidth = 1;
+ if (ODD(idealWidth)) /* Is ideal width odd? */
+ {
+ /* center "ref" over pel */
+ hintValue = FPFLOOR(currRef) + FPHALF - currRef;
+ }
+ else
+ {
+ /* align "ref" on pel boundary */
+ hintValue = FPROUND(currRef) - currRef;
+ }
+ }
+ else if (hP->hinttype == 'c') /* Curve extrema */
+ {
+ /* align "ref" on pel boundary */
+ hintValue = FPROUND(currRef) - currRef;
+ }
+ else /* error */
+ {
+ Abort("ComputeHint: invalid hinttype");
+ }
+
+ if (orientation == 'v') /* vertical */
+ {
+ hintP->x = hintValue;
+ hintP->y = 0;
+ }
+ else if (orientation == 'h') /* horizontal */
+ {
+ hintP->x = 0;
+ hintP->y = hintValue;
+ }
+ else /* error */
+ {
+ Abort("ComputeHint: invalid orientation");
+ }
+}
+
+/*
+:h3.ProcessHint(hP, currX, currY, hintP) - Process a rasterization hint
+*/
+
+void
+ProcessHint(struct hintsegment *hP,
+ fractpel currX, fractpel currY,
+ struct fractpoint *hintP)
+{
+ struct fractpoint thisHint;
+
+ if ((hP->adjusttype == 'm') /* Move */
+ || (hP->adjusttype == 'a')) /* Adjust */
+ {
+ /* Look up hint in oldHint table */
+ if ((hP->label >= 0) && (hP->label < MAXLABEL))
+ {
+ if (oldHint[hP->label].computed)
+ /* Use old hint value if already computed */
+ {
+ thisHint.x = oldHint[hP->label].hint.x;
+ thisHint.y = oldHint[hP->label].hint.y;
+ oldHint[hP->label].inuse = TRUE;
+ }
+ else
+ /* Compute new value for hint and store it for future use */
+ {
+ ComputeHint(hP, currX, currY, &thisHint);
+
+ oldHint[hP->label].hint.x = thisHint.x;
+ oldHint[hP->label].hint.y = thisHint.y;
+ oldHint[hP->label].inuse = TRUE;
+ oldHint[hP->label].computed = TRUE;
+ }
+ }
+ else /* error */
+ {
+ Abort("ProcessHint: invalid label");
+ }
+ }
+ else if (hP->adjusttype == 'r') /* Reverse */
+ {
+ /* Use the inverse of the existing hint value to reverse hint */
+ if ((hP->label >= 0) && (hP->label < MAXLABEL))
+ {
+ if (oldHint[hP->label].inuse)
+ {
+ thisHint.x = -oldHint[hP->label].hint.x;
+ thisHint.y = -oldHint[hP->label].hint.y;
+ oldHint[hP->label].inuse = FALSE;
+ }
+ else /* error */
+ {
+ Abort("ProcessHint: label is not in use");
+ }
+ }
+ else /* error */
+ {
+ Abort("ProcessHint: invalid label");
+ }
+
+ }
+ else /* error */
+ {
+ Abort("ProcessHint: invalid adjusttype");
+ }
+
+ hintP->x += thisHint.x;
+ hintP->y += thisHint.y;
+}
+
+/*
+:h2 id=subpath.Navigation Through Edge Lists
+
+For continuity checking purposes, we need to navigate through edge
+lists by the "subpath" chains and answer questions about edges. The
+subpath chain links together edges that were part of the same subpath
+(no intervening move segments) when the interior of the path was
+calculated. Here we use the term "edge" to mean every edge list
+that was created in between changes of direction.
+
+The subpath chains are singly-linked circular chains. For the convenience
+of building them, they direction of the list (from edge to edge) is the
+reverse of the order in which they were built. Within any single edge,
+the subpath chain goes from top-to-bottom. (There might be a violation
+of this because of the way the user started the first chain; see
+:hdref refid=fixsubp..).
+
+:h3.ISTOP() and ISBOTTOM() - Flag Bits for Edge Lists at the Top and
+Bottom of Their SubPaths
+*/
+
+#define ISTOP(flag) ((flag)&0x20)
+#define ISBOTTOM(flag) ((flag)&0x10)
+/*
+:h3.ISLEFT() - Flag Bit for Left Edges
+*/
+
+#define ISLEFT(flag) ((flag)&0x08)
+
+/*
+:h3.XofY() - Macro to Find X Value at Given Y
+
+This macro can only be used if it is known that the Y is within the
+given edgelist's ymin and ymax.
+*/
+
+#define XofY(edge, y) edge->xvalues[y - edge->ymin]
+
+/*
+:h3.findXofY() - Like XofY(), Except not Restricted
+
+If the Y is out of bounds of the given edgelist, this macro will
+call SearchXofY to search the edge's subpath chain for the correct
+Y range. If the Y value is off the edge, MINPEL is returned.
+*/
+#define findXofY(edge, y) ((y < edge->ymin || y >= edge->ymax) ? SearchXofY(edge, y) : XofY(edge, y))
+
+/*
+:h4.SearchXofY() - Routine Called by FindXofY() for Difficult Cases
+
+The concept of this routine is to follow the subpath chain to find the
+edge just below (i.e., next in chain) or just above (i.e., immediately
+before in chain. It is assumed that the Y value is no more than one
+off of the edge's range; XofY() could be replace by FindXofY() to
+call ourselves recursively if this were not true.
+*/
+
+static pel
+SearchXofY(register struct edgelist *edge, /* represents edge */
+ register pel y) /* 'y' value to find edge for */
+{
+ register struct edgelist *e; /* loop variable */
+
+ if (y < edge->ymin) {
+ if (ISTOP(edge->flag))
+ return(MINPEL);
+ for (e = edge->subpath; e->subpath != edge; e = e->subpath) { ; }
+ if (e->ymax == edge->ymin)
+ return(XofY(e, y));
+ }
+ else if (y >= edge->ymax) {
+ if (ISBOTTOM(edge->flag))
+ return(MINPEL);
+ e = edge->subpath;
+ if (e->ymin == edge->ymax)
+ return(XofY(e, y));
+ }
+ else
+ return(XofY(edge, y));
+
+ Abort("bad subpath chain");
+ /*NOTREACHED*/
+}
+/*
+:h3.ISBREAK() Macro - Tests if an Edge List is at a "Break"
+
+The subpath chains are organized top to bottom. When the bottom of
+a given edge is reached, the subpath chain points to the top of the
+next edge. We call this a "break" in the chain. The following macro
+is the simple test for the break condition:
+*/
+
+#define ISBREAK(top,bot) (top->ymax != bot->ymin)
+
+
+/*
+:h3.ImpliedHorizontalLine() - Tests for Horizontal Connectivity
+
+This function returns true if two edges are connected horizontally.
+They are connected horizontally if they are consecutive in the subpath,
+and either we are at the bottom and the first edge is going down or we
+are at the top and the first edge is going up.
+*/
+
+#define BLACKABOVE -1
+#define BLACKBELOW +1
+#define NONE 0
+
+static int
+ImpliedHorizontalLine(struct edgelist *e1, /* two edges to check */
+ struct edgelist *e2,
+ int y) /* y where they might be connected */
+{
+ register struct edgelist *e3,*e4;
+
+ if (ISDOWN(e1->flag) == ISDOWN(e2->flag))
+ return(NONE); /* can't be consecutive unless different directions */
+/*
+Now we check for consecutiveness: Can we get from 'e1' to 'e2' with
+only one intervening break? Can we get from 'e2' to 'e1' with only one
+intervening break? 'e3' will be as far as we can get after 'e1'; 'e4'
+will be has far as we can get after 'e2':
+*/
+ for (e3 = e1; !ISBREAK(e3, e3->subpath); e3 = e3->subpath) { ; }
+ for (e3 = e3->subpath; e3 != e2; e3 = e3->subpath)
+ if (ISBREAK(e3, e3->subpath))
+ break;
+
+ for (e4 = e2; !ISBREAK(e4, e4->subpath); e4 = e4->subpath) { ; }
+ for (e4 = e4->subpath; e4 != e1; e4 = e4->subpath)
+ if (ISBREAK(e4, e4->subpath))
+ break;
+/*
+If the edges are mutually consecutive, we must have horizontal lines
+both top and bottom:
+*/
+ if (e3 == e2 && e4 == e1)
+ return(TRUE);
+/*
+If the edges are not consecutive either way, no horizontal lines are
+possible:
+*/
+ if (e3 != e2 && e4 != e1)
+ return(NONE);
+/*
+Now let's swap 'e1' and 'e2' if necessary to enforce the rule that 'e2'
+follows 'e1'. Remember that subpath chains go in the opposite direction
+from the way the subpaths were built; this led to the simplest way
+do build them.
+*/
+ if (e4 != e1) {
+ e2 = e1;
+ e1 = e3; /* remember e3 == e2, this just swaps 'e1' and 'e2' */
+ }
+/*
+Now we have everything to return the answer:
+*/
+ if (ISTOP(e1->flag) && y == e1->ymin)
+ return(ISDOWN(e2->flag));
+ else if (ISBOTTOM(e1->flag) && y == e1->ymax)
+ return(!ISDOWN(e2->flag));
+ else
+ Abort("ImpliedHorizontalLine: why ask?");
+ /*NOTREACHED*/
+}
+
+/*
+:h3 id=fixsubp.FixSubPaths() - Must be Called to Organize Subpath Chains
+
+The region-building code in Interior(), in particular splitedge(),
+maintains the rule that sub-paths are linked top-to-bottom except
+at breaks. However, it is possible that there may be a "false break"
+because the user started the subpath in the middle of an edge (and
+went in the "wrong" direction from there, up instead of down). This
+routine finds and fixes false breaks.
+
+Also, this routine sets the ISTOP and ISBOTTOM flags in the edge lists.
+*/
+
+static void
+FixSubPaths(struct region *R) /* anchor of region */
+{
+ register struct edgelist *e; /* fast loop variable */
+ register struct edgelist *edge; /* current edge in region */
+ register struct edgelist *next; /* next in subpath after 'edge' */
+ register struct edgelist *break1; /* first break after 'next' */
+ register struct edgelist *break2 = NULL; /* last break before 'edge' */
+ register struct edgelist *prev; /* previous edge for fixing links */
+ int left = TRUE;
+
+ for (edge = R->anchor; edge != NULL; edge = edge->link) {
+
+ if (left)
+ edge->flag |= ISLEFT(ON);
+ left = !left;
+
+ next = edge->subpath;
+
+ if (!ISBREAK(edge, next))
+ continue;
+ if (edge->ymax < next->ymin)
+ Abort("disjoint subpath?");
+/*
+'edge' now contains an edgelist at the bottom of an edge, and 'next'
+contains the next subsequent edgelist in the subpath, which must be at
+the top. We refer to this a "break" in the subpath.
+*/
+ next->flag |= ISTOP(ON);
+ edge->flag |= ISBOTTOM(ON);
+
+ if (ISDOWN(edge->flag) != ISDOWN(next->flag))
+ continue;
+/*
+We are now in the unusual case; both edges are going in the same
+direction so this must be a "false break" due to the way that the user
+created the path. We'll have to fix it.
+*/
+ for (break1 = next; !ISBREAK(break1, break1->subpath); break1 = break1->subpath) { ; }
+
+ for (e = break1->subpath; e != edge; e = e->subpath)
+ if (ISBREAK(e, e->subpath))
+ break2 = e;
+/*
+Now we've set up 'break1' and 'break2'. I've found the following
+diagram invaluable. 'break1' is the first break after 'next'. 'break2'
+is the LAST break before 'edge'.
+&drawing.
+ next
+ +------+ +---->+------+
+ +--->| >-----+ | | >-----+
+ | | | | | | | |
+ | +-------------+ | +-------------+
+ | | |break1| | | | |
+ | +->| >-------+ +->| >-----+
+ | | | | | |
+ | | | +-------------+
+ | +------+ | | |
+ | +----------------+ | | |
+ | | +------+ | +->| >-----+
+ | +->| >-----+ | | | |
+ | | | | | +-------------+
+ | +-------------+ | | | |
+ | | |edge | | | |break2|
+ | +->| >-----+ | +->| >-----+
+ | | | | | | | |
+ | | | | | | | |
+ | | | | | | | |
+ | +------+ | | +------+ |
+ | | | |
+ +---------------+ +---------------+
+
+&edrawing.
+We want to fix this situation by having 'edge' point to where 'break1'
+now points, and having 'break1' point to where 'break2' now points.
+Finally, 'break2' should point to 'next'. Also, we observe that
+'break1' can't be a bottom, and is also not a top unless it is the same
+as 'next':
+*/
+ edge->subpath = break1->subpath;
+
+ break1->subpath = break2->subpath;
+ if (ISBREAK(break1, break1->subpath))
+ Abort("unable to fix subpath break?");
+
+ break2->subpath = next;
+
+ break1->flag &= ~ISBOTTOM(ON);
+ if (break1 != next)
+ break1->flag &= ~ISTOP(ON);
+ }
+/*
+This region might contain "ambiguous" edges; edges exactly equal to
+edge->link. Due to the random dynamics of where they get sorted into
+the list, they can yield false crossings, where the edges appear
+to cross. This confuses our continuity logic no end. Since we can
+swap them without changing the region, we do.
+*/
+ for (edge = R->anchor, prev = NULL; VALIDEDGE(edge); prev = edge, edge = prev->link) {
+
+ if (! ISAMBIGUOUS(edge->flag))
+ continue;
+
+ next = edge->subpath;
+
+ while (ISAMBIGUOUS(next->flag) && next != edge)
+ next = next->subpath;
+/*
+We've finally found a non-ambiguous edge; we make sure it is left/right
+compatible with 'edge':
+*/
+ if ( (ISLEFT(edge->flag) == ISLEFT(next->flag) && ISDOWN(edge->flag) == ISDOWN(next->flag) )
+ || (ISLEFT(edge->flag) != ISLEFT(next->flag) && ISDOWN(edge->flag) != ISDOWN(next->flag) ) )
+ continue;
+
+/*
+Incompatible, we will swap 'edge' and the following edge in the list.
+You may think that there must be a next edge in this swath. So did I.
+No! If there is a totally ambiguous inner loop, for example, we could
+get all the way to the outside without resolving ambiguity.
+*/
+ next = edge->link; /* note new meaning of 'next' */
+ if (next == NULL || edge->ymin != next->ymin)
+ continue;
+ if (prev == NULL)
+ R->anchor = next;
+ else
+ prev->link = next;
+ edge->link = next->link;
+ next->link = edge;
+ edge->flag ^= ISLEFT(ON);
+ edge->flag &= ~ISAMBIGUOUS(ON);
+ next->flag ^= ISLEFT(ON);
+ next->flag &= ~ISAMBIGUOUS(ON);
+ edge = next;
+ }
+}
+/*
+:h3.DumpSubPaths()
+
+A debug tool.
+*/
+
+static struct edgelist *before(struct edgelist *e); /* subroutine of DumpSubPaths */
+
+static void
+DumpSubPaths(struct edgelist *anchor)
+{
+
+ register struct edgelist *edge,*e,*e2;
+ pel y;
+
+ for (edge = anchor; VALIDEDGE(edge); edge = edge->link) {
+ if (ISPERMANENT(edge->flag))
+ continue;
+ for (e2 = edge; !ISPERMANENT(e2->flag);) {
+ if (ISDOWN(e2->flag)) {
+ for (e = e2;; e = e->subpath) {
+ for (y=e->ymin+1; y < e->ymax; y++)
+ e->flag |= ISPERMANENT(ON);
+ if (ISBREAK(e, e->subpath))
+ break;
+ }
+ }
+ else {
+ for (e = e2; !ISBREAK(e, e->subpath); e = e->subpath) { ; }
+ for (;; e=before(e)) {
+ for (y=e->ymax-2; y >= e->ymin; y--)
+ e->flag |= ISPERMANENT(ON);
+ if (e == e2)
+ break;
+ }
+ }
+ do {
+ e2 = before(e2);
+ } while (!ISBREAK(before(e2), e2));
+ }
+ }
+}
+
+static struct edgelist *
+before(struct edgelist *e)
+{
+ struct edgelist *r;
+ for (r = e->subpath; r->subpath != e; r = r->subpath) { ; }
+ return(r);
+}
+
+/*
+:h2.Fixing Region Continuity Problems
+
+Small regions may become disconnected when their connecting segments are
+less than a pel wide. This may be correct in some applications, but in
+many (especially small font characters), it is more pleasing to keep
+connectivity. ApplyContinuity() (invoked by +CONTINUITY on the
+Interior() fill rule) fixes connection breaks. The resulting region
+is geometrically less accurate, but may be more pleasing to the eye.
+*/
+/*
+Here are some macros which we will need:
+*/
+
+#define IsValidPel(j) (j!=MINPEL)
+
+/*
+:h3.writeXofY() - Stuffs an X Value Into an "edgelist"
+
+writeXofY writes an x value into an edge at position 'y'. It must
+update the edge's xmin and xmax. If there is a possibility that this
+new x might exceed the region's bounds, updating those are the
+responsibility of the caller.
+*/
+
+static void
+writeXofY(struct edgelist *e,/* relevant edgelist */
+ int y, /* y value */
+ int x) /* new x value */
+{
+ if (e->xmin > x) e->xmin = x;
+ if (e->xmax < x) e->xmax = x;
+ e->xvalues[y - e->ymin] = x;
+}
+
+/*-------------------------------------------------------------------------*/
+/* the following three macros tell us whether we are at a birth point, a */
+/* death point, or simply in the middle of the character */
+/*-------------------------------------------------------------------------*/
+#define WeAreAtTop(e,i) (ISTOP(e->flag) && e->ymin == i)
+#define WeAreAtBottom(e,i) (ISBOTTOM(e->flag) && e->ymax-1 == i)
+#define WeAreInMiddle(e,i) \
+ ((!ISTOP(e->flag) && !ISBOTTOM(e->flag))||(i < e->ymax-1 && i > e->ymin))
+/*
+The following macro tests if two "edgelist" structures are in the same
+swath:
+*/
+#define SAMESWATH(e1,e2) (e1->ymin == e2->ymin)
+
+/*
+:h3.CollapseWhiteRun() - Subroutine of ApplyContinuity()
+
+When we have a white run with an implied horizontal line above or
+below it, we better have black on the other side of this line. This
+function both tests to see if black is there, and adjusts the end
+points (collapses) the white run as necessary if it is not. The
+goal is to collapse the white run as little as possible.
+*/
+
+static void
+CollapseWhiteRun(struct edgelist *anchor, /* anchor of edge list */
+ pel yblack, /* y of (hopefully) black run above or below */
+ struct edgelist *left, /* edgelist at left of WHITE run */
+ struct edgelist *right, /* edgelist at right of WHITE run */
+ pel ywhite) /* y location of white run */
+{
+ struct edgelist *edge;
+ struct edgelist *swathstart = anchor;
+ register pel x;
+
+ if (XofY(left, ywhite) >= XofY(right, ywhite))
+ return;
+/*
+Find the swath with 'yblack'. If we don't find it, completely collapse
+the white run and return:
+*/
+ while (VALIDEDGE(swathstart)) {
+ if (yblack < swathstart->ymin) {
+ writeXofY(left, ywhite, XofY(right, ywhite));
+ return;
+ }
+ if (yblack < swathstart->ymax) break;
+ swathstart = swathstart->link->link;
+ }
+ if(!VALIDEDGE(swathstart)) {
+ writeXofY(left, ywhite, XofY(right, ywhite));
+ return;
+ }
+/*
+Now we are in the swath that contains 'y', the reference line above
+or below that we are trying to maintain continuity with. If black
+in this line begins in the middle of our white run, we must collapse
+the white run from the left to that point. If black ends in the
+middle of our white run, we must collapse the white run from the right
+to that point.
+*/
+ for (edge = swathstart; VALIDEDGE(edge); edge = edge->link) {
+
+ if (!SAMESWATH(swathstart,edge))
+ break;
+ if( XofY(edge, yblack) > XofY(left, ywhite)) {
+ if (ISLEFT(edge->flag)) {
+ x = XofY(edge, yblack);
+ if (XofY(right, ywhite) < x)
+ x = XofY(right, ywhite);
+ writeXofY(left, ywhite, x);
+ }
+ else {
+ x = XofY(edge, yblack);
+ while (edge->link != NULL && SAMESWATH(edge, edge->link)
+ && x >= XofY(edge->link, yblack) ) {
+ edge = edge->link->link;
+ x = XofY(edge, yblack);
+ }
+ if (x < XofY(right, ywhite))
+ writeXofY(right, ywhite, x);
+ return;
+ }
+ }
+ }
+ writeXofY(left, ywhite, XofY(right, ywhite));
+}
+
+/*
+:h3.ApplyContinuity() - Fix False Breaks in a Region
+
+This is the externally visible routine called from the REGIONS module
+when the +CONTINUITY flag is on the Interior() fill rule.
+*/
+
+void
+ApplyContinuity(struct region *R)
+{
+ struct edgelist *left;
+ struct edgelist *right;
+ struct edgelist *edge,*e2;
+ pel rightXabove,rightXbelow,leftXabove,leftXbelow;
+ pel leftX,rightX;
+ int i;
+ long newcenter,abovecenter,belowcenter;
+
+ FixSubPaths(R);
+ if (RegionDebug >= 3)
+ DumpSubPaths(R->anchor);
+ left = R->anchor;
+/* loop through and do all of the easy checking. ( no tops or bottoms) */
+ while(VALIDEDGE(left))
+ {
+ right = left->link;
+ for(i=left->ymin;i<left->ymax;++i)
+ {
+ leftX = findXofY(left,i);
+ rightX = findXofY(right,i);
+ leftXbelow = findXofY(left,i+1);
+ rightXbelow = findXofY(right,i+1);
+ if(rightX <= leftX)
+ {
+/* then, we have a break in a near vertical line */
+ leftXabove = findXofY(left,i-1);
+ rightXabove = findXofY(right,i-1);
+ if( IsValidPel(leftXabove) && IsValidPel(rightXabove) )
+ {
+ abovecenter = leftXabove + rightXabove;
+ }
+ else
+ {
+ abovecenter = leftX + rightX;
+ }
+ if( IsValidPel(leftXbelow) && IsValidPel(rightXbelow) )
+ {
+ belowcenter = leftXbelow + rightXbelow;
+ }
+ else
+ {
+ belowcenter = leftX + rightX;
+ }
+ newcenter = abovecenter + belowcenter;
+ if( newcenter > 4*leftX )
+ {
+ rightX = rightX + 1;
+ }
+ else if( newcenter < 4*leftX)
+ {
+ leftX = leftX - 1;
+ }
+ else
+ {
+ rightX = rightX + 1;
+ }
+ writeXofY(right,i,rightX);
+ writeXofY(left,i,leftX);
+ if(rightX > R->xmax) {R->xmax = rightX;}
+ if(leftX < R->xmin) {R->xmin = leftX;}
+ }
+ if( !WeAreAtBottom(left,i) && (leftXbelow>=rightX))
+ {
+/* then we have a break in a near horizontal line in the middle */
+ writeXofY(right,i,leftXbelow);
+ }
+ if( !WeAreAtBottom(right,i) && (leftX >=rightXbelow))
+ {
+/* then we have a break in a near horizontal line in the middle */
+ writeXofY(left,i,rightXbelow);
+ }
+ }
+ left = right->link;
+ }
+/*
+There may be "implied horizontal lines" between edges that have
+implications for continuity. This loop looks for white runs that
+have implied horizontal lines on the top or bottom, and calls
+CollapseWhiteRuns to check and fix any continuity problems from
+them.
+*/
+ for (edge = R->anchor; VALIDEDGE(edge); edge = edge->link) {
+ if ((!ISTOP(edge->flag) && !ISBOTTOM(edge->flag)) || ISLEFT(edge->flag))
+ continue; /* at some future date we may want left edge logic here too */
+ for (e2 = edge->link; VALIDEDGE(e2) && SAMESWATH(edge,e2); e2 = e2->link) {
+ if (ISTOP(e2->flag) && ISTOP(edge->flag)
+ && NONE != ImpliedHorizontalLine(edge,e2,edge->ymin)) {
+ if (ISLEFT(e2->flag))
+ CollapseWhiteRun(R->anchor, edge->ymin-1,
+ edge, e2, edge->ymin);
+ }
+ if (ISBOTTOM(e2->flag) && ISBOTTOM(edge->flag)
+ && NONE != ImpliedHorizontalLine(edge,e2, edge->ymax)) {
+ if (ISLEFT(e2->flag))
+ CollapseWhiteRun(R->anchor, edge->ymax,
+ edge, e2, edge->ymax-1);
+ }
+ }
+ }
+}
+
+
+
+
diff --git a/libXfont/src/Type1/hints.h b/libXfont/src/Type1/hints.h
new file mode 100644
index 000000000..8e2ae2ade
--- /dev/null
+++ b/libXfont/src/Type1/hints.h
@@ -0,0 +1,48 @@
+/* $Xorg: hints.h,v 1.3 2000/08/17 19:46:30 cpqbld Exp $ */
+/* Copyright International Business Machines, Corp. 1991
+ * All Rights Reserved
+ * Copyright Lexmark International, Inc. 1991
+ * All Rights Reserved
+ *
+ * License to use, copy, modify, and distribute this software and its
+ * documentation for any purpose and without fee is hereby granted,
+ * provided that the above copyright notice appear in all copies and that
+ * both that copyright notice and this permission notice appear in
+ * supporting documentation, and that the name of IBM or Lexmark not be
+ * used in advertising or publicity pertaining to distribution of the
+ * software without specific, written prior permission.
+ *
+ * IBM AND LEXMARK PROVIDE THIS SOFTWARE "AS IS", WITHOUT ANY WARRANTIES OF
+ * ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING, BUT NOT LIMITED TO ANY
+ * IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE,
+ * AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. THE ENTIRE RISK AS TO THE
+ * QUALITY AND PERFORMANCE OF THE SOFTWARE, INCLUDING ANY DUTY TO SUPPORT
+ * OR MAINTAIN, BELONGS TO THE LICENSEE. SHOULD ANY PORTION OF THE
+ * SOFTWARE PROVE DEFECTIVE, THE LICENSEE (NOT IBM OR LEXMARK) ASSUMES THE
+ * ENTIRE COST OF ALL SERVICING, REPAIR AND CORRECTION. IN NO EVENT SHALL
+ * IBM OR LEXMARK BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
+ * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
+ * THIS SOFTWARE.
+ */
+/* $XFree86: xc/lib/font/Type1/hints.h,v 1.3 1999/08/22 08:58:51 dawes Exp $ */
+
+/*SHARED*/
+
+#define InitHints t1_InitHints
+extern void t1_InitHints ( void ); /* Initialize hint data structure */
+
+#define CloseHints(hintP) t1_CloseHints(hintP)
+/* Reverse hints that are still open */
+extern void t1_CloseHints ( struct fractpoint *hintP );
+
+#define ProcessHint(hP, currX, currY, hintP) t1_ProcessHint(hP, currX, currY, hintP)
+/* Process a rasterization hint */
+extern void t1_ProcessHint ( struct hintsegment *hP, fractpel currX, fractpel currY, struct fractpoint *hintP );
+
+#define ApplyContinuity(R) t1_ApplyContinuity(R)
+/* fix false connection breaks in a region */
+extern void t1_ApplyContinuity ( struct region *R );
+
+/*END SHARED*/
diff --git a/libXfont/src/Type1/lines.c b/libXfont/src/Type1/lines.c
new file mode 100644
index 000000000..72fb79f97
--- /dev/null
+++ b/libXfont/src/Type1/lines.c
@@ -0,0 +1,188 @@
+/* $Xorg: lines.c,v 1.3 2000/08/17 19:46:30 cpqbld Exp $ */
+/* Copyright International Business Machines, Corp. 1991
+ * All Rights Reserved
+ * Copyright Lexmark International, Inc. 1991
+ * All Rights Reserved
+ *
+ * License to use, copy, modify, and distribute this software and its
+ * documentation for any purpose and without fee is hereby granted,
+ * provided that the above copyright notice appear in all copies and that
+ * both that copyright notice and this permission notice appear in
+ * supporting documentation, and that the name of IBM or Lexmark not be
+ * used in advertising or publicity pertaining to distribution of the
+ * software without specific, written prior permission.
+ *
+ * IBM AND LEXMARK PROVIDE THIS SOFTWARE "AS IS", WITHOUT ANY WARRANTIES OF
+ * ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING, BUT NOT LIMITED TO ANY
+ * IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE,
+ * AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. THE ENTIRE RISK AS TO THE
+ * QUALITY AND PERFORMANCE OF THE SOFTWARE, INCLUDING ANY DUTY TO SUPPORT
+ * OR MAINTAIN, BELONGS TO THE LICENSEE. SHOULD ANY PORTION OF THE
+ * SOFTWARE PROVE DEFECTIVE, THE LICENSEE (NOT IBM OR LEXMARK) ASSUMES THE
+ * ENTIRE COST OF ALL SERVICING, REPAIR AND CORRECTION. IN NO EVENT SHALL
+ * IBM OR LEXMARK BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
+ * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
+ * THIS SOFTWARE.
+ */
+/* $XFree86: xc/lib/font/Type1/lines.c,v 1.4tsi Exp $ */
+
+ /* LINES CWEB V0003 ******** */
+/*
+:h1.LINES Module - Rasterizing Lines
+
+&author. Duaine W. Pryor, Jr. and Jeffrey B. Lotspiech (lotspiech@almaden.ibm.com)
+
+
+:h3.Include Files
+
+The included files are:
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "objects.h"
+#include "spaces.h"
+#include "paths.h"
+#include "regions.h"
+#include "lines.h"
+
+/*
+:h3.Functions Provided to the TYPE1IMAGER User
+
+None.
+*/
+
+/*
+:h3.Functions Provided to Other Modules
+
+This module provides the following entry point to other modules:
+*/
+
+/*SHARED LINE(S) ORIGINATED HERE*/
+
+/*
+:h3.Macros Provided to Other Modules
+
+None.
+*/
+
+/*
+:h3.Bresenham() - Actually Produces Run Ends
+
+This routine runs a Bresenham line-stepping
+algorithm. See, for example, Newman and Sproul, :hp1/Principles
+of Interactive Computer Graphics/, pp. 25-27.
+When we enter this, we
+are guaranteed that dy is positive.
+We'd like to work in 8 bit precision, so we'll define some macros and
+constants to let us do that:
+*/
+
+#define PREC 8 /* we'll keep fraction pels in 8 bit precision */
+/*
+RoundFP() rounds down by 'b' bits:
+*/
+#define RoundFP(xy,b) (((xy)+(1<<((b)-1)))>>(b))
+
+/*
+TruncFP() truncates down by 'b' bits:
+*/
+#define TruncFP(xy,b) ((xy)>>(b))
+
+
+static void
+Bresenham(pel *edgeP, fractpel x1, fractpel y1, fractpel x2, fractpel y2)
+{
+ register long dx,dy; /* change in x and y, in my own precision */
+ register long x,y; /* integer pel starting point */
+ register int count; /* integer pel delta y */
+ register long d; /* the Bresenham algorithm error term */
+
+ x1 = TruncFP(x1, FRACTBITS-PREC);
+ y1 = TruncFP(y1, FRACTBITS-PREC);
+ x2 = TruncFP(x2, FRACTBITS-PREC);
+ y2 = TruncFP(y2, FRACTBITS-PREC);
+
+ dx = x2 - x1;
+ dy = y2 - y1;
+/*
+Find the starting x and y integer pel coordinates:
+*/
+
+ x = RoundFP(x1,PREC);
+ y = RoundFP(y1,PREC);
+ edgeP += y;
+ count = RoundFP(y2,PREC) - y;
+/*------------------------------------------------------------------*/
+/* Force dx to be positive so that dfy will be negative */
+/* this means that vertical moves will decrease d */
+/*------------------------------------------------------------------*/
+ if (dx<0)
+ {
+ dx = -dx;
+#define P PREC
+ d=(dy*(x1-(x<<P)+(1<<(P-1)))-dx*((y<<P)-y1+(1<<(P-1))))>>P;
+#undef P
+ while(--count >= 0 )
+ {
+ while(d<0)
+ {
+ --x;
+ d += dy;
+ }
+ *(edgeP++) = x;
+ d -= dx;
+ }
+ }
+ else /* positive dx */
+ {
+#define P PREC
+ d = (dy*((x<<P)-x1+(1<<(P-1)))-dx*((y<<P)-y1+(1<<(P-1))))>>P;
+#undef P
+ while(--count >= 0 )
+ {
+ while(d<0)
+ {
+ ++x;
+ d += dy;
+ }
+ *(edgeP++) = x;
+ d -= dx;
+ }
+ }
+}
+
+/*
+:h2.StepLine() - Produces Run Ends for a Line After Checks
+
+The main work is done by Bresenham(); here we just perform checks and
+get the line so that its Y direction is always increasing:
+*/
+
+void StepLine(R, x1, y1, x2, y2)
+ register struct region *R; /* region being built */
+ register fractpel x1,y1; /* starting point */
+ register fractpel x2,y2; /* ending point */
+{
+ register fractpel dy;
+
+ dy = y2 - y1;
+
+/*
+We execute the "GOING_TO" macro to call back the REGIONS module, if
+necessary (like if the Y direction of the edge has changed):
+*/
+ GOING_TO(R, x1, y1, x2, y2, dy);
+
+ if (dy == 0)
+ return;
+
+ if (dy < 0)
+ Bresenham(R->edge, x2, y2, x1, y1);
+ else
+ Bresenham(R->edge, x1, y1, x2, y2);
+ return;
+}
diff --git a/libXfont/src/Type1/lines.h b/libXfont/src/Type1/lines.h
new file mode 100644
index 000000000..4efe5a689
--- /dev/null
+++ b/libXfont/src/Type1/lines.h
@@ -0,0 +1,37 @@
+/* $Xorg: lines.h,v 1.3 2000/08/17 19:46:30 cpqbld Exp $ */
+/* Copyright International Business Machines, Corp. 1991
+ * All Rights Reserved
+ * Copyright Lexmark International, Inc. 1991
+ * All Rights Reserved
+ *
+ * License to use, copy, modify, and distribute this software and its
+ * documentation for any purpose and without fee is hereby granted,
+ * provided that the above copyright notice appear in all copies and that
+ * both that copyright notice and this permission notice appear in
+ * supporting documentation, and that the name of IBM or Lexmark not be
+ * used in advertising or publicity pertaining to distribution of the
+ * software without specific, written prior permission.
+ *
+ * IBM AND LEXMARK PROVIDE THIS SOFTWARE "AS IS", WITHOUT ANY WARRANTIES OF
+ * ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING, BUT NOT LIMITED TO ANY
+ * IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE,
+ * AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. THE ENTIRE RISK AS TO THE
+ * QUALITY AND PERFORMANCE OF THE SOFTWARE, INCLUDING ANY DUTY TO SUPPORT
+ * OR MAINTAIN, BELONGS TO THE LICENSEE. SHOULD ANY PORTION OF THE
+ * SOFTWARE PROVE DEFECTIVE, THE LICENSEE (NOT IBM OR LEXMARK) ASSUMES THE
+ * ENTIRE COST OF ALL SERVICING, REPAIR AND CORRECTION. IN NO EVENT SHALL
+ * IBM OR LEXMARK BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
+ * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
+ * THIS SOFTWARE.
+ */
+/* $XFree86: xc/lib/font/Type1/lines.h,v 1.3 1999/08/22 08:58:52 dawes Exp $ */
+
+/*SHARED*/
+
+#define StepLine(R,x1,y1,x2,y2) t1_StepLine(R,x1,y1,x2,y2)
+
+extern void t1_StepLine ( struct region *R, fractpel x1, fractpel y1, fractpel x2, fractpel y2 );
+
+/*END SHARED*/
diff --git a/libXfont/src/Type1/objects.c b/libXfont/src/Type1/objects.c
new file mode 100644
index 000000000..7a49bcbba
--- /dev/null
+++ b/libXfont/src/Type1/objects.c
@@ -0,0 +1,944 @@
+/* $Xorg: objects.c,v 1.3 2000/08/17 19:46:30 cpqbld Exp $ */
+/* Copyright International Business Machines, Corp. 1991
+ * All Rights Reserved
+ * Copyright Lexmark International, Inc. 1991
+ * All Rights Reserved
+ *
+ * License to use, copy, modify, and distribute this software and its
+ * documentation for any purpose and without fee is hereby granted,
+ * provided that the above copyright notice appear in all copies and that
+ * both that copyright notice and this permission notice appear in
+ * supporting documentation, and that the name of IBM or Lexmark not be
+ * used in advertising or publicity pertaining to distribution of the
+ * software without specific, written prior permission.
+ *
+ * IBM AND LEXMARK PROVIDE THIS SOFTWARE "AS IS", WITHOUT ANY WARRANTIES OF
+ * ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING, BUT NOT LIMITED TO ANY
+ * IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE,
+ * AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. THE ENTIRE RISK AS TO THE
+ * QUALITY AND PERFORMANCE OF THE SOFTWARE, INCLUDING ANY DUTY TO SUPPORT
+ * OR MAINTAIN, BELONGS TO THE LICENSEE. SHOULD ANY PORTION OF THE
+ * SOFTWARE PROVE DEFECTIVE, THE LICENSEE (NOT IBM OR LEXMARK) ASSUMES THE
+ * ENTIRE COST OF ALL SERVICING, REPAIR AND CORRECTION. IN NO EVENT SHALL
+ * IBM OR LEXMARK BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
+ * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
+ * THIS SOFTWARE.
+ */
+/* $XFree86: xc/lib/font/Type1/objects.c,v 1.10tsi Exp $ */
+ /* OBJECTS CWEB V0025 ******** */
+/*
+:h1.OBJECTS Module - TYPE1IMAGER Objects Common Routines
+
+This module defines and implements the C structures that represent
+objects in the TYPE1IMAGER. All common routines for manipulating these
+objects are defined in this module. Specific routines for
+specific objects are defined in the modules that deal with that
+object type.
+
+
+&author. Jeffrey B. Lotspiech (lotspiech@almaden.ibm.com)
+
+
+:h3.Include Files
+
+The included files are:
+*/
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#define GLOBALS 1 /* see :hdref refid=debugvar. */
+/*
+The following two includes are C standards; we include them because we
+use 'toupper' and the 'str'-type functions in this module. Potentially
+these may be defined as macros; if these ".h" files do not exist on your
+system it is a pretty safe bet that these are external entry points and
+you do do not need to include these header files.
+*/
+
+#ifndef FONTMODULE
+#include <string.h>
+#include <ctype.h>
+#include <stdarg.h>
+#include <stdio.h>
+#else
+#include "Xdefs.h" /* Bool declaration */
+#include "Xmd.h" /* INT32 declaration */
+#include "os.h"
+#include "xf86_ansic.h"
+#endif
+
+/*
+override incorrect system functions; for example you might define
+a macro for "strcpy" that diverts it to "my_strcpy".
+*/
+
+ /* moved these includes from above the */
+ /* was included first (it contains com- */
+ /* piler defines). dsr 081291 */
+#include "objects.h"
+#include "spaces.h"
+#include "paths.h"
+#include "regions.h"
+#include "fonts.h"
+#include "pictures.h"
+#include "strokes.h"
+#include "cluts.h"
+
+static char LineIOTrace INITIALIZED(TRUE);
+static char MustCrash INITIALIZED(TRUE);
+static char *TypeFmt(int type);
+
+/*
+:h3.The "pointer" Macro - Define a Generic Pointer
+
+Sadly, many compilers will give a warning message when a pointer to
+one structure is assigned to a pointer to another. We've even seen
+some that give severe errors (when the wrong pointer type is used as
+an initializer or returned from a function). TYPE1IMAGER has routines
+like Dup and Allocate that are perfectly willing to duplicate or
+allocate any of a number of different types of structures. How to
+declare them in a truely portable way?
+
+Well, there is no single good answer that I've found. You can always
+beg the question and "cast" everything. I find this distracting and the
+resulting code ugly. On the other hand, we have found at least one
+compiler that will accept "void *" as a generic pointer that can
+assigned to any other pointer type without error or warning (apparently
+this is also the ANSI standard). So, we define "void *" to be a generic
+pointer. (You might have to change this for your compiler; the "ifndef"
+allows the change to be made on the command line if you want.)
+:i1/portability assumptions/
+*/
+/*SHARED LINE(S) ORIGINATED HERE*/
+/*
+:h3.Functions Provided to the TYPE1IMAGER User
+
+This module provides the following TYPE1IMAGER entry points:
+*/
+/*SHARED LINE(S) ORIGINATED HERE*/
+/*
+Note that entry points that are intended for use external to TYPE1IMAGER
+begin with the characters :q/xi/. Macros are used to make the names
+more mnemonic.
+*/
+
+/*
+:h3.Functions Provided to Other Modules
+
+This module provides the following functions for other modules:
+*/
+/*SHARED LINE(S) ORIGINATED HERE*/
+/*
+Note that entry points that intended for use within TYPE1IMAGER, but
+which must be global because they are used across module boundaries,
+begin with the characters :q/I_/. Macros are used to make the names
+more mnemonic.
+
+Entry points totally within a module use mnemonic names and are
+declared :hp2/static/. One of the compilers I used had a bug when
+static functions were passed as addresses. Thus, some functions
+which are logically "static" are not so declared.
+
+Note also the trick of declaring routines, like Consume(), with a
+variable number of arguments. To avoid the restrictions on variable
+numbers of arguments in the macro processor, we just replace the
+text 'Consume' with 'I_Consume'.
+*/
+/*
+:h3.Macros Provided to Other Modules
+
+This is the module where we define all the useful constants like
+TRUE, FALSE, and NULL, and simple expressions like MIN(), MAX(), and ABS().
+We might as well get to it right here:
+*/
+/*SHARED LINE(S) ORIGINATED HERE*/
+/*
+Notice that upper case is used for constant values and macro
+definitions. I generally follow that convention.
+
+Many more global macros are defined later in this module.
+*/
+/*
+:h2.Basic TYPE1IMAGER Object Structure
+
+All TYPE1IMAGER objects which are available to the user have a common
+header. This header is defined below:
+*/
+
+/*SHARED LINE(S) ORIGINATED HERE*/
+/*
+The following define is an attempt to centralize the definition of the
+common xobject data shared by structures that are derived from the
+generic xobject structure. For example, the structure font, defined in
+fonts.shr :
+&code.
+ struct font {
+ char type;
+ char flag;
+ int references;
+ ... other data types & structs ...
+ }
+&ecode.
+would now be defined as:
+&code.
+ struct font {
+ XOBJ_COMMON
+ ... other data types & structs ...
+ }
+&ecode.
+Thus we have a better-structured inheritance mechanism. 3-26-91 PNM
+*/
+/*SHARED LINE(S) ORIGINATED HERE*/
+/*
+:h3.Object Type Definitions
+
+These constants define the values which go in the 'type' field of
+an TYPE1IMAGER object structure:
+*/
+/*SHARED LINE(S) ORIGINATED HERE*/
+/*
+:h3.Flag Byte Definitions
+
+Many programmers define flag bits as a mask (for example, 0x04), and
+test, set, and reset them as follows:
+
+&code.
+ if ((flag & PERMANENT) != 0)
+
+ flag |= PERMANENT;
+ flag &= &inv.PERMANENT;
+:exmp.
+
+I favor a style where the 'if' statement can ask a question:
+
+&code.
+ if (ISPERMANENT(flag))
+
+ flag |= ISPERMANENT(ON);
+ flag &= &inv.ISPERMANENT(ON);
+
+:exmp.
+This said, we now define two bit settings of the flag byte of the
+object. "ISPERMANENT" will be set by the user, when he calls
+Permanent(). "ISIMMORTAL" will be used for compiled-in objects
+that we don't want the user to ever destroy.
+*/
+/*SHARED LINE(S) ORIGINATED HERE*/
+/*
+Flag bit definitions that apply to all objects are assigned
+starting with the least significant (0x01) bit. Flag bit definitions
+specific to a certain object type are assigned starting with the
+most significant (0x80) bit. We hope they never meet.
+*/
+/*
+:h3 id=preserve.PRESERVE() Macro
+
+Occasionally an TYPE1IMAGER operator is implemented by calling other
+TYPE1IMAGER operators. For example, Arc2() calls Conic(). When we
+call more than one operator as a subroutine, we have to be careful
+of temporary objects. A temporary object will be consumed by the
+subroutine operator and then is no longer available for the caller.
+This can be prevented simply by bumping a temporary object's reference
+count.
+*/
+/*SHARED LINE(S) ORIGINATED HERE*/
+
+/*
+:h3.RefRoll() Macro to Detect References Count Rollover
+
+The following macro is designed to check for reference count rollover.
+A return value of TRUE means rollover has not occurred; a return value
+of FALSE means we cannot increment the reference count. Note also that
+those functions that use this macro must decrement the reference count
+afterwards. 3-26-91 PNM
+*/
+
+#define RefRoll(obj) (++(obj)->references > 0)
+
+/*
+:h2.TYPE1IMAGER Object Functions
+
+:h3.LONGCOPY() - Macro to Copy "long" Aligned Data
+
+Copying arbitrary bytes in C is a bit of a problem. "strcpy" can't be
+used, because 0 bytes are special-cased. Most environments have a
+routine "memcopy" or "bcopy" or "bytecopy" that copies memory containing
+zero bytes. Sadly, there is no standard on the name of such a routine,
+which makes it impossible to write truely portable code to use it.
+
+It turns out that TYPE1IMAGER, when it wants to copy data, frequently
+knows that both the source and destination are aligned on "long"
+boundaries. This allows us to copy by using "long *" pointers. This
+is usually very efficient on almost all processors. Frequently, it
+is more efficient than using general-purpose assembly language routines.
+So, we define a macro to do this in a portable way. "dest" and "source"
+must be long-aligned, and "bytes" must be a multiple of "sizeof(long)":
+*/
+/*SHARED LINE(S) ORIGINATED HERE*/
+/*
+:h3.Allocate() - Allocating a Memory Block
+
+Allocate returns a pointer to memory object that is a copy of
+the template passed (if any). In addition, extra bytes may be
+allocated contiguously with the object. (This may be useful for
+variable size objects such as edge lists. See :hdref refid=regions..)
+
+Allocate() always returns a non-immortal object, even if the template is
+immortal. Therefore a non-NULL template must have a "flag" byte.
+
+If the template is NULL, then 'size' bytes are cleared to all NULLs.
+
+If the template is non-NULL, a new object is allocated in memory.
+It therefore seems logical that its reference count field should be
+set to 1. So, a nun-NULL template must also have a "references" field.
+PNM 3-26-91
+*/
+
+struct xobject *
+t1_Allocate(int size, /* number of bytes to allocate & initialize */
+ pointer ptr, /* example structure to allocate */
+ int extra) /* any extra uninitialized bytes needed contiguously */
+{
+ register struct xobject *template = (struct xobject *)ptr;
+ register struct xobject *r;
+
+ /*
+ * round up 'size' and 'extra' to be an integer number of 'long's:
+ */
+ size = (size + sizeof(long) - 1) & -(int)sizeof(long);
+ extra = (extra + sizeof(long) - 1) & -(int)sizeof(long);
+ if (size + extra <= 0)
+ Abort("Non-positive allocate?");
+ r = (struct xobject *) xiMalloc(size + extra);
+
+ while (r == NULL) {
+ if (!GimeSpace()) {
+ Abort("We have REALLY run out of memory");
+ }
+ r = (struct xobject *) xiMalloc(size + extra);
+ }
+
+ /*
+ * copy the template into the new memory:
+ */
+ if (template != NULL) {
+ /* Added references count decrement if template is not permanent.
+ This is for the case where Allocate is called by a Dupxxxx
+ function, which was in turn called by Unique(). (PNM) */
+ if (!ISPERMANENT(template->flag))
+ --template->references;
+ LONGCOPY(r, template, size);
+ r->flag &= ~(ISPERMANENT(ON) | ISIMMORTAL(ON));
+ /* added reference field 3-2-6-91 PNM */
+ r->references = 1;
+ }
+ else {
+ register char **p1;
+
+ for (p1=(char **)r; size > 0; size -= sizeof(char *))
+ *p1++ = NULL;
+ }
+
+ return(r);
+}
+
+/*
+:h3.Free() - Frees an Allocated Object
+
+This routine makes a sanity check to make sure the "type" field of the
+standard object structure has not been cleared. If the object is
+not a standard structure, then the macro "NonObjectFree" is available
+that does not perform this check.
+
+In either case, the object must not be the NULL pointer. This preserves
+portability, as the C system xiFree() will not always accept NULL.
+*/
+
+void
+Free(pointer objPtr)
+{
+ struct xobject *obj = (struct xobject *)objPtr; /* structure to free */
+
+ if (obj->type == INVALIDTYPE)
+ Abort("Free of already freed object?");
+ obj->type = INVALIDTYPE;
+
+ xiFree((long *)obj);
+}
+
+/*
+:h3.Copy() - Make a New Copy of an Object
+
+This is the generic Copy() where the object type is unknown. There
+are specific Copyxxx functions for known object types.
+
+Copy will create a NEW temporary object, and WILL NOT simply bump the
+reference count.
+
+Sometimes duplicating an object is just as simple as Allocating with it
+as a template. But other objects are complicated linked lists. So, we
+let each module provide us a routine (or macro) that duplicates the
+objects it knows about.
+*/
+
+static struct xobject *
+t1_Copy(pointer objPtr)
+{
+ register struct xobject *obj
+ = (struct xobject *)objPtr; /* object to be Copy'ed */
+ if (obj == NULL)
+ return(NULL);
+
+ if (ISPATHTYPE(obj->type))
+ obj = (struct xobject *) CopyPath((struct segment *)obj);
+ else
+ switch (obj->type) {
+ case SPACETYPE:
+ obj = (struct xobject *)
+ CopySpace((struct XYspace *)obj);
+ break;
+ case FONTTYPE:
+ obj = (struct xobject *) CopyFont(obj); break;
+ case REGIONTYPE:
+ obj = (struct xobject *)
+ CopyRegion((struct region *)obj);
+ break;
+ case PICTURETYPE:
+ obj = (struct xobject *) CopyPicture(obj); break;
+ case LINESTYLETYPE:
+ obj = (struct xobject *) CopyLineStyle(obj); break;
+ case STROKEPATHTYPE:
+ obj = (struct xobject *) CopyStrokePath(obj); break;
+ case CLUTTYPE:
+ obj = (struct xobject *) CopyCLUT(obj); break;
+ default:
+ return(ArgErr("Copy: invalid object", obj, NULL));
+ }
+
+ return(obj);
+}
+
+
+/*
+:h3.Permanent() - Makes an Object Permanent
+
+Real simple--just set a flag. Every routine that consumes its objects
+(which is almost every user entry) must check this flag, and not consume
+the object if it is set.
+
+If a temporary object is made permanent, and there is more than one
+reference to it, we must first Copy() it, then set the ISPERMANENT
+flag. Note also that the reference count must be incremented when an
+object is changed from temporary to permanent (see the ISUNIQUE macro).
+
+Note that the purpose of this function is to convert an object into a
+permanent object:
+ If it was permanent to begin with, we do nothing;
+ If it was temporary and unique, we set the PERMANENT flag and increment
+the reference count;
+ If it was temporary and nonunique, we must make a unique Copy(), set
+the PERMANENT flag, and set the reference count to 2. We must also
+decrement the original object's reference count, because what we have
+done is to change one of the old temporary handles to a permanent one.
+3-26-91 PNM
+*/
+
+struct xobject *
+t1_Permanent(pointer objPtr)
+{
+ struct xobject *obj = (struct xobject *)objPtr; /* object to be made permanent */
+
+ if ( (obj != NULL) && ( !(ISPERMANENT(obj->flag)) ) )
+ {
+ /* there is a non-NULL, temporary object to be made permanent.
+ If there are multiple references to this object, first get
+ a new COPY().
+ Note also that we have to decrement the reference count if
+ we do a Copy() here, because we are consuming the temporary
+ argument passed, and returning a unique, permanent one.
+ */
+ if ( obj->references > 1)
+ {
+ obj = Copy(obj);
+ }
+ /* now set the permanent flag, and increment the reference
+ count, since a temporary object has now become permanent. */
+ obj->references++;
+ obj->flag |= ISPERMANENT(ON);
+ }
+ return(obj);
+}
+
+#ifdef notused
+/*
+:h3.Temporary() - Undoes the Effect of "Permanent()"
+
+This simply resets the "ISPERMANENT" flag.
+
+If a permanent object is made temporary, and there is more than one reference
+to it, we must first Copy() it, then reset the ISPERMANENT flag. However,
+if the permanent object has obly one reference, we need only decrement the
+reference count ( and reset the flag).
+
+Note that this function, in the case of a PERMANENT argument, basically
+converts the PERMANENT handle to a TEMPORARY one. Thus, in the case of
+a nonunique, permanent argument passed, we not only make a Copy(),
+we also decrement the reference count, to reflect the fact that we have
+lost a permanent handle and gained a temporary one.
+PNM 3-2-6-91
+*/
+
+struct xobject *
+xiTemporary(pointer objPtr)
+{
+ register struct xobject *obj
+ = (struct xobject *)objPtr; /* object to be made permanent */
+ if (obj != NULL) {
+ /* if it's already temporary, there's nothing to do. */
+ if ISPERMANENT(obj->flag)
+ {
+ /* if there are multiple references to this object, get a
+ Copy we can safely alter. Recall that the reference count
+ is incremented for permanent objects.
+ Recall further that Copy returns an object with the
+ same flag state and a reference count of 2 (for PERMANENT
+ objects).
+ Thus, regardless of whether or not we need to copy a
+ permanent object, we still decrement its reference
+ count and reset the flag.
+ */
+ if (obj->references != 2 || ISIMMORTAL(obj->flag))
+ {
+ /* not unique; consume handle, get a temporary Copy! */
+ obj = Copy(obj);
+ }
+ /* else decrement the reference count (since it's going from
+ permanent to temporary) and clear the flag. */
+ else {
+ obj->references--;
+ obj->flag &= ~ISPERMANENT(ON);
+ }
+ }
+ }
+ return(obj);
+}
+#endif /* notused */
+
+/*
+:h3.Dup() - Duplicate an Object
+
+Dup will increment the reference count of an object, only making a
+Copy() if needed.
+Note that Dup() retains the state of the permanent flag.
+3-26-91 PNM
+*/
+
+
+struct xobject *
+t1_Dup(pointer objPtr)
+{
+ register struct xobject *obj
+ = (struct xobject *)objPtr; /* object to be duplicated */
+ register char oldflag; /* copy of original object's flag byte */
+
+ if (obj == NULL)
+ return(NULL);
+ /* An immortal object must be Copy'ed, so that we get a mortal
+ copy of it, since we try not to destroy immortal objects. */
+ if (ISIMMORTAL(obj->flag))
+ return(Copy(obj));
+
+ /* if incrementing the reference count doesn't cause the count
+ to wrap, simply return the object with the count bumped. Note
+ that the RefRoll macro increments the count to perform the
+ rollover check, so we must decrement the count. */
+ if (RefRoll(obj))
+ return(obj);
+
+ /* that didn't work out, so put the count back and call Copy(). */
+ --obj->references;
+ oldflag = obj->flag;
+ obj = Copy(obj);
+ if (ISPERMANENT(oldflag))
+ obj = Permanent(obj);
+ return(obj);
+}
+
+/*
+:h3.Destroy() - Destroys an Object
+
+This can get complicated. Just like with Copy(), we let the experts
+handle it.
+*/
+struct xobject *
+Destroy(pointer objPtr)
+{
+ register struct xobject *obj
+ = (struct xobject *)objPtr; /* object to be destroyed */
+ if (obj == NULL)
+ return(NULL);
+ if (ISIMMORTAL(obj->flag)) {
+ return(NULL);
+ }
+ if (ISPATHTYPE(obj->type))
+ KillPath((struct segment *)obj);
+ else {
+ switch (obj->type) {
+ case REGIONTYPE:
+ KillRegion((struct region *)obj);
+ break;
+ case SPACETYPE:
+ KillSpace(obj);
+ break;
+ case LINESTYLETYPE:
+ KillLineStyle(obj);
+ break;
+ case FONTTYPE:
+ KillFont(obj);
+ break;
+ case PICTURETYPE:
+ KillPicture(obj);
+ break;
+ case STROKEPATHTYPE:
+ KillStrokePath(obj);
+ break;
+ case CLUTTYPE:
+ KillCLUT(obj);
+ break;
+ default:
+ return(ArgErr("Destroy: invalid object", obj, NULL));
+ }
+ }
+ return(NULL);
+}
+/*
+:h2.Generally Useful Macros
+
+:h3.FOLLOWING() - Macro to Point to the Data Following a Structure
+
+There are several places in TYPE1IMAGER where we will allocate variable
+data that belongs to a structure immediately after that structure.
+This is a performance technique, because it reduces the number of
+trips we have to take through xiMalloc() and xiFree(). It turns out C has
+a very convenient way to point past a structure--if 'p' is a pointer
+to a structure, 'p+1' is a pointer to the data after it. This
+behavior of C is somewhat startling and somewhat hard to follow, if
+you are not used to it, so we define a macro to point to the data
+following a structure:
+*/
+/*SHARED LINE(S) ORIGINATED HERE*/
+/*
+:h3.TYPECHECK() - Verify the Type of an Argument
+
+This macro tests the type of an argument. If the test fails, it consumes
+any other arguments as necessary and causes the imbedding routine to
+return the value 'whenBAD'.
+
+Note that the consumeables list should be an argument list itself, for
+example (0) or (2,A,B). See :hdref refid=consume. below.
+*/
+
+/*SHARED LINE(S) ORIGINATED HERE*/
+/*
+:h3.ARGCHECK() - Perform an Arbitrary Check on an Argument
+
+This macro is a generalization of TYPECHECK to take an arbitrary
+predicate. If the error occurs (i.e., the predicate is true), the
+arbitrary message 'msg' is returned.
+*/
+
+/*SHARED LINE(S) ORIGINATED HERE*/
+/*
+:h3.TYPENULLCHECK() - Extension of TYPECHECK() for NULL arguments
+
+Many routines allow NULLs to be passed as arguments. 'whenBAD' will
+be returned in this case, too.
+*/
+
+/*SHARED LINE(S) ORIGINATED HERE*/
+/*
+:h3.MAKECONSUME() - Create a "Consume"-type Macro
+
+Consuming an object means destroying it if it is not permanent. This
+logic is so common to all the routines, that it is immortalized in this
+macro. For example, ConsumePath(p) can be simply defined as
+MAKECONSUME(p,KillPath(p)). In effect, this macro operates on a
+meta-level.
+:i1/consuming objects/
+*/
+
+/*SHARED LINE(S) ORIGINATED HERE*/
+
+/*
+:h3.MAKEUNIQUE() - Create a "Unique"-type Macro
+
+Many routines are written to modify their arguments in place. Thus,
+they want to insure that they duplicate an object if it is permanent.
+This is called making an object "unique". For example, UniquePath(p)
+can be simply defined as MAKEUNIQUE(p,DupPath(p)).
+:i1/unique objects/
+*/
+
+/*SHARED LINE(S) ORIGINATED HERE*/
+
+/*
+An object is unique (and directly alterable) if there is only one
+reference to it, and it is not permanent (in which case we increment
+the reference count, so we don't have to check the permanent bit).
+3-26-91 PNM
+
+Note the rules for making a unique object:
+&drawing.
+ IF (obj->references = 1) return(obj);
+ ELSE (references > 1)
+ IF (ISPERMANENT(obj->flag)) return(Dupxxx(obj));
+ ELSE (nonunique, temporary object!)
+ obj->references--; return(Dupxxx(obj));
+&edrawing.
+If we must make a Copy of a nonunique, temporary object, we decrement
+reference count of the original object!
+*/
+
+/*
+:h3.Unique() - Make a Unique Object
+
+Here is a generic 'Unique' function if the object type is not known.
+Why didn't we build it with the MAKEUNIQUE macro, you ask? Well, we
+used to, but there is at least one damn compiler in the world that
+raises errors if the types of an "(a) ? b : c" expression do not match.
+Also, when we changed Dup() to retain the permanent/temporary flag, we
+wanted to make sure "Unique" always returned a temporary object.
+
+Note that we cannot use Dup() to create a copy of the object in question,
+because Dup() may simply bump the reference count, and not return a
+unique copy to us. That is why we use t1_Copy().
+
+The purpose of this function is to make sure we have a copy of an object
+that we can safely alter:
+:ol.
+:li.If we have a unique, temporary object, we simply return the argument.
+:li.If we have a nonunique, temporary object, we have to make a new copy
+of it, and decrement the reference count of the original object, to reflect
+the fact that we traded temporary handles.
+:li.If we have a permanent object, we make a temporary copy of it, but
+we do not decrement the reference count of the original permanent object,
+because permanent objects, by definition, are persistent. 3-2-6-91 PNM
+:eol.
+*/
+
+struct xobject *
+t1_Unique(pointer objPtr)
+{
+ struct xobject *obj = (struct xobject *)objPtr;
+
+ /* if the original object is not already unique, make a unique
+ copy...Note also that if the object was not permanent, we must
+ consume the old handle! 3-26-91 PNM
+ NOTE : consumption of the old handle moved to Allocate. 4-18-91 */
+ if (!obj || obj->references == 1)
+ return(obj);
+
+ obj = Copy(obj);
+ /* and make sure we return a temporary object ! */
+ if (ISPERMANENT(obj->flag))
+ {
+ obj->flag &= ~ISPERMANENT(ON);
+ obj->references--;
+ }
+ return(obj);
+}
+
+
+/*
+:h2.Initialization, Error, and Debug Routines
+
+:h3 id=debugvar.Declarations for Debug Purposes
+
+We declare all the debug flags here. Some link editors make the not
+unreasonable restriction that only one module may declare and
+initialize global variables; all the rest must declare the variable
+'extern'. This is logical, but is somewhat awkward to implement with
+C include files. We solve the problem by temporarily making the name
+'extern' a null name if GLOBALS is defined. (GLOBALS is only defined
+in this OBJECTS module.) Since 'externs' can't be initialized, we
+have to handle that with #defines too.
+:i1/GLOBALS (&#define.)/
+*/
+
+/*SHARED LINE(S) ORIGINATED HERE*/
+static char *ErrorMessage = NULL;
+
+/*
+:h3.Consume() - Consume a List of Arguments
+
+This general purpose routine is provided in the case where the object
+type(s) to be consumed are unknown or not yet verified, and/or it is
+not known whether the object is permanent.
+
+If the type of the argument is known, it is faster to directly consume
+that type, for example, ConsumeRegion() or ConsumePath(). Furthermore,
+if it is already known that the object is temporary, it is faster to
+just kill it rather than consume it, for example, KillSpace().
+*/
+
+void
+Consume(int n, ...)
+{
+ struct xobject *obj;
+ va_list ap;
+
+ va_start(ap, n);
+
+ while (n-- > 0) {
+ obj = va_arg(ap, struct xobject *);
+ if (obj != NULL && !ISPERMANENT(obj->flag))
+ Destroy(obj);
+ }
+}
+
+/*
+:h3.TypeErr() - Handles "Invalid Object Type" Errors
+*/
+
+struct xobject *
+TypeErr(char *name, /* Name of routine (for error message) */
+ pointer objPtr, /* Object in error */
+ int expect, /* type expected */
+ pointer retPtr) /* object to return to caller */
+{
+ struct xobject *obj = (struct xobject *)objPtr;
+ struct xobject *ret = (struct xobject *)retPtr;
+ /*
+ * This buffer must be large enough to hold 'name' plus
+ * two of the largest strings that can be returned by TypeFmt.
+ * The largest value of 'name' is currently 9 ("ClosePath")
+ * and the longest strings in TypeFmt are 30 characters.
+ */
+ static char typemsg[115];
+
+ if (MustCrash)
+ LineIOTrace = TRUE;
+
+ sprintf(typemsg, "Wrong object type in %s. Expected %s; was %s.\n",
+ name, TypeFmt(expect), TypeFmt(obj->type));
+
+ if (MustCrash)
+ Abort("Terminating because of CrashOnUserError...");
+ else
+ ErrorMessage = typemsg;
+
+/* changed ISPERMANENT to ret->references > 1 3-26-91 PNM */
+ if (ret != NULL && (ret->references > 1))
+ ret = Dup(ret);
+ return(ret);
+}
+
+/*
+:h4.TypeFmt() - Returns Pointer to English Name of Object Type
+
+This is a subroutine of TypeErr().
+*/
+
+static char *
+TypeFmt(int type) /* type field */
+{
+ char *r;
+
+ if (ISPATHTYPE(type))
+ if (type == TEXTTYPE)
+ r = "path or region (from TextPath)";
+ else
+ r = "path";
+ else {
+ switch (type) {
+ case INVALIDTYPE:
+ r = "INVALID (previously consumed?)";
+ break;
+ case REGIONTYPE:
+ r = "region";
+ break;
+ case SPACETYPE:
+ r = "XYspace";
+ break;
+ case LINESTYLETYPE:
+ r = "linestyle";
+ break;
+ case FONTTYPE:
+ r = "font";
+ break;
+ case PICTURETYPE:
+ r = "picture";
+ break;
+ case STROKEPATHTYPE:
+ r = "path (from StrokePath)";
+ break;
+ default:
+ r = "UNKNOWN";
+ break;
+ }
+ }
+ return(r);
+}
+/*
+:h3.ArgErr() - Invalid Argument Passed to a Routine
+
+A common routine to report argument errors. It is usually called
+is returned to the caller in case MustCrash is FALSE and ArgErr
+returns to its caller.
+*/
+
+struct xobject *
+ArgErr(char *string, /* description of error */
+ pointer objPtr, /* object, if any, that was in error */
+ pointer retPtr) /* object returned to caller or NULL */
+{
+ struct xobject *ret = (struct xobject *)retPtr;
+
+ if (MustCrash)
+ LineIOTrace = TRUE;
+
+ if (MustCrash)
+ Abort("Terminating because of CrashOnUserError...");
+ else
+ ErrorMessage = string;
+ return(ret);
+}
+
+/*
+:h3.Abort() - Crash Due to Error
+
+Defined in objects.h to be FatalError(), the server's abort routine.
+*/
+
+/*
+:h4.InitImager() - Initialize TYPE1IMAGER
+
+We check that a short is 16 bits and a long 32 bits; we have made
+those assumptions elsewhere in the code. (This is almost a C standard,
+anyway.) Note that TYPE1IMAGER makes no assumptions about the size of an
+'int'!
+:i1/portability assumptions/
+*/
+
+void
+InitImager(void)
+{
+
+/* Check to see if we have been using our own malloc. If so,*/
+/* Undef malloc so that we can get to the system call. */
+/* All other calls to malloc are defined to xiMalloc. */
+
+
+/* if (sizeof(short) != 2 || sizeof(INT32) != 4)
+ Abort("Fundamental TYPE1IMAGER assumptions invalid in this port");
+*/
+ InitSpaces();
+ InitFonts();
+ InitFiles();
+/*
+In some environments, constants and/or exception handling need to be
+*/
+ LibInit();
+}
diff --git a/libXfont/src/Type1/objects.h b/libXfont/src/Type1/objects.h
new file mode 100644
index 000000000..ea481480e
--- /dev/null
+++ b/libXfont/src/Type1/objects.h
@@ -0,0 +1,293 @@
+/* $Xorg: objects.h,v 1.3 2000/08/17 19:46:31 cpqbld Exp $ */
+/* Copyright International Business Machines, Corp. 1991
+ * All Rights Reserved
+ * Copyright Lexmark International, Inc. 1991
+ * All Rights Reserved
+ *
+ * License to use, copy, modify, and distribute this software and its
+ * documentation for any purpose and without fee is hereby granted,
+ * provided that the above copyright notice appear in all copies and that
+ * both that copyright notice and this permission notice appear in
+ * supporting documentation, and that the name of IBM or Lexmark not be
+ * used in advertising or publicity pertaining to distribution of the
+ * software without specific, written prior permission.
+ *
+ * IBM AND LEXMARK PROVIDE THIS SOFTWARE "AS IS", WITHOUT ANY WARRANTIES OF
+ * ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING, BUT NOT LIMITED TO ANY
+ * IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE,
+ * AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. THE ENTIRE RISK AS TO THE
+ * QUALITY AND PERFORMANCE OF THE SOFTWARE, INCLUDING ANY DUTY TO SUPPORT
+ * OR MAINTAIN, BELONGS TO THE LICENSEE. SHOULD ANY PORTION OF THE
+ * SOFTWARE PROVE DEFECTIVE, THE LICENSEE (NOT IBM OR LEXMARK) ASSUMES THE
+ * ENTIRE COST OF ALL SERVICING, REPAIR AND CORRECTION. IN NO EVENT SHALL
+ * IBM OR LEXMARK BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
+ * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
+ * THIS SOFTWARE.
+ */
+/* $XFree86: xc/lib/font/Type1/objects.h,v 1.14tsi Exp $ */
+/*SHARED*/
+
+/*END SHARED*/
+
+#include <X11/Xdefs.h>
+#include <X11/Xfuncproto.h>
+#ifndef FONTMODULE
+#include <stdlib.h>
+#endif
+/*SHARED*/
+
+#define Permanent(obj) t1_Permanent(obj)
+#ifdef notused
+#define Temporary(obj) t1_Temporary(obj)
+#endif
+#define Destroy(obj) t1_Destroy(obj)
+#define Dup(obj) t1_Dup(obj)
+#define InitImager t1_InitImager
+#define TermImager t1_TermImager
+#define Pragmatics(f,v) t1_Pragmatics(f,v)
+#define ErrorMsg t1_ErrorMsg
+
+/* make an object permanent */
+extern struct xobject *t1_Permanent ( pointer obj );
+
+#ifdef notused
+/* make an object temporary */
+extern struct xobject *t1_Temporary( pointer obj );
+#endif
+
+/* destroy an object */
+extern struct xobject *t1_Destroy ( pointer obj );
+
+/* duplicate an object */
+extern struct xobject *t1_Dup ( pointer obj );
+
+
+extern void t1_InitImager ( void ); /* initialize TYPE1IMAGER */
+
+/*END SHARED*/
+/*SHARED*/
+extern void xiFree ( long *addr );
+extern char *xiMalloc ( unsigned Size );
+extern void addmemory ( long *addr, long size );
+extern void delmemory ( void );
+
+#ifndef OS_H
+extern void FatalError(const char *f, ...)
+#if defined(__GNUC__) && \
+ ((__GNUC__ > 2) || ((__GNUC__ == 2) && (__GNUC_MINOR__ > 4)))
+__attribute((noreturn))
+#endif
+;
+
+extern void ErrorF(const char *f, ...);
+#endif
+
+#define Abort(line) FatalError(line)
+#define Allocate(n,t,s) t1_Allocate(n,t,s)
+#define Free(obj) t1_Free(obj)
+#define NonObjectFree(a) xiFree((long *)(a))
+#define Consume t1_Consume
+#define ArgErr(s,o,r) t1_ArgErr(s,o,r)
+#define TypeErr(n,o,e,r) t1_TypeErr(n,o,e,r)
+#define Copy(obj) t1_Copy(obj)
+#define Unique(obj) t1_Unique(obj)
+
+/* allocate memory */
+extern struct xobject *t1_Allocate( int size, pointer template,
+ int extra );
+
+/* free memory */
+extern void t1_Free ( pointer obj );
+
+/* make a unique temporary copy of an object */
+extern struct xobject *t1_Unique ( pointer obj );
+
+/* handle argument errors */
+extern struct xobject *t1_ArgErr ( char *string, pointer obj, pointer ret );
+
+/* handle 'bad type' argument errors */
+extern struct xobject *t1_TypeErr ( char *name, pointer obj,
+ int expect, pointer ret );
+
+/* consume a variable number of arguments */
+extern void t1_Consume ( int n, ... );
+
+/*END SHARED*/
+/*SHARED*/
+
+#define ON (~0) /* all bits on */
+#ifndef FALSE
+#define FALSE 0 /* handy zero value */
+#endif
+#ifndef TRUE
+#define TRUE 1 /* handy non-zero value */
+#endif
+
+#ifndef NULL
+#include <stddef.h>
+/*
+The NULL pointer is system specific. (Most systems, however, use 0.)
+TYPE1IMAGER could have its own NULL, independent of the rest of the system,
+were it not for malloc(). The system call malloc() returns NULL when
+out of memory.
+:i1/portibility assumptions/
+*/
+#endif
+
+#ifndef MIN
+#define MIN(a,b) (((a)<(b)) ? a : b)
+#endif
+#ifndef MAX
+#define MAX(a,b) (((a)>(b)) ? a : b)
+#endif
+#ifndef ABS
+#define ABS(a) (((a)>=0)?(a):-(a))
+#endif
+
+/*END SHARED*/
+/*SHARED*/
+
+struct xobject {
+ char type; /* encoded type of object */
+ unsigned char flag; /* flag byte for temporary object characteristics*/
+ short references; /* count of pointers to this object
+ (plus 1 for permanent objects) PNM */
+} ;
+
+/*END SHARED*/
+/*SHARED*/
+
+#define XOBJ_COMMON char type; unsigned char flag; short references;
+
+/*END SHARED*/
+/*SHARED*/
+
+
+#define INVALIDTYPE 0
+#define FONTTYPE 1
+#define REGIONTYPE 3
+#define PICTURETYPE 4
+#define SPACETYPE 5
+#define LINESTYLETYPE 6
+#define EDGETYPE 7
+#define STROKEPATHTYPE 8
+#define CLUTTYPE 9
+
+#define ISPATHTYPE(type) ((type)&0x10) /* all path segments have this bit on */
+#define LINETYPE (0+ISPATHTYPE(ON))
+#define CONICTYPE (1+ISPATHTYPE(ON))
+#define BEZIERTYPE (2+ISPATHTYPE(ON))
+#define HINTTYPE (3+ISPATHTYPE(ON))
+
+#define MOVETYPE (5+ISPATHTYPE(ON))
+#define TEXTTYPE (6+ISPATHTYPE(ON))
+
+/*END SHARED*/
+/*SHARED*/
+
+#define ISPERMANENT(flag) ((flag)&0x01)
+#define ISIMMORTAL(flag) ((flag)&0x02)
+
+/*END SHARED*/
+/*SHARED*/
+
+#define PRESERVE(obj) if (!ISPERMANENT((obj)->flag)) \
+ (obj)->references++;
+
+/*END SHARED*/
+/*SHARED*/
+
+#define LONGCOPY(dest,source,bytes) { \
+ register long *p1 = (long *)dest; register long *p2 = (long *)source; \
+ register int count = (bytes) / sizeof(long); \
+ while (--count >= 0) *p1++ = *p2++; }
+
+
+/*END SHARED*/
+/*SHARED*/
+
+#define FOLLOWING(p) ((p)+1)
+
+/*END SHARED*/
+/*SHARED*/
+
+#define TYPECHECK(name, obj, expect, whenBAD, consumables, rettype) { \
+ if (obj->type != expect) { \
+ (Consume)consumables; \
+ return((rettype)TypeErr(name, obj, expect, whenBAD)); \
+ } \
+}
+
+/*END SHARED*/
+/*SHARED*/
+
+#define ARGCHECK(test,msg,obj,whenBAD,consumables,rettype) { \
+ if (test) { \
+ (Consume)consumables; \
+ return((rettype)ArgErr(msg, obj, whenBAD)); \
+ } \
+}
+
+/*END SHARED*/
+/*SHARED*/
+
+/* Changed use of Dup() below to Temporary(Copy()) because Dup() does not
+ necessarily return a Unique Copy anymore! 3-26-91 */
+#define TYPENULLCHECK(name, obj, expect, whenBAD, consumables,rettype) \
+ if (obj == NULL) { \
+ (Consume)consumables; \
+ if (whenBAD != NULL && ISPERMANENT(whenBAD->flag)) \
+ return((rettype)Temporary(Copy(whenBAD))); \
+ else return((rettype)whenBAD); \
+ } else { \
+ if (obj->type != expect) { \
+ (Consume)consumables; \
+ return((rettype)TypeErr(name, obj, expect, whenBAD)); \
+ } \
+ }
+/*END SHARED*/
+/*SHARED*/
+
+#define MAKECONSUME(obj,stmt) { if (!ISPERMANENT(obj->flag)) stmt; }
+
+/*END SHARED*/
+/*SHARED*/
+
+#define MAKEUNIQUE(obj,stmt) ( ( (obj)->references > 1 ) ? stmt : obj )
+
+/*END SHARED*/
+/*SHARED*/
+
+#ifdef GLOBALS
+
+#define extern
+#define INITIALIZED(value) = value
+
+#else
+
+#define INITIALIZED(value)
+
+#endif
+
+extern char ProcessHints INITIALIZED(TRUE);
+
+extern char RegionDebug INITIALIZED(0);
+
+extern char Continuity INITIALIZED(2);
+
+#ifdef extern
+#undef extern
+#endif
+
+/*
+We define other routines formatting parameters
+*/
+#define DumpArea(area) t1_DumpArea(area)
+#define DumpPath(path) t1_DumpPath(path)
+#define DumpSpace(space) t1_DumpSpace(space)
+#define DumpEdges(e) t1_DumpEdges(e)
+#define FormatFP(s,p) t1_FormatFP(s,p)
+
+/*END SHARED*/
diff --git a/libXfont/src/Type1/paths.c b/libXfont/src/Type1/paths.c
new file mode 100644
index 000000000..b8b13646e
--- /dev/null
+++ b/libXfont/src/Type1/paths.c
@@ -0,0 +1,748 @@
+/* $Xorg: paths.c,v 1.3 2000/08/17 19:46:31 cpqbld Exp $ */
+/* Copyright International Business Machines, Corp. 1991
+ * All Rights Reserved
+ * Copyright Lexmark International, Inc. 1991
+ * All Rights Reserved
+ *
+ * License to use, copy, modify, and distribute this software and its
+ * documentation for any purpose and without fee is hereby granted,
+ * provided that the above copyright notice appear in all copies and that
+ * both that copyright notice and this permission notice appear in
+ * supporting documentation, and that the name of IBM or Lexmark not be
+ * used in advertising or publicity pertaining to distribution of the
+ * software without specific, written prior permission.
+ *
+ * IBM AND LEXMARK PROVIDE THIS SOFTWARE "AS IS", WITHOUT ANY WARRANTIES OF
+ * ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING, BUT NOT LIMITED TO ANY
+ * IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE,
+ * AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. THE ENTIRE RISK AS TO THE
+ * QUALITY AND PERFORMANCE OF THE SOFTWARE, INCLUDING ANY DUTY TO SUPPORT
+ * OR MAINTAIN, BELONGS TO THE LICENSEE. SHOULD ANY PORTION OF THE
+ * SOFTWARE PROVE DEFECTIVE, THE LICENSEE (NOT IBM OR LEXMARK) ASSUMES THE
+ * ENTIRE COST OF ALL SERVICING, REPAIR AND CORRECTION. IN NO EVENT SHALL
+ * IBM OR LEXMARK BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
+ * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
+ * THIS SOFTWARE.
+ */
+/* $XFree86: xc/lib/font/Type1/paths.c,v 1.7tsi Exp $ */
+
+ /* PATHS CWEB V0021 ******** */
+/*
+:h1 id=paths.PATHS Module - Path Operator Handler
+
+This is the module that is responsible for building and transforming
+path lists.
+
+&author. Jeffrey B. Lotspiech (lotspiech@almaden.ibm.com)
+
+
+:h3.Include Files
+
+The included files are:
+*/
+
+ /* after the system includes (dsr) */
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#ifdef FONTMODULE
+# include "os.h"
+#endif
+#include "objects.h"
+#include "spaces.h"
+#include "paths.h"
+#include "regions.h" /* understands about Union */
+#include "fonts.h" /* understands about TEXTTYPEs */
+#include "pictures.h" /* understands about handles */
+#include "strokes.h" /* understands how to coerce stroke paths */
+#include "trig.h"
+
+
+/*
+:h3.Routines Available to the TYPE1IMAGER User
+
+The PATHS routines that are made available to the outside user are:
+*/
+
+/*SHARED LINE(S) ORIGINATED HERE*/
+/*
+:h3.Functions Provided to Other Modules
+
+The path routines that are made available to other TYPE1IMAGER modules
+are defined here:
+*/
+
+/*SHARED LINE(S) ORIGINATED HERE*/
+/*
+NOTE: because of the casts put in the macros for Loc, ArcCA, Conic,
+RoundConic, PathSegment, and JoinSegment, we cannot use the macro names
+when the functions are actually defined. We have to use the unique
+names with their unique first two characters. Thus, if anyone in the
+future ever decided to change the first two characters, it would not be
+enough just to change the macro (as it would for most other functions).
+He would have to also change the function definition.
+*/
+/*
+:h3.Macros Provided to Other Modules
+
+The CONCAT macro is defined here and used in the STROKES module. See
+:hdref refid=pathmac..
+*/
+
+/*SHARED LINE(S) ORIGINATED HERE*/
+
+/*
+:h2.Path Segment Structures
+
+A path is represented as a linked list of the following structure:
+*/
+
+/*SHARED LINE(S) ORIGINATED HERE*/
+/*
+When 'link' is NULL, we are at the last segment in the path (surprise!).
+
+'last' is only non-NULL on the first segment of a path,
+for all the other segments 'last' == NULL. We test for a non-NULL
+'last' (ISPATHANCHOR predicate) when we are given an alleged path
+to make sure the user is not trying to pull a fast one on us.
+
+A path may be a collection of disjoint paths. Every break in the
+disjoint path is represented by a MOVETYPE segment.
+
+Closed paths are discussed in :hdref refid=close..
+
+:h3.CopyPath() - Physically Duplicating a Path
+
+This simple function illustrates moving through the path linked list.
+Duplicating a segment just involves making a copy of it, except for
+text, which has some auxilliary things involved. We don't feel
+competent to duplicate text in this module, so we call someone who
+knows how (in the FONTS module).
+*/
+struct segment *
+CopyPath(struct segment *p0) /* path to duplicate */
+{
+ register struct segment *p,*n = NULL,*last = NULL,*anchor;
+
+ for (p = p0, anchor = NULL; p != NULL; p = p->link) {
+
+ ARGCHECK((!ISPATHTYPE(p->type) || (p != p0 && p->last != NULL)),
+ "CopyPath: invalid segment", p, NULL, (0), struct segment *);
+
+ if (p->type == TEXTTYPE)
+ n = (struct segment *) CopyText(p);
+ else
+ n = (struct segment *)Allocate(p->size, p, 0);
+ n->last = NULL;
+ if (anchor == NULL)
+ anchor = n;
+ else
+ last->link = n;
+ last = n;
+ }
+/*
+At this point we have a chain of newly allocated segments hanging off
+'anchor'. We need to make sure the first segment points to the last:
+*/
+ if (anchor != NULL) {
+ n->link = NULL;
+ anchor->last = n;
+ }
+
+ return(anchor);
+}
+/*
+:h3.KillPath() - Destroying a Path
+
+Destroying a path is simply a matter of freeing each segment in the
+linked list. Again, we let the experts handle text.
+*/
+void
+KillPath(struct segment *p) /* path to destroy */
+{
+ register struct segment *linkp; /* temp register holding next segment*/
+
+ /* return conditional based on reference count 3-26-91 PNM */
+ if ( (--(p->references) > 1) ||
+ ( (p->references == 1) && !ISPERMANENT(p->flag) ) )
+ return;
+
+ while (p != NULL) {
+ if (!ISPATHTYPE(p->type)) {
+ ArgErr("KillPath: bad segment", p, NULL);
+ return;
+ }
+ linkp = p->link;
+ if (p->type == TEXTTYPE)
+ KillText(p);
+ else
+ Free(p);
+ p = linkp;
+ }
+}
+
+/*
+:h2 id=location."location" Objects
+
+The TYPE1IMAGER user creates and destroys objects of type "location". These
+objects locate points for the primitive path operators. We play a trick
+here and store these objects in the same "segment" structure used for
+paths, with a type field == MOVETYPE.
+
+This allows the Line() operator, for example, to be very trivial:
+It merely stamps its input structure as a LINETYPE and returns it to the
+caller--assuming, of course, the input structure was not permanent (as
+it usually isn't).
+
+:h3.The "movesegment" Template Structure
+
+This template is used as a generic segment structure for Allocate:
+*/
+
+/* added reference field 1 to temporary template below 3-26-91 PNM */
+static struct segment movetemplate = { MOVETYPE, 0, 1, sizeof(struct segment), 0,
+ NULL, NULL, {0, 0} };
+/*
+:h3.Loc() - Create an "Invisible Line" Between (0,0) and a Point
+
+*/
+
+struct segment *
+t1_Loc(struct XYspace *S, /* coordinate space to interpret X,Y */
+ double x, double y) /* destination point */
+{
+ register struct segment *r;
+
+
+ r = (struct segment *)Allocate(sizeof(struct segment), &movetemplate, 0);
+ TYPECHECK("Loc", S, SPACETYPE, r, (0), struct segment *);
+
+ r->last = r;
+ r->context = S->context;
+ (*S->convert)(&r->dest, S, x, y);
+ ConsumeSpace(S);
+ return(r);
+}
+/*
+:h3.ILoc() - Loc() With Integer Arguments
+
+*/
+struct segment *
+ILoc(struct XYspace *S, /* coordinate space to interpret X,Y */
+ int x, int y) /* destination point */
+{
+ register struct segment *r;
+
+ r = (struct segment *)Allocate(sizeof(struct segment), &movetemplate, 0);
+ TYPECHECK("Loc", S, SPACETYPE, r, (0), struct segment *);
+
+ r->last = r;
+ r->context = S->context;
+ (*S->iconvert)(&r->dest, S, (long) x, (long) y);
+ ConsumeSpace(S);
+ return(r);
+}
+
+/*
+:h2.Straight Line Segments
+
+:h3.PathSegment() - Create a Generic Path Segment
+
+Many routines need a LINETYPE or MOVETYPE path segment, but do not
+want to go through the external user's interface, because, for example,
+they already know the "fractpel" destination of the segment and the
+conversion is unnecessary. PathSegment() is an internal routine
+provided to the rest of TYPE1IMAGER for handling these cases.
+*/
+
+struct segment *
+t1_PathSegment(int type, /* LINETYPE or MOVETYPE */
+ fractpel x, fractpel y) /* where to go to, if known */
+{
+ register struct segment *r; /* newly created segment */
+
+ r = (struct segment *)Allocate(sizeof(struct segment), &movetemplate, 0);
+ r->type = type;
+ r->last = r; /* last points to itself for singleton */
+ r->dest.x = x;
+ r->dest.y = y;
+ return(r);
+}
+/*
+:h3.Line() - Create a Line Segment Between (0,0) and a Point P
+
+This involves just creating and filling out a segment structure:
+*/
+struct segment *
+Line(struct segment *P) /* relevant coordinate space */
+{
+ ARGCHECK(!ISLOCATION(P), "Line: arg not a location", P, NULL, (0), struct segment *);
+
+ P = UniquePath(P);
+ P->type = LINETYPE;
+ return(P);
+}
+/*
+:h2.Curved Path Segments
+
+We need more points to describe curves. So, the structures for curved
+path segments are slightly different. The first part is identical;
+the curved structures are larger with the extra points on the end.
+
+:h3.Bezier Segment Structure
+
+We support third order Bezier curves. They are specified with four
+control points A, B, C, and D. The curve starts at A with slope AB
+and ends at D with slope CD. The curvature at the point A is inversely
+related to the length |AB|, and the curvature at the point D is
+inversely related to the length |CD|. Point A is always point (0,0).
+
+*/
+
+/*SHARED LINE(S) ORIGINATED HERE*/
+/*
+:h3.Bezier() - Generate a Bezier Segment
+
+This is just a simple matter of filling out a 'beziersegment' structure:
+*/
+
+struct beziersegment *
+Bezier(struct segment *B, /* second control point */
+ struct segment *C, /* third control point */
+ struct segment *D) /* fourth control point (ending point) */
+{
+/* added reference field of 1 to temporary template below 3-26-91 PNM */
+ static struct beziersegment template =
+ { BEZIERTYPE, 0, 1, sizeof(struct beziersegment), 0,
+ NULL, NULL, { 0, 0 }, { 0, 0 }, { 0, 0 } };
+
+ register struct beziersegment *r; /* output segment */
+
+ ARGCHECK(!ISLOCATION(B), "Bezier: bad B", B, NULL, (2,C,D), struct beziersegment *);
+ ARGCHECK(!ISLOCATION(C), "Bezier: bad C", C, NULL, (2,B,D), struct beziersegment *);
+ ARGCHECK(!ISLOCATION(D), "Bezier: bad D", D, NULL, (2,B,C), struct beziersegment *);
+
+ r = (struct beziersegment *)Allocate(sizeof(struct beziersegment), &template, 0);
+ r->last = (struct segment *) r;
+ r->dest.x = D->dest.x;
+ r->dest.y = D->dest.y;
+ r->B.x = B->dest.x;
+ r->B.y = B->dest.y;
+ r->C.x = C->dest.x;
+ r->C.y = C->dest.y;
+
+ ConsumePath(B);
+ ConsumePath(C);
+ ConsumePath(D);
+ return(r);
+}
+
+/*SHARED LINE(S) ORIGINATED HERE*/
+
+/*
+POP removes the first segment in a path 'p' and Frees it. 'p' is left
+pointing to the end of the path:
+*/
+#define POP(p) \
+ { register struct segment *linkp; \
+ linkp = p->link; \
+ if (linkp != NULL) \
+ linkp->last = p->last; \
+ Free(p); \
+ p = linkp; }
+/*
+INSERT inserts a single segment in the middle of a chain. 'b' is
+the segment before, 'p' the segment to be inserted, and 'a' the
+segment after.
+*/
+#define INSERT(b,p,a) b->link=p; p->link=a; p->last=NULL
+
+/*
+:h3.Join() - Join Two Objects Together
+
+If these are paths, this operator simply invokes the CONCAT macro.
+Why so much code then, you ask? Well we have to check for object
+types other than paths, and also check for certain path consistency
+rules.
+*/
+
+struct segment *
+Join(struct segment *p1, struct segment *p2)
+{
+/*
+We start with a whole bunch of very straightforward argument tests:
+*/
+ if (p2 != NULL) {
+ if (!ISPATHTYPE(p2->type)) {
+
+ if (p1 == NULL)
+ return((struct segment *)Unique(p2));
+
+ switch (p1->type) {
+
+ case REGIONTYPE:
+
+ case STROKEPATHTYPE:
+ p1 = CoercePath(p1);
+ break;
+
+ default:
+ return((struct segment *)BegHandle(p1, p2));
+ }
+ }
+
+ ARGCHECK((p2->last == NULL), "Join: right arg not anchor", p2, NULL, (1,p1), struct segment *);
+ p2 = UniquePath(p2);
+
+/*
+In certain circumstances, we don't have to duplicate a permanent
+location. (We would just end up destroying it anyway). These cases
+are when 'p2' begins with a move-type segment:
+*/
+ if (p2->type == TEXTTYPE || p2->type == MOVETYPE) {
+ if (p1 == NULL)
+ return(p2);
+ if (ISLOCATION(p1)) {
+ p2->dest.x += p1->dest.x;
+ p2->dest.y += p1->dest.y;
+ ConsumePath(p1);
+ return(p2);
+ }
+ }
+ }
+ else
+ return((struct segment *)Unique(p1));
+
+ if (p1 != NULL) {
+ if (!ISPATHTYPE(p1->type))
+
+ switch (p2->type) {
+
+ case REGIONTYPE:
+
+ case STROKEPATHTYPE:
+ p2 = CoercePath(p2);
+ break;
+
+ default:
+ return((struct segment *)EndHandle(p1, p2));
+ }
+
+ ARGCHECK((p1->last == NULL), "Join: left arg not anchor", p1, NULL, (1,p2), struct segment *);
+ p1 = UniquePath(p1);
+ }
+ else
+ return(p2);
+
+/*
+At this point all the checking is done. We have two temporary non-null
+path types in 'p1' and 'p2'. If p1 ends with a MOVE, and p2 begins with
+a MOVE, we collapse the two MOVEs into one. We enforce the rule that
+there may not be two MOVEs in a row:
+*/
+
+ if (p1->last->type == MOVETYPE && p2->type == MOVETYPE) {
+ p1->last->flag |= p2->flag;
+ p1->last->dest.x += p2->dest.x;
+ p1->last->dest.y += p2->dest.y;
+ POP(p2);
+ if (p2 == NULL)
+ return(p1);
+ }
+/*
+Now we check for another silly rule. If a path has any TEXTTYPEs,
+then it must have only TEXTTYPEs and MOVETYPEs, and furthermore,
+it must begin with a TEXTTYPE. This rule makes it easy to check
+for the special case of text. If necessary, we will coerce
+TEXTTYPEs into paths so we don't mix TEXTTYPEs with normal paths.
+*/
+ if (p1->type == TEXTTYPE) {
+ if (p2->type != TEXTTYPE && !ISLOCATION(p2))
+ p1 = CoerceText(p1);
+ }
+ else {
+ if (p2->type == TEXTTYPE) {
+ if (ISLOCATION(p1)) {
+ p2->dest.x += p1->dest.x;
+ p2->dest.y += p1->dest.y;
+ Free(p1);
+ return(p2);
+ }
+ else
+ p2 = CoerceText(p2);
+ }
+ }
+/*
+Thank God! Finally! It's hard to believe, but we are now able to
+actually do the join. This is just invoking the CONCAT macro:
+*/
+ CONCAT(p1, p2);
+
+ return(p1);
+}
+
+/*
+:h3.JoinSegment() - Create a Path Segment and Join It to a Known Path
+
+This internal function is quicker than a full-fledged join because
+it can do much less checking.
+*/
+
+struct segment *
+t1_JoinSegment(struct segment *before, /* path to join before new segment */
+ int type, /* type of new segment (MOVETYPE or LINETYPE) */
+ fractpel x, fractpel y, /* x,y of new segment */
+ struct segment *after) /* path to join after new segment */
+{
+ register struct segment *r; /* returned path built here */
+
+ r = PathSegment(type, x, y);
+ if (before != NULL) {
+ CONCAT(before, r);
+ r = before;
+ }
+ else
+ r->context = after->context;
+ if (after != NULL)
+ CONCAT(r, after);
+ return(r);
+}
+
+/*
+:h2.Other Path Functions
+
+*/
+
+
+struct segment *
+t1_ClosePath(struct segment *p0, /* path to close */
+ int lastonly) /* flag deciding to close all subpaths or... */
+{
+ register struct segment *p,*last = NULL,*start; /* used in looping through path */
+ register fractpel x,y; /* current position in path */
+ register fractpel firstx = 0,firsty = 0; /* start position of sub path */
+ register struct segment *lastnonhint = NULL; /* last non-hint segment in path */
+
+ if (p0 != NULL && p0->type == TEXTTYPE)
+ return(UniquePath(p0));
+ if (p0->type == STROKEPATHTYPE)
+ return((struct segment *)Unique(p0));
+ /*
+ * NOTE: a null closed path is different from a null open path
+ * and is denoted by a closed (0,0) move segment. We make
+ * sure this path begins and ends with a MOVETYPE:
+ */
+ if (p0 == NULL || p0->type != MOVETYPE)
+ p0 = JoinSegment(NULL, MOVETYPE, 0, 0, p0);
+ TYPECHECK("ClosePath", p0, MOVETYPE, NULL, (0), struct segment *);
+ if (p0->last->type != MOVETYPE)
+ p0 = JoinSegment(p0, MOVETYPE, 0, 0, NULL);
+
+ p0 = UniquePath(p0);
+
+/*
+We now begin a loop through the path,
+incrementing current 'x' and 'y'. We are searching
+for MOVETYPE segments (breaks in the path) that are not already closed.
+At each break, we insert a close segment.
+*/
+ for (p = p0, x = y = 0, start = NULL;
+ p != NULL;
+ x += p->dest.x, y += p->dest.y, last = p, p = p->link)
+ {
+
+ if (p->type == MOVETYPE) {
+ if (start != NULL && (lastonly?p->link==NULL:TRUE) &&
+ !(ISCLOSED(start->flag) && LASTCLOSED(last->flag))) {
+ register struct segment *r; /* newly created */
+
+ start->flag |= ISCLOSED(ON);
+ r = PathSegment(LINETYPE, firstx - x,
+ firsty - y);
+ INSERT(last, r, p);
+ r->flag |= LASTCLOSED(ON);
+ /*< adjust 'last' if possible for a 0,0 close >*/
+{
+
+#define CLOSEFUDGE 3 /* if we are this close, let's change last segment */
+
+ if (r->dest.x != 0 || r->dest.y != 0) {
+ if (r->dest.x <= CLOSEFUDGE && r->dest.x >= -CLOSEFUDGE
+ && r->dest.y <= CLOSEFUDGE && r->dest.y >= -CLOSEFUDGE) {
+ lastnonhint->dest.x += r->dest.x;
+ lastnonhint->dest.y += r->dest.y;
+ r->dest.x = r->dest.y = 0;
+ }
+ }
+}
+ if (p->link != NULL) {
+ p->dest.x += x - firstx;
+ p->dest.y += y - firsty;
+ x = firstx;
+ y = firsty;
+ }
+ }
+ start = p;
+ firstx = x + p->dest.x;
+ firsty = y + p->dest.y;
+ }
+ else if (p->type != HINTTYPE)
+ lastnonhint = p;
+ }
+ return(p0);
+}
+
+/*
+:h2.Transforming and Putting Handles on Paths
+
+:h3.PathTransform() - Transform a Path
+
+Transforming a path involves transforming all the points. In order
+that closed paths do not become "unclosed" when their relative
+positions are slightly changed due to loss of arithmetic precision,
+all point transformations are in absolute coordinates.
+
+(It might be better to reset the "absolute" coordinates every time a
+move segment is encountered. This would mean that we could accumulate
+error from subpath to subpath, but we would be less likely to make
+the "big error" where our fixed point arithmetic "wraps". However, I
+think I'll keep it this way until something happens to convince me
+otherwise.)
+
+The transform is described as a "space", that way we can use our
+old friend the "iconvert" function, which should be very efficient.
+*/
+
+struct segment *
+PathTransform(struct segment *p0, /* path to transform */
+ struct XYspace *S) /* pseudo space to transform in */
+{
+ register struct segment *p; /* to loop through path with */
+ register fractpel newx,newy; /* current transformed position in path */
+ register fractpel oldx,oldy; /* current untransformed position in path */
+ register fractpel savex,savey; /* save path delta x,y */
+
+ p0 = UniquePath(p0);
+
+ newx = newy = oldx = oldy = 0;
+
+ for (p=p0; p != NULL; p=p->link) {
+
+ savex = p->dest.x; savey = p->dest.y;
+
+ (*S->iconvert)(&p->dest, S, p->dest.x + oldx, p->dest.y + oldy);
+ p->dest.x -= newx;
+ p->dest.y -= newy;
+
+ switch (p->type) {
+
+ case LINETYPE:
+ case MOVETYPE:
+ break;
+
+ case CONICTYPE:
+ {
+ register struct conicsegment *cp = (struct conicsegment *) p;
+
+ (*S->iconvert)(&cp->M, S, cp->M.x + oldx, cp->M.y + oldy);
+ cp->M.x -= newx;
+ cp->M.y -= newy;
+ /*
+ * Note roundness doesn't change... linear transform
+ */
+ break;
+ }
+
+
+ case BEZIERTYPE:
+ {
+ register struct beziersegment *bp = (struct beziersegment *) p;
+
+ (*S->iconvert)(&bp->B, S, bp->B.x + oldx, bp->B.y + oldy);
+ bp->B.x -= newx;
+ bp->B.y -= newy;
+ (*S->iconvert)(&bp->C, S, bp->C.x + oldx, bp->C.y + oldy);
+ bp->C.x -= newx;
+ bp->C.y -= newy;
+ break;
+ }
+
+ case HINTTYPE:
+ {
+ register struct hintsegment *hp = (struct hintsegment *) p;
+
+ (*S->iconvert)(&hp->ref, S, hp->ref.x + oldx, hp->ref.y + oldy);
+ hp->ref.x -= newx;
+ hp->ref.y -= newy;
+ (*S->iconvert)(&hp->width, S, hp->width.x, hp->width.y);
+ /* Note: width is not relative to origin */
+ break;
+ }
+
+ case TEXTTYPE:
+ {
+ XformText(p,S);
+ break;
+ }
+
+ default:
+ Abort("PathTransform: invalid segment");
+ }
+ oldx += savex;
+ oldy += savey;
+ newx += p->dest.x;
+ newy += p->dest.y;
+ }
+ return(p0);
+}
+
+/*
+:h3.PathDelta() - Return a Path's Ending Point
+*/
+
+void
+PathDelta(struct segment *p, /* input path */
+ struct fractpoint *pt) /* pointer to x,y to set */
+{
+ struct fractpoint mypoint; /* I pass this to TextDelta */
+ register fractpel x,y; /* working variables for path current point */
+
+ mypoint.x = mypoint.y = 0;
+
+ for (x=y=0; p != NULL; p=p->link) {
+ x += p->dest.x;
+ y += p->dest.y;
+ if (p->type == TEXTTYPE) {
+ TextDelta(p, &mypoint);
+ x += mypoint.x;
+ y += mypoint.y;
+ }
+ }
+
+ pt->x = x;
+ pt->y = y;
+}
+
+/*
+:h2.Querying Locations and Paths
+
+:h3.QueryLoc() - Return the X,Y of a Locition
+*/
+
+void
+QueryLoc(struct segment *P, /* location to query, not consumed */
+ struct XYspace *S, /* XY space to return coordinates in */
+ double *xP, double *yP) /* coordinates returned here */
+{
+ if (!ISLOCATION(P)) {
+ ArgErr("QueryLoc: first arg not a location", P, NULL);
+ return;
+ }
+ if (S->type != SPACETYPE) {
+ ArgErr("QueryLoc: second arg not a space", S, NULL);
+ return;
+ }
+ UnConvert(S, &P->dest, xP, yP);
+}
diff --git a/libXfont/src/Type1/paths.h b/libXfont/src/Type1/paths.h
new file mode 100644
index 000000000..3803c530c
--- /dev/null
+++ b/libXfont/src/Type1/paths.h
@@ -0,0 +1,205 @@
+/* $Xorg: paths.h,v 1.3 2000/08/17 19:46:31 cpqbld Exp $ */
+/* Copyright International Business Machines, Corp. 1991
+ * All Rights Reserved
+ * Copyright Lexmark International, Inc. 1991
+ * All Rights Reserved
+ *
+ * License to use, copy, modify, and distribute this software and its
+ * documentation for any purpose and without fee is hereby granted,
+ * provided that the above copyright notice appear in all copies and that
+ * both that copyright notice and this permission notice appear in
+ * supporting documentation, and that the name of IBM or Lexmark not be
+ * used in advertising or publicity pertaining to distribution of the
+ * software without specific, written prior permission.
+ *
+ * IBM AND LEXMARK PROVIDE THIS SOFTWARE "AS IS", WITHOUT ANY WARRANTIES OF
+ * ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING, BUT NOT LIMITED TO ANY
+ * IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE,
+ * AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. THE ENTIRE RISK AS TO THE
+ * QUALITY AND PERFORMANCE OF THE SOFTWARE, INCLUDING ANY DUTY TO SUPPORT
+ * OR MAINTAIN, BELONGS TO THE LICENSEE. SHOULD ANY PORTION OF THE
+ * SOFTWARE PROVE DEFECTIVE, THE LICENSEE (NOT IBM OR LEXMARK) ASSUMES THE
+ * ENTIRE COST OF ALL SERVICING, REPAIR AND CORRECTION. IN NO EVENT SHALL
+ * IBM OR LEXMARK BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
+ * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
+ * THIS SOFTWARE.
+ */
+/* $XFree86: xc/lib/font/Type1/paths.h,v 1.3 1999/08/22 08:58:53 dawes Exp $ */
+
+/*SHARED*/
+
+#define Loc(S,x,y) t1_Loc(S,(double)x,(double)y)
+#define ILoc(S,x,y) t1_ILoc(S,x,y)
+#define Line(P) t1_Line(P)
+#define Join(p1,p2) t1_Join(p1,p2)
+#define ClosePath(p) t1_ClosePath(p,0)
+#define CloseLastSubPath(p) t1_ClosePath(p,1)
+#define Conic(B,C,s) t1_Conic(B,C,(double)s)
+#define RoundConic(M,C,r) t1_RoundConic(M,C,(double)r)
+#define ArcP3(S,P2,P3) t1_ArcP3(S,P2,P3)
+#define ArcCA(S,C,d) t1_ArcCA(S,C,(double)d)
+#define Bezier(B,C,D) t1_Bezier(B,C,D)
+#define Hint(S,r,w,o,h,a,d,l) t1_Hint(S,r,w,o,h,a,d,l)
+#define Reverse(p) t1_Reverse(p)
+#define ReverseSubPaths(p) t1_ReverseSubPaths(p)
+#define AddLoc(p1,p2) t1_Join(p1,p2)
+#define SubLoc(p1,p2) t1_SubLoc(p1,p2)
+#define DropSegment(p) t1_DropSegment(p)
+#define HeadSegment(p) t1_HeadSegment(p)
+#define QueryLoc(P,S,x,y) t1_QueryLoc(P,S,x,y)
+#define QueryPath(p,t,B,C,D,r) t1_QueryPath(p,t,B,C,D,r)
+#define QueryBounds(p,S,x1,y1,x2,y2) t1_QueryBounds(p,S,x1,y1,x2,y2)
+
+
+/* create a location object (or "move" segment) */
+extern struct segment *t1_Loc ( struct XYspace *S, double x, double y );
+/* integer argument version of same */
+extern struct segment *t1_ILoc ( struct XYspace *S, int x, int y );
+/* straight line path segment */
+extern struct segment *t1_Line ( struct segment *P );
+/* join two paths or regions together */
+extern struct segment *t1_Join ( struct segment *p1, struct segment *p2 );
+/* close a path or path set */
+extern struct segment *t1_ClosePath ( struct segment *p0, int lastonly );
+#if 0
+struct conicsegment *t1_Conic(); /* conic curve path segment */
+
+struct conicsegment *t1_RoundConic(); /* ditto, specified another way */
+struct conicsegment *t1_ArcP3(); /* circular path segment with three points */
+struct conicsegment *t1_ArcCA(); /* ditto, with center point and angle */
+#endif
+/* Bezier third order curve path segment */
+extern struct beziersegment *t1_Bezier ( struct segment *B, struct segment *C,
+ struct segment *D );
+/* Query location; return its (x,y) */
+extern void t1_QueryLoc ( struct segment *P, struct XYspace *S, double *xP,
+ double *yP );
+/*END SHARED*/
+/*SHARED*/
+
+#define CopyPath(p) t1_CopyPath(p)
+#define KillPath(p) t1_KillPath(p)
+#define PathTransform(p,m) t1_PathXform(p,m)
+#define PathDelta(p,pt) t1_PathDelta(p,pt)
+#define BoundingBox(h,w) t1_BoundingBox(h,w)
+#define PathSegment(t,x,y) t1_PathSegment(t,(fractpel)x,(fractpel)y)
+#define JoinSegment(b,t,x,y,a) t1_JoinSegment(b,t,(fractpel)x,(fractpel)y,a)
+#define Hypoteneuse(dx,dy) t1_Hypoteneuse(dx,dy)
+
+/* duplicate a path */
+extern struct segment *t1_CopyPath ( struct segment *p0 );
+/* destroy a path */
+extern void t1_KillPath ( struct segment *p );
+/* transform a path arbitrarily */
+extern struct segment *t1_PathXform ( struct segment *p0, struct XYspace *S );
+/* calculate the ending point of a path */
+extern void t1_PathDelta ( struct segment *p, struct fractpoint *pt );
+/* produce a MOVE or LINE segment */
+extern struct segment *t1_PathSegment ( int type, fractpel x, fractpel y );
+/* join a MOVE or LINE segment to a path */
+extern struct segment *t1_JoinSegment ( struct segment *before, int type, fractpel x, fractpel y, struct segment *after );
+
+/*END SHARED*/
+/*SHARED*/
+
+#define ConsumePath(p) MAKECONSUME(p,KillPath(p))
+#define UniquePath(p) MAKEUNIQUE(p,CopyPath(p))
+
+/*END SHARED*/
+/*SHARED*/
+
+struct segment {
+ XOBJ_COMMON /* xobject common data define 3-26-91 PNM */
+ unsigned char size; /* size of the structure */
+ unsigned char context; /* index to device context */
+ struct segment *link; /* pointer to next structure in linked list */
+ struct segment *last; /* pointer to last structure in list */
+ struct fractpoint dest; /* relative ending location of path segment */
+} ;
+
+#define ISCLOSED(flag) ((flag)&0x80) /* subpath is closed */
+#define LASTCLOSED(flag) ((flag)&0x40) /* last segment in closed subpath */
+
+/*
+NOTE: The ISCLOSED flag is set on the MOVETYPE segment before the
+subpath proper; the LASTCLOSED flag is set on the last segment (LINETYPE)
+in the subpath
+
+We define the ISPATHANCHOR predicate to test that a path handle
+passed by the user is valid:
+*/
+
+#define ISPATHANCHOR(p) (ISPATHTYPE(p->type)&&p->last!=NULL)
+
+/*
+For performance reasons, a user's "location" object is identical to
+a path whose only segment is a move segment. We define a predicate
+to test for this case. See also :hdref refid=location..
+*/
+
+#define ISLOCATION(p) ((p)->type == MOVETYPE && (p)->link == NULL)
+
+/*END SHARED*/
+/*SHARED*/
+
+struct conicsegment {
+ XOBJ_COMMON /* xobject common data define 3-26-91 PNM */
+ /* type = CONICTYPE */
+ unsigned char size; /* as with any 'segment' type */
+ unsigned char context; /* as with any 'segment' type */
+ struct segment *link; /* as with any 'segment' type */
+ struct segment *last; /* as with any 'segment' type */
+ struct fractpoint dest; /* Ending point (C point) */
+ struct fractpoint M; /* "midpoint" of conic explained above */
+ float roundness; /* explained above */
+} ;
+/*END SHARED*/
+/*SHARED*/
+
+struct beziersegment {
+ XOBJ_COMMON /* xobject common data define 3-26-91 PNM */
+ /* type = BEZIERTYPE */
+ unsigned char size; /* as with any 'segment' type */
+ unsigned char context; /* as with any 'segment' type */
+ struct segment *link; /* as with any 'segment' type */
+ struct segment *last; /* as with any 'segment' type */
+ struct fractpoint dest; /* ending point (D) */
+ struct fractpoint B; /* control point B */
+ struct fractpoint C; /* control point C */
+} ;
+
+/*END SHARED*/
+/*SHARED*/
+
+struct hintsegment {
+ XOBJ_COMMON /* xobject common data define 3-26-91 PNM */
+ /* type = HINTTYPE */
+ unsigned char size; /* size of the structure */
+ unsigned char context; /* device context */
+ struct segment *link; /* pointer to next structure in linked list */
+ struct segment *last; /* pointer to last structure in list */
+ struct fractpoint dest; /* ALWAYS 0,0 */
+ struct fractpoint ref;
+ struct fractpoint width;
+ char orientation;
+ char hinttype;
+ char adjusttype;
+ char direction;
+ int label;
+} ;
+
+/*END SHARED*/
+/*SHARED*/
+
+/*
+CONCAT links the 'p2' path chain on the end of the 'p1' chain. (This macro
+is also used by the STROKES module.)
+*/
+#define CONCAT(p1, p2) { \
+ p1->last->link = p2; /* link p2 on end of p1 */ \
+ p1->last = p2->last; /* last of new is last of p2 */ \
+ p2->last = NULL; } /* only first segment has non-NULL "last" */
+
+/*END SHARED*/
diff --git a/libXfont/src/Type1/pictures.h b/libXfont/src/Type1/pictures.h
new file mode 100644
index 000000000..0abc715ce
--- /dev/null
+++ b/libXfont/src/Type1/pictures.h
@@ -0,0 +1,50 @@
+/* $Xorg: pictures.h,v 1.3 2000/08/17 19:46:31 cpqbld Exp $ */
+/* Copyright International Business Machines,Corp. 1991
+ * All Rights Reserved
+ *
+ * License to use, copy, modify, and distribute this software
+ * and its documentation for any purpose and without fee is
+ * hereby granted, provided that the above copyright notice
+ * appear in all copies and that both that copyright notice and
+ * this permission notice appear in supporting documentation,
+ * and that the name of IBM not be used in advertising or
+ * publicity pertaining to distribution of the software without
+ * specific, written prior permission.
+ *
+ * IBM PROVIDES THIS SOFTWARE "AS IS", WITHOUT ANY WARRANTIES
+ * OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING, BUT NOT
+ * LIMITED TO ANY IMPLIED WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE, AND NONINFRINGEMENT OF
+ * THIRD PARTY RIGHTS. THE ENTIRE RISK AS TO THE QUALITY AND
+ * PERFORMANCE OF THE SOFTWARE, INCLUDING ANY DUTY TO SUPPORT
+ * OR MAINTAIN, BELONGS TO THE LICENSEE. SHOULD ANY PORTION OF
+ * THE SOFTWARE PROVE DEFECTIVE, THE LICENSEE (NOT IBM) ASSUMES
+ * THE ENTIRE COST OF ALL SERVICING, REPAIR AND CORRECTION. IN
+ * NO EVENT SHALL IBM BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING
+ * FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF
+ * CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
+ * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+ * SOFTWARE.
+ */
+/* $XFree86: xc/lib/font/Type1/pictures.h,v 1.3 1999/08/22 08:58:53 dawes Exp $ */
+
+/* STUB */
+
+#define CopyPicture(p) p
+#define UniquePicture(p) p
+#define KillPicture(p)
+#define BegHandle(o,m) o
+#define EndHandle(o,m) o
+#define PictureBounds(P) P
+
+struct picture {
+ struct fractpoint origin;
+ struct fractpoint ending;
+};
+
+#define Phantom(o) t1_Phantom(o)
+#define Snap(o) t1_Snap(o)
+
+extern struct segment *t1_Phantom ( struct segment *p );
+extern struct segment *t1_Snap ( struct segment *p );
diff --git a/libXfont/src/Type1/regions.c b/libXfont/src/Type1/regions.c
new file mode 100644
index 000000000..a08682174
--- /dev/null
+++ b/libXfont/src/Type1/regions.c
@@ -0,0 +1,1328 @@
+/* $Xorg: regions.c,v 1.3 2000/08/17 19:46:31 cpqbld Exp $ */
+/* Copyright International Business Machines, Corp. 1991
+ * All Rights Reserved
+ * Copyright Lexmark International, Inc. 1991
+ * All Rights Reserved
+ *
+ * License to use, copy, modify, and distribute this software and its
+ * documentation for any purpose and without fee is hereby granted,
+ * provided that the above copyright notice appear in all copies and that
+ * both that copyright notice and this permission notice appear in
+ * supporting documentation, and that the name of IBM or Lexmark not be
+ * used in advertising or publicity pertaining to distribution of the
+ * software without specific, written prior permission.
+ *
+ * IBM AND LEXMARK PROVIDE THIS SOFTWARE "AS IS", WITHOUT ANY WARRANTIES OF
+ * ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING, BUT NOT LIMITED TO ANY
+ * IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE,
+ * AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. THE ENTIRE RISK AS TO THE
+ * QUALITY AND PERFORMANCE OF THE SOFTWARE, INCLUDING ANY DUTY TO SUPPORT
+ * OR MAINTAIN, BELONGS TO THE LICENSEE. SHOULD ANY PORTION OF THE
+ * SOFTWARE PROVE DEFECTIVE, THE LICENSEE (NOT IBM OR LEXMARK) ASSUMES THE
+ * ENTIRE COST OF ALL SERVICING, REPAIR AND CORRECTION. IN NO EVENT SHALL
+ * IBM OR LEXMARK BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
+ * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
+ * THIS SOFTWARE.
+ */
+/* $XFree86: xc/lib/font/Type1/regions.c,v 3.8tsi Exp $ */
+ /* REGIONS CWEB V0023 LOTS */
+/*
+:h1 id=regions.REGIONS Module - Regions Operator Handler
+
+This module is responsible for creating and manipulating regions.
+
+&author. Jeffrey B. Lotspiech (lotspiech@almaden.ibm.com)
+
+
+:h3.Include Files
+
+The included files are:
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#ifdef FONTMODULE
+# include "os.h"
+#endif
+#include "objects.h"
+#include "spaces.h"
+#include "paths.h"
+#include "regions.h"
+#include "curves.h"
+#include "lines.h"
+#include "pictures.h"
+#include "fonts.h"
+#include "hints.h"
+#include "strokes.h" /* to pick up 'DoStroke' */
+
+
+static void newfilledge ( struct region *R, fractpel xmin, fractpel xmax,
+ fractpel ymin, fractpel ymax, int isdown );
+static struct edgelist *splitedge ( struct edgelist *list, pel y );
+static void vertjoin ( struct edgelist *top, struct edgelist *bottom );
+static int touches ( int h, pel *left, pel *right );
+static int crosses ( int h, pel *left, pel *right );
+static void edgemin ( int h, pel *e1, pel *e2 );
+static void edgemax ( int h, pel *e1, pel *e2 );
+static struct edgelist *NewEdge ( pel xmin, pel xmax, pel ymin, pel ymax,
+ pel *xvalues, int isdown );
+static struct edgelist *swathxsort ( struct edgelist *before0,
+ struct edgelist *edge );
+/*
+:h3.Functions Provided to the TYPE1IMAGER User
+
+This module provides the following TYPE1IMAGER entry points:
+*/
+
+/*SHARED LINE(S) ORIGINATED HERE*/
+/*
+:h3.Functions Provided to Other Modules
+
+This module provides the following entry points to other modules:
+*/
+
+/*SHARED LINE(S) ORIGINATED HERE*/
+/*
+:h3.Macros Provided to Other Modules
+
+:h4.GOING_TO() - Macro Predicate Needed for Changing Direction, Etc.
+
+The actual generation of run end lists (edge boundaries) is left
+to the low level rasterizing modules, LINES and CURVES. There
+are some global region-type
+questions that occur when doing a low-level
+rasterization:
+:ol.
+:li.Did we just change direction in Y and therefore need to start
+a new edge?
+:li.Did we run out of allocated edge space?
+:li.Do the minimum or maximum X values for the current edge need
+updating?
+:eol.
+In general the REGIONS is not smart enough to answer those questions
+itself. (For example, determining if and when a curve changes direction
+may need detailed curve knowledge.) Yet, this must be done efficiently.
+We provide a macro "GOING_TO" where the invoker tells us where it is
+heading for (x2,y2), plus where it is now (x1,y1), plus the current
+region under construction, and the macro answers the questions above.
+*/
+
+/*SHARED LINE(S) ORIGINATED HERE*/
+/*
+:h2.Data Structures Used to Represent Regions
+
+:h3.The "region" Structure
+
+The region structure is an anchor for a linked list of "edgelist"
+structures (see :hdref refid=edgelist..). It also summarizes the
+information in the edgelist structures (for example, the bounding
+box of the region). And, it contains scratch areas used during
+the creation of a region.
+*/
+
+/*SHARED LINE(S) ORIGINATED HERE*/
+/*
+The ISOPTIMIZED flag tells us if we've put a permanent region in
+'optimal' form.
+*/
+#define ISOPTIMIZED(flag) ((flag)&0x10)
+
+/*
+The ISRECTANGULAR flag tells us if a region is a rectangle. We don't
+always notice rectangles--if this flag is set, the region definitely
+is a rectangle, but some rectangular regions will not have the flag
+set. The flag is used to optimize some paths.
+*/
+
+/*SHARED LINE(S) ORIGINATED HERE*/
+
+/*
+:h4."EmptyRegion" - A Region Structure with Zero Area
+
+This structure is used to initialize the region to be built in
+Interior():
+Note - replaced refcount = 1 init with references = 2 3-26-91 PNM
+*/
+
+/*SHARED LINE(S) ORIGINATED HERE*/
+static struct region EmptyRegion = { REGIONTYPE,
+ ISPERMANENT(ON)+ISIMMORTAL(ON), 2,
+ {0, 0}, {0, 0},
+ MAXPEL, MAXPEL, MINPEL, MINPEL,
+ NULL, NULL,
+ 0, 0, 0, 0, 0, NULL, NULL,
+ NULL, 0, NULL, NULL };
+
+/*
+:h3 id=edgelist.The "edgelist" Structure
+
+Regions are represented by a linked list of 'edgelist' structures.
+When a region is complete, the structures are paired, one for the
+left and one for the right edge. While a region is being built,
+this rule may be violated temporarily.
+
+An 'edgelist' structure contains the X values for a given span
+of Y values. The (X,Y) pairs define an edge. We use the crack
+and edge coordinate system, so that integer values of X and Y
+go between pels. The edge is defined between the minimum Y and
+maximum Y.
+
+The linked list is kept sorted from top to bottom, that is, in
+increasing y. Also, if 'e1' is an edgelist structure and 'e2' is the
+next one in the list, they must have exactly the same ymin,ymax values
+or be totally disjoint. These two requirements mean that if e2's ymin
+is less than e1's ymax, it must be exactly equal to e1's ymin. A
+sublist of structures with identical ymin and ymax values is called a
+'swath'.
+
+In addition, edgelist structures are separately linked together based
+on what subpath originally created them; each subpath is kept as a
+separate circular linked list. This information is ignored unless
+continuity checking is invoked. See :hdref refid=subpath. for a
+complete description of this.
+*/
+
+
+/*SHARED LINE(S) ORIGINATED HERE*/
+
+/*
+The "edgelist" structure follows the convention of TYPE1IMAGER user
+objects, having a type field and a flag field as the first two
+elements. However, the user never sees "edgelist" structures
+directly; he is given handles to "region" structures only.
+
+By having a type field, we can use the "copy" feature of Allocate()
+to duplicate edge lists quickly.
+
+We also define two flag bits for this structure. The ISDOWN bit is set
+if the edge is going in the direction of increasing Y. The ISAMBIGUOUS
+bit is set if the edge is identical to its neighbor (edge->link); such
+edges may be "left" when they should be "right", or vice versa,
+unnecessarily confusing the continuity checking logic. The FixSubPaths()
+routine in HINTS will swap ambiguous edges if that avoids crossing edges;
+see :hdref refid=fixsubp..
+*/
+
+/*SHARED LINE(S) ORIGINATED HERE*/
+
+/*
+:h3.KillRegion() - Destroys a Region
+
+KillRegion nominally just decrements the reference count to that region.
+If the reference count becomes 0, all memory associated with it is
+freed. We just follow the linked list, freeing as we go, then kill any
+associated (thresholded) picture.
+Note - added conditional return based on references 3-26-91 PNM
+*/
+
+void
+KillRegion(struct region *area) /* area to free */
+{
+ register struct edgelist *p; /* loop variable */
+ register struct edgelist *next; /* loop variable */
+
+ if (area->references < 0)
+ Abort("KillRegion: negative reference count");
+ if ( (--(area->references) > 1) ||
+ ( (area->references == 1) && !ISPERMANENT(area->flag) ) )
+ return;
+
+ for (p=area->anchor; p != NULL; p=next) {
+ next = p->link;
+ Free(p);
+ }
+ if (area->thresholded != NULL)
+ KillPicture(area->thresholded);
+ Free(area);
+}
+/*
+:h3.CopyRegion() - Makes a Copy of a Region
+*/
+struct region *
+CopyRegion(struct region *area) /* region to duplicate */
+{
+ register struct region *r; /* output region built here */
+ register struct edgelist *last = NULL; /* loop variable */
+ register struct edgelist *p,*newp; /* loop variables */
+
+ r = (struct region *)Allocate(sizeof(struct region), area, 0);
+ r->anchor = NULL;
+
+ for (p=area->anchor; VALIDEDGE(p); p=p->link) {
+
+ newp = NewEdge(p->xmin, p->xmax, p->ymin, p->ymax, p->xvalues, ISDOWN(p->flag));
+ if (r->anchor == NULL)
+ r->anchor = last = newp;
+ else
+ last->link = newp;
+
+ last = newp;
+ }
+ if (area->thresholded != NULL)
+ /* replaced DupPicture with Dup() 3-26-91 PNM */
+ r->thresholded = (struct picture *)Dup(area->thresholded);
+ return(r);
+}
+/*
+:h4.NewEdge() - Allocates and Returns a New "edgelist" Structure
+
+We allocate space for the X values contiguously with the 'edgelist'
+structure that locates them. That way, we only have to free the
+edgelist structure to free all memory associated with it. Damn
+clever, huh?
+*/
+
+static struct edgelist *
+NewEdge(pel xmin, pel xmax, /* X extent of edge */
+ pel ymin, pel ymax, /* Y extent of edge */
+ pel *xvalues, /* list of X values for entire edge */
+ int isdown) /* flag: TRUE means edge progresses downward */
+{
+ static struct edgelist template = {
+ EDGETYPE, 0, 1, NULL, NULL,
+ 0, 0, 0, 0, NULL };
+
+ register struct edgelist *r; /* returned structure */
+ register int iy; /* ymin adjusted for 'long' alignment purposes */
+
+ if (ymin >= ymax)
+ Abort("newedge: height not positive");
+/*
+We are going to copy the xvalues into a newly allocated area. It
+helps performance if the values are all "long" aligned. We can test
+if the xvalues are long aligned by ANDing the address with the
+(sizeof(long) - 1)--if non zero, the xvalues are not aligned well. We
+set 'iy' to the ymin value that would give us good alignment:
+*/
+ iy = ymin - (((unsigned long)xvalues) & (sizeof(long)-1)) / sizeof(pel);
+
+ r = (struct edgelist *)Allocate(sizeof(struct edgelist), &template,
+ (ymax - iy) * sizeof(pel));
+
+ if (isdown) r->flag = ISDOWN(ON);
+ r->xmin = xmin;
+ r->xmax = xmax;
+ r->ymin = ymin;
+ r->ymax = ymax;
+
+ r->xvalues = (pel *) FOLLOWING(r);
+ if (ymin != iy) {
+ r->xvalues += ymin - iy;
+ xvalues -= ymin - iy;
+ }
+
+/*
+We must round up (ymax - iy) so we get the ceiling of the number of
+longs. The destination must be able to hold these extra bytes because
+Allocate() makes everything it allocates be in multiples of longs.
+*/
+ LONGCOPY(&r[1], xvalues, (ymax - iy) * sizeof(pel) + sizeof(long) - 1);
+
+ return(r);
+}
+
+/*
+:h3 id=discard.discard() - Discard All Edges Between Two Edges
+
+At first glance it would seem that we could discard an edgelist
+structure merely by unlinking it from the list and freeing it. You are
+wrong, region-breath! For performance, the X values associated with an
+edge are allocated contiguously with it. So, we free the X values when
+we free a structure. However, once an edge has been split, we are no
+longer sure which control block actually is part of the memory block
+that contains the edges. Rather than trying to decide, we play it safe
+and never free part of a region.
+
+So, to mark a 'edgelist' structure as discarded, we move it to the end
+of the list and set ymin=ymax.
+*/
+
+static void
+discard(struct edgelist *left, /* all edges between here exclusive */
+ struct edgelist *right) /* should be discarded */
+{
+ register struct edgelist *beg,*end,*p;
+
+ beg = left->link;
+ if (beg == right)
+ return;
+
+ for (p = beg; p != right; p = p->link) {
+ if (p->link == NULL && right != NULL)
+ Abort("discard(): ran off end");
+ p->ymin = p->ymax = 32767;
+ end = p;
+ }
+ /*
+ * now put the chain beg/end at the end of right, if it is not
+ * already there:
+ */
+ if (right != NULL) {
+ left->link = right;
+ while (right->link != NULL)
+ right = right->link;
+ right->link = beg;
+ }
+ end->link = NULL;
+}
+
+/*
+:h4.Unwind() - Discards Edges That Fail the Winding Rule Test
+
+The winding rule says that upward going edges should be paired with
+downward going edges only, and vice versa. So, if two upward edges
+or two downward edges are nominally left/right pairs, Unwind() should
+discard the second one. Everything should balance; we should discard
+an even number of edges; of course, we abort if we don't.
+*/
+static void
+Unwind(struct edgelist *area) /* input area modified in place */
+{
+ register struct edgelist *last = NULL,*next; /* struct before and after current one */
+ register int y; /* ymin of current swath */
+ register int count,newcount; /* winding count registers */
+
+ while (VALIDEDGE(area)) {
+
+ count = 0;
+ y = area->ymin;
+
+ do {
+ next = area->link;
+
+ if (ISDOWN(area->flag))
+ newcount = count + 1;
+ else
+ newcount = count - 1;
+
+ if (count == 0 || newcount == 0)
+ last = area;
+ else
+ discard(last, next);
+
+ count = newcount;
+ area = next;
+
+ } while (area != NULL && area->ymin == y);
+
+ if (count != 0)
+ Abort("Unwind: uneven edges");
+ }
+}
+/*
+:h2.Building Regions
+
+:h3.Interior() - Iterate Through a Path, Building a Region
+
+This routine is the workhorse driver routine that iterates through a
+path, calling the appropriate stepping routines to actually produce the
+run end "edgelist" structures.
+
+:ol.
+:li."Interior" calls StepLine or StepConic or StepBezier as appropriate
+to produce run ends.
+:li.Occasionally these routines will notice a change in Y direction
+and will call ChangeDirection (through the GOING_TO macro); this is
+a call back to the REGIONS module.
+:li.ChangeDirection will call whatever function is in the region
+structure; for Interior, this function is 'newfilledge'.
+:li.Newfilledge will call NewEdge to create a new edgelist structure,
+then, call SortSwath to sort it onto the linked list being built at
+the region "anchor".
+:eol.
+
+By making the function called by ChangeDirection be a parameter of the
+region, we allow the same ChangeDirection logic to be used by stroking.
+*/
+
+/*SHARED LINE(S) ORIGINATED HERE*/
+
+struct region *
+Interior(struct segment *p, /* take interior of this path */
+ int fillrule) /* rule to follow if path crosses itself */
+{
+ register fractpel x,y; /* keeps ending point of path segment */
+ fractpel lastx,lasty; /* previous x,y from path segment before */
+ register struct region *R; /* region I will build */
+ register struct segment *nextP; /* next segment of path */
+ struct fractpoint hint; /* accumulated hint value */
+ char tempflag; /* flag; is path temporary? */
+ char Cflag; /* flag; should we apply continuity? */
+
+ if (p == NULL)
+ return(NULL);
+/*
+Establish the 'Cflag' continuity flag based on user's fill rule and
+our own 'Continuity' pragmatic (0: never do continuity, 1: do what
+user asked, >1: do it regardless).
+*/
+ if (fillrule > 0) {
+ Cflag = Continuity > 0;
+ fillrule -= CONTINUITY;
+ }
+ else
+ Cflag = Continuity > 1;
+
+ ARGCHECK((fillrule != WINDINGRULE && fillrule != EVENODDRULE),
+ "Interior: bad fill rule", NULL, NULL, (1,p), struct region *);
+
+ if (p->type == TEXTTYPE)
+/* if (fillrule != EVENODDRULE)
+ else */
+ return((struct region *)UniquePath(p));
+ if (p->type == STROKEPATHTYPE) {
+ if (fillrule == WINDINGRULE)
+ return((struct region *)DoStroke(p));
+ else
+ p = CoercePath(p);
+ }
+
+ R = (struct region *)Allocate(sizeof(struct region), &EmptyRegion, 0);
+
+ ARGCHECK(!ISPATHANCHOR(p), "Interior: bad path", p, R, (0), struct region *);
+ ARGCHECK((p->type != MOVETYPE), "Interior: path not closed", p, R, (0), struct region *);
+
+
+/* changed definition from !ISPERMANENT to references <= 1 3-26-91 PNM */
+ tempflag = (p->references <= 1); /* only first segment in path is so marked */
+ if (!ISPERMANENT(p->flag)) p->references -= 1;
+
+ R->newedgefcn = newfilledge;
+/*
+Believe it or not, "R" is now completely initialized. We are counting
+on the copy of template to get other fields the way we want them,
+namely
+:ol.
+:li.anchor = NULL
+:li.xmin, ymin, xmax, ymax, to minimum and maximum values respectively.
+:eol.
+Anchor = NULL is very
+important to ChangeDirection.
+See :hdref refid=CD..
+
+To minimize problems of "wrapping" in our pel arithmetic, we keep an
+origin of the region which is the first move. Hopefully, that keeps
+numbers within plus or minus 32K pels.
+*/
+ R->origin.x = 0/*TOFRACTPEL(NEARESTPEL(p->dest.x))*/;
+ R->origin.y = 0/*TOFRACTPEL(NEARESTPEL(p->dest.y))*/;
+ lastx = - R->origin.x;
+ lasty = - R->origin.y;
+/*
+ChangeDirection initializes other important fields in R, such as
+lastdy, edge, edgeYstop, edgexmin, and edgexmax. The first segment
+is a MOVETYPE, so it will be called first.
+*/
+/*
+The hints data structure must be initialized once for each path.
+*/
+
+ if (ProcessHints)
+ InitHints(); /* initialize hint data structure */
+
+ while (p != NULL) {
+
+ x = lastx + p->dest.x;
+ y = lasty + p->dest.y;
+
+ nextP = p->link;
+
+/*
+Here we start the hints processing by initializing the hint value to
+zero. If ProcessHints is FALSE, the value will remain zero.
+Otherwise, hint accumulates the computed hint values.
+*/
+
+ hint.x = hint.y = 0;
+
+/*
+If we are processing hints, and this is a MOVE segment (other than
+the first on the path), we need to close (reverse) any open hints.
+*/
+
+ if (ProcessHints)
+ if ((p->type == MOVETYPE) && (p->last == NULL)) {
+ CloseHints(&hint);
+ }
+
+/*
+Next we run through all the hint segments (if any) attached to this
+segment. If ProcessHints is TRUE, we will accumulate computed hint
+values. In either case, nextP will be advanced to the first non-HINT
+segment (or NULL), and each hint segment will be freed if necessary.
+*/
+
+ while ((nextP != NULL) && (nextP->type == HINTTYPE)) {
+ if (ProcessHints)
+ ProcessHint((struct hintsegment *)nextP,
+ x + hint.x, y + hint.y, &hint);
+
+ {
+ register struct segment *saveP = nextP;
+
+ nextP = nextP->link;
+ if (tempflag)
+ Free(saveP);
+ }
+ }
+
+/*
+We now apply the full hint value to the ending point of the path segment.
+*/
+
+ x += hint.x;
+ y += hint.y;
+
+ switch(p->type) {
+
+ case LINETYPE:
+ StepLine(R, lastx, lasty, x, y);
+ break;
+
+ case CONICTYPE:
+ {
+
+/*
+For a conic curve, we apply half the hint value to the conic midpoint.
+*/
+
+ }
+ break;
+
+ case BEZIERTYPE:
+ {
+ register struct beziersegment *bp = (struct beziersegment *) p;
+
+/*
+For a Bezier curve, we apply the full hint value to the Bezier C point.
+*/
+
+ StepBezier(R, lastx, lasty,
+ lastx + bp->B.x, lasty + bp->B.y,
+ lastx + bp->C.x + hint.x,
+ lasty + bp->C.y + hint.y,
+ x, y);
+ }
+ break;
+
+ case MOVETYPE:
+/*
+At this point we have encountered a MOVE segment. This breaks the
+path, making it disjoint.
+*/
+ if (p->last == NULL) /* i.e., not first in path */
+ ChangeDirection(CD_LAST, R, lastx, lasty, (fractpel) 0);
+
+ ChangeDirection(CD_FIRST, R, x, y, (fractpel) 0);
+/*
+We'll just double check for closure here. We forgive an appended
+MOVETYPE at the end of the path, if it isn't closed:
+*/
+ if (!ISCLOSED(p->flag) && p->link != NULL)
+ return((struct region *)ArgErr("Fill: sub-path not closed", p, NULL));
+ break;
+
+ default:
+ Abort("Interior: path type error");
+ }
+/*
+We're done with this segment. Advance to the next path segment in
+the list, freeing this one if necessary:
+*/
+ lastx = x; lasty = y;
+
+ if (tempflag)
+ Free(p);
+ p = nextP;
+ }
+ ChangeDirection(CD_LAST, R, lastx, lasty, (fractpel) 0);
+ R->ending.x = lastx;
+ R->ending.y = lasty;
+/*
+Finally, clean up the region's based on the user's 'fillrule' request:
+*/
+ if (Cflag)
+ ApplyContinuity(R);
+ if (fillrule == WINDINGRULE)
+ Unwind(R->anchor);
+ return(R);
+}
+/*
+:h3."workedge" Array
+
+This is a statically allocated array where edges are built
+before being copied into more permanent storage by NewEdge().
+*/
+
+#ifndef MAXEDGE
+#define MAXEDGE 1000
+#endif
+
+static pel workedge[MAXEDGE];
+static pel *currentworkarea = workedge;
+static pel currentsize = MAXEDGE;
+
+/*
+:h3 id=cd.ChangeDirection() - Called When Y Direction Changes
+
+The rasterizing routines call this entry point when they detect
+a change in Y. We then build the current edge and sort it into
+emerging edgelist at 'anchor' by calling whatever "newedgefcn"
+is appropriate.
+*/
+
+void
+ChangeDirection(int type, /* CD_FIRST, CD_CONTINUE, or CD_LAST */
+ struct region *R, /* region in which we are changing direction */
+ fractpel x, fractpel y, /* current beginning x,y */
+ fractpel dy) /* direction and magnitude of change in y */
+{
+ register fractpel ymin,ymax; /* minimum and maximum Y since last call */
+ register pel iy; /* nearest integer pel to 'y' */
+ register pel idy; /* nearest integer pel to 'dy' */
+ register int ydiff; /* allowed Y difference in 'currentworkarea' */
+
+ if (type != CD_FIRST) {
+
+ if (R->lastdy > 0) {
+ ymin = R->firsty;
+ ymax = y;
+ }
+ else {
+ ymin = y;
+ ymax = R->firsty;
+ }
+
+ if (ymax < ymin)
+ Abort("negative sized edge?");
+
+
+ (*R->newedgefcn)(R, R->edgexmin, R->edgexmax, ymin, ymax,
+ R->lastdy > 0);
+
+ }
+
+ R->firsty = y;
+ R->firstx = x;
+ R->lastdy = dy;
+
+ iy = NEARESTPEL(y);
+ idy = NEARESTPEL(dy);
+ if (currentworkarea != workedge && idy < MAXEDGE && idy > -MAXEDGE) {
+ NonObjectFree(currentworkarea);
+ currentworkarea = workedge;
+ currentsize = MAXEDGE;
+ }
+ ydiff = currentsize - 1;
+ if (dy > 0) {
+ R->edge = &currentworkarea[-iy];
+ R->edgeYstop = TOFRACTPEL(ydiff + iy) + FPHALF;
+ }
+ else {
+ R->edge = &currentworkarea[ydiff - iy];
+ R->edgeYstop = TOFRACTPEL(iy - ydiff) - FPHALF;
+ }
+ R->edgexmax = R->edgexmin = x;
+/*
+If this is the end of a subpath, we complete the subpath circular
+chain:
+*/
+ if (type == CD_LAST && R->lastedge != NULL) {
+ register struct edgelist *e = R->firstedge;
+
+ while (e->subpath != NULL)
+ e = e->subpath;
+ e->subpath = R->lastedge;
+ R->lastedge = R->firstedge = NULL;
+ }
+}
+
+/*
+:h2.Sorting Edges
+
+:h3.SortSwath() - Vertically Sort an Edge into a Region
+
+This routine sorts an edge or a pair of edges into a growing region,
+so that the region maintains its top-to-bottom, left-to-right form.
+The rules for sorting horizontally may vary depending on what you
+are doing, but the rules for vertical sorting are always the same.
+This routine is passed an argument that is a function that will
+perform the horizontal sort on demand (for example, swathxsort() or
+SwathUnion()).
+
+This is a recursive routine. A new edge (or edge pair) may overlap
+the list I am building in strange and wonderful ways. Edges may
+cross. When this happens, my strategy is to split the incoming edge
+(or the growing list) in two at that point, execute the actual sort on
+the top part of the split, and recursively call myself to figure out
+exactly where the bottom part belongs.
+*/
+
+#define TOP(e) ((e)->ymin) /* the top of an edge (for readability */
+#define BOTTOM(e) ((e)->ymax) /* the bottom of an edge (for readability */
+
+static struct edgelist *
+SortSwath(struct edgelist *anchor, /* list being built */
+ struct edgelist *edge, /* incoming edge or pair of edges */
+ SwathFunc swathfcn) /* horizontal sorter */
+{
+ register struct edgelist *before,*after;
+ struct edgelist base;
+
+ if (anchor == NULL)
+ return(edge);
+
+ before = &base;
+ before->ymin = before->ymax = MINPEL;
+ before->link = after = anchor;
+
+/*
+If the incoming edge is above the current list, we connect the current
+list to the bottom of the incoming edge. One slight complication is
+if the incoming edge overlaps into the current list. Then, we
+first split the incoming edge in two at the point of overlap and recursively
+call ourselves to sort the bottom of the split into the current list:
+*/
+ if (TOP(edge) < TOP(after)) {
+ if (BOTTOM(edge) > TOP(after)) {
+
+ after = SortSwath(after, splitedge(edge, TOP(after)), swathfcn);
+ }
+ vertjoin(edge, after);
+ return(edge);
+ }
+/*
+At this point the top of edge is not higher than the top of the list,
+which we keep in 'after'. We move the 'after' point down the list,
+until the top of the edge occurs in the swath beginning with 'after'.
+
+If the bottom of 'after' is below the bottom of the edge, we have to
+split the 'after' swath into two parts, at the bottom of the edge.
+If the bottom of 'after' is above the bottom of the swath,
+*/
+
+ while (VALIDEDGE(after)) {
+
+ if (TOP(after) == TOP(edge)) {
+ if (BOTTOM(after) > BOTTOM(edge))
+ vertjoin(after, splitedge(after, BOTTOM(edge)));
+ else if (BOTTOM(after) < BOTTOM(edge)) {
+ after = SortSwath(after,
+ splitedge(edge, BOTTOM(after)), swathfcn);
+ }
+ break;
+ }
+ else if (TOP(after) > TOP(edge)) {
+ if (BOTTOM(edge) > TOP(after)) {
+ after = SortSwath(after,
+ splitedge(edge, TOP(after)), swathfcn);
+ }
+ break;
+ }
+ else if (BOTTOM(after) > TOP(edge))
+ vertjoin(after, splitedge(after, TOP(edge)));
+
+ before = after;
+ after = after->link;
+ }
+
+/*
+At this point 'edge' exactly corresponds in height to the current
+swath pointed to by 'after'.
+*/
+ if (after != NULL && TOP(after) == TOP(edge)) {
+ before = (*swathfcn)(before, edge);
+ after = before->link;
+ }
+/*
+At this point 'after' contains all the edges after 'edge', and 'before'
+contains all the edges before. Whew! A simple matter now of adding
+'edge' to the linked list in its rightful place:
+*/
+ before->link = edge;
+ if (RegionDebug > 1) {
+ while (edge->link != NULL) {
+ edge = edge->link;
+ }
+ }
+ else
+ for (; edge->link != NULL; edge = edge->link) { ; }
+
+ edge->link = after;
+ return(base.link);
+}
+
+/*
+:h3 id=newfill.newfilledge() - Called When We Have a New Edge While Filling
+
+This is the prototypical "newedge" function passed to "Rasterize" and
+stored in "newedgefcn" in the region being built.
+
+If the edge is non-null, we sort it onto the list of edges we are
+building at "anchor".
+
+This function also has to keep the bounding box of the region
+up to date.
+*/
+
+static void
+newfilledge(struct region *R, /* region being built */
+ fractpel xmin, fractpel xmax, /* X range of this edge */
+ fractpel ymin, fractpel ymax, /* Y range of this edge */
+ int isdown) /* flag: TRUE means edge goes down, else up */
+{
+
+ register pel pelxmin,pelymin,pelxmax,pelymax; /* pel versions of bounds */
+ register struct edgelist *edge; /* newly created edge */
+
+ pelymin = NEARESTPEL(ymin);
+ pelymax = NEARESTPEL(ymax);
+ if (pelymin == pelymax)
+ return;
+
+ pelxmin = NEARESTPEL(xmin);
+ pelxmax = NEARESTPEL(xmax);
+
+ if (pelxmin < R->xmin) R->xmin = pelxmin;
+ if (pelxmax > R->xmax) R->xmax = pelxmax;
+ if (pelymin < R->ymin) R->ymin = pelymin;
+ if (pelymax > R->ymax) R->ymax = pelymax;
+
+ edge = NewEdge(pelxmin, pelxmax, pelymin, pelymax, &R->edge[pelymin], isdown);
+ edge->subpath = R->lastedge;
+ R->lastedge = edge;
+ if (R->firstedge == NULL)
+ R->firstedge = edge;
+
+ R->anchor = SortSwath(R->anchor, edge, swathxsort);
+
+}
+
+/*
+:h3.splitedge() - Split an Edge or Swath in Two at a Given Y Value
+
+This function returns the edge or swath beginning at the Y value, and
+is guaranteed not to change the address of the old swath while splitting
+it.
+*/
+
+static struct edgelist *
+splitedge(struct edgelist *list, /* area to split */
+ pel y) /* Y value to split list at */
+{
+ register struct edgelist *new; /* anchor for newly built list */
+ register struct edgelist *last = NULL; /* end of newly built list */
+ register struct edgelist *r; /* temp pointer to new structure */
+ register struct edgelist *lastlist; /* temp pointer to last 'list' value */
+
+ lastlist = new = NULL;
+
+ while (list != NULL) {
+ if (y < list->ymin)
+ break;
+ if (y >= list->ymax)
+ Abort("splitedge: above top of list");
+ if (y == list->ymin)
+ Abort("splitedge: would be null");
+
+ r = (struct edgelist *)Allocate(sizeof(struct edgelist), list, 0);
+/*
+At this point 'r' points to a copy of the single structure at 'list'.
+We will make 'r' be the new split 'edgelist'--the lower half.
+We don't bother to correct 'xmin' and 'xmax', we'll take the
+the pessimistic answer that results from using the old values.
+*/
+ r->ymin = y;
+ r->xvalues = list->xvalues + (y - list->ymin);
+/*
+Note that we do not need to allocate new memory for the X values,
+they can remain with the old "edgelist" structure. We do have to
+update that old structure so it is not as high:
+*/
+ list->ymax = y;
+/*
+Insert 'r' in the subpath chain:
+*/
+ r->subpath = list->subpath;
+ list->subpath = r;
+/*
+Now attach 'r' to the list we are building at 'new', and advance
+'list' to point to the next element in the old list:
+*/
+ if (new == NULL)
+ new = r;
+ else
+ last->link = r;
+ last = r;
+ lastlist = list;
+ list = list->link;
+ }
+/*
+At this point we have a new list built at 'new'. We break the old
+list at 'lastlist', and add the broken off part to the end of 'new'.
+Then, we return the caller a pointer to 'new':
+*/
+ if (new == NULL)
+ Abort("null splitedge");
+ lastlist->link = NULL;
+ last->link = list;
+ return(new);
+}
+
+/*
+:h3.vertjoin() - Join Two Disjoint Edge Lists Vertically
+
+The two edges must be disjoint vertically.
+*/
+static void vertjoin(top, bottom)
+ register struct edgelist *top; /* uppermost region */
+ register struct edgelist *bottom; /* bottommost region */
+{
+ if (BOTTOM(top) > TOP(bottom))
+ Abort("vertjoin not disjoint");
+
+ for (; top->link != NULL; top=top->link) { ; }
+
+ top->link = bottom;
+ return;
+}
+
+/*
+:h3.swathxsort() - Sorting by X Values
+
+We need to sort 'edge' into its rightful
+place in the swath by X value, taking care that we do not accidentally
+advance to the next swath while searching for the correct X value. Like
+all swath functions, this function returns a pointer to the edge
+BEFORE the given edge in the sort.
+*/
+
+static struct edgelist *
+swathxsort(struct edgelist *before0, /* edge before this swath */
+ struct edgelist *edge) /* input edge */
+{
+ register struct edgelist *before;
+ register struct edgelist *after;
+ register pel y = 0;
+
+ before = before0;
+ after = before->link;
+
+ while (after != NULL && TOP(after) == TOP(edge)) {
+
+ register pel *x1,*x2;
+
+ y = TOP(edge);
+ x1 = after->xvalues;
+ x2 = edge->xvalues;
+
+ while (y < BOTTOM(edge) && *x1 == *x2) {
+ x1++; x2++; y++;
+ }
+ if (y >= BOTTOM(edge)) {
+ edge->flag |= ISAMBIGUOUS(ON);
+ after->flag |= ISAMBIGUOUS(ON);
+ break;
+ }
+
+ if (*x1 >= *x2)
+ break;
+
+ before = after;
+ after = after->link;
+ }
+
+/*
+At this point, 'edge' is between 'before' and 'after'. If 'edge' didn't
+cross either of those other edges, we would be done. We check for
+crossing. If it does cross, we split the problem up by calling SortSwath
+recursively with the part of the edge that is below the crossing point:
+*/
+{
+ register int h0,h; /* height of edge--number of scans */
+
+ h0 = h = BOTTOM(edge) - y;
+ y -= TOP(edge);
+
+ if (h0 <= 0) {
+ return(before);
+ }
+
+ if (TOP(before) == TOP(edge))
+ h -= crosses(h, &before->xvalues[y], &edge->xvalues[y]);
+ if (after != NULL && TOP(after) == TOP(edge))
+ h -= crosses(h, &edge->xvalues[y], &after->xvalues[y]);
+
+ if (h < h0) {
+ SortSwath(before0->link,
+ splitedge(edge, TOP(edge) + y + h),
+ swathxsort);
+
+ }
+}
+
+ return(before);
+}
+/*
+:h3.SwathUnion() - Union Two Edges by X Value
+
+We have a left and right edge that must be unioned into a growing
+swath. If they are totally disjoint, they are just added in. The
+fun comes in they overlap the existing edges. Then some edges
+will disappear.
+*/
+
+static struct edgelist *
+SwathUnion(struct edgelist *before0, /* edge before the swath */
+ struct edgelist *edge) /* list of two edges to be unioned */
+{
+ register int h; /* saves height of edge */
+ register struct edgelist *rightedge; /* saves right edge of 'edge' */
+ register struct edgelist *before,*after; /* edge before and after */
+ int h0; /* saves initial height */
+
+ h0 = h = edge->ymax - edge->ymin;
+ if (h <= 0)
+ Abort("SwathUnion: 0 height swath?");
+
+ before = before0;
+ after = before->link;
+
+ while (after != NULL && TOP(after) == TOP(edge)) {
+ register struct edgelist *right;
+
+ right = after->link;
+ if (right->xvalues[0] >= edge->xvalues[0])
+ break;
+ before = right;
+ after = before->link;
+ }
+/*
+This is the picture at this point. 'L' indicates a left hand edge,
+'R' indicates the right hand edge.
+'<--->' indicates the degree of uncertainty as to its placement
+relative to other edges:
+:xmp atomic.
+ before after
+ R <---L----> R L R L R
+ <---L---> <------R-------------------------->
+ edge
+:exmp.
+In case the left of 'edge' touches 'before', we need to reduce
+the height by that amount.
+*/
+ if (TOP(before) == TOP(edge))
+ h -= touches(h, before->xvalues, edge->xvalues);
+
+ rightedge = edge->link;
+
+ if (after == NULL || TOP(after) != TOP(edge) ||
+ after->xvalues[0] > rightedge->xvalues[0]) {
+/*
+On this side of the the above 'if', the new edge is disjoint from the
+existing edges in the swath. This is the picture:
+:xmp atomic.
+ before after
+ R L R L R L R
+ L R
+ edge
+:exmp.
+We will verify it remains disjoint for the entire height. If the
+situation changes somewhere down the edge, we split the edge at that
+point and recursively call ourselves (through 'SortSwath') to figure
+out the new situation:
+*/
+ if (after != NULL && TOP(after) == TOP(edge))
+ h -= touches(h, rightedge->xvalues, after->xvalues);
+ if (h < h0)
+ SortSwath(before0->link, splitedge(edge, edge->ymin + h), t1_SwathUnion);
+ /* go to "return" this edge pair; it is totally disjoint */
+ }
+ else {
+/*
+At this point, at the 'else', we know that the
+new edge overlaps one or more pairs in the existing swath. Here is
+a picture of our knowledge and uncertainties:
+:xmp atomic.
+ before after
+ R L R L R L R
+ <---L---> <---R------------------->
+ edge
+:exmp.
+We need to move 'after' along until it is to the right of the
+right of 'edge'. ('After' should always point to a left edge of a pair:)
+*/
+ register struct edgelist *left; /* variable to keep left edge in */
+
+ do {
+ left = after;
+ after = (after->link)->link;
+
+ } while (after != NULL && TOP(after) == TOP(edge)
+ && after->xvalues[0] <= rightedge->xvalues[0]);
+/*
+At this point this is the picture:
+:xmp atomic.
+ before left after
+ R L R L R L R
+ <---L---> <---R--->
+ edge
+:exmp.
+We need to verify that the situation stays like this all the way
+down the edge. Again, if the
+situation changes somewhere down the edge, we split the edge at that
+point and recursively call ourselves (through 'SortSwath') to figure
+out the new situation:
+*/
+
+ h -= crosses(h, left->xvalues, rightedge->xvalues);
+ h -= crosses(h, edge->xvalues, ((before->link)->link)->xvalues);
+
+ if (after != NULL && TOP(after) == TOP(edge))
+
+ h -= touches(h, rightedge->xvalues, after->xvalues);
+
+/*
+OK, if we touched either of our neighbors we need to split at that point
+and recursively sort the split edge onto the list. One tricky part
+is that when we recursively sort, 'after' will change if it was not
+in our current swath:
+*/
+ if (h < h0) {
+ SortSwath(before0->link,
+ splitedge(edge, edge->ymin + h),
+ t1_SwathUnion);
+
+ if (after == NULL || TOP(after) != TOP(edge))
+ for (after = before0->link;
+ TOP(after) == TOP(edge);
+ after = after->link) { ; }
+ }
+/*
+Now we need to augment 'edge' by the left and right of the overlapped
+swath, and to discard all edges between before and after, because they
+were overlapped and have been combined with the new incoming 'edge':
+*/
+ edge->xmin = MIN(edge->xmin, (before->link)->xmin);
+ edge->xmax = MIN(edge->xmax, (before->link)->xmax);
+ edgemin(h, edge->xvalues, (before->link)->xvalues);
+ rightedge->xmin = MAX(rightedge->xmin, (left->link)->xmin);
+ rightedge->xmax = MAX(rightedge->xmax, (left->link)->xmax);
+ edgemax(h, rightedge->xvalues, (left->link)->xvalues);
+ discard(before, after);
+ }
+ return(before);
+}
+#ifdef notused
+/*
+:h3.swathrightmost() - Simply Sorts New Edge to Rightmost of Swath
+
+Like all swath functions, this function returns a pointer to the edge
+BEFORE the given edge in the sort.
+*/
+
+static struct edgelist *
+swathrightmost(struct edgelist *before, /* edge before this swath */
+ struct edgelist *edge) /* input edge */
+{
+ register struct edgelist *after;
+
+ after = before->link;
+
+ while (after != NULL && TOP(after) == TOP(edge)) {
+ before = after;
+ after = after->link;
+ }
+
+ return(before);
+
+}
+#endif
+/*
+:h3.touches() - Returns the Remaining Height When Two Edges Touch
+
+So, it will return 0 if they never touch. Allows incredibly(?) mnemonic
+if (touches(...)) construct.
+*/
+
+static int
+touches(int h, pel *left, pel *right)
+{
+ for (; h > 0; h--)
+ if (*left++ >= *right++)
+ break;
+ return(h);
+}
+/*
+:h3.crosses() - Returns the Remaining Height When Two Edges Cross
+
+So, it will return 0 if they never cross.
+*/
+
+static int
+crosses(int h, pel *left, pel *right)
+{
+ for (; h > 0; h--)
+ if (*left++ > *right++)
+ break;
+ return(h);
+}
+/*
+:h3.edgemin() - Stores the Mininum of Two Edges in First Edge
+*/
+
+static void
+edgemin(int h, pel *e1, pel *e2)
+{
+ for (; --h >= 0; e1++,e2++)
+ if (*e1 > *e2)
+ *e1 = *e2;
+}
+/*
+:h3.edgemax() - Stores the Maximum of Two Edges in First Edge
+*/
+
+static void
+edgemax(int h, pel *e1, pel *e2)
+{
+ for (; --h >= 0; e1++,e2++)
+ if (*e1 < *e2)
+ *e1 = *e2;
+}
+
+/*
+:h2.Miscelaneous Routines
+
+:h3.MoreWorkArea() - Allocate New Space for "edge"
+
+Our strategy is to temporarily allocate an array to hold this
+unexpectedly large edge. ChangeDirection frees this array any time
+it gets a shorter 'dy'.
+*/
+
+/*ARGSUSED*/
+void
+MoreWorkArea(struct region *R, /* region we are generating */
+ fractpel x1, fractpel y1, /* starting point of line */
+ fractpel x2, fractpel y2) /* ending point of line */
+{
+ register int idy; /* integer dy of line */
+
+ idy = NEARESTPEL(y1) - NEARESTPEL(y2);
+ if (idy < 0) idy = - idy;
+
+ /*
+ * we must add one to the delta for the number of run ends we
+ * need to store:
+ */
+ if (++idy > currentsize) {
+ if (currentworkarea != workedge)
+ NonObjectFree(currentworkarea);
+ currentworkarea = (pel *)Allocate(0, NULL, idy * sizeof(pel));
+ currentsize = idy;
+ }
+ ChangeDirection(CD_CONTINUE, R, x1, y1, y2 - y1);
+}
diff --git a/libXfont/src/Type1/regions.h b/libXfont/src/Type1/regions.h
new file mode 100644
index 000000000..d869cf7e1
--- /dev/null
+++ b/libXfont/src/Type1/regions.h
@@ -0,0 +1,224 @@
+/* $Xorg: regions.h,v 1.3 2000/08/17 19:46:32 cpqbld Exp $ */
+/* Copyright International Business Machines, Corp. 1991
+ * All Rights Reserved
+ * Copyright Lexmark International, Inc. 1991
+ * All Rights Reserved
+ *
+ * License to use, copy, modify, and distribute this software and its
+ * documentation for any purpose and without fee is hereby granted,
+ * provided that the above copyright notice appear in all copies and that
+ * both that copyright notice and this permission notice appear in
+ * supporting documentation, and that the name of IBM or Lexmark not be
+ * used in advertising or publicity pertaining to distribution of the
+ * software without specific, written prior permission.
+ *
+ * IBM AND LEXMARK PROVIDE THIS SOFTWARE "AS IS", WITHOUT ANY WARRANTIES OF
+ * ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING, BUT NOT LIMITED TO ANY
+ * IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE,
+ * AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. THE ENTIRE RISK AS TO THE
+ * QUALITY AND PERFORMANCE OF THE SOFTWARE, INCLUDING ANY DUTY TO SUPPORT
+ * OR MAINTAIN, BELONGS TO THE LICENSEE. SHOULD ANY PORTION OF THE
+ * SOFTWARE PROVE DEFECTIVE, THE LICENSEE (NOT IBM OR LEXMARK) ASSUMES THE
+ * ENTIRE COST OF ALL SERVICING, REPAIR AND CORRECTION. IN NO EVENT SHALL
+ * IBM OR LEXMARK BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
+ * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
+ * THIS SOFTWARE.
+ */
+/* $XFree86: xc/lib/font/Type1/regions.h,v 1.7 2001/01/17 19:43:23 dawes Exp $ */
+/*SHARED*/
+
+#define Interior(p,rule) t1_Interior(p,rule)
+#define Union(a1,a2) t1_Union(a1,a2)
+#define Intersect(a1,a2) t1_Intersect(a1,a2)
+#define Complement(area) t1_Complement(area)
+#define Overlap(a1,a2) t1_OverLap(a1,a2)
+
+
+/* returns the interior of a closed path */
+extern struct region *t1_Interior ( struct segment *p, int fillrule );
+#if 0
+struct region *t1_Union(); /* set union of paths or regions */
+struct region *t1_Intersect(); /* set intersection of regions */
+struct region *t1_Complement(); /* complement of a region */
+int t1_Overlap(); /* returns a Boolean; TRUE if regions overlap */
+#endif
+
+#define TT_INFINITY t1_Infinity
+
+/*END SHARED*/
+/*SHARED*/
+
+#define ChangeDirection(type,R,x,y,dy) t1_ChangeDirection(type,R,x,y,dy)
+
+/* called when we change direction in Y */
+extern void t1_ChangeDirection ( int type, struct region *R, fractpel x,
+ fractpel y, fractpel dy );
+#define CD_FIRST -1 /* enumeration of ChangeDirection type */
+#define CD_CONTINUE 0 /* enumeration of ChangeDirection type */
+#define CD_LAST 1 /* enumeration of ChangeDirection type */
+
+#define MoreWorkArea(R,x1,y1,x2,y2) t1_MoreWorkArea(R,x1,y1,x2,y2)
+#define KillRegion(area) t1_KillRegion(area)
+#define CopyRegion(area) t1_CopyRegion(area)
+#define BoxClip(R,xmin,ymin,xmax,ymax) t1_BoxClip(R,xmin,ymin,xmax,ymax)
+#define SortSwath(a,p,f) t1_SortSwath(a,p,f)
+#define SwathUnion(b,e) t1_SwathUnion(b,e)
+#define RegionBounds(r) t1_RegionBounds(r)
+#define CoerceRegion(p) t1_CoerceRegion(p)
+#define MoveEdges(R,dx,dy) t1_MoveEdges(R,dx,dy)
+#define UnJumble(R) t1_UnJumble(R)
+
+typedef struct edgelist *(*SwathFunc)(struct edgelist *, struct edgelist *);
+
+/* get longer edge list for stepping */
+extern void t1_MoreWorkArea ( struct region *R, fractpel x1, fractpel y1,
+ fractpel x2, fractpel y2 );
+/* duplicate a region */
+extern struct region *t1_CopyRegion ( struct region *area );
+/* destroy a region */
+extern void t1_KillRegion ( struct region *area );
+
+/*END SHARED*/
+/*SHARED*/
+
+#define GOING_TO(R, x1, y1, x2, y2, dy) { \
+ if (dy < 0) { \
+ if (R->lastdy >= 0) \
+ ChangeDirection(CD_CONTINUE, R, x1, y1, dy); \
+ if (y2 < R->edgeYstop) \
+ MoreWorkArea(R, x1, y1, x2, y2); \
+ } \
+ else if (dy > 0) { \
+ if (R->lastdy <= 0) \
+ ChangeDirection(CD_CONTINUE, R, x1, y1, dy); \
+ if (y2 > R->edgeYstop) \
+ MoreWorkArea(R, x1, y1, x2, y2); \
+ } \
+ else /* dy == 0 */ ChangeDirection(CD_CONTINUE, R, x1, y1, dy); \
+ if (x2 < R->edgexmin) R->edgexmin = x2; \
+ else if (x2 > R->edgexmax) R->edgexmax = x2; \
+}
+
+#ifndef FONTMODULE
+#ifndef __sxg__
+#include <limits.h>
+#endif
+#endif
+#ifdef SHRT_MIN
+#define MINPEL SHRT_MIN
+#else
+#define MINPEL ((pel)(-1<<(8*sizeof(pel)-1))) /* smallest value fitting in a pel */
+#endif
+#ifdef SHRT_MAX
+#define MAXPEL SHRT_MAX
+#else
+#define MAXPEL ((pel)((1<<(8*sizeof(pel)-1))-1))/* largest value fitting in a pel */
+#endif
+
+/*
+The "Unique"-type macro is different (unique?) for regions, because some
+regions structures are shared among several objects, and might have
+to be made unique for that reason (i.e., references > 1).
+*/
+
+#define ConsumeRegion(R) MAKECONSUME(R,KillRegion(R))
+#define UniqueRegion(R) MAKEUNIQUE(R,CopyRegion(R))
+
+
+/*END SHARED*/
+/*SHARED*/
+
+typedef void (*NewEdgeFunc)(struct region *,
+ fractpel, fractpel, fractpel, fractpel, int);
+
+struct region {
+ XOBJ_COMMON /* xobject common data define 3-26-91 PNM */
+ /* type = REGIONTYPE */
+ struct fractpoint origin; /* beginning handle: X,Y origin of region */
+ struct fractpoint ending; /* ending handle: X,Y change after painting region */
+ pel xmin,ymin; /* minimum X,Y of region */
+ pel xmax,ymax; /* mat1_mum X,Y of region */
+ struct edgelist *anchor; /* list of edges that bound the region */
+ struct picture *thresholded; /* region defined by thresholded picture*/
+/*
+Note that the ending handle and the bounding box values are stored
+relative to 'origin'.
+
+The above elements describe a region. The following elements are
+scratchpad areas used while the region is being built:
+*/
+ fractpel lastdy; /* direction of last segment */
+ fractpel firstx,firsty; /* starting point of current edge */
+ fractpel edgexmin,edgexmax; /* x extent of current edge */
+ struct edgelist *lastedge,*firstedge; /* last and first edges in subpath */
+ pel *edge; /* pointer to array of X values for edge */
+ fractpel edgeYstop; /* Y value where 'edges' array ends */
+ NewEdgeFunc newedgefcn; /* function to use when building a new edge */
+ struct strokeinfo *strokeinfo; /* scratchpad info during stroking only */
+} ;
+/*
+The ISCOMPLEMENT flag indicates the region is reversed--it is the
+"outside" of the nominal region.
+*/
+#define ISCOMPLEMENT(flag) ((flag)&0x80)
+/*
+The ISJUMBLED flag indicates the region is not sorted top-to-bottom.
+*/
+#define ISJUMBLED(flag) ((flag)&0x40)
+/*
+The ISINFINITE flag allows a quick check for an INFINITE region, which
+is frequently intersected.
+*/
+#define ISINFINITE(flag) ((flag)&0x20)
+
+/*END SHARED*/
+/*SHARED*/
+
+#define ISRECTANGULAR(flag) ((flag)&0x08)
+
+/*END SHARED*/
+/*SHARED*/
+
+#define EmptyRegion t1_EmptyRegion
+
+/*END SHARED*/
+/*SHARED*/
+
+struct edgelist {
+ XOBJ_COMMON /* xobject common data define 3-26-91 PNM */
+ /* type = EDGETYPE */
+ struct edgelist *link; /* pointer to next in linked list */
+ struct edgelist *subpath; /* informational link for "same subpath" */
+ pel xmin,xmax; /* range of edge in X */
+ pel ymin,ymax; /* range of edge in Y */
+ pel *xvalues; /* pointer to ymax-ymin X values */
+} ;
+/*
+The end of the list is marked by either "link" being NULL, or by
+ymin == ymax. See :hdref refid=discard.. We define the VALIDEDGE
+predicate to test for the opposite of these conditions:
+*/
+
+#define VALIDEDGE(p) ((p)!=NULL&&(p)->ymin<(p)->ymax)
+
+/*END SHARED*/
+/*SHARED*/
+
+#define ISDOWN(f) ((f)&0x80)
+
+#define ISAMBIGUOUS(f) ((f)&0x40)
+
+/*END SHARED*/
+/*SHARED*/
+
+/*
+Interior() rule enumerations:
+*/
+#define WINDINGRULE -2
+#define EVENODDRULE -3
+
+#define CONTINUITY 0x80 /* can be added to above rules; e.g. WINDINGRULE+CONTINUITY */
+
+/*END SHARED*/
diff --git a/libXfont/src/Type1/scanfont.c b/libXfont/src/Type1/scanfont.c
new file mode 100644
index 000000000..8cad57fcf
--- /dev/null
+++ b/libXfont/src/Type1/scanfont.c
@@ -0,0 +1,1526 @@
+/* $XdotOrg: xc/lib/font/Type1/scanfont.c,v 1.5 2005/07/09 23:18:27 keithp Exp $ */
+/* $Xorg: scanfont.c,v 1.3 2000/08/17 19:46:32 cpqbld Exp $ */
+/* Copyright International Business Machines,Corp. 1991
+ * All Rights Reserved
+ *
+ * License to use, copy, modify, and distribute this software
+ * and its documentation for any purpose and without fee is
+ * hereby granted, provided that the above copyright notice
+ * appear in all copies and that both that copyright notice and
+ * this permission notice appear in supporting documentation,
+ * and that the name of IBM not be used in advertising or
+ * publicity pertaining to distribution of the software without
+ * specific, written prior permission.
+ *
+ * IBM PROVIDES THIS SOFTWARE "AS IS", WITHOUT ANY WARRANTIES
+ * OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING, BUT NOT
+ * LIMITED TO ANY IMPLIED WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE, AND NONINFRINGEMENT OF
+ * THIRD PARTY RIGHTS. THE ENTIRE RISK AS TO THE QUALITY AND
+ * PERFORMANCE OF THE SOFTWARE, INCLUDING ANY DUTY TO SUPPORT
+ * OR MAINTAIN, BELONGS TO THE LICENSEE. SHOULD ANY PORTION OF
+ * THE SOFTWARE PROVE DEFECTIVE, THE LICENSEE (NOT IBM) ASSUMES
+ * THE ENTIRE COST OF ALL SERVICING, REPAIR AND CORRECTION. IN
+ * NO EVENT SHALL IBM BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING
+ * FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF
+ * CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
+ * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+ * SOFTWARE.
+ */
+/* Author: Katherine A. Hitchcock IBM Almaden Research Laboratory */
+/* $XFree86: xc/lib/font/Type1/scanfont.c,v 1.16 2003/05/27 22:26:46 tsi Exp $ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#ifndef FONTMODULE
+#include <string.h>
+#else
+#include "Xdefs.h" /* Bool declaration */
+#include "Xmd.h" /* INT32 declaration */
+#include "xf86_ansic.h"
+#endif
+#include "t1stdio.h"
+#include "util.h"
+#include "token.h"
+#include "objects.h"
+#include "spaces.h"
+#include "fontfcn.h"
+#include "blues.h"
+
+#include <limits.h>
+
+static int rc;
+static boolean InPrivateDict;
+static boolean WantFontInfo;
+static boolean TwoSubrs;
+static psobj inputFile;
+static psobj filterFile;
+static psobj *inputP;
+
+
+/**********************************************************************/
+/* Init_BuiltInEncoding() */
+/* */
+/* Initializes the StandardEncoding and ISOLatin1Encoding vector. */
+/* */
+/**********************************************************************/
+typedef struct /* Builtin Standard Encoding */
+{
+ int index;
+ char *name;
+} EncodingTable;
+
+static EncodingTable StdEnc[] = {
+ { 040 , "space" },
+ { 041 , "exclam" },
+ { 042 , "quotedbl" },
+ { 043 , "numbersign" },
+ { 044 , "dollar" },
+ { 045 , "percent" },
+ { 046 , "ampersand" },
+ { 047 , "quoteright" },
+ { 050 , "parenleft" },
+ { 051 , "parenright" },
+ { 052 , "asterisk" },
+ { 053 , "plus" },
+ { 054 , "comma" },
+ { 055 , "hyphen" },
+ { 056 , "period" },
+ { 057 , "slash" },
+ { 060 , "zero" },
+ { 061 , "one" },
+ { 062 , "two" },
+ { 063 , "three" },
+ { 064 , "four" },
+ { 065 , "five" },
+ { 066 , "six" },
+ { 067 , "seven" },
+ { 070 , "eight" },
+ { 071 , "nine" },
+ { 072 , "colon" },
+ { 073 , "semicolon" },
+ { 074 , "less" },
+ { 075 , "equal" },
+ { 076 , "greater" },
+ { 077 , "question" },
+ { 0100 , "at" },
+ { 0101 , "A" },
+ { 0102 , "B" },
+ { 0103 , "C" },
+ { 0104 , "D" },
+ { 0105 , "E" },
+ { 0106 , "F" },
+ { 0107 , "G" },
+ { 0110 , "H" },
+ { 0111 , "I" },
+ { 0112 , "J" },
+ { 0113 , "K" },
+ { 0114 , "L" },
+ { 0115 , "M" },
+ { 0116 , "N" },
+ { 0117 , "O" },
+ { 0120 , "P" },
+ { 0121 , "Q" },
+ { 0122 , "R" },
+ { 0123 , "S" },
+ { 0124 , "T" },
+ { 0125 , "U" },
+ { 0126 , "V" },
+ { 0127 , "W" },
+ { 0130 , "X" },
+ { 0131 , "Y" },
+ { 0132 , "Z" },
+ { 0133 , "bracketleft" },
+ { 0134 , "backslash" },
+ { 0135 , "bracketright" },
+ { 0136 , "asciicircum" },
+ { 0137 , "underscore" },
+ { 0140 , "quoteleft" },
+ { 0141 , "a" },
+ { 0142 , "b" },
+ { 0143 , "c" },
+ { 0144 , "d" },
+ { 0145 , "e" },
+ { 0146 , "f" },
+ { 0147 , "g" },
+ { 0150 , "h" },
+ { 0151 , "i" },
+ { 0152 , "j" },
+ { 0153 , "k" },
+ { 0154 , "l" },
+ { 0155 , "m" },
+ { 0156 , "n" },
+ { 0157 , "o" },
+ { 0160 , "p" },
+ { 0161 , "q" },
+ { 0162 , "r" },
+ { 0163 , "s" },
+ { 0164 , "t" },
+ { 0165 , "u" },
+ { 0166 , "v" },
+ { 0167 , "w" },
+ { 0170 , "x" },
+ { 0171 , "y" },
+ { 0172 , "z" },
+ { 0173 , "braceleft" },
+ { 0174 , "bar" },
+ { 0175 , "braceright" },
+ { 0176 , "asciitilde" },
+ { 0241 , "exclamdown" },
+ { 0242 , "cent" },
+ { 0243 , "sterling" },
+ { 0244 , "fraction" },
+ { 0245 , "yen" },
+ { 0246 , "florin" },
+ { 0247 , "section" },
+ { 0250 , "currency" },
+ { 0251 , "quotesingle" },
+ { 0252 , "quotedblleft" },
+ { 0253 , "guillemotleft" },
+ { 0254 , "guilsinglleft" },
+ { 0255 , "guilsinglright" },
+ { 0256 , "fi" },
+ { 0257 , "fl" },
+ { 0261 , "endash" },
+ { 0262 , "dagger" },
+ { 0263 , "daggerdbl" },
+ { 0264 , "periodcentered" },
+ { 0266 , "paragraph" },
+ { 0267 , "bullet" },
+ { 0270 , "quotesinglbase" },
+ { 0271 , "quotedblbase" },
+ { 0272 , "quotedblright" },
+ { 0273 , "guillemotright" },
+ { 0274 , "ellipsis" },
+ { 0275 , "perthousand" },
+ { 0277 , "questiondown" },
+ { 0301 , "grave" },
+ { 0302 , "acute" },
+ { 0303 , "circumflex" },
+ { 0304 , "tilde" },
+ { 0305 , "macron" },
+ { 0306 , "breve" },
+ { 0307 , "dotaccent" },
+ { 0310 , "dieresis" },
+ { 0312 , "ring" },
+ { 0313 , "cedilla" },
+ { 0315 , "hungarumlaut" },
+ { 0316 , "ogonek" },
+ { 0317 , "caron" },
+ { 0320 , "emdash" },
+ { 0341 , "AE" },
+ { 0343 , "ordfeminine" },
+ { 0350 , "Lslash" },
+ { 0351 , "Oslash" },
+ { 0352 , "OE" },
+ { 0353 , "ordmasculine" },
+ { 0361 , "ae" },
+ { 0365 , "dotlessi" },
+ { 0370 , "lslash" },
+ { 0371 , "oslash" },
+ { 0372 , "oe" },
+ { 0373 , "germandbls" },
+ { 0, 0 }
+};
+
+static EncodingTable ISO8859Enc[] = {
+ { 32, "space" },
+ { 33, "exclam" },
+ { 34, "quotedbl" },
+ { 35, "numbersign" },
+ { 36, "dollar" },
+ { 37, "percent" },
+ { 38, "ampersand" },
+ { 39, "quoteright" },
+ { 40, "parenleft" },
+ { 41, "parenright" },
+ { 42, "asterisk" },
+ { 43, "plus" },
+ { 44, "comma" },
+ { 45, "minus" },
+ { 46, "period" },
+ { 47, "slash" },
+ { 48, "zero" },
+ { 49, "one" },
+ { 50, "two" },
+ { 51, "three" },
+ { 52, "four" },
+ { 53, "five" },
+ { 54, "six" },
+ { 55, "seven" },
+ { 56, "eight" },
+ { 57, "nine" },
+ { 58, "colon" },
+ { 59, "semicolon" },
+ { 60, "less" },
+ { 61, "equal" },
+ { 62, "greater" },
+ { 63, "question" },
+ { 64, "at" },
+ { 65, "A" },
+ { 66, "B" },
+ { 67, "C" },
+ { 68, "D" },
+ { 69, "E" },
+ { 70, "F" },
+ { 71, "G" },
+ { 72, "H" },
+ { 73, "I" },
+ { 74, "J" },
+ { 75, "K" },
+ { 76, "L" },
+ { 77, "M" },
+ { 78, "N" },
+ { 79, "O" },
+ { 80, "P" },
+ { 81, "Q" },
+ { 82, "R" },
+ { 83, "S" },
+ { 84, "T" },
+ { 85, "U" },
+ { 86, "V" },
+ { 87, "W" },
+ { 88, "X" },
+ { 89, "Y" },
+ { 90, "Z" },
+ { 91, "bracketleft" },
+ { 92, "backslash" },
+ { 93, "bracketright" },
+ { 94, "asciicircum" },
+ { 95, "underscore" },
+ { 96, "quoteleft" },
+ { 97, "a" },
+ { 98, "b" },
+ { 99, "c" },
+ { 100, "d" },
+ { 101, "e" },
+ { 102, "f" },
+ { 103, "g" },
+ { 104, "h" },
+ { 105, "i" },
+ { 106, "j" },
+ { 107, "k" },
+ { 108, "l" },
+ { 109, "m" },
+ { 110, "n" },
+ { 111, "o" },
+ { 112, "p" },
+ { 113, "q" },
+ { 114, "r" },
+ { 115, "s" },
+ { 116, "t" },
+ { 117, "u" },
+ { 118, "v" },
+ { 119, "w" },
+ { 120, "x" },
+ { 121, "y" },
+ { 122, "z" },
+ { 123, "braceleft" },
+ { 124, "bar" },
+ { 125, "braceright" },
+ { 126, "asciitilde" },
+ { 160, "space" },
+ { 161, "exclamdown" },
+ { 162, "cent" },
+ { 163, "sterling" },
+ { 164, "currency" },
+ { 165, "yen" },
+ { 166, "brokenbar" },
+ { 167, "section" },
+ { 168, "dieresis" },
+ { 169, "copyright" },
+ { 170, "ordfeminine" },
+ { 171, "guillemotleft" },
+ { 172, "logicalnot" },
+ { 173, "hyphen" },
+ { 174, "registered" },
+ { 175, "macron" },
+ { 176, "degree" },
+ { 177, "plusminus" },
+ { 178, "twosuperior" },
+ { 179, "threesuperior" },
+ { 180, "acute" },
+ { 181, "mu" },
+ { 182, "paragraph" },
+ { 183, "periodcentered" },
+ { 184, "cedilla" },
+ { 185, "onesuperior" },
+ { 186, "ordmasculine" },
+ { 187, "guillemotright" },
+ { 188, "onequarter" },
+ { 189, "onehalf" },
+ { 190, "threequarters" },
+ { 191, "questiondown" },
+ { 192, "Agrave" },
+ { 193, "Aacute" },
+ { 194, "Acircumflex" },
+ { 195, "Atilde" },
+ { 196, "Adieresis" },
+ { 197, "Aring" },
+ { 198, "AE" },
+ { 199, "Ccedilla" },
+ { 200, "Egrave" },
+ { 201, "Eacute" },
+ { 202, "Ecircumflex" },
+ { 203, "Edieresis" },
+ { 204, "Igrave" },
+ { 205, "Iacute" },
+ { 206, "Icircumflex" },
+ { 207, "Idieresis" },
+ { 208, "Eth" },
+ { 209, "Ntilde" },
+ { 210, "Ograve" },
+ { 211, "Oacute" },
+ { 212, "Ocircumflex" },
+ { 213, "Otilde" },
+ { 214, "Odieresis" },
+ { 215, "multiply" },
+ { 216, "Oslash" },
+ { 217, "Ugrave" },
+ { 218, "Uacute" },
+ { 219, "Ucircumflex" },
+ { 220, "Udieresis" },
+ { 221, "Yacute" },
+ { 222, "Thorn" },
+ { 223, "germandbls" },
+ { 224, "agrave" },
+ { 225, "aacute" },
+ { 226, "acircumflex" },
+ { 227, "atilde" },
+ { 228, "adieresis" },
+ { 229, "aring" },
+ { 230, "ae" },
+ { 231, "ccedilla" },
+ { 232, "egrave" },
+ { 233, "eacute" },
+ { 234, "ecircumflex" },
+ { 235, "edieresis" },
+ { 236, "igrave" },
+ { 237, "iacute" },
+ { 238, "icircumflex" },
+ { 239, "idieresis" },
+ { 240, "eth" },
+ { 241, "ntilde" },
+ { 242, "ograve" },
+ { 243, "oacute" },
+ { 244, "ocircumflex" },
+ { 245, "otilde" },
+ { 246, "odieresis" },
+ { 247, "divide" },
+ { 248, "oslash" },
+ { 249, "ugrave" },
+ { 250, "uacute" },
+ { 251, "ucircumflex" },
+ { 252, "udieresis" },
+ { 253, "yacute" },
+ { 254, "thorn" },
+ { 255, "ydieresis" },
+ { 0, 0 }
+};
+
+static psobj *StdEncArrayP = NULL;
+static psobj *ISOLatin1EncArrayP = NULL;
+
+static psobj *
+MakeEncodingArrayP(EncodingTable *encodingTable)
+{
+ int i;
+ psobj *encodingArrayP;
+
+ encodingArrayP = (psobj *)vm_alloc(256*(sizeof(psobj)));
+ if (!encodingArrayP)
+ return NULL;
+
+ /* initialize everything to .notdef */
+ for (i=0; i<256;i++)
+ objFormatName(&(encodingArrayP[i]),7, ".notdef");
+
+ for (i=0; encodingTable[i].name; i++)
+ {
+ objFormatName(&(encodingArrayP[encodingTable[i].index]),
+ strlen(encodingTable[i].name),
+ encodingTable[i].name);
+ }
+
+ return(encodingArrayP);
+}
+
+boolean
+Init_BuiltInEncoding(void)
+{
+ StdEncArrayP = MakeEncodingArrayP(StdEnc);
+ ISOLatin1EncArrayP = MakeEncodingArrayP(ISO8859Enc);
+ return (StdEncArrayP && ISOLatin1EncArrayP);
+}
+
+/********************************************************************/
+/***================================================================***/
+static int
+getNextValue(int valueType)
+{
+ scan_token(inputP);
+ if (tokenType != valueType) {
+ return(SCAN_ERROR);
+ }
+ return(SCAN_OK);
+
+}
+/***================================================================***/
+/* This routine will set the global rc if there is an error */
+/***================================================================***/
+static int
+getInt(void)
+{
+ scan_token(inputP);
+ if (tokenType != TOKEN_INTEGER) {
+ rc = SCAN_ERROR;
+ return(0);
+ }
+ else {
+ return( tokenValue.integer);
+ }
+
+}
+/***================================================================***/
+/*
+ * See Sec 10.3 of ``Adobe Type 1 Font Format'' v1.1,
+ * for parsing Encoding.
+ */
+static int
+getEncoding(psobj *arrayP)
+{
+ scan_token(inputP);
+ if ((tokenType == TOKEN_NAME && (tokenLength==16 || tokenLength==17)))
+ {
+ if((tokenLength==16) && (!strncmp(tokenStartP,"StandardEncoding",16)))
+ arrayP->data.valueP = (char *) StdEncArrayP;
+ else
+ arrayP->data.valueP = (char *) ISOLatin1EncArrayP;
+ arrayP->len = 256;
+ return(SCAN_OK);
+ }
+ else if ( (tokenType == TOKEN_LEFT_BRACE) ||
+ (tokenType == TOKEN_LEFT_BRACKET) )
+ {
+ /* Array of literal names */
+
+ psobj *objP;
+ int i;
+
+ objP = (psobj *)vm_alloc(256*(sizeof(psobj)));
+ if (!(objP)) return(SCAN_OUT_OF_MEMORY);
+
+ arrayP->data.valueP = (char *) objP;
+ arrayP->len = 256;
+
+ for (i=0; i<256; i++, objP++)
+ {
+ scan_token(inputP);
+
+ if (tokenType != TOKEN_LITERAL_NAME)
+ return(SCAN_ERROR);
+
+ if (!(vm_alloc(tokenLength)) ) return(SCAN_OUT_OF_MEMORY);
+ objFormatName(objP,tokenLength,tokenStartP);
+ }
+
+ scan_token(inputP);
+ if ( (tokenType == TOKEN_RIGHT_BRACE) ||
+ (tokenType == TOKEN_RIGHT_BRACKET) )
+ return(SCAN_OK);
+ }
+ else
+ {
+ /* Must be sequences of ``dup <index> <charactername> put" */
+
+ psobj *objP;
+ int i;
+
+ objP = (psobj *)vm_alloc(256*(sizeof(psobj)));
+ if (!(objP)) return(SCAN_OUT_OF_MEMORY);
+
+ arrayP->data.valueP = (char *) objP;
+ arrayP->len = 256;
+
+ for (i=0; i<256; i++)
+ objFormatName(objP + i, 7, ".notdef");
+
+ while (TRUE)
+ {
+ scan_token(inputP);
+
+ switch (tokenType)
+ {
+ case TOKEN_NAME:
+ if (tokenLength == 3)
+ {
+ if (strncmp(tokenStartP,"dup",3) == 0)
+ {
+ /* get <index> */
+ scan_token(inputP);
+ if (tokenType != TOKEN_INTEGER ||
+ tokenValue.integer < 0 ||
+ tokenValue.integer > 255)
+ return (SCAN_ERROR);
+ i = tokenValue.integer;
+
+ /* get <characer_name> */
+ scan_token(inputP);
+ if (tokenType != TOKEN_LITERAL_NAME)
+ return(SCAN_ERROR);
+
+ if (!(vm_alloc(tokenLength)) )
+ return(SCAN_OUT_OF_MEMORY);
+ objFormatName(objP + i,tokenLength,tokenStartP);
+
+ /* get "put" */
+ scan_token(inputP);
+ if (tokenType != TOKEN_NAME)
+ return(SCAN_ERROR);
+ }
+ else if (strncmp(tokenStartP,"def",3) == 0)
+ return (SCAN_OK);
+ }
+ break;
+ case TOKEN_EOF:
+ case TOKEN_NONE:
+ case TOKEN_INVALID:
+ return (SCAN_ERROR);
+ }
+ }
+ }
+
+ return (SCAN_ERROR);
+}
+/***================================================================***/
+static int
+getArray(psobj *arrayP)
+{
+ int N; /* count the items in the array */
+ psobj *objP;
+
+ /* That is totally a kludge. If some stupid font file has
+ * /foo/foo # ftp://ftp.cdrom.com/pub/os2/fonts/future.zip
+ * we will treat it as /foo.
+ * H.J. */
+ char tmp [1024];
+
+ strncpy (tmp, tokenStartP, sizeof (tmp));
+ tmp [sizeof (tmp) - 1] = '\0';
+
+restart:
+ scan_token(inputP);
+ switch (tokenType)
+ {
+ case TOKEN_LEFT_BRACE:
+ case TOKEN_LEFT_BRACKET:
+ break;
+
+ case TOKEN_LITERAL_NAME:
+ tokenStartP[tokenLength] = '\0';
+ if (strcmp (tokenStartP, tmp) == 0)
+ {
+ /* Ok, We see /foo/foo. Let's restart. */
+ goto restart;
+ }
+
+ default:
+ return(SCAN_ERROR);
+ }
+ /* format the array in memory, save pointer to the beginning */
+ arrayP->data.valueP = tokenStartP;
+ /* loop, picking up next object, until right BRACE or BRACKET */
+ N = 0;
+ do {
+ scan_token(inputP);
+ if ( (tokenType == TOKEN_RIGHT_BRACE) ||
+ (tokenType == TOKEN_RIGHT_BRACKET) ) {
+ /* save then number of items in the array */
+ arrayP->len = N;
+ return(SCAN_OK);
+ }
+ /* allocate the space for the object */
+ objP = (psobj *)vm_alloc(sizeof(psobj));
+ if (!(objP)) return(SCAN_OUT_OF_MEMORY);
+
+ /* array is an array of numbers, (real or integer) */
+ if (tokenType == TOKEN_REAL) {
+ objFormatReal(objP, tokenValue.real);
+ }
+ else
+ if (tokenType == TOKEN_INTEGER) {
+ objFormatInteger(objP, tokenValue.integer);
+ }
+ else return(SCAN_ERROR);
+ N++;
+ } while ( 1>0 );
+ /* NOTREACHED*/
+}
+/***================================================================***/
+static int
+getName(char *nameP)
+{
+ do {
+ scan_token(inputP);
+ if (tokenType <= TOKEN_NONE) {
+ if (tokenTooLong) return(SCAN_OUT_OF_MEMORY);
+ return(SCAN_ERROR);
+ }
+ } while ((tokenType != TOKEN_NAME) ||
+ (0 != strncmp(tokenStartP,nameP,strlen(nameP))) );
+ /* found */
+ return(SCAN_OK);
+}
+/***================================================================***/
+static int
+getNbytes(int N)
+{
+ int I;
+
+
+ tokenStartP = vm_next_byte();
+ tokenMaxP = tokenStartP + MIN(vm_free_bytes(), MAX_STRING_LEN);
+ if (N > vm_free_bytes()) {
+ return(SCAN_OUT_OF_MEMORY);
+ }
+ I = T1Read(tokenStartP,1,N,inputP->data.fileP);
+ if ( I != N ) return(SCAN_FILE_EOF);
+ return(SCAN_OK);
+}
+
+/***================================================================***/
+/* getLiteralName(nameObjP) */
+/* scan for next literal. */
+/* if we encounter the name 'end' then terminate and say ok. */
+/* It means that the CharStrings does not have as many characters */
+/* as the dictionary said it would and that is ok. */
+/***================================================================***/
+static int
+getLiteralName(psobj *nameObjP)
+{
+ do {
+ scan_token(inputP);
+ if (tokenType <= TOKEN_NONE) {
+ if (tokenTooLong) return(SCAN_OUT_OF_MEMORY);
+ return(SCAN_ERROR);
+ }
+ if (tokenType == TOKEN_NAME) {
+ if (0 == strncmp(tokenStartP,"end",3) ) {
+ return(SCAN_END);
+ }
+ }
+ } while (tokenType != TOKEN_LITERAL_NAME) ;
+ nameObjP->len = tokenLength;
+ /* allocate all the names in the CharStrings Structure */
+ if (!(vm_alloc(tokenLength)) ) return(SCAN_OUT_OF_MEMORY);
+ nameObjP->data.valueP = tokenStartP;
+ /* found */
+ return(SCAN_OK);
+}
+
+/***================================================================***/
+/*
+ * BuildSubrs routine
+ */
+/***================================================================***/
+
+static int
+BuildSubrs(psfont *FontP)
+{
+ int N; /* number of values in Subrs */
+ int I; /* index into Subrs */
+ int i; /* loop thru Subrs */
+ int J; /* length of Subrs entry */
+ psobj *arrayP;
+
+ /* next token should be a positive int */
+ /* note: rc is set by getInt. */
+ N = getInt();
+ if (rc) return(rc);
+ if (N < 0 ) return(SCAN_ERROR);
+ /* if we already have a Subrs, then skip the second one */
+ /* The second one is for hiresolution devices. */
+ if (FontP->Subrs.data.arrayP != NULL) {
+ TwoSubrs = TRUE;
+ /* process all the Subrs, but do not update anything */
+ /* can not just skip them because of the binary data */
+ for (i=0;i<N;i++) {
+ /* look for dup */
+ rc = getName("dup");
+ if (rc) return(rc);
+ /* get 2 integers */
+ I = getInt();
+ if (rc) return(rc);
+ J = getInt();
+ if (rc) return(rc);
+ if ( (I < 0) || (J < 0 ) ) return (SCAN_ERROR);
+ /* get the next token, it should be RD or -|, either is ok */
+ rc = getNextValue(TOKEN_NAME);
+ if ( rc != SCAN_OK ) return(rc);
+ rc = getNbytes(J);
+ if (rc) return(rc);
+ }
+ return(SCAN_OK);
+ }
+ if (N > INT_MAX / sizeof(psobj))
+ return (SCAN_ERROR);
+ arrayP = (psobj *)vm_alloc(N*sizeof(psobj));
+ if (!(arrayP) ) return(SCAN_OUT_OF_MEMORY);
+ FontP->Subrs.len = N;
+ FontP->Subrs.data.arrayP = arrayP;
+ /* get N values for Subrs */
+ for (i=0;i<N;i++) {
+ /* look for dup */
+ rc = getName("dup");
+ if (rc) return(rc);
+ /* get 2 integers */
+ I = getInt();
+ if (rc) return(rc);
+ J = getInt();
+ if (rc) return(rc);
+ if ( (I < 0) || (J < 0 ) ) return (SCAN_ERROR);
+ arrayP[I].len = J;
+ /* get the next token, it should be RD or -|, either is ok */
+ rc = getNextValue(TOKEN_NAME);
+ if ( rc != SCAN_OK ) return(rc);
+ rc = getNbytes(J);
+ if (rc == SCAN_OK) {
+ arrayP[I].data.valueP = tokenStartP;
+ if ( !(vm_alloc(J)) ) return(SCAN_OUT_OF_MEMORY);
+ }
+ else return(rc);
+ }
+ return(SCAN_OK);
+
+}
+/***================================================================***/
+/***================================================================***/
+/*
+ * BuildCharStrings routine
+ */
+/***================================================================***/
+
+static int
+BuildCharStrings(psfont *FontP)
+{
+ int N; /* number of values in CharStrings */
+ int i; /* loop thru Subrs */
+ int J; /* length of Subrs entry */
+ psdict *dictP;
+
+ /* next token should be a positive int */
+ N = getInt();
+ if (rc) {
+ /* check if file had TwoSubrs, hi resolution stuff is in file*/
+ if (TwoSubrs) {
+ do {
+ scan_token(inputP);
+ if (tokenType <= TOKEN_NONE) {
+ if (tokenTooLong) return(SCAN_OUT_OF_MEMORY);
+ return(SCAN_ERROR);
+ }
+ } while (tokenType != TOKEN_INTEGER);
+ N = tokenValue.integer;
+ }
+ else return(rc); /* if next token was not an Int */
+ }
+ if (N<=0 || N > INT_MAX / sizeof(psdict)) return(SCAN_ERROR);
+ /* save number of entries in the dictionary */
+
+ dictP = (psdict *)vm_alloc((N+1)*sizeof(psdict));
+ if (!(dictP)) return(SCAN_OUT_OF_MEMORY);
+ FontP->CharStringsP = dictP;
+ dictP[0].key.len = N;
+ /* get N values for CharStrings */
+ for (i=1;i<=N;i++) {
+ /* look for next literal name */
+ rc = getLiteralName(&(dictP[i].key));
+ if (rc) return(rc);
+ /* get 1 integer */
+ J = getInt();
+ if (rc) return(rc); /* if next token was not an Int */
+ if (J<0) return (SCAN_ERROR);
+ dictP[i].value.len = J;
+ /* get the next token, it should be RD or -|, either is ok */
+ rc = getNextValue(TOKEN_NAME);
+ if ( rc != SCAN_OK ) return(rc);
+ rc = getNbytes(J);
+ if (rc == SCAN_OK) {
+ dictP[i].value.data.valueP = tokenStartP;
+ if ( !(vm_alloc(J)) ) return(SCAN_OUT_OF_MEMORY);
+ }
+ else return(rc);
+ }
+ return(SCAN_OK);
+
+}
+/***================================================================***/
+/*
+ * BuildFontInfo Dictionary
+ */
+/***================================================================***/
+static int
+BuildFontInfo(psfont *fontP)
+{
+ psdict *dictP;
+
+ /* allocate the private dictionary */
+ dictP = (psdict *)vm_alloc(20*sizeof(psdict));
+ if (!(dictP)) return(SCAN_OUT_OF_MEMORY);
+
+ fontP->fontInfoP = dictP;
+ fontP->fontInfoP[0].key.len = 17; /* number of actual entries */
+ objFormatName(&(dictP[FONTNAME].key),8,"FontName");
+ objFormatName(&(dictP[FONTNAME].value),0,NULL);
+ objFormatName(&(dictP[PAINTTYPE].key),9,"PaintType");
+ objFormatInteger(&(dictP[PAINTTYPE].value),0);
+ objFormatName(&(dictP[FONTTYPENUM].key),8,"FontType");
+ objFormatInteger(&(dictP[FONTTYPENUM].value),0);
+ objFormatName(&(dictP[FONTMATRIX].key),10,"FontMatrix");
+ objFormatArray(&(dictP[FONTMATRIX].value),0,NULL);
+ objFormatName(&(dictP[FONTBBOX].key),8,"FontBBox");
+ objFormatArray(&(dictP[FONTBBOX].value),0,NULL);
+ objFormatName(&(dictP[ENCODING].key),8,"Encoding");
+ objFormatEncoding(&(dictP[ENCODING].value),0,NULL);
+ objFormatName(&(dictP[UNIQUEID].key),8,"UniqueID");
+ objFormatInteger(&(dictP[UNIQUEID].value),0);
+ objFormatName(&(dictP[STROKEWIDTH].key),11,"StrokeWidth");
+ objFormatReal(&(dictP[STROKEWIDTH].value),0.0);
+ objFormatName(&(dictP[VERSION].key),7,"version");
+ objFormatString(&(dictP[VERSION].value),0,NULL);
+ objFormatName(&(dictP[NOTICE].key),6,"Notice");
+ objFormatString(&(dictP[NOTICE].value),0,NULL);
+ objFormatName(&(dictP[FULLNAME].key),8,"FullName");
+ objFormatString(&(dictP[FULLNAME].value),0,NULL);
+ objFormatName(&(dictP[FAMILYNAME].key),10,"FamilyName");
+ objFormatString(&(dictP[FAMILYNAME].value),0,NULL);
+ objFormatName(&(dictP[WEIGHT].key),6,"Weight");
+ objFormatString(&(dictP[WEIGHT].value),0,NULL);
+ objFormatName(&(dictP[ITALICANGLE].key),11,"ItalicAngle");
+ objFormatReal(&(dictP[ITALICANGLE].value),0.0);
+ objFormatName(&(dictP[ISFIXEDPITCH].key),12,"isFixedPitch");
+ objFormatBoolean(&(dictP[ISFIXEDPITCH].value),FALSE);
+ objFormatName(&(dictP[UNDERLINEPOSITION].key),17,"UnderlinePosition");
+ objFormatReal(&(dictP[UNDERLINEPOSITION].value),0.0);
+ objFormatName(&(dictP[UNDERLINETHICKNESS].key),18,"UnderlineThickness");
+ objFormatReal(&(dictP[UNDERLINETHICKNESS].value),0.0);
+ return(SCAN_OK);
+}
+/***================================================================***/
+/*
+ * BuildPrivate Dictionary
+ */
+/***================================================================***/
+static int
+BuildPrivate(psfont *fontP)
+{
+ psdict *Private;
+
+ /* allocate the private dictionary */
+ Private = (psdict *)vm_alloc(20*sizeof(psdict));
+
+ if (!(Private)) return(SCAN_OUT_OF_MEMORY);
+
+ fontP->Private = Private;
+ fontP->Private[0].key.len = 16; /* number of actual entries */
+
+ objFormatName(&(Private[BLUEVALUES].key),10,"BlueValues");
+ objFormatArray(&(Private[BLUEVALUES].value),0,NULL);
+ objFormatName(&(Private[OTHERBLUES].key),10,"OtherBlues");
+ objFormatArray(&(Private[OTHERBLUES].value),0,NULL);
+ objFormatName(&(Private[FAMILYBLUES].key),11,"FamilyBlues");
+ objFormatArray(&(Private[FAMILYBLUES].value),0,NULL);
+ objFormatName(&(Private[FAMILYOTHERBLUES].key),16,"FamilyOtherBlues");
+ objFormatArray(&(Private[FAMILYOTHERBLUES].value),0,NULL);
+ objFormatName(&(Private[BLUESCALE].key),9,"BlueScale");
+ objFormatReal(&(Private[BLUESCALE].value),DEFAULTBLUESCALE);
+ objFormatName(&(Private[BLUESHIFT].key),9,"BlueShift");
+ objFormatInteger(&(Private[BLUESHIFT].value),DEFAULTBLUESHIFT);
+ objFormatName(&(Private[BLUEFUZZ].key),8,"BlueFuzz");
+ objFormatInteger(&(Private[BLUEFUZZ].value),DEFAULTBLUEFUZZ);
+ objFormatName(&(Private[STDHW].key),5,"StdHW");
+ objFormatArray(&(Private[STDHW].value),0,NULL);
+ objFormatName(&(Private[STDVW].key),5,"StdVW");
+ objFormatArray(&(Private[STDVW].value),0,NULL);
+ objFormatName(&(Private[STEMSNAPH].key),9,"StemSnapH");
+ objFormatArray(&(Private[STEMSNAPH].value),0,NULL);
+ objFormatName(&(Private[STEMSNAPV].key),9,"StemSnapV");
+ objFormatArray(&(Private[STEMSNAPV].value),0,NULL);
+ objFormatName(&(Private[FORCEBOLD].key),9,"ForceBold");
+ objFormatBoolean(&(Private[FORCEBOLD].value),DEFAULTFORCEBOLD);
+ objFormatName(&(Private[LANGUAGEGROUP].key),13,"LanguageGroup");
+ objFormatInteger(&(Private[LANGUAGEGROUP].value),DEFAULTLANGUAGEGROUP);
+ objFormatName(&(Private[LENIV].key),5,"lenIV");
+ objFormatInteger(&(Private[LENIV].value),DEFAULTLENIV);
+ objFormatName(&(Private[RNDSTEMUP].key),9,"RndStemUp");
+ objFormatBoolean(&(Private[RNDSTEMUP].value),DEFAULTRNDSTEMUP);
+ objFormatName(&(Private[EXPANSIONFACTOR].key),9,"ExpansionFactor");
+ objFormatReal(&(Private[EXPANSIONFACTOR].value),
+ DEFAULTEXPANSIONFACTOR);
+ return(SCAN_OK);
+}
+/***================================================================***/
+/**********************************************************************/
+/* GetType1Blues(fontP) */
+/* */
+/* Routine to support font-level hints. */
+/* */
+/* Gets all the Blues information from the Private dictionary */
+/* for the font. */
+/* */
+/* */
+/**********************************************************************/
+static int
+GetType1Blues(psfont *fontP)
+{
+ psdict *PrivateDictP; /* the Private dict relating to hints */
+ struct blues_struct *blues; /* ptr for the blues struct we will allocate */
+ int i;
+ psobj *HintEntryP;
+
+
+
+ /* get the Private dictionary pointer */
+ PrivateDictP = fontP->Private;
+
+ /* allocate the memory for the blues structure */
+ blues = (struct blues_struct *) vm_alloc(sizeof(struct blues_struct));
+
+ if (!blues) return(SCAN_OUT_OF_MEMORY);
+
+ /* Make fontP's blues ptr point to this newly allocated structure. */
+ fontP->BluesP = blues;
+
+ /* fill in the BlueValues array */
+ HintEntryP = &(PrivateDictP[BLUEVALUES].value);
+ /* check to see if the entry exists and if it's an array */
+ if ( !objPIsArray(HintEntryP) || (HintEntryP->len == 0 ))
+ blues->numBlueValues = 0;
+ else {
+ /* get the number of values in the array */
+ if (HintEntryP->len > NUMBLUEVALUES) {
+ blues->numBlueValues = NUMBLUEVALUES;
+ } else
+ blues->numBlueValues = HintEntryP->len;
+ for (i = 0; i<= blues->numBlueValues-1; ++i) {
+ if (objPIsInteger(&HintEntryP->data.arrayP[i]))
+ blues->BlueValues[i] =
+ HintEntryP->data.arrayP[i].data.integer;
+ else if (objPIsReal(&HintEntryP->data.arrayP[i]))
+ blues->BlueValues[i] =
+ HintEntryP->data.arrayP[i].data.real;
+ else
+ blues->BlueValues[i] = 0;
+ }
+ }
+
+ /* fill in the OtherBlues array */
+ HintEntryP = &(PrivateDictP[OTHERBLUES].value);
+ /* check to see if the entry exists and if it's an array */
+ if ( !objPIsArray(HintEntryP) || (HintEntryP->len == 0 ))
+ blues->numOtherBlues = 0;
+ else {
+ /* get the number of values in the array */
+ if (HintEntryP->len > NUMOTHERBLUES) {
+ blues->numOtherBlues = NUMOTHERBLUES;
+ } else
+ blues->numOtherBlues = HintEntryP->len;
+ for (i = 0; i<= blues->numOtherBlues-1; ++i) {
+ if (objPIsInteger(&HintEntryP->data.arrayP[i]))
+ blues->OtherBlues[i] =
+ HintEntryP->data.arrayP[i].data.integer;
+ else if (objPIsReal(&HintEntryP->data.arrayP[i]))
+ blues->OtherBlues[i] =
+ HintEntryP->data.arrayP[i].data.real;
+ else
+ blues->OtherBlues[i] = 0;
+ }
+ }
+
+ /* fill in the FamilyBlues array */
+ HintEntryP = &(PrivateDictP[FAMILYBLUES].value);
+ /* check to see if the entry exists and if it's an array */
+ if ( !objPIsArray(HintEntryP) || (HintEntryP->len == 0 ))
+ blues->numFamilyBlues = 0;
+ else {
+ /* get the number of values in the array */
+ if (HintEntryP->len > NUMFAMILYBLUES) {
+ blues->numFamilyBlues = NUMFAMILYBLUES;
+ } else
+ blues->numFamilyBlues = HintEntryP->len;
+ for (i = 0; i<= blues->numFamilyBlues-1; ++i) {
+ if (objPIsInteger(&HintEntryP->data.arrayP[i]))
+ blues->FamilyBlues[i] =
+ HintEntryP->data.arrayP[i].data.integer;
+ else if (objPIsReal(&HintEntryP->data.arrayP[i]))
+ blues->FamilyBlues[i] =
+ HintEntryP->data.arrayP[i].data.real;
+ else
+ blues->FamilyBlues[i] = 0;
+ }
+ }
+
+ /* fill in the FamilyOtherBlues array */
+ HintEntryP = &(PrivateDictP[FAMILYOTHERBLUES].value);
+ /* check to see if the entry exists and if it's an array */
+ if ( !objPIsArray(HintEntryP) || (HintEntryP->len == 0 ))
+ blues->numFamilyOtherBlues = 0;
+ else {
+ /* get the number of values in the array */
+ if (HintEntryP->len > NUMFAMILYOTHERBLUES) {
+ blues->numFamilyOtherBlues = NUMFAMILYOTHERBLUES;
+ } else
+ blues->numFamilyOtherBlues = HintEntryP->len;
+ for (i = 0; i<= blues->numFamilyOtherBlues-1; ++i) {
+ if (objPIsInteger(&HintEntryP->data.arrayP[i]))
+ blues->FamilyOtherBlues[i] =
+ HintEntryP->data.arrayP[i].data.integer;
+ else if (objPIsReal(&HintEntryP->data.arrayP[i]))
+ blues->FamilyOtherBlues[i] =
+ HintEntryP->data.arrayP[i].data.real;
+ else
+ blues->FamilyOtherBlues[i] = 0;
+ }
+ }
+
+ /* fill in the StemSnapH array */
+ HintEntryP = &(PrivateDictP[STEMSNAPH].value);
+ /* check to see if the entry exists and if it's an array */
+ if ( !objPIsArray(HintEntryP) || (HintEntryP->len == 0 ))
+ blues->numStemSnapH = 0;
+ else {
+ /* get the number of values in the array */
+ if (HintEntryP->len > NUMSTEMSNAPH) {
+ blues->numStemSnapH = NUMSTEMSNAPH;
+ } else
+ blues->numStemSnapH = HintEntryP->len;
+ for (i = 0; i<= blues->numStemSnapH-1; ++i) {
+ if (objPIsInteger(&HintEntryP->data.arrayP[i]))
+ blues->StemSnapH[i] =
+ HintEntryP->data.arrayP[i].data.integer;
+ else if (objPIsReal(&HintEntryP->data.arrayP[i]))
+ blues->StemSnapH[i] =
+ HintEntryP->data.arrayP[i].data.real;
+ else
+ blues->StemSnapH[i] = 0;
+ }
+ }
+
+ /* fill in the StemSnapV array */
+ HintEntryP = &(PrivateDictP[STEMSNAPV].value);
+ /* check to see if the entry exists and if it's an array */
+ if ( !objPIsArray(HintEntryP) || (HintEntryP->len == 0 ))
+ blues->numStemSnapV = 0;
+ else {
+ /* get the number of values in the array */
+ if (HintEntryP->len > NUMSTEMSNAPV) {
+ blues->numStemSnapV = NUMSTEMSNAPV;
+ } else
+ blues->numStemSnapV = HintEntryP->len;
+ for (i = 0; i<= blues->numStemSnapV-1; ++i) {
+ if (objPIsInteger(&HintEntryP->data.arrayP[i]))
+ blues->StemSnapV[i] =
+ HintEntryP->data.arrayP[i].data.integer;
+ else if (objPIsReal(&HintEntryP->data.arrayP[i]))
+ blues->StemSnapV[i] =
+ HintEntryP->data.arrayP[i].data.real;
+ else
+ blues->StemSnapV[i] = 0;
+ }
+ }
+
+ /* fill in the StdVW array */
+ HintEntryP = &(PrivateDictP[STDVW].value);
+ /* check to see if the entry exists and if it's an array */
+ if ( !objPIsArray(HintEntryP) || (HintEntryP->len == 0 ))
+ /* a value of zero signifies no entry */
+ blues->StdVW = 0;
+ else {
+ if (HintEntryP->len > NUMSTDVW) {
+ }
+ if (objPIsInteger(&HintEntryP->data.arrayP[0]))
+ blues->StdVW = HintEntryP->data.arrayP[0].data.integer;
+ else if (objPIsReal(&HintEntryP->data.arrayP[0]))
+ blues->StdVW = HintEntryP->data.arrayP[0].data.real;
+ else
+ blues->StdVW = 0;
+ }
+
+ /* fill in the StdHW array */
+ HintEntryP = &(PrivateDictP[STDHW].value);
+ /* check to see if the entry exists and if it's an array */
+ if ( !objPIsArray(HintEntryP) || (HintEntryP->len == 0 ))
+ /* a value of zero signifies no entry */
+ blues->StdHW = 0;
+ else {
+ if (HintEntryP->len > NUMSTDHW) {
+ }
+ if (objPIsInteger(&HintEntryP->data.arrayP[0]))
+ blues->StdHW = HintEntryP->data.arrayP[0].data.integer;
+ else if (objPIsReal(&HintEntryP->data.arrayP[0]))
+ blues->StdHW = HintEntryP->data.arrayP[0].data.real;
+ else
+ blues->StdHW = 0;
+ }
+
+
+ /* get the ptr to the BlueScale entry */
+ HintEntryP = &(PrivateDictP[BLUESCALE].value);
+ /* put the BlueScale in the blues structure */
+ if (objPIsInteger(HintEntryP)) /* Must be integer! */
+ blues->BlueScale = HintEntryP->data.integer;
+ else if (objPIsReal(HintEntryP)) /* Error? */
+ blues->BlueScale = HintEntryP->data.real;
+ else
+ blues->BlueScale = DEFAULTBLUESCALE;
+
+ /* get the ptr to the BlueShift entry */
+ HintEntryP = &(PrivateDictP[BLUESHIFT].value);
+ if (objPIsInteger(HintEntryP)) /* Must be integer! */
+ blues->BlueShift = HintEntryP->data.integer;
+ else if (objPIsReal(HintEntryP)) /* Error? */
+ blues->BlueShift = HintEntryP->data.real;
+ else
+ blues->BlueShift = DEFAULTBLUESHIFT;
+
+ /* get the ptr to the BlueFuzz entry */
+ HintEntryP = &(PrivateDictP[BLUEFUZZ].value);
+ if (objPIsInteger(HintEntryP)) /* Must be integer! */
+ blues->BlueFuzz = HintEntryP->data.integer;
+ else if (objPIsReal(HintEntryP)) /* Error? */
+ blues->BlueFuzz = HintEntryP->data.real;
+ else
+ blues->BlueFuzz = DEFAULTBLUEFUZZ;
+
+ /* get the ptr to the ForceBold entry */
+ HintEntryP = &(PrivateDictP[FORCEBOLD].value);
+ if (objPIsBoolean(HintEntryP)) /* Must be integer! */
+ blues->ForceBold = HintEntryP->data.boolean;
+ else
+ blues->ForceBold = DEFAULTFORCEBOLD;
+
+ /* get the ptr to the LanguageGroup entry */
+ HintEntryP = &(PrivateDictP[LANGUAGEGROUP].value);
+ if (objPIsInteger(HintEntryP)) /* Must be integer! */
+ blues->LanguageGroup = HintEntryP->data.integer;
+ else
+ blues->LanguageGroup = DEFAULTLANGUAGEGROUP;
+
+ /* get the ptr to the RndStemUp entry */
+ HintEntryP = &(PrivateDictP[RNDSTEMUP].value);
+ if (objPIsBoolean(HintEntryP)) /* Must be integer! */
+ blues->RndStemUp = HintEntryP->data.boolean;
+ else
+ blues->RndStemUp = DEFAULTRNDSTEMUP;
+
+ /* get the ptr to the lenIV entry */
+ HintEntryP = &(PrivateDictP[LENIV].value);
+ if (objPIsInteger(HintEntryP)) /* Must be integer! */
+ blues->lenIV = HintEntryP->data.integer;
+ else
+ blues->lenIV = DEFAULTLENIV;
+
+ /* get the ptr to the ExpansionFactor entry */
+ HintEntryP = &(PrivateDictP[EXPANSIONFACTOR].value);
+ if (objPIsInteger(HintEntryP))
+ blues->ExpansionFactor = HintEntryP->data.integer;
+ else if (objPIsReal(HintEntryP))
+ blues->ExpansionFactor = HintEntryP->data.real;
+ else
+ blues->ExpansionFactor = DEFAULTEXPANSIONFACTOR;
+ return(SCAN_OK);
+}
+/**********************************************************************/
+/* GetType1CharString(fontP,code) */
+/* */
+/* Look up code in the standard encoding vector and return */
+/* the charstring associated with the character name. */
+/* */
+/* fontP is the psfont structure. */
+/* */
+/* Returns a psobj (string) */
+/**********************************************************************/
+psobj *
+GetType1CharString(psfont *fontP, unsigned char code)
+{
+ int N; /* the 'Nth' entry in the CharStrings */
+ psobj *charnameP; /* points to psobj that is name of character*/
+
+ psdict *CharStringsDictP; /* dictionary with char strings */
+ psobj *theStringP; /* the definition for the code */
+
+
+
+ if (StdEncArrayP == NULL) {
+ return(NULL);
+ }
+ /* use the code to index into the standard encoding vector */
+ charnameP = &(StdEncArrayP[code]);
+
+ /* test if the encoding array points to a name */
+ if (!(objPIsName(charnameP)) ) {
+ return(NULL);
+ }
+
+ /* Now that we have the character name out of the standardencoding */
+ /* get the character definition out of the current font */
+ CharStringsDictP = fontP->CharStringsP;
+
+ /* search the chars string for this charname as key */
+ N = SearchDictName(CharStringsDictP,charnameP);
+ if (N<=0) {
+ return(NULL);
+ }
+ /* OK, the nth item is the psobj that is the string for this char */
+ theStringP = &(CharStringsDictP[N].value);
+
+ return(theStringP);
+}
+
+/***================================================================***/
+/*
+ * FindDictValue
+ */
+/***================================================================***/
+
+static int
+FindDictValue(psdict *dictP)
+{
+ psobj LitName;
+ int N;
+ int V;
+
+ /* we have just scanned a token and it is a literal name */
+ /* need to check if that name is in Private dictionary */
+ objFormatName(&LitName,tokenLength,tokenStartP);
+ /* is it in the dictP */
+ N = SearchDictName(dictP,&LitName);
+ /* if found */
+ if ( N > 0 ) {
+ /* what type */
+ switch (dictP[N].value.type) {
+ case OBJ_ENCODING:
+ V = getEncoding(&(dictP[N].value));
+ if ( V != SCAN_OK ) return(V);
+ break;
+ case OBJ_ARRAY:
+ V = getArray(&(dictP[N].value));
+ if ( V != SCAN_OK ) return(V);
+ break;
+ case OBJ_INTEGER:
+ /* next value in integer */
+ dictP[N].value.data.integer = getInt();
+ if (rc) return(rc); /* if next token was not an Int */
+ break;
+ case OBJ_REAL:
+ /* next value must be real or int, store as a real */
+ scan_token(inputP);
+ if (tokenType == TOKEN_REAL) {
+ dictP[N].value.data.real = tokenValue.real;
+ }
+ else
+ if (tokenType == TOKEN_INTEGER) {
+ dictP[N].value.data.real = tokenValue.integer;
+ }
+ else return(SCAN_ERROR);
+ break;
+ case OBJ_NAME:
+ V = getNextValue(TOKEN_LITERAL_NAME);
+ if ( V != SCAN_OK ) return(V);
+ if (!(vm_alloc(tokenLength)) ) return(SCAN_OUT_OF_MEMORY);
+ objFormatName(&(dictP[N].value),tokenLength,tokenStartP);
+ break;
+ case OBJ_STRING:
+ V = getNextValue(TOKEN_STRING);
+ if ( V != SCAN_OK ) return(V);
+ if (!(vm_alloc(tokenLength)) ) return(SCAN_OUT_OF_MEMORY);
+ objFormatString(&(dictP[N].value),tokenLength,tokenStartP);
+ break;
+ case OBJ_BOOLEAN:
+ scan_token(inputP);
+ if (tokenType != TOKEN_NAME) {
+ return(SCAN_ERROR);
+ }
+ if (0 == strncmp(tokenStartP,"true",4) ) {
+ dictP[N].value.data.boolean =TRUE;
+ }
+ else
+ if (0 == strncmp(tokenStartP,"false",5) ) {
+ dictP[N].value.data.boolean =FALSE;
+ }
+ else return(SCAN_ERROR);
+ break;
+
+ default:
+ return(SCAN_ERROR);
+ }
+ }
+ /* Name is not in dictionary. That is ok. */
+ return(SCAN_OK);
+
+}
+/***================================================================***/
+
+/*
+ * -------------------------------------------------------------------
+ * Scan the next token and convert it into an object
+ * Result is placed on the Operand Stack as next object
+ * -------------------------------------------------------------------
+ */
+int
+scan_font(psfont *FontP)
+{
+
+
+ char filename[128];
+ char filetype[3];
+ FILE *fileP;
+ char *nameP;
+ int namelen;
+ int V;
+ int i;
+ boolean starthex80;
+
+ starthex80 = FALSE;
+ filetype[0] = 'r';
+ filetype[1] = 'b';
+ filetype[2] = '\0';
+ /* copy the filename and remove leading or trailing blanks */
+ /* point to name and search for leading blanks */
+ nameP= FontP->FontFileName.data.nameP;
+ namelen = FontP->FontFileName.len;
+ while (nameP[0] == ' ') {
+ nameP++;
+ namelen--;
+ }
+ /* now remove any trailing blanks */
+ while ((namelen>0) && ( nameP[namelen-1] == ' ')) {
+ namelen--;
+ }
+ strncpy(filename,nameP,namelen);
+ filename[namelen] = '\0';
+ /* file name is now constructed */
+ inputFile.data.fileP = NULL;
+ filterFile.data.fileP = NULL;
+
+ inputP = &inputFile;
+ if ((fileP = T1Open(filename,filetype))) {
+ /* get the first byte of file */
+ V = _XT1getc(fileP);
+ /* if file starts with x'80' then skip next 5 bytes */
+ if ( V == 0X80 ) {
+ for (i=0;i<5;i++) V = _XT1getc(fileP);
+ starthex80 = TRUE;
+ }
+ else T1Ungetc(V,fileP);
+ objFormatFile(inputP,fileP);
+ }
+ else {
+ return(SCAN_FILE_OPEN_ERROR);
+ };
+
+ WantFontInfo = TRUE;
+ InPrivateDict = FALSE;
+ TwoSubrs = FALSE;
+ rc = BuildFontInfo(FontP);
+ if (rc != 0) return(rc);
+
+ /* Assume everything will be OK */
+ rc = 0;
+
+ /* Loop until complete font is read */
+ do {
+ /* Scan the next token */
+ scan_token(inputP);
+
+ /* ==> tokenLength, tokenTooLong, tokenType, and tokenValue are */
+ /* now set */
+
+ switch (tokenType) {
+ case TOKEN_EOF:
+ case TOKEN_NONE:
+ case TOKEN_INVALID:
+ /* in this case we are done */
+ if (tokenTooLong) return(SCAN_OUT_OF_MEMORY);
+ rc = SCAN_ERROR;
+ break;
+ case TOKEN_LITERAL_NAME:
+ /* Look up the name */
+ tokenStartP[tokenLength] = '\0';
+ if (InPrivateDict ) {
+ if (0== strncmp(tokenStartP,"Subrs",5) ) {
+ rc = BuildSubrs(FontP);
+ break;
+ }
+ if (0== strncmp(tokenStartP,"CharStrings",11) ) {
+ rc = BuildCharStrings(FontP);
+ if ( (rc == SCAN_OK) ||(rc == SCAN_END) ) {
+ T1Close(inputP->data.fileP);
+ /* Build the Blues Structure */
+ rc = GetType1Blues(FontP);
+ /* whatever the return code, return it */
+ /* all the work is done. This is the normal exit.*/
+ return(rc);
+ }
+ break;
+ }
+ rc = FindDictValue(FontP->Private);
+ /* we are not going to report errors */
+ /* Sometimes the font file may test a value such as */
+ /* testing to see if the font is alreadly loaded with */
+ /* same UniqueID. We would faile on /UniqueID get */
+ /* because we are expecting a int to follow UniqueID*/
+ /* If the correct object type does not follow a Name*/
+ /* then we will skip over it without reporting error except */
+ /* when out of memory */
+ if (rc != SCAN_OUT_OF_MEMORY)
+ rc = SCAN_OK;
+ break;
+ } /* end of reading Private dictionary */
+ else
+ if (0== strncmp(tokenStartP,"Private",7) ) {
+ InPrivateDict = TRUE;
+ rc = BuildPrivate(FontP);
+ break;
+ }
+ else
+ if (WantFontInfo) {
+ rc = FindDictValue(FontP->fontInfoP);
+ /* we are not going to report errors except out of memory */
+ if (rc != SCAN_OUT_OF_MEMORY)
+ rc = SCAN_OK;
+ break;
+ }
+ break;
+ case TOKEN_NAME:
+ if (0 == strncmp(tokenStartP,"eexec",5) ) {
+ /* if file started with x'80', check next 5 bytes */
+ if (starthex80) {
+ V = _XT1getc(fileP);
+ if ( V == 0X80 ) {
+ for (i=0;i<5;i++) V = _XT1getc(fileP);
+ }
+ else T1Ungetc(V,fileP);
+ }
+ filterFile.data.fileP = T1eexec(inputP->data.fileP);
+ if (filterFile.data.fileP == NULL) {
+ T1Close(inputFile.data.fileP);
+ return(SCAN_FILE_OPEN_ERROR);
+ }
+ inputP = &filterFile;
+
+ WantFontInfo = FALSE;
+ }
+ break;
+ }
+
+ }
+ while (rc ==0);
+ T1Close(inputP->data.fileP);
+ if (tokenTooLong) return(SCAN_OUT_OF_MEMORY);
+ return(rc);
+}
+
diff --git a/libXfont/src/Type1/spaces.c b/libXfont/src/Type1/spaces.c
new file mode 100644
index 000000000..1f5a321c1
--- /dev/null
+++ b/libXfont/src/Type1/spaces.c
@@ -0,0 +1,941 @@
+/* $Xorg: spaces.c,v 1.4 2000/08/17 19:46:32 cpqbld Exp $ */
+/* Copyright International Business Machines, Corp. 1991
+ * All Rights Reserved
+ * Copyright Lexmark International, Inc. 1991
+ * All Rights Reserved
+ *
+ * License to use, copy, modify, and distribute this software and its
+ * documentation for any purpose and without fee is hereby granted,
+ * provided that the above copyright notice appear in all copies and that
+ * both that copyright notice and this permission notice appear in
+ * supporting documentation, and that the name of IBM or Lexmark not be
+ * used in advertising or publicity pertaining to distribution of the
+ * software without specific, written prior permission.
+ *
+ * IBM AND LEXMARK PROVIDE THIS SOFTWARE "AS IS", WITHOUT ANY WARRANTIES OF
+ * ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING, BUT NOT LIMITED TO ANY
+ * IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE,
+ * AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. THE ENTIRE RISK AS TO THE
+ * QUALITY AND PERFORMANCE OF THE SOFTWARE, INCLUDING ANY DUTY TO SUPPORT
+ * OR MAINTAIN, BELONGS TO THE LICENSEE. SHOULD ANY PORTION OF THE
+ * SOFTWARE PROVE DEFECTIVE, THE LICENSEE (NOT IBM OR LEXMARK) ASSUMES THE
+ * ENTIRE COST OF ALL SERVICING, REPAIR AND CORRECTION. IN NO EVENT SHALL
+ * IBM OR LEXMARK BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
+ * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
+ * THIS SOFTWARE.
+ */
+/* $XFree86: xc/lib/font/Type1/spaces.c,v 3.10tsi Exp $ */
+ /* SPACES CWEB V0021 ******** */
+/*
+:h1 id=spaces.SPACES Module - Handles Coordinate Spaces
+
+This module is responsible for handling the TYPE1IMAGER "XYspace" object.
+
+&author. Jeffrey B. Lotspiech (lotspiech@almaden.ibm.com)
+
+
+:h3.Include Files
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#ifdef FONTMODULE
+#include "Xdefs.h" /* Bool declaration ??? */
+#include "Xmd.h" /* INT32 declaration ??? */
+#include "os.h"
+#include "xf86_ansic.h"
+#else
+#include "X11/Xos.h"
+#include <stdio.h>
+#endif
+#include "objects.h"
+#include "spaces.h"
+#include "paths.h"
+#include "pictures.h"
+#include "fonts.h"
+#include "arith.h"
+#include "trig.h"
+
+static void FindFfcn ( double cx, double cy,
+ convertFunc *fcnP );
+static void FindIfcn ( double cx, double cy,
+ fractpel *icxP, fractpel *icyP,
+ iconvertFunc *fcnP );
+
+/*
+:h3.MatrixMultiply() - Implements Multiplication of Two Matrices
+
+Implements matrix multiplication, A * B = C.
+
+To remind myself, matrix multiplication goes rows of A times columns
+of B.
+The output matrix may be the same as one of the input matrices.
+*/
+static void
+MatrixMultiply(double A[2][2], double B[2][2], /* input matrices */
+ double C[2][2]) /* output matrix */
+{
+ register double txx,txy,tyx,tyy;
+
+ txx = A[0][0] * B[0][0] + A[0][1] * B[1][0];
+ txy = A[1][0] * B[0][0] + A[1][1] * B[1][0];
+ tyx = A[0][0] * B[0][1] + A[0][1] * B[1][1];
+ tyy = A[1][0] * B[0][1] + A[1][1] * B[1][1];
+
+ C[0][0] = txx;
+ C[1][0] = txy;
+ C[0][1] = tyx;
+ C[1][1] = tyy;
+}
+
+/*
+:h3.MatrixInvert() - Invert a Matrix
+
+My reference for matrix inversion was :hp1/Elementary Linear Algebra/
+by Paul C. Shields, Worth Publishers, Inc., 1968.
+*/
+static void
+MatrixInvert(double M[2][2], /* input matrix */
+ double Mprime[2][2]) /* output inverted matrix */
+{
+ register double D; /* determinant of matrix M */
+ register double txx,txy,tyx,tyy;
+
+ txx = M[0][0];
+ txy = M[1][0];
+ tyx = M[0][1];
+ tyy = M[1][1];
+
+ D = M[1][1] * M[0][0] - M[1][0] * M[0][1];
+ if (D == 0.0)
+ Abort("MatrixInvert: can't");
+
+ Mprime[0][0] = tyy / D;
+ Mprime[1][0] = -txy / D;
+ Mprime[0][1] = -tyx / D;
+ Mprime[1][1] = txx / D;
+}
+
+/*
+:h3.Entry Points Provided to the TYPE1IMAGER User
+*/
+
+/*SHARED LINE(S) ORIGINATED HERE*/
+
+/*
+:h3.Entry Points Provided to Other Modules
+*/
+
+/*
+In addition, other modules call the SPACES module through function
+vectors in the "XYspace" structure. The entry points accessed that
+way are "FConvert()", "IConvert()", and "ForceFloat()".
+*/
+
+/*SHARED LINE(S) ORIGINATED HERE*/
+/*
+:h3.Macros and Typedefs Provided to Other Modules
+
+:h4.Duplicating and Killing Spaces
+
+Destroying XYspaces is so simple we can do it with a
+macro:
+*/
+
+/*SHARED LINE(S) ORIGINATED HERE*/
+/*
+On the other hand, duplicating XYspaces is slightly more difficult
+because of the need to keep a unique ID in the space, see
+:hdref refid=dupspace..
+
+:h4.Fixed Point Pel Representation
+
+We represent pel positions with fixed point numbers. This does NOT
+mean integer, but truly means fixed point, with a certain number
+of binary digits (FRACTBITS) representing the fractional part of the
+pel.
+*/
+
+/*SHARED LINE(S) ORIGINATED HERE*/
+/*
+:h2.Data Structures for Coordinate Spaces and Points
+*/
+/*
+:h3 id=matrix.Matrices
+
+TYPE1IMAGER uses 2x2 transformation matrices. We'll use C notation for
+such a matrix (M[2][2]), the first index being rows, the second columns.
+*/
+
+/*
+:h3.The "doublematrix" Structure
+
+We frequently find it desirable to store both a matrix and its
+inverse. We store these in a "doublematrix" structure.
+*/
+
+/*SHARED LINE(S) ORIGINATED HERE*/
+
+/*
+:h3.The "XYspace" Structure
+
+The XYspace structure represents the XYspace object.
+*/
+
+/*SHARED LINE(S) ORIGINATED HERE*/
+#define RESERVED 10 /* 'n' IDs are reserved for invalid & immortal spaces */
+/*
+*/
+#define NEXTID ((SpaceID < RESERVED) ? (SpaceID = RESERVED) : ++SpaceID)
+
+static unsigned int SpaceID = 1;
+
+struct XYspace *
+CopySpace(struct XYspace *S)
+{
+ S = (struct XYspace *)Allocate(sizeof(struct XYspace), S, 0);
+ S->ID = NEXTID;
+ return(S);
+}
+/*
+:h3.The "fractpoint" Structure
+
+A fractional point is just a "fractpel" x and y:
+*/
+
+/*SHARED LINE(S) ORIGINATED HERE*/
+
+/*
+:h3.Lazy Evaluation of Matrix Inverses
+
+Calculating the inverse of a matrix is somewhat involved, and we usually
+do not need them. So, we flag whether or not the space has the inverse
+already calculated:
+*/
+
+#define HASINVERSE(flag) ((flag)&0x80)
+
+/*
+The following macro forces a space to have an inverse:
+*/
+
+#define CoerceInverse(S) if (!HASINVERSE((S)->flag)) { \
+ MatrixInvert((S)->tofract.normal, (S)->tofract.inverse); (S)->flag |= HASINVERSE(ON); }
+/*
+:h3.IDENTITY Space
+
+IDENTITY space is (logically) the space corresponding to the identity
+transformation matrix. However, since all our transformation matrices
+have a common FRACTFLOAT scale factor to convert to 'fractpel's, that
+is actually what we store in 'tofract' matrix of IDENTITY:
+*/
+
+static struct XYspace identity = { SPACETYPE, ISPERMANENT(ON) + ISIMMORTAL(ON)
+ + HASINVERSE(ON), 2, /* added 3-26-91 PNM */
+ NULL, NULL,
+ NULL, NULL, NULL, NULL,
+ INVALIDID + 1, 0,
+ {{{FRACTFLOAT, 0.0}, {0.0, FRACTFLOAT}},
+ {{1.0/FRACTFLOAT, 0.0}, {0.0, 1.0/FRACTFLOAT}}},
+ {{0, 0}, {0, 0}}};
+struct XYspace *IDENTITY = &identity;
+
+/*
+*/
+#define MAXCONTEXTS 16
+
+static struct doublematrix contexts[MAXCONTEXTS];
+
+#ifdef notdef
+
+static int nextcontext = 1;
+
+/*SHARED LINE(S) ORIGINATED HERE*/
+
+/*
+:h3.FindDeviceContext() - Find the Context Given a Device
+
+This routine, given a device, returns the index of the device's
+transformation matrix in the context array. If it cannot find it,
+it will allocate a new array entry and fill it out.
+*/
+
+static int
+FindDeviceContext(pointer device) /* device token */
+{
+ double M[2][2]; /* temporary matrix */
+ float Xres,Yres; /* device resolution */
+ int orient = -1; /* device orientation */
+ int rc = -1; /* return code for QueryDeviceState */
+
+ if (rc != 0) /* we only bother with this check once */
+ Abort("Context: QueryDeviceState didn't work");
+
+ M[0][0] = M[1][0] = M[0][1] = M[1][1] = 0.0;
+
+ switch (orient) {
+ case 0:
+ M[0][0] = Xres; M[1][1] = -Yres;
+ break;
+ case 1:
+ M[1][0] = Yres; M[0][1] = Xres;
+ break;
+ case 2:
+ M[0][0] = -Xres; M[1][1] = Yres;
+ break;
+ case 3:
+ M[1][0] = -Yres; M[0][1] = -Xres;
+ break;
+ default:
+ Abort("QueryDeviceState returned invalid orientation");
+ }
+ return(FindContext(M));
+}
+
+/*
+:h3.FindContext() - Find the Context Given a Matrix
+
+This routine, given a matrix, returns the index of that matrix matrix in
+the context array. If it cannot find it, it will allocate a new array
+entry and fill it out.
+*/
+
+int
+FindContext(double M[2][2]) /* array to search for */
+{
+ register int i; /* loop variable for search */
+ for (i=0; i < nextcontext; i++)
+ if (M[0][0] == contexts[i].normal[0][0] && M[1][0] == contexts[i].normal[1][0]
+ && M[0][1] == contexts[i].normal[0][1] && M[1][1] == contexts[i].normal[1][1])
+ break;
+
+ if (i >= nextcontext) {
+ if (i >= MAXCONTEXTS)
+ Abort("Context: out of them");
+ LONGCOPY(contexts[i].normal, M, sizeof(contexts[i].normal));
+ MatrixInvert(M, contexts[i].inverse);
+ nextcontext++;
+ }
+
+ return(i);
+}
+
+/*
+:h3.Context() - Create a Coordinate Space for a Device
+
+This user operator is implemented by first finding the device context
+array index, then transforming IDENTITY space to create an appropriate
+cooridnate space.
+*/
+
+struct XYspace *
+Context(pointer device, /* device token */
+ double units) /* multiples of one inch */
+{
+ double M[2][2]; /* device transformation matrix */
+ register int n; /* will hold device context number */
+ register struct XYspace *S; /* XYspace constructed */
+
+ ARGCHECK((device == NULL), "Context of NULLDEVICE not allowed",
+ NULL, IDENTITY, (0), struct XYspace *);
+ ARGCHECK((units == 0.0), "Context: bad units", NULL, IDENTITY, (0), struct XYspace *);
+
+ n = FindDeviceContext(device);
+
+ LONGCOPY(M, contexts[n].normal, sizeof(M));
+
+ M[0][0] *= units;
+ M[0][1] *= units;
+ M[1][0] *= units;
+ M[1][1] *= units;
+
+ S = (struct XYspace *)Xform(IDENTITY, M);
+
+ S->context = n;
+ return(S);
+}
+#endif
+
+/*
+:h3.ConsiderContext() - Adjust a Matrix to Take Out Device Transform
+
+Remember, we have :f/x times U times D/ and :f/M/ and and we want :f/x
+times U times M times D/. An easy way to do this is to calculate
+:f/D sup <-1> times M times D/, because:
+:formula.
+x times U times D times D sup <-1> times M times D = x times U times M times D
+:formula.
+So this subroutine, given an :f/M/and an object, finds the :f/D/ for that
+object and modifies :f/M/ so it is :f/D sup <-1> times M times D/.
+*/
+
+static void
+ConsiderContext(struct xobject *obj, /* object to be transformed */
+ double M[2][2]) /* matrix (may be changed) */
+{
+ register int context = 0; /* index in contexts array */
+
+ if (obj == NULL) return;
+
+ if (ISPATHTYPE(obj->type)) {
+ struct segment *path = (struct segment *) obj;
+
+ context = path->context;
+ }
+ else if (obj->type == SPACETYPE) {
+ struct XYspace *S = (struct XYspace *) obj;
+
+ context = S->context;
+ }
+ else if (obj->type == PICTURETYPE) {
+
+ }
+ else
+ context = NULLCONTEXT;
+
+ if (context != NULLCONTEXT) {
+ MatrixMultiply(contexts[context].inverse, M, M);
+ MatrixMultiply(M, contexts[context].normal, M);
+ }
+}
+
+/*
+:h2.Conversion from User's X,Y to "fractpel" X,Y
+
+When the user is building paths (lines, moves, curves, etc.) he passes
+the control points (x,y) for the paths together with an XYspace. We
+must convert from the user's (x,y) to our internal representation
+which is in pels (fractpels, actually). This involves transforming
+the user's (x,y) under the coordinate space transformation. It is
+important that we do this quickly. So, we store pointers to different
+conversion functions right in the XYspace structure. This allows us
+to have simpler special case functions for the more commonly
+encountered types of transformations.
+
+:h3.Convert(), IConvert(), and ForceFloat() - Called Through "XYspace" Structure
+
+These are functions that fit in the "convert" and "iconvert" function
+pointers in the XYspace structure. They call the "xconvert", "yconvert",
+"ixconvert", and "iyconvert" as appropriate to actually do the work.
+These secondary routines come in many flavors to handle different
+special cases as quickly as possible.
+*/
+
+static void
+FXYConvert(struct fractpoint *pt, /* point to set */
+ struct XYspace *S, /* relevant coordinate space */
+ double x, double y) /* user's coordinates of point */
+{
+ pt->x = (*S->xconvert)(S->tofract.normal[0][0], S->tofract.normal[1][0], x, y);
+ pt->y = (*S->yconvert)(S->tofract.normal[0][1], S->tofract.normal[1][1], x, y);
+}
+
+static void
+IXYConvert(struct fractpoint *pt, /* point to set */
+ struct XYspace *S, /* relevant coordinate space */
+ long x, long y) /* user's coordinates of point */
+{
+ pt->x = (*S->ixconvert)(S->itofract[0][0], S->itofract[1][0], x, y);
+ pt->y = (*S->iyconvert)(S->itofract[0][1], S->itofract[1][1], x, y);
+}
+
+/*
+ForceFloat is a substitute for IConvert(), when we just do not have
+enough significant digits in the coefficients to get high enough
+precision in the answer with fixed point arithmetic. So, we force the
+integers to floats, and do the arithmetic all with floats:
+*/
+
+static void
+ForceFloat(struct fractpoint *pt, /* point to set */
+ struct XYspace *S, /* relevant coordinate space */
+ long x, long y) /* user's coordinates of point */
+{
+ (*S->convert)(pt, S, (double) x, (double) y);
+}
+
+/*
+:h3.FXYboth(), FXonly(), FYonly() - Floating Point Conversion
+
+These are the routines we use when the user has given us floating
+point numbers for x and y. FXYboth() is the general purpose routine;
+FXonly() and FYonly() are special cases when one of the coefficients
+is 0.0.
+*/
+
+static fractpel
+FXYboth(double cx, double cy, /* x and y coefficients */
+ double x, double y) /* user x,y */
+{
+ register double r; /* temporary float */
+
+ r = x * cx + y * cy;
+ return((fractpel) r);
+}
+
+/*ARGSUSED*/
+static fractpel
+FXonly(double cx, double cy, /* x and y coefficients */
+ double x, double y) /* user x,y */
+{
+ register double r; /* temporary float */
+
+ r = x * cx;
+ return((fractpel) r);
+}
+
+/*ARGSUSED*/
+static fractpel
+FYonly(double cx, double cy, /* x and y coefficients */
+ double x, double y) /* user x,y */
+{
+ register double r; /* temporary float */
+
+ r = y * cy;
+ return((fractpel) r);
+}
+
+/*
+:h3.IXYboth(), IXonly(), IYonly() - Simple Integer Conversion
+
+These are the routines we use when the user has given us integers for
+x and y, and the coefficients have enough significant digits to
+provide precise answers with only "long" (32 bit?) multiplication.
+IXYboth() is the general purpose routine; IXonly() and IYonly() are
+special cases when one of the coefficients is 0.
+*/
+
+static fractpel
+IXYboth(fractpel cx, fractpel cy, /* x and y coefficients */
+ long x, long y) /* user x,y */
+{
+ return(x * cx + y * cy);
+}
+
+/*ARGSUSED*/
+static fractpel
+IXonly(fractpel cx, fractpel cy, /* x and y coefficients */
+ long x, long y) /* user x,y */
+{
+ return(x * cx);
+}
+
+/*ARGSUSED*/
+static fractpel
+IYonly(fractpel cx, fractpel cy, /* x and y coefficients */
+ long x, long y) /* user x,y */
+{
+ return(y * cy);
+}
+
+
+/*
+:h3.FPXYboth(), FPXonly(), FPYonly() - More Involved Integer Conversion
+
+These are the routines we use when the user has given us integers for
+x and y, but the coefficients do not have enough significant digits to
+provide precise answers with only "long" (32 bit?) multiplication.
+We have increased the number of significant bits in the coefficients
+by FRACTBITS; therefore we must use "double long" (64 bit?)
+multiplication by calling FPmult(). FPXYboth() is the general purpose
+routine; FPXonly() and FPYonly() are special cases when one of the
+coefficients is 0.
+
+Note that it is perfectly possible for us to calculate X with the
+"FP" method and Y with the "I" method, or vice versa. It all depends
+on how the functions in the XYspace structure are filled out.
+*/
+
+static fractpel
+FPXYboth(fractpel cx, fractpel cy, /* x and y coefficients */
+ long x, long y) /* user x,y */
+{
+ return( FPmult(x, cx) + FPmult(y, cy) );
+}
+
+/*ARGSUSED*/
+static fractpel
+FPXonly(fractpel cx, fractpel cy, /* x and y coefficients */
+ long x, long y) /* user x,y */
+{
+ return( FPmult(x, cx) );
+}
+
+/*ARGSUSED*/
+static fractpel
+FPYonly(fractpel cx, fractpel cy, /* x and y coefficients */
+ long x, long y) /* user x,y */
+{
+ return( FPmult(y, cy) );
+}
+
+
+
+/*
+:h3.FillOutFcns() - Determine the Appropriate Functions to Use for Conversion
+
+This function fills out the "convert" and "iconvert" function pointers
+in an XYspace structure, and also fills the "helper"
+functions that actually do the work.
+*/
+
+static void
+FillOutFcns(struct XYspace *S) /* functions will be set in this structure */
+{
+ S->convert = FXYConvert;
+ S->iconvert = IXYConvert;
+
+ FindFfcn(S->tofract.normal[0][0], S->tofract.normal[1][0], &S->xconvert);
+ FindFfcn(S->tofract.normal[0][1], S->tofract.normal[1][1], &S->yconvert);
+ FindIfcn(S->tofract.normal[0][0], S->tofract.normal[1][0],
+ &S->itofract[0][0], &S->itofract[1][0], &S->ixconvert);
+ FindIfcn(S->tofract.normal[0][1], S->tofract.normal[1][1],
+ &S->itofract[0][1], &S->itofract[1][1], &S->iyconvert);
+
+ if (S->ixconvert == NULL || S->iyconvert == NULL)
+ S->iconvert = ForceFloat;
+}
+
+/*
+:h3.PseudoSpace() - Build a Coordinate Space from a Matrix
+
+Since we have built all this optimized code that, given an (x,y) and
+a coordinate space, yield transformed (x,y), it seems a shame not to
+use the same logic when we need to multiply an (x,y) by an arbitrary
+matrix that is not (initially) part of a coordinate space. This
+subroutine takes the arbitrary matrix and builds a coordinate
+space, with all its nifty function pointers.
+*/
+
+static void
+PseudoSpace(struct XYspace *S, /* coordinate space structure to fill out */
+ double M[2][2]) /* matrix that will become 'tofract.normal' */
+{
+ S->type = SPACETYPE;
+ S->flag = ISPERMANENT(ON) + ISIMMORTAL(ON);
+ S->references = 2; /* 3-26-91 added PNM */
+ S->tofract.normal[0][0] = M[0][0];
+ S->tofract.normal[1][0] = M[1][0];
+ S->tofract.normal[0][1] = M[0][1];
+ S->tofract.normal[1][1] = M[1][1];
+
+ FillOutFcns(S);
+}
+
+/*
+:h4.FindFfcn() - Subroutine of FillOutFcns() to Fill Out Floating Functions
+
+This function tests for the special case of one of the coefficients
+being zero:
+*/
+
+static void
+FindFfcn(double cx, double cy, /* x and y coefficients */
+ convertFunc *fcnP) /* pointer to function to set */
+{
+ if (cx == 0.0)
+ *fcnP = FYonly;
+ else if (cy == 0.0)
+ *fcnP = FXonly;
+ else
+ *fcnP = FXYboth;
+}
+
+/*
+:h4.FindIfcn() - Subroutine of FillOutFcns() to Fill Out Integer Functions
+
+There are two types of integer functions, the 'I' type and the 'FP' type.
+We use the I type functions when we are satisfied with simple integer
+arithmetic. We used the FP functions when we feel we need higher
+precision (but still fixed point) arithmetic. If all else fails,
+we store a NULL indicating that this we should do the conversion in
+floating point.
+*/
+
+static void
+FindIfcn(double cx, double cy, /* x and y coefficients */
+ fractpel *icxP, fractpel *icyP, /* fixed point coefficients to set */
+ iconvertFunc *fcnP) /* pointer to function to set */
+{
+ register fractpel imax; /* maximum of cx and cy */
+
+ *icxP = cx;
+ *icyP = cy;
+
+ if (cx != (float) (*icxP) || cy != (float) (*icyP)) {
+/*
+At this point we know our integer approximations of the coefficients
+are not exact. However, we will still use them if the maximum
+coefficient will not fit in a 'fractpel'. Of course, we have little
+choice at that point, but we haven't lost that much precision by
+staying with integer arithmetic. We have enough significant digits
+so that
+any error we introduce is less than one part in 2:sup/16/.
+*/
+
+ imax = MAX(ABS(*icxP), ABS(*icyP));
+ if (imax < (fractpel) (1<<(FRACTBITS-1)) ) {
+/*
+At this point we know our integer approximations just do not have
+enough significant digits for accuracy. We will add FRACTBITS
+significant digits to the coefficients (by multiplying them by
+1<<FRACTBITS) and go to the "FP" form of the functions. First, we
+check to see if we have ANY significant digits at all (that is, if
+imax == 0). If we don't, we suspect that adding FRACTBITS digits
+won't help, so we punt the whole thing.
+*/
+ if (imax == 0) {
+ *fcnP = NULL;
+ return;
+ }
+ cx *= FRACTFLOAT;
+ cy *= FRACTFLOAT;
+ *icxP = cx;
+ *icyP = cy;
+ *fcnP = FPXYboth;
+ }
+ else
+ *fcnP = IXYboth;
+ }
+ else
+ *fcnP = IXYboth;
+/*
+Now we check for special cases where one coefficient is zero (after
+integer conversion):
+*/
+ if (*icxP == 0)
+ *fcnP = (*fcnP == FPXYboth) ? FPYonly : IYonly;
+ else if (*icyP == 0)
+ *fcnP = (*fcnP == FPXYboth) ? FPXonly : IXonly;
+}
+/*
+:h3.UnConvert() - Find User Coordinates From FractPoints
+
+The interesting thing with this routine is that we avoid calculating
+the matrix inverse of the device transformation until we really need
+it, which is to say, until this routine is called for the first time
+with a given coordinate space.
+
+We also only calculate it only once. If the inverted matrix is valid,
+we don't calculate it; if not, we do. We never expect matrices with
+zero determinants, so by convention, we mark the matrix is invalid by
+marking both X terms zero.
+*/
+
+void
+UnConvert(struct XYspace *S, /* relevant coordinate space */
+ struct fractpoint *pt, /* device coordinates */
+ double *xp, double *yp) /* where to store resulting x,y */
+{
+ double x,y;
+
+ CoerceInverse(S);
+ x = pt->x;
+ y = pt->y;
+ *xp = S->tofract.inverse[0][0] * x + S->tofract.inverse[1][0] * y;
+ *yp = S->tofract.inverse[0][1] * x + S->tofract.inverse[1][1] * y;
+}
+
+/*
+:h2.Transformations
+*/
+/*
+:h3 id=xform.Xform() - Transform Object in X and Y
+
+TYPE1IMAGER wants transformations of objects like paths to be identical
+to transformations of spaces. For example, if you scale a line(1,1)
+by 10 it should yield the same result as generating the line(1,1) in
+a coordinate space that has been scaled by 10.
+
+We handle fonts by storing the accumulated transform, for example, SR
+(accumulating on the right). Then when we map the font through space TD,
+for example, we multiply the accumulated font transform on the left by
+the space transform on the right, yielding SRTD in this case. We will
+get the same result if we did S, then R, then T on the space and mapping
+an unmodified font through that space.
+*/
+
+static struct xobject *
+t1_Xform(struct xobject *obj, /* object to transform */
+ double M[2][2]) /* transformation matrix */
+{
+ if (obj == NULL)
+ return(NULL);
+
+ if (obj->type == FONTTYPE) {
+ register struct font *F = (struct font *) obj;
+
+ F = UniqueFont(F);
+ return((struct xobject*)F);
+ }
+ if (obj->type == PICTURETYPE) {
+/*
+In the case of a picture, we choose both to update the picture's
+transformation matrix and keep the handles up to date.
+*/
+ register struct picture *P = (struct picture *) obj;
+ register struct segment *handles; /* temporary path to transform handles */
+
+ P = UniquePicture(P);
+ handles = PathSegment(LINETYPE, P->origin.x, P->origin.y);
+ handles = Join(handles,
+ PathSegment(LINETYPE, P->ending.x, P->ending.y) );
+ handles = (struct segment *)Xform((struct xobject *) handles, M);
+ P->origin = handles->dest;
+ P->ending = handles->link->dest;
+ KillPath(handles);
+ return((struct xobject *)P);
+ }
+
+ if (ISPATHTYPE(obj->type)) {
+ struct XYspace pseudo; /* local temporary space */
+ PseudoSpace(&pseudo, M);
+ return((struct xobject *) PathTransform((struct segment *)obj,
+ &pseudo));
+ }
+
+
+ if (obj->type == SPACETYPE) {
+ register struct XYspace *S = (struct XYspace *) obj;
+
+/* replaced ISPERMANENT(S->flag) with S->references > 1 3-26-91 PNM */
+ if (S->references > 1)
+ S = CopySpace(S);
+ else
+ S->ID = NEXTID;
+
+ MatrixMultiply(S->tofract.normal, M, S->tofract.normal);
+ /*
+ * mark inverted matrix invalid:
+ */
+ S->flag &= ~HASINVERSE(ON);
+
+ FillOutFcns(S);
+ return((struct xobject *) S);
+ }
+
+ return(ArgErr("Untransformable object", obj, obj));
+}
+
+/*
+:h3.Transform() - Transform an Object
+
+This is the external user's entry point.
+*/
+struct xobject *
+t1_Transform(struct xobject *obj,
+ double cxx, double cyx, /* 2x2 transform matrix elements */
+ double cxy, double cyy) /* in row order */
+{
+ double M[2][2];
+
+ M[0][0] = cxx;
+ M[0][1] = cyx;
+ M[1][0] = cxy;
+ M[1][1] = cyy;
+ ConsiderContext(obj, M);
+ return(Xform(obj, M));
+}
+
+/*
+:h3 id=rotate.Rotate() - Special Case of Transform()
+
+We special-case different settings of 'degrees' for performance
+and accuracy within the DegreeSin() and DegreeCos() routines themselves.
+*/
+
+#ifdef notdef
+struct xobject *
+xiRotate(struct xobject *obj, /* object to be transformed */
+ double degrees) /* degrees of COUNTER-clockwise rotation */
+{
+ double M[2][2];
+
+ M[0][0] = M[1][1] = DegreeCos(degrees);
+ M[1][0] = - (M[0][1] = DegreeSin(degrees));
+ ConsiderContext(obj, M);
+ return(Xform(obj, M));
+}
+#endif
+
+
+/*
+:h2 id=matrixa.Matrix Arithmetic
+
+Following the convention in Newman and Sproull, :hp1/Interactive
+Computer Graphics/,
+matrices are organized:
+:xmp.
+ | cxx cyx |
+ | cxy cyy |
+:exmp.
+A point is horizontal, for example:
+:xmp.
+ [ x y ]
+:exmp.
+This means that:
+:formula/x prime = cxx times x + cxy times y/
+:formula/y prime = cyx times x + cyy times y/
+I've seen the other convention, where transform matrices are
+transposed, equally often in the literature.
+*/
+
+/*
+:h2.Initialization, Queries, and Debug
+*/
+/*
+:h3.InitSpaces() - Initialize Constant Spaces
+
+For compatibility, we initialize a coordinate space called USER which
+maps 72nds of an inch to pels on the default device.
+*/
+
+static struct XYspace *USER = &identity;
+
+void
+InitSpaces(void)
+{
+ IDENTITY->type = SPACETYPE;
+ FillOutFcns(IDENTITY);
+
+ contexts[NULLCONTEXT].normal[1][0]
+ = contexts[NULLCONTEXT].normal[0][1]
+ = contexts[NULLCONTEXT].inverse[1][0]
+ = contexts[NULLCONTEXT].inverse[0][1] = 0.0;
+ contexts[NULLCONTEXT].normal[0][0]
+ = contexts[NULLCONTEXT].normal[1][1]
+ = contexts[NULLCONTEXT].inverse[0][0]
+ = contexts[NULLCONTEXT].inverse[1][1] = 1.0;
+
+ USER->flag |= ISIMMORTAL(ON);
+ CoerceInverse(USER);
+}
+/*
+:h3.QuerySpace() - Returns the Transformation Matrix of a Space
+
+Since the tofract matrix of an XYspace includes the scale factor
+necessary to produce fractpel results (i.e., FRACTFLOAT), this
+must be taken out before we return the matrix to the user. Fortunately,
+this is simple: just multiply by the inverse of IDENTITY!
+*/
+
+void
+QuerySpace(struct XYspace *S, /* space asked about */
+ double *cxxP, double *cyxP, /* where to put answer */
+ double *cxyP, double *cyyP)
+{
+ double M[2][2]; /* temp matrix to build user's answer */
+
+ if (S->type != SPACETYPE) {
+ ArgErr("QuerySpace: not a space", S, NULL);
+ return;
+ }
+ MatrixMultiply(S->tofract.normal, IDENTITY->tofract.inverse, M);
+ *cxxP = M[0][0];
+ *cxyP = M[1][0];
+ *cyxP = M[0][1];
+ *cyyP = M[1][1];
+}
diff --git a/libXfont/src/Type1/spaces.h b/libXfont/src/Type1/spaces.h
new file mode 100644
index 000000000..88d1b1524
--- /dev/null
+++ b/libXfont/src/Type1/spaces.h
@@ -0,0 +1,151 @@
+/* $Xorg: spaces.h,v 1.3 2000/08/17 19:46:32 cpqbld Exp $ */
+/* Copyright International Business Machines, Corp. 1991
+ * All Rights Reserved
+ * Copyright Lexmark International, Inc. 1991
+ * All Rights Reserved
+ *
+ * License to use, copy, modify, and distribute this software and its
+ * documentation for any purpose and without fee is hereby granted,
+ * provided that the above copyright notice appear in all copies and that
+ * both that copyright notice and this permission notice appear in
+ * supporting documentation, and that the name of IBM or Lexmark not be
+ * used in advertising or publicity pertaining to distribution of the
+ * software without specific, written prior permission.
+ *
+ * IBM AND LEXMARK PROVIDE THIS SOFTWARE "AS IS", WITHOUT ANY WARRANTIES OF
+ * ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING, BUT NOT LIMITED TO ANY
+ * IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE,
+ * AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. THE ENTIRE RISK AS TO THE
+ * QUALITY AND PERFORMANCE OF THE SOFTWARE, INCLUDING ANY DUTY TO SUPPORT
+ * OR MAINTAIN, BELONGS TO THE LICENSEE. SHOULD ANY PORTION OF THE
+ * SOFTWARE PROVE DEFECTIVE, THE LICENSEE (NOT IBM OR LEXMARK) ASSUMES THE
+ * ENTIRE COST OF ALL SERVICING, REPAIR AND CORRECTION. IN NO EVENT SHALL
+ * IBM OR LEXMARK BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
+ * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
+ * THIS SOFTWARE.
+ */
+/* $XFree86: xc/lib/font/Type1/spaces.h,v 3.3 1999/08/22 08:58:53 dawes Exp $ */
+
+/*SHARED*/
+
+#define USER t1_User
+#define IDENTITY t1_Identity
+
+#define Context(d,u) t1_Context(d,u)
+#define Transform(o,f1,f2,f3,f4) t1_Transform(o,f1,f2,f3,f4)
+#define Rotate(o,d) t1_Rotate(o,d)
+#define Scale(o,sx,sy) t1_Scale(o,sx,sy)
+#define QuerySpace(S,f1,f2,f3,f4) t1_QuerySpace(S,f1,f2,f3,f4)
+#define Warp(s1,o,s2) t1_Warp(s1,o,s2)
+
+/* IDENTITY space */
+extern struct XYspace *IDENTITY;
+
+/* creates a coordinate space for a device */
+extern struct XYspace *Context(pointer device, double units);
+/* transform an object */
+extern struct xobject *t1_Transform ( struct xobject *obj, double cxx,
+ double cyx, double cxy, double cyy );
+/* returns coordinate space matrix */
+extern void t1_QuerySpace ( struct XYspace *S, double *cxxP, double *cyxP,
+ double *cxyP, double *cyyP );
+
+/*END SHARED*/
+/*SHARED*/
+
+/* #define KillSpace(s) Free(s)
+Note - redefined KillSpace() to check references !
+3-26-91 PNM */
+
+#define KillSpace(s) if ( (--(s->references) == 0) ||\
+ ( (s->references == 1) && ISPERMANENT(s->flag) ) )\
+ Free(s)
+
+#define ConsumeSpace(s) MAKECONSUME(s,KillSpace(s))
+#define UniqueSpace(s) MAKEUNIQUE(s,CopySpace(s))
+
+/*END SHARED*/
+/*SHARED*/
+
+typedef short pel; /* integer pel locations */
+typedef long fractpel; /* fractional pel locations */
+
+#define FRACTBITS 16 /* number of fractional bits in 'fractpel' */
+/*
+We define the following macros to convert from 'fractpel' to 'pel' and
+vice versa:
+*/
+#define TOFRACTPEL(p) (((fractpel)p)<<FRACTBITS)
+#define FPHALF (1<<(FRACTBITS-1))
+#define NEARESTPEL(fp) (((fp)+FPHALF)>>FRACTBITS)
+#define FRACTFLOAT (double)(1L<<FRACTBITS)
+
+/*END SHARED*/
+/*SHARED*/
+
+struct doublematrix {
+ double normal[2][2];
+ double inverse[2][2];
+} ;
+
+/*END SHARED*/
+/*SHARED*/
+
+struct fractpoint {
+ fractpel x,y;
+} ;
+
+/*SHARED*/
+
+typedef fractpel (*convertFunc)(double, double, double, double);
+typedef fractpel (*iconvertFunc)(fractpel, fractpel, long, long);
+
+struct XYspace {
+ XOBJ_COMMON /* xobject common data define 3-26-91 PNM */
+ /* type = SPACETYPE */
+ void (*convert)(struct fractpoint *, struct XYspace *, double, double); /* calculate "fractpoint" X,Y from float X,Y */
+ void (*iconvert)(struct fractpoint *, struct XYspace *, long, long); /* calculate "fractpoint" X,Y from int X,Y */
+ convertFunc xconvert; /* subroutine of convert */
+ convertFunc yconvert; /* subroutine of convert */
+ iconvertFunc ixconvert; /* subroutine of iconvert */
+ iconvertFunc iyconvert; /* subroutine of iconvert */
+ int ID; /* unique identifier (used in font caching) */
+ unsigned char context; /* device context of coordinate space */
+ struct doublematrix tofract; /* xform to get to fractional pels */
+ fractpel itofract[2][2]; /* integer version of "tofract.normal" */
+} ;
+
+#define INVALIDID 0 /* no valid space will have this ID */
+
+/*END SHARED*/
+/*END SHARED*/
+/*SHARED*/
+
+#define DeviceResolution t1_DeviceResolution
+#define InitSpaces t1_InitSpaces
+#define CopySpace(s) t1_CopySpace(s)
+#define Xform(o,M) t1_Xform(o,M)
+#define UnConvert(S,pt,xp,yp) t1_UnConvert(S,pt,xp,yp)
+#define MatrixMultiply(A,B,C) t1_MMultiply(A,B,C)
+#define MatrixInvert(A,B) t1_MInvert(A,B)
+#define PseudoSpace(S,M) t1_PseudoSpace(S,M)
+#define FindContext(M) t1_FindContext(M)
+
+/* initialize pre-defined coordinate spaces */
+extern void t1_InitSpaces ( void );
+/* duplicate a coordinate space */
+extern struct XYspace *t1_CopySpace ( struct XYspace *S );
+/* return user coordinates from device coordinates */
+extern void t1_UnConvert ( struct XYspace *S, struct fractpoint *pt,
+ double *xp, double *yp );
+/* return the "context" represented by a matrix */
+int t1_FindContext(double M[2][2]);
+
+/*END SHARED*/
+/*SHARED*/
+
+#define NULLCONTEXT 0
+
+/*END SHARED*/
diff --git a/libXfont/src/Type1/strokes.h b/libXfont/src/Type1/strokes.h
new file mode 100644
index 000000000..c374e16db
--- /dev/null
+++ b/libXfont/src/Type1/strokes.h
@@ -0,0 +1,38 @@
+/* $Xorg: strokes.h,v 1.3 2000/08/17 19:46:32 cpqbld Exp $ */
+/* Copyright International Business Machines,Corp. 1991
+ * All Rights Reserved
+ *
+ * License to use, copy, modify, and distribute this software
+ * and its documentation for any purpose and without fee is
+ * hereby granted, provided that the above copyright notice
+ * appear in all copies and that both that copyright notice and
+ * this permission notice appear in supporting documentation,
+ * and that the name of IBM not be used in advertising or
+ * publicity pertaining to distribution of the software without
+ * specific, written prior permission.
+ *
+ * IBM PROVIDES THIS SOFTWARE "AS IS", WITHOUT ANY WARRANTIES
+ * OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING, BUT NOT
+ * LIMITED TO ANY IMPLIED WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE, AND NONINFRINGEMENT OF
+ * THIRD PARTY RIGHTS. THE ENTIRE RISK AS TO THE QUALITY AND
+ * PERFORMANCE OF THE SOFTWARE, INCLUDING ANY DUTY TO SUPPORT
+ * OR MAINTAIN, BELONGS TO THE LICENSEE. SHOULD ANY PORTION OF
+ * THE SOFTWARE PROVE DEFECTIVE, THE LICENSEE (NOT IBM) ASSUMES
+ * THE ENTIRE COST OF ALL SERVICING, REPAIR AND CORRECTION. IN
+ * NO EVENT SHALL IBM BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING
+ * FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF
+ * CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
+ * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+ * SOFTWARE.
+ */
+/*STUB*/
+
+#define CopyLineStyle(s) s
+#define CopyStrokePath(p) p
+#define KillStrokePath(p)
+#define KillLineStyle(s)
+#define CoercePath(sp) sp
+#define DoStroke(sp) sp
+
diff --git a/libXfont/src/Type1/t1funcs.c b/libXfont/src/Type1/t1funcs.c
new file mode 100644
index 000000000..e4b2209b0
--- /dev/null
+++ b/libXfont/src/Type1/t1funcs.c
@@ -0,0 +1,754 @@
+/* $Xorg: t1funcs.c,v 1.5 2001/02/09 02:04:01 xorgcvs Exp $ */
+/* Copyright International Business Machines,Corp. 1991
+ * All Rights Reserved
+ *
+ * License, subject to the license given below, to use,
+ * copy, modify, and distribute this software * and its
+ * documentation for any purpose and without fee is hereby
+ * granted, provided that the above copyright notice appear
+ * in all copies and that both that copyright notice and
+ * this permission notice appear in supporting documentation,
+ * and that the name of IBM not be used in advertising or
+ * publicity pertaining to distribution of the software
+ * without specific, written prior permission.
+ *
+ * IBM PROVIDES THIS SOFTWARE "AS IS", WITHOUT ANY WARRANTIES
+ * OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING, BUT NOT
+ * LIMITED TO ANY IMPLIED WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE, AND NONINFRINGEMENT OF
+ * THIRD PARTY RIGHTS. THE ENTIRE RISK AS TO THE QUALITY AND
+ * PERFORMANCE OF THE SOFTWARE, INCLUDING ANY DUTY TO SUPPORT
+ * OR MAINTAIN, BELONGS TO THE LICENSEE. SHOULD ANY PORTION OF
+ * THE SOFTWARE PROVE DEFECTIVE, THE LICENSEE (NOT IBM) ASSUMES
+ * THE ENTIRE COST OF ALL SERVICING, REPAIR AND CORRECTION. IN
+ * NO EVENT SHALL IBM BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING
+ * FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF
+ * CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
+ * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+ * SOFTWARE.
+ *
+ * Author: Jeffrey B. Lotspiech, IBM Almaden Research Center
+ * Modeled on spfuncs.c by Dave Lemke, Network Computing Devices, Inc
+ * which contains the following copyright and permission notices:
+ *
+ * Copyright 1990, 1991 Network Computing Devices;
+ * Portions Copyright 1987 by Digital Equipment Corporation
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the names of Network Computing Devices
+ * or Digital not be used in advertising or publicity pertaining to
+ * distribution of the software without specific, written prior permission.
+ * Network Computing Devices or Digital make no representations about the
+ * suitability of this software for any purpose. It is provided "as is"
+ * without express or implied warranty.
+ *
+ * NETWORK COMPUTING DEVICES AND DIGITAL DISCLAIM ALL WARRANTIES WITH
+ * REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS, IN NO EVENT SHALL NETWORK COMPUTING DEVICES OR DIGITAL BE
+ * LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+/* $XFree86: xc/lib/font/Type1/t1funcs.c,v 3.33 2003/07/19 13:16:40 tsi Exp $ */
+
+/*
+
+Copyright 1987, 1994, 1998 The Open Group
+
+Permission to use, copy, modify, distribute, and sell this software and its
+documentation for any purpose is hereby granted without fee, provided that
+the above copyright notice appear in all copies and that both that
+copyright notice and this permission notice appear in supporting
+documentation.
+
+The above copyright notice and this permission notice shall be included
+in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+IN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR
+OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of The Open Group shall
+not be used in advertising or otherwise to promote the sale, use or
+other dealings in this Software without prior written authorization
+from The Open Group.
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#ifndef FONTMODULE
+#include <string.h>
+#ifdef _XOPEN_SOURCE
+#include <math.h>
+#else
+#define _XOPEN_SOURCE /* to get prototype for hypot on some systems */
+#include <math.h>
+#undef _XOPEN_SOURCE
+#endif
+#include "X11/Xfuncs.h"
+#ifdef USE_MMAP
+#include <sys/types.h>
+#include <sys/mman.h>
+#endif
+#else
+#include "Xmd.h"
+#include "Xdefs.h"
+#endif
+
+#ifdef FONTMODULE
+#include "os.h"
+#include "xf86_ansic.h"
+#endif
+
+#include <X11/fonts/fntfilst.h>
+#include <X11/fonts/fontutil.h>
+#include <X11/fonts/FSproto.h>
+#include <X11/fonts/fontenc.h>
+#include "t1unicode.h"
+
+#include "objects.h"
+#include "spaces.h"
+#include "paths.h"
+#include "regions.h"
+#include "t1stdio.h"
+#include "util.h"
+#include "fontfcn.h"
+#include "t1intf.h"
+
+
+static int Type1GetGlyphs ( FontPtr pFont, unsigned long count,
+ unsigned char *chars, FontEncoding charEncoding,
+ unsigned long *glyphCount, CharInfoPtr *glyphs );
+
+static int Type1GetMetrics ( FontPtr pFont, unsigned long count,
+ unsigned char *chars,
+ FontEncoding charEncoding,
+ unsigned long *glyphCount,
+ xCharInfo **glyphs );
+
+
+#define minchar(p) ((p).min_char_low + ((p).min_char_high << 8))
+#define maxchar(p) ((p).max_char_low + ((p).max_char_high << 8))
+
+static void fillrun ( char *p, pel x0, pel x1, int bit );
+
+extern psfont *FontP;
+extern psobj *ISOLatin1EncArrayP;
+
+static void fill ( char *dest, int h, int w, struct region *area, int byte,
+ int bit, int wordsize );
+
+static int
+Type1ReturnCodeToXReturnCode(int rc)
+{
+ switch(rc) {
+ case SCAN_OK:
+ return Successful;
+ case SCAN_FILE_EOF:
+ /* fall through to BadFontFormat */
+ case SCAN_ERROR:
+ return BadFontFormat;
+ case SCAN_OUT_OF_MEMORY:
+ return AllocError;
+ case SCAN_FILE_OPEN_ERROR:
+ return BadFontName;
+ case SCAN_TRUE:
+ case SCAN_FALSE:
+ case SCAN_END:
+ /* fall through */
+ default:
+ /* this should not happen */
+ ErrorF("Type1 return code not convertable to X return code: %d\n", rc);
+ return rc;
+ }
+}
+
+/*ARGSUSED*/
+int
+Type1OpenScalable (FontPathElementPtr fpe,
+ FontPtr *ppFont,
+ int flags,
+ FontEntryPtr entry,
+ char *fileName,
+ FontScalablePtr vals,
+ fsBitmapFormat format,
+ fsBitmapFormatMask fmask,
+ FontPtr non_cachable_font) /* We don't do licensing */
+{
+ FontPtr pFont;
+ int bit,
+ byte,
+ glyph,
+ scan,
+ image;
+ int pad,wordsize; /* scan & image in bits */
+ long *pool; /* memory pool for ximager objects */
+ int size; /* for memory size calculations */
+ struct XYspace *S; /* coordinate space for character */
+ struct region *area;
+ CharInfoRec *glyphs;
+ int len, rc, count = 0, i = 0;
+ struct type1font *type1;
+ char *p;
+ FontMapPtr mapping = NULL;
+ int no_mapping;
+ psobj *fontmatrix;
+ long x0, total_width = 0, total_raw_width = 0;
+ double x1, y1, t1 = .001, t2 = 0.0, t3 = 0.0, t4 = .001;
+ double sxmult;
+
+ /* Reject ridiculously small font sizes that will blow up the math */
+ if (hypot(vals->pixel_matrix[0], vals->pixel_matrix[1]) < 1.0 ||
+ hypot(vals->pixel_matrix[2], vals->pixel_matrix[3]) < 1.0)
+ return BadFontName;
+
+ /* set up default values */
+ FontDefaultFormat(&bit, &byte, &glyph, &scan);
+ /* get any changes made from above */
+ rc = CheckFSFormat(format, fmask, &bit, &byte, &scan, &glyph, &image);
+ if (rc != Successful)
+ return rc;
+
+ pad = glyph * 8;
+ wordsize = scan * 8;
+
+#define PAD(bits, pad) (((bits)+(pad)-1)&-(pad))
+
+ pFont = CreateFontRec();
+ if (pFont == NULL)
+ return AllocError;
+
+ type1 = (struct type1font *)xalloc(sizeof(struct type1font));
+ if (type1 == NULL) {
+ DestroyFontRec(pFont);
+ return AllocError;
+ }
+ bzero(type1, sizeof(struct type1font));
+
+ /* heuristic for "maximum" size of pool we'll need: */
+ size = 200000 + 600 *
+ (int)hypot(vals->pixel_matrix[2], vals->pixel_matrix[3])
+ * sizeof(short);
+ if (size < 0 || NULL == (pool = (long *) xalloc(size))) {
+ xfree(type1);
+ DestroyFontRec(pFont);
+ return AllocError;
+ }
+
+ addmemory(pool, size);
+
+
+ glyphs = type1->glyphs;
+
+ /* load font if not already loaded */
+ if (!fontfcnA(fileName, &rc)) {
+ delmemory();
+ xfree(type1);
+ DestroyFontRec(pFont);
+ xfree(pool);
+ return Type1ReturnCodeToXReturnCode(rc);
+ }
+
+ fontmatrix = &FontP->fontInfoP[FONTMATRIX].value;
+ if (objPIsArray(fontmatrix) && fontmatrix->len == 6)
+ {
+#define assign(n,d,f) if (objPIsInteger(fontmatrix->data.arrayP + n)) \
+ d = fontmatrix->data.arrayP[n].data.integer; \
+ else if (objPIsReal(fontmatrix->data.arrayP + n)) \
+ d = fontmatrix->data.arrayP[n].data.real; \
+ else d = f;
+
+ assign(0, t1, .001);
+ assign(1, t2, 0.0);
+ assign(2, t3, 0.0);
+ assign(3, t4, .001);
+ }
+
+ S = (struct XYspace *) t1_Transform((struct xobject *)IDENTITY,
+ t1, t2, t3, t4);
+
+ S = (struct XYspace *) Permanent(t1_Transform((struct xobject *)S,
+ vals->pixel_matrix[0],
+ -vals->pixel_matrix[1],
+ vals->pixel_matrix[2],
+ -vals->pixel_matrix[3]));
+
+
+ /* multiplier for computation of raw values */
+ sxmult = hypot(vals->pixel_matrix[0], vals->pixel_matrix[1]);
+ if (sxmult > EPS) sxmult = 1000.0 / sxmult;
+
+ no_mapping=0;
+ p = FontEncFromXLFD(entry->name.name, entry->name.length);
+
+ if(p==0) { /* XLFD does not specify an encoding */
+ mapping=0;
+ no_mapping=2; /* ISO 8859-1 */
+ }
+
+ if(!strcmp(p, "adobe-fontspecific")) {
+ mapping=0;
+ no_mapping=1; /* font's native encoding vector */
+ }
+
+ pFont->info.firstCol = 255;
+ pFont->info.lastCol = 0;
+
+ if(!no_mapping) {
+ mapping = FontEncMapFind(p,
+ FONT_ENCODING_POSTSCRIPT, -1, -1,
+ fileName);
+ if(!mapping)
+ mapping = FontEncMapFind(p,
+ FONT_ENCODING_UNICODE, -1, -1,
+ fileName);
+ if(!mapping)
+ goto NoEncoding;
+ else
+ no_mapping=0;
+ }
+
+ for (i=0; i < 256; i++) {
+ long h,w;
+ long paddedW;
+ int j;
+ char *codename;
+
+ if(no_mapping == 1) {
+ codename = FontP->fontInfoP[ENCODING].
+ value.data.arrayP[i].data.valueP;
+ len = FontP->fontInfoP[ENCODING].
+ value.data.arrayP[i].len;
+ } else if(no_mapping) {
+ codename = unicodetoPSname(i);
+ len = codename ? strlen(codename) : 0;
+ } else {
+ if(mapping->type == FONT_ENCODING_UNICODE) {
+ codename = unicodetoPSname(FontEncRecode(i, mapping));
+ } else
+ codename = FontEncName(i, mapping);
+ len=codename?strlen(codename):0;
+ }
+
+ /* Avoid multiply rasterising the undefined glyph */
+ if(len==7 && !strncmp(codename, ".notdef", 7)) {
+ len=0;
+ codename=0;
+ }
+
+ /* But do rasterise it at least once */
+ if(len==0) {
+ if(i==0) {
+ codename=".notdef";
+ len=7;
+ } else
+ continue;
+ }
+
+ /* See if this character is in the list of ranges specified
+ in the XLFD name */
+ if(i!=0) {
+ for (j = 0; j < vals->nranges; j++)
+ if (i >= minchar(vals->ranges[j]) &&
+ i <= maxchar(vals->ranges[j]))
+ break;
+
+ /* If not, don't realize it. */
+ if (vals->nranges && j == vals->nranges)
+ continue;
+ }
+
+ rc = 0;
+ area = (struct region *)fontfcnB(S, (unsigned char *)codename,
+ &len, &rc);
+ if (rc < 0) {
+ rc = Type1ReturnCodeToXReturnCode(rc);
+ break;
+ }
+ else if (rc > 0)
+ continue;
+
+ if (area == NULL)
+ continue;
+
+ if (pFont->info.firstCol > i)
+ pFont->info.firstCol = i;
+ if (pFont->info.lastCol < i)
+ pFont->info.lastCol = i;
+
+ h = area->ymax - area->ymin;
+ w = area->xmax - area->xmin;
+ paddedW = PAD(w, pad);
+
+ if (h > 0 && w > 0) {
+ size = h * paddedW / 8;
+ glyphs[i].bits = (char *)xalloc(size);
+ if (glyphs[i].bits == NULL) {
+ rc = AllocError;
+ break;
+ }
+ }
+ else {
+ size = 0;
+ h = w = 0;
+ area->xmin = area->xmax = 0;
+ area->ymax = area->ymax = 0;
+ }
+
+ glyphs[i].metrics.leftSideBearing = area->xmin;
+ x1 = (double)(x0 = area->ending.x - area->origin.x);
+ y1 = (double)(area->ending.y - area->origin.y);
+ glyphs[i].metrics.characterWidth =
+ (x0 + (x0 > 0 ? FPHALF : -FPHALF)) / (1 << FRACTBITS);
+ if (!glyphs[i].metrics.characterWidth && size == 0)
+ {
+ /* Zero size and zero extents: presumably caused by
+ the choice of transformation. Let's create a
+ small bitmap so we're not mistaken for an undefined
+ character. */
+ h = w = 1;
+ size = paddedW = PAD(w, pad);
+ glyphs[i].bits = (char *)xalloc(size);
+ if (glyphs[i].bits == NULL) {
+ rc = AllocError;
+ break;
+ }
+ }
+ glyphs[i].metrics.attributes =
+ NEARESTPEL((long)(hypot(x1, y1) * sxmult));
+ total_width += glyphs[i].metrics.attributes;
+ total_raw_width += abs((int)(INT16)glyphs[i].metrics.attributes);
+ count++;
+ glyphs[i].metrics.rightSideBearing = w + area->xmin;
+ glyphs[i].metrics.descent = area->ymax - NEARESTPEL(area->origin.y);
+ glyphs[i].metrics.ascent = h - glyphs[i].metrics.descent;
+
+
+ bzero(glyphs[i].bits, size);
+ if (h > 0 && w > 0) {
+ fill(glyphs[i].bits, h, paddedW, area, byte, bit, wordsize );
+ }
+
+ Destroy(area);
+ }
+ NoEncoding:
+
+ delmemory();
+ xfree(pool);
+
+ if (pFont->info.firstCol > pFont->info.lastCol)
+ {
+ xfree(type1);
+ DestroyFontRec(pFont);
+ return BadFontName;
+ }
+
+ if (i != 256) {
+ for (i--; i >= 0; i--)
+ if (glyphs[i].bits != NULL)
+ xfree(glyphs[i].bits);
+ xfree(type1);
+ DestroyFontRec(pFont);
+ return rc;
+ }
+ type1->pDefault = NULL;
+
+ pFont->format = format;
+
+ pFont->bit = bit;
+ pFont->byte = byte;
+ pFont->glyph = glyph;
+ pFont->scan = scan;
+
+ pFont->info.firstRow = 0;
+ pFont->info.lastRow = 0;
+
+ pFont->get_metrics = Type1GetMetrics;
+ pFont->get_glyphs = Type1GetGlyphs;
+ pFont->unload_font = Type1CloseFont;
+ pFont->unload_glyphs = NULL;
+ pFont->refcnt = 0;
+
+ pFont->fontPrivate = (unsigned char *) type1;
+
+ if (count)
+ {
+ total_raw_width = (total_raw_width * 10 + count / 2) / count;
+ if (total_width < 0)
+ {
+ /* Predominant direction is R->L */
+ total_raw_width = -total_raw_width;
+ }
+ vals->width = (int)((double)total_raw_width *
+ vals->pixel_matrix[0] / 1000.0 +
+ (vals->pixel_matrix[0] > 0 ? .5 : -.5));
+ }
+
+ T1FillFontInfo(pFont, vals, fileName, entry->name.name, total_raw_width);
+
+ *ppFont = pFont;
+ return Successful;
+}
+
+static int
+Type1GetGlyphs(FontPtr pFont,
+ unsigned long count,
+ unsigned char *chars,
+ FontEncoding charEncoding,
+ unsigned long *glyphCount, /* RETURN */
+ CharInfoPtr *glyphs) /* RETURN */
+{
+ unsigned int firstRow;
+ unsigned int numRows;
+ CharInfoPtr *glyphsBase;
+ register unsigned int c;
+ register CharInfoPtr pci;
+ unsigned int r;
+ CharInfoPtr pDefault;
+ register struct type1font *type1Font;
+ register int firstCol;
+
+ type1Font = (struct type1font *) pFont->fontPrivate;
+ firstCol = pFont->info.firstCol;
+ pDefault = type1Font->pDefault;
+ glyphsBase = glyphs;
+
+ switch (charEncoding) {
+
+#define EXIST(pci) \
+ ((pci)->metrics.attributes || \
+ (pci)->metrics.ascent != -(pci)->metrics.descent || \
+ (pci)->metrics.leftSideBearing != (pci)->metrics.rightSideBearing)
+
+ case Linear8Bit:
+ case TwoD8Bit:
+ if (pFont->info.firstRow > 0)
+ break;
+ while (count--) {
+ c = (*chars++);
+ if (c >= firstCol &&
+ (pci = &type1Font->glyphs[c]) &&
+ EXIST(pci))
+ *glyphs++ = pci;
+ else if (pDefault)
+ *glyphs++ = pDefault;
+ }
+ break;
+ case Linear16Bit:
+ while (count--) {
+ c = *chars++ << 8;
+ c = (c | *chars++);
+ if (c < 256 && c >= firstCol &&
+ (pci = &type1Font->glyphs[c]) &&
+ EXIST(pci))
+ *glyphs++ = pci;
+ else if (pDefault)
+ *glyphs++ = pDefault;
+ }
+ break;
+
+ case TwoD16Bit:
+ firstRow = pFont->info.firstRow;
+ numRows = pFont->info.lastRow - firstRow + 1;
+ while (count--) {
+ r = (*chars++) - firstRow;
+ c = (*chars++);
+ if (r < numRows && c < 256 && c >= firstCol &&
+ (pci = &type1Font->glyphs[(r << 8) + c]) &&
+ EXIST(pci))
+ *glyphs++ = pci;
+ else if (pDefault)
+ *glyphs++ = pDefault;
+ }
+ break;
+ }
+ *glyphCount = glyphs - glyphsBase;
+ return Successful;
+
+#undef EXIST
+}
+
+static int
+Type1GetMetrics(FontPtr pFont,
+ unsigned long count,
+ unsigned char *chars,
+ FontEncoding charEncoding,
+ unsigned long *glyphCount, /* RETURN */
+ xCharInfo **glyphs) /* RETURN */
+{
+ static CharInfoRec nonExistantChar;
+
+ int ret;
+ struct type1font *type1Font;
+ CharInfoPtr oldDefault;
+
+ type1Font = (struct type1font *) pFont->fontPrivate;
+ oldDefault = type1Font->pDefault;
+ type1Font->pDefault = &nonExistantChar;
+ ret = Type1GetGlyphs(pFont, count, chars, charEncoding, glyphCount, (CharInfoPtr *) glyphs);
+ type1Font->pDefault = oldDefault;
+ return ret;
+}
+
+void
+Type1CloseFont(FontPtr pFont)
+{
+ register int i;
+ struct type1font *type1;
+
+ type1 = (struct type1font *) pFont->fontPrivate;
+ for (i=0; i < 256; i++)
+ if (type1->glyphs[i].bits != NULL)
+ xfree(type1->glyphs[i].bits);
+ xfree(type1);
+
+ if (pFont->info.props)
+ xfree(pFont->info.props);
+
+ if (pFont->info.isStringProp)
+ xfree(pFont->info.isStringProp);
+
+ DestroyFontRec(pFont);
+}
+
+static void
+fill(char *dest, /* destination bitmap */
+ int h, int w, /* dimensions of 'dest', w padded */
+ struct region *area, /* region to write to 'dest' */
+ int byte, int bit, /* flags; LSBFirst or MSBFirst */
+ int wordsize) /* number of bits per word for LSB/MSB purposes */
+{
+ register struct edgelist *edge; /* for looping through edges */
+ register char *p; /* current scan line in 'dest' */
+ register int y; /* for looping through scans */
+ register int wbytes = w / 8; /* number of bytes in width */
+ register pel *leftP,*rightP; /* pointers to X values, left and right */
+ int xmin = area->xmin; /* upper left X */
+ int ymin = area->ymin; /* upper left Y */
+
+ for (edge = area->anchor; VALIDEDGE(edge); edge = edge->link->link) {
+
+ p = dest + (edge->ymin - ymin) * wbytes;
+ leftP = edge->xvalues;
+ rightP = edge->link->xvalues;
+
+ for (y = edge->ymin; y < edge->ymax; y++) {
+ fillrun(p, *leftP++ - xmin, *rightP++ - xmin, bit);
+ p += wbytes;
+ }
+ }
+/*
+Now, as an afterthought, we'll go reorganize if odd byte order requires
+it:
+*/
+ if (byte == LSBFirst && wordsize != 8) {
+ register int i;
+
+ switch (wordsize) {
+ case 16:
+ {
+ register unsigned short data,*p;
+
+ p = (unsigned short *) dest;
+
+ for (i = h * w /16; --i >= 0;) {
+ data = *p;
+ *p++ = (data << 8) + (data >> 8);
+ }
+ break;
+ }
+ case 64:
+ case 32:
+ {
+ register unsigned long data,*p;
+
+ p = (unsigned long *) dest;
+
+ for (i = h * w / 32; --i >= 0;) {
+ data = *p;
+ *p++ = (data << 24) + (data >> 24)
+ + (0xFF00 & (data >> 8))
+ + (0xFF0000 & (data << 8));
+ }
+ if (wordsize == 64) {
+
+ p = (unsigned long *) dest;
+
+ for (i = h * w / 64; --i >= 0;) {
+ data = *p++;
+ p[-1] = p[0];
+ *p++ = data;
+ }
+ }
+ break;
+ }
+ default:
+ Abort("xiFill: unknown format");
+ }
+ }
+
+}
+
+#define ALLONES 0xFF
+
+static void
+fillrun(char *p, /* address of this scan line */
+ pel x0, pel x1, /* left and right X */
+ int bit) /* format: LSBFirst or MSBFirst */
+{
+ register int startmask,endmask; /* bits to set in first and last char*/
+ register int middle; /* number of chars between start and end + 1 */
+
+ if (x1 <= x0)
+ return;
+ middle = x1/8 - x0/8;
+ p += x0/8;
+ x0 &= 7; x1 &= 7;
+ if (bit == LSBFirst) {
+ startmask = ALLONES << x0;
+ endmask = ~(ALLONES << x1);
+ }
+ else {
+ startmask = ALLONES >> x0;
+ endmask = ~(ALLONES >> x1);
+ }
+ if (middle == 0)
+ *p++ |= startmask & endmask;
+ else {
+ *p++ |= startmask;
+ while (--middle > 0)
+ *p++ = (char)ALLONES;
+ *p |= endmask;
+ }
+}
+
+#define CAPABILITIES (CAP_MATRIX | CAP_CHARSUBSETTING)
+
+static FontRendererRec renderers[] = {
+ { ".pfa", 4, NULL, Type1OpenScalable,
+ NULL, Type1GetInfoScalable, 0, CAPABILITIES },
+ { ".pfb", 4, NULL, Type1OpenScalable,
+ NULL, Type1GetInfoScalable, 0, CAPABILITIES }
+};
+
+void
+Type1RegisterFontFileFunctions(void)
+{
+ int i;
+
+ T1InitStdProps();
+ for (i=0; i < sizeof(renderers) / sizeof(FontRendererRec); i++)
+ FontFilePriorityRegisterRenderer(&renderers[i], -10);
+}
diff --git a/libXfont/src/Type1/t1hdigit.h b/libXfont/src/Type1/t1hdigit.h
new file mode 100644
index 000000000..e05f0de5d
--- /dev/null
+++ b/libXfont/src/Type1/t1hdigit.h
@@ -0,0 +1,40 @@
+/* $Xorg: t1hdigit.h,v 1.3 2000/08/17 19:46:33 cpqbld Exp $ */
+/* Copyright International Business Machines,Corp. 1991
+ * All Rights Reserved
+ *
+ * License to use, copy, modify, and distribute this software
+ * and its documentation for any purpose and without fee is
+ * hereby granted, provided that the above copyright notice
+ * appear in all copies and that both that copyright notice and
+ * this permission notice appear in supporting documentation,
+ * and that the name of IBM not be used in advertising or
+ * publicity pertaining to distribution of the software without
+ * specific, written prior permission.
+ *
+ * IBM PROVIDES THIS SOFTWARE "AS IS", WITHOUT ANY WARRANTIES
+ * OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING, BUT NOT
+ * LIMITED TO ANY IMPLIED WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE, AND NONINFRINGEMENT OF
+ * THIRD PARTY RIGHTS. THE ENTIRE RISK AS TO THE QUALITY AND
+ * PERFORMANCE OF THE SOFTWARE, INCLUDING ANY DUTY TO SUPPORT
+ * OR MAINTAIN, BELONGS TO THE LICENSEE. SHOULD ANY PORTION OF
+ * THE SOFTWARE PROVE DEFECTIVE, THE LICENSEE (NOT IBM) ASSUMES
+ * THE ENTIRE COST OF ALL SERVICING, REPAIR AND CORRECTION. IN
+ * NO EVENT SHALL IBM BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING
+ * FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF
+ * CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
+ * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+ * SOFTWARE.
+ */
+/* Indicators for special characters in the p_hdigit.h tables */
+#define HERROR (0xfe)
+#define HWHITE_SPACE (0xfd)
+#define HRIGHT_ANGLE (0xfc)
+#define LAST_HDIGIT (0xf0)
+
+/* Declarations for the tables */
+#define HighHexP (HighHex+1)
+extern unsigned char HighHex[];
+#define LowHexP (LowHex+1)
+extern unsigned char LowHex[];
diff --git a/libXfont/src/Type1/t1imager.h b/libXfont/src/Type1/t1imager.h
new file mode 100644
index 000000000..9730f9a47
--- /dev/null
+++ b/libXfont/src/Type1/t1imager.h
@@ -0,0 +1,84 @@
+/* $Xorg: t1imager.h,v 1.3 2000/08/17 19:46:33 cpqbld Exp $ */
+/* Copyright International Business Machines,Corp. 1991
+ * All Rights Reserved
+ *
+ * License to use, copy, modify, and distribute this software
+ * and its documentation for any purpose and without fee is
+ * hereby granted, provided that the above copyright notice
+ * appear in all copies and that both that copyright notice and
+ * this permission notice appear in supporting documentation,
+ * and that the name of IBM not be used in advertising or
+ * publicity pertaining to distribution of the software without
+ * specific, written prior permission.
+ *
+ * IBM PROVIDES THIS SOFTWARE "AS IS", WITHOUT ANY WARRANTIES
+ * OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING, BUT NOT
+ * LIMITED TO ANY IMPLIED WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE, AND NONINFRINGEMENT OF
+ * THIRD PARTY RIGHTS. THE ENTIRE RISK AS TO THE QUALITY AND
+ * PERFORMANCE OF THE SOFTWARE, INCLUDING ANY DUTY TO SUPPORT
+ * OR MAINTAIN, BELONGS TO THE LICENSEE. SHOULD ANY PORTION OF
+ * THE SOFTWARE PROVE DEFECTIVE, THE LICENSEE (NOT IBM) ASSUMES
+ * THE ENTIRE COST OF ALL SERVICING, REPAIR AND CORRECTION. IN
+ * NO EVENT SHALL IBM BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING
+ * FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF
+ * CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
+ * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+ * SOFTWARE.
+ */
+/* $XFree86: xc/lib/font/Type1/t1imager.h,v 1.4 2001/01/17 19:43:23 dawes Exp $ */
+
+
+#include "objects.h"
+#include "spaces.h"
+#include "paths.h"
+#include "regions.h"
+
+typedef struct xobject *xobject;
+typedef struct segment *path;
+typedef struct region *region;
+typedef struct XYspace *XYspace;
+
+
+#ifndef NULL
+#include <stddef.h>
+#endif
+
+#ifndef TRUE
+#define TRUE 1
+#endif
+
+#ifndef FALSE
+#define FALSE 0
+#endif
+
+
+#define WINDINGRULE -2
+#define EVENODDRULE -3
+
+#define CONTINUITY 0x80 /* can be added to above rules; e.g. WINDINGRULE+CONTINUITY */
+
+
+/*
+Generic null object definition:
+*/
+#define NULLOBJECT ((xobject)NULL)
+
+/*
+Null path definition:
+*/
+#define NULLPATH NULLOBJECT
+
+/*
+Full page and null region definition:
+*/
+#define INFINITY t1_Infinity
+#ifndef NOEXTERNS
+extern region *INFINITY;
+#endif
+#define NULLREGION NULLOBJECT
+
+#define FF_PARSE_ERROR 5
+#define FF_PATH 1
+
diff --git a/libXfont/src/Type1/t1info.c b/libXfont/src/Type1/t1info.c
new file mode 100644
index 000000000..eea22b307
--- /dev/null
+++ b/libXfont/src/Type1/t1info.c
@@ -0,0 +1,496 @@
+/* $Xorg: t1info.c,v 1.4 2001/02/09 02:04:01 xorgcvs Exp $ */
+/* Copyright International Business Machines,Corp. 1991
+ * All Rights Reserved
+ *
+ * License, subject to the license given below, to use,
+ * copy, modify, and distribute this software * and its
+ * documentation for any purpose and without fee is hereby
+ * granted, provided that the above copyright notice appear
+ * in all copies and that both that copyright notice and
+ * this permission notice appear in supporting documentation,
+ * and that the name of IBM not be used in advertising or
+ * publicity pertaining to distribution of the software
+ * without specific, written prior permission.
+ *
+ * IBM PROVIDES THIS SOFTWARE "AS IS", WITHOUT ANY WARRANTIES
+ * OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING, BUT NOT
+ * LIMITED TO ANY IMPLIED WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE, AND NONINFRINGEMENT OF
+ * THIRD PARTY RIGHTS. THE ENTIRE RISK AS TO THE QUALITY AND
+ * PERFORMANCE OF THE SOFTWARE, INCLUDING ANY DUTY TO SUPPORT
+ * OR MAINTAIN, BELONGS TO THE LICENSEE. SHOULD ANY PORTION OF
+ * THE SOFTWARE PROVE DEFECTIVE, THE LICENSEE (NOT IBM) ASSUMES
+ * THE ENTIRE COST OF ALL SERVICING, REPAIR AND CORRECTION. IN
+ * NO EVENT SHALL IBM BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING
+ * FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF
+ * CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
+ * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+ * SOFTWARE.
+ *
+ * Author: Carol H. Thompson IBM Almaden Research Center
+ * Modeled on spinfo.c by Dave Lemke, Network Computing Devices, Inc
+ * which contains the following copyright and permission notices:
+ *
+ * Copyright 1990, 1991 Network Computing Devices;
+ * Portions Copyright 1987 by Digital Equipment Corporation
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the names of Network Computing Devices or Digital
+ * not be used in advertising or publicity pertaining to distribution of the
+ * software without specific, written prior permission. Network Computing
+ * Devices and Digital make no representations about the suitability of this
+ * software for any purpose. It is provided "as is" without express or
+ * implied warranty.
+ *
+ * NETWORK COMPUTING DEVICES AND DIGITAL DISCLAIM ALL WARRANTIES WITH
+ * REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS, IN NO EVENT SHALL NETWORK COMPUTING DEVICES OR DIGITAL BE
+ * LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/*
+
+Copyright 1987, 1998 The Open Group
+
+Permission to use, copy, modify, distribute, and sell this software and its
+documentation for any purpose is hereby granted without fee, provided that
+the above copyright notice appear in all copies and that both that
+copyright notice and this permission notice appear in supporting
+documentation.
+
+The above copyright notice and this permission notice shall be included
+in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+IN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR
+OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of The Open Group shall
+not be used in advertising or otherwise to promote the sale, use or
+other dealings in this Software without prior written authorization
+from The Open Group.
+
+*/
+/* $XFree86: xc/lib/font/Type1/t1info.c,v 1.18tsi Exp $ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <X11/fonts/fntfilst.h>
+#include <X11/fonts/fontutil.h>
+#ifndef FONTMODULE
+#include <stdio.h>
+#include <math.h>
+#else
+#include "xf86_ansic.h"
+#endif
+#include <X11/fonts/FSproto.h>
+
+#include "objects.h"
+#include "spaces.h"
+#include "fontfcn.h"
+
+#include "t1intf.h"
+
+#define DECIPOINTSPERINCH 722.7
+#define DEFAULTRES 75
+#define DEFAULTPOINTSIZE 120
+
+enum scaleType {
+ atom, truncate_atom, pixel_size, point_size, resolution_x,
+ resolution_y, average_width
+};
+
+typedef struct _fontProp {
+ char *name;
+ long atom;
+ enum scaleType type;
+} fontProp;
+
+static fontProp fontNamePropTable[] = { /* Example: */
+ { "FOUNDRY", 0, atom }, /* adobe */
+ { "FAMILY_NAME", 0, atom }, /* times roman */
+ { "WEIGHT_NAME", 0, atom }, /* bold */
+ { "SLANT", 0, atom }, /* i */
+ { "SETWIDTH_NAME", 0, atom }, /* normal */
+ { "ADD_STYLE_NAME", 0, atom }, /* */
+ { "PIXEL_SIZE", 0, pixel_size }, /* 18 */
+ { "POINT_SIZE", 0, point_size }, /* 180 */
+ { "RESOLUTION_X", 0, resolution_x }, /* 72 */
+ { "RESOLUTION_Y", 0, resolution_y }, /* 72 */
+ { "SPACING", 0, atom }, /* p */
+ { "AVERAGE_WIDTH", 0, average_width }, /* 0 */
+ { "CHARSET_REGISTRY", 0, atom }, /* ISO8859 */
+ { "CHARSET_ENCODING", 0, truncate_atom } /* 1 */
+};
+
+/* NOTICE: Following array is closely related to the sequence of defines
+ following it. */
+static fontProp extraProps[] = {
+ { "FONT", 0, },
+ { "COPYRIGHT", 0, },
+ { "RAW_PIXEL_SIZE", 0, },
+ { "RAW_POINT_SIZE", 0, },
+ { "RAW_ASCENT", 0, },
+ { "RAW_DESCENT", 0, },
+ { "RAW_AVERAGE_WIDTH", 0, },
+ { "FACE_NAME", 0, },
+ { "FONT_TYPE", 0, },
+ { "RASTERIZER_NAME", 0, }
+};
+
+/* this is a bit kludgy */
+#define FONTPROP 0
+#define COPYRIGHTPROP 1
+#define RAWPIXELPROP 2
+#define RAWPOINTPROP 3
+#define RAWASCENTPROP 4
+#define RAWDESCENTPROP 5
+#define RAWWIDTHPROP 6
+#define FACE_NAMEPROP 7
+#define FONT_TYPEPROP 8
+#define RASTERIZER_NAMEPROP 9
+
+#define NNAMEPROPS (sizeof(fontNamePropTable) / sizeof(fontProp))
+#define NEXTRAPROPS (sizeof(extraProps) / sizeof(fontProp))
+
+#define NPROPS (NNAMEPROPS + NEXTRAPROPS)
+
+/*ARGSUSED*/
+static void
+FillHeader(FontInfoPtr pInfo, FontScalablePtr Vals)
+{
+ /* OpenScalable in T1FUNCS sets the following:
+ pInfo->firstCol,
+ pInfo->firstRow,
+ pInfo->lastCol, and
+ pInfo->lastRow. */
+ /* the following are ununsed
+ pInfo->pad. */
+
+ /* Items we should handle better someday +++ */
+ pInfo->defaultCh = 0;
+ pInfo->drawDirection = LeftToRight;
+ if (Vals->point_matrix[0] == Vals->point_matrix[3])
+ pInfo->anamorphic = 0;
+ else
+ pInfo->anamorphic = 1;
+ pInfo->inkMetrics = 0; /* no ink metrics here */
+ pInfo->cachable = 1; /* no licensing (yet) */
+}
+
+static void
+adjust_min_max(xCharInfo *minc, xCharInfo *maxc, xCharInfo *tmp)
+{
+#define MINMAX(field,ci) \
+ if (minc->field > (ci)->field) \
+ minc->field = (ci)->field; \
+ if (maxc->field < (ci)->field) \
+ maxc->field = (ci)->field;
+
+ MINMAX(ascent, tmp);
+ MINMAX(descent, tmp);
+ MINMAX(leftSideBearing, tmp);
+ MINMAX(rightSideBearing, tmp);
+ MINMAX(characterWidth, tmp);
+
+ /* Do MINMAX for attributes field. Since that field is CARD16,
+ we'll cast to a signed integer */
+ if ((INT16)minc->attributes > (INT16)tmp->attributes)
+ minc->attributes = tmp->attributes;
+ if ((INT16)maxc->attributes < (INT16)tmp->attributes)
+ maxc->attributes = tmp->attributes;
+
+#undef MINMAX
+}
+
+static void
+ComputeBounds(FontInfoPtr pInfo, CharInfoPtr pChars, FontScalablePtr Vals)
+{
+ int i;
+ xCharInfo minchar, maxchar;
+ int numchars = 0;
+ int totchars;
+ int overlap;
+ int maxlap;
+
+ minchar.ascent = minchar.descent =
+ minchar.leftSideBearing = minchar.rightSideBearing =
+ minchar.characterWidth = minchar.attributes = 32767;
+ maxchar.ascent = maxchar.descent =
+ maxchar.leftSideBearing = maxchar.rightSideBearing =
+ maxchar.characterWidth = maxchar.attributes = -32767;
+
+ maxlap = -32767;
+ totchars = pInfo->lastCol - pInfo->firstCol + 1;
+ pChars += pInfo->firstCol;
+ pInfo->allExist = 1;
+ for (i = 0; i < totchars; i++,pChars++) {
+ xCharInfo *pmetrics = &pChars->metrics;
+
+ if (pmetrics->attributes ||
+ pmetrics->ascent != -pmetrics->descent ||
+ pmetrics->leftSideBearing != pmetrics->rightSideBearing) {
+ numchars++;
+ adjust_min_max(&minchar, &maxchar, pmetrics);
+ overlap = pmetrics->rightSideBearing - pmetrics->characterWidth;
+ if (overlap > maxlap) maxlap = overlap;
+ }
+ else pInfo->allExist = 0;
+ }
+
+ /* If we're monospaced, round the average width field to the
+ nearest pixel */
+ if (minchar.characterWidth == maxchar.characterWidth)
+ Vals->width = minchar.characterWidth * 10;
+
+ pInfo->maxbounds = maxchar;
+ pInfo->minbounds = minchar;
+ pInfo->ink_maxbounds = maxchar;
+ pInfo->ink_minbounds = minchar;
+ pInfo->maxOverlap = maxlap + -(minchar.leftSideBearing);
+
+ /* Set the pInfo flags */
+ /* Properties set by FontComputeInfoAccelerators:
+ pInfo->noOverlap;
+ pInfo->terminalFont;
+ pInfo->constantMetrics;
+ pInfo->constantWidth;
+ pInfo->inkInside;
+
+ */
+ FontComputeInfoAccelerators (pInfo);
+}
+
+static void
+ComputeProps(FontInfoPtr pInfo, FontScalablePtr Vals, char *Filename,
+ long *sAscent, long *sDescent)
+{
+ int infoint;
+ int infoBBox[4];
+ int rc;
+
+ QueryFontLib(Filename, "isFixedPitch", &infoint, &rc);
+ if (!rc) {
+ pInfo->constantWidth = infoint;
+ }
+ QueryFontLib((char *)0, "FontBBox", infoBBox, &rc);
+ if (!rc) {
+ pInfo->fontAscent =
+ (int)((double)infoBBox[3] * Vals->pixel_matrix[3] +
+ (infoBBox[3] > 0 ? 500 : -500)) / 1000;
+ pInfo->fontDescent =
+ -(int)((double)infoBBox[1] * Vals->pixel_matrix[3] +
+ (infoBBox[1] > 0 ? 500 : -500)) / 1000;
+ *sAscent = infoBBox[3];
+ *sDescent = -infoBBox[1];
+ }
+}
+
+static void
+ComputeStdProps(FontInfoPtr pInfo, FontScalablePtr Vals,
+ char *Filename, char *Fontname,
+ long sAscent, long sDescent, long sWidth)
+{
+ FontPropPtr pp;
+ int i,
+ nprops;
+ fontProp *fpt;
+ char *is_str;
+ char *ptr1 = NULL,
+ *ptr2;
+ char *ptr3;
+ char *infostrP;
+ int rc;
+ char scaledName[MAXFONTNAMELEN];
+
+ strcpy (scaledName, Fontname);
+ /* Fill in our copy of the fontname from the Vals structure */
+ FontParseXLFDName (scaledName, Vals, FONT_XLFD_REPLACE_VALUE);
+
+ /* This form of the properties is used by the X-client; the X-server
+ doesn't care what they are. */
+ nprops = pInfo->nprops = NPROPS;
+ pInfo->isStringProp = (char *) xalloc(sizeof(char) * nprops);
+ pInfo->props = (FontPropPtr) xalloc(sizeof(FontPropRec) * nprops);
+ if (!pInfo->isStringProp || !pInfo->props) {
+ xfree(pInfo->isStringProp);
+ pInfo->isStringProp = (char *) 0;
+ xfree(pInfo->props);
+ pInfo->props = (FontPropPtr) 0;
+ return;
+ }
+ bzero(pInfo->isStringProp, (sizeof(char) * nprops));
+
+ ptr2 = scaledName;
+ for (i = NNAMEPROPS, pp = pInfo->props, fpt = fontNamePropTable, is_str = pInfo->isStringProp;
+ i;
+ i--, pp++, fpt++, is_str++) {
+
+ if (*ptr2)
+ {
+ ptr1 = ptr2 + 1;
+ if (!(ptr2 = strchr(ptr1, '-'))) ptr2 = strchr(ptr1, '\0');
+ }
+
+ pp->name = fpt->atom;
+ switch (fpt->type) {
+ case atom: /* Just copy info from scaledName */
+ *is_str = TRUE;
+ pp->value = MakeAtom(ptr1, ptr2 - ptr1, TRUE);
+ break;
+ case truncate_atom:
+ *is_str = TRUE;
+ for (ptr3 = ptr1; *ptr3; ptr3++)
+ if (*ptr3 == '[')
+ break;
+ pp->value = MakeAtom(ptr1, ptr3 - ptr1, TRUE);
+ break;
+ case pixel_size:
+ pp->value = (int)(fabs(Vals->pixel_matrix[3]) + .5);
+ break;
+ case point_size:
+ pp->value = (int)(fabs(Vals->point_matrix[3]) * 10.0 + .5);
+ break;
+ case resolution_x:
+ pp->value = Vals->x;
+ break;
+ case resolution_y:
+ pp->value = Vals->y;
+ break;
+ case average_width:
+ pp->value = Vals->width;
+ break;
+ }
+ }
+
+ for (i = 0, fpt = extraProps;
+ i < NEXTRAPROPS;
+ i++, is_str++, pp++, fpt++) {
+ pp->name = fpt->atom;
+ switch (i) {
+ case FONTPROP:
+ *is_str = TRUE;
+ pp->value = MakeAtom(scaledName, strlen(scaledName), TRUE);
+ break;
+ case COPYRIGHTPROP:
+ *is_str = TRUE;
+ QueryFontLib(Filename, "Notice", &infostrP, &rc);
+ if (rc || !infostrP) {
+ infostrP = "Copyright Notice not available";
+ }
+ pp->value = MakeAtom(infostrP, strlen(infostrP), TRUE);
+ break;
+ case FACE_NAMEPROP:
+ *is_str = TRUE;
+ QueryFontLib(Filename, "FontName", &infostrP, &rc);
+ if (rc || !infostrP) {
+ infostrP = "(unknown)";
+ }
+ pp->value = MakeAtom(infostrP, strlen(infostrP), TRUE);
+ break;
+ case FONT_TYPEPROP:
+ *is_str = TRUE;
+ infostrP = "Type 1";
+ pp->value = MakeAtom(infostrP, strlen(infostrP), TRUE);
+ break;
+ case RASTERIZER_NAMEPROP:
+ *is_str = TRUE;
+ infostrP = "X Consortium Type 1 Rasterizer";
+ pp->value = MakeAtom(infostrP, strlen(infostrP), TRUE);
+ break;
+ case RAWPIXELPROP:
+ *is_str = FALSE;
+ pp->value = 1000;
+ break;
+ case RAWPOINTPROP:
+ *is_str = FALSE;
+ pp->value = (long)(72270.0 / (double)Vals->y + .5);
+ break;
+ case RAWASCENTPROP:
+ *is_str = FALSE;
+ pp->value = sAscent;
+ break;
+ case RAWDESCENTPROP:
+ *is_str = FALSE;
+ pp->value = sDescent;
+ break;
+ case RAWWIDTHPROP:
+ *is_str = FALSE;
+ pp->value = sWidth;
+ break;
+ }
+ }
+}
+
+/*ARGSUSED*/
+int
+Type1GetInfoScalable(FontPathElementPtr fpe,
+ FontInfoPtr pInfo,
+ FontEntryPtr entry,
+ FontNamePtr fontName,
+ char *fileName,
+ FontScalablePtr Vals)
+{
+ FontPtr pfont;
+ int flags = 0;
+ long format = 0; /* It doesn't matter what format for just info */
+ long fmask = 0;
+ int ret;
+
+ ret = Type1OpenScalable(fpe, &pfont, flags, entry, fileName, Vals,
+ format, fmask , NULL);
+ if (ret != Successful)
+ return ret;
+ *pInfo = pfont->info;
+
+ /* XXX - Set pointers in pfont->info to NULL so they are not freed. */
+ pfont->info.props = NULL;
+ pfont->info.isStringProp = NULL;
+
+ Type1CloseFont(pfont);
+ return Successful;
+}
+
+void
+T1FillFontInfo(FontPtr pFont, FontScalablePtr Vals,
+ char *Filename, char *Fontname, long sWidth)
+{
+ FontInfoPtr pInfo = &pFont->info;
+ struct type1font *p = (struct type1font *)pFont->fontPrivate;
+ long sAscent = 0, sDescent = 0; /* Scalable 1000-pixel values */
+
+ FillHeader(pInfo, Vals);
+
+ ComputeBounds(pInfo, p->glyphs, Vals);
+
+ ComputeProps(pInfo, Vals, Filename, &sAscent, &sDescent);
+ ComputeStdProps(pInfo, Vals, Filename, Fontname, sAscent, sDescent, sWidth);
+}
+
+/* Called once, at renderer registration time */
+void
+T1InitStdProps(void)
+{
+ int i;
+ fontProp *t;
+
+ i = sizeof(fontNamePropTable) / sizeof(fontProp);
+ for (t = fontNamePropTable; i; i--, t++)
+ t->atom = MakeAtom(t->name, (unsigned) strlen(t->name), TRUE);
+ i = sizeof(extraProps) / sizeof(fontProp);
+ for (t = extraProps; i; i--, t++)
+ t->atom = MakeAtom(t->name, (unsigned) strlen(t->name), TRUE);
+}
diff --git a/libXfont/src/Type1/t1intf.h b/libXfont/src/Type1/t1intf.h
new file mode 100644
index 000000000..371908090
--- /dev/null
+++ b/libXfont/src/Type1/t1intf.h
@@ -0,0 +1,54 @@
+/* $Xorg: t1intf.h,v 1.3 2000/08/17 19:46:33 cpqbld Exp $ */
+/* Copyright International Business Machines,Corp. 1991
+ * All Rights Reserved
+ *
+ * License to use, copy, modify, and distribute this software
+ * and its documentation for any purpose and without fee is
+ * hereby granted, provided that the above copyright notice
+ * appear in all copies and that both that copyright notice and
+ * this permission notice appear in supporting documentation,
+ * and that the name of IBM not be used in advertising or
+ * publicity pertaining to distribution of the software without
+ * specific, written prior permission.
+ *
+ * IBM PROVIDES THIS SOFTWARE "AS IS", WITHOUT ANY WARRANTIES
+ * OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING, BUT NOT
+ * LIMITED TO ANY IMPLIED WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE, AND NONINFRINGEMENT OF
+ * THIRD PARTY RIGHTS. THE ENTIRE RISK AS TO THE QUALITY AND
+ * PERFORMANCE OF THE SOFTWARE, INCLUDING ANY DUTY TO SUPPORT
+ * OR MAINTAIN, BELONGS TO THE LICENSEE. SHOULD ANY PORTION OF
+ * THE SOFTWARE PROVE DEFECTIVE, THE LICENSEE (NOT IBM) ASSUMES
+ * THE ENTIRE COST OF ALL SERVICING, REPAIR AND CORRECTION. IN
+ * NO EVENT SHALL IBM BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING
+ * FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF
+ * CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
+ * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+ * SOFTWARE.
+ */
+/* $XFree86: xc/lib/font/Type1/t1intf.h,v 1.6 2001/01/17 19:43:23 dawes Exp $ */
+
+struct type1font {
+ CharInfoPtr pDefault;
+ CharInfoRec glyphs[256];
+};
+
+/*
+ * Function prototypes
+ */
+/* t1funcs.c */
+extern int Type1OpenScalable ( FontPathElementPtr fpe, FontPtr *ppFont,
+ int flags, FontEntryPtr entry, char *fileName,
+ FontScalablePtr vals, fsBitmapFormat format,
+ fsBitmapFormatMask fmask,
+ FontPtr non_cachable_font );
+extern void Type1CloseFont ( FontPtr pFont );
+
+/* t1info.c */
+extern int Type1GetInfoScalable ( FontPathElementPtr fpe, FontInfoPtr pInfo,
+ FontEntryPtr entry, FontNamePtr fontName,
+ char *fileName, FontScalablePtr Vals );
+extern void T1FillFontInfo ( FontPtr pFont, FontScalablePtr Vals,
+ char *Filename, char *Fontname, long sWidth );
+extern void Type1InitStdProps ( void );
diff --git a/libXfont/src/Type1/t1io.c b/libXfont/src/Type1/t1io.c
new file mode 100644
index 000000000..ba2e580f8
--- /dev/null
+++ b/libXfont/src/Type1/t1io.c
@@ -0,0 +1,299 @@
+/* $Xorg: t1io.c,v 1.3 2000/08/17 19:46:33 cpqbld Exp $ */
+/* Copyright International Business Machines,Corp. 1991
+ * All Rights Reserved
+ *
+ * License to use, copy, modify, and distribute this software
+ * and its documentation for any purpose and without fee is
+ * hereby granted, provided that the above copyright notice
+ * appear in all copies and that both that copyright notice and
+ * this permission notice appear in supporting documentation,
+ * and that the name of IBM not be used in advertising or
+ * publicity pertaining to distribution of the software without
+ * specific, written prior permission.
+ *
+ * IBM PROVIDES THIS SOFTWARE "AS IS", WITHOUT ANY WARRANTIES
+ * OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING, BUT NOT
+ * LIMITED TO ANY IMPLIED WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE, AND NONINFRINGEMENT OF
+ * THIRD PARTY RIGHTS. THE ENTIRE RISK AS TO THE QUALITY AND
+ * PERFORMANCE OF THE SOFTWARE, INCLUDING ANY DUTY TO SUPPORT
+ * OR MAINTAIN, BELONGS TO THE LICENSEE. SHOULD ANY PORTION OF
+ * THE SOFTWARE PROVE DEFECTIVE, THE LICENSEE (NOT IBM) ASSUMES
+ * THE ENTIRE COST OF ALL SERVICING, REPAIR AND CORRECTION. IN
+ * NO EVENT SHALL IBM BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING
+ * FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF
+ * CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
+ * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+ * SOFTWARE.
+ * Author: Carol H. Thompson IBM Almaden Research Center
+ */
+/* $XFree86: xc/lib/font/Type1/t1io.c,v 3.8 2001/01/17 19:43:23 dawes Exp $ */
+/*******************************************************************
+* I/O package for Type 1 font reading
+********************************************************************/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#ifndef STATIC
+#define STATIC static
+#endif
+
+#ifndef FONTMODULE
+#include <fcntl.h>
+#include <unistd.h>
+#else
+#include "Xdefs.h"
+#include "Xmd.h" /* INT32 declaration */
+#include "xf86_ansic.h"
+#endif
+#include "t1stdio.h"
+#include "t1hdigit.h"
+#ifdef WIN32
+#include <X11/Xw32defs.h>
+#endif
+#include <X11/Xdefs.h>
+
+/* Constants and variables used in the decryption */
+#define c1 ((unsigned short)52845)
+#define c2 ((unsigned short)22719)
+static unsigned short r;
+static int asc, Decrypt;
+static int extrach;
+static int haveextrach;
+
+/* Our single FILE structure and buffer for this package */
+STATIC F_FILE TheFile;
+STATIC unsigned char TheBuffer[F_BUFSIZ];
+
+/* Our routines */
+static int T1Decrypt ( unsigned char *p, int len );
+static int T1Fill ( F_FILE *f );
+
+/* -------------------------------------------------------------- */
+/*ARGSUSED*/
+F_FILE *
+T1Open(char *fn, /* Pointer to filename */
+ char *mode) /* Pointer to open mode string */
+{
+ F_FILE *of = &TheFile;
+ int oflags = O_RDONLY; /* We know we are only reading */
+
+ Decrypt = 0;
+
+#ifdef O_BINARY /* VMS or DOS */
+ oflags |= O_BINARY;
+#endif
+ of->fd = open(fn, oflags, 0);
+ if (of->fd < 0)
+ return NULL;
+
+ /* Initialize the buffer information of our file descriptor */
+ of->b_base = TheBuffer;
+ of->b_size = F_BUFSIZ;
+ of->b_ptr = NULL;
+ of->b_cnt = 0;
+ of->flags = 0;
+ of->error = 0;
+ haveextrach = 0;
+ return &TheFile;
+} /* end Open */
+
+/* -------------------------------------------------------------- */
+int /* Read one character */
+T1Getc(F_FILE *f) /* Stream descriptor */
+{
+ if (f->b_base == NULL) return EOF; /* already closed */
+
+ if (f->flags & UNGOTTENC) { /* there is an ungotten c */
+ f->flags &= ~UNGOTTENC;
+ return (int) f->ungotc;
+ }
+
+ if (f->b_cnt == 0) /* Buffer needs to be (re)filled */
+ f->b_cnt = T1Fill(f);
+ if (f->b_cnt > 0) return (f->b_cnt--, (int) *(f->b_ptr++));
+ else {
+ f->flags |= FIOEOF;
+ return EOF;
+ }
+} /* end Getc */
+
+/* -------------------------------------------------------------- */
+int /* Put back one character */
+T1Ungetc(int c,
+ F_FILE *f) /* Stream descriptor */
+{
+ if (c != EOF) {
+ f->ungotc = c;
+ f->flags |= UNGOTTENC; /* set flag */
+ f->flags &= ~FIOEOF; /* reset EOF */
+ }
+ return c;
+} /* end Ungetc */
+
+/* -------------------------------------------------------------- */
+int /* Read n items into caller's buffer */
+T1Read(char *buffP, /* Buffer to be filled */
+ int size, /* Size of each item */
+ int n, /* Number of items to read */
+ F_FILE *f) /* Stream descriptor */
+{
+ int bytelen, cnt, i;
+ F_char *p = (F_char *)buffP;
+ int icnt; /* Number of characters to read */
+
+ if (f->b_base == NULL) return 0; /* closed */
+ icnt = (size!=1)?n*size:n; /* Number of bytes we want */
+
+ if (f->flags & UNGOTTENC) { /* there is an ungotten c */
+ f->flags &= ~UNGOTTENC;
+ *(p++) = f->ungotc;
+ icnt--; bytelen = 1;
+ }
+ else bytelen = 0;
+
+ while (icnt > 0) {
+ /* First use any bytes we have buffered in the stream buffer */
+ if ((cnt=f->b_cnt) > 0) {
+ if (cnt > icnt) cnt = icnt;
+ for (i=0; i<cnt; i++) *(p++) = *(f->b_ptr++);
+ f->b_cnt -= cnt;
+ icnt -= cnt;
+ bytelen += cnt;
+ }
+
+ if ((icnt == 0) || (f->flags & FIOEOF)) break;
+
+ f->b_cnt = T1Fill(f);
+ }
+ return ((size!=1)?bytelen/size:bytelen);
+} /* end Read */
+
+/* -------------------------------------------------------------- */
+int /* Close the file */
+T1Close(F_FILE *f) /* Stream descriptor */
+{
+ if (f->b_base == NULL) return 0; /* already closed */
+ f->b_base = NULL; /* no valid stream */
+ return close(f->fd);
+} /* end Close */
+
+
+/* -------------------------------------------------------------- */
+F_FILE * /* Initialization */
+T1eexec(F_FILE *f) /* Stream descriptor */
+{
+ int i, c;
+ int H;
+ unsigned char *p;
+ unsigned char randomP[8];
+
+ r = 55665; /* initial key */
+ asc = 1; /* indicate ASCII form */
+
+ /* Consume the 4 random bytes, determining if we are also to
+ ASCIIDecodeHex as we process our input. (See pages 63-64
+ of the Adobe Type 1 Font Format book.) */
+
+ /* Skip over any initial white space chars */
+ while (HighHexP[c=_XT1getc(f)] == HWHITE_SPACE) ;
+
+ /* If ASCII, the next 7 chars are guaranteed consecutive */
+ randomP[0] = c; /* store first non white space char */
+ T1Read((pointer)(randomP+1), 1, 3, f); /* read 3 more, for a total of 4 */
+ /* store first four chars */
+ for (i=0,p=randomP; i<4; i++) { /* Check 4 valid ASCIIEncode chars */
+ if (HighHexP[*p++] > LAST_HDIGIT) { /* non-ASCII byte */
+ asc = 0;
+ break;
+ }
+ }
+ if (asc) { /* ASCII form, convert first eight bytes to binary */
+ T1Read((pointer)(randomP+4), 1, 4, f); /* Need four more */
+ for (i=0,p=randomP; i<4; i++) { /* Convert */
+ H = HighHexP[*p++];
+ randomP[i] = H | LowHexP[*p++];
+ }
+ }
+
+ /* Adjust our key */
+ for (i=0,p=randomP; i<4; i++) {
+ r = (*p++ + r) * c1 + c2;
+ }
+
+ /* Decrypt the remaining buffered bytes */
+ f->b_cnt = T1Decrypt(f->b_ptr, f->b_cnt);
+ Decrypt = 1;
+ return (T1Feof(f))?NULL:f;
+} /* end eexec */
+
+/* -------------------------------------------------------------- */
+STATIC int
+T1Decrypt(unsigned char *p, int len)
+{
+ int n;
+ int H = 0, L;
+ unsigned char *inp = p;
+ unsigned char *tblP;
+
+ if (asc) {
+ if (haveextrach) {
+ H = extrach;
+ tblP = LowHexP;
+ }
+ else tblP = HighHexP;
+ for (n=0; len>0; len--) {
+ L = tblP[*inp++];
+ if (L == HWHITE_SPACE) continue;
+ if (L > LAST_HDIGIT) break;
+ if (tblP == HighHexP) { /* Got first hexit value */
+ H = L;
+ tblP = LowHexP;
+ } else { /* Got second hexit value; compute value and store it */
+ n++;
+ tblP = HighHexP;
+ H |= L;
+ /* H is an int, 0 <= H <= 255, so all of this will work */
+ *p++ = H ^ (r >> 8);
+ r = (H + r) * c1 + c2;
+ }
+ }
+ if (tblP != HighHexP) { /* We had an odd number of hexits */
+ extrach = H;
+ haveextrach = 1;
+ } else haveextrach = 0;
+ return n;
+ } else {
+ for (n = len; n>0; n--) {
+ H = *inp++;
+ *p++ = H ^ (r >> 8);
+ r = (H + r) * c1 + c2;
+ }
+ return len;
+ }
+} /* end Decrypt */
+
+/* -------------------------------------------------------------- */
+STATIC int /* Refill stream buffer */
+T1Fill(F_FILE *f) /* Stream descriptor */
+{
+ int rc;
+
+ rc = read(f->fd, f->b_base, F_BUFSIZ);
+ /* propagate any error or eof to current file */
+ if (rc <= 0) {
+ if (rc == 0) /* means EOF */
+ f->flags |= FIOEOF;
+ else {
+ f->error = (short)-rc;
+ f->flags |= FIOERROR;
+ rc = 0;
+ }
+ }
+ f->b_ptr = f->b_base;
+ if (Decrypt) rc = T1Decrypt(f->b_base, rc);
+ return rc;
+} /* end Fill */
diff --git a/libXfont/src/Type1/t1malloc.c b/libXfont/src/Type1/t1malloc.c
new file mode 100644
index 000000000..df863a234
--- /dev/null
+++ b/libXfont/src/Type1/t1malloc.c
@@ -0,0 +1,759 @@
+/* $Xorg: t1malloc.c,v 1.3 2000/08/17 19:46:34 cpqbld Exp $ */
+/* Copyright International Business Machines, Corp. 1991
+ * All Rights Reserved
+ * Copyright Lexmark International, Inc. 1991
+ * All Rights Reserved
+ *
+ * License to use, copy, modify, and distribute this software and its
+ * documentation for any purpose and without fee is hereby granted,
+ * provided that the above copyright notice appear in all copies and that
+ * both that copyright notice and this permission notice appear in
+ * supporting documentation, and that the name of IBM or Lexmark not be
+ * used in advertising or publicity pertaining to distribution of the
+ * software without specific, written prior permission.
+ *
+ * IBM AND LEXMARK PROVIDE THIS SOFTWARE "AS IS", WITHOUT ANY WARRANTIES OF
+ * ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING, BUT NOT LIMITED TO ANY
+ * IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE,
+ * AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. THE ENTIRE RISK AS TO THE
+ * QUALITY AND PERFORMANCE OF THE SOFTWARE, INCLUDING ANY DUTY TO SUPPORT
+ * OR MAINTAIN, BELONGS TO THE LICENSEE. SHOULD ANY PORTION OF THE
+ * SOFTWARE PROVE DEFECTIVE, THE LICENSEE (NOT IBM OR LEXMARK) ASSUMES THE
+ * ENTIRE COST OF ALL SERVICING, REPAIR AND CORRECTION. IN NO EVENT SHALL
+ * IBM OR LEXMARK BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
+ * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
+ * THIS SOFTWARE.
+ */
+/* $XFree86: xc/lib/font/Type1/t1malloc.c,v 1.11 2002/02/18 20:51:57 herrb Exp $ */
+ /* MALLOC CWEB V0004 LOTS */
+/*
+:h1.MALLOC - Fast Memory Allocation
+
+This module is meant to provide portable C-style memory allocation
+routines (malloc/free).
+
+&author. Jeffrey B. Lotspiech (lotspiech@almaden.ibm.com)
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#ifndef FONTMODULE
+#include <stdio.h>
+#else
+#include "Xdefs.h" /* Bool declaration */
+#include "Xmd.h" /* INT32 declaration */
+#include "os.h"
+#include "xf86_ansic.h"
+#endif
+#include "objects.h" /* get #define for Abort() */
+
+
+/*
+:h3.Define NULL
+
+In the beginning, C compilers made no assumptions about NULL. It was
+even theoretically possible that NULL would not be 0. ANSI has tied
+this down a bit. The following definition seems to be the most
+popular (in terms of reducing compiler complaints), however, if your
+compiler is unhappy about it, you can redefine it on the command line:
+*/
+#ifndef NULL
+#include <stddef.h>
+#endif
+/*
+Of course, NULL is important because xiMalloc() is defined to return
+NULL when out of memory.
+
+:h2.Data Structures Used to Manage Free Memory
+
+:h3.The "freeblock" Structure
+
+The list of available memory blocks is a doubly-linked list. Each
+block begins with the following structure:
+*/
+
+struct freeblock {
+ long size; /* number of 'longs' in block,
+ including this header */
+ struct freeblock *fore; /* forward in doubly-linked list */
+ struct freeblock *back; /* backward in doubly-linked list */
+} ;
+/*
+In addition, each free block has a TRAILER that is simply the 'size'
+repeated. Thus 'size' is found at the beginning of the block and at the
+end of the block (size-1 longs away). 'size' includes both the header
+and the trailer.
+
+When a block is allocated, its 'size' is turned negative (both at the
+beginning and at the end). Thus, checking whether two blocks may be
+combined is very simple. We merely examine both neighboring blocks'
+size to see if they are positive (and hence available for combination).
+
+The memory address returned to the user is therefore one "long" below the
+size, and one extra "long" is added to the end of the block (beyond what
+the user requested) to store the trailing size.
+
+:h3."firstfree" and "lastfree", the Anchors to the Free List
+
+"firstfree" points to the first available free block; "lastfree" points
+to the end of the chain of available blocks. These are linked together
+by initialization code; see :hdref refid=addmem..
+*/
+
+static struct freeblock firstfree = { 0L, NULL, NULL };
+static struct freeblock lastfree = { 0L, NULL, NULL };
+
+/*
+:h3."firstcombined" and "uncombined", Keeping Track of Uncombined Blocks
+
+This module is designed to make the combining of adjacent free memory
+blocks be very fast. Nonetheless, combining blocks is naturally the
+most expensive part of any memory system. In an X system,
+it is worthwhile to defer the combination for a while, because
+frequently we will end up asking for a block of exactly the same
+size that we recently returned and we can save ourselves some work.
+
+"MAXUNCOMBINED" is the maximum number of uncombined blocks that we will
+allow at any time:
+*/
+
+#define MAXUNCOMBINED 3
+
+/*
+"firstcombined" is a pointer into the free list. The uncombined blocks
+are always at the front of the list. "firstcombined" points to the
+first block that has been combined.
+*/
+static struct freeblock *firstcombined = &lastfree;
+static short uncombined = 0; /* current number of uncombined blocks */
+
+/*
+Uncombined blocks have a negative 'size'; in this they are like
+allocated blocks.
+
+We store a distinctive hex pattern in 'size' when we combine a block
+to help us debug:
+*/
+#define COMBINED 0xBADBAD
+
+/*
+:h3.DEBUGWORDS - Extra Memory Saved With Each Block for Debug
+
+We add 'DEBUGWORDS' words to each allocated block to put interesting
+debug information:
+*/
+#ifndef DEBUGWORDS
+#define DEBUGWORDS 0
+#endif
+
+/*
+:h3.MINEXCESS - Amount of "Excess" We Would be Willing to Ignore
+
+When we search the free list to find memory for a user request, we
+frequently find an area that is bigger than what the user has asked for.
+Normally we put the remaining words (the excess) back on the free list.
+However, if the area is just slightly bigger than what the user needs,
+it is counter-productive to do this, as the small amount recovered tends
+to hurt by increasing memory fragmentation rather than help by providing
+more available memory. "MINEXCESS" is the number of words that must be
+recovered before we would bother to put the excess back on the free
+list. If there is not enough excess, we just give the user more than he
+asked for.
+*/
+
+#define MINEXCESS (7 + DEBUGWORDS)
+
+/*
+:h3.Some Flags for Debug
+*/
+
+static long AvailableWords = 0; /* number of words available in memory */
+static char mallocdebug = 0; /* a flag that enables some chatty printf's */
+
+/*
+:h3.Prototypes of static functions
+*/
+
+static void combine ( void );
+static void freeuncombinable ( long *addr, long size );
+static void unhook ( struct freeblock *p );
+static void dumpchain ( void );
+#ifdef notused
+static void reportarea ( long *area );
+#endif
+
+/*
+:h3.whocalledme() - Debug for Memory Leaks
+
+This routine is 68000-specific; it copies the value of the application's
+curOper variable (which is often a pointer to a character string), and
+the first part of the stack at the time malloc was called into the
+DEBUGWORDS area reserved with each block.
+We use it to see who is malloc-ing memory without free-ing it.
+*/
+
+#if DEBUGWORDS
+
+static void
+whocalledme(long *addr, /* address of memory block */
+ long *stack) /* address of malloc's parameter on stack */
+{
+ register long size; /* size of memory block */
+ register int i; /* loop index */
+ extern char *curOper; /* ptr to last operator (kept by appl.) */
+
+ stack--;
+ size = - *addr;
+
+ addr += size - 1 - DEBUGWORDS;
+ *addr++ = (long) curOper;
+ for (i=0; i < DEBUGWORDS-1; i++)
+ *addr++ = *stack++;
+}
+#else
+
+#define whocalledme(addr, stack)
+
+#endif
+/*
+:h2.xiFree() - User-Callable "Return Memory" Routine
+
+The actual beginning of the block is one 'long' before the address we
+gave to the user. The block begins and ends with '-size' in words.
+*/
+
+void
+xiFree(long *addr) /* user's memory to be returned */
+{
+ register long size; /* amount of memory in this block */
+ register struct freeblock *p; /* identical to 'addr' */
+
+ if (addr == NULL) { /* common "mistake", so allow it (CHT) */
+ printf("\nxiFree(NULL)?\n");
+ return;
+ }
+
+ size = *--addr;
+/*
+Make sure this address looks OK; 'size' must be less than zero (meaning
+the block is allocated) and should be repeated at the end of the block.
+*/
+ if (size >= 0)
+ Abort("free: bad size");
+ if (addr[-1 - size] != size)
+ Abort("free: mismatched size");
+/*
+Now make this a 'freeblock' structure and tack it on the FRONT of the
+free list (where uncombined blocks go):
+*/
+ AvailableWords -= size; /* actually INCREASES AvailableWords */
+ p = (struct freeblock *) addr;
+ p->back = &firstfree;
+ (p->fore = firstfree.fore)->back = p;
+ firstfree.fore = p;
+/*
+If we have too many uncombined blocks, call combine() to combine one.
+*/
+ if (++uncombined > MAXUNCOMBINED) {
+ combine();
+ if (mallocdebug) {
+ printf("xiFree(%p) with combine, ", (void *)addr);
+ dumpchain();
+ }
+ }
+ else {
+ if (mallocdebug) {
+ printf("xiFree(%p), ", (void *)addr);
+ dumpchain();
+ }
+ }
+
+ return;
+}
+
+/*
+:h3.combine() - Subroutine of xiFree() to Combine Blocks
+
+This routine tries to combine the block just before 'firstcombined'.
+In any event, that block will be moved to the end of the list (after
+'firstcombined').
+*/
+
+static void
+combine(void)
+{
+ register struct freeblock *p; /* block we will try to combine */
+ register long *addr; /* identical to 'p' for 'long' access */
+ register long size; /* size of this block */
+ register long size2; /* size of potential combinee */
+
+ p = firstcombined->back;
+ if (p == &firstfree)
+ Abort("why are we combining?");
+
+ addr = (long *) p;
+ size = - p->size;
+ if (--uncombined < 0)
+ Abort("too many combine()s");
+
+ if (addr[-1] < 0 && addr[size] < 0) {
+/*
+We special case the situation where no combining can be done. Then, we
+just mark the chain "combined" (i.e., positive size), move the
+'firstcombined' pointer back in the chain, and return.
+*/
+ addr[0] = addr[size - 1] = size;
+ firstcombined = (struct freeblock *) addr;
+ return;
+ }
+/*
+Otherwise, we unhook this pointer from the chain:
+*/
+ unhook(p);
+/*
+First we attempt to combine this with the block immediately above:
+*/
+ size2 = addr[-1];
+ if (size2 > 0) { /* i.e., block above is free */
+ *addr = COMBINED; /* might help debug */
+ addr -= size2;
+ if (addr[0] != size2)
+ Abort("bad block above");
+ unhook((struct freeblock *)addr);
+ size += size2;
+ }
+/*
+At this point 'addr' and 'size' may be the original block, or it may be
+the newly combined block. Now we attempt to combine it with the block
+below:
+*/
+ p = (struct freeblock *) (addr + size);
+ size2 = p->size;
+
+ if (size2 > 0) { /* i.e., block below is free */
+ p->size = COMBINED;
+ if (size2 != ((long *) p)[size2 - 1])
+ Abort("bad block below");
+ unhook(p);
+ size += size2;
+ }
+/*
+Finally we take the newly combined block and put it on the end of the
+chain by calling the "freeuncombinable" subroutine:
+*/
+ freeuncombinable(addr, size);
+}
+
+/*
+:h3.freeuncombinable() - Free a Block That Need Not be Combined
+
+This block is "uncombinable" either because we have already combined
+it with its eligible neighbors, or perhaps because we know it has
+no neighbors.
+*/
+
+static void
+freeuncombinable(long *addr, /* address of the block to be freed */
+ long size) /* size of block in words */
+{
+ register struct freeblock *p; /* a convenient synonym for 'addr' */
+
+/*
+Mark block allocated and combined by setting its 'size' positive:
+*/
+ addr[size - 1] = addr[0] = size;
+/*
+Now tack the block on the end of the doubly-linked free list:
+*/
+ p = (struct freeblock *) addr;
+ p->fore = &lastfree;
+ (p->back = lastfree.back)->fore = p;
+ lastfree.back = p;
+/*
+If we have previously had no combined blocks, we must update
+'firstcombined' to point to this block:
+*/
+ if (firstcombined->fore == NULL)
+ firstcombined = p;
+}
+
+/*
+:h3.unhook() - Unhook a Block from the Doubly-linked List
+
+The only tricky thing here is to make sure that 'firstcombined' is
+updated if this block happened to be the old 'firstcombined'. (We
+would never be unhooking 'firstfree' or 'lastfree', so we do not
+have to worry about the end cases.)
+*/
+
+static void
+unhook(struct freeblock *p) /* block to unhook */
+{
+ p->back->fore = p->fore;
+ p->fore->back = p->back;
+
+ if (firstcombined == p)
+ firstcombined = p->fore;
+}
+/*
+:h2.xiMalloc() - Main User Entry Point for Getting Memory
+
+We have two slightly different versions of xiMalloc(). In the case
+where we have TYPE1IMAGER and a font cache, we are prepared, when nominally
+out of memory, to loop calling TYPE1IMAGER's GimeSpace() to release font
+cache.
+*/
+
+/* The following code put in by MDC on 11/10/90 */
+
+#ifdef TYPE1IMAGER
+
+static char *malloc_local(unsigned size);
+
+char *
+xiMalloc(unsigned size)
+{
+ char *memaddr;
+
+ while ( (memaddr = malloc_local(size)) == NULL ) {
+ /* Ask TYPE1IMAGER to give us some of its cache back */
+ if ( I_GimeSpace() == 0 ) break; /* We are really, really, out of memory */
+ }
+
+ return(memaddr);
+}
+#endif
+
+/*
+Now begins the real workhorse xiMalloc() (called 'malloc_local' if
+we are taking advantage of TYPE1IMAGER). Its argument is an unsigned;
+at least that lets users with 16-bit integers get a 64K chunk of
+memory, and it is also compatible with the definition of a "size_t"
+in most systems.
+*/
+#ifdef TYPE1IMAGER
+static char *
+malloc_local(unsigned Size) /* number of bytes the user requested */
+#else
+char *
+xiMalloc(unsigned Size)
+#endif
+{
+ register long size = (long)Size; /* a working register for size */
+ register struct freeblock *p; /* tentative block to be returned */
+ register long excess; /* words in excess of user request */
+ register long *area; /* a convenient synonym for 'p' */
+
+/*
+First, we increase 'size' to allow for the two size fields we will
+save with the block, plus any information for debug purposes.
+Then we ensure that the block will be large enough to hold our
+'freeblock' information. Finally we convert it to be in words
+(longs), not bytes, increased to span an integral number of double
+words, so that all memory blocks dispensed with be properly aligned.
+*/
+ size += 2*sizeof(long) + DEBUGWORDS*sizeof(long);
+ if (size < sizeof(struct freeblock) + sizeof(long))
+ size = sizeof(struct freeblock) + sizeof(long);
+ size = ((unsigned) (size + sizeof(double) - 1) / sizeof(double)) * (sizeof(double)/sizeof(long));
+
+/*
+For speed, we will try first to give the user back a very recently
+returned block--one that is on the front of the chain before
+'firstcombined'. These blocks still have negative sizes, and need
+only to be "unhook"ed:
+*/
+ size = -size;
+ for (p=firstfree.fore; p != firstcombined; p=p->fore) {
+ if (p->size == size) {
+ unhook(p);
+ uncombined--;
+ if (mallocdebug) {
+ printf("fast xiMalloc(%ld) = %p, ", size,
+ (void *)p);
+ dumpchain();
+ }
+ AvailableWords += size; /* decreases AvailableWords */
+ whocalledme(p, &Size);
+ return((char *)&p->fore);
+ }
+ }
+/*
+Well, if we get here, there are no uncombined blocks matching the user's
+request. So, we search the rest of the chain for a block that is big
+enough. ('size' becomes positive again):
+*/
+ size = -size;
+ for (;; p = p->fore) {
+/*
+If we hit the end of the chain (p->size == 0), we are probably out of
+memory. However, we should first try to combine any memory that has
+not yet been combined before we give that pessimistic answer. If
+we succeed in combining, we can call ourselves recursively to try to
+allocate the requested amount:
+*/
+ if (p->size == 0) {
+ if (uncombined <= 0)
+ return(NULL);
+ while (firstfree.fore != firstcombined)
+ combine();
+ return(xiMalloc(sizeof(long) * (size - 2 - DEBUGWORDS)));
+ }
+/*
+Otherwise, we keep searching until we find a big enough block:
+*/
+ if (p->size >= size)
+ break;
+ }
+/*
+At this point, 'p' contains a block at least as big as what the user
+requested, so we take it off the free chain. If it is excessively big,
+we return the excess to the free chain:
+*/
+ unhook(p);
+ excess = p->size - size;
+ area = (long *) p;
+
+ if (excess > MINEXCESS)
+ freeuncombinable(area + size, excess);
+ else
+ size = p->size;
+
+ AvailableWords -= size;
+/*
+Mark first and last word of block with the negative of the size, to
+flag that this block is allocated:
+*/
+ area[size - 1] = area[0] = - size;
+
+ if (mallocdebug) {
+ printf("slow xiMalloc(%ld) @ %p, ", size, (void *)area);
+ dumpchain();
+ }
+ whocalledme(area, &Size);
+/*
+The address we return to the user is one 'long' BELOW the address of
+the block. This protects our 'size' field, so we can tell the size
+of the block when he returns it to us with xiFree(). Also, he better not
+touch the 'size' field at the end of the block either. (That would be
+nasty of him, as he would be touching memory outside of the bytes he
+requested).
+*/
+ return((char *) (area + 1));
+}
+
+/*
+:h2 id=addmem.addmemory() - Initialize Free Memory
+
+This routine should be called at initialization to initialize the
+free chain. There is no standard way to do this in C.
+We want the memory dispensed by malloc to be aligned on a double word
+boundary (because some machines either require alignment, or are
+more efficient if accesses are aligned). Since the total size of
+any block created by malloc is an integral number of double words,
+all we have to do to ensure alignment is to adjust each large block
+added to the free chain to start on an odd long-word boundary.
+(Malloc's size field will occupy the odd long and the user's memory
+will then begin on an even boundary.) Since we fill in additional
+size fields at the beginning and end of each of the large freeblocks,
+we need only adjust the address passed to addmemory to a double word
+boundary.
+*/
+
+#define MAXAREAS 10 /* there can be this many calls to addmemory() */
+
+static long *freearea[MAXAREAS] = { NULL }; /* so we can report later */
+
+void
+addmemory(long *addr, /* beginning of free area */
+ long size) /* number of bytes of free area */
+{
+ register int i; /* loop index variable */
+ register long *aaddr; /* aligned beginning of free area */
+
+#if DEBUGWORDS
+ printf("malloc has DEBUGWORDS=%d\n", DEBUGWORDS);
+#endif
+/*
+First link together firstfree and lastfree if necessary:
+*/
+ if (firstfree.fore == NULL) {
+ firstfree.fore = &lastfree;
+ lastfree.back = &firstfree;
+ }
+/*
+We'll record where the area was that was given to us for later reports:
+*/
+ for (i=0; i < MAXAREAS; i++)
+ if (freearea[i] == NULL) break;
+ if (i >= MAXAREAS)
+ Abort("too many addmemory()s");
+ aaddr = (long *) ( ((long) addr + sizeof(double) - 1) & - (long)sizeof(double) );
+ size -= (char *) aaddr - (char *) addr;
+ freearea[i] = aaddr;
+/*
+Convert 'size' to number of longs, and store '-size' guards at the
+beginning and end of this area so we will not accidentally recombine the
+first or last block:
+*/
+ size /= sizeof(long);
+
+ AvailableWords += size - 2;
+
+ aaddr[size - 1] = aaddr[0] = -size;
+/*
+Finally, call 'freeuncombinable' to put the remaining memory on the
+free list:
+*/
+ freeuncombinable(aaddr + 1, size - 2);
+}
+
+/*
+:h3.delmemory() - Delete Memory Pool
+*/
+void
+delmemory(void)
+{
+ register int i;
+
+ AvailableWords = 0;
+ firstfree.fore = &lastfree;
+ lastfree.back = &firstfree;
+ firstcombined = &lastfree;
+ uncombined = 0;
+ for (i=0; i<MAXAREAS; i++)
+ freearea[i] = NULL;
+}
+
+/*
+:h2.Debug Routines
+
+:h3.dumpchain() - Print the Chain of Free Blocks
+*/
+
+static void
+dumpchain(void)
+{
+ register struct freeblock *p; /* current free block */
+ register long size; /* size of block */
+ register struct freeblock *back; /* block before 'p' */
+ register int i; /* temp variable for counting */
+
+ printf("DUMPING FAST FREE LIST:\n");
+ back = &firstfree;
+ for (p = firstfree.fore, i=uncombined; p != firstcombined;
+ p = p->fore) {
+ if (--i < 0)
+ Abort("too many uncombined areas");
+ size = p->size;
+ printf(". . . area @ %p, size = %ld\n", (void *)p, -size);
+ if (size >= 0 || size != ((int *) p)[-1 - size])
+ Abort("dumpchain: bad size");
+ if (p->back != back)
+ Abort("dumpchain: bad back");
+ back = p;
+ }
+ printf("DUMPING COMBINED FREE LIST:\n");
+ for (; p != &lastfree; p = p->fore) {
+ size = p->size;
+ printf(". . . area @ %p, size = %ld\n", (void *)p, size);
+ if (size <= 0 || size != ((int *) p)[size - 1])
+ Abort("dumpchain: bad size");
+ if (p->back != back)
+ Abort("dumpchain: bad back");
+ back = p;
+ }
+ if (back != lastfree.back)
+ Abort("dumpchain: bad lastfree");
+}
+
+#ifdef notused
+/*
+:h3.reportarea() - Display a Contiguous Set of Memory Blocks
+*/
+
+static void
+reportarea(long *area) /* start of blocks (from addmemory) */
+{
+ register long size; /* size of current block */
+ register long wholesize; /* size of original area */
+ register struct freeblock *p; /* pointer to block */
+
+ if (area == NULL)
+ return;
+ wholesize = - *area++;
+ wholesize -= 2;
+
+ while (wholesize > 0) {
+ size = *area;
+ if (size < 0) {
+ register int i,j;
+
+ size = -size;
+ printf("Allocated %5ld bytes at %p, first words=%08lx %08lx\n",
+ size * sizeof(long), area + 1, area[1], area[2]);
+#if DEBUGWORDS
+ printf(" ...Last operator: %s\n",
+ (char *)area[size-DEBUGWORDS-1]);
+#endif
+ for (i = size - DEBUGWORDS; i < size - 2; i += 8) {
+ printf(" ...");
+ for (j=0; j<8; j++)
+ printf(" %08lx", area[i+j]);
+ printf("\n");
+ }
+
+ }
+ else {
+ printf("Free %ld bytes at %p\n", size * sizeof(long),
+ area);
+ if (size == 0)
+ Abort("zero sized memory block");
+
+ for (p = firstfree.fore; p != NULL; p = p->fore)
+ if ((long *) p == area) break;
+ if ((long *) p != area)
+ Abort("not found on forward chain");
+
+ for (p = lastfree.back; p != NULL; p = p->back)
+ if ((long *) p == area) break;
+ if ((long *) p != area)
+ Abort("not found on backward chain");
+ }
+ if (area[0] != area[size - 1])
+ Abort("unmatched check sizes");
+ area += size;
+ wholesize -= size;
+ }
+}
+
+/*
+:h3.MemReport() - Display All of Memory
+*/
+
+void
+MemReport(void)
+{
+ register int i;
+
+ dumpchain();
+
+ for (i=0; i<MAXAREAS; i++)
+ reportarea(freearea[i]);
+}
+
+/*
+:h3.MemBytesAvail - Display Number of Bytes Now Available
+*/
+
+void
+MemBytesAvail(void)
+{
+ printf("There are now %ld bytes available\n", AvailableWords *
+ sizeof(long) );
+}
+#endif
diff --git a/libXfont/src/Type1/t1snap.c b/libXfont/src/Type1/t1snap.c
new file mode 100644
index 000000000..5618b581b
--- /dev/null
+++ b/libXfont/src/Type1/t1snap.c
@@ -0,0 +1,85 @@
+/* $Xorg: t1snap.c,v 1.3 2000/08/17 19:46:34 cpqbld Exp $ */
+/* Copyright International Business Machines,Corp. 1991
+ * All Rights Reserved
+ *
+ * License to use, copy, modify, and distribute this software
+ * and its documentation for any purpose and without fee is
+ * hereby granted, provided that the above copyright notice
+ * appear in all copies and that both that copyright notice and
+ * this permission notice appear in supporting documentation,
+ * and that the name of IBM not be used in advertising or
+ * publicity pertaining to distribution of the software without
+ * specific, written prior permission.
+ *
+ * IBM PROVIDES THIS SOFTWARE "AS IS", WITHOUT ANY WARRANTIES
+ * OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING, BUT NOT
+ * LIMITED TO ANY IMPLIED WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE, AND NONINFRINGEMENT OF
+ * THIRD PARTY RIGHTS. THE ENTIRE RISK AS TO THE QUALITY AND
+ * PERFORMANCE OF THE SOFTWARE, INCLUDING ANY DUTY TO SUPPORT
+ * OR MAINTAIN, BELONGS TO THE LICENSEE. SHOULD ANY PORTION OF
+ * THE SOFTWARE PROVE DEFECTIVE, THE LICENSEE (NOT IBM) ASSUMES
+ * THE ENTIRE COST OF ALL SERVICING, REPAIR AND CORRECTION. IN
+ * NO EVENT SHALL IBM BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING
+ * FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF
+ * CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
+ * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+ * SOFTWARE.
+ */
+/* $XFree86: xc/lib/font/Type1/t1snap.c,v 1.3 1999/08/22 08:58:54 dawes Exp $ */
+
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "objects.h"
+#include "spaces.h"
+#include "paths.h"
+#include "pictures.h"
+
+/*
+:h2.Handle Functions
+
+:h3.Phantom() - Returns a Move Segment Equivalent to Handles
+
+This is a user operator. Its new name is QueryHandle.
+*/
+
+struct segment *
+t1_Phantom(struct segment *p) /* object to take the Phantom of */
+{
+ struct fractpoint pt; /* handle size will built here */
+
+ if (p == NULL)
+ pt.x = pt.y = 0;
+ else
+ PathDelta(p, &pt);
+
+ return(PathSegment(MOVETYPE, pt.x, pt.y));
+}
+
+/*
+:h3.Snap() - Force Ending Handle of Object to Origin
+
+This is a user operator.
+*/
+
+struct segment *
+t1_Snap(struct segment *p) /* path to snap */
+{
+ struct fractpoint pt; /* for finding length of path */
+
+ if (p == NULL)
+ return(NULL);
+ p = UniquePath(p);
+
+ PathDelta(p, &pt);
+ if (p->last->type == MOVETYPE) {
+ p->last->dest.x -= pt.x;
+ p->last->dest.y -= pt.y;
+ }
+ else
+ p = JoinSegment(p, MOVETYPE, -pt.x, -pt.y, NULL);
+ return(p);
+}
diff --git a/libXfont/src/Type1/t1stdio.h b/libXfont/src/Type1/t1stdio.h
new file mode 100644
index 000000000..aa281c019
--- /dev/null
+++ b/libXfont/src/Type1/t1stdio.h
@@ -0,0 +1,94 @@
+/* $Xorg: t1stdio.h,v 1.3 2000/08/17 19:46:34 cpqbld Exp $ */
+/* Copyright International Business Machines,Corp. 1991
+ * All Rights Reserved
+ *
+ * License to use, copy, modify, and distribute this software
+ * and its documentation for any purpose and without fee is
+ * hereby granted, provided that the above copyright notice
+ * appear in all copies and that both that copyright notice and
+ * this permission notice appear in supporting documentation,
+ * and that the name of IBM not be used in advertising or
+ * publicity pertaining to distribution of the software without
+ * specific, written prior permission.
+ *
+ * IBM PROVIDES THIS SOFTWARE "AS IS", WITHOUT ANY WARRANTIES
+ * OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING, BUT NOT
+ * LIMITED TO ANY IMPLIED WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE, AND NONINFRINGEMENT OF
+ * THIRD PARTY RIGHTS. THE ENTIRE RISK AS TO THE QUALITY AND
+ * PERFORMANCE OF THE SOFTWARE, INCLUDING ANY DUTY TO SUPPORT
+ * OR MAINTAIN, BELONGS TO THE LICENSEE. SHOULD ANY PORTION OF
+ * THE SOFTWARE PROVE DEFECTIVE, THE LICENSEE (NOT IBM) ASSUMES
+ * THE ENTIRE COST OF ALL SERVICING, REPAIR AND CORRECTION. IN
+ * NO EVENT SHALL IBM BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING
+ * FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF
+ * CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
+ * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+ * SOFTWARE.
+ */
+/* $XFree86: xc/lib/font/Type1/t1stdio.h,v 1.9 2001/01/17 19:43:24 dawes Exp $ */
+/* T1IO FILE structure and related stuff */
+
+#ifdef XFree86LOADER
+#undef FILE
+#endif
+#define FILE F_FILE
+typedef unsigned char F_char;
+
+typedef struct F_FILE {
+ F_char *b_base; /* Pointer to beginning of buffer */
+ long b_size; /* Size of the buffer */
+ F_char *b_ptr; /* Pointer to next char in buffer */
+ long b_cnt; /* Number of chars remaining in buffer */
+ F_char flags; /* other flags; != 0 means getc must call fgetc */
+ F_char ungotc; /* Place for ungotten char; flag set if present */
+ short error; /* error status */
+ int fd; /* underlying file descriptor */
+} F_FILE;
+
+
+/* defines for flags */
+#define UNGOTTENC (0x01)
+#define FIOEOF (0x80)
+#define FIOERROR (0x40)
+
+#ifndef NULL
+#include <stddef.h>
+#endif
+
+#define EOF (-1) /* end of file */
+#define F_BUFSIZ (512)
+
+#define _XT1getc(f) \
+ ( \
+ ( ((f)->b_cnt > 0) && ((f)->flags == 0) ) ? \
+ ( (f)->b_cnt--, (unsigned int)*( (f)->b_ptr++ ) ) : \
+ T1Getc(f) \
+ )
+
+#define T1Feof(f) (((f)->flags & FIOEOF) && ((f)->b_cnt==0))
+
+extern FILE *T1Open ( char *fn, char *mode );
+extern int T1Getc ( FILE *f );
+extern int T1Ungetc ( int c, FILE *f );
+extern int T1Read ( char *buffP, int size, int n, FILE *f );
+extern int T1Close ( FILE *f );
+extern FILE *T1eexec ( FILE *f );
+extern void resetDecrypt ( void );
+
+#undef fclose
+#undef fopen
+#undef ungetc
+#undef fgetc
+#undef fread
+#undef feof
+#undef ferror
+#define fclose(f) T1Close(f)
+#define fopen(name,mode) T1Open(name,mode)
+#define ungetc(c,f) T1Ungetc(c,f)
+#define fgetc(f) T1Getc(f)
+
+#define fread(bufP,size,n,f) T1Read(bufP,size,n,f)
+#define feof(f) (((f)->flags & FIOEOF) && ((f)->b_cnt==0))
+#define ferror(f) (((f)->flags & FIOERROR)?(f)->error:0)
diff --git a/libXfont/src/Type1/t1unicode.c b/libXfont/src/Type1/t1unicode.c
new file mode 100644
index 000000000..136cc4441
--- /dev/null
+++ b/libXfont/src/Type1/t1unicode.c
@@ -0,0 +1,251 @@
+/*
+Copyright (c) 1998 by Juliusz Chroboczek
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
+*/
+
+/* $XFree86$ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "t1unicode.h"
+
+static char* table_32[] =
+{ "space", "exclam", "quotedbl", "numbersign", "dollar", "percent",
+ "ampersand", "quotesingle", "parenleft", "parenright", "asterisk",
+ "plus", "comma", "hyphen", "period", "slash", "zero", "one", "two",
+ "three", "four", "five", "six", "seven", "eight", "nine", "colon",
+ "semicolon", "less", "equal", "greater", "question", "at", "A", "B",
+ "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P",
+ "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z", "bracketleft",
+ "backslash", "bracketright", "asciicircum", "underscore", "grave",
+ "a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n",
+ "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z",
+ "braceleft", "bar", "braceright", "asciitilde", 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, "space", "exclamdown", "cent", "sterling", "currency", "yen",
+ "brokenbar", "section", "dieresis", "copyright", "ordfeminine",
+ "guillemotleft", "logicalnot", "hyphen", "registered", "macron",
+ "degree", "plusminus", "twosuperior", "threesuperior", "acute", "mu",
+ "paragraph", "periodcentered", "cedilla", "onesuperior",
+ "ordmasculine", "guillemotright", "onequarter", "onehalf",
+ "threequarters", "questiondown", "Agrave", "Aacute", "Acircumflex",
+ "Atilde", "Adieresis", "Aring", "AE", "Ccedilla", "Egrave", "Eacute",
+ "Ecircumflex", "Edieresis", "Igrave", "Iacute", "Icircumflex",
+ "Idieresis", "Eth", "Ntilde", "Ograve", "Oacute", "Ocircumflex",
+ "Otilde", "Odieresis", "multiply", "Oslash", "Ugrave", "Uacute",
+ "Ucircumflex", "Udieresis", "Yacute", "Thorn", "germandbls", "agrave",
+ "aacute", "acircumflex", "atilde", "adieresis", "aring", "ae",
+ "ccedilla", "egrave", "eacute", "ecircumflex", "edieresis", "igrave",
+ "iacute", "icircumflex", "idieresis", "eth", "ntilde", "ograve",
+ "oacute", "ocircumflex", "otilde", "odieresis", "divide", "oslash",
+ "ugrave", "uacute", "ucircumflex", "udieresis", "yacute", "thorn",
+ "ydieresis", "Amacron", "amacron", "Abreve", "abreve", "Aogonek",
+ "aogonek", "Cacute", "cacute", "Ccircumflex", "ccircumflex",
+ "Cdotaccent", "cdotaccent", "Ccaron", "ccaron", "Dcaron", "dcaron",
+ "Dcroat", "dcroat", "Emacron", "emacron", "Ebreve", "ebreve",
+ "Edotaccent", "edotaccent", "Eogonek", "eogonek", "Ecaron", "ecaron",
+ "Gcircumflex", "gcircumflex", "Gbreve", "gbreve", "Gdotaccent",
+ "gdotaccent", "Gcommaaccent", "gcommaaccent", "Hcircumflex",
+ "hcircumflex", "Hbar", "hbar", "Itilde", "itilde", "Imacron",
+ "imacron", "Ibreve", "ibreve", "Iogonek", "iogonek", "Idotaccent",
+ "dotlessi", "IJ", "ij", "Jcircumflex", "jcircumflex", "Kcommaaccent",
+ "kcommaaccent", "kgreenlandic", "Lacute", "lacute", "Lcommaaccent",
+ "lcommaaccent", "Lcaron", "lcaron", "Ldot", "ldot", "Lslash",
+ "lslash", "Nacute", "nacute", "Ncommaaccent", "ncommaaccent",
+ "Ncaron", "ncaron", "napostrophe", "Eng", "eng", "Omacron", "omacron",
+ "Obreve", "obreve", "Ohungarumlaut", "ohungarumlaut", "OE", "oe",
+ "Racute", "racute", "Rcommaaccent", "rcommaaccent", "Rcaron",
+ "rcaron", "Sacute", "sacute", "Scircumflex", "scircumflex",
+ "Scommaaccent", "scommaaccent", "Scaron", "scaron", "Tcommaaccent",
+ "tcommaaccent", "Tcaron", "tcaron", "Tbar", "tbar", "Utilde",
+ "utilde", "Umacron", "umacron", "Ubreve", "ubreve", "Uring", "uring",
+ "Uhungarumlaut", "uhungarumlaut", "Uogonek", "uogonek", "Wcircumflex",
+ "wcircumflex", "Ycircumflex", "ycircumflex", "Ydieresis", "Zacute",
+ "zacute", "Zdotaccent", "zdotaccent", "Zcaron", "zcaron", "longs", 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "florin", 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "Ohorn", "ohorn", 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, "Uhorn", "uhorn", 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "Gcaron",
+ "gcaron", 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ "Aringacute", "aringacute", "AEacute", "aeacute", "Oslashacute",
+ "oslashacute", 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, "afii57929", "afii64937", 0, 0, 0, 0, 0, 0,
+ 0, 0, "circumflex", "caron", 0, "macron", 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, "breve", "dotaccent", "ring", "ogonek", "tilde",
+ "hungarumlaut", 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "gravecomb",
+ "acutecomb", 0, "tildecomb", 0, 0, 0, 0, 0, "hookabovecomb", 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ "dotbelowcomb", 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, "tonos", "dieresistonos", "Alphatonos",
+ "anoteleia", "Epsilontonos", "Etatonos", "Iotatonos", 0,
+ "Omicrontonos", 0, "Upsilontonos", "Omegatonos", "iotadieresistonos",
+ "Alpha", "Beta", "Gamma", "Delta", "Epsilon", "Zeta", "Eta", "Theta",
+ "Iota", "Kappa", "Lambda", "Mu", "Nu", "Xi", "Omicron", "Pi", "Rho",
+ 0, "Sigma", "Tau", "Upsilon", "Phi", "Chi", "Psi", "Omega",
+ "Iotadieresis", "Upsilondieresis", "alphatonos", "epsilontonos",
+ "etatonos", "iotatonos", "upsilondieresistonos", "alpha", "beta",
+ "gamma", "delta", "epsilon", "zeta", "eta", "theta", "iota", "kappa",
+ "lambda", "mu", "nu", "xi", "omicron", "pi", "rho", "sigma1", "sigma",
+ "tau", "upsilon", "phi", "chi", "psi", "omega", "iotadieresis",
+ "upsilondieresis", "omicrontonos", "upsilontonos", "omegatonos", 0, 0,
+ "theta1", "Upsilon1", 0, 0, "phi1", "omega1", 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "afii10023", "afii10051",
+ "afii10052", "afii10053", "afii10054", "afii10055", "afii10056",
+ "afii10057", "afii10058", "afii10059", "afii10060", "afii10061", 0,
+ "afii10062", "afii10145", "afii10017", "afii10018", "afii10019",
+ "afii10020", "afii10021", "afii10022", "afii10024", "afii10025",
+ "afii10026", "afii10027", "afii10028", "afii10029", "afii10030",
+ "afii10031", "afii10032", "afii10033", "afii10034", "afii10035",
+ "afii10036", "afii10037", "afii10038", "afii10039", "afii10040",
+ "afii10041", "afii10042", "afii10043", "afii10044", "afii10045",
+ "afii10046", "afii10047", "afii10048", "afii10049", "afii10065",
+ "afii10066", "afii10067", "afii10068", "afii10069", "afii10070",
+ "afii10072", "afii10073", "afii10074", "afii10075", "afii10076",
+ "afii10077", "afii10078", "afii10079", "afii10080", "afii10081",
+ "afii10082", "afii10083", "afii10084", "afii10085", "afii10086",
+ "afii10087", "afii10088", "afii10089", "afii10090", "afii10091",
+ "afii10092", "afii10093", "afii10094", "afii10095", "afii10096",
+ "afii10097", 0, "afii10071", "afii10099", "afii10100", "afii10101",
+ "afii10102", "afii10103", "afii10104", "afii10105", "afii10106",
+ "afii10107", "afii10108", "afii10109", 0, "afii10110", "afii10193", 0,
+ 0, "afii10146", "afii10194", 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ "afii10147", "afii10195", "afii10148", "afii10196", 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ "afii10050", "afii10098", 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "afii10846", 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ "afii57799", "afii57801", "afii57800", "afii57802", "afii57793",
+ "afii57794", "afii57795", "afii57798", "afii57797", "afii57806", 0,
+ "afii57796", "afii57807", "afii57839", "afii57645", "afii57841",
+ "afii57842", "afii57804", "afii57803", "afii57658", 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, "afii57664", "afii57665", "afii57666", "afii57667",
+ "afii57668", "afii57669", "afii57670", "afii57671", "afii57672",
+ "afii57673", "afii57674", "afii57675", "afii57676", "afii57677",
+ "afii57678", "afii57679", "afii57680", "afii57681", "afii57682",
+ "afii57683", "afii57684", "afii57685", "afii57686", "afii57687",
+ "afii57688", "afii57689", "afii57690", 0, 0, 0, 0, 0, "afii57716",
+ "afii57717", "afii57718", 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "afii57388", 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, "afii57403", 0, 0, 0, "afii57407", 0, "afii57409",
+ "afii57410", "afii57411", "afii57412", "afii57413", "afii57414",
+ "afii57415", "afii57416", "afii57417", "afii57418", "afii57419",
+ "afii57420", "afii57421", "afii57422", "afii57423", "afii57424",
+ "afii57425", "afii57426", "afii57427", "afii57428", "afii57429",
+ "afii57430", "afii57431", "afii57432", "afii57433", "afii57434", 0, 0,
+ 0, 0, 0, "afii57440", "afii57441", "afii57442", "afii57443",
+ "afii57444", "afii57445", "afii57446", "afii57470", "afii57448",
+ "afii57449", "afii57450", "afii57451", "afii57452", "afii57453",
+ "afii57454", "afii57455", "afii57456", "afii57457", "afii57458", 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "afii57392", "afii57393",
+ "afii57394", "afii57395", "afii57396", "afii57397", "afii57398",
+ "afii57399", "afii57400", "afii57401", "afii57381", 0, 0, "afii63167",
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "afii57511", 0, 0, 0, 0, "afii57506",
+ 0, 0, 0, 0, 0, 0, 0, "afii57507", 0, "afii57512", 0, 0, 0, 0, 0, 0, 0,
+ 0, "afii57513", 0, 0, 0, 0, 0, 0, "afii57508", 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, "afii57505", 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "afii57509", 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, "afii57514", 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "afii57519", 0, 0, "afii57534", 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
+
+static char* table_2000[] = /* general punctuation, s*scripts, currency */
+{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "afii61664", "afii301", "afii299",
+ "afii300", 0, 0, "figuredash", "endash", "emdash", "afii00208", 0,
+ "underscoredbl", "quoteleft", "quoteright", "quotesinglbase",
+ "quotereversed", "quotedblleft", "quotedblright", "quotedblbase", 0,
+ "dagger", "daggerdbl", "bullet", 0, "onedotenleader",
+ "twodotenleader", "ellipsis", 0, 0, 0, 0, 0, "afii61573", "afii61574",
+ "afii61575", 0, "perthousand", 0, "minute", "second", 0, 0, 0, 0, 0,
+ "guilsinglleft", "guilsinglright", 0, "exclamdbl", 0, 0, 0, 0, 0, 0,
+ 0, "fraction", 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, "zerosuperior", 0, 0, 0, "foursuperior", "fivesuperior",
+ "sixsuperior", "sevensuperior", "eightsuperior", "ninesuperior", 0, 0,
+ 0, "parenleftsuperior", "parenrightsuperior", "nsuperior",
+ "zeroinferior", "oneinferior", "twoinferior", "threeinferior",
+ "fourinferior", "fiveinferior", "sixinferior", "seveninferior",
+ "eightinferior", "nineinferior", 0, 0, 0, "parenleftinferior",
+ "parenrightinferior", 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, "colonmonetary", 0, "franc", "lira", 0, 0, "peseta", 0, 0,
+ "afii57636", "dong", "Euro", 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
+
+static char* table_2500[]= /* line and box drawing */
+{ "SF100000", 0, "SF110000", 0, 0, 0, 0, 0, 0, 0, 0, 0, "SF010000", 0,
+ 0, 0, "SF030000", 0, 0, 0, "SF020000", 0, 0, 0, "SF040000", 0, 0, 0,
+ "SF080000", 0, 0, 0, 0, 0, 0, 0, "SF090000", 0, 0, 0, 0, 0, 0, 0,
+ "SF060000", 0, 0, 0, 0, 0, 0, 0, "SF070000", 0, 0, 0, 0, 0, 0, 0,
+ "SF050000", 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ "SF430000", "SF240000", "SF510000", "SF520000", "SF390000",
+ "SF220000", "SF210000", "SF250000", "SF500000", "SF490000",
+ "SF380000", "SF280000", "SF270000", "SF260000", "SF360000",
+ "SF370000", "SF420000", "SF190000", "SF200000", "SF230000",
+ "SF470000", "SF480000", "SF410000", "SF450000", "SF460000",
+ "SF400000", "SF540000", "SF530000", "SF440000", 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "upblock", 0, 0, 0, "dnblock", 0,
+ 0, 0, "block", 0, 0, 0, "lfblock", 0, 0, 0, "rtblock", "ltshade",
+ "shade", "dkshade", 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
+
+static char* table_FB00[] = /* alphabetic presentation forms */
+{ "ff", "fi", "fl", "ffi", "ffl", 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "afii57705", 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, "afii57694", "afii57695", 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ "afii57723", 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, "afii57700", 0, 0, 0, 0 };
+
+char*
+unicodetoPSname(unsigned short code)
+{
+ if(code<32) return 0;
+ else if(code<0x6FF) return table_32[code-32];
+ else if(code<0x2000) return 0;
+ else if(code<0x20D0) return table_2000[code-0x2000];
+ else if(code==0x2116) return "afii61352"; /* numero sign, for Koi */
+ else if(code==0x2122) return "trademark";
+ else if(code<0x2500) return 0;
+ else if(code<0x25A0) return table_2500[code-0x2500];
+ else if(code<0xFB00) return 0;
+ else if(code<0xFB50) return table_FB00[code-0xFB00];
+ else return 0;
+}
diff --git a/libXfont/src/Type1/t1unicode.h b/libXfont/src/Type1/t1unicode.h
new file mode 100644
index 000000000..bad0274a0
--- /dev/null
+++ b/libXfont/src/Type1/t1unicode.h
@@ -0,0 +1,25 @@
+/*
+Copyright (c) 1998 by Juliusz Chroboczek
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
+*/
+
+/* $XFree86$ */
+
+char *unicodetoPSname(unsigned short code);
diff --git a/libXfont/src/Type1/token.c b/libXfont/src/Type1/token.c
new file mode 100644
index 000000000..71a968b30
--- /dev/null
+++ b/libXfont/src/Type1/token.c
@@ -0,0 +1,1208 @@
+/* $Xorg: token.c,v 1.4 2000/08/17 19:46:34 cpqbld Exp $ */
+/* Copyright International Business Machines,Corp. 1991
+ * All Rights Reserved
+ *
+ * License to use, copy, modify, and distribute this software
+ * and its documentation for any purpose and without fee is
+ * hereby granted, provided that the above copyright notice
+ * appear in all copies and that both that copyright notice and
+ * this permission notice appear in supporting documentation,
+ * and that the name of IBM not be used in advertising or
+ * publicity pertaining to distribution of the software without
+ * specific, written prior permission.
+ *
+ * IBM PROVIDES THIS SOFTWARE "AS IS", WITHOUT ANY WARRANTIES
+ * OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING, BUT NOT
+ * LIMITED TO ANY IMPLIED WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE, AND NONINFRINGEMENT OF
+ * THIRD PARTY RIGHTS. THE ENTIRE RISK AS TO THE QUALITY AND
+ * PERFORMANCE OF THE SOFTWARE, INCLUDING ANY DUTY TO SUPPORT
+ * OR MAINTAIN, BELONGS TO THE LICENSEE. SHOULD ANY PORTION OF
+ * THE SOFTWARE PROVE DEFECTIVE, THE LICENSEE (NOT IBM) ASSUMES
+ * THE ENTIRE COST OF ALL SERVICING, REPAIR AND CORRECTION. IN
+ * NO EVENT SHALL IBM BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING
+ * FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF
+ * CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
+ * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+ * SOFTWARE.
+ */
+/* $XFree86: xc/lib/font/Type1/token.c,v 1.5tsi Exp $ */
+/* Authors: Sig Nin & Carol Thompson IBM Almaden Research Laboratory */
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "t1stdio.h"
+#include "util.h"
+#include "digit.h"
+#include "token.h"
+#include "tokst.h"
+#include "hdigit.h"
+
+/*
+ * -------------------------------------------------------------------
+ * Globals
+ * -------------------------------------------------------------------
+ */
+
+/* These variables are set by the caller */
+char *tokenStartP; /* Pointer to token buffer in VM */
+char *tokenMaxP; /* Pointer to last byte in buffer + 1 */
+
+/* These variables are set by TOKEN */
+int tokenLength; /* Characters in token */
+boolean tokenTooLong; /* Token too long for buffer */
+int tokenType; /* Type of token identified */
+psvalue tokenValue; /* Token value */
+
+/*
+ * -------------------------------------------------------------------
+ * Private variables
+ * -------------------------------------------------------------------
+ */
+
+static FILE *inputFileP; /* Current input file */
+
+
+/* Token */
+static char *tokenCharP; /* Pointer to next character in token */
+
+/*
+ * -------------------------------------------------------------------
+ * Private routines for manipulating numbers
+ * -------------------------------------------------------------------
+ */
+
+#define Exp10(e) \
+((e) == 0\
+ ? (double)(1.0)\
+ : (-64 <= (e) && (e) <= 63\
+ ? Exp10T[(e)+64]\
+ : P10(e)\
+ )\
+)
+
+static double Exp10T[128] = {
+ 1e-64, 1e-63, 1e-62, 1e-61, 1e-60, 1e-59, 1e-58, 1e-57,
+ 1e-56, 1e-55, 1e-54, 1e-53, 1e-52, 1e-51, 1e-50, 1e-49,
+ 1e-48, 1e-47, 1e-46, 1e-45, 1e-44, 1e-43, 1e-42, 1e-41,
+ 1e-40, 1e-39, 1e-38, 1e-37, 1e-36, 1e-35, 1e-34, 1e-33,
+ 1e-32, 1e-31, 1e-30, 1e-29, 1e-28, 1e-27, 1e-26, 1e-25,
+ 1e-24, 1e-23, 1e-22, 1e-21, 1e-20, 1e-19, 1e-18, 1e-17,
+ 1e-16, 1e-15, 1e-14, 1e-13, 1e-12, 1e-11, 1e-10, 1e-9,
+ 1e-8, 1e-7, 1e-6, 1e-5, 1e-4, 1e-3, 1e-2, 1e-1,
+ 1e0, 1e1, 1e2, 1e3, 1e4, 1e5, 1e6, 1e7,
+ 1e8, 1e9, 1e10, 1e11, 1e12, 1e13, 1e14, 1e15,
+ 1e16, 1e17, 1e18, 1e19, 1e20, 1e21, 1e22, 1e23,
+ 1e24, 1e25, 1e26, 1e27, 1e28, 1e29, 1e30, 1e31,
+ 1e32, 1e33, 1e34, 1e35, 1e36, 1e37, 1e38, 1e39,
+ 1e40, 1e41, 1e42, 1e43, 1e44, 1e45, 1e46, 1e47,
+ 1e48, 1e49, 1e50, 1e51, 1e52, 1e53, 1e54, 1e55,
+ 1e56, 1e57, 1e58, 1e59, 1e60, 1e61, 1e62, 1e63
+};
+
+static double
+P10(long exponent)
+{
+ double value, power;
+
+ if (exponent < 0) {
+ power = 0.1;
+ value = (exponent & 1 ? power : 1.0);
+ exponent++;
+ exponent = -(exponent >> 1); /* portable C for -(exponent/2) */
+ }
+ else {
+ power = 10.0;
+ value = (exponent & 1 ? power : 1.0);
+ exponent = exponent >> 1;
+ }
+
+ while(exponent > 0) {
+ power *= power;
+ if (exponent & 1)
+ value *= power;
+ exponent >>= 1;
+ }
+
+ return(value);
+}
+
+/*
+ * -------------------------------------------------------------------
+ * Private routines and macros for manipulating the input
+ * -------------------------------------------------------------------
+ */
+
+/* Get next character from the input --
+ *
+ */
+#define next_ch() (_XT1getc(inputFileP))
+
+/* Push a character back into the input --
+ *
+ * Ungetc of EOF will fail, but that's ok: the next getc will
+ * return EOF.
+ *
+ * NOTE: These macros are presently written to return the character
+ * pushed, or EOF if none was pushed. However, they are not
+ * required to return anything in particular, and callers should
+ * not rely on the returned value.
+ */
+#define back_ch(ch) (T1Ungetc(ch, inputFileP))
+
+/* Push a character back into the input if it was not white space.
+ * If it is a carriage return (\r) then check next char for
+ * linefeed and consume them both, otherwise put next char back.
+ *
+ */
+#define back_ch_not_white(ch) \
+(\
+isWHITE_SPACE(ch)\
+ ? ((ch == '\r')\
+ ? (((ch = next_ch()) == '\n')\
+ ? EOF\
+ : back_ch(ch)\
+ )\
+ : EOF\
+ )\
+ : back_ch(ch)\
+)
+
+/*
+ * -------------------------------------------------------------------
+ * Private routines and macros for manipulating the token buffer
+ * -------------------------------------------------------------------
+ */
+
+/* Add a character to the token
+ * ---- use ONLY when you KNOW that this character will
+ * be stored within the token buffer.
+ */
+#define save_unsafe_ch(ch) (*tokenCharP++ = ch)
+
+/* Add a character to the token, if not too long to fit */
+#define save_ch(ch) \
+((tokenCharP < tokenMaxP)\
+ ? save_unsafe_ch(ch)\
+ : (tokenTooLong = TRUE)\
+)
+
+#define save_ch_no_inc(ch) \
+if (tokenCharP < tokenMaxP) *tokenCharP = ch
+
+/*
+ * -------------------------------------------------------------------
+ * Action Routines
+ *
+ * These routines all
+ * -- take int ch as a parameter
+ * -- return int ch if no token was recognized, DONE otherwise
+ * -- leave the next character in the input, if returning DONE
+ * -------------------------------------------------------------------
+ */
+
+#define DONE (256)
+
+/* Get the next input character */
+static int
+next_char(int ch)
+{
+ return(next_ch());
+}
+
+/* Add character to token */
+static int
+add_char(int ch)
+{
+ save_ch(ch);
+ return(next_ch());
+}
+
+
+/* -------------------------------------------------------------------
+ * Skip white space and comments
+ */
+
+/* Skip white space */
+static int
+skip_space(int ch)
+{
+ do {
+ ch = next_ch();
+ } while(isWHITE_SPACE(ch));
+ return(ch);
+}
+
+/* Skip comments */
+static int
+skip_comment(int ch)
+{
+ do {
+ ch = next_ch();
+ } while(isCOMMENT(ch));
+ return(ch);
+}
+
+/* -------------------------------------------------------------------
+ * Collect value elements for a number
+ */
+
+/* decimal integer or real number mantissa */
+static int m_sign;
+static long m_value;
+static long m_scale;
+
+/* real number exponent */
+static int e_sign;
+static long e_value;
+
+/* radix number */
+static long r_base;
+static long r_value;
+static long r_scale;
+
+static int
+add_sign(int ch)
+{
+ m_sign = ch;
+ save_unsafe_ch(ch);
+ return(next_ch());
+}
+
+static int
+add_1st_digits(int ch)
+{
+ m_sign = '+';
+ return(add_digits(ch));
+}
+
+static int
+add_digits(int ch)
+{
+ long value, p_value, scale;
+ int digit;
+
+ /* On entry, expect m_sign to be set to '+' or '-';
+ * ch is a decimal digit.
+ * Expect at most one character saved at this point,
+ * a sign. This routine will save up to 10 more
+ * characters without checking the buffer boundary.
+ */
+
+ value = ch - '0';
+ save_unsafe_ch(ch);
+ ch = next_ch();
+
+ while(isDECIMAL_DIGIT(ch) && value < (MAX_INTEGER/10)) {
+ value = (value << 3) + (value << 1) + (ch - '0');
+ save_unsafe_ch(ch);
+ ch = next_ch();
+ }
+
+ /* Quick exit for small integers --
+ * |x| <= 10*((MAX_INTEGER/10)-1)+9
+ * |x| <= 2,147,483,639 for 32 bit integers
+ */
+ if (isNUMBER_ENDER(ch)) {
+ back_ch_not_white(ch);
+ tokenValue.integer = (m_sign == '-' ? -value : value);
+ tokenType = TOKEN_INTEGER;
+ return(DONE);
+ }
+
+ /* Handle additional digits. Beyond the boundary case,
+ * 10*(MAX_INTEGER/10) <= |number| <= MAX_INTEGER
+ * just count the digits: the number is too large to
+ * represent as an integer and will be returned as a real.
+ * The mantissa of a real holds fewer bits than an integer.
+ */
+ p_value = value;
+ value = (m_sign == '-' ? -value : value);
+ scale = 0;
+
+ if (isDECIMAL_DIGIT(ch)) {
+
+ /* Handle the boundary case */
+ if (p_value == (MAX_INTEGER/10)) {
+ digit = ch - '0';
+
+ /* Must handle positive and negative values separately */
+ /* for 2's complement arithmetic */
+ if (value > 0) {
+ if (digit <= MAX_INTEGER%10)
+ value = (value << 3) + (value << 1) + digit;
+ else
+ ++scale; /* Too big, just count it */
+ }
+ else {
+ /* Use positive % operands for portability */
+ if (digit <= -(MIN_INTEGER+10)%10)
+ value = (value << 3) + (value << 1) - digit;
+ else
+ ++scale; /* Too big, just count it */
+ }
+ }
+ else
+ ++scale; /* Not boundary case, just count digit */
+
+ save_unsafe_ch(ch);
+ ch = next_ch();
+
+ /* Continue scanning digits, but can't store them */
+ while(isDECIMAL_DIGIT(ch)) {
+ ++scale;
+ save_ch(ch);
+ ch = next_ch();
+ }
+ }
+
+ /* Continue from here scanning radix integer or real */
+ m_value = value;
+ m_scale = scale;
+
+ /* Initialize for possible real */
+ e_sign = '+';
+ e_value = 0;
+
+ return(ch);
+}
+
+static int
+add_1st_decpt(int ch)
+{
+ m_sign = '+';
+ return(add_decpt(ch));
+}
+
+static int
+add_decpt(int ch)
+{
+ /* On entry, expect m_sign to be set to '+' or '-' */
+ m_value = 0;
+ m_scale = 0;
+ save_unsafe_ch(ch);
+ return(next_ch());
+}
+
+static int
+add_fraction(int ch)
+{
+ long value, scale;
+ int digit;
+
+ /* On entry, expect m_value and m_scale to be initialized,
+ * and m_sign to be set to '+' or '-'. Expect m_value and m_sign
+ * to be consistent (this is not checked).
+ */
+ value = m_value;
+ scale = m_scale;
+
+ /* Scan leading zeroes */
+ if (value == 0) {
+ while(ch == '0') {
+ --scale;
+ save_ch(ch);
+ ch = next_ch();
+ }
+
+ /* Scan first significant digit */
+ if (isDECIMAL_DIGIT(ch)) {
+ --scale;
+ value = ch - '0';
+ value = (m_sign == '-' ? -value : value);
+ save_ch(ch);
+ ch = next_ch();
+ }
+ else
+ /* no significant digits -- number is zero */
+ scale = 0;
+ }
+ /* value != 0 || value == 0 && !isDECIMAL_DIGIT(ch) */
+
+ /* Scan additional significant digits */
+ if (isDECIMAL_DIGIT(ch)) {
+ if (value > 0) {
+ while(isDECIMAL_DIGIT(ch) && value < (MAX_INTEGER/10)) {
+ --scale;
+ value = (value << 3) + (value << 1) + (ch - '0');
+ save_ch(ch);
+ ch = next_ch();
+ }
+ /* Check boundary case */
+ if (isDECIMAL_DIGIT(ch) && value == (MAX_INTEGER/10)) {
+ digit = ch - '0';
+ if (digit <= MAX_INTEGER%10) {
+ --scale;
+ value = (value << 3) + (value << 1) + digit;
+ save_ch(ch);
+ ch = next_ch();
+ }
+ }
+ }
+ else {
+ /* value < 0 */
+ while(isDECIMAL_DIGIT(ch) && value > -(-(MIN_INTEGER+10)/10+1)) {
+ /* Use positive / operands for portability */
+ --scale;
+ value = (value << 3) + (value << 1) - (ch - '0');
+ save_ch(ch);
+ ch = next_ch();
+ }
+ /* Check boundary case */
+ if (isDECIMAL_DIGIT(ch)
+ && value == -(-(MIN_INTEGER+10)/10+1)) {
+ digit = ch - '0';
+ if (digit <= -(MIN_INTEGER+10)%10) {
+ /* Use positive % operands for portability */
+ --scale;
+ value = (value << 3) + (value << 1) - digit;
+ save_ch(ch);
+ ch = next_ch();
+ }
+ }
+ }
+
+ /* Additional digits can be discarded */
+ while(isDECIMAL_DIGIT(ch)) {
+ save_ch(ch);
+ ch = next_ch();
+ }
+ }
+
+ /* Store results */
+ m_value = value;
+ m_scale = scale;
+
+ /* Initialize for possible real */
+ e_sign = '+';
+ e_value = 0;
+
+ return(ch);
+}
+
+static int
+add_e_sign(int ch)
+{
+ e_sign = ch;
+ save_ch(ch);
+ return(next_ch());
+}
+
+static int
+add_exponent(int ch)
+{
+ long value, p_value;
+ long scale = 0;
+ int digit;
+
+ /* On entry, expect e_sign to be set to '+' or '-' */
+
+ value = ch - '0';
+ save_ch(ch);
+ ch = next_ch();
+
+ while(isDECIMAL_DIGIT(ch) && value < (MAX_INTEGER/10)) {
+ value = (value << 3) + (value << 1) + (ch - '0');
+ save_ch(ch);
+ ch = next_ch();
+ }
+
+ p_value = value;
+ value = (e_sign == '-' ? -value : value);
+
+ /* Handle additional digits. Beyond the boundary case,
+ * 10*(MAX_INTEGER/10) <= |number| <= MAX_INTEGER
+ * just count the digits: the number is too large to
+ * represent as an integer.
+ */
+ if (isDECIMAL_DIGIT(ch)) {
+
+ /* Examine boundary case */
+ if (p_value == (MAX_INTEGER/10)) {
+ digit = ch - '0';
+
+ /* Must handle positive and negative values separately */
+ /* for 2's complement arithmetic */
+ if (value > 0) {
+ if (digit <= MAX_INTEGER%10)
+ value = (value << 3) + (value << 1) + digit;
+ else
+ ++scale; /* Too big, just count it */
+ }
+ else {
+ /* Use positive % operands for portability */
+ if (digit <= -(MIN_INTEGER+10)%10)
+ value = (value << 3) + (value << 1) - digit;
+ else
+ ++scale; /* Too big, just count it */
+ }
+ }
+ else
+ ++scale; /* Not boundary case, just count digit */
+
+ save_ch(ch);
+ ch = next_ch();
+
+ /* Continue scanning digits, but can't store any more */
+ while(isDECIMAL_DIGIT(ch)) {
+ ++scale;
+ save_ch(ch);
+ ch = next_ch();
+ }
+ }
+
+ /* Store results */
+ e_value = value;
+
+ return(ch);
+}
+
+static int
+add_radix(int ch)
+{
+ if (2 <= m_value && m_value <= 36 && m_scale == 0) {
+ r_base = m_value;
+ save_ch(ch);
+ return(next_ch());
+ }
+ else {
+ /* Radix invalid, complete a name token */
+ return(AAH_NAME(ch));
+ }
+}
+
+static int
+add_r_digits(int ch)
+{
+ unsigned long value;
+ long radix, scale;
+ int digit;
+
+ /* NOTE: The syntax of a radix number allows only for
+ * values of zero or more. The value will be stored as
+ * a 32 bit integer, which PostScript then interprets
+ * as signed. This means, for example, that the numbers:
+ *
+ * 8#37777777777
+ * 10#4294967295
+ * 16#FFFFFFFF
+ * 36#1Z141Z3
+ *
+ * are all interpreted as -1. This routine implements this
+ * idea explicitly: it accumulates the number's value
+ * as unsigned, then casts it to signed when done.
+ */
+
+ /* Expect r_base to be initialized */
+ radix = r_base;
+ value = 0;
+ scale = 0;
+
+ /* Scan leading zeroes */
+ while(ch == '0') {
+ save_ch(ch);
+ ch = next_ch();
+ }
+
+ /* Handle first non-zero digit */
+ if ((digit=digit_value[ch]) < radix) {
+ value = digit;
+ save_ch(ch);
+ ch = next_ch();
+
+ /* Add digits until boundary case reached */
+ while((digit=digit_value[ch]) < radix
+ && value < (MAX_ULONG / radix)) {
+ value = value * radix + digit;
+ save_ch(ch);
+ ch = next_ch();
+ };
+
+ /* Scan remaining digits */
+ if ((digit=digit_value[ch]) < radix) {
+
+ /* Examine boundary case ---
+ * radix*(MAX_ULONG/radix) <= number <= MAX_ULONG
+ */
+ if (value == (MAX_ULONG/radix) && digit <= MAX_ULONG%radix)
+ value = value * radix + digit;
+ else
+ ++scale;
+
+ /* Continue scanning digits, but can't store them */
+ save_ch(ch);
+ ch = next_ch();
+ while(digit_value[ch] < radix) {
+ ++scale;
+ save_ch(ch);
+ ch = next_ch();
+ }
+ }
+ }
+
+ /* Store result */
+ r_value = (long) value; /* result is signed */
+ r_scale = scale;
+
+ return(ch);
+}
+
+/* -------------------------------------------------------------------
+ * Complete a number; set token type and done flag.
+ * Put current input character back, if it is not white space.
+ */
+
+/* Done: Radix Number */
+static int
+RADIX_NUMBER(int ch)
+{
+ back_ch_not_white(ch);
+ if (r_scale == 0) {
+ tokenValue.integer = r_value;
+ tokenType = TOKEN_INTEGER;
+ }
+ else {
+ tokenType = TOKEN_NAME;
+ }
+ return(DONE);
+}
+
+/* Done: Integer */
+static int
+INTEGER(int ch)
+{
+ back_ch_not_white(ch);
+ if (m_scale == 0) {
+ tokenValue.integer = m_value;
+ tokenType = TOKEN_INTEGER;
+ }
+ else {
+ tokenValue.real = (double)(m_value) * Exp10(m_scale);
+ tokenType = TOKEN_REAL;
+ }
+ return(DONE);
+}
+
+/* Done: Real */
+static int
+REAL(int ch)
+{
+ double temp;
+
+ back_ch_not_white(ch);
+
+ /* HAZARD: exponent overflow of intermediate result
+ * (e.g., in 370 floating point); this should not be a problem
+ * with IEEE floating point. Reduce exponent overflow hazard by
+ * combining m_scale and e_value first, if they have different signs,
+ * or multiplying m_value and one of the other factors, if both
+ * m_scale and e_value are negative.
+ */
+ if ((m_scale >= 0 && e_value <= 0)
+ || (m_scale <= 0 && e_value >= 0)) {
+ tokenValue.real = (double)(m_value) * Exp10(m_scale + e_value);
+ }
+ else {
+ temp = (double)(m_value) * Exp10(m_scale);
+ tokenValue.real = temp * Exp10(e_value);
+ }
+
+ tokenType = TOKEN_REAL;
+ return(DONE);
+}
+
+
+/* -------------------------------------------------------------------
+ * Assemble a hex string; set token type and done flag.
+ */
+
+/* Done: Hex String */
+static int
+HEX_STRING(int ch)
+{
+ int value;
+
+ while(TRUE) {
+
+ /* Process odd digit */
+ ch = next_ch();
+ if (!isHEX_DIGIT(ch)) {
+
+ /* Skip white space */
+ while(isWHITE_SPACE(ch))
+ ch = next_ch();
+
+ /* Check for terminator */
+ if (!isHEX_DIGIT(ch)) {
+ break;
+ }
+ }
+ value = digit_value[ch] << 4;
+
+ /* Process even digit */
+ ch = next_ch();
+ if (!isHEX_DIGIT(ch)) {
+
+ /* Skip white space */
+ while(isWHITE_SPACE(ch))
+ ch = next_ch();
+
+ /* Check for terminator */
+ if (!isHEX_DIGIT(ch)) {
+ save_ch(value);
+ break;
+ }
+ }
+ save_ch(value + digit_value[ch]);
+ }
+
+ /* Classify result, based on why loop ended */
+ if (ch == '>')
+ tokenType = TOKEN_HEX_STRING;
+ else {
+ /* save the invalid character for error reporting */
+ save_ch(ch);
+ tokenType = TOKEN_INVALID;
+ }
+
+ return(DONE);
+}
+
+/* -------------------------------------------------------------------
+ * Assemble a string; set token type and done flag
+ */
+
+/* Save a backslash-coded character in a string --
+ *
+ * Store the proper character for special cases
+ * "\b", "\f", "\n", "\r", and "\t".
+ *
+ * Decode and store octal-coded character, up to
+ * three octal digits, "\o", "\oo", and "\ooo".
+ *
+ * The sequence "\<newline>" is a line continuation,
+ * so consume both without storing anything.
+ *
+ * The sequence "\<EOF>" is an error; exit without
+ * storing anything and let the caller handle it.
+ *
+ * For other characters, including the sequences
+ * "\\", "\(", and "\)", simply store the second
+ * character.
+ */
+static void
+save_digraph(int ch)
+{
+ int value;
+
+ switch (ch) {
+
+ case 'b': /* backspace */
+ ch = '\b';
+ break;
+
+ case 'f': /* formfeed */
+ ch = '\f';
+ break;
+
+ case 'n': /* newline */
+ ch = '\n';
+ break;
+
+ case 'r': /* carriage return */
+ ch = '\r';
+ break;
+
+ case 't': /* horizontal tab */
+ ch = '\t';
+ break;
+
+ case '\n': /* line continuation -- consume it */
+ return;
+
+ case '\r': /* carriage return -- consume it */
+ ch = next_ch(); /* look at next character, is it \n? */
+ if (ch == '\n') return;
+ back_ch(ch); /* if not a line feed, then return it */
+ return;
+
+ case EOF: /* end of file -- forget it */
+ return;
+
+ default:
+ /* scan up to three octal digits to get value */
+ if (isOCTAL_DIGIT(ch)) {
+ value = digit_value[ch];
+ ch = next_ch();
+ if (isOCTAL_DIGIT(ch)) {
+ value = (value << 3) + digit_value[ch];
+ ch = next_ch();
+ if (isOCTAL_DIGIT(ch))
+ value = (value << 3) + digit_value[ch];
+ else
+ back_ch(ch);
+ }
+ else
+ back_ch(ch);
+ ch = value;
+ }
+ }
+
+ /* Found a character to save */
+ save_ch(ch);
+}
+
+/* Done: String */
+static int
+STRING(int ch)
+{
+ int nest_level = 1;
+
+ tokenType = TOKEN_STRING;
+
+ do {
+
+ ch = next_ch();
+ while(!isSTRING_SPECIAL(ch)) {
+ save_ch(ch);
+ ch = next_ch();
+ };
+
+ switch (ch) {
+
+ case '(':
+ ++nest_level;
+ save_ch(ch);
+ break;
+
+ case ')':
+ if (--nest_level > 0)
+ save_ch(ch);
+ break;
+
+ case '\\':
+ save_digraph(next_ch());
+ break;
+
+ case '\r':
+ /* All carriage returns (\r) are turned into linefeeds (\n)*/
+ ch = next_ch(); /* get the next one, is it \n? */
+ if (ch != '\n') { /* if not, then put it back. */
+ back_ch(ch);
+ }
+ save_ch('\n'); /* in either case, save a linefeed */
+ break;
+
+
+ case EOF:
+ tokenType = TOKEN_INVALID; /* Unterminated string */
+ nest_level = 0;
+ break;
+ }
+
+ } while(nest_level > 0);
+
+ /* If there's room, add a 0-byte termination without increasing string
+ length. This fixes certain dependencies on 0-terminated strings */
+ save_ch_no_inc(0);
+
+ return(DONE);
+}
+
+
+/* -------------------------------------------------------------------
+ * Assemble a name; set token type and done flag.
+ * Put current input character back, if it is not white space.
+ */
+
+/* Done: Name
+ * (Safe version used to complete name tokens that
+ * start out looking like something else).
+ */
+
+static int
+AAH_NAME(int ch)
+{
+ do {
+ save_ch(ch);
+ ch = next_ch();
+ } while(isNAME(ch));
+
+ back_ch_not_white(ch);
+ tokenType = TOKEN_NAME;
+ return(DONE);
+}
+
+/* Done: Name */
+static int
+NAME(int ch)
+{
+ save_unsafe_ch(ch);
+ ch = next_ch();
+ if (isNAME(ch)) {
+ save_unsafe_ch(ch);
+ ch = next_ch();
+ if (isNAME(ch)) {
+ save_unsafe_ch(ch);
+ ch = next_ch();
+ if (isNAME(ch)) {
+ save_unsafe_ch(ch);
+ ch = next_ch();
+ if (isNAME(ch)) {
+ save_unsafe_ch(ch);
+ ch = next_ch();
+ if (isNAME(ch)) {
+ save_unsafe_ch(ch);
+ ch = next_ch();
+ if (isNAME(ch)) {
+ save_unsafe_ch(ch);
+ ch = next_ch();
+ while(isNAME(ch)) {
+ save_ch(ch);
+ ch = next_ch();
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+
+ back_ch_not_white(ch);
+ tokenType = TOKEN_NAME;
+ return(DONE);
+}
+
+/* Done: Literal Name */
+static int
+LITERAL_NAME(int ch)
+{
+ if (isNAME(ch)) {
+ save_unsafe_ch(ch);
+ ch = next_ch();
+ if (isNAME(ch)) {
+ save_unsafe_ch(ch);
+ ch = next_ch();
+ if (isNAME(ch)) {
+ save_unsafe_ch(ch);
+ ch = next_ch();
+ if (isNAME(ch)) {
+ save_unsafe_ch(ch);
+ ch = next_ch();
+ if (isNAME(ch)) {
+ save_unsafe_ch(ch);
+ ch = next_ch();
+ if (isNAME(ch)) {
+ save_unsafe_ch(ch);
+ ch = next_ch();
+ while(isNAME(ch)) {
+ save_ch(ch);
+ ch = next_ch();
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+
+ back_ch_not_white(ch);
+ tokenType = TOKEN_LITERAL_NAME;
+ return(DONE);
+}
+
+/* Done: immediate Name */
+static int
+IMMED_NAME(int ch)
+{
+ ch = next_ch();
+ if (isNAME(ch)) {
+ save_unsafe_ch(ch);
+ ch = next_ch();
+ if (isNAME(ch)) {
+ save_unsafe_ch(ch);
+ ch = next_ch();
+ if (isNAME(ch)) {
+ save_unsafe_ch(ch);
+ ch = next_ch();
+ if (isNAME(ch)) {
+ save_unsafe_ch(ch);
+ ch = next_ch();
+ if (isNAME(ch)) {
+ save_unsafe_ch(ch);
+ ch = next_ch();
+ if (isNAME(ch)) {
+ save_unsafe_ch(ch);
+ ch = next_ch();
+ while(isNAME(ch)) {
+ save_ch(ch);
+ ch = next_ch();
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+
+ back_ch_not_white(ch);
+ tokenType = TOKEN_IMMED_NAME;
+ return(DONE);
+}
+
+/* Done: Name found while looking for something else */
+static int
+OOPS_NAME(int ch)
+{
+ back_ch_not_white(ch);
+ tokenType = TOKEN_NAME;
+ return(DONE);
+}
+
+
+/* -------------------------------------------------------------------
+ * Complete a miscellaneous token; set token type and done flag.
+ */
+
+/* Done: Unmatched Right Angle-Bracket */
+static int
+RIGHT_ANGLE(int ch)
+{
+ tokenType = TOKEN_RIGHT_ANGLE;
+ return(DONE);
+}
+
+/* Done: Unmatched Right Parenthesis */
+static int
+RIGHT_PAREN(int ch)
+{
+ tokenType = TOKEN_RIGHT_PAREN;
+ return(DONE);
+}
+
+/* Done: Left Brace */
+static int
+LEFT_BRACE(int ch)
+{
+ tokenType = TOKEN_LEFT_BRACE;
+ return(DONE);
+}
+
+/* Done: Right Brace */
+static int
+RIGHT_BRACE(int ch)
+{
+ tokenType = TOKEN_RIGHT_BRACE;
+ return(DONE);
+}
+
+/* Done: Left Bracket */
+static int
+LEFT_BRACKET(int ch)
+{
+ save_unsafe_ch(ch);
+ tokenType = TOKEN_LEFT_BRACKET;
+ return(DONE);
+}
+
+/* Done: Right Bracket */
+static int
+RIGHT_BRACKET(int ch)
+{
+ save_unsafe_ch(ch);
+ tokenType = TOKEN_RIGHT_BRACKET;
+ return(DONE);
+}
+
+/* Done: Break */
+static int
+BREAK_SIGNAL(int ch)
+{
+ tokenType = TOKEN_BREAK;
+ return(DONE);
+}
+
+/* Done: No Token Found */
+static int
+NO_TOKEN(int ch)
+{
+ tokenType = TOKEN_EOF;
+ return(DONE);
+}
+
+
+/*
+ * -------------------------------------------------------------------
+ * scan_token -- scan one token from the input. It uses a simple
+ * finite state machine to recognize token classes.
+ *
+ * The input is from a file.
+ *
+ * On entry --
+ *
+ * inputP -> input PostScript object, a file.
+ * tokenStartP -> buffer in VM for accumulating the token.
+ * tokenMaxP -> last character in the token buffer
+ *
+ * On exit --
+ *
+ * tokenLength = number of characters in the token
+ * tokenTooLong = TRUE if the token did not fit in the buffer
+ * tokenType = code for the type of token parsed.
+ * tokenValue = converted value of a numeric token.
+ *
+ *
+ * -------------------------------------------------------------------
+ */
+void
+scan_token(psobj *inputP)
+{
+ int ch;
+ unsigned char *stateP = s0;
+ unsigned char entry;
+ int (*actionP)(int);
+
+ /* Define input source */
+ inputFileP = inputP->data.fileP;
+ if (inputFileP == NULL) {
+ tokenType = TOKEN_EOF;
+ return;
+ }
+
+ /* Ensure enough space for most cases
+ * (so we don't have to keep checking)
+ * The length needs to cover the maximum number
+ * of save_unsafe_ch() calls that might be executed.
+ * That number is 11 (a sign and 10 decimal digits, e.g.,
+ * when scanning -2147483648), but use MAX_NAME_LEN
+ * in case someone changes that without checking.
+ */
+ tokenStartP = vm_next_byte();
+ tokenMaxP = tokenStartP + MIN(vm_free_bytes(), MAX_STRING_LEN);
+
+ if ((tokenMaxP-tokenStartP) < (MAX_NAME_LEN)) {
+ tokenLength = 0;
+ tokenTooLong = TRUE;
+ tokenType = TOKEN_NONE;
+ tokenValue.integer = 0;
+ return;
+ }
+
+ /* Reset token */
+ tokenCharP = tokenStartP;
+ tokenTooLong = FALSE;
+
+ /* Scan one token */
+ ch = next_ch();
+ do {
+ entry = stateP[ch];
+ stateP = classActionTable[entry].nextStateP;
+ actionP = classActionTable[entry].actionRoutineP;
+ ch = (*actionP)(ch);
+ } while(ch != DONE);
+
+
+ /* Return results */
+ tokenLength = tokenCharP - tokenStartP;
+}
diff --git a/libXfont/src/Type1/token.h b/libXfont/src/Type1/token.h
new file mode 100644
index 000000000..663982889
--- /dev/null
+++ b/libXfont/src/Type1/token.h
@@ -0,0 +1,79 @@
+/* $Xorg: token.h,v 1.3 2000/08/17 19:46:34 cpqbld Exp $ */
+/* Copyright International Business Machines,Corp. 1991
+ * All Rights Reserved
+ *
+ * License to use, copy, modify, and distribute this software
+ * and its documentation for any purpose and without fee is
+ * hereby granted, provided that the above copyright notice
+ * appear in all copies and that both that copyright notice and
+ * this permission notice appear in supporting documentation,
+ * and that the name of IBM not be used in advertising or
+ * publicity pertaining to distribution of the software without
+ * specific, written prior permission.
+ *
+ * IBM PROVIDES THIS SOFTWARE "AS IS", WITHOUT ANY WARRANTIES
+ * OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING, BUT NOT
+ * LIMITED TO ANY IMPLIED WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE, AND NONINFRINGEMENT OF
+ * THIRD PARTY RIGHTS. THE ENTIRE RISK AS TO THE QUALITY AND
+ * PERFORMANCE OF THE SOFTWARE, INCLUDING ANY DUTY TO SUPPORT
+ * OR MAINTAIN, BELONGS TO THE LICENSEE. SHOULD ANY PORTION OF
+ * THE SOFTWARE PROVE DEFECTIVE, THE LICENSEE (NOT IBM) ASSUMES
+ * THE ENTIRE COST OF ALL SERVICING, REPAIR AND CORRECTION. IN
+ * NO EVENT SHALL IBM BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING
+ * FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF
+ * CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
+ * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+ * SOFTWARE.
+ */
+/* $XFree86: xc/lib/font/Type1/token.h,v 1.3 1999/08/22 08:58:54 dawes Exp $ */
+
+#ifndef TOKEN_H
+#define TOKEN_H
+
+/* Special characters */
+#define CONTROL_C (3)
+
+/* Token type codes */
+#define TOKEN_INVALID (-3)
+#define TOKEN_BREAK (-2)
+#define TOKEN_EOF (-1)
+#define TOKEN_NONE (0)
+#define TOKEN_LEFT_PAREN (1)
+#define TOKEN_RIGHT_PAREN (2)
+#define TOKEN_LEFT_ANGLE (3)
+#define TOKEN_RIGHT_ANGLE (4)
+#define TOKEN_LEFT_BRACE (5)
+#define TOKEN_RIGHT_BRACE (6)
+#define TOKEN_LEFT_BRACKET (7)
+#define TOKEN_RIGHT_BRACKET (8)
+#define TOKEN_NAME (9)
+#define TOKEN_LITERAL_NAME (10)
+#define TOKEN_INTEGER (11)
+#define TOKEN_REAL (12)
+#define TOKEN_RADIX_NUMBER (13)
+#define TOKEN_HEX_STRING (14)
+#define TOKEN_STRING (15)
+#define TOKEN_IMMED_NAME (16)
+
+/* Token routines */
+extern void scan_token( psobj *inputP );
+
+/*
+ * -------------------------------------------------------------------------
+ * Globals shared -- (everyone else KEEP YOUR MITTS OFF THEM!)
+ * -------------------------------------------------------------------------
+ */
+
+/* These variables are set by the caller */
+extern char *tokenStartP; /* Pointer to token buffer in VM */
+extern char *tokenMaxP; /* Pointer to end of VM we may use + 1 */
+
+/* These variables are set by P_TOKEN */
+extern int tokenLength; /* Characters in token */
+extern boolean tokenTooLong; /* Token too long for space available */
+extern int tokenType; /* Type of token identified */
+extern psvalue tokenValue; /* Token value */
+
+#endif /* TOKEN_H */
diff --git a/libXfont/src/Type1/tokst.h b/libXfont/src/Type1/tokst.h
new file mode 100644
index 000000000..02166afde
--- /dev/null
+++ b/libXfont/src/Type1/tokst.h
@@ -0,0 +1,510 @@
+/* $Xorg: tokst.h,v 1.3 2000/08/17 19:46:34 cpqbld Exp $ */
+/* Copyright International Business Machines,Corp. 1991
+ * All Rights Reserved
+ *
+ * License to use, copy, modify, and distribute this software
+ * and its documentation for any purpose and without fee is
+ * hereby granted, provided that the above copyright notice
+ * appear in all copies and that both that copyright notice and
+ * this permission notice appear in supporting documentation,
+ * and that the name of IBM not be used in advertising or
+ * publicity pertaining to distribution of the software without
+ * specific, written prior permission.
+ *
+ * IBM PROVIDES THIS SOFTWARE "AS IS", WITHOUT ANY WARRANTIES
+ * OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING, BUT NOT
+ * LIMITED TO ANY IMPLIED WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE, AND NONINFRINGEMENT OF
+ * THIRD PARTY RIGHTS. THE ENTIRE RISK AS TO THE QUALITY AND
+ * PERFORMANCE OF THE SOFTWARE, INCLUDING ANY DUTY TO SUPPORT
+ * OR MAINTAIN, BELONGS TO THE LICENSEE. SHOULD ANY PORTION OF
+ * THE SOFTWARE PROVE DEFECTIVE, THE LICENSEE (NOT IBM) ASSUMES
+ * THE ENTIRE COST OF ALL SERVICING, REPAIR AND CORRECTION. IN
+ * NO EVENT SHALL IBM BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING
+ * FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF
+ * CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
+ * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+ * SOFTWARE.
+ */
+/* $XFree86: xc/lib/font/Type1/tokst.h,v 1.3 1999/08/22 08:58:54 dawes Exp $ */
+
+/* -------------------------------------- */
+/* --- MACHINE GENERATED, DO NOT EDIT --- */
+/* -------------------------------------- */
+
+#ifndef TOKST
+#define TOKST 1
+
+/*
+ * State Index Tables --
+ *
+ * These tables map the input character to the
+ * proper entry in the Class Action Table.
+ * There is one table for each state.
+ *
+ */
+#define s0 (si0+2)
+static unsigned char si0[258] = { 0x10,0x11,
+ 0x02,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x02,0x02,0x0F,0x0F,0x02,0x0F,0x0F,
+ 0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,
+ 0x02,0x0F,0x0F,0x0F,0x0F,0x03,0x0F,0x0F,0x05,0x0B,0x0F,0x0D,0x0F,0x0D,0x0E,0x04,
+ 0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x0F,0x0F,0x08,0x0F,0x0C,0x0F,
+ 0x0F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x07,0x0F,0x0A,0x0F,0x0F,
+ 0x0F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x06,0x0F,0x09,0x0F,0x0F,
+ 0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,
+ 0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,
+ 0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,
+ 0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,
+ 0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,
+ 0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,
+ 0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,
+ 0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F
+};
+
+#define s1 (si1+2)
+static unsigned char si1[258] = { 0x14,0x15,
+ 0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,
+ 0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,
+ 0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x12,
+ 0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,
+ 0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,
+ 0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,
+ 0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,
+ 0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,
+ 0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,
+ 0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,
+ 0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,
+ 0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,
+ 0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,
+ 0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,
+ 0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,
+ 0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13
+};
+
+#define s2 (si2+2)
+static unsigned char si2[258] = { 0x1B,0x1C,
+ 0x16,0x1A,0x1A,0x1A,0x1A,0x1A,0x1A,0x1A,0x1A,0x16,0x16,0x1A,0x1A,0x16,0x1A,0x1A,
+ 0x1A,0x1A,0x1A,0x1A,0x1A,0x1A,0x1A,0x1A,0x1A,0x1A,0x1A,0x1A,0x1A,0x1A,0x1A,0x1A,
+ 0x16,0x1A,0x1A,0x1A,0x1A,0x17,0x1A,0x1A,0x17,0x17,0x1A,0x1A,0x1A,0x1A,0x19,0x17,
+ 0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x1A,0x1A,0x17,0x1A,0x17,0x1A,
+ 0x1A,0x1A,0x1A,0x1A,0x1A,0x1A,0x1A,0x1A,0x1A,0x1A,0x1A,0x1A,0x1A,0x1A,0x1A,0x1A,
+ 0x1A,0x1A,0x1A,0x1A,0x1A,0x1A,0x1A,0x1A,0x1A,0x1A,0x1A,0x17,0x1A,0x17,0x1A,0x1A,
+ 0x1A,0x1A,0x1A,0x1A,0x1A,0x1A,0x1A,0x1A,0x1A,0x1A,0x1A,0x1A,0x1A,0x1A,0x1A,0x1A,
+ 0x1A,0x1A,0x1A,0x1A,0x1A,0x1A,0x1A,0x1A,0x1A,0x1A,0x1A,0x17,0x1A,0x17,0x1A,0x1A,
+ 0x1A,0x1A,0x1A,0x1A,0x1A,0x1A,0x1A,0x1A,0x1A,0x1A,0x1A,0x1A,0x1A,0x1A,0x1A,0x1A,
+ 0x1A,0x1A,0x1A,0x1A,0x1A,0x1A,0x1A,0x1A,0x1A,0x1A,0x1A,0x1A,0x1A,0x1A,0x1A,0x1A,
+ 0x1A,0x1A,0x1A,0x1A,0x1A,0x1A,0x1A,0x1A,0x1A,0x1A,0x1A,0x1A,0x1A,0x1A,0x1A,0x1A,
+ 0x1A,0x1A,0x1A,0x1A,0x1A,0x1A,0x1A,0x1A,0x1A,0x1A,0x1A,0x1A,0x1A,0x1A,0x1A,0x1A,
+ 0x1A,0x1A,0x1A,0x1A,0x1A,0x1A,0x1A,0x1A,0x1A,0x1A,0x1A,0x1A,0x1A,0x1A,0x1A,0x1A,
+ 0x1A,0x1A,0x1A,0x1A,0x1A,0x1A,0x1A,0x1A,0x1A,0x1A,0x1A,0x1A,0x1A,0x1A,0x1A,0x1A,
+ 0x1A,0x1A,0x1A,0x1A,0x1A,0x1A,0x1A,0x1A,0x1A,0x1A,0x1A,0x1A,0x1A,0x1A,0x1A,0x1A,
+ 0x1A,0x1A,0x1A,0x1A,0x1A,0x1A,0x1A,0x1A,0x1A,0x1A,0x1A,0x1A,0x1A,0x1A,0x1A,0x1A
+};
+
+#define s3 (si3+2)
+static unsigned char si3[258] = { 0x23,0x24,
+ 0x1D,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x1D,0x1D,0x22,0x22,0x1D,0x22,0x22,
+ 0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,
+ 0x1D,0x22,0x22,0x20,0x22,0x1E,0x22,0x22,0x1E,0x1E,0x22,0x22,0x22,0x22,0x1F,0x1E,
+ 0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x1E,0x22,0x1E,0x22,
+ 0x22,0x22,0x22,0x22,0x22,0x21,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,
+ 0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x1E,0x22,0x1E,0x22,0x22,
+ 0x22,0x22,0x22,0x22,0x22,0x21,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,
+ 0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x1E,0x22,0x1E,0x22,0x22,
+ 0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,
+ 0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,
+ 0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,
+ 0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,
+ 0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,
+ 0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,
+ 0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,
+ 0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22
+};
+
+#define s4 (si4+2)
+static unsigned char si4[258] = { 0x29,0x2A,
+ 0x25,0x28,0x28,0x28,0x28,0x28,0x28,0x28,0x28,0x25,0x25,0x28,0x28,0x25,0x28,0x28,
+ 0x28,0x28,0x28,0x28,0x28,0x28,0x28,0x28,0x28,0x28,0x28,0x28,0x28,0x28,0x28,0x28,
+ 0x25,0x28,0x28,0x28,0x28,0x26,0x28,0x28,0x26,0x26,0x28,0x28,0x28,0x28,0x28,0x26,
+ 0x27,0x27,0x27,0x27,0x27,0x27,0x27,0x27,0x27,0x27,0x28,0x28,0x26,0x28,0x26,0x28,
+ 0x28,0x28,0x28,0x28,0x28,0x28,0x28,0x28,0x28,0x28,0x28,0x28,0x28,0x28,0x28,0x28,
+ 0x28,0x28,0x28,0x28,0x28,0x28,0x28,0x28,0x28,0x28,0x28,0x26,0x28,0x26,0x28,0x28,
+ 0x28,0x28,0x28,0x28,0x28,0x28,0x28,0x28,0x28,0x28,0x28,0x28,0x28,0x28,0x28,0x28,
+ 0x28,0x28,0x28,0x28,0x28,0x28,0x28,0x28,0x28,0x28,0x28,0x26,0x28,0x26,0x28,0x28,
+ 0x28,0x28,0x28,0x28,0x28,0x28,0x28,0x28,0x28,0x28,0x28,0x28,0x28,0x28,0x28,0x28,
+ 0x28,0x28,0x28,0x28,0x28,0x28,0x28,0x28,0x28,0x28,0x28,0x28,0x28,0x28,0x28,0x28,
+ 0x28,0x28,0x28,0x28,0x28,0x28,0x28,0x28,0x28,0x28,0x28,0x28,0x28,0x28,0x28,0x28,
+ 0x28,0x28,0x28,0x28,0x28,0x28,0x28,0x28,0x28,0x28,0x28,0x28,0x28,0x28,0x28,0x28,
+ 0x28,0x28,0x28,0x28,0x28,0x28,0x28,0x28,0x28,0x28,0x28,0x28,0x28,0x28,0x28,0x28,
+ 0x28,0x28,0x28,0x28,0x28,0x28,0x28,0x28,0x28,0x28,0x28,0x28,0x28,0x28,0x28,0x28,
+ 0x28,0x28,0x28,0x28,0x28,0x28,0x28,0x28,0x28,0x28,0x28,0x28,0x28,0x28,0x28,0x28,
+ 0x28,0x28,0x28,0x28,0x28,0x28,0x28,0x28,0x28,0x28,0x28,0x28,0x28,0x28,0x28,0x28
+};
+
+#define s5 (si5+2)
+static unsigned char si5[258] = { 0x30,0x31,
+ 0x2B,0x2F,0x2F,0x2F,0x2F,0x2F,0x2F,0x2F,0x2F,0x2B,0x2B,0x2F,0x2F,0x2B,0x2F,0x2F,
+ 0x2F,0x2F,0x2F,0x2F,0x2F,0x2F,0x2F,0x2F,0x2F,0x2F,0x2F,0x2F,0x2F,0x2F,0x2F,0x2F,
+ 0x2B,0x2F,0x2F,0x2F,0x2F,0x2C,0x2F,0x2F,0x2C,0x2C,0x2F,0x2F,0x2F,0x2F,0x2F,0x2C,
+ 0x2E,0x2E,0x2E,0x2E,0x2E,0x2E,0x2E,0x2E,0x2E,0x2E,0x2F,0x2F,0x2C,0x2F,0x2C,0x2F,
+ 0x2F,0x2F,0x2F,0x2F,0x2F,0x2D,0x2F,0x2F,0x2F,0x2F,0x2F,0x2F,0x2F,0x2F,0x2F,0x2F,
+ 0x2F,0x2F,0x2F,0x2F,0x2F,0x2F,0x2F,0x2F,0x2F,0x2F,0x2F,0x2C,0x2F,0x2C,0x2F,0x2F,
+ 0x2F,0x2F,0x2F,0x2F,0x2F,0x2D,0x2F,0x2F,0x2F,0x2F,0x2F,0x2F,0x2F,0x2F,0x2F,0x2F,
+ 0x2F,0x2F,0x2F,0x2F,0x2F,0x2F,0x2F,0x2F,0x2F,0x2F,0x2F,0x2C,0x2F,0x2C,0x2F,0x2F,
+ 0x2F,0x2F,0x2F,0x2F,0x2F,0x2F,0x2F,0x2F,0x2F,0x2F,0x2F,0x2F,0x2F,0x2F,0x2F,0x2F,
+ 0x2F,0x2F,0x2F,0x2F,0x2F,0x2F,0x2F,0x2F,0x2F,0x2F,0x2F,0x2F,0x2F,0x2F,0x2F,0x2F,
+ 0x2F,0x2F,0x2F,0x2F,0x2F,0x2F,0x2F,0x2F,0x2F,0x2F,0x2F,0x2F,0x2F,0x2F,0x2F,0x2F,
+ 0x2F,0x2F,0x2F,0x2F,0x2F,0x2F,0x2F,0x2F,0x2F,0x2F,0x2F,0x2F,0x2F,0x2F,0x2F,0x2F,
+ 0x2F,0x2F,0x2F,0x2F,0x2F,0x2F,0x2F,0x2F,0x2F,0x2F,0x2F,0x2F,0x2F,0x2F,0x2F,0x2F,
+ 0x2F,0x2F,0x2F,0x2F,0x2F,0x2F,0x2F,0x2F,0x2F,0x2F,0x2F,0x2F,0x2F,0x2F,0x2F,0x2F,
+ 0x2F,0x2F,0x2F,0x2F,0x2F,0x2F,0x2F,0x2F,0x2F,0x2F,0x2F,0x2F,0x2F,0x2F,0x2F,0x2F,
+ 0x2F,0x2F,0x2F,0x2F,0x2F,0x2F,0x2F,0x2F,0x2F,0x2F,0x2F,0x2F,0x2F,0x2F,0x2F,0x2F
+};
+
+#define s6 (si6+2)
+static unsigned char si6[258] = { 0x36,0x37,
+ 0x32,0x35,0x35,0x35,0x35,0x35,0x35,0x35,0x35,0x32,0x32,0x35,0x35,0x32,0x35,0x35,
+ 0x35,0x35,0x35,0x35,0x35,0x35,0x35,0x35,0x35,0x35,0x35,0x35,0x35,0x35,0x35,0x35,
+ 0x32,0x35,0x35,0x35,0x35,0x33,0x35,0x35,0x33,0x33,0x35,0x35,0x35,0x35,0x35,0x33,
+ 0x35,0x35,0x35,0x35,0x35,0x35,0x35,0x35,0x35,0x35,0x35,0x35,0x33,0x35,0x33,0x35,
+ 0x35,0x35,0x35,0x35,0x35,0x34,0x35,0x35,0x35,0x35,0x35,0x35,0x35,0x35,0x35,0x35,
+ 0x35,0x35,0x35,0x35,0x35,0x35,0x35,0x35,0x35,0x35,0x35,0x33,0x35,0x33,0x35,0x35,
+ 0x35,0x35,0x35,0x35,0x35,0x34,0x35,0x35,0x35,0x35,0x35,0x35,0x35,0x35,0x35,0x35,
+ 0x35,0x35,0x35,0x35,0x35,0x35,0x35,0x35,0x35,0x35,0x35,0x33,0x35,0x33,0x35,0x35,
+ 0x35,0x35,0x35,0x35,0x35,0x35,0x35,0x35,0x35,0x35,0x35,0x35,0x35,0x35,0x35,0x35,
+ 0x35,0x35,0x35,0x35,0x35,0x35,0x35,0x35,0x35,0x35,0x35,0x35,0x35,0x35,0x35,0x35,
+ 0x35,0x35,0x35,0x35,0x35,0x35,0x35,0x35,0x35,0x35,0x35,0x35,0x35,0x35,0x35,0x35,
+ 0x35,0x35,0x35,0x35,0x35,0x35,0x35,0x35,0x35,0x35,0x35,0x35,0x35,0x35,0x35,0x35,
+ 0x35,0x35,0x35,0x35,0x35,0x35,0x35,0x35,0x35,0x35,0x35,0x35,0x35,0x35,0x35,0x35,
+ 0x35,0x35,0x35,0x35,0x35,0x35,0x35,0x35,0x35,0x35,0x35,0x35,0x35,0x35,0x35,0x35,
+ 0x35,0x35,0x35,0x35,0x35,0x35,0x35,0x35,0x35,0x35,0x35,0x35,0x35,0x35,0x35,0x35,
+ 0x35,0x35,0x35,0x35,0x35,0x35,0x35,0x35,0x35,0x35,0x35,0x35,0x35,0x35,0x35,0x35
+};
+
+#define s7 (si7+2)
+static unsigned char si7[258] = { 0x3D,0x3E,
+ 0x38,0x3C,0x3C,0x3C,0x3C,0x3C,0x3C,0x3C,0x3C,0x38,0x38,0x3C,0x3C,0x38,0x3C,0x3C,
+ 0x3C,0x3C,0x3C,0x3C,0x3C,0x3C,0x3C,0x3C,0x3C,0x3C,0x3C,0x3C,0x3C,0x3C,0x3C,0x3C,
+ 0x38,0x3C,0x3C,0x3C,0x3C,0x39,0x3C,0x3C,0x39,0x39,0x3C,0x3A,0x3C,0x3A,0x3C,0x39,
+ 0x3B,0x3B,0x3B,0x3B,0x3B,0x3B,0x3B,0x3B,0x3B,0x3B,0x3C,0x3C,0x39,0x3C,0x39,0x3C,
+ 0x3C,0x3C,0x3C,0x3C,0x3C,0x3C,0x3C,0x3C,0x3C,0x3C,0x3C,0x3C,0x3C,0x3C,0x3C,0x3C,
+ 0x3C,0x3C,0x3C,0x3C,0x3C,0x3C,0x3C,0x3C,0x3C,0x3C,0x3C,0x39,0x3C,0x39,0x3C,0x3C,
+ 0x3C,0x3C,0x3C,0x3C,0x3C,0x3C,0x3C,0x3C,0x3C,0x3C,0x3C,0x3C,0x3C,0x3C,0x3C,0x3C,
+ 0x3C,0x3C,0x3C,0x3C,0x3C,0x3C,0x3C,0x3C,0x3C,0x3C,0x3C,0x39,0x3C,0x39,0x3C,0x3C,
+ 0x3C,0x3C,0x3C,0x3C,0x3C,0x3C,0x3C,0x3C,0x3C,0x3C,0x3C,0x3C,0x3C,0x3C,0x3C,0x3C,
+ 0x3C,0x3C,0x3C,0x3C,0x3C,0x3C,0x3C,0x3C,0x3C,0x3C,0x3C,0x3C,0x3C,0x3C,0x3C,0x3C,
+ 0x3C,0x3C,0x3C,0x3C,0x3C,0x3C,0x3C,0x3C,0x3C,0x3C,0x3C,0x3C,0x3C,0x3C,0x3C,0x3C,
+ 0x3C,0x3C,0x3C,0x3C,0x3C,0x3C,0x3C,0x3C,0x3C,0x3C,0x3C,0x3C,0x3C,0x3C,0x3C,0x3C,
+ 0x3C,0x3C,0x3C,0x3C,0x3C,0x3C,0x3C,0x3C,0x3C,0x3C,0x3C,0x3C,0x3C,0x3C,0x3C,0x3C,
+ 0x3C,0x3C,0x3C,0x3C,0x3C,0x3C,0x3C,0x3C,0x3C,0x3C,0x3C,0x3C,0x3C,0x3C,0x3C,0x3C,
+ 0x3C,0x3C,0x3C,0x3C,0x3C,0x3C,0x3C,0x3C,0x3C,0x3C,0x3C,0x3C,0x3C,0x3C,0x3C,0x3C,
+ 0x3C,0x3C,0x3C,0x3C,0x3C,0x3C,0x3C,0x3C,0x3C,0x3C,0x3C,0x3C,0x3C,0x3C,0x3C,0x3C
+};
+
+#define s8 (si8+2)
+static unsigned char si8[258] = { 0x43,0x44,
+ 0x3F,0x42,0x42,0x42,0x42,0x42,0x42,0x42,0x42,0x3F,0x3F,0x42,0x42,0x3F,0x42,0x42,
+ 0x42,0x42,0x42,0x42,0x42,0x42,0x42,0x42,0x42,0x42,0x42,0x42,0x42,0x42,0x42,0x42,
+ 0x3F,0x42,0x42,0x42,0x42,0x40,0x42,0x42,0x40,0x40,0x42,0x42,0x42,0x42,0x42,0x40,
+ 0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x42,0x42,0x40,0x42,0x40,0x42,
+ 0x42,0x42,0x42,0x42,0x42,0x42,0x42,0x42,0x42,0x42,0x42,0x42,0x42,0x42,0x42,0x42,
+ 0x42,0x42,0x42,0x42,0x42,0x42,0x42,0x42,0x42,0x42,0x42,0x40,0x42,0x40,0x42,0x42,
+ 0x42,0x42,0x42,0x42,0x42,0x42,0x42,0x42,0x42,0x42,0x42,0x42,0x42,0x42,0x42,0x42,
+ 0x42,0x42,0x42,0x42,0x42,0x42,0x42,0x42,0x42,0x42,0x42,0x40,0x42,0x40,0x42,0x42,
+ 0x42,0x42,0x42,0x42,0x42,0x42,0x42,0x42,0x42,0x42,0x42,0x42,0x42,0x42,0x42,0x42,
+ 0x42,0x42,0x42,0x42,0x42,0x42,0x42,0x42,0x42,0x42,0x42,0x42,0x42,0x42,0x42,0x42,
+ 0x42,0x42,0x42,0x42,0x42,0x42,0x42,0x42,0x42,0x42,0x42,0x42,0x42,0x42,0x42,0x42,
+ 0x42,0x42,0x42,0x42,0x42,0x42,0x42,0x42,0x42,0x42,0x42,0x42,0x42,0x42,0x42,0x42,
+ 0x42,0x42,0x42,0x42,0x42,0x42,0x42,0x42,0x42,0x42,0x42,0x42,0x42,0x42,0x42,0x42,
+ 0x42,0x42,0x42,0x42,0x42,0x42,0x42,0x42,0x42,0x42,0x42,0x42,0x42,0x42,0x42,0x42,
+ 0x42,0x42,0x42,0x42,0x42,0x42,0x42,0x42,0x42,0x42,0x42,0x42,0x42,0x42,0x42,0x42,
+ 0x42,0x42,0x42,0x42,0x42,0x42,0x42,0x42,0x42,0x42,0x42,0x42,0x42,0x42,0x42,0x42
+};
+
+#define s9 (si9+2)
+static unsigned char si9[258] = { 0x48,0x49,
+ 0x45,0x47,0x47,0x47,0x47,0x47,0x47,0x47,0x47,0x45,0x45,0x47,0x47,0x45,0x47,0x47,
+ 0x47,0x47,0x47,0x47,0x47,0x47,0x47,0x47,0x47,0x47,0x47,0x47,0x47,0x47,0x47,0x47,
+ 0x45,0x47,0x47,0x47,0x47,0x46,0x47,0x47,0x46,0x46,0x47,0x47,0x47,0x47,0x47,0x46,
+ 0x47,0x47,0x47,0x47,0x47,0x47,0x47,0x47,0x47,0x47,0x47,0x47,0x46,0x47,0x46,0x47,
+ 0x47,0x47,0x47,0x47,0x47,0x47,0x47,0x47,0x47,0x47,0x47,0x47,0x47,0x47,0x47,0x47,
+ 0x47,0x47,0x47,0x47,0x47,0x47,0x47,0x47,0x47,0x47,0x47,0x46,0x47,0x46,0x47,0x47,
+ 0x47,0x47,0x47,0x47,0x47,0x47,0x47,0x47,0x47,0x47,0x47,0x47,0x47,0x47,0x47,0x47,
+ 0x47,0x47,0x47,0x47,0x47,0x47,0x47,0x47,0x47,0x47,0x47,0x46,0x47,0x46,0x47,0x47,
+ 0x47,0x47,0x47,0x47,0x47,0x47,0x47,0x47,0x47,0x47,0x47,0x47,0x47,0x47,0x47,0x47,
+ 0x47,0x47,0x47,0x47,0x47,0x47,0x47,0x47,0x47,0x47,0x47,0x47,0x47,0x47,0x47,0x47,
+ 0x47,0x47,0x47,0x47,0x47,0x47,0x47,0x47,0x47,0x47,0x47,0x47,0x47,0x47,0x47,0x47,
+ 0x47,0x47,0x47,0x47,0x47,0x47,0x47,0x47,0x47,0x47,0x47,0x47,0x47,0x47,0x47,0x47,
+ 0x47,0x47,0x47,0x47,0x47,0x47,0x47,0x47,0x47,0x47,0x47,0x47,0x47,0x47,0x47,0x47,
+ 0x47,0x47,0x47,0x47,0x47,0x47,0x47,0x47,0x47,0x47,0x47,0x47,0x47,0x47,0x47,0x47,
+ 0x47,0x47,0x47,0x47,0x47,0x47,0x47,0x47,0x47,0x47,0x47,0x47,0x47,0x47,0x47,0x47,
+ 0x47,0x47,0x47,0x47,0x47,0x47,0x47,0x47,0x47,0x47,0x47,0x47,0x47,0x47,0x47,0x47
+};
+
+#define s10 (si10+2)
+static unsigned char si10[258] = { 0x4E,0x4F,
+ 0x4A,0x4D,0x4D,0x4D,0x4D,0x4D,0x4D,0x4D,0x4D,0x4A,0x4A,0x4D,0x4D,0x4A,0x4D,0x4D,
+ 0x4D,0x4D,0x4D,0x4D,0x4D,0x4D,0x4D,0x4D,0x4D,0x4D,0x4D,0x4D,0x4D,0x4D,0x4D,0x4D,
+ 0x4A,0x4D,0x4D,0x4D,0x4D,0x4B,0x4D,0x4D,0x4B,0x4B,0x4D,0x4D,0x4D,0x4D,0x4D,0x4B,
+ 0x4C,0x4C,0x4C,0x4C,0x4C,0x4C,0x4C,0x4C,0x4C,0x4C,0x4D,0x4D,0x4B,0x4D,0x4B,0x4D,
+ 0x4D,0x4C,0x4C,0x4C,0x4C,0x4C,0x4C,0x4C,0x4C,0x4C,0x4C,0x4C,0x4C,0x4C,0x4C,0x4C,
+ 0x4C,0x4C,0x4C,0x4C,0x4C,0x4C,0x4C,0x4C,0x4C,0x4C,0x4C,0x4B,0x4D,0x4B,0x4D,0x4D,
+ 0x4D,0x4C,0x4C,0x4C,0x4C,0x4C,0x4C,0x4C,0x4C,0x4C,0x4C,0x4C,0x4C,0x4C,0x4C,0x4C,
+ 0x4C,0x4C,0x4C,0x4C,0x4C,0x4C,0x4C,0x4C,0x4C,0x4C,0x4C,0x4B,0x4D,0x4B,0x4D,0x4D,
+ 0x4D,0x4D,0x4D,0x4D,0x4D,0x4D,0x4D,0x4D,0x4D,0x4D,0x4D,0x4D,0x4D,0x4D,0x4D,0x4D,
+ 0x4D,0x4D,0x4D,0x4D,0x4D,0x4D,0x4D,0x4D,0x4D,0x4D,0x4D,0x4D,0x4D,0x4D,0x4D,0x4D,
+ 0x4D,0x4D,0x4D,0x4D,0x4D,0x4D,0x4D,0x4D,0x4D,0x4D,0x4D,0x4D,0x4D,0x4D,0x4D,0x4D,
+ 0x4D,0x4D,0x4D,0x4D,0x4D,0x4D,0x4D,0x4D,0x4D,0x4D,0x4D,0x4D,0x4D,0x4D,0x4D,0x4D,
+ 0x4D,0x4D,0x4D,0x4D,0x4D,0x4D,0x4D,0x4D,0x4D,0x4D,0x4D,0x4D,0x4D,0x4D,0x4D,0x4D,
+ 0x4D,0x4D,0x4D,0x4D,0x4D,0x4D,0x4D,0x4D,0x4D,0x4D,0x4D,0x4D,0x4D,0x4D,0x4D,0x4D,
+ 0x4D,0x4D,0x4D,0x4D,0x4D,0x4D,0x4D,0x4D,0x4D,0x4D,0x4D,0x4D,0x4D,0x4D,0x4D,0x4D,
+ 0x4D,0x4D,0x4D,0x4D,0x4D,0x4D,0x4D,0x4D,0x4D,0x4D,0x4D,0x4D,0x4D,0x4D,0x4D,0x4D
+};
+
+#define s11 (si11+2)
+static unsigned char si11[258] = { 0x53,0x54,
+ 0x50,0x52,0x52,0x52,0x52,0x52,0x52,0x52,0x52,0x50,0x50,0x52,0x52,0x50,0x52,0x52,
+ 0x52,0x52,0x52,0x52,0x52,0x52,0x52,0x52,0x52,0x52,0x52,0x52,0x52,0x52,0x52,0x52,
+ 0x50,0x52,0x52,0x52,0x52,0x51,0x52,0x52,0x51,0x51,0x52,0x52,0x52,0x52,0x52,0x51,
+ 0x52,0x52,0x52,0x52,0x52,0x52,0x52,0x52,0x52,0x52,0x52,0x52,0x51,0x52,0x51,0x52,
+ 0x52,0x52,0x52,0x52,0x52,0x52,0x52,0x52,0x52,0x52,0x52,0x52,0x52,0x52,0x52,0x52,
+ 0x52,0x52,0x52,0x52,0x52,0x52,0x52,0x52,0x52,0x52,0x52,0x51,0x52,0x51,0x52,0x52,
+ 0x52,0x52,0x52,0x52,0x52,0x52,0x52,0x52,0x52,0x52,0x52,0x52,0x52,0x52,0x52,0x52,
+ 0x52,0x52,0x52,0x52,0x52,0x52,0x52,0x52,0x52,0x52,0x52,0x51,0x52,0x51,0x52,0x52,
+ 0x52,0x52,0x52,0x52,0x52,0x52,0x52,0x52,0x52,0x52,0x52,0x52,0x52,0x52,0x52,0x52,
+ 0x52,0x52,0x52,0x52,0x52,0x52,0x52,0x52,0x52,0x52,0x52,0x52,0x52,0x52,0x52,0x52,
+ 0x52,0x52,0x52,0x52,0x52,0x52,0x52,0x52,0x52,0x52,0x52,0x52,0x52,0x52,0x52,0x52,
+ 0x52,0x52,0x52,0x52,0x52,0x52,0x52,0x52,0x52,0x52,0x52,0x52,0x52,0x52,0x52,0x52,
+ 0x52,0x52,0x52,0x52,0x52,0x52,0x52,0x52,0x52,0x52,0x52,0x52,0x52,0x52,0x52,0x52,
+ 0x52,0x52,0x52,0x52,0x52,0x52,0x52,0x52,0x52,0x52,0x52,0x52,0x52,0x52,0x52,0x52,
+ 0x52,0x52,0x52,0x52,0x52,0x52,0x52,0x52,0x52,0x52,0x52,0x52,0x52,0x52,0x52,0x52,
+ 0x52,0x52,0x52,0x52,0x52,0x52,0x52,0x52,0x52,0x52,0x52,0x52,0x52,0x52,0x52,0x52
+};
+
+/*
+ * Class Action Table --
+ *
+ * The entries in the Class Action Table indicate the
+ * action routine to be called, and the next state to
+ * enter, for each relevant character class in each.
+ * state. There are several entries for each state.
+ *
+ */
+static int AAH_NAME ( int ch );
+static int BREAK_SIGNAL ( int ch );
+static int HEX_STRING ( int ch );
+static int IMMED_NAME ( int ch );
+static int INTEGER ( int ch );
+static int LEFT_BRACE ( int ch );
+static int LEFT_BRACKET ( int ch );
+static int LITERAL_NAME ( int ch );
+static int NAME ( int ch );
+static int NO_TOKEN ( int ch );
+static int OOPS_NAME ( int ch );
+static int RADIX_NUMBER ( int ch );
+static int REAL ( int ch );
+static int RIGHT_ANGLE ( int ch );
+static int RIGHT_BRACE ( int ch );
+static int RIGHT_BRACKET ( int ch );
+static int RIGHT_PAREN ( int ch );
+static int STRING ( int ch );
+static int add_1st_decpt ( int ch );
+static int add_1st_digits ( int ch );
+static int add_char ( int ch );
+static int add_decpt ( int ch );
+static int add_digits ( int ch );
+static int add_exponent ( int ch );
+static int add_e_sign ( int ch );
+static int add_fraction ( int ch );
+static int add_radix ( int ch );
+static int add_r_digits ( int ch );
+static int add_sign ( int ch );
+static int next_char ( int ch );
+static int skip_comment ( int ch );
+static int skip_space ( int ch );
+
+static struct cat {
+ int (*actionRoutineP)(int);
+ unsigned char *nextStateP;
+} classActionTable[] = {
+
+ /* s0: Classify initial character */
+ /* 00 ALPHA */ {NAME, s0}, /* executable name */
+ /* 01 DIGIT */ {add_1st_digits, s3}, /* number? */
+ /* 02 WHITE_SPACE */ {skip_space, s0}, /* skip white space */
+ /* 03 PERCENT */ {skip_comment, s0}, /* comment? */
+ /* 04 SLASH */ {next_char, s1}, /* literal or imm name */
+ /* 05 LEFT_PAREN */ {STRING, s0}, /* string */
+ /* 06 LEFT_BRACE */ {LEFT_BRACE, s0}, /* begin procedure body */
+ /* 07 LEFT_BRACKET */ {LEFT_BRACKET, s0}, /* begin array */
+ /* 08 LEFT_ANGLE */ {HEX_STRING, s0}, /* hex string? */
+ /* 09 RIGHT_BRACE */ {RIGHT_BRACE, s0}, /* end procedure body */
+ /* 0A RIGHT_BRACKET */ {RIGHT_BRACKET, s0}, /* end array */
+ /* 0B RIGHT_PAREN */ {RIGHT_PAREN, s0}, /* unmatched right paren */
+ /* 0C RIGHT_ANGLE */ {RIGHT_ANGLE, s0}, /* unmatched right angle */
+ /* 0D SIGN */ {add_sign, s2}, /* signed number? */
+ /* 0E DECIMAL_POINT */ {add_1st_decpt, s4}, /* real number? */
+ /* 0F ANY */ {NAME, s0}, /* executable name */
+ /* 10 BREAK */ {BREAK_SIGNAL, s0}, /* break signalled */
+ /* 11 EOF */ {NO_TOKEN, s0}, /* no token found */
+
+ /* s1: Further classify a '/' */
+ /* 12 SLASH */ {IMMED_NAME, s0}, /* immediate name */
+ /* 13 ANY */ {LITERAL_NAME, s0}, /* literal name */
+ /* 14 BREAK */ {BREAK_SIGNAL, s0}, /* break signalled */
+ /* 15 EOF */ {OOPS_NAME, s0}, /* isolated sign */
+
+ /* s2: sign */
+ /* 16 WHITE_SPACE */ {OOPS_NAME, s0}, /* isolated sign */
+ /* 17 SPECIAL */ {OOPS_NAME, s0}, /* isolated sign */
+ /* 18 DIGIT */ {add_digits, s3}, /* number? */
+ /* 19 DECIMAL_POINT */ {add_decpt, s4}, /* real number? */
+ /* 1A ANY */ {NAME, s0}, /* executable name */
+ /* 1B BREAK */ {BREAK_SIGNAL, s0}, /* break signalled */
+ /* 1C EOF */ {OOPS_NAME, s0}, /* isolated sign */
+
+ /* s3: sign? digit+ */
+ /* 1D WHITE_SPACE */ {INTEGER, s0}, /* n-digit integer */
+ /* 1E SPECIAL */ {INTEGER, s0}, /* n-digit integer */
+ /* 1F DECIMAL_POINT */ {add_char, s5}, /* real number? */
+ /* 20 POUND */ {add_radix, s10}, /* radix number? */
+ /* 21 eE */ {add_char, s7}, /* real with exponent? */
+ /* 22 ANY */ {AAH_NAME, s0}, /* executable name */
+ /* 23 BREAK */ {BREAK_SIGNAL, s0}, /* break signalled */
+ /* 24 EOF */ {INTEGER, s0}, /* n-digit integer */
+
+ /* s4: sign? . */
+ /* 25 WHITE_SPACE */ {OOPS_NAME, s0}, /* isolated +. or -. */
+ /* 26 SPECIAL */ {OOPS_NAME, s0}, /* isolated +. or -. */
+ /* 27 DIGIT */ {add_fraction, s6}, /* number? */
+ /* 28 ANY */ {NAME, s0}, /* executable name */
+ /* 29 BREAK */ {BREAK_SIGNAL, s0}, /* break signalled */
+ /* 2A EOF */ {OOPS_NAME, s0}, /* isolated +. or -. */
+
+ /* s5: sign? digit+ . */
+ /* 2B WHITE_SPACE */ {REAL, s0}, /* real with fraction */
+ /* 2C SPECIAL */ {REAL, s0}, /* real with fraction */
+ /* 2D eE */ {add_char, s7}, /* real with exponent? */
+ /* 2E DIGIT */ {add_fraction, s6}, /* number? */
+ /* 2F ANY */ {AAH_NAME, s0}, /* executable name */
+ /* 30 BREAK */ {BREAK_SIGNAL, s0}, /* break signalled */
+ /* 31 EOF */ {REAL, s0}, /* real with fraction */
+
+ /* s6: sign? (digit+ . digit+) | (. digit+) */
+ /* 32 WHITE_SPACE */ {REAL, s0}, /* real with fraction */
+ /* 33 SPECIAL */ {REAL, s0}, /* real with fraction */
+ /* 34 eE */ {add_char, s7}, /* real with exponent? */
+ /* 35 ANY */ {AAH_NAME, s0}, /* executable name */
+ /* 36 BREAK */ {BREAK_SIGNAL, s0}, /* break signalled */
+ /* 37 EOF */ {REAL, s0}, /* real with fraction */
+
+ /* s7: sign? ((digit+ (. digit*)?) | (. digit+)) Ee */
+ /* 38 WHITE_SPACE */ {OOPS_NAME, s0}, /* invalid real number */
+ /* 39 SPECIAL */ {OOPS_NAME, s0}, /* invalid real number */
+ /* 3A SIGN */ {add_e_sign, s8}, /* real w signed exponent? */
+ /* 3B DIGIT */ {add_exponent, s9}, /* real w exponent ? */
+ /* 3C ANY */ {AAH_NAME, s0}, /* executable name */
+ /* 3D BREAK */ {BREAK_SIGNAL, s0}, /* break signalled */
+ /* 3E EOF */ {OOPS_NAME, s0}, /* invalid real number */
+
+ /* s8: sign? (digit+ (. digit*)? | (digit* . digit+) Ee sign */
+ /* 3F WHITE_SPACE */ {OOPS_NAME, s0}, /* invalid real number */
+ /* 40 SPECIAL */ {OOPS_NAME, s0}, /* invalid real number */
+ /* 41 DIGIT */ {add_exponent, s9}, /* real w exponent? */
+ /* 42 ANY */ {AAH_NAME, s0}, /* executable name */
+ /* 43 BREAK */ {BREAK_SIGNAL, s0}, /* break signalled */
+ /* 44 EOF */ {OOPS_NAME, s0}, /* invalid real number */
+
+ /* s9: sign? (digit+ (. digit*)? | (digit* . digit+) Ee sign? digit+ */
+ /* 45 WHITE_SPACE */ {REAL, s0}, /* real w exponent */
+ /* 46 SPECIAL */ {REAL, s0}, /* real w exponent */
+ /* 47 ANY */ {AAH_NAME, s0}, /* executable name */
+ /* 48 BREAK */ {BREAK_SIGNAL, s0}, /* break signalled */
+ /* 49 EOF */ {REAL, s0}, /* real w exponent */
+
+ /* s10: digit+ # */
+ /* 4A WHITE_SPACE */ {OOPS_NAME, s0}, /* invalid radix number */
+ /* 4B SPECIAL */ {OOPS_NAME, s0}, /* invalid radix number */
+ /* 4C R_DIGIT */ {add_r_digits, s11}, /* radix number? */
+ /* 4D ANY */ {AAH_NAME, s0}, /* executable name */
+ /* 4E BREAK */ {BREAK_SIGNAL, s0}, /* break signalled */
+ /* 4F EOF */ {OOPS_NAME, s0}, /* invalid radix number */
+
+ /* s11: digit+ # r_digit+ */
+ /* 50 WHITE_SPACE */ {RADIX_NUMBER, s0}, /* radix number */
+ /* 51 SPECIAL */ {RADIX_NUMBER, s0}, /* radix number */
+ /* 52 ANY */ {AAH_NAME, s0}, /* executable name */
+ /* 53 BREAK */ {BREAK_SIGNAL, s0}, /* break signalled */
+ /* 54 EOF */ {RADIX_NUMBER, s0} /* radix number */
+};
+
+/*
+ * Character Classification Tables --
+ *
+ * The entries in the Character Classification Tables
+ * map character codes to character classes. The
+ * tables contains one entry per code. The bits in
+ * each entry indicate which classes the character
+ * code belongs to.
+ *
+ * The macros 'isInCLASS(ch)' generate code to test
+ * whether 'ch' is a character in 'CLASS'.
+ *
+ */
+/* Membership macros for classes defined in table 1 ... */
+#define isRADIX_DIGIT(c) ((isInP1[c] & 0x80) != 0)
+#define isHEX_DIGIT(c) ((isInP1[c] & 0x40) != 0)
+#define isDECIMAL_DIGIT(c) ((isInP1[c] & 0x10) != 0)
+#define isOCTAL_DIGIT(c) ((isInP1[c] & 0x20) != 0)
+
+/* Membership macros for classes defined in table 2 ... */
+#define isWHITE_SPACE(c) ((isInP2[c] & 0x80) != 0)
+#define isCOMMENT(c) ((isInP2[c] & 0x40) != 0)
+#define isNAME(c) ((isInP2[c] & 0x20) != 0)
+#define isSTRING_SPECIAL(c) ((isInP2[c] & 0x10) != 0)
+#define isNUMBER_ENDER(c) ((isInP2[c] & 0x08) != 0)
+
+#define isInP1 (isInT1+2)
+static unsigned char isInT1[258] = { 0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xD0,0xD0,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,
+ 0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,
+ 0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+};
+
+#define isInP2 (isInT2+2)
+static unsigned char isInT2[258] = { 0x18,0x18,
+ 0xC8,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0xC8,0x88,0x60,0x60,0x98,0x60,0x60,
+ 0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,
+ 0xC8,0x60,0x60,0x60,0x60,0x48,0x60,0x60,0x58,0x58,0x60,0x60,0x60,0x60,0x60,0x48,
+ 0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x48,0x60,0x48,0x60,
+ 0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,
+ 0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x48,0x70,0x48,0x60,0x60,
+ 0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,
+ 0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x48,0x60,0x48,0x60,0x60,
+ 0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,
+ 0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,
+ 0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,
+ 0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,
+ 0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,
+ 0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,
+ 0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,
+ 0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60
+};
+
+#endif
diff --git a/libXfont/src/Type1/trig.h b/libXfont/src/Type1/trig.h
new file mode 100644
index 000000000..d569ed067
--- /dev/null
+++ b/libXfont/src/Type1/trig.h
@@ -0,0 +1,41 @@
+/* $Xorg: trig.h,v 1.3 2000/08/17 19:46:34 cpqbld Exp $ */
+/* Copyright International Business Machines,Corp. 1991
+ * All Rights Reserved
+ *
+ * License to use, copy, modify, and distribute this software
+ * and its documentation for any purpose and without fee is
+ * hereby granted, provided that the above copyright notice
+ * appear in all copies and that both that copyright notice and
+ * this permission notice appear in supporting documentation,
+ * and that the name of IBM not be used in advertising or
+ * publicity pertaining to distribution of the software without
+ * specific, written prior permission.
+ *
+ * IBM PROVIDES THIS SOFTWARE "AS IS", WITHOUT ANY WARRANTIES
+ * OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING, BUT NOT
+ * LIMITED TO ANY IMPLIED WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE, AND NONINFRINGEMENT OF
+ * THIRD PARTY RIGHTS. THE ENTIRE RISK AS TO THE QUALITY AND
+ * PERFORMANCE OF THE SOFTWARE, INCLUDING ANY DUTY TO SUPPORT
+ * OR MAINTAIN, BELONGS TO THE LICENSEE. SHOULD ANY PORTION OF
+ * THE SOFTWARE PROVE DEFECTIVE, THE LICENSEE (NOT IBM) ASSUMES
+ * THE ENTIRE COST OF ALL SERVICING, REPAIR AND CORRECTION. IN
+ * NO EVENT SHALL IBM BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING
+ * FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF
+ * CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
+ * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+ * SOFTWARE.
+ */
+/*SHARED*/
+
+/* $XFree86: xc/lib/font/Type1/trig.h,v 1.2 1998/07/25 06:57:00 dawes Exp $ */
+
+#undef DegreeCos
+#undef DegreeSin
+#undef sqrt
+
+#define DegreeCos(d) xiStub()
+#define DegreeSin(d) xiStub()
+#define sqrt(d) xiStub()
+
diff --git a/libXfont/src/Type1/type1.c b/libXfont/src/Type1/type1.c
new file mode 100644
index 000000000..5515f461c
--- /dev/null
+++ b/libXfont/src/Type1/type1.c
@@ -0,0 +1,1797 @@
+/* $Xorg: type1.c,v 1.4 2000/08/17 19:46:34 cpqbld Exp $ */
+/* Copyright International Business Machines, Corp. 1991
+ * All Rights Reserved
+ * Copyright Lexmark International, Inc. 1991
+ * All Rights Reserved
+ * Portions Copyright (c) 1990 Adobe Systems Incorporated.
+ * All Rights Reserved
+ *
+ * License to use, copy, modify, and distribute this software and its
+ * documentation for any purpose and without fee is hereby granted,
+ * provided that the above copyright notice appear in all copies and that
+ * both that copyright notice and this permission notice appear in
+ * supporting documentation, and that the name of IBM or Lexmark or Adobe
+ * not be used in advertising or publicity pertaining to distribution of
+ * the software without specific, written prior permission.
+ *
+ * IBM, LEXMARK, AND ADOBE PROVIDE THIS SOFTWARE "AS IS", WITHOUT ANY
+ * WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING, BUT NOT
+ * LIMITED TO ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
+ * PARTICULAR PURPOSE, AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. THE
+ * ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE SOFTWARE, INCLUDING
+ * ANY DUTY TO SUPPORT OR MAINTAIN, BELONGS TO THE LICENSEE. SHOULD ANY
+ * PORTION OF THE SOFTWARE PROVE DEFECTIVE, THE LICENSEE (NOT IBM,
+ * LEXMARK, OR ADOBE) ASSUMES THE ENTIRE COST OF ALL SERVICING, REPAIR AND
+ * CORRECTION. IN NO EVENT SHALL IBM, LEXMARK, OR ADOBE BE LIABLE FOR ANY
+ * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
+ * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF
+ * CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+/* $XFree86: xc/lib/font/Type1/type1.c,v 1.9tsi Exp $ */
+
+/*********************************************************************/
+/* */
+/* Type 1 module - Converting fonts in Adobe Type 1 Font Format */
+/* to scaled and hinted paths for rasterization. */
+/* Files: type1.c, type1.h, and blues.h. */
+/* */
+/* Authors: Sten F. Andler, IBM Almaden Research Center */
+/* (Type 1 interpreter, stem & flex hints) */
+/* */
+/* Patrick A. Casey, Lexmark International, Inc. */
+/* (Font level hints & stem hints) */
+/* */
+/*********************************************************************/
+
+/******************/
+/* Include Files: */
+/******************/
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#ifndef FONTMODULE
+#include <stdio.h> /* a system-dependent include, usually */
+#include <math.h>
+#else
+#include "Xdefs.h"
+#include "Xmd.h"
+#include "xf86_ansic.h"
+#endif
+#include "objects.h"
+#include "spaces.h"
+#include "paths.h"
+#include "fonts.h" /* understands about TEXTTYPEs */
+#include "pictures.h" /* understands about handles */
+
+typedef struct xobject xobject;
+#include "util.h" /* PostScript objects */
+#include "fontfcn.h"
+#include "blues.h" /* Blues structure for font-level hints */
+
+/**********************************/
+/* Type1 Constants and Structures */
+/**********************************/
+#define MAXSTACK 24 /* Adobe Type1 limit */
+#define MAXCALLSTACK 10 /* Adobe Type1 limit */
+#define MAXPSFAKESTACK 32 /* Max depth of fake PostScript stack (local) */
+#define MAXSTRLEN 512 /* Max length of a Type 1 string (local) */
+#define MAXLABEL 256 /* Maximum number of new hints */
+#define MAXSTEMS 128 /* Maximum number of VSTEM and HSTEM hints */
+#define EPS 0.001 /* Small number for comparisons */
+
+/************************************/
+/* Adobe Type 1 CharString commands */
+/************************************/
+#define HSTEM 1
+#define VSTEM 3
+#define VMOVETO 4
+#define RLINETO 5
+#define HLINETO 6
+#define VLINETO 7
+#define RRCURVETO 8
+#define CLOSEPATH 9
+#define CALLSUBR 10
+#define RETURN 11
+#define ESCAPE 12
+#define HSBW 13
+#define ENDCHAR 14
+#define RMOVETO 21
+#define HMOVETO 22
+#define VHCURVETO 30
+#define HVCURVETO 31
+
+/*******************************************/
+/* Adobe Type 1 CharString Escape commands */
+/*******************************************/
+#define DOTSECTION 0
+#define VSTEM3 1
+#define HSTEM3 2
+#define SEAC 6
+#define SBW 7
+#define DIV 12
+#define CALLOTHERSUBR 16
+#define POP 17
+#define SETCURRENTPOINT 33
+
+/*****************/
+/* Useful macros */
+/*****************/
+
+#define FABS(x) fabs(x)
+
+#define CEIL(x) ceil(x)
+
+#define FLOOR(x) floor(x)
+
+#define ROUND(x) FLOOR((x) + 0.5)
+
+#define ODD(x) (((int)(x)) & 01)
+
+#define Error {errflag = TRUE; return;}
+#define ErrorRet(ret) {errflag = TRUE; return (ret);}
+
+/********************/
+/* global variables */
+/********************/
+struct stem { /* representation of a STEM hint */
+ int vertical; /* TRUE if vertical, FALSE otherwise */
+ double x, dx; /* interval of vertical stem */
+ double y, dy; /* interval of horizontal stem */
+ struct segment *lbhint, *lbrevhint; /* left or bottom hint adjustment */
+ struct segment *rthint, *rtrevhint; /* right or top hint adjustment */
+};
+
+struct xobject *Type1Char(char *env, struct XYspace *S,
+ psobj *charstrP, psobj *subrsP, psobj *osubrsP,
+ struct blues_struct *bluesP, int *modeP);
+
+static double escapementX, escapementY;
+static double sidebearingX, sidebearingY;
+static double accentoffsetX, accentoffsetY;
+
+static struct segment *path;
+static int errflag;
+
+/*************************************************/
+/* Global variables to hold Type1Char parameters */
+/*************************************************/
+static char *Environment;
+static struct XYspace *CharSpace;
+static psobj *CharStringP, *SubrsP;
+
+/************************/
+/* Forward declarations */
+/************************/
+static struct segment *Applyhint ( struct segment *p, int stemnumber,
+ int half );
+static struct segment *Applyrevhint ( struct segment *p, int stemnumber,
+ int half );
+static void CallOtherSubr ( int othersubrno );
+static void CallSubr ( int subrno );
+static struct segment *CenterStem ( double edge1, double edge2 );
+static void ClearCallStack ( void );
+static void ClearPSFakeStack ( void );
+static void ClearStack ( void );
+static void ComputeAlignmentZones ( void );
+static void ComputeStem ( int stemno );
+static void Decode ( int Code );
+static unsigned char Decrypt ( unsigned char cipher );
+static double Div ( double num1, double num2 );
+static void DoClosePath ( void );
+static void DoCommand ( int Code );
+static int DoRead ( int *CodeP );
+static void DotSection ( void );
+static void EndChar ( void );
+static void Escape ( int Code );
+static struct segment *FindStems ( double x, double y, double dx, double dy );
+static void FinitStems ( void );
+static void FlxProc ( double c1x2, double c1y2, double c3x0, double c3y0,
+ double c3x1, double c3y1, double c3x2, double c3y2,
+ double c4x0, double c4y0, double c4x1, double c4y1,
+ double c4x2, double c4y2, double epY, double epX,
+ int idmin );
+static void FlxProc1 ( void );
+static void FlxProc2 ( void );
+static void HintReplace ( void );
+static void HStem ( double y, double dy );
+static void InitStems ( void );
+static void PopCall ( psobj **CurrStrPP, int *CurrIndexP,
+ unsigned short *CurrKeyP );
+static double PSFakePop ( void );
+static void PSFakePush ( double Num );
+static void Push ( double Num );
+static void PushCall ( psobj *CurrStrP, int CurrIndex,
+ unsigned short CurrKey );
+static void Return ( void );
+static void RLineTo ( double dx, double dy );
+static void RMoveTo ( double dx, double dy );
+static void RRCurveTo ( double dx1, double dy1, double dx2, double dy2,
+ double dx3, double dy3 );
+static void Sbw ( double sbx, double sby, double wx, double wy );
+static void Seac ( double asb, double adx, double ady, unsigned char bchar,
+ unsigned char achar );
+static void SetCurrentPoint ( double x, double y );
+static void StartDecrypt ( void );
+static void VStem ( double x, double dx );
+
+/*****************************************/
+/* statics for Flex procedures (FlxProc) */
+/*****************************************/
+static struct segment *FlxOldPath; /* save path before Flex feature */
+
+/******************************************************/
+/* statics for Font level hints (Blues) (see blues.h) */
+/******************************************************/
+static struct blues_struct *blues; /* the blues structure */
+static struct alignmentzone alignmentzones[MAXALIGNMENTZONES];
+static int numalignmentzones; /* total number of alignment zones */
+
+/****************************************************************/
+/* Subroutines for the Font level hints (Alignment zones, etc.) */
+/****************************************************************/
+
+/******************************************/
+/* Fill in the alignment zone structures. */
+/******************************************/
+static void
+ComputeAlignmentZones(void)
+{
+ int i;
+ double dummy, bluezonepixels, familyzonepixels;
+ struct segment *p;
+
+ numalignmentzones = 0; /* initialize total # of zones */
+
+ /* do the BlueValues zones */
+ for (i = 0; i < blues->numBlueValues; i +=2, ++numalignmentzones) {
+ /* the 0th & 1st numbers in BlueValues are for a bottom zone */
+ /* the rest are topzones */
+ if (i == 0) /* bottom zone */
+ alignmentzones[numalignmentzones].topzone = FALSE;
+ else /* top zone */
+ alignmentzones[numalignmentzones].topzone = TRUE;
+ if (i < blues->numFamilyBlues) { /* we must consider FamilyBlues */
+ p = ILoc(CharSpace,0,blues->BlueValues[i] - blues->BlueValues[i+1]);
+ QueryLoc(p, IDENTITY, &dummy, &bluezonepixels);
+ Destroy(p);
+ p = ILoc(CharSpace,0,blues->FamilyBlues[i]-blues->FamilyBlues[i+1]);
+ QueryLoc(p, IDENTITY, &dummy, &familyzonepixels);
+ Destroy(p);
+ /* is the difference in size of the zones less than 1 pixel? */
+ if (FABS(bluezonepixels - familyzonepixels) < 1.0) {
+ /* use the Family zones */
+ alignmentzones[numalignmentzones].bottomy =
+ blues->FamilyBlues[i];
+ alignmentzones[numalignmentzones].topy =
+ blues->FamilyBlues[i+1];
+ continue;
+ }
+ }
+ /* use this font's Blue zones */
+ alignmentzones[numalignmentzones].bottomy = blues->BlueValues[i];
+ alignmentzones[numalignmentzones].topy = blues->BlueValues[i+1];
+ }
+
+ /* do the OtherBlues zones */
+ for (i = 0; i < blues->numOtherBlues; i +=2, ++numalignmentzones) {
+ /* all of the OtherBlues zones are bottom zones */
+ alignmentzones[numalignmentzones].topzone = FALSE;
+ if (i < blues->numFamilyOtherBlues) {/* consider FamilyOtherBlues */
+ p = ILoc(CharSpace,0,blues->OtherBlues[i] - blues->OtherBlues[i+1]);
+ QueryLoc(p, IDENTITY, &dummy, &bluezonepixels);
+ Destroy(p);
+ p = ILoc(CharSpace,0,blues->FamilyOtherBlues[i] -
+ blues->FamilyOtherBlues[i+1]);
+ QueryLoc(p, IDENTITY, &dummy, &familyzonepixels);
+ Destroy(p);
+ /* is the difference in size of the zones less than 1 pixel? */
+ if (FABS(bluezonepixels - familyzonepixels) < 1.0) {
+ /* use the Family zones */
+ alignmentzones[numalignmentzones].bottomy =
+ blues->FamilyOtherBlues[i];
+ alignmentzones[numalignmentzones].topy =
+ blues->FamilyOtherBlues[i+1];
+ continue;
+ }
+ }
+ /* use this font's Blue zones (as opposed to the Family Blues */
+ alignmentzones[numalignmentzones].bottomy = blues->OtherBlues[i];
+ alignmentzones[numalignmentzones].topy = blues->OtherBlues[i+1];
+ }
+}
+
+/**********************************************************************/
+/* Subroutines and statics for handling of the VSTEM and HSTEM hints. */
+/**********************************************************************/
+static int InDotSection; /* DotSection flag */
+static struct stem stems[MAXSTEMS]; /* All STEM hints */
+static int numstems; /* Number of STEM hints */
+static int currstartstem; /* The current starting stem. */
+static int oldvert, oldhor; /* Remember hint in effect */
+static int oldhorhalf, oldverthalf; /* Remember which half of the stem */
+static double wsoffsetX, wsoffsetY; /* White space offset - for VSTEM3,HSTEM3 */
+static int wsset; /* Flag for whether we've set wsoffsetX,Y */
+
+static void
+InitStems(void) /* Initialize the STEM hint data structures */
+{
+ InDotSection = FALSE;
+ currstartstem = numstems = 0;
+ oldvert = oldhor = -1;
+}
+
+static void
+FinitStems(void) /* Terminate the STEM hint data structures */
+{
+ int i;
+
+ for (i = 0; i < numstems; i++) {
+ Destroy(stems[i].lbhint);
+ Destroy(stems[i].lbrevhint);
+ Destroy(stems[i].rthint);
+ Destroy(stems[i].rtrevhint);
+ }
+}
+
+/*******************************************************************/
+/* Compute the dislocation that a stemhint should cause for points */
+/* inside the stem. */
+/*******************************************************************/
+static void
+ComputeStem(int stemno)
+{
+ int verticalondevice, idealwidth;
+ double stemstart, stemwidth;
+ struct segment *p;
+ int i;
+ double stembottom, stemtop, flatposition;
+ double Xpixels, Ypixels;
+ double unitpixels, onepixel;
+ int suppressovershoot, enforceovershoot;
+ double stemshift, flatpospixels, overshoot;
+ double widthdiff; /* Number of character space units to adjust width */
+ double lbhintvalue, rthintvalue;
+ double cxx, cyx, cxy, cyy; /* Transformation matrix */
+ int rotated; /* TRUE if character is on the side, FALSE if upright */
+
+ /************************************************/
+ /* DETERMINE ORIENTATION OF CHARACTER ON DEVICE */
+ /************************************************/
+
+ QuerySpace(CharSpace, &cxx, &cyx, &cxy, &cyy); /* Transformation matrix */
+
+ if (FABS(cxx) < 0.00001 || FABS(cyy) < 0.00001)
+ rotated = TRUE; /* Char is on side (90 or 270 degrees), possibly oblique. */
+ else if (FABS(cyx) < 0.00001 || FABS(cxy) < 0.00001)
+ rotated = FALSE; /* Char is upright (0 or 180 degrees), possibly oblique. */
+ else {
+ stems[stemno].lbhint = NULL; /* Char is at non-axial angle, ignore hints. */
+ stems[stemno].lbrevhint = NULL;
+ stems[stemno].rthint = NULL;
+ stems[stemno].rtrevhint = NULL;
+ return;
+ }
+
+ /* Determine orientation of stem */
+
+ if (stems[stemno].vertical) {
+ verticalondevice = !rotated;
+ stemstart = stems[stemno].x;
+ stemwidth = stems[stemno].dx;
+ } else {
+ verticalondevice = rotated;
+ stemstart = stems[stemno].y;
+ stemwidth = stems[stemno].dy;
+ }
+
+ /* Determine how many pixels (non-negative) correspond to 1 character space
+ unit (unitpixels), and how many character space units (non-negative)
+ correspond to one pixel (onepixel). */
+
+ if (stems[stemno].vertical)
+ p = ILoc(CharSpace, 1, 0);
+ else
+ p = ILoc(CharSpace, 0, 1);
+ QueryLoc(p, IDENTITY, &Xpixels, &Ypixels);
+ Destroy(p);
+ if (verticalondevice)
+ unitpixels = FABS(Xpixels);
+ else
+ unitpixels = FABS(Ypixels);
+
+ onepixel = 1.0 / unitpixels;
+
+ /**********************/
+ /* ADJUST STEM WIDTHS */
+ /**********************/
+
+ widthdiff = 0.0;
+
+ /* Find standard stem with smallest width difference from this stem */
+ if (stems[stemno].vertical) { /* vertical stem */
+ if (blues->StdVW != 0) /* there is an entry for StdVW */
+ widthdiff = blues->StdVW - stemwidth;
+ for (i = 0; i < blues->numStemSnapV; ++i) { /* now look at StemSnapV */
+ if (blues->StemSnapV[i] - stemwidth < widthdiff)
+ /* this standard width is the best match so far for this stem */
+ widthdiff = blues->StemSnapV[i] - stemwidth;
+ }
+ } else { /* horizontal stem */
+ if (blues->StdHW != 0) /* there is an entry for StdHW */
+ widthdiff = blues->StdHW - stemwidth;
+ for (i = 0; i < blues->numStemSnapH; ++i) { /* now look at StemSnapH */
+ if (blues->StemSnapH[i] - stemwidth < widthdiff)
+ /* this standard width is the best match so far for this stem */
+ widthdiff = blues->StemSnapH[i] - stemwidth;
+ }
+ }
+
+ /* Only expand or contract stems if they differ by less than 1 pixel from
+ the closest standard width, otherwise make the width difference = 0. */
+ if (FABS(widthdiff) > onepixel)
+ widthdiff = 0.0;
+
+ /* Expand or contract stem to the nearest integral number of pixels. */
+ idealwidth = ROUND((stemwidth + widthdiff) * unitpixels);
+ /* Ensure that all stems are at least one pixel wide. */
+ if (idealwidth == 0)
+ idealwidth = 1;
+ /* Apply ForceBold to vertical stems. */
+ if (blues->ForceBold && stems[stemno].vertical)
+ /* Force this vertical stem to be at least DEFAULTBOLDSTEMWIDTH wide. */
+ if (idealwidth < DEFAULTBOLDSTEMWIDTH)
+ idealwidth = DEFAULTBOLDSTEMWIDTH;
+ /* Now compute the number of character space units necessary */
+ widthdiff = idealwidth * onepixel - stemwidth;
+
+ /*********************************************************************/
+ /* ALIGNMENT ZONES AND OVERSHOOT SUPPRESSION - HORIZONTAL STEMS ONLY */
+ /*********************************************************************/
+
+ stemshift = 0.0;
+
+ if (!stems[stemno].vertical) {
+
+ /* Get bottom and top boundaries of the stem. */
+ stembottom = stemstart;
+ stemtop = stemstart + stemwidth;
+
+ /* Find out if this stem intersects an alignment zone (the BlueFuzz */
+ /* entry in the Private dictionary specifies the number of character */
+ /* units to extend (in both directions) the effect of an alignment */
+ /* zone on a horizontal stem. The default value of BlueFuzz is 1. */
+ for (i = 0; i < numalignmentzones; ++i) {
+ if (alignmentzones[i].topzone) {
+ if (stemtop >= alignmentzones[i].bottomy &&
+ stemtop <= alignmentzones[i].topy + blues->BlueFuzz) {
+ break; /* We found a top-zone */
+ }
+ } else {
+ if (stembottom <= alignmentzones[i].topy &&
+ stembottom >= alignmentzones[i].bottomy - blues->BlueFuzz) {
+ break; /* We found a bottom-zone */
+ }
+ }
+ }
+
+ if (i < numalignmentzones) { /* We found an intersecting zone (number i). */
+ suppressovershoot = FALSE;
+ enforceovershoot = FALSE;
+
+ /* When 1 character space unit is rendered smaller than BlueScale
+ device units (pixels), we must SUPPRESS overshoots. Otherwise,
+ if the top (or bottom) of this stem is more than BlueShift character
+ space units away from the flat position, we must ENFORCE overshoot. */
+
+ if (unitpixels < blues->BlueScale)
+ suppressovershoot = TRUE;
+ else
+ if (alignmentzones[i].topzone) {
+ if (stemtop >= alignmentzones[i].bottomy + blues->BlueShift)
+ enforceovershoot = TRUE;
+ } else
+ if (stembottom <= alignmentzones[i].topy - blues->BlueShift)
+ enforceovershoot = TRUE;
+
+ /*************************************************/
+ /* ALIGN THE FLAT POSITION OF THE ALIGNMENT ZONE */
+ /*************************************************/
+
+ /* Compute the position of the alignment zone's flat position in
+ device space and the amount of shift needed to align it on a
+ pixel boundary. Move all stems this amount. */
+
+ if (alignmentzones[i].topzone)
+ flatposition = alignmentzones[i].bottomy;
+ else
+ flatposition = alignmentzones[i].topy;
+
+ /* Find the flat position in pixels */
+ flatpospixels = flatposition * unitpixels;
+
+ /* Find the stem shift necessary to align the flat
+ position on a pixel boundary, and use this shift for all stems */
+ stemshift = (ROUND(flatpospixels) - flatpospixels) * onepixel;
+
+ /************************************************/
+ /* HANDLE OVERSHOOT ENFORCEMENT AND SUPPRESSION */
+ /************************************************/
+
+ /* Compute overshoot amount (non-negative) */
+ if (alignmentzones[i].topzone)
+ overshoot = stemtop - flatposition;
+ else
+ overshoot = flatposition - stembottom;
+
+ if (overshoot > 0.0) {
+ /* ENFORCE overshoot by shifting the entire stem (if necessary) so that
+ it falls at least one pixel beyond the flat position. */
+
+ if (enforceovershoot)
+ if (overshoot < onepixel) {
+ if (alignmentzones[i].topzone)
+ stemshift += onepixel - overshoot;
+ else
+ stemshift -= onepixel - overshoot;
+ }
+ /* SUPPRESS overshoot by aligning the stem to the alignment zone's
+ flat position. */
+
+ if (suppressovershoot) {
+ if (alignmentzones[i].topzone)
+ stemshift -= overshoot;
+ else
+ stemshift += overshoot;
+ }
+ }
+
+ /************************************************************/
+ /* COMPUTE HINT VALUES FOR EACH SIDE OF THE HORIZONTAL STEM */
+ /************************************************************/
+
+ /* If the stem was aligned by a topzone, we expand or contract the stem
+ only at the bottom - since the stem top was aligned by the zone.
+ If the stem was aligned by a bottomzone, we expand or contract the stem
+ only at the top - since the stem bottom was aligned by the zone. */
+ if (alignmentzones[i].topzone) {
+ lbhintvalue = stemshift - widthdiff; /* bottom */
+ rthintvalue = stemshift; /* top */
+ } else {
+ lbhintvalue = stemshift; /* bottom */
+ rthintvalue = stemshift + widthdiff; /* top */
+ }
+
+ stems[stemno].lbhint = (struct segment *)Permanent(Loc(CharSpace, 0.0, lbhintvalue));
+ stems[stemno].lbrevhint = (struct segment *)Permanent(Loc(CharSpace, 0.0, -lbhintvalue));
+ stems[stemno].rthint = (struct segment *)Permanent(Loc(CharSpace, 0.0, rthintvalue));
+ stems[stemno].rtrevhint = (struct segment *)Permanent(Loc(CharSpace, 0.0, -rthintvalue));
+
+ return;
+
+ } /* endif (i < numalignmentzones) */
+
+ /* We didn't find any alignment zones intersecting this stem, so
+ proceed with normal stem alignment below. */
+
+ } /* endif (!stems[stemno].vertical) */
+
+ /* Align stem with pixel boundaries on device */
+ stemstart = stemstart - widthdiff / 2;
+ stemshift = ROUND(stemstart * unitpixels) * onepixel - stemstart;
+
+ /* Adjust the boundaries of the stem */
+ lbhintvalue = stemshift - widthdiff / 2; /* left or bottom */
+ rthintvalue = stemshift + widthdiff / 2; /* right or top */
+
+ if (stems[stemno].vertical) {
+ stems[stemno].lbhint = (struct segment *)Permanent(Loc(CharSpace, lbhintvalue, 0.0));
+ stems[stemno].lbrevhint = (struct segment *)Permanent(Loc(CharSpace, -lbhintvalue, 0.0));
+ stems[stemno].rthint = (struct segment *)Permanent(Loc(CharSpace, rthintvalue, 0.0));
+ stems[stemno].rtrevhint = (struct segment *)Permanent(Loc(CharSpace, -rthintvalue, 0.0));
+ } else {
+ stems[stemno].lbhint = (struct segment *)Permanent(Loc(CharSpace, 0.0, lbhintvalue));
+ stems[stemno].lbrevhint = (struct segment *)Permanent(Loc(CharSpace, 0.0, -lbhintvalue));
+ stems[stemno].rthint = (struct segment *)Permanent(Loc(CharSpace, 0.0, rthintvalue));
+ stems[stemno].rtrevhint = (struct segment *)Permanent(Loc(CharSpace, 0.0, -rthintvalue));
+ }
+}
+
+#define LEFT 1
+#define RIGHT 2
+#define BOTTOM 3
+#define TOP 4
+
+/*********************************************************************/
+/* Adjust a point using the given stem hint. Use the left/bottom */
+/* hint value or the right/top hint value depending on where the */
+/* point lies in the stem. */
+/*********************************************************************/
+static struct segment *
+Applyhint(struct segment *p, int stemnumber, int half)
+{
+ if (half == LEFT || half == BOTTOM)
+ return Join(p, stems[stemnumber].lbhint); /* left or bottom hint */
+ else
+ return Join(p, stems[stemnumber].rthint); /* right or top hint */
+}
+
+/*********************************************************************/
+/* Adjust a point using the given reverse hint. Use the left/bottom */
+/* hint value or the right/top hint value depending on where the */
+/* point lies in the stem. */
+/*********************************************************************/
+static struct segment *
+Applyrevhint(struct segment *p, int stemnumber, int half)
+{
+ if (half == LEFT || half == BOTTOM)
+ return Join(p, stems[stemnumber].lbrevhint); /* left or bottom hint */
+ else
+ return Join(p, stems[stemnumber].rtrevhint); /* right or top hint */
+}
+
+/***********************************************************************/
+/* Find the vertical and horizontal stems that the current point */
+/* (x, y) may be involved in. At most one horizontal and one vertical */
+/* stem can apply to a single point, since there are no overlaps */
+/* allowed. */
+/* The actual hintvalue is returned as a location. */
+/* Hints are ignored inside a DotSection. */
+/***********************************************************************/
+static struct segment *
+FindStems(double x, double y, double dx, double dy)
+{
+ int i;
+ int newvert, newhor;
+ struct segment *p;
+ int newhorhalf, newverthalf;
+
+ if (InDotSection) return(NULL);
+
+ newvert = newhor = -1;
+ newhorhalf = newverthalf = -1;
+
+ for (i = currstartstem; i < numstems; i++) {
+ if (stems[i].vertical) { /* VSTEM hint */
+ if ((x >= stems[i].x - EPS) &&
+ (x <= stems[i].x+stems[i].dx + EPS)) {
+ newvert = i;
+ if (dy != 0.0) {
+ if (dy < 0) newverthalf = LEFT;
+ else newverthalf = RIGHT;
+ } else {
+ if (x < stems[i].x+stems[i].dx / 2) newverthalf = LEFT;
+ else newverthalf = RIGHT;
+ }
+ }
+ } else { /* HSTEM hint */
+ if ((y >= stems[i].y - EPS) &&
+ (y <= stems[i].y+stems[i].dy + EPS)) {
+ newhor = i;
+ if (dx != 0.0) {
+ if (dx < 0) newhorhalf = TOP;
+ else newhorhalf = BOTTOM;
+ } else {
+ if (y < stems[i].y+stems[i].dy / 2) newhorhalf = BOTTOM;
+ else newhorhalf = TOP;
+ }
+ }
+ }
+ }
+
+ p = NULL;
+
+ if (newvert == -1 && oldvert == -1) ; /* Outside of any hints */
+ else if (newvert == oldvert &&
+ newverthalf == oldverthalf); /* No hint change */
+ else if (oldvert == -1) { /* New vertical hint in effect */
+ p = Applyhint(p, newvert, newverthalf);
+ } else if (newvert == -1) { /* Old vertical hint no longer in effect */
+ p = Applyrevhint(p, oldvert, oldverthalf);
+ } else { /* New vertical hint in effect, old hint no longer in effect */
+ p = Applyrevhint(p, oldvert, oldverthalf);
+ p = Applyhint(p, newvert, newverthalf);
+ }
+
+ if (newhor == -1 && oldhor == -1) ; /* Outside of any hints */
+ else if (newhor == oldhor &&
+ newhorhalf == oldhorhalf) ; /* No hint change */
+ else if (oldhor == -1) { /* New horizontal hint in effect */
+ p = Applyhint(p, newhor, newhorhalf);
+ } else if (newhor == -1) { /* Old horizontal hint no longer in effect */
+ p = Applyrevhint(p, oldhor, oldhorhalf);
+ }
+ else { /* New horizontal hint in effect, old hint no longer in effect */
+ p = Applyrevhint(p, oldhor, oldhorhalf);
+ p = Applyhint(p, newhor, newhorhalf);
+ }
+
+ oldvert = newvert; oldverthalf = newverthalf;
+ oldhor = newhor; oldhorhalf = newhorhalf;
+
+ return p;
+}
+
+/******************************************************/
+/* Subroutines and statics for the Type1Char routines */
+/******************************************************/
+
+static int strindex; /* index into PostScript string being interpreted */
+static double currx, curry; /* accumulated x and y values for hints */
+
+struct callstackentry {
+ psobj *currstrP; /* current CharStringP */
+ int currindex; /* current strindex */
+ unsigned short currkey; /* current decryption key */
+ };
+
+static double Stack[MAXSTACK];
+static int Top;
+static struct callstackentry CallStack[MAXCALLSTACK];
+static int CallTop;
+static double PSFakeStack[MAXPSFAKESTACK];
+static int PSFakeTop;
+
+static void
+ClearStack(void)
+{
+ Top = -1;
+}
+
+static void
+Push(double Num)
+{
+ if (++Top < MAXSTACK) Stack[Top] = Num;
+ else Error;
+}
+
+static void
+ClearCallStack(void)
+{
+ CallTop = -1;
+}
+
+static void
+PushCall(psobj *CurrStrP, int CurrIndex, unsigned short CurrKey)
+{
+ if (++CallTop < MAXCALLSTACK) {
+ CallStack[CallTop].currstrP = CurrStrP; /* save CharString pointer */
+ CallStack[CallTop].currindex = CurrIndex; /* save CharString index */
+ CallStack[CallTop].currkey = CurrKey; /* save decryption key */
+ }
+ else Error;
+}
+
+static void
+PopCall(psobj **CurrStrPP, int *CurrIndexP, unsigned short *CurrKeyP)
+{
+ if (CallTop >= 0) {
+ *CurrStrPP = CallStack[CallTop].currstrP; /* restore CharString pointer */
+ *CurrIndexP = CallStack[CallTop].currindex; /* restore CharString index */
+ *CurrKeyP = CallStack[CallTop--].currkey; /* restore decryption key */
+ }
+ else Error;
+}
+
+static void
+ClearPSFakeStack(void)
+{
+ PSFakeTop = -1;
+}
+
+/* PSFakePush: Pushes a number onto the fake PostScript stack */
+static void
+PSFakePush(double Num)
+{
+ if (++PSFakeTop < MAXPSFAKESTACK) PSFakeStack[PSFakeTop] = Num;
+ else Error;
+}
+
+/* PSFakePop: Removes a number from the top of the fake PostScript stack */
+static double
+PSFakePop (void)
+{
+ if (PSFakeTop >= 0) return(PSFakeStack[PSFakeTop--]);
+ else ErrorRet(0.0);
+ /*NOTREACHED*/
+}
+
+/***********************************************************************/
+/* Center a stem on the pixel grid -- used by HStem3 and VStem3 */
+/***********************************************************************/
+static struct segment *
+CenterStem(double edge1, double edge2)
+{
+ int idealwidth, verticalondevice;
+ double leftx, lefty, rightx, righty, center, width;
+ double widthx, widthy;
+ double shift, shiftx, shifty;
+ double Xpixels, Ypixels;
+ struct segment *p;
+
+ p = Loc(CharSpace, edge1, 0.0);
+ QueryLoc(p, IDENTITY, &leftx, &lefty);
+
+ p = Join(p, Loc(CharSpace, edge2, 0.0));
+ QueryLoc(p, IDENTITY, &rightx, &righty);
+ Destroy(p);
+
+ widthx = FABS(rightx - leftx);
+ widthy = FABS(righty - lefty);
+
+ if (widthy <= EPS) { /* verticalondevice hint */
+ verticalondevice = TRUE;
+ center = (rightx + leftx) / 2.0;
+ width = widthx;
+ }
+ else if (widthx <= EPS) { /* horizontal hint */
+ verticalondevice = FALSE;
+ center = (righty + lefty) / 2.0;
+ width = widthy;
+ }
+ else { /* neither horizontal nor verticalondevice and not oblique */
+ return (NULL);
+ }
+
+ idealwidth = ROUND(width);
+ if (idealwidth == 0) idealwidth = 1;
+ if (ODD(idealwidth)) { /* is ideal width odd? */
+ /* center stem over pixel */
+ shift = FLOOR(center) + 0.5 - center;
+ }
+ else {
+ /* align stem on pixel boundary */
+ shift = ROUND(center) - center;
+ }
+
+ if (verticalondevice) {
+ shiftx = shift;
+ shifty = 0.0;
+ } else {
+ shifty = shift;
+ shiftx = 0.0;
+ }
+
+ p = Loc(IDENTITY, shiftx, shifty);
+ QueryLoc(p, CharSpace, &Xpixels, &Ypixels);
+ wsoffsetX = Xpixels; wsoffsetY = Ypixels;
+ currx += wsoffsetX; curry += wsoffsetY;
+
+ return (p);
+}
+
+/*-----------------------------------------------------------------------
+ Decrypt - From Adobe Type 1 book page 63, with some modifications
+-----------------------------------------------------------------------*/
+#define KEY 4330 /* Initial key (seed) for CharStrings decryption */
+#define C1 52845 /* Multiplier for pseudo-random number generator */
+#define C2 22719 /* Constant for pseudo-random number generator */
+
+static unsigned short r; /* Pseudo-random sequence of keys */
+
+static unsigned char
+Decrypt(unsigned char cipher)
+{
+ unsigned char plain;
+
+ plain = cipher ^ (r >> 8);
+ r = (cipher + r) * C1 + C2;
+ return plain;
+}
+
+/* Get the next byte from the codestring being interpreted */
+static int
+DoRead(int *CodeP)
+{
+ if (strindex >= CharStringP->len) return(FALSE); /* end of string */
+ *CodeP = Decrypt((unsigned char) CharStringP->data.stringP[strindex++]);
+ return(TRUE);
+}
+
+/* Strip blues->lenIV bytes from CharString and update encryption key */
+/* (the lenIV entry in the Private dictionary specifies the number of */
+/* random bytes at the beginning of each CharString; default is 4) */
+static void
+StartDecrypt(void)
+{
+ int Code;
+
+ r = KEY; /* Initial key (seed) for CharStrings decryption */
+ for (strindex = 0; strindex < blues->lenIV;)
+ if (!DoRead(&Code)) /* Read a byte and update decryption key */
+ Error;
+}
+
+static void
+Decode(int Code)
+{
+ int Code1, Code2, Code3, Code4;
+
+ if (Code <= 31) /* Code is [0,31] */
+ DoCommand(Code);
+ else if (Code <= 246) /* Code is [32,246] */
+ Push((double)(Code - 139));
+ else if (Code <= 250) { /* Code is [247,250] */
+ if (!DoRead(&Code2)) goto ended;
+ Push((double)(((Code - 247) << 8) + Code2 + 108));
+ }
+ else if (Code <= 254) { /* Code is [251,254] */
+ if (!DoRead(&Code2)) goto ended;
+ Push((double)( -((Code - 251) << 8) - Code2 - 108));
+ }
+ else { /* Code is 255 */
+ if (!DoRead(&Code1)) goto ended;
+ if (!DoRead(&Code2)) goto ended;
+ if (!DoRead(&Code3)) goto ended;
+ if (!DoRead(&Code4)) goto ended;
+ Push((double)((((((Code1<<8) + Code2)<<8) + Code3)<<8) + Code4));
+ }
+ return;
+
+ended: Error;
+}
+
+/* Interpret a command code */
+static void
+DoCommand(int Code)
+{
+ switch(Code) {
+ case HSTEM: /* |- y dy HSTEM |- */
+ /* Vertical range of a horizontal stem zone */
+ if (Top < 1) Error;
+ HStem(Stack[0], Stack[1]);
+ ClearStack();
+ break;
+ case VSTEM: /* |- x dx VSTEM |- */
+ /* Horizontal range of a vertical stem zone */
+ if (Top < 1) Error;
+ VStem(Stack[0], Stack[1]);
+ ClearStack();
+ break;
+ case VMOVETO: /* |- dy VMOVETO |- */
+ /* Vertical MOVETO, equivalent to 0 dy RMOVETO */
+ if (Top < 0) Error;
+ RMoveTo(0.0, Stack[0]);
+ ClearStack();
+ break;
+ case RLINETO: /* |- dx dy RLINETO |- */
+ /* Like RLINETO in PostScript */
+ if (Top < 1) Error;
+ RLineTo(Stack[0], Stack[1]);
+ ClearStack();
+ break;
+ case HLINETO: /* |- dx HLINETO |- */
+ /* Horizontal LINETO, equivalent to dx 0 RLINETO */
+ if (Top < 0) Error;
+ RLineTo(Stack[0], 0.0);
+ ClearStack();
+ break;
+ case VLINETO: /* |- dy VLINETO |- */
+ /* Vertical LINETO, equivalent to 0 dy RLINETO */
+ if (Top < 0) Error;
+ RLineTo(0.0, Stack[0]);
+ ClearStack();
+ break;
+ case RRCURVETO:
+ /* |- dx1 dy1 dx2 dy2 dx3 dy3 RRCURVETO |- */
+ /* Relative RCURVETO, equivalent to dx1 dy1 */
+ /* (dx1+dx2) (dy1+dy2) (dx1+dx2+dx3) */
+ /* (dy1+dy2+dy3) RCURVETO in PostScript */
+ if (Top < 5) Error;
+ RRCurveTo(Stack[0], Stack[1], Stack[2], Stack[3],
+ Stack[4], Stack[5]);
+ ClearStack();
+ break;
+ case CLOSEPATH: /* - CLOSEPATH |- */
+ /* Closes a subpath without repositioning the */
+ /* current point */
+ DoClosePath();
+ ClearStack();
+ break;
+ case CALLSUBR: /* subr# CALLSUBR - */
+ /* Calls a CharString subroutine with index */
+ /* subr# from the Subrs array */
+ if (Top < 0) Error;
+ CallSubr((int)Stack[Top--]);
+ break;
+ case RETURN: /* - RETURN - */
+ /* Returns from a Subrs array CharString */
+ /* subroutine called with CALLSUBR */
+ Return();
+ break;
+ case ESCAPE: /* ESCAPE to two-byte command code */
+ if (!DoRead(&Code)) Error;
+ Escape(Code);
+ break;
+ case HSBW: /* |- sbx wx HSBW |- */
+ /* Set the left sidebearing point to (sbx,0), */
+ /* set the character width vector to (wx,0). */
+ /* Equivalent to sbx 0 wx 0 SBW. Space */
+ /* character should have sbx = 0 */
+ if (Top < 1) Error;
+ Sbw(Stack[0], 0.0, Stack[1], 0.0);
+ ClearStack();
+ break;
+ case ENDCHAR: /* - ENDCHAR |- */
+ /* Finishes a CharString outline */
+ EndChar();
+ ClearStack();
+ break;
+ case RMOVETO: /* |- dx dy RMOVETO |- */
+ /* Behaves like RMOVETO in PostScript */
+ if (Top < 1) Error;
+ RMoveTo(Stack[0], Stack[1]);
+ ClearStack();
+ break;
+ case HMOVETO: /* |- dx HMOVETO |- */
+ /* Horizontal MOVETO. Equivalent to dx 0 RMOVETO */
+ if (Top < 0) Error;
+ RMoveTo(Stack[0], 0.0);
+ ClearStack();
+ break;
+ case VHCURVETO: /* |- dy1 dx2 dy2 dx3 VHCURVETO |- */
+ /* Vertical-Horizontal CURVETO, equivalent to */
+ /* 0 dy1 dx2 dy2 dx3 0 RRCURVETO */
+ if (Top < 3) Error;
+ RRCurveTo(0.0, Stack[0], Stack[1], Stack[2],
+ Stack[3], 0.0);
+ ClearStack();
+ break;
+ case HVCURVETO: /* |- dx1 dx2 dy2 dy3 HVCURVETO |- */
+ /* Horizontal-Vertical CURVETO, equivalent to */
+ /* dx1 0 dx2 dy2 0 dy3 RRCURVETO */
+ if (Top < 3) Error;
+ RRCurveTo(Stack[0], 0.0, Stack[1], Stack[2], 0.0, Stack[3]);
+ ClearStack();
+ break;
+ default: /* Unassigned command code */
+ ClearStack();
+ Error;
+ }
+}
+
+static void
+Escape(int Code)
+{
+ int i, Num;
+ struct segment *p;
+
+ switch(Code) {
+ case DOTSECTION: /* - DOTSECTION |- */
+ /* Brackets an outline section for the dots in */
+ /* letters such as "i", "j", and "!". */
+ DotSection();
+ ClearStack();
+ break;
+ case VSTEM3: /* |- x0 dx0 x1 dx1 x2 dx2 VSTEM3 |- */
+ /* Declares the horizontal ranges of three */
+ /* vertical stem zones between x0 and x0+dx0, */
+ /* x1 and x1+dx1, and x2 and x2+dx2. */
+ if (Top < 5) Error;
+ if (!wsset && ProcessHints) {
+ /* Shift the whole character so that the middle stem is centered. */
+ p = CenterStem(Stack[2] + sidebearingX, Stack[3]);
+ path = Join(path, p);
+ wsset = 1;
+ }
+
+ VStem(Stack[0], Stack[1]);
+ VStem(Stack[2], Stack[3]);
+ VStem(Stack[4], Stack[5]);
+ ClearStack();
+ break;
+ case HSTEM3: /* |- y0 dy0 y1 dy1 y2 dy2 HSTEM3 |- */
+ /* Declares the vertical ranges of three hori- */
+ /* zontal stem zones between y0 and y0+dy0, */
+ /* y1 and y1+dy1, and y2 and y2+dy2. */
+ if (Top < 5) Error;
+ HStem(Stack[0], Stack[1]);
+ HStem(Stack[2], Stack[3]);
+ HStem(Stack[4], Stack[5]);
+ ClearStack();
+ break;
+ case SEAC: /* |- asb adx ady bchar achar SEAC |- */
+ /* Standard Encoding Accented Character. */
+ if (Top < 4) Error;
+ Seac(Stack[0], Stack[1], Stack[2],
+ (unsigned char) Stack[3],
+ (unsigned char) Stack[4]);
+ ClearStack();
+ break;
+ case SBW: /* |- sbx sby wx wy SBW |- */
+ /* Set the left sidebearing point to (sbx,sby), */
+ /* set the character width vector to (wx,wy). */
+ if (Top < 3) Error;
+ Sbw(Stack[0], Stack[1], Stack[2], Stack[3]);
+ ClearStack();
+ break;
+ case DIV: /* num1 num2 DIV quotient */
+ /* Behaves like DIV in the PostScript language */
+ if (Top < 1) Error;
+ Stack[Top-1] = Div(Stack[Top-1], Stack[Top]);
+ Top--;
+ break;
+ case CALLOTHERSUBR:
+ /* arg1 ... argn n othersubr# CALLOTHERSUBR - */
+ /* Make calls on the PostScript interpreter */
+ if (Top < 1) Error;
+ Num = Stack[Top-1];
+ if (Top < Num+1) Error;
+ for (i = 0; i < Num; i++) PSFakePush(Stack[Top - i - 2]);
+ Top -= Num + 2;
+ CallOtherSubr((int)Stack[Top + Num + 2]);
+ break;
+ case POP: /* - POP number */
+ /* Removes a number from the top of the */
+ /* PostScript interpreter stack and pushes it */
+ /* onto the Type 1 BuildChar operand stack */
+ Push(PSFakePop());
+ break;
+ case SETCURRENTPOINT: /* |- x y SETCURRENTPOINT |- */
+ /* Sets the current point to (x,y) in absolute */
+ /* character space coordinates without per- */
+ /* forming a CharString MOVETO command */
+ if (Top < 1) Error;
+ SetCurrentPoint(Stack[0], Stack[1]);
+ ClearStack();
+ break;
+ default: /* Unassigned escape code command */
+ ClearStack();
+ Error;
+ }
+}
+
+/* |- y dy HSTEM |- */
+/* Declares the vertical range of a horizontal stem zone */
+/* between coordinates y and y + dy */
+/* y is relative to the left sidebearing point */
+static void
+HStem(double y, double dy)
+{
+ if (ProcessHints) {
+ if (numstems >= MAXSTEMS) Error;
+ if (dy < 0.0) {y += dy; dy = -dy;}
+ stems[numstems].vertical = FALSE;
+ stems[numstems].x = 0.0;
+ stems[numstems].y = sidebearingY + y + wsoffsetY;
+ stems[numstems].dx = 0.0;
+ stems[numstems].dy = dy;
+ ComputeStem(numstems);
+ numstems++;
+ }
+}
+
+/* |- x dx VSTEM |- */
+/* Declares the horizontal range of a vertical stem zone */
+/* between coordinates x and x + dx */
+/* x is relative to the left sidebearing point */
+
+static void
+VStem(double x, double dx)
+{
+ if (ProcessHints) {
+ if (numstems >= MAXSTEMS) Error;
+ if (dx < 0.0) {x += dx; dx = -dx;}
+ stems[numstems].vertical = TRUE;
+ stems[numstems].x = sidebearingX + x + wsoffsetX;
+ stems[numstems].y = 0.0;
+ stems[numstems].dx = dx;
+ stems[numstems].dy = 0.0;
+ ComputeStem(numstems);
+ numstems++;
+ }
+}
+
+/* |- dx dy RLINETO |- */
+/* Behaves like RLINETO in PostScript */
+static void
+RLineTo(double dx, double dy)
+{
+ struct segment *B;
+
+ B = Loc(CharSpace, dx, dy);
+
+ if (ProcessHints) {
+ currx += dx;
+ curry += dy;
+ /* B = Join(B, FindStems(currx, curry)); */
+ B = Join(B, FindStems(currx, curry, dx, dy));
+ }
+
+ path = Join(path, Line(B));
+}
+
+/* |- dx1 dy1 dx2 dy2 dx3 dy3 RRCURVETO |- */
+/* Relative RCURVETO, equivalent to dx1 dy1 */
+/* (dx1+dx2) (dy1+dy2) (dx1+dx2+dx3) */
+/* (dy1+dy2+dy3) RCURVETO in PostScript */
+static void
+RRCurveTo(double dx1, double dy1, double dx2, double dy2,
+ double dx3, double dy3)
+{
+ struct segment *B, *C, *D;
+
+ B = Loc(CharSpace, dx1, dy1);
+ C = Loc(CharSpace, dx2, dy2);
+ D = Loc(CharSpace, dx3, dy3);
+
+ if (ProcessHints) {
+ /* For a Bezier curve, we apply the full hint value to
+ the Bezier C point (and thereby D point). */
+ currx += dx1 + dx2 + dx3;
+ curry += dy1 + dy2 + dy3;
+ /* C = Join(C, FindStems(currx, curry)); */
+ C = Join(C, FindStems(currx, curry, dx3, dy3));
+ }
+
+ /* Since XIMAGER is not completely relative, */
+ /* we need to add up the delta values */
+
+ C = Join(C, (struct segment *)Dup(B));
+ D = Join(D, (struct segment *)Dup(C));
+
+ path = Join(path, (struct segment *)Bezier(B, C, D));
+}
+
+/* - CLOSEPATH |- */
+/* Closes a subpath WITHOUT repositioning the */
+/* current point */
+static void
+DoClosePath(void)
+{
+ struct segment *CurrentPoint;
+
+ CurrentPoint = Phantom(path);
+ path = ClosePath(path);
+ path = Join(Snap(path), CurrentPoint);
+}
+
+/* subr# CALLSUBR - */
+/* Calls a CharString subroutine with index */
+/* subr# from the Subrs array */
+static void
+CallSubr(int subrno)
+{
+ if ((subrno < 0) || (subrno >= SubrsP->len))
+ Error;
+ PushCall(CharStringP, strindex, r);
+ CharStringP = &SubrsP->data.arrayP[subrno];
+ StartDecrypt();
+}
+
+/* - RETURN - */
+/* Returns from a Subrs array CharString */
+/* subroutine called with CALLSUBR */
+static void
+Return(void)
+{
+ PopCall(&CharStringP, &strindex, &r);
+}
+
+/* - ENDCHAR |- */
+/* Finishes a CharString outline */
+/* Executes SETCHACHEDEVICE using a bounding box */
+/* it computes directly from the character outline */
+/* and using the width information acquired from a previous */
+/* HSBW or SBW. It then calls a special version of FILL */
+/* or STROKE depending on the value of PaintType in the */
+/* font dictionary */
+static void
+EndChar(void)
+{
+ /* There is no need to compute and set bounding box for
+ the cache, since XIMAGER does that on the fly. */
+
+ /* Perform a Closepath just in case the command was left out */
+ path = ClosePath(path);
+
+ /* Set character width */
+ path = Join(Snap(path), Loc(CharSpace, escapementX, escapementY));
+
+}
+
+/* |- dx dy RMOVETO |- */
+/* Behaves like RMOVETO in PostScript */
+static void
+RMoveTo(double dx, double dy)
+{
+ struct segment *B;
+
+ B = Loc(CharSpace, dx, dy);
+
+ if (ProcessHints) {
+ currx += dx;
+ curry += dy;
+ /* B = Join(B, FindStems(currx, curry)); */
+ B = Join(B, FindStems(currx, curry, 0.0, 0.0));
+ }
+
+ path = Join(path, B);
+}
+
+/* - DOTSECTION |- */
+/* Brackets an outline section for the dots in */
+/* letters such as "i", "j", and "!". */
+static void
+DotSection(void)
+{
+ InDotSection = !InDotSection;
+}
+
+/* |- asb adx ady bchar achar SEAC |- */
+/* Standard Encoding Accented Character. */
+static void
+Seac(double asb, double adx, double ady,
+ unsigned char bchar, unsigned char achar)
+{
+ int Code;
+ struct segment *mypath;
+
+ /* Move adx - asb, ady over and up from base char's sbpoint. */
+ /* (We use adx - asb to counteract the accents sb shift.) */
+ /* The variables accentoffsetX/Y modify sidebearingX/Y in Sbw(). */
+ /* Note that these incorporate the base character's sidebearing shift by */
+ /* using the current sidebearingX, Y values. */
+ accentoffsetX = sidebearingX + adx - asb;
+ accentoffsetY = sidebearingY + ady;
+
+ /* Set path = NULL to avoid complaints from Sbw(). */
+ path = NULL;
+
+ /* Go find the CharString for the accent's code via an upcall */
+ CharStringP = GetType1CharString((psfont *)Environment, achar);
+ StartDecrypt();
+
+ ClearStack();
+ ClearPSFakeStack();
+ ClearCallStack();
+
+ for (;;) {
+ if (!DoRead(&Code)) break;
+ Decode(Code);
+ if (errflag) return;
+ }
+ /* Copy snapped path to mypath and set path to NULL as above. */
+ mypath = Snap(path);
+ path = NULL;
+
+ /* We must reset these to null now. */
+ accentoffsetX = accentoffsetY = 0;
+
+ /* go find the CharString for the base char's code via an upcall */
+ CharStringP = GetType1CharString((psfont *)Environment, bchar);
+ StartDecrypt();
+
+ ClearStack();
+ ClearPSFakeStack();
+ ClearCallStack();
+
+ FinitStems();
+ InitStems();
+
+ for (;;) {
+ if (!DoRead(&Code)) break;
+ Decode(Code);
+ if (errflag) return;
+ }
+ path = Join(mypath, path);
+}
+
+
+/* |- sbx sby wx wy SBW |- */
+/* Set the left sidebearing point to (sbx,sby), */
+/* set the character width vector to (wx,wy). */
+static void
+Sbw(double sbx, double sby, double wx, double wy)
+{
+ escapementX = wx; /* Character width vector */
+ escapementY = wy;
+
+ /* Sidebearing values are sbx, sby args, plus accent offset from Seac(). */
+ sidebearingX = sbx + accentoffsetX;
+ sidebearingY = sby + accentoffsetY;
+
+ path = Join(path, Loc(CharSpace, sidebearingX, sidebearingY));
+ if (ProcessHints) {currx = sidebearingX; curry = sidebearingY;}
+}
+
+ /* num1 num2 DIV quotient */
+/* Behaves like DIV in the PostScript language */
+static double
+Div(double num1, double num2)
+{
+ return(num1 / num2);
+}
+
+/*
+ The following four subroutines (FlxProc, FlxProc1, FlxProc2, and
+ HintReplace) are C versions of the OtherSubrs Programs, which were
+ were published in the Adobe Type 1 Font Format book.
+
+ The Flex outline fragment is described by
+ c1: (x0, y0) = c3: (x0, yshrink(y0)) or (xshrink(x0), y0)
+ " (x1, y1) = " (x1, yshrink(y1)) or (xshrink(x1), y1)
+ " (x2, y2) - reference point
+ c2: (x0, y0) = c4: (x0, yshrink(y0)) or (xshrink(x0), y0)
+ " (x1, y1) = " (x1, yshrink(y1)) or (xshrink(x1), y1)
+ " (x2, y2) = " (x2, y2), rightmost endpoint
+ c3: (x0, y0) - control point, 1st Bezier curve
+ " (x1, y1) - control point, -"-
+ " (x2, y2) - end point, -"-
+ c4: (x0, y0) - control point, 2nd Bezier curve
+ " (x1, y1) - control point, -"-
+ " (x2, y2) - end point, -"-
+ ep: (epY, epX) - final endpoint (should be same as c4: (x2, y2))
+ idmin - minimum Flex height (1/100 pixel) at which to render curves
+*/
+
+#define dtransform(dxusr,dyusr,dxdev,dydev) { \
+ register struct segment *point = Loc(CharSpace, dxusr, dyusr); \
+ QueryLoc(point, IDENTITY, dxdev, dydev); \
+ Destroy(point); \
+}
+
+#define itransform(xdev,ydev,xusr,yusr) { \
+ register struct segment *point = Loc(IDENTITY, xdev, ydev); \
+ QueryLoc(point, CharSpace, xusr, yusr); \
+ Destroy(point); \
+}
+
+#define transform(xusr,yusr,xdev,ydev) dtransform(xusr,yusr,xdev,ydev)
+
+#define PaintType (0)
+
+#define lineto(x,y) { \
+ struct segment *CurrentPoint; \
+ double CurrentX, CurrentY; \
+ CurrentPoint = Phantom(path); \
+ QueryLoc(CurrentPoint, CharSpace, &CurrentX, &CurrentY); \
+ Destroy(CurrentPoint); \
+ RLineTo(x - CurrentX, y - CurrentY); \
+}
+
+#define curveto(x0,y0,x1,y1,x2,y2) { \
+ struct segment *CurrentPoint; \
+ double CurrentX, CurrentY; \
+ CurrentPoint = Phantom(path); \
+ QueryLoc(CurrentPoint, CharSpace, &CurrentX, &CurrentY); \
+ Destroy(CurrentPoint); \
+ RRCurveTo(x0 - CurrentX, y0 - CurrentY, x1 - x0, y1 - y0, x2 - x1, y2 - y1); \
+}
+
+#define xshrink(x) ((x - c4x2) * shrink +c4x2)
+#define yshrink(y) ((y - c4y2) * shrink +c4y2)
+
+#define PickCoords(flag) \
+ if (flag) { /* Pick "shrunk" coordinates */ \
+ x0 = c1x0; y0 = c1y0; \
+ x1 = c1x1; y1 = c1y1; \
+ x2 = c1x2; y2 = c1y2; \
+ x3 = c2x0; y3 = c2y0; \
+ x4 = c2x1; y4 = c2y1; \
+ x5 = c2x2; y5 = c2y2; \
+ } else { /* Pick original coordinates */ \
+ x0 = c3x0; y0 = c3y0; \
+ x1 = c3x1; y1 = c3y1; \
+ x2 = c3x2; y2 = c3y2; \
+ x3 = c4x0; y3 = c4y0; \
+ x4 = c4x1; y4 = c4y1; \
+ x5 = c4x2; y5 = c4y2; \
+ }
+
+/* FlxProc() = OtherSubrs[0]; Main part of Flex */
+/* Calling sequence: 'idmin epX epY 3 0 callothersubr' */
+/* Computes Flex values, and renders the Flex path, */
+/* and returns (leaves) ending coordinates on stack */
+static void
+FlxProc(double c1x2, double c1y2, double c3x0, double c3y0,
+ double c3x1, double c3y1, double c3x2, double c3y2,
+ double c4x0, double c4y0, double c4x1, double c4y1,
+ double c4x2, double c4y2, double epY, double epX, int idmin)
+{
+ double dmin;
+ double c1x0, c1y0, c1x1, c1y1;
+ double c2x0, c2y0, c2x1, c2y1, c2x2, c2y2;
+ char yflag;
+ double x0, y0, x1, y1, x2, y2, x3, y3, x4, y4, x5, y5;
+ double cxx, cyx, cxy, cyy; /* Transformation matrix */
+ int flipXY;
+ double x, y;
+ double erosion = 1; /* Device parameter */
+ /* Erosion may have different value specified in 'internaldict' */
+ double shrink;
+ double dX, dY;
+ char erode;
+ double eShift;
+ double cx, cy;
+ double ex, ey;
+
+ c1x0 = c1y0 = c1x1 = c1y1 = c2x0 = c2y0 = c2x1 = c2y1 = c2x2 = c2y2 = 0.0;
+
+ Destroy(path);
+ path = FlxOldPath; /* Restore previous path (stored in FlxProc1) */
+
+ if (ProcessHints) {
+ dmin = ABS(idmin) / 100.0; /* Minimum Flex height in pixels */
+
+ c2x2 = c4x2; c2y2 = c4y2; /* Point c2 = c4 */
+
+ yflag = FABS(c1y2 - c3y2) > FABS(c1x2 - c3x2); /* Flex horizontal? */
+
+ QuerySpace(CharSpace, &cxx, &cyx, &cxy, &cyy); /* Transformation matrix */
+
+ if (FABS(cxx) < 0.00001 || FABS(cyy) < 0.00001)
+ flipXY = -1; /* Char on side */
+ else if (FABS(cyx) < 0.00001 || FABS(cxy) < 0.00001)
+ flipXY = 1; /* Char upright */
+ else
+ flipXY = 0; /* Char at angle */
+
+ if (yflag) { /* Flex horizontal */
+ if (flipXY == 0 || c3y2 == c4y2) { /* Char at angle or Flex height = 0 */
+ PickCoords(FALSE); /* Pick original control points */
+ } else {
+ shrink = FABS((c1y2 - c4y2) / (c3y2 - c4y2)); /* Slope */
+
+ c1x0 = c3x0; c1y0 = yshrink(c3y0);
+ c1x1 = c3x1; c1y1 = yshrink(c3y1);
+ c2x0 = c4x0; c2y0 = yshrink(c4y0);
+ c2x1 = c4x1; c2y1 = yshrink(c4y1);
+
+ dtransform(0.0, ROUND(c3y2-c1y2), &x, &y); /* Flex height in pixels */
+ dY = FABS((flipXY == 1) ? y : x);
+ PickCoords(dY < dmin); /* If Flex small, pick 'shrunk' control points */
+
+ if (FABS(y2 - c1y2) > 0.001) { /* Flex 'non-zero'? */
+ transform(c1x2, c1y2, &x, &y);
+
+ if (flipXY == 1) {
+ cx = x; cy = y;
+ } else {
+ cx = y; cy = x;
+ }
+
+ dtransform(0.0, ROUND(y2-c1y2), &x, &y);
+ dY = (flipXY == 1) ? y : x;
+ if (ROUND(dY) != 0)
+ dY = ROUND(dY);
+ else
+ dY = (dY < 0) ? -1 : 1;
+
+ erode = PaintType != 2 && erosion >= 0.5;
+ if (erode)
+ cy -= 0.5;
+ ey = cy + dY;
+ ey = CEIL(ey) - ey;
+ ey = ey + FLOOR(cy + dY);
+ if (erode)
+ ey += 0.5;
+
+ if (flipXY == 1) {
+ itransform(cx, ey, &x, &y);
+ } else {
+ itransform(ey, cx, &x, &y);
+ }
+
+ eShift = y - y2;
+ y1 += eShift;
+ y2 += eShift;
+ y3 += eShift;
+ }
+ }
+ } else { /* Flex vertical */
+ if (flipXY == 0 || c3x2 == c4x2) { /* Char at angle or Flex height = 0 */
+ PickCoords(FALSE); /* Pick original control points */
+ } else {
+ shrink = FABS((c1x2 - c4x2) / (c3x2 - c4x2)); /* Slope */
+
+ c1x0 = xshrink(c3x0); c1y0 = c3y0;
+ c1x1 = xshrink(c3x1); c1y1 = c3y1;
+ c2x0 = xshrink(c4x0); c2y0 = c4y0;
+ c2x1 = xshrink(c4x1); c2y1 = c4y1;
+
+ dtransform(ROUND(c3x2 - c1x2), 0.0, &x, &y); /* Flex height in pixels */
+ dX = FABS((flipXY == -1) ? y : x);
+ PickCoords(dX < dmin); /* If Flex small, pick 'shrunk' control points */
+
+ if (FABS(x2 - c1x2) > 0.001) {
+ transform(c1x2, c1y2, &x, &y);
+ if (flipXY == -1) {
+ cx = y; cy = x;
+ } else {
+ cx = x; cy = y;
+ }
+
+ dtransform(ROUND(x2-c1x2), 0.0, &x, &y);
+ dX = (flipXY == -1) ? y : x;
+ if (ROUND(dX) != 0)
+ dX = ROUND(dX);
+ else
+ dX = (dX < 0) ? -1 : 1;
+
+ erode = PaintType != 2 && erosion >= 0.5;
+ if (erode)
+ cx -= 0.5;
+ ex = cx + dX;
+ ex = CEIL(ex) - ex;
+ ex = ex + FLOOR(cx + dX);
+ if (erode)
+ ex += 0.5;
+
+ if (flipXY == -1) {
+ itransform(cy, ex, &x, &y);
+ } else {
+ itransform(ex, cy, &x, &y);
+ }
+
+ eShift = x - x2;
+ x1 += eShift;
+ x2 += eShift;
+ x3 += eShift;
+ }
+ }
+ }
+
+ if (x2 == x5 || y2 == y5) {
+ lineto(x5, y5);
+ } else {
+ curveto(x0, y0, x1, y1, x2, y2);
+ curveto(x3, y3, x4, y4, x5, y5);
+ }
+ } else { /* ProcessHints is off */
+ PickCoords(FALSE); /* Pick original control points */
+ curveto(x0, y0, x1, y1, x2, y2);
+ curveto(x3, y3, x4, y4, x5, y5);
+ }
+
+ PSFakePush(epY);
+ PSFakePush(epX);
+}
+
+/* FlxProc1() = OtherSubrs[1]; Part of Flex */
+/* Calling sequence: '0 1 callothersubr' */
+/* Saves and clears path, then restores currentpoint */
+static void
+FlxProc1(void)
+{
+ struct segment *CurrentPoint;
+
+ CurrentPoint = Phantom(path);
+
+ FlxOldPath = path;
+ path = CurrentPoint;
+}
+
+/* FlxProc2() = OtherSubrs[2]; Part of Flex */
+/* Calling sequence: '0 2 callothersubr' */
+/* Returns currentpoint on stack */
+static void
+FlxProc2(void)
+{
+ struct segment *CurrentPoint;
+ double CurrentX, CurrentY;
+
+ CurrentPoint = Phantom(path);
+ QueryLoc(CurrentPoint, CharSpace, &CurrentX, &CurrentY);
+ Destroy(CurrentPoint);
+
+ /* Push CurrentPoint on fake PostScript stack */
+ PSFakePush(CurrentX);
+ PSFakePush(CurrentY);
+}
+
+/* HintReplace() = OtherSubrs[3]; Hint Replacement */
+/* Calling sequence: 'subr# 1 3 callothersubr pop callsubr' */
+/* Reinitializes stem hint structure */
+static void
+HintReplace(void)
+{
+ /* Effectively retire the current stems, but keep them around for */
+ /* revhint use in case we are in a stem when we replace hints. */
+ currstartstem = numstems;
+
+ /* 'subr#' is left on PostScript stack (for 'pop callsubr') */
+}
+
+/* arg1 ... argn n othersubr# CALLOTHERSUBR - */
+/* Make calls on the PostScript interpreter (or call equivalent C code) */
+/* NOTE: The n arguments have been pushed on the fake PostScript stack */
+static void
+CallOtherSubr(int othersubrno)
+{
+ switch(othersubrno) {
+ case 0: /* OtherSubrs[0]; Main part of Flex */
+ if (PSFakeTop < 16) Error;
+ ClearPSFakeStack();
+ FlxProc(
+ PSFakeStack[0], PSFakeStack[1], PSFakeStack[2], PSFakeStack[3],
+ PSFakeStack[4], PSFakeStack[5], PSFakeStack[6], PSFakeStack[7],
+ PSFakeStack[8], PSFakeStack[9], PSFakeStack[10], PSFakeStack[11],
+ PSFakeStack[12], PSFakeStack[13], PSFakeStack[14], PSFakeStack[15],
+ (int) PSFakeStack[16]
+ );
+ break;
+ case 1: /* OtherSubrs[1]; Part of Flex */
+ FlxProc1();
+ break;
+ case 2: /* OtherSubrs[2]; Part of Flex */
+ FlxProc2();
+ break;
+ case 3: /* OtherSubrs[3]; Hint Replacement */
+ HintReplace();
+ break;
+ default: { /* call OtherSubrs[4] or higher if PostScript is present */
+ }
+ }
+}
+
+/* |- x y SETCURRENTPOINT |- */
+/* Sets the current point to (x,y) in absolute */
+/* character space coordinates without per- */
+/* forming a CharString MOVETO command */
+static void
+SetCurrentPoint(double x, double y)
+{
+ currx = x;
+ curry = y;
+}
+
+/* The Type1Char routine for use by PostScript. */
+/************************************************/
+struct xobject *
+Type1Char(char *env, struct XYspace *S, psobj *charstrP, psobj *subrsP,
+ psobj *osubrsP,
+ struct blues_struct *bluesP, /* FontID's ptr to the blues struct */
+ int *modeP)
+{
+ int Code;
+
+ path = NULL;
+ errflag = FALSE;
+
+ /* Make parameters available to all Type1 routines */
+ Environment = env;
+ CharSpace = S; /* used when creating path elements */
+ CharStringP = charstrP;
+ SubrsP = subrsP;
+
+ blues = bluesP;
+
+ /* compute the alignment zones */
+ ComputeAlignmentZones();
+
+ StartDecrypt();
+
+ ClearStack();
+ ClearPSFakeStack();
+ ClearCallStack();
+
+ InitStems();
+
+ currx = curry = 0;
+ escapementX = escapementY = 0;
+ sidebearingX = sidebearingY = 0;
+ accentoffsetX = accentoffsetY = 0;
+ wsoffsetX = wsoffsetY = 0; /* No shift to preserve whitspace. */
+ wsset = 0; /* wsoffsetX,Y haven't been set yet. */
+
+ for (;;) {
+ if (!DoRead(&Code)) break;
+ Decode(Code);
+ if (errflag) break;
+ }
+
+ FinitStems();
+
+
+ /* Clean up if an error has occurred */
+ if (errflag) {
+ if (path != NULL) {
+ Destroy(path); /* Reclaim storage */
+ path = NULL; /* Indicate that character could not be built */
+ }
+ }
+
+ return((struct xobject *) path);
+}
diff --git a/libXfont/src/Type1/util.c b/libXfont/src/Type1/util.c
new file mode 100644
index 000000000..2eefc11df
--- /dev/null
+++ b/libXfont/src/Type1/util.c
@@ -0,0 +1,194 @@
+/* $Xorg: util.c,v 1.3 2000/08/17 19:46:34 cpqbld Exp $ */
+/* Copyright International Business Machines,Corp. 1991
+ * All Rights Reserved
+ *
+ * License to use, copy, modify, and distribute this software
+ * and its documentation for any purpose and without fee is
+ * hereby granted, provided that the above copyright notice
+ * appear in all copies and that both that copyright notice and
+ * this permission notice appear in supporting documentation,
+ * and that the name of IBM not be used in advertising or
+ * publicity pertaining to distribution of the software without
+ * specific, written prior permission.
+ *
+ * IBM PROVIDES THIS SOFTWARE "AS IS", WITHOUT ANY WARRANTIES
+ * OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING, BUT NOT
+ * LIMITED TO ANY IMPLIED WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE, AND NONINFRINGEMENT OF
+ * THIRD PARTY RIGHTS. THE ENTIRE RISK AS TO THE QUALITY AND
+ * PERFORMANCE OF THE SOFTWARE, INCLUDING ANY DUTY TO SUPPORT
+ * OR MAINTAIN, BELONGS TO THE LICENSEE. SHOULD ANY PORTION OF
+ * THE SOFTWARE PROVE DEFECTIVE, THE LICENSEE (NOT IBM) ASSUMES
+ * THE ENTIRE COST OF ALL SERVICING, REPAIR AND CORRECTION. IN
+ * NO EVENT SHALL IBM BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING
+ * FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF
+ * CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
+ * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+ * SOFTWARE.
+ */
+/* $XFree86: xc/lib/font/Type1/util.c,v 1.5 1999/08/21 13:47:53 dawes Exp $ */
+/* Author: Katherine A. Hitchcock IBM Almaden Research Laboratory */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#ifndef FONTMODULE
+#include <stdio.h>
+#else
+#include "Xdefs.h"
+#include "Xmd.h"
+#include "xf86_ansic.h"
+#endif
+#include "util.h"
+#include <X11/fonts/fontmisc.h> /* for xalloc/xfree */
+
+static char *vm_base = NULL; /* Start of virtual memory area */
+ char *vm_next = NULL; /* Pointer to first free byte */
+ long vm_free = 0; /* Count of free bytes */
+ long vm_size = 0; /* Total size of memory */
+
+/*
+ * Initialize memory.
+ */
+boolean
+vm_init(int cnt)
+{
+ vm_next = vm_base = (char *)xalloc (cnt);
+
+ if (vm_base != NULL) {
+ vm_free = cnt;
+ vm_size = cnt;
+ return(TRUE);
+ }
+ else
+ return(FALSE);
+
+}
+
+char *
+vm_alloc(int bytes)
+{
+ char *answer;
+
+ /* Round to next word multiple */
+ bytes = (bytes + 7) & ~7;
+
+ /* Allocate the space, if it is available */
+ if (bytes > 0 && bytes <= vm_free) {
+ answer = vm_next;
+ vm_free -= bytes;
+ vm_next += bytes;
+ }
+ else
+ answer = NULL;
+
+ return(answer);
+}
+
+/*
+ * Format an Integer object
+ */
+void
+objFormatInteger(psobj *objP, int value)
+{
+ if (objP != NULL) {
+ objP->type = OBJ_INTEGER;
+ objP->len = 0;
+ objP->data.integer = value;
+ }
+}
+
+/*
+ * Format a Real object
+ */
+void
+objFormatReal(psobj *objP, float value)
+{
+ if (objP != NULL) {
+ objP->type = OBJ_REAL;
+ objP->len = 0;
+ objP->data.real = value;
+ }
+}
+
+/*
+ * Format a Boolean object
+ */
+void
+objFormatBoolean(psobj *objP, boolean value)
+{
+ if (objP != NULL) {
+ objP->type = OBJ_BOOLEAN;
+ objP->len = 0;
+ objP->data.boolean = value;
+ }
+}
+
+/*
+ * Format an Encoding object
+ */
+void
+objFormatEncoding(psobj *objP, int length, psobj *valueP)
+{
+ if (objP != NULL) {
+ objP->type = OBJ_ENCODING;
+ objP->len = length;
+ objP->data.arrayP = valueP;
+ }
+}
+
+/*
+ * Format an Array object
+ */
+void
+objFormatArray(psobj *objP, int length, psobj *valueP)
+{
+ if (objP != NULL) {
+ objP->type = OBJ_ARRAY;
+ objP->len = length;
+ objP->data.arrayP = valueP;
+ }
+}
+
+
+/*
+ * Format a String object
+ */
+void
+objFormatString(psobj *objP, int length, char *valueP)
+{
+ if (objP != NULL) {
+ objP->type = OBJ_STRING;
+ objP->len = length;
+ objP->data.valueP = valueP;
+ }
+}
+
+/*
+ * Format a Name object
+ */
+void
+objFormatName(psobj *objP, int length, char *valueP)
+{
+ if (objP != NULL) {
+ objP->type = OBJ_NAME;
+ objP->len = length;
+ objP->data.nameP = valueP;
+ }
+}
+
+/*
+ * Format a File object
+ */
+void
+objFormatFile(psobj *objP, FILE *valueP)
+{
+ if (objP != NULL) {
+ objP->type = OBJ_FILE;
+ objP->len = 0;
+ objP->data.fileP = valueP;
+ }
+}
+
diff --git a/libXfont/src/Type1/util.h b/libXfont/src/Type1/util.h
new file mode 100644
index 000000000..25ba5720c
--- /dev/null
+++ b/libXfont/src/Type1/util.h
@@ -0,0 +1,190 @@
+/* $Xorg: util.h,v 1.3 2000/08/17 19:46:34 cpqbld Exp $ */
+/* Copyright International Business Machines,Corp. 1991
+ * All Rights Reserved
+ *
+ * License to use, copy, modify, and distribute this software
+ * and its documentation for any purpose and without fee is
+ * hereby granted, provided that the above copyright notice
+ * appear in all copies and that both that copyright notice and
+ * this permission notice appear in supporting documentation,
+ * and that the name of IBM not be used in advertising or
+ * publicity pertaining to distribution of the software without
+ * specific, written prior permission.
+ *
+ * IBM PROVIDES THIS SOFTWARE "AS IS", WITHOUT ANY WARRANTIES
+ * OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING, BUT NOT
+ * LIMITED TO ANY IMPLIED WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE, AND NONINFRINGEMENT OF
+ * THIRD PARTY RIGHTS. THE ENTIRE RISK AS TO THE QUALITY AND
+ * PERFORMANCE OF THE SOFTWARE, INCLUDING ANY DUTY TO SUPPORT
+ * OR MAINTAIN, BELONGS TO THE LICENSEE. SHOULD ANY PORTION OF
+ * THE SOFTWARE PROVE DEFECTIVE, THE LICENSEE (NOT IBM) ASSUMES
+ * THE ENTIRE COST OF ALL SERVICING, REPAIR AND CORRECTION. IN
+ * NO EVENT SHALL IBM BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING
+ * FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF
+ * CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
+ * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+ * SOFTWARE.
+ */
+/* $XFree86: xc/lib/font/Type1/util.h,v 1.4 1999/08/22 08:58:55 dawes Exp $ */
+
+#ifndef UTIL_H
+#define UTIL_H
+
+#ifndef boolean
+typedef int boolean;
+#endif
+
+#ifndef TRUE
+#define TRUE (1)
+#endif
+
+#ifndef FALSE
+#define FALSE (0)
+#endif
+
+/***================================================================***/
+/* Portable definitions for 2's complement machines.
+ * NOTE: These really should be based on PostScript types,
+ * for example, sizeof(ps_integer), or sizeof(ps_unsigned)
+ */
+#define MAX_ULONG (~(unsigned long)(0))
+/* This code is portable, assuming K&R C and 2's complement arithmetic */
+#define MAX_INTEGER \
+ ((long)((((unsigned long) 1)<<(sizeof(unsigned long)*8-1))-1))
+#define MIN_INTEGER ((-MAX_INTEGER)-1)
+
+#define MAX_ARRAY_CNT (65535)
+#define MAX_DICT_CNT (65535)
+#define MAX_STRING_LEN (65535)
+#define MAX_NAME_LEN (128)
+
+#ifndef MIN
+#define MIN(a,b) (((a)<(b)) ? a : b )
+#endif
+
+/***================================================================***/
+/* Routines for managing virtual memory */
+/***================================================================***/
+
+#define VM_SIZE (50 * 1024)
+
+extern boolean vm_init ( int cnt );
+extern long vm_free;
+extern long vm_size;
+extern char *vm_next;
+extern char *vm_alloc ( int bytes );
+
+/***================================================================***/
+/* Macros for managing virtual memory */
+/***================================================================***/
+#define vm_next_byte() (vm_next)
+#define vm_free_bytes() (vm_free)
+#define vm_avail(B) (B <= vm_free)
+
+
+
+/***================================================================***/
+/* Types of PostScript objects */
+/***================================================================***/
+#define OBJ_INTEGER (0)
+#define OBJ_REAL (1)
+#define OBJ_BOOLEAN (2)
+#define OBJ_ARRAY (3)
+#define OBJ_STRING (4)
+#define OBJ_NAME (5)
+#define OBJ_FILE (6)
+#define OBJ_ENCODING (7)
+
+/***================================================================***/
+/* Value of PostScript objects */
+/***================================================================***/
+typedef union ps_value {
+ char *valueP; /* value pointer for unspecified type */
+ int value; /* value for unspecified type */
+ int integer; /* when type is OBJ_INTEGER */
+ float real; /* when type is OBJ_REAL */
+ int boolean; /* when type is OBJ_BOOLEAN */
+ struct ps_obj *arrayP; /* when type is OBJ_ARRAY */
+ unsigned char *stringP; /* when type is OBJ_STRING */
+ char *nameP; /* when type is OBJ_NAME */
+ FILE *fileP; /* when type is OBJ_FILE */
+} psvalue;
+
+/***================================================================***/
+/* Definition of a PostScript object */
+/***================================================================***/
+typedef struct ps_obj {
+ char type;
+ char unused;
+ unsigned short len;
+ union ps_value data;
+} psobj;
+
+/***================================================================***/
+/* Definition of a PostScript Dictionary Entry */
+/***================================================================***/
+typedef struct ps_dict {
+ psobj key;
+ psobj value;
+} psdict;
+
+/***================================================================***/
+/* Macros for testing type of PostScript objects */
+/***================================================================***/
+#define objIsInteger(o) ((o).type == OBJ_INTEGER)
+#define objIsReal(o) ((o).type == OBJ_REAL)
+#define objIsBoolean(o) ((o).type == OBJ_BOOLEAN)
+#define objIsArray(o) ((o).type == OBJ_ARRAY)
+#define objIsString(o) ((o).type == OBJ_STRING)
+#define objIsName(o) ((o).type == OBJ_NAME)
+#define objIsFile(o) ((o).type == OBJ_FILE)
+
+/***================================================================***/
+/* Macros for setting type of PostScript objects */
+/***================================================================***/
+#define objSetInteger(o) ((o).type = OBJ_INTEGER)
+#define objSetReal(o) ((o).type = OBJ_REAL)
+#define objSetBoolean(o) ((o).type = OBJ_BOOLEAN)
+#define objSetArray(o) ((o).type = OBJ_ARRAY)
+#define objSetString(o) ((o).type = OBJ_STRING)
+#define objSetName(o) ((o).type = OBJ_NAME)
+#define objSetFile(o) ((o).type = OBJ_FILE)
+
+/***================================================================***/
+/* Macros for testing type of PostScript objects (pointer access) */
+/***================================================================***/
+#define objPIsInteger(o) ((o)->type == OBJ_INTEGER)
+#define objPIsReal(o) ((o)->type == OBJ_REAL)
+#define objPIsBoolean(o) ((o)->type == OBJ_BOOLEAN)
+#define objPIsArray(o) ((o)->type == OBJ_ARRAY)
+#define objPIsString(o) ((o)->type == OBJ_STRING)
+#define objPIsName(o) ((o)->type == OBJ_NAME)
+#define objPIsFile(o) ((o)->type == OBJ_FILE)
+
+/***================================================================***/
+/* Macros for setting type of PostScript objects (pointer access) */
+/***================================================================***/
+#define objPSetInteger(o) ((o)->type = OBJ_INTEGER)
+#define objPSetReal(o) ((o)->type = OBJ_REAL)
+#define objPSetBoolean(o) ((o)->type = OBJ_BOOLEAN)
+#define objPSetArray(o) ((o)->type = OBJ_ARRAY)
+#define objPSetString(o) ((o)->type = OBJ_STRING)
+#define objPSetName(o) ((o)->type = OBJ_NAME)
+#define objPSetFile(o) ((o)->type = OBJ_FILE)
+
+/***================================================================***/
+/* Prototypes of object formatting functions */
+/***================================================================***/
+extern void objFormatInteger ( psobj *objP, int value );
+extern void objFormatReal ( psobj *objP, float value );
+extern void objFormatBoolean ( psobj *objP, boolean value );
+extern void objFormatEncoding ( psobj *objP, int length, psobj *valueP );
+extern void objFormatArray ( psobj *objP, int length, psobj *valueP );
+extern void objFormatString ( psobj *objP, int length, char *valueP );
+extern void objFormatName ( psobj *objP, int length, char *valueP );
+extern void objFormatFile ( psobj *objP, FILE *valueP );
+
+extern void T1InitStdProps(void);
+#endif
diff --git a/libXfont/src/bitmap/Makefile.am b/libXfont/src/bitmap/Makefile.am
new file mode 100644
index 000000000..b5b967450
--- /dev/null
+++ b/libXfont/src/bitmap/Makefile.am
@@ -0,0 +1,19 @@
+INCLUDES = \
+ -I${top_srcdir}/include
+
+AM_CFLAGS = $(XFONT_CFLAGS) $(OS_CFLAGS) $(CWARNFLAGS)
+
+noinst_LTLIBRARIES = libbitmap.la
+
+libbitmap_la_SOURCES = \
+ bdfread.c \
+ bdfutils.c \
+ bitmap.c \
+ bitmapfunc.c \
+ bitmaputil.c \
+ bitscale.c \
+ fontink.c \
+ pcfread.c \
+ pcfwrite.c \
+ snfread.c \
+ snfstr.h
diff --git a/libXfont/src/bitmap/Makefile.in b/libXfont/src/bitmap/Makefile.in
new file mode 100644
index 000000000..7bd5fe3ad
--- /dev/null
+++ b/libXfont/src/bitmap/Makefile.in
@@ -0,0 +1,473 @@
+# Makefile.in generated by automake 1.10 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
+# 2003, 2004, 2005, 2006 Free Software Foundation, Inc.
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+@SET_MAKE@
+
+VPATH = @srcdir@
+pkgdatadir = $(datadir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+install_sh_DATA = $(install_sh) -c -m 644
+install_sh_PROGRAM = $(install_sh) -c
+install_sh_SCRIPT = $(install_sh) -c
+INSTALL_HEADER = $(INSTALL_DATA)
+transform = $(program_transform_name)
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+build_triplet = @build@
+host_triplet = @host@
+subdir = src/bitmap
+DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/configure.ac
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+ $(ACLOCAL_M4)
+mkinstalldirs = $(install_sh) -d
+CONFIG_HEADER = $(top_builddir)/config.h \
+ $(top_builddir)/include/X11/fonts/fontconf.h
+CONFIG_CLEAN_FILES =
+LTLIBRARIES = $(noinst_LTLIBRARIES)
+libbitmap_la_LIBADD =
+am_libbitmap_la_OBJECTS = bdfread.lo bdfutils.lo bitmap.lo \
+ bitmapfunc.lo bitmaputil.lo bitscale.lo fontink.lo pcfread.lo \
+ pcfwrite.lo snfread.lo
+libbitmap_la_OBJECTS = $(am_libbitmap_la_OBJECTS)
+DEFAULT_INCLUDES = -I. -I$(top_builddir) -I$(top_builddir)/include/X11/fonts@am__isrc@
+depcomp = $(SHELL) $(top_srcdir)/depcomp
+am__depfiles_maybe = depfiles
+COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
+ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+LTCOMPILE = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
+ --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \
+ $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+CCLD = $(CC)
+LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
+ --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \
+ $(LDFLAGS) -o $@
+SOURCES = $(libbitmap_la_SOURCES)
+DIST_SOURCES = $(libbitmap_la_SOURCES)
+ETAGS = etags
+CTAGS = ctags
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+ACLOCAL = @ACLOCAL@
+AMTAR = @AMTAR@
+AR = @AR@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+CC = @CC@
+CCDEPMODE = @CCDEPMODE@
+CFLAGS = @CFLAGS@
+CHANGELOG_CMD = @CHANGELOG_CMD@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CWARNFLAGS = @CWARNFLAGS@
+CXX = @CXX@
+CXXCPP = @CXXCPP@
+CXXDEPMODE = @CXXDEPMODE@
+CXXFLAGS = @CXXFLAGS@
+CYGPATH_W = @CYGPATH_W@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+ECHO = @ECHO@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+EGREP = @EGREP@
+ENCODINGSDIR = @ENCODINGSDIR@
+EXEEXT = @EXEEXT@
+F77 = @F77@
+FFLAGS = @FFLAGS@
+FREETYPE_CFLAGS = @FREETYPE_CFLAGS@
+FREETYPE_LIBS = @FREETYPE_LIBS@
+FREETYPE_REQUIRES = @FREETYPE_REQUIRES@
+GREP = @GREP@
+INSTALL = @INSTALL@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+LDFLAGS = @LDFLAGS@
+LIBOBJS = @LIBOBJS@
+LIBS = @LIBS@
+LIBTOOL = @LIBTOOL@
+LN_S = @LN_S@
+LTLIBOBJS = @LTLIBOBJS@
+MAKEINFO = @MAKEINFO@
+MATH_LIBS = @MATH_LIBS@
+MKDIR_P = @MKDIR_P@
+OBJEXT = @OBJEXT@
+OS_CFLAGS = @OS_CFLAGS@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+PKG_CONFIG = @PKG_CONFIG@
+RANLIB = @RANLIB@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+STRIP = @STRIP@
+VERSION = @VERSION@
+XFONT_CFLAGS = @XFONT_CFLAGS@
+XFONT_LIBS = @XFONT_LIBS@
+X_GZIP_FONT_COMPRESSION = @X_GZIP_FONT_COMPRESSION@
+Z_LIBS = @Z_LIBS@
+abs_builddir = @abs_builddir@
+abs_srcdir = @abs_srcdir@
+abs_top_builddir = @abs_top_builddir@
+abs_top_srcdir = @abs_top_srcdir@
+ac_ct_CC = @ac_ct_CC@
+ac_ct_CXX = @ac_ct_CXX@
+ac_ct_F77 = @ac_ct_F77@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+am__tar = @am__tar@
+am__untar = @am__untar@
+bindir = @bindir@
+build = @build@
+build_alias = @build_alias@
+build_cpu = @build_cpu@
+build_os = @build_os@
+build_vendor = @build_vendor@
+builddir = @builddir@
+datadir = @datadir@
+datarootdir = @datarootdir@
+distcleancheck_listfiles = @distcleancheck_listfiles@
+docdir = @docdir@
+dvidir = @dvidir@
+exec_prefix = @exec_prefix@
+ft_config = @ft_config@
+host = @host@
+host_alias = @host_alias@
+host_cpu = @host_cpu@
+host_os = @host_os@
+host_vendor = @host_vendor@
+htmldir = @htmldir@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+libdir = @libdir@
+libexecdir = @libexecdir@
+localedir = @localedir@
+localstatedir = @localstatedir@
+mandir = @mandir@
+mkdir_p = @mkdir_p@
+oldincludedir = @oldincludedir@
+pdfdir = @pdfdir@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+psdir = @psdir@
+sbindir = @sbindir@
+sharedstatedir = @sharedstatedir@
+srcdir = @srcdir@
+sysconfdir = @sysconfdir@
+target_alias = @target_alias@
+top_builddir = @top_builddir@
+top_srcdir = @top_srcdir@
+INCLUDES = \
+ -I${top_srcdir}/include
+
+AM_CFLAGS = $(XFONT_CFLAGS) $(OS_CFLAGS) $(CWARNFLAGS)
+noinst_LTLIBRARIES = libbitmap.la
+libbitmap_la_SOURCES = \
+ bdfread.c \
+ bdfutils.c \
+ bitmap.c \
+ bitmapfunc.c \
+ bitmaputil.c \
+ bitscale.c \
+ fontink.c \
+ pcfread.c \
+ pcfwrite.c \
+ snfread.c \
+ snfstr.h
+
+all: all-am
+
+.SUFFIXES:
+.SUFFIXES: .c .lo .o .obj
+$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps)
+ @for dep in $?; do \
+ case '$(am__configure_deps)' in \
+ *$$dep*) \
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh \
+ && exit 0; \
+ exit 1;; \
+ esac; \
+ done; \
+ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign src/bitmap/Makefile'; \
+ cd $(top_srcdir) && \
+ $(AUTOMAKE) --foreign src/bitmap/Makefile
+.PRECIOUS: Makefile
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+ @case '$?' in \
+ *config.status*) \
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
+ *) \
+ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
+ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
+ esac;
+
+$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+
+$(top_srcdir)/configure: $(am__configure_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(ACLOCAL_M4): $(am__aclocal_m4_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+
+clean-noinstLTLIBRARIES:
+ -test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES)
+ @list='$(noinst_LTLIBRARIES)'; for p in $$list; do \
+ dir="`echo $$p | sed -e 's|/[^/]*$$||'`"; \
+ test "$$dir" != "$$p" || dir=.; \
+ echo "rm -f \"$${dir}/so_locations\""; \
+ rm -f "$${dir}/so_locations"; \
+ done
+libbitmap.la: $(libbitmap_la_OBJECTS) $(libbitmap_la_DEPENDENCIES)
+ $(LINK) $(libbitmap_la_OBJECTS) $(libbitmap_la_LIBADD) $(LIBS)
+
+mostlyclean-compile:
+ -rm -f *.$(OBJEXT)
+
+distclean-compile:
+ -rm -f *.tab.c
+
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/bdfread.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/bdfutils.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/bitmap.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/bitmapfunc.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/bitmaputil.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/bitscale.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fontink.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcfread.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcfwrite.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/snfread.Plo@am__quote@
+
+.c.o:
+@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
+@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(COMPILE) -c $<
+
+.c.obj:
+@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'`
+@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(COMPILE) -c `$(CYGPATH_W) '$<'`
+
+.c.lo:
+@am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
+@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(LTCOMPILE) -c -o $@ $<
+
+mostlyclean-libtool:
+ -rm -f *.lo
+
+clean-libtool:
+ -rm -rf .libs _libs
+
+ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) ' { files[$$0] = 1; } \
+ END { for (i in files) print i; }'`; \
+ mkid -fID $$unique
+tags: TAGS
+
+TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
+ $(TAGS_FILES) $(LISP)
+ tags=; \
+ here=`pwd`; \
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) ' { files[$$0] = 1; } \
+ END { for (i in files) print i; }'`; \
+ if test -z "$(ETAGS_ARGS)$$tags$$unique"; then :; else \
+ test -n "$$unique" || unique=$$empty_fix; \
+ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+ $$tags $$unique; \
+ fi
+ctags: CTAGS
+CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
+ $(TAGS_FILES) $(LISP)
+ tags=; \
+ here=`pwd`; \
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) ' { files[$$0] = 1; } \
+ END { for (i in files) print i; }'`; \
+ test -z "$(CTAGS_ARGS)$$tags$$unique" \
+ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
+ $$tags $$unique
+
+GTAGS:
+ here=`$(am__cd) $(top_builddir) && pwd` \
+ && cd $(top_srcdir) \
+ && gtags -i $(GTAGS_ARGS) $$here
+
+distclean-tags:
+ -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
+
+distdir: $(DISTFILES)
+ @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ list='$(DISTFILES)'; \
+ dist_files=`for file in $$list; do echo $$file; done | \
+ sed -e "s|^$$srcdirstrip/||;t" \
+ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
+ case $$dist_files in \
+ */*) $(MKDIR_P) `echo "$$dist_files" | \
+ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
+ sort -u` ;; \
+ esac; \
+ for file in $$dist_files; do \
+ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
+ if test -d $$d/$$file; then \
+ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
+ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
+ cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \
+ fi; \
+ cp -pR $$d/$$file $(distdir)$$dir || exit 1; \
+ else \
+ test -f $(distdir)/$$file \
+ || cp -p $$d/$$file $(distdir)/$$file \
+ || exit 1; \
+ fi; \
+ done
+check-am: all-am
+check: check-am
+all-am: Makefile $(LTLIBRARIES)
+installdirs:
+install: install-am
+install-exec: install-exec-am
+install-data: install-data-am
+uninstall: uninstall-am
+
+install-am: all-am
+ @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-am
+install-strip:
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ `test -z '$(STRIP)' || \
+ echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
+mostlyclean-generic:
+
+clean-generic:
+
+distclean-generic:
+ -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
+
+maintainer-clean-generic:
+ @echo "This command is intended for maintainers to use"
+ @echo "it deletes files that may require special tools to rebuild."
+clean: clean-am
+
+clean-am: clean-generic clean-libtool clean-noinstLTLIBRARIES \
+ mostlyclean-am
+
+distclean: distclean-am
+ -rm -rf ./$(DEPDIR)
+ -rm -f Makefile
+distclean-am: clean-am distclean-compile distclean-generic \
+ distclean-tags
+
+dvi: dvi-am
+
+dvi-am:
+
+html: html-am
+
+info: info-am
+
+info-am:
+
+install-data-am:
+
+install-dvi: install-dvi-am
+
+install-exec-am:
+
+install-html: install-html-am
+
+install-info: install-info-am
+
+install-man:
+
+install-pdf: install-pdf-am
+
+install-ps: install-ps-am
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-am
+ -rm -rf ./$(DEPDIR)
+ -rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-am
+
+mostlyclean-am: mostlyclean-compile mostlyclean-generic \
+ mostlyclean-libtool
+
+pdf: pdf-am
+
+pdf-am:
+
+ps: ps-am
+
+ps-am:
+
+uninstall-am:
+
+.MAKE: install-am install-strip
+
+.PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \
+ clean-libtool clean-noinstLTLIBRARIES ctags distclean \
+ distclean-compile distclean-generic distclean-libtool \
+ distclean-tags distdir dvi dvi-am html html-am info info-am \
+ install install-am install-data install-data-am install-dvi \
+ install-dvi-am install-exec install-exec-am install-html \
+ install-html-am install-info install-info-am install-man \
+ install-pdf install-pdf-am install-ps install-ps-am \
+ install-strip installcheck installcheck-am installdirs \
+ maintainer-clean maintainer-clean-generic mostlyclean \
+ mostlyclean-compile mostlyclean-generic mostlyclean-libtool \
+ pdf pdf-am ps ps-am tags uninstall uninstall-am
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/libXfont/src/bitmap/bdfread.c b/libXfont/src/bitmap/bdfread.c
new file mode 100644
index 000000000..a6f0c1e7e
--- /dev/null
+++ b/libXfont/src/bitmap/bdfread.c
@@ -0,0 +1,967 @@
+/* $Xorg: bdfread.c,v 1.5 2001/02/09 02:04:01 xorgcvs Exp $ */
+
+/************************************************************************
+Copyright 1989 by Digital Equipment Corporation, Maynard, Massachusetts.
+
+ All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and its
+documentation for any purpose and without fee is hereby granted,
+provided that the above copyright notice appear in all copies and that
+both that copyright notice and this permission notice appear in
+supporting documentation, and that the name of Digital not be
+used in advertising or publicity pertaining to distribution of the
+software without specific, written prior permission.
+
+DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
+ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
+DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
+ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
+ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+SOFTWARE.
+
+************************************************************************/
+
+/*
+
+Copyright 1994, 1998 The Open Group
+
+Permission to use, copy, modify, distribute, and sell this software and its
+documentation for any purpose is hereby granted without fee, provided that
+the above copyright notice appear in all copies and that both that
+copyright notice and this permission notice appear in supporting
+documentation.
+
+The above copyright notice and this permission notice shall be included
+in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+IN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR
+OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of The Open Group shall
+not be used in advertising or otherwise to promote the sale, use or
+other dealings in this Software without prior written authorization
+from The Open Group.
+
+*/
+/* $XFree86: xc/lib/font/bitmap/bdfread.c,v 1.12tsi Exp $ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#ifndef FONTMODULE
+#include <ctype.h>
+#endif
+#include <X11/fonts/fntfilst.h>
+#include <X11/fonts/fontutil.h>
+/* use bitmap structure */
+#include <X11/fonts/bitmap.h>
+#include <X11/fonts/bdfint.h>
+
+#if HAVE_STDINT_H
+#include <stdint.h>
+#elif !defined(INT32_MAX)
+#define INT32_MAX 0x7fffffff
+#endif
+
+#define INDICES 256
+#define MAXENCODING 0xFFFF
+#define BDFLINELEN 1024
+
+static Bool bdfPadToTerminal(FontPtr pFont);
+extern int bdfFileLineNum;
+
+/***====================================================================***/
+
+static Bool
+bdfReadBitmap(CharInfoPtr pCI, FontFilePtr file, int bit, int byte,
+ int glyph, int scan, CARD32 *sizes)
+{
+ int widthBits,
+ widthBytes,
+ widthHexChars;
+ int height,
+ row;
+ int i,
+ inLineLen,
+ nextByte;
+ unsigned char *pInBits,
+ *picture,
+ *line = NULL;
+ unsigned char lineBuf[BDFLINELEN];
+
+ widthBits = GLYPHWIDTHPIXELS(pCI);
+ height = GLYPHHEIGHTPIXELS(pCI);
+
+ widthBytes = BYTES_PER_ROW(widthBits, glyph);
+ if (widthBytes * height > 0) {
+ picture = (unsigned char *) xalloc(widthBytes * height);
+ if (!picture) {
+ bdfError("Couldn't allocate picture (%d*%d)\n", widthBytes, height);
+ goto BAILOUT;
+ }
+ } else
+ picture = NULL;
+ pCI->bits = (char *) picture;
+
+ if (sizes) {
+ for (i = 0; i < GLYPHPADOPTIONS; i++)
+ sizes[i] += BYTES_PER_ROW(widthBits, (1 << i)) * height;
+ }
+ nextByte = 0;
+ widthHexChars = BYTES_PER_ROW(widthBits, 1);
+
+/* 5/31/89 (ef) -- hack, hack, hack. what *am* I supposed to do with */
+/* 0 width characters? */
+
+ for (row = 0; row < height; row++) {
+ line = bdfGetLine(file, lineBuf, BDFLINELEN);
+ if (!line)
+ break;
+
+ if (widthBits == 0) {
+ if ((!line) || (bdfIsPrefix(line, "ENDCHAR")))
+ break;
+ else
+ continue;
+ }
+ pInBits = line;
+ inLineLen = strlen((char *) pInBits);
+
+ if (inLineLen & 1) {
+ bdfError("odd number of characters in hex encoding\n");
+ line[inLineLen++] = '0';
+ line[inLineLen] = '\0';
+ }
+ inLineLen >>= 1;
+ i = inLineLen;
+ if (i > widthHexChars)
+ i = widthHexChars;
+ for (; i > 0; i--, pInBits += 2)
+ picture[nextByte++] = bdfHexByte(pInBits);
+
+ /* pad if line is too short */
+ if (inLineLen < widthHexChars) {
+ for (i = widthHexChars - inLineLen; i > 0; i--)
+ picture[nextByte++] = 0;
+ } else {
+ unsigned char mask;
+
+ mask = 0xff << (8 - (widthBits & 0x7));
+ if (mask && picture[nextByte - 1] & ~mask) {
+ picture[nextByte - 1] &= mask;
+ }
+ }
+
+ if (widthBytes > widthHexChars) {
+ i = widthBytes - widthHexChars;
+ while (i-- > 0)
+ picture[nextByte++] = 0;
+ }
+ }
+
+ if ((line && (!bdfIsPrefix(line, "ENDCHAR"))) || (height == 0))
+ line = bdfGetLine(file, lineBuf, BDFLINELEN);
+
+ if ((!line) || (!bdfIsPrefix(line, "ENDCHAR"))) {
+ bdfError("missing 'ENDCHAR'\n");
+ goto BAILOUT;
+ }
+ if (nextByte != height * widthBytes) {
+ bdfError("bytes != rows * bytes_per_row (%d != %d * %d)\n",
+ nextByte, height, widthBytes);
+ goto BAILOUT;
+ }
+ if (picture != NULL) {
+ if (bit == LSBFirst)
+ BitOrderInvert(picture, nextByte);
+ if (bit != byte) {
+ if (scan == 2)
+ TwoByteSwap(picture, nextByte);
+ else if (scan == 4)
+ FourByteSwap(picture, nextByte);
+ }
+ }
+ return (TRUE);
+BAILOUT:
+ if (picture)
+ xfree(picture);
+ pCI->bits = NULL;
+ return (FALSE);
+}
+
+/***====================================================================***/
+
+static Bool
+bdfSkipBitmap(FontFilePtr file, int height)
+{
+ unsigned char *line;
+ int i = 0;
+ unsigned char lineBuf[BDFLINELEN];
+
+ do {
+ line = bdfGetLine(file, lineBuf, BDFLINELEN);
+ i++;
+ } while (line && !bdfIsPrefix(line, "ENDCHAR") && i <= height);
+
+ if (i > 1 && line && !bdfIsPrefix(line, "ENDCHAR")) {
+ bdfError("Error in bitmap, missing 'ENDCHAR'\n");
+ return (FALSE);
+ }
+ return (TRUE);
+}
+
+/***====================================================================***/
+
+static void
+bdfFreeFontBits(FontPtr pFont)
+{
+ BitmapFontPtr bitmapFont;
+ BitmapExtraPtr bitmapExtra;
+ int i, nencoding;
+
+ bitmapFont = (BitmapFontPtr) pFont->fontPrivate;
+ bitmapExtra = (BitmapExtraPtr) bitmapFont->bitmapExtra;
+ xfree(bitmapFont->ink_metrics);
+ if(bitmapFont->encoding) {
+ nencoding = (pFont->info.lastCol - pFont->info.firstCol + 1) *
+ (pFont->info.lastRow - pFont->info.firstRow + 1);
+ for(i=0; i<NUM_SEGMENTS(nencoding); i++)
+ xfree(bitmapFont->encoding[i]);
+ }
+ xfree(bitmapFont->encoding);
+ for (i = 0; i < bitmapFont->num_chars; i++)
+ xfree(bitmapFont->metrics[i].bits);
+ xfree(bitmapFont->metrics);
+ if (bitmapExtra)
+ {
+ xfree (bitmapExtra->glyphNames);
+ xfree (bitmapExtra->sWidths);
+ xfree (bitmapExtra);
+ }
+ xfree(pFont->info.props);
+ xfree(bitmapFont);
+}
+
+
+static Bool
+bdfReadCharacters(FontFilePtr file, FontPtr pFont, bdfFileState *pState,
+ int bit, int byte, int glyph, int scan)
+{
+ unsigned char *line;
+ register CharInfoPtr ci;
+ int i,
+ ndx,
+ nchars,
+ nignored;
+ unsigned int char_row, char_col;
+ int numEncodedGlyphs = 0;
+ CharInfoPtr *bdfEncoding[256];
+ BitmapFontPtr bitmapFont;
+ BitmapExtraPtr bitmapExtra;
+ CARD32 *bitmapsSizes;
+ unsigned char lineBuf[BDFLINELEN];
+ int nencoding;
+
+ bitmapFont = (BitmapFontPtr) pFont->fontPrivate;
+ bitmapExtra = (BitmapExtraPtr) bitmapFont->bitmapExtra;
+
+ if (bitmapExtra) {
+ bitmapsSizes = bitmapExtra->bitmapsSizes;
+ for (i = 0; i < GLYPHPADOPTIONS; i++)
+ bitmapsSizes[i] = 0;
+ } else
+ bitmapsSizes = NULL;
+
+ bzero(bdfEncoding, sizeof(bdfEncoding));
+ bitmapFont->metrics = NULL;
+ ndx = 0;
+
+ line = bdfGetLine(file, lineBuf, BDFLINELEN);
+
+ if ((!line) || (sscanf((char *) line, "CHARS %d", &nchars) != 1)) {
+ bdfError("bad 'CHARS' in bdf file\n");
+ return (FALSE);
+ }
+ if (nchars < 1) {
+ bdfError("invalid number of CHARS in BDF file\n");
+ return (FALSE);
+ }
+ if (nchars > INT32_MAX / sizeof(CharInfoRec)) {
+ bdfError("Couldn't allocate pCI (%d*%d)\n", nchars,
+ sizeof(CharInfoRec));
+ goto BAILOUT;
+ }
+ ci = (CharInfoPtr) xalloc(nchars * sizeof(CharInfoRec));
+ if (!ci) {
+ bdfError("Couldn't allocate pCI (%d*%d)\n", nchars,
+ sizeof(CharInfoRec));
+ goto BAILOUT;
+ }
+ bzero((char *)ci, nchars * sizeof(CharInfoRec));
+ bitmapFont->metrics = ci;
+
+ if (bitmapExtra) {
+ bitmapExtra->glyphNames = (Atom *) xalloc(nchars * sizeof(Atom));
+ if (!bitmapExtra->glyphNames) {
+ bdfError("Couldn't allocate glyphNames (%d*%d)\n",
+ nchars, sizeof(Atom));
+ goto BAILOUT;
+ }
+ }
+ if (bitmapExtra) {
+ bitmapExtra->sWidths = (int *) xalloc(nchars * sizeof(int));
+ if (!bitmapExtra->sWidths) {
+ bdfError("Couldn't allocate sWidth (%d *%d)\n",
+ nchars, sizeof(int));
+ return FALSE;
+ }
+ }
+ line = bdfGetLine(file, lineBuf, BDFLINELEN);
+ pFont->info.firstRow = 256;
+ pFont->info.lastRow = 0;
+ pFont->info.firstCol = 256;
+ pFont->info.lastCol = 0;
+ nignored = 0;
+ for (ndx = 0; (ndx < nchars) && (line) && (bdfIsPrefix(line, "STARTCHAR"));) {
+ int t;
+ int wx; /* x component of width */
+ int wy; /* y component of width */
+ int bw; /* bounding-box width */
+ int bh; /* bounding-box height */
+ int bl; /* bounding-box left */
+ int bb; /* bounding-box bottom */
+ int enc,
+ enc2; /* encoding */
+ unsigned char *p; /* temp pointer into line */
+ char charName[100];
+ int ignore;
+
+ if (sscanf((char *) line, "STARTCHAR %s", charName) != 1) {
+ bdfError("bad character name in BDF file\n");
+ goto BAILOUT; /* bottom of function, free and return error */
+ }
+ if (bitmapExtra)
+ bitmapExtra->glyphNames[ndx] = bdfForceMakeAtom(charName, NULL);
+
+ line = bdfGetLine(file, lineBuf, BDFLINELEN);
+ if (!line || (t = sscanf((char *) line, "ENCODING %d %d", &enc, &enc2)) < 1) {
+ bdfError("bad 'ENCODING' in BDF file\n");
+ goto BAILOUT;
+ }
+ if (enc < -1 || (t == 2 && enc2 < -1)) {
+ bdfError("bad ENCODING value");
+ goto BAILOUT;
+ }
+ if (t == 2 && enc == -1)
+ enc = enc2;
+ ignore = 0;
+ if (enc == -1) {
+ if (!bitmapExtra) {
+ nignored++;
+ ignore = 1;
+ }
+ } else if (enc > MAXENCODING) {
+ bdfError("char '%s' has encoding too large (%d)\n",
+ charName, enc);
+ } else {
+ char_row = (enc >> 8) & 0xFF;
+ char_col = enc & 0xFF;
+ if (char_row < pFont->info.firstRow)
+ pFont->info.firstRow = char_row;
+ if (char_row > pFont->info.lastRow)
+ pFont->info.lastRow = char_row;
+ if (char_col < pFont->info.firstCol)
+ pFont->info.firstCol = char_col;
+ if (char_col > pFont->info.lastCol)
+ pFont->info.lastCol = char_col;
+ if (bdfEncoding[char_row] == (CharInfoPtr *) NULL) {
+ bdfEncoding[char_row] =
+ (CharInfoPtr *) xalloc(256 * sizeof(CharInfoPtr));
+ if (!bdfEncoding[char_row]) {
+ bdfError("Couldn't allocate row %d of encoding (%d*%d)\n",
+ char_row, INDICES, sizeof(CharInfoPtr));
+ goto BAILOUT;
+ }
+ for (i = 0; i < 256; i++)
+ bdfEncoding[char_row][i] = (CharInfoPtr) NULL;
+ }
+ if (bdfEncoding[char_row] != NULL) {
+ bdfEncoding[char_row][char_col] = ci;
+ numEncodedGlyphs++;
+ }
+ }
+
+ line = bdfGetLine(file, lineBuf, BDFLINELEN);
+ if ((!line) || (sscanf((char *) line, "SWIDTH %d %d", &wx, &wy) != 2)) {
+ bdfError("bad 'SWIDTH'\n");
+ goto BAILOUT;
+ }
+ if (wy != 0) {
+ bdfError("SWIDTH y value must be zero\n");
+ goto BAILOUT;
+ }
+ if (bitmapExtra)
+ bitmapExtra->sWidths[ndx] = wx;
+
+/* 5/31/89 (ef) -- we should be able to ditch the character and recover */
+/* from all of these. */
+
+ line = bdfGetLine(file, lineBuf, BDFLINELEN);
+ if ((!line) || (sscanf((char *) line, "DWIDTH %d %d", &wx, &wy) != 2)) {
+ bdfError("bad 'DWIDTH'\n");
+ goto BAILOUT;
+ }
+ if (wy != 0) {
+ bdfError("DWIDTH y value must be zero\n");
+ goto BAILOUT;
+ }
+ line = bdfGetLine(file, lineBuf, BDFLINELEN);
+ if ((!line) || (sscanf((char *) line, "BBX %d %d %d %d", &bw, &bh, &bl, &bb) != 4)) {
+ bdfError("bad 'BBX'\n");
+ goto BAILOUT;
+ }
+ if ((bh < 0) || (bw < 0)) {
+ bdfError("character '%s' has a negative sized bitmap, %dx%d\n",
+ charName, bw, bh);
+ goto BAILOUT;
+ }
+ line = bdfGetLine(file, lineBuf, BDFLINELEN);
+ if ((line) && (bdfIsPrefix(line, "ATTRIBUTES"))) {
+ for (p = line + strlen("ATTRIBUTES ");
+ (*p == ' ') || (*p == '\t');
+ p++)
+ /* empty for loop */ ;
+ ci->metrics.attributes = (bdfHexByte(p) << 8) + bdfHexByte(p + 2);
+ line = bdfGetLine(file, lineBuf, BDFLINELEN);
+ } else
+ ci->metrics.attributes = 0;
+
+ if (!line || !bdfIsPrefix(line, "BITMAP")) {
+ bdfError("missing 'BITMAP'\n");
+ goto BAILOUT;
+ }
+ /* collect data for generated properties */
+ if ((strlen(charName) == 1)) {
+ if ((charName[0] >= '0') && (charName[0] <= '9')) {
+ pState->digitWidths += wx;
+ pState->digitCount++;
+ } else if (charName[0] == 'x') {
+ pState->exHeight = (bh + bb) <= 0 ? bh : bh + bb;
+ }
+ }
+ if (!ignore) {
+ ci->metrics.leftSideBearing = bl;
+ ci->metrics.rightSideBearing = bl + bw;
+ ci->metrics.ascent = bh + bb;
+ ci->metrics.descent = -bb;
+ ci->metrics.characterWidth = wx;
+ ci->bits = NULL;
+ bdfReadBitmap(ci, file, bit, byte, glyph, scan, bitmapsSizes);
+ ci++;
+ ndx++;
+ } else
+ bdfSkipBitmap(file, bh);
+
+ line = bdfGetLine(file, lineBuf, BDFLINELEN); /* get STARTCHAR or
+ * ENDFONT */
+ }
+
+ if (ndx + nignored != nchars) {
+ bdfError("%d too few characters\n", nchars - (ndx + nignored));
+ goto BAILOUT;
+ }
+ nchars = ndx;
+ bitmapFont->num_chars = nchars;
+ if ((line) && (bdfIsPrefix(line, "STARTCHAR"))) {
+ bdfError("more characters than specified\n");
+ goto BAILOUT;
+ }
+ if ((!line) || (!bdfIsPrefix(line, "ENDFONT"))) {
+ bdfError("missing 'ENDFONT'\n");
+ goto BAILOUT;
+ }
+ if (numEncodedGlyphs == 0)
+ bdfWarning("No characters with valid encodings\n");
+
+ nencoding = (pFont->info.lastRow - pFont->info.firstRow + 1) *
+ (pFont->info.lastCol - pFont->info.firstCol + 1);
+ bitmapFont->encoding =
+ (CharInfoPtr **) xcalloc(NUM_SEGMENTS(nencoding),
+ sizeof(CharInfoPtr*));
+ if (!bitmapFont->encoding) {
+ bdfError("Couldn't allocate ppCI (%d,%d)\n",
+ NUM_SEGMENTS(nencoding),
+ sizeof(CharInfoPtr*));
+ goto BAILOUT;
+ }
+ pFont->info.allExist = TRUE;
+ i = 0;
+ for (char_row = pFont->info.firstRow;
+ char_row <= pFont->info.lastRow;
+ char_row++) {
+ if (bdfEncoding[char_row] == (CharInfoPtr *) NULL) {
+ pFont->info.allExist = FALSE;
+ i += pFont->info.lastCol - pFont->info.firstCol + 1;
+ } else {
+ for (char_col = pFont->info.firstCol;
+ char_col <= pFont->info.lastCol;
+ char_col++) {
+ if (!bdfEncoding[char_row][char_col])
+ pFont->info.allExist = FALSE;
+ else {
+ if (!bitmapFont->encoding[SEGMENT_MAJOR(i)]) {
+ bitmapFont->encoding[SEGMENT_MAJOR(i)]=
+ (CharInfoPtr*)xcalloc(BITMAP_FONT_SEGMENT_SIZE,
+ sizeof(CharInfoPtr));
+ if (!bitmapFont->encoding[SEGMENT_MAJOR(i)])
+ goto BAILOUT;
+ }
+ ACCESSENCODINGL(bitmapFont->encoding,i) =
+ bdfEncoding[char_row][char_col];
+ }
+ i++;
+ }
+ }
+ }
+ for (i = 0; i < 256; i++)
+ if (bdfEncoding[i])
+ xfree(bdfEncoding[i]);
+ return (TRUE);
+BAILOUT:
+ for (i = 0; i < 256; i++)
+ if (bdfEncoding[i])
+ xfree(bdfEncoding[i]);
+ /* bdfFreeFontBits will clean up the rest */
+ return (FALSE);
+}
+
+/***====================================================================***/
+
+static Bool
+bdfReadHeader(FontFilePtr file, bdfFileState *pState)
+{
+ unsigned char *line;
+ char namebuf[BDFLINELEN];
+ unsigned char lineBuf[BDFLINELEN];
+
+ line = bdfGetLine(file, lineBuf, BDFLINELEN);
+ if (!line || sscanf((char *) line, "STARTFONT %s", namebuf) != 1 ||
+ !bdfStrEqual(namebuf, "2.1")) {
+ bdfError("bad 'STARTFONT'\n");
+ return (FALSE);
+ }
+ line = bdfGetLine(file, lineBuf, BDFLINELEN);
+ if (!line || sscanf((char *) line, "FONT %[^\n]", pState->fontName) != 1) {
+ bdfError("bad 'FONT'\n");
+ return (FALSE);
+ }
+ line = bdfGetLine(file, lineBuf, BDFLINELEN);
+ if (!line || !bdfIsPrefix(line, "SIZE")) {
+ bdfError("missing 'SIZE'\n");
+ return (FALSE);
+ }
+ if (sscanf((char *) line, "SIZE %f%d%d", &pState->pointSize,
+ &pState->resolution_x, &pState->resolution_y) != 3) {
+ bdfError("bad 'SIZE'\n");
+ return (FALSE);
+ }
+ if (pState->pointSize < 1 ||
+ pState->resolution_x < 1 || pState->resolution_y < 1) {
+ bdfError("SIZE values must be > 0\n");
+ return (FALSE);
+ }
+ line = bdfGetLine(file, lineBuf, BDFLINELEN);
+ if (!line || !bdfIsPrefix(line, "FONTBOUNDINGBOX")) {
+ bdfError("missing 'FONTBOUNDINGBOX'\n");
+ return (FALSE);
+ }
+ return (TRUE);
+}
+
+/***====================================================================***/
+
+static Bool
+bdfReadProperties(FontFilePtr file, FontPtr pFont, bdfFileState *pState)
+{
+ int nProps, props_left,
+ nextProp;
+ char *stringProps;
+ FontPropPtr props;
+ char namebuf[BDFLINELEN],
+ secondbuf[BDFLINELEN],
+ thirdbuf[BDFLINELEN];
+ unsigned char *line;
+ unsigned char lineBuf[BDFLINELEN];
+ BitmapFontPtr bitmapFont = (BitmapFontPtr) pFont->fontPrivate;
+
+ line = bdfGetLine(file, lineBuf, BDFLINELEN);
+ if (!line || !bdfIsPrefix(line, "STARTPROPERTIES")) {
+ bdfError("missing 'STARTPROPERTIES'\n");
+ return (FALSE);
+ }
+ if (sscanf((char *) line, "STARTPROPERTIES %d", &nProps) != 1) {
+ bdfError("bad 'STARTPROPERTIES'\n");
+ return (FALSE);
+ }
+ pFont->info.isStringProp = NULL;
+ pFont->info.props = NULL;
+ pFont->info.nprops = 0;
+
+ stringProps = (char *) xalloc((nProps + BDF_GENPROPS) * sizeof(char));
+ pFont->info.isStringProp = stringProps;
+ if (stringProps == NULL) {
+ bdfError("Couldn't allocate stringProps (%d*%d)\n",
+ (nProps + BDF_GENPROPS), sizeof(Bool));
+ goto BAILOUT;
+ }
+ pFont->info.props = props = (FontPropPtr) xalloc((nProps + BDF_GENPROPS) *
+ sizeof(FontPropRec));
+ if (props == NULL) {
+ bdfError("Couldn't allocate props (%d*%d)\n", nProps + BDF_GENPROPS,
+ sizeof(FontPropRec));
+ goto BAILOUT;
+ }
+ bzero((char *)props, (nProps + BDF_GENPROPS) * sizeof(FontPropRec));
+
+ nextProp = 0;
+ props_left = nProps;
+ while (props_left-- > 0) {
+ line = bdfGetLine(file, lineBuf, BDFLINELEN);
+ if (line == NULL || bdfIsPrefix(line, "ENDPROPERTIES")) {
+ bdfError("\"STARTPROPERTIES %d\" followed by only %d properties\n",
+ nProps, nProps - props_left - 1);
+ goto BAILOUT;
+ }
+ while (*line && isspace(*line))
+ line++;
+
+ switch (sscanf((char *) line, "%s%s%s", namebuf, secondbuf, thirdbuf)) {
+ default:
+ bdfError("missing '%s' parameter value\n", namebuf);
+ goto BAILOUT;
+
+ case 2:
+ /*
+ * Possibilites include: valid quoted string with no white space
+ * valid integer value invalid value
+ */
+ if (secondbuf[0] == '"') {
+ stringProps[nextProp] = TRUE;
+ props[nextProp].value =
+ bdfGetPropertyValue((char *)line + strlen(namebuf) + 1);
+ if (!props[nextProp].value)
+ goto BAILOUT;
+ break;
+ } else if (bdfIsInteger(secondbuf)) {
+ stringProps[nextProp] = FALSE;
+ props[nextProp].value = atoi(secondbuf);
+ break;
+ } else {
+ bdfError("invalid '%s' parameter value\n", namebuf);
+ goto BAILOUT;
+ }
+
+ case 3:
+ /*
+ * Possibilites include: valid quoted string with some white space
+ * invalid value (reject even if second string is integer)
+ */
+ if (secondbuf[0] == '"') {
+ stringProps[nextProp] = TRUE;
+ props[nextProp].value =
+ bdfGetPropertyValue((char *)line + strlen(namebuf) + 1);
+ if (!props[nextProp].value)
+ goto BAILOUT;
+ break;
+ } else {
+ bdfError("invalid '%s' parameter value\n", namebuf);
+ goto BAILOUT;
+ }
+ }
+ props[nextProp].name = bdfForceMakeAtom(namebuf, NULL);
+ if (props[nextProp].name == None) {
+ bdfError("Empty property name.\n");
+ goto BAILOUT;
+ }
+ if (!bdfSpecialProperty(pFont, &props[nextProp],
+ stringProps[nextProp], pState))
+ nextProp++;
+ }
+
+ line = bdfGetLine(file, lineBuf, BDFLINELEN);
+ if (!line || !bdfIsPrefix(line, "ENDPROPERTIES")) {
+ bdfError("missing 'ENDPROPERTIES'\n");
+ goto BAILOUT;
+ }
+ if (!pState->haveFontAscent || !pState->haveFontDescent) {
+ bdfError("missing 'FONT_ASCENT' or 'FONT_DESCENT' properties\n");
+ goto BAILOUT;
+ }
+ if (bitmapFont->bitmapExtra) {
+ bitmapFont->bitmapExtra->info.fontAscent = pFont->info.fontAscent;
+ bitmapFont->bitmapExtra->info.fontDescent = pFont->info.fontDescent;
+ }
+ if (!pState->pointSizeProp) {
+ props[nextProp].name = bdfForceMakeAtom("POINT_SIZE", NULL);
+ props[nextProp].value = (INT32) (pState->pointSize * 10.0);
+ stringProps[nextProp] = FALSE;
+ pState->pointSizeProp = &props[nextProp];
+ nextProp++;
+ }
+ if (!pState->fontProp) {
+ props[nextProp].name = bdfForceMakeAtom("FONT", NULL);
+ props[nextProp].value = (INT32) bdfForceMakeAtom(pState->fontName, NULL);
+ stringProps[nextProp] = TRUE;
+ pState->fontProp = &props[nextProp];
+ nextProp++;
+ }
+ if (!pState->weightProp) {
+ props[nextProp].name = bdfForceMakeAtom("WEIGHT", NULL);
+ props[nextProp].value = -1; /* computed later */
+ stringProps[nextProp] = FALSE;
+ pState->weightProp = &props[nextProp];
+ nextProp++;
+ }
+ if (!pState->resolutionProp &&
+ pState->resolution_x == pState->resolution_y) {
+ props[nextProp].name = bdfForceMakeAtom("RESOLUTION", NULL);
+ props[nextProp].value = (INT32) ((pState->resolution_x * 100.0) / 72.27);
+ stringProps[nextProp] = FALSE;
+ pState->resolutionProp = &props[nextProp];
+ nextProp++;
+ }
+ if (!pState->resolutionXProp) {
+ props[nextProp].name = bdfForceMakeAtom("RESOLUTION_X", NULL);
+ props[nextProp].value = (INT32) pState->resolution_x;
+ stringProps[nextProp] = FALSE;
+ pState->resolutionProp = &props[nextProp];
+ nextProp++;
+ }
+ if (!pState->resolutionYProp) {
+ props[nextProp].name = bdfForceMakeAtom("RESOLUTION_Y", NULL);
+ props[nextProp].value = (INT32) pState->resolution_y;
+ stringProps[nextProp] = FALSE;
+ pState->resolutionProp = &props[nextProp];
+ nextProp++;
+ }
+ if (!pState->xHeightProp) {
+ props[nextProp].name = bdfForceMakeAtom("X_HEIGHT", NULL);
+ props[nextProp].value = -1; /* computed later */
+ stringProps[nextProp] = FALSE;
+ pState->xHeightProp = &props[nextProp];
+ nextProp++;
+ }
+ if (!pState->quadWidthProp) {
+ props[nextProp].name = bdfForceMakeAtom("QUAD_WIDTH", NULL);
+ props[nextProp].value = -1; /* computed later */
+ stringProps[nextProp] = FALSE;
+ pState->quadWidthProp = &props[nextProp];
+ nextProp++;
+ }
+ pFont->info.nprops = nextProp;
+ return (TRUE);
+BAILOUT:
+ if (pFont->info.isStringProp) {
+ xfree(pFont->info.isStringProp);
+ pFont->info.isStringProp = NULL;
+ }
+ if (pFont->info.props) {
+ xfree(pFont->info.props);
+ pFont->info.props = NULL;
+ }
+ while (line && bdfIsPrefix(line, "ENDPROPERTIES"))
+ line = bdfGetLine(file, lineBuf, BDFLINELEN);
+ return (FALSE);
+}
+
+/***====================================================================***/
+
+static void
+bdfUnloadFont(FontPtr pFont)
+{
+ bdfFreeFontBits (pFont);
+ DestroyFontRec(pFont);
+}
+
+int
+bdfReadFont(FontPtr pFont, FontFilePtr file,
+ int bit, int byte, int glyph, int scan)
+{
+ bdfFileState state;
+ xCharInfo *min,
+ *max;
+ BitmapFontPtr bitmapFont;
+
+ pFont->fontPrivate = 0;
+
+ bzero(&state, sizeof(bdfFileState));
+ bdfFileLineNum = 0;
+
+ if (!bdfReadHeader(file, &state))
+ goto BAILOUT;
+
+ bitmapFont = (BitmapFontPtr) xalloc(sizeof(BitmapFontRec));
+ if (!bitmapFont) {
+ bdfError("Couldn't allocate bitmapFontRec (%d)\n", sizeof(BitmapFontRec));
+ goto BAILOUT;
+ }
+ bzero((char *)bitmapFont, sizeof(BitmapFontRec));
+
+ pFont->fontPrivate = (pointer) bitmapFont;
+ bitmapFont->metrics = 0;
+ bitmapFont->ink_metrics = 0;
+ bitmapFont->bitmaps = 0;
+ bitmapFont->encoding = 0;
+ bitmapFont->pDefault = NULL;
+
+ bitmapFont->bitmapExtra = (BitmapExtraPtr) xalloc(sizeof(BitmapExtraRec));
+ if (!bitmapFont->bitmapExtra) {
+ bdfError("Couldn't allocate bitmapExtra (%d)\n", sizeof(BitmapExtraRec));
+ goto BAILOUT;
+ }
+ bzero((char *)bitmapFont->bitmapExtra, sizeof(BitmapExtraRec));
+
+ bitmapFont->bitmapExtra->glyphNames = 0;
+ bitmapFont->bitmapExtra->sWidths = 0;
+
+ if (!bdfReadProperties(file, pFont, &state))
+ goto BAILOUT;
+
+ if (!bdfReadCharacters(file, pFont, &state, bit, byte, glyph, scan))
+ goto BAILOUT;
+
+ if (state.haveDefaultCh) {
+ unsigned int r, c, cols;
+
+ r = pFont->info.defaultCh >> 8;
+ c = pFont->info.defaultCh & 0xFF;
+ if (pFont->info.firstRow <= r && r <= pFont->info.lastRow &&
+ pFont->info.firstCol <= c && c <= pFont->info.lastCol) {
+ cols = pFont->info.lastCol - pFont->info.firstCol + 1;
+ r = r - pFont->info.firstRow;
+ c = c - pFont->info.firstCol;
+ bitmapFont->pDefault = ACCESSENCODING(bitmapFont->encoding,
+ r * cols + c);
+ }
+ }
+ pFont->bit = bit;
+ pFont->byte = byte;
+ pFont->glyph = glyph;
+ pFont->scan = scan;
+ pFont->info.anamorphic = FALSE;
+ pFont->info.cachable = TRUE;
+ bitmapComputeFontBounds(pFont);
+ if (FontCouldBeTerminal(&pFont->info)) {
+ bdfPadToTerminal(pFont);
+ bitmapComputeFontBounds(pFont);
+ }
+ FontComputeInfoAccelerators(&pFont->info);
+ if (bitmapFont->bitmapExtra)
+ FontComputeInfoAccelerators(&bitmapFont->bitmapExtra->info);
+ if (pFont->info.constantMetrics) {
+ if (!bitmapAddInkMetrics(pFont)) {
+ bdfError("Failed to add bitmap ink metrics\n");
+ goto BAILOUT;
+ }
+ }
+ if (bitmapFont->bitmapExtra)
+ bitmapFont->bitmapExtra->info.inkMetrics = pFont->info.inkMetrics;
+
+ bitmapComputeFontInkBounds(pFont);
+/* ComputeFontAccelerators (pFont); */
+
+ /* generate properties */
+ min = &pFont->info.ink_minbounds;
+ max = &pFont->info.ink_maxbounds;
+ if (state.xHeightProp && (state.xHeightProp->value == -1))
+ state.xHeightProp->value = state.exHeight ?
+ state.exHeight : min->ascent;
+
+ if (state.quadWidthProp && (state.quadWidthProp->value == -1))
+ state.quadWidthProp->value = state.digitCount ?
+ (INT32) (state.digitWidths / state.digitCount) :
+ (min->characterWidth + max->characterWidth) / 2;
+
+ if (state.weightProp && (state.weightProp->value == -1))
+ state.weightProp->value = bitmapComputeWeight(pFont);
+
+ pFont->get_glyphs = bitmapGetGlyphs;
+ pFont->get_metrics = bitmapGetMetrics;
+ pFont->unload_font = bdfUnloadFont;
+ pFont->unload_glyphs = NULL;
+ return Successful;
+BAILOUT:
+ if (pFont->fontPrivate)
+ bdfFreeFontBits (pFont);
+ return AllocError;
+}
+
+int
+bdfReadFontInfo(FontInfoPtr pFontInfo, FontFilePtr file)
+{
+ FontRec font;
+ int ret;
+
+ bzero(&font, sizeof (FontRec));
+
+ ret = bdfReadFont(&font, file, MSBFirst, LSBFirst, 1, 1);
+ if (ret == Successful) {
+ *pFontInfo = font.info;
+ font.info.props = 0;
+ font.info.isStringProp = 0;
+ font.info.nprops = 0;
+ bdfFreeFontBits (&font);
+ }
+ return ret;
+}
+
+static Bool
+bdfPadToTerminal(FontPtr pFont)
+{
+ BitmapFontPtr bitmapFont;
+ BitmapExtraPtr bitmapExtra;
+ int i;
+ int new_size;
+ CharInfoRec new;
+ int w,
+ h;
+
+ bitmapFont = (BitmapFontPtr) pFont->fontPrivate;
+
+ bzero(&new, sizeof(CharInfoRec));
+ new.metrics.ascent = pFont->info.fontAscent;
+ new.metrics.descent = pFont->info.fontDescent;
+ new.metrics.leftSideBearing = 0;
+ new.metrics.rightSideBearing = pFont->info.minbounds.characterWidth;
+ new.metrics.characterWidth = new.metrics.rightSideBearing;
+ new_size = BYTES_FOR_GLYPH(&new, pFont->glyph);
+
+ for (i = 0; i < bitmapFont->num_chars; i++) {
+ new.bits = (char *) xalloc(new_size);
+ if (!new.bits) {
+ bdfError("Couldn't allocate bits (%d)\n", new_size);
+ return FALSE;
+ }
+ FontCharReshape(pFont, &bitmapFont->metrics[i], &new);
+ new.metrics.attributes = bitmapFont->metrics[i].metrics.attributes;
+ xfree(bitmapFont->metrics[i].bits);
+ bitmapFont->metrics[i] = new;
+ }
+ bitmapExtra = bitmapFont->bitmapExtra;
+ if (bitmapExtra) {
+ w = GLYPHWIDTHPIXELS(&new);
+ h = GLYPHHEIGHTPIXELS(&new);
+ for (i = 0; i < GLYPHPADOPTIONS; i++)
+ bitmapExtra->bitmapsSizes[i] = bitmapFont->num_chars *
+ (BYTES_PER_ROW(w, 1 << i) * h);
+ }
+ return TRUE;
+}
diff --git a/libXfont/src/bitmap/bdfutils.c b/libXfont/src/bitmap/bdfutils.c
new file mode 100644
index 000000000..a0c5ae949
--- /dev/null
+++ b/libXfont/src/bitmap/bdfutils.c
@@ -0,0 +1,340 @@
+/* $Xorg: bdfutils.c,v 1.5 2001/02/09 02:04:02 xorgcvs Exp $ */
+/************************************************************************
+Copyright 1989 by Digital Equipment Corporation, Maynard, Massachusetts.
+
+ All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and its
+documentation for any purpose and without fee is hereby granted,
+provided that the above copyright notice appear in all copies and that
+both that copyright notice and this permission notice appear in
+supporting documentation, and that the name of Digital not be
+used in advertising or publicity pertaining to distribution of the
+software without specific, written prior permission.
+
+DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
+ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
+DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
+ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
+ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+SOFTWARE.
+
+************************************************************************/
+
+/*
+
+Copyright 1994, 1998 The Open Group
+
+Permission to use, copy, modify, distribute, and sell this software and its
+documentation for any purpose is hereby granted without fee, provided that
+the above copyright notice appear in all copies and that both that
+copyright notice and this permission notice appear in supporting
+documentation.
+
+The above copyright notice and this permission notice shall be included
+in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+IN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR
+OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of The Open Group shall
+not be used in advertising or otherwise to promote the sale, use or
+other dealings in this Software without prior written authorization
+from The Open Group.
+
+*/
+/* $XFree86: xc/lib/font/bitmap/bdfutils.c,v 1.10 2001/12/14 19:56:45 dawes Exp $ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#ifndef FONTMODULE
+#include <ctype.h>
+#include <stdio.h>
+#include <stdarg.h>
+#endif
+
+#include <X11/fonts/fntfilst.h>
+#include <X11/fonts/fontstruct.h>
+/* use bitmap structure */
+#include <X11/fonts/bitmap.h>
+#include <X11/fonts/bdfint.h>
+
+int bdfFileLineNum;
+
+/***====================================================================***/
+
+void
+bdfError(char* message, ...)
+{
+ va_list args;
+
+ va_start (args, message);
+ fprintf(stderr, "BDF Error on line %d: ", bdfFileLineNum);
+ vfprintf(stderr, message, args);
+ va_end (args);
+}
+
+/***====================================================================***/
+
+void
+bdfWarning(char *message, ...)
+{
+ va_list args;
+
+ va_start (args, message);
+ fprintf(stderr, "BDF Warning on line %d: ", bdfFileLineNum);
+ vfprintf(stderr, message, args);
+ va_end (args);
+}
+
+/*
+ * read the next (non-comment) line and keep a count for error messages.
+ * Returns buf, or NULL if EOF.
+ */
+
+unsigned char *
+bdfGetLine(FontFilePtr file, unsigned char *buf, int len)
+{
+ int c;
+ unsigned char *b;
+
+ for (;;) {
+ b = buf;
+ while ((c = FontFileGetc(file)) != FontFileEOF) {
+ if (c == '\r')
+ continue;
+ if (c == '\n') {
+ bdfFileLineNum++;
+ break;
+ }
+ if (b - buf >= (len - 1))
+ break;
+ *b++ = c;
+ }
+ *b = '\0';
+ if (c == FontFileEOF)
+ return NULL;
+ if (b != buf && !bdfIsPrefix(buf, "COMMENT"))
+ break;
+ }
+ return buf;
+}
+
+/***====================================================================***/
+
+Atom
+bdfForceMakeAtom(char *str, int *size)
+{
+ register int len = strlen(str);
+ Atom the_atom;
+
+ if (size != NULL)
+ *size += len + 1;
+ the_atom = MakeAtom(str, len, TRUE);
+ if (the_atom == None)
+ bdfError("Atom allocation failed\n");
+ return the_atom;
+}
+
+/***====================================================================***/
+
+/*
+ * Handle quoted strings.
+ */
+
+Atom
+bdfGetPropertyValue(char *s)
+{
+ register char *p,
+ *pp;
+ char *orig_s = s;
+ Atom atom;
+
+ /* strip leading white space */
+ while (*s && (*s == ' ' || *s == '\t'))
+ s++;
+ if (*s == 0) {
+ return bdfForceMakeAtom(s, NULL);
+ }
+ if (*s != '"') {
+ pp = s;
+ /* no white space in value */
+ for (pp = s; *pp; pp++)
+ if (*pp == ' ' || *pp == '\t' || *pp == '\015' || *pp == '\n') {
+ *pp = 0;
+ break;
+ }
+ return bdfForceMakeAtom(s, NULL);
+ }
+ /* quoted string: strip outer quotes and undouble inner quotes */
+ s++;
+ pp = p = (char *) xalloc((unsigned) strlen(s) + 1);
+ if (pp == NULL) {
+ bdfError("Couldn't allocate property value string (%d)\n", strlen(s) + 1);
+ return None;
+ }
+ while (*s) {
+ if (*s == '"') {
+ if (*(s + 1) != '"') {
+ *p++ = 0;
+ atom = bdfForceMakeAtom(pp, NULL);
+ xfree(pp);
+ return atom;
+ } else {
+ s++;
+ }
+ }
+ *p++ = *s++;
+ }
+ xfree (pp);
+ bdfError("unterminated quoted string property: %s\n", (pointer) orig_s);
+ return None;
+}
+
+/***====================================================================***/
+
+/*
+ * return TRUE if string is a valid integer
+ */
+int
+bdfIsInteger(char *str)
+{
+ char c;
+
+ c = *str++;
+ if (!(isdigit(c) || c == '-' || c == '+'))
+ return (FALSE);
+
+ while ((c = *str++))
+ if (!isdigit(c))
+ return (FALSE);
+
+ return (TRUE);
+}
+
+/***====================================================================***/
+
+/*
+ * make a byte from the first two hex characters in glyph picture
+ */
+
+unsigned char
+bdfHexByte(unsigned char *s)
+{
+ unsigned char b = 0;
+ register char c;
+ int i;
+
+ for (i = 2; i; i--) {
+ c = *s++;
+ if ((c >= '0') && (c <= '9'))
+ b = (b << 4) + (c - '0');
+ else if ((c >= 'A') && (c <= 'F'))
+ b = (b << 4) + 10 + (c - 'A');
+ else if ((c >= 'a') && (c <= 'f'))
+ b = (b << 4) + 10 + (c - 'a');
+ else
+ bdfError("bad hex char '%c'", c);
+ }
+ return b;
+}
+
+/***====================================================================***/
+
+/*
+ * check for known special property values
+ */
+
+static char *SpecialAtoms[] = {
+ "FONT_ASCENT",
+#define BDF_FONT_ASCENT 0
+ "FONT_DESCENT",
+#define BDF_FONT_DESCENT 1
+ "DEFAULT_CHAR",
+#define BDF_DEFAULT_CHAR 2
+ "POINT_SIZE",
+#define BDF_POINT_SIZE 3
+ "RESOLUTION",
+#define BDF_RESOLUTION 4
+ "X_HEIGHT",
+#define BDF_X_HEIGHT 5
+ "WEIGHT",
+#define BDF_WEIGHT 6
+ "QUAD_WIDTH",
+#define BDF_QUAD_WIDTH 7
+ "FONT",
+#define BDF_FONT 8
+ "RESOLUTION_X",
+#define BDF_RESOLUTION_X 9
+ "RESOLUTION_Y",
+#define BDF_RESOLUTION_Y 10
+ 0,
+};
+
+Bool
+bdfSpecialProperty(FontPtr pFont, FontPropPtr prop,
+ char isString, bdfFileState *bdfState)
+{
+ char **special;
+ char *name;
+
+ name = NameForAtom(prop->name);
+ for (special = SpecialAtoms; *special; special++)
+ if (!strcmp(name, *special))
+ break;
+
+ switch (special - SpecialAtoms) {
+ case BDF_FONT_ASCENT:
+ if (!isString) {
+ pFont->info.fontAscent = prop->value;
+ bdfState->haveFontAscent = TRUE;
+ }
+ return TRUE;
+ case BDF_FONT_DESCENT:
+ if (!isString) {
+ pFont->info.fontDescent = prop->value;
+ bdfState->haveFontDescent = TRUE;
+ }
+ return TRUE;
+ case BDF_DEFAULT_CHAR:
+ if (!isString) {
+ pFont->info.defaultCh = prop->value;
+ bdfState->haveDefaultCh = TRUE;
+ }
+ return TRUE;
+ case BDF_POINT_SIZE:
+ bdfState->pointSizeProp = prop;
+ return FALSE;
+ case BDF_RESOLUTION:
+ bdfState->resolutionProp = prop;
+ return FALSE;
+ case BDF_X_HEIGHT:
+ bdfState->xHeightProp = prop;
+ return FALSE;
+ case BDF_WEIGHT:
+ bdfState->weightProp = prop;
+ return FALSE;
+ case BDF_QUAD_WIDTH:
+ bdfState->quadWidthProp = prop;
+ return FALSE;
+ case BDF_FONT:
+ bdfState->fontProp = prop;
+ return FALSE;
+ case BDF_RESOLUTION_X:
+ bdfState->resolutionXProp = prop;
+ return FALSE;
+ case BDF_RESOLUTION_Y:
+ bdfState->resolutionYProp = prop;
+ return FALSE;
+ default:
+ return FALSE;
+ }
+}
diff --git a/libXfont/src/bitmap/bitmap.c b/libXfont/src/bitmap/bitmap.c
new file mode 100644
index 000000000..d238f4d30
--- /dev/null
+++ b/libXfont/src/bitmap/bitmap.c
@@ -0,0 +1,160 @@
+/* $Xorg: bitmap.c,v 1.4 2001/02/09 02:04:02 xorgcvs Exp $ */
+
+/*
+
+Copyright 1991, 1998 The Open Group
+
+Permission to use, copy, modify, distribute, and sell this software and its
+documentation for any purpose is hereby granted without fee, provided that
+the above copyright notice appear in all copies and that both that
+copyright notice and this permission notice appear in supporting
+documentation.
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of The Open Group shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from The Open Group.
+
+*/
+/* $XFree86: xc/lib/font/bitmap/bitmap.c,v 1.6 2001/01/17 19:43:27 dawes Exp $ */
+
+/*
+ * Author: Keith Packard, MIT X Consortium
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <X11/fonts/fntfilst.h>
+#include <X11/fonts/bitmap.h>
+
+int
+bitmapGetGlyphs(FontPtr pFont, unsigned long count, unsigned char *chars,
+ FontEncoding charEncoding,
+ unsigned long *glyphCount, /* RETURN */
+ CharInfoPtr *glyphs) /* RETURN */
+{
+ BitmapFontPtr bitmapFont;
+ unsigned int firstCol;
+ register unsigned int numCols;
+ unsigned int firstRow;
+ unsigned int numRows;
+ CharInfoPtr *glyphsBase;
+ register unsigned int c;
+ register CharInfoPtr pci;
+ unsigned int r;
+ CharInfoPtr **encoding;
+ CharInfoPtr pDefault;
+
+ bitmapFont = (BitmapFontPtr) pFont->fontPrivate;
+ encoding = bitmapFont->encoding;
+ pDefault = bitmapFont->pDefault;
+ firstCol = pFont->info.firstCol;
+ numCols = pFont->info.lastCol - firstCol + 1;
+ glyphsBase = glyphs;
+ switch (charEncoding) {
+
+ case Linear8Bit:
+ case TwoD8Bit:
+ if (pFont->info.firstRow > 0)
+ break;
+ if (pFont->info.allExist && pDefault) {
+ while (count--) {
+ c = (*chars++) - firstCol;
+ if (c < numCols)
+ *glyphs++ = ACCESSENCODING(encoding,c);
+ else
+ *glyphs++ = pDefault;
+ }
+ } else {
+ while (count--) {
+ c = (*chars++) - firstCol;
+ if (c < numCols && (pci = ACCESSENCODING(encoding,c)))
+ *glyphs++ = pci;
+ else if (pDefault)
+ *glyphs++ = pDefault;
+ }
+ }
+ break;
+ case Linear16Bit:
+ if (pFont->info.allExist && pDefault) {
+ while (count--) {
+ c = *chars++ << 8;
+ c = (c | *chars++) - firstCol;
+ if (c < numCols)
+ *glyphs++ = ACCESSENCODING(encoding,c);
+ else
+ *glyphs++ = pDefault;
+ }
+ } else {
+ while (count--) {
+ c = *chars++ << 8;
+ c = (c | *chars++) - firstCol;
+ if (c < numCols && (pci = ACCESSENCODING(encoding,c)))
+ *glyphs++ = pci;
+ else if (pDefault)
+ *glyphs++ = pDefault;
+ }
+ }
+ break;
+
+ case TwoD16Bit:
+ firstRow = pFont->info.firstRow;
+ numRows = pFont->info.lastRow - firstRow + 1;
+ while (count--) {
+ r = (*chars++) - firstRow;
+ c = (*chars++) - firstCol;
+ if (r < numRows && c < numCols &&
+ (pci = ACCESSENCODING(encoding, r * numCols + c)))
+ *glyphs++ = pci;
+ else if (pDefault)
+ *glyphs++ = pDefault;
+ }
+ break;
+ }
+ *glyphCount = glyphs - glyphsBase;
+ return Successful;
+}
+
+static CharInfoRec nonExistantChar;
+
+int
+bitmapGetMetrics(FontPtr pFont, unsigned long count, unsigned char *chars,
+ FontEncoding charEncoding,
+ unsigned long *glyphCount, /* RETURN */
+ xCharInfo **glyphs) /* RETURN */
+{
+ int ret;
+ xCharInfo *ink_metrics;
+ CharInfoPtr metrics;
+ BitmapFontPtr bitmapFont;
+ CharInfoPtr oldDefault;
+ int i;
+
+ bitmapFont = (BitmapFontPtr) pFont->fontPrivate;
+ oldDefault = bitmapFont->pDefault;
+ bitmapFont->pDefault = &nonExistantChar;
+ ret = bitmapGetGlyphs(pFont, count, chars, charEncoding, glyphCount, (CharInfoPtr *) glyphs);
+ if (ret == Successful) {
+ if (bitmapFont->ink_metrics) {
+ metrics = bitmapFont->metrics;
+ ink_metrics = bitmapFont->ink_metrics;
+ for (i = 0; i < *glyphCount; i++) {
+ if (glyphs[i] != (xCharInfo *) & nonExistantChar)
+ glyphs[i] = ink_metrics + (((CharInfoPtr) glyphs[i]) - metrics);
+ }
+ }
+ }
+ bitmapFont->pDefault = oldDefault;
+ return ret;
+}
diff --git a/libXfont/src/bitmap/bitmapfunc.c b/libXfont/src/bitmap/bitmapfunc.c
new file mode 100644
index 000000000..e980dfbcc
--- /dev/null
+++ b/libXfont/src/bitmap/bitmapfunc.c
@@ -0,0 +1,265 @@
+/* $Xorg: bitmapfunc.c,v 1.5 2001/02/09 02:04:02 xorgcvs Exp $ */
+
+/*
+
+Copyright 1991, 1998 The Open Group
+
+Permission to use, copy, modify, distribute, and sell this software and its
+documentation for any purpose is hereby granted without fee, provided that
+the above copyright notice appear in all copies and that both that
+copyright notice and this permission notice appear in supporting
+documentation.
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of The Open Group shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from The Open Group.
+
+*/
+
+/* $XFree86: xc/lib/font/bitmap/bitmapfunc.c,v 3.17 2002/09/19 13:21:58 tsi Exp $ */
+
+/*
+ * Author: Keith Packard, MIT X Consortium
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+/*
+ * Translate monolithic #defines to modular definitions
+ */
+
+#ifdef PCFFORMAT
+#define XFONT_PCFFORMAT 1
+#endif
+
+#ifdef SNFFORMAT
+#define XFONT_SNFFORMAT 1
+#endif
+
+#ifdef BDFFORMAT
+#define XFONT_BDFFORMAT 1
+#endif
+
+#include <X11/fonts/fntfilst.h>
+#include <X11/fonts/bitmap.h>
+#include <X11/fonts/fontutil.h>
+#include <X11/fonts/bdfint.h>
+#include <X11/fonts/pcf.h>
+#include "snfstr.h"
+
+typedef struct _BitmapFileFunctions {
+ int (*ReadFont) (FontPtr /* pFont */, FontFilePtr /* file */,
+ int /* bit */, int /* byte */,
+ int /* glyph */, int /* scan */);
+ int (*ReadInfo) ( FontInfoPtr /* pFontInfo */,
+ FontFilePtr /* file */ );
+} BitmapFileFunctionsRec, *BitmapFileFunctionsPtr;
+
+
+/*
+ * the readers[] and renderers[] arrays must be in the same order,
+ * and also in the same order as scale[] and find_scale[] in bitscale.c
+ *
+ */
+static BitmapFileFunctionsRec readers[] = {
+#if XFONT_PCFFORMAT
+ { pcfReadFont, pcfReadFontInfo} ,
+ { pcfReadFont, pcfReadFontInfo} ,
+# ifdef X_GZIP_FONT_COMPRESSION
+ { pcfReadFont, pcfReadFontInfo} ,
+# endif
+# ifdef X_BZIP2_FONT_COMPRESSION
+ { pcfReadFont, pcfReadFontInfo} ,
+# endif
+#endif
+#if XFONT_SNFFORMAT
+ { snfReadFont, snfReadFontInfo},
+ { snfReadFont, snfReadFontInfo},
+# ifdef X_GZIP_FONT_COMPRESSION
+ { snfReadFont, snfReadFontInfo} ,
+# endif
+# ifdef X_BZIP2_FONT_COMPRESSION
+ { snfReadFont, snfReadFontInfo} ,
+# endif
+#endif
+#if XFONT_BDFFORMAT
+ { bdfReadFont, bdfReadFontInfo} ,
+ { bdfReadFont, bdfReadFontInfo} ,
+# ifdef X_GZIP_FONT_COMPRESSION
+ { bdfReadFont, bdfReadFontInfo} ,
+# endif
+# ifdef X_BZIP2_FONT_COMPRESSION
+ { bdfReadFont, bdfReadFontInfo} ,
+# endif
+#endif
+#if XFONT_PCFFORMAT
+ { pmfReadFont, pcfReadFontInfo} ,
+#endif
+};
+
+
+#define CAPABILITIES (CAP_MATRIX | CAP_CHARSUBSETTING)
+
+static int
+BitmapOpenBitmap (FontPathElementPtr fpe, FontPtr *ppFont, int flags,
+ FontEntryPtr entry, char *fileName,
+ fsBitmapFormat format, fsBitmapFormatMask fmask,
+ FontPtr non_cachable_font) /* We don't do licensing */
+{
+ FontFilePtr file;
+ FontPtr pFont;
+ int i;
+ int ret;
+ int bit,
+ byte,
+ glyph,
+ scan,
+ image;
+
+ i = BitmapGetRenderIndex(entry->u.bitmap.renderer);
+ file = FontFileOpen (fileName);
+ if (!file)
+ return BadFontName;
+ if (!(pFont = CreateFontRec())) {
+ fprintf(stderr, "Error: Couldn't allocate pFont (%ld)\n",
+ (unsigned long)sizeof(FontRec));
+ FontFileClose (file);
+ return AllocError;
+ }
+ /* set up default values */
+ FontDefaultFormat(&bit, &byte, &glyph, &scan);
+ /* get any changes made from above */
+ ret = CheckFSFormat(format, fmask, &bit, &byte, &scan, &glyph, &image);
+
+ /* Fill in font record. Data format filled in by reader. */
+ pFont->refcnt = 0;
+
+ ret = (*readers[i].ReadFont) (pFont, file, bit, byte, glyph, scan);
+
+ FontFileClose (file);
+ if (ret != Successful) {
+ xfree(pFont);
+ } else {
+ *ppFont = pFont;
+ }
+ return ret;
+}
+
+static int
+BitmapGetInfoBitmap (FontPathElementPtr fpe, FontInfoPtr pFontInfo,
+ FontEntryPtr entry, char *fileName)
+{
+ FontFilePtr file;
+ int i;
+ int ret;
+ FontRendererPtr renderer;
+
+ renderer = FontFileMatchRenderer (fileName);
+ if (!renderer)
+ return BadFontName;
+ i = BitmapGetRenderIndex(renderer);
+ file = FontFileOpen (fileName);
+ if (!file)
+ return BadFontName;
+ ret = (*readers[i].ReadInfo) (pFontInfo, file);
+ FontFileClose (file);
+ return ret;
+}
+
+static FontRendererRec renderers[] = {
+#if XFONT_PCFFORMAT
+ { ".pcf", 4, BitmapOpenBitmap, BitmapOpenScalable,
+ BitmapGetInfoBitmap, BitmapGetInfoScalable, 0,
+ CAPABILITIES },
+ { ".pcf.Z", 6, BitmapOpenBitmap, BitmapOpenScalable,
+ BitmapGetInfoBitmap, BitmapGetInfoScalable, 0,
+ CAPABILITIES },
+# ifdef X_GZIP_FONT_COMPRESSION
+ { ".pcf.gz", 7,
+ BitmapOpenBitmap, BitmapOpenScalable,
+ BitmapGetInfoBitmap, BitmapGetInfoScalable, 0,
+ CAPABILITIES },
+# endif
+# ifdef X_BZIP2_FONT_COMPRESSION
+ { ".pcf.bz2", 8,
+ BitmapOpenBitmap, BitmapOpenScalable,
+ BitmapGetInfoBitmap, BitmapGetInfoScalable, 0,
+ CAPABILITIES },
+# endif
+#endif
+#if XFONT_SNFFORMAT
+ { ".snf", 4, BitmapOpenBitmap, BitmapOpenScalable,
+ BitmapGetInfoBitmap, BitmapGetInfoScalable, 0,
+ CAPABILITIES },
+ { ".snf.Z", 6, BitmapOpenBitmap, BitmapOpenScalable,
+ BitmapGetInfoBitmap, BitmapGetInfoScalable, 0,
+ CAPABILITIES },
+# ifdef X_GZIP_FONT_COMPRESSION
+ { ".snf.gz", 7, BitmapOpenBitmap, BitmapOpenScalable,
+ BitmapGetInfoBitmap, BitmapGetInfoScalable, 0,
+ CAPABILITIES },
+# endif
+# ifdef X_BZIP2_FONT_COMPRESSION
+ { ".snf.bz2", 8, BitmapOpenBitmap, BitmapOpenScalable,
+ BitmapGetInfoBitmap, BitmapGetInfoScalable, 0,
+ CAPABILITIES },
+# endif
+#endif
+#if XFONT_BDFFORMAT
+ { ".bdf", 4, BitmapOpenBitmap, BitmapOpenScalable,
+ BitmapGetInfoBitmap, BitmapGetInfoScalable, 0,
+ CAPABILITIES },
+ { ".bdf.Z", 6, BitmapOpenBitmap, BitmapOpenScalable,
+ BitmapGetInfoBitmap, BitmapGetInfoScalable, 0,
+ CAPABILITIES },
+# ifdef X_GZIP_FONT_COMPRESSION
+ { ".bdf.gz", 7, BitmapOpenBitmap, BitmapOpenScalable,
+ BitmapGetInfoBitmap, BitmapGetInfoScalable, 0,
+ CAPABILITIES },
+# endif
+# ifdef X_BZIP2_FONT_COMPRESSION
+ { ".bdf.bz2", 8, BitmapOpenBitmap, BitmapOpenScalable,
+ BitmapGetInfoBitmap, BitmapGetInfoScalable, 0,
+ CAPABILITIES },
+# endif
+#endif
+#if XFONT_PCFFORMAT
+ { ".pmf", 4, BitmapOpenBitmap, BitmapOpenScalable,
+ BitmapGetInfoBitmap, BitmapGetInfoScalable, 0,
+ CAPABILITIES }
+#endif
+};
+
+#define numRenderers (sizeof renderers / sizeof renderers[0])
+
+void
+BitmapRegisterFontFileFunctions (void)
+{
+ int i;
+
+ for (i = 0; i < numRenderers; i++)
+ FontFileRegisterRenderer (&renderers[i]);
+}
+
+/*
+ * compute offset into renderers array - used to find the font reader,
+ * the font info reader, and the bitmap scaling routine. All users
+ * of this routine must be kept in step with the renderer array.
+ */
+int
+BitmapGetRenderIndex(FontRendererPtr renderer)
+{
+ return renderer - renderers;
+}
diff --git a/libXfont/src/bitmap/bitmaputil.c b/libXfont/src/bitmap/bitmaputil.c
new file mode 100644
index 000000000..3487f7f92
--- /dev/null
+++ b/libXfont/src/bitmap/bitmaputil.c
@@ -0,0 +1,232 @@
+/* $Xorg: bitmaputil.c,v 1.5 2001/02/09 02:04:02 xorgcvs Exp $ */
+
+/*
+
+Copyright 1990, 1994, 1998 The Open Group
+
+Permission to use, copy, modify, distribute, and sell this software and its
+documentation for any purpose is hereby granted without fee, provided that
+the above copyright notice appear in all copies and that both that
+copyright notice and this permission notice appear in supporting
+documentation.
+
+The above copyright notice and this permission notice shall be included
+in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+IN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR
+OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of The Open Group shall
+not be used in advertising or otherwise to promote the sale, use or
+other dealings in this Software without prior written authorization
+from The Open Group.
+
+*/
+/* $XFree86: xc/lib/font/bitmap/bitmaputil.c,v 1.10 2002/09/24 20:52:48 tsi Exp $ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <X11/fonts/fntfilst.h>
+#include <X11/fonts/bitmap.h>
+#include <X11/fonts/bdfint.h>
+
+#ifndef MAXSHORT
+#define MAXSHORT 32767
+#endif
+
+#ifndef MINSHORT
+#define MINSHORT -32768
+#endif
+
+static xCharInfo initMinMetrics = {
+MAXSHORT, MAXSHORT, MAXSHORT, MAXSHORT, MAXSHORT, 0xFFFF};
+static xCharInfo initMaxMetrics = {
+MINSHORT, MINSHORT, MINSHORT, MINSHORT, MINSHORT, 0x0000};
+
+#define MINMAX(field,ci) \
+ if (minbounds->field > (ci)->field) \
+ minbounds->field = (ci)->field; \
+ if (maxbounds->field < (ci)->field) \
+ maxbounds->field = (ci)->field;
+
+#define COMPUTE_MINMAX(ci) \
+ if ((ci)->ascent || (ci)->descent || \
+ (ci)->leftSideBearing || (ci)->rightSideBearing || \
+ (ci)->characterWidth) \
+ { \
+ MINMAX(ascent, (ci)); \
+ MINMAX(descent, (ci)); \
+ MINMAX(leftSideBearing, (ci)); \
+ MINMAX(rightSideBearing, (ci)); \
+ MINMAX(characterWidth, (ci)); \
+ }
+
+void
+bitmapComputeFontBounds(FontPtr pFont)
+{
+ BitmapFontPtr bitmapFont = (BitmapFontPtr) pFont->fontPrivate;
+ int nchars;
+ int r,
+ c;
+ CharInfoPtr ci;
+ int maxOverlap;
+ int overlap;
+ xCharInfo *minbounds,
+ *maxbounds;
+ int i;
+ int numneg = 0, numpos = 0;
+
+ if (bitmapFont->bitmapExtra) {
+ minbounds = &bitmapFont->bitmapExtra->info.minbounds;
+ maxbounds = &bitmapFont->bitmapExtra->info.maxbounds;
+ } else {
+ minbounds = &pFont->info.minbounds;
+ maxbounds = &pFont->info.maxbounds;
+ }
+ *minbounds = initMinMetrics;
+ *maxbounds = initMaxMetrics;
+ maxOverlap = MINSHORT;
+ nchars = bitmapFont->num_chars;
+ for (i = 0, ci = bitmapFont->metrics; i < nchars; i++, ci++) {
+ COMPUTE_MINMAX(&ci->metrics);
+ if (ci->metrics.characterWidth < 0)
+ numneg++;
+ else
+ numpos++;
+ minbounds->attributes &= ci->metrics.attributes;
+ maxbounds->attributes |= ci->metrics.attributes;
+ overlap = ci->metrics.rightSideBearing - ci->metrics.characterWidth;
+ if (maxOverlap < overlap)
+ maxOverlap = overlap;
+ }
+ if (bitmapFont->bitmapExtra) {
+ if (numneg > numpos)
+ bitmapFont->bitmapExtra->info.drawDirection = RightToLeft;
+ else
+ bitmapFont->bitmapExtra->info.drawDirection = LeftToRight;
+ bitmapFont->bitmapExtra->info.maxOverlap = maxOverlap;
+ minbounds = &pFont->info.minbounds;
+ maxbounds = &pFont->info.maxbounds;
+ *minbounds = initMinMetrics;
+ *maxbounds = initMaxMetrics;
+ i = 0;
+ maxOverlap = MINSHORT;
+ for (r = pFont->info.firstRow; r <= pFont->info.lastRow; r++) {
+ for (c = pFont->info.firstCol; c <= pFont->info.lastCol; c++) {
+ ci = ACCESSENCODING(bitmapFont->encoding, i);
+ if (ci) {
+ COMPUTE_MINMAX(&ci->metrics);
+ if (ci->metrics.characterWidth < 0)
+ numneg++;
+ else
+ numpos++;
+ minbounds->attributes &= ci->metrics.attributes;
+ maxbounds->attributes |= ci->metrics.attributes;
+ overlap = ci->metrics.rightSideBearing -
+ ci->metrics.characterWidth;
+ if (maxOverlap < overlap)
+ maxOverlap = overlap;
+ }
+ i++;
+ }
+ }
+ }
+ if (numneg > numpos)
+ pFont->info.drawDirection = RightToLeft;
+ else
+ pFont->info.drawDirection = LeftToRight;
+ pFont->info.maxOverlap = maxOverlap;
+}
+
+void
+bitmapComputeFontInkBounds(FontPtr pFont)
+{
+ BitmapFontPtr bitmapFont = (BitmapFontPtr) pFont->fontPrivate;
+ int nchars;
+ int r,
+ c;
+ CharInfoPtr cit;
+ xCharInfo *ci;
+ int offset;
+ xCharInfo *minbounds,
+ *maxbounds;
+ int i;
+
+ if (!bitmapFont->ink_metrics) {
+ if (bitmapFont->bitmapExtra) {
+ bitmapFont->bitmapExtra->info.ink_minbounds = bitmapFont->bitmapExtra->info.minbounds;
+ bitmapFont->bitmapExtra->info.ink_maxbounds = bitmapFont->bitmapExtra->info.maxbounds;
+ }
+ pFont->info.ink_minbounds = pFont->info.minbounds;
+ pFont->info.ink_maxbounds = pFont->info.maxbounds;
+ } else {
+ if (bitmapFont->bitmapExtra) {
+ minbounds = &bitmapFont->bitmapExtra->info.ink_minbounds;
+ maxbounds = &bitmapFont->bitmapExtra->info.ink_maxbounds;
+ } else {
+ minbounds = &pFont->info.ink_minbounds;
+ maxbounds = &pFont->info.ink_maxbounds;
+ }
+ *minbounds = initMinMetrics;
+ *maxbounds = initMaxMetrics;
+ nchars = bitmapFont->num_chars;
+ for (i = 0, ci = bitmapFont->ink_metrics; i < nchars; i++, ci++) {
+ COMPUTE_MINMAX(ci);
+ minbounds->attributes &= ci->attributes;
+ maxbounds->attributes |= ci->attributes;
+ }
+ if (bitmapFont->bitmapExtra) {
+ minbounds = &pFont->info.ink_minbounds;
+ maxbounds = &pFont->info.ink_maxbounds;
+ *minbounds = initMinMetrics;
+ *maxbounds = initMaxMetrics;
+ i=0;
+ for (r = pFont->info.firstRow; r <= pFont->info.lastRow; r++) {
+ for (c = pFont->info.firstCol; c <= pFont->info.lastCol; c++) {
+ cit = ACCESSENCODING(bitmapFont->encoding, i);
+ if (cit) {
+ offset = cit - bitmapFont->metrics;
+ ci = &bitmapFont->ink_metrics[offset];
+ COMPUTE_MINMAX(ci);
+ minbounds->attributes &= ci->attributes;
+ maxbounds->attributes |= ci->attributes;
+ }
+ i++;
+ }
+ }
+ }
+ }
+}
+
+Bool
+bitmapAddInkMetrics(FontPtr pFont)
+{
+ BitmapFontPtr bitmapFont;
+ int i;
+
+ bitmapFont = (BitmapFontPtr) pFont->fontPrivate;
+ bitmapFont->ink_metrics = (xCharInfo *) xalloc(bitmapFont->num_chars * sizeof(xCharInfo));
+ if (!bitmapFont->ink_metrics) {
+ fprintf(stderr, "Error: Couldn't allocate ink_metrics (%d*%ld)\n",
+ bitmapFont->num_chars, (unsigned long)sizeof(xCharInfo));
+ return FALSE;
+ }
+ for (i = 0; i < bitmapFont->num_chars; i++)
+ FontCharInkMetrics(pFont, &bitmapFont->metrics[i], &bitmapFont->ink_metrics[i]);
+ pFont->info.inkMetrics = TRUE;
+ return TRUE;
+}
+
+/* ARGSUSED */
+int
+bitmapComputeWeight(FontPtr pFont)
+{
+ return 10;
+}
diff --git a/libXfont/src/bitmap/bitscale.c b/libXfont/src/bitmap/bitscale.c
new file mode 100644
index 000000000..ffdbe1d3c
--- /dev/null
+++ b/libXfont/src/bitmap/bitscale.c
@@ -0,0 +1,1987 @@
+/* $Xorg: bitscale.c,v 1.5 2001/02/09 02:04:02 xorgcvs Exp $ */
+/*
+
+Copyright 1991, 1994, 1998 The Open Group
+
+Permission to use, copy, modify, distribute, and sell this software and its
+documentation for any purpose is hereby granted without fee, provided that
+the above copyright notice appear in all copies and that both that
+copyright notice and this permission notice appear in supporting
+documentation.
+
+The above copyright notice and this permission notice shall be included
+in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+IN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR
+OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of The Open Group shall
+not be used in advertising or otherwise to promote the sale, use or
+other dealings in this Software without prior written authorization
+from The Open Group.
+
+*/
+/* $XFree86: xc/lib/font/bitmap/bitscale.c,v 3.29tsi Exp $ */
+
+/*
+ * Author: Keith Packard, MIT X Consortium
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+/*
+ * Translate monolithic #defines to modular definitions
+ */
+
+#ifdef PCFFORMAT
+#define XFONT_PCFFORMAT 1
+#endif
+
+#ifdef SNFFORMAT
+#define XFONT_SNFFORMAT 1
+#endif
+
+#ifdef BDFFORMAT
+#define XFONT_BDFFORMAT 1
+#endif
+
+#include <X11/fonts/fntfilst.h>
+#include <X11/fonts/bitmap.h>
+#include <X11/fonts/fontutil.h>
+#ifndef FONTMODULE
+#ifdef _XOPEN_SOURCE
+#include <math.h>
+#else
+#define _XOPEN_SOURCE /* to get prototype for hypot on some systems */
+#include <math.h>
+#undef _XOPEN_SOURCE
+#endif
+#endif
+
+#ifndef MAX
+#define MAX(a,b) (((a)>(b)) ? a : b)
+#endif
+
+/* Should get this from elsewhere */
+extern unsigned long serverGeneration;
+
+static void bitmapUnloadScalable (FontPtr pFont);
+static void ScaleBitmap ( FontPtr pFont, CharInfoPtr opci,
+ CharInfoPtr pci, double *inv_xform,
+ double widthMult, double heightMult );
+static FontPtr BitmapScaleBitmaps(FontPtr pf, FontPtr opf,
+ double widthMult, double heightMult,
+ FontScalablePtr vals);
+static FontPtr PrinterScaleBitmaps(FontPtr pf, FontPtr opf,
+ double widthMult, double heightMult,
+ FontScalablePtr vals);
+
+enum scaleType {
+ atom, truncate_atom, pixel_size, point_size, resolution_x,
+ resolution_y, average_width, scaledX, scaledY, unscaled, fontname,
+ raw_ascent, raw_descent, raw_pixelsize, raw_pointsize,
+ raw_average_width, uncomputed
+};
+
+typedef struct _fontProp {
+ char *name;
+ Atom atom;
+ enum scaleType type;
+} fontProp;
+
+typedef FontPtr (*ScaleFunc) ( FontPtr /* pf */,
+ FontPtr /* opf */,
+ double /* widthMult */,
+ double /* heightMult */,
+ FontScalablePtr /* vals */);
+
+/* These next two arrays must be kept in step with the renderer array */
+static const ScaleFunc scale[] =
+{
+#if XFONT_PCFFORMAT
+ BitmapScaleBitmaps,
+ BitmapScaleBitmaps,
+# ifdef X_GZIP_FONT_COMPRESSION
+ BitmapScaleBitmaps,
+# endif
+# ifdef X_BZIP2_FONT_COMPRESSION
+ BitmapScaleBitmaps,
+# endif
+#endif
+#if XFONT_SNFFORMAT
+ BitmapScaleBitmaps,
+ BitmapScaleBitmaps,
+# ifdef X_GZIP_FONT_COMPRESSION
+ BitmapScaleBitmaps,
+# endif
+# ifdef X_BZIP2_FONT_COMPRESSION
+ BitmapScaleBitmaps,
+# endif
+#endif
+#if XFONT_BDFFORMAT
+ BitmapScaleBitmaps,
+ BitmapScaleBitmaps,
+# ifdef X_GZIP_FONT_COMPRESSION
+ BitmapScaleBitmaps,
+# endif
+# ifdef X_BZIP2_FONT_COMPRESSION
+ BitmapScaleBitmaps,
+# endif
+#endif
+#if XFONT_PCFFORMAT
+ PrinterScaleBitmaps,
+#endif
+};
+
+static FontEntryPtr FindBestToScale ( FontPathElementPtr fpe,
+ FontEntryPtr entry,
+ FontScalablePtr vals,
+ FontScalablePtr best,
+ double *dxp, double *dyp,
+ double *sdxp, double *sdyp,
+ FontPathElementPtr *fpep );
+static FontEntryPtr FindPmfToScale ( FontPathElementPtr fpe,
+ FontEntryPtr entry,
+ FontScalablePtr vals,
+ FontScalablePtr best,
+ double *dxp, double *dyp,
+ double *sdxp, double *sdyp,
+ FontPathElementPtr *fpep );
+
+typedef FontEntryPtr (*FindToScale) (FontPathElementPtr fpe,
+ FontEntryPtr entry,
+ FontScalablePtr vals,
+ FontScalablePtr best,
+ double *dxp, double *dyp,
+ double *sdxp, double *sdyp,
+ FontPathElementPtr *fpep);
+static const FindToScale find_scale[] =
+{
+#if XFONT_PCFFORMAT
+ FindBestToScale,
+ FindBestToScale,
+#ifdef X_GZIP_FONT_COMPRESSION
+ FindBestToScale,
+#endif
+#endif
+#if XFONT_SNFFORMAT
+ FindBestToScale,
+ FindBestToScale,
+#ifdef X_GZIP_FONT_COMPRESSION
+ FindBestToScale,
+#endif
+#endif
+#if XFONT_BDFFORMAT
+ FindBestToScale,
+ FindBestToScale,
+#ifdef X_GZIP_FONT_COMPRESSION
+ FindBestToScale,
+#endif
+#endif
+#if XFONT_PCFFORMAT
+ FindPmfToScale,
+#endif
+};
+
+static unsigned long bitscaleGeneration = 0; /* initialization flag */
+
+static fontProp fontNamePropTable[] = {
+ { "FOUNDRY", 0, atom },
+ { "FAMILY_NAME", 0, atom },
+ { "WEIGHT_NAME", 0, atom },
+ { "SLANT", 0, atom },
+ { "SETWIDTH_NAME", 0, atom },
+ { "ADD_STYLE_NAME", 0, atom },
+ { "PIXEL_SIZE", 0, pixel_size },
+ { "POINT_SIZE", 0, point_size },
+ { "RESOLUTION_X", 0, resolution_x },
+ { "RESOLUTION_Y", 0, resolution_y },
+ { "SPACING", 0, atom },
+ { "AVERAGE_WIDTH", 0, average_width },
+ { "CHARSET_REGISTRY", 0, atom },
+ { "CHARSET_ENCODING", 0, truncate_atom },
+ { "FONT", 0, fontname },
+ { "RAW_ASCENT", 0, raw_ascent },
+ { "RAW_DESCENT", 0, raw_descent },
+ { "RAW_PIXEL_SIZE", 0, raw_pixelsize },
+ { "RAW_POINT_SIZE", 0, raw_pointsize },
+ { "RAW_AVERAGE_WIDTH", 0, raw_average_width }
+};
+
+#define TRANSFORM_POINT(matrix, x, y, dest) \
+ ((dest)[0] = (matrix)[0] * (x) + (matrix)[2] * (y), \
+ (dest)[1] = (matrix)[1] * (x) + (matrix)[3] * (y))
+
+#define CHECK_EXTENT(lsb, rsb, desc, asc, data) \
+ ((lsb) > (data)[0] ? (lsb) = (data)[0] : 0 , \
+ (rsb) < (data)[0] ? (rsb) = (data)[0] : 0, \
+ (-desc) > (data)[1] ? (desc) = -(data)[1] : 0 , \
+ (asc) < (data)[1] ? (asc) = (data)[1] : 0)
+
+#define NPROPS (sizeof(fontNamePropTable) / sizeof(fontProp))
+
+/* Warning: order of the next two tables is critically interdependent.
+ Location of "unscaled" properties at the end of fontPropTable[]
+ is important. */
+
+static fontProp fontPropTable[] = {
+ { "MIN_SPACE", 0, scaledX },
+ { "NORM_SPACE", 0, scaledX },
+ { "MAX_SPACE", 0, scaledX },
+ { "END_SPACE", 0, scaledX },
+ { "AVG_CAPITAL_WIDTH", 0, scaledX },
+ { "AVG_LOWERCASE_WIDTH", 0, scaledX },
+ { "QUAD_WIDTH", 0, scaledX },
+ { "FIGURE_WIDTH", 0, scaledX },
+ { "SUPERSCRIPT_X", 0, scaledX },
+ { "SUPERSCRIPT_Y", 0, scaledY },
+ { "SUBSCRIPT_X", 0, scaledX },
+ { "SUBSCRIPT_Y", 0, scaledY },
+ { "SUPERSCRIPT_SIZE", 0, scaledY },
+ { "SUBSCRIPT_SIZE", 0, scaledY },
+ { "SMALL_CAP_SIZE", 0, scaledY },
+ { "UNDERLINE_POSITION", 0, scaledY },
+ { "UNDERLINE_THICKNESS", 0, scaledY },
+ { "STRIKEOUT_ASCENT", 0, scaledY },
+ { "STRIKEOUT_DESCENT", 0, scaledY },
+ { "CAP_HEIGHT", 0, scaledY },
+ { "X_HEIGHT", 0, scaledY },
+ { "ITALIC_ANGLE", 0, unscaled },
+ { "RELATIVE_SETWIDTH", 0, unscaled },
+ { "RELATIVE_WEIGHT", 0, unscaled },
+ { "WEIGHT", 0, unscaled },
+ { "DESTINATION", 0, unscaled },
+ { "PCL_FONT_NAME", 0, unscaled },
+ { "_ADOBE_POSTSCRIPT_FONTNAME", 0, unscaled }
+};
+
+/* sleazy way to shut up the compiler */
+#define zerohack (enum scaleType)0
+
+static fontProp rawFontPropTable[] = {
+ { "RAW_MIN_SPACE", 0, },
+ { "RAW_NORM_SPACE", 0, },
+ { "RAW_MAX_SPACE", 0, },
+ { "RAW_END_SPACE", 0, },
+ { "RAW_AVG_CAPITAL_WIDTH", 0, },
+ { "RAW_AVG_LOWERCASE_WIDTH", 0, },
+ { "RAW_QUAD_WIDTH", 0, },
+ { "RAW_FIGURE_WIDTH", 0, },
+ { "RAW_SUPERSCRIPT_X", 0, },
+ { "RAW_SUPERSCRIPT_Y", 0, },
+ { "RAW_SUBSCRIPT_X", 0, },
+ { "RAW_SUBSCRIPT_Y", 0, },
+ { "RAW_SUPERSCRIPT_SIZE", 0, },
+ { "RAW_SUBSCRIPT_SIZE", 0, },
+ { "RAW_SMALL_CAP_SIZE", 0, },
+ { "RAW_UNDERLINE_POSITION", 0, },
+ { "RAW_UNDERLINE_THICKNESS", 0, },
+ { "RAW_STRIKEOUT_ASCENT", 0, },
+ { "RAW_STRIKEOUT_DESCENT", 0, },
+ { "RAW_CAP_HEIGHT", 0, },
+ { "RAW_X_HEIGHT", 0, }
+};
+
+static void
+initFontPropTable(void)
+{
+ int i;
+ fontProp *t;
+
+ i = sizeof(fontNamePropTable) / sizeof(fontProp);
+ for (t = fontNamePropTable; i; i--, t++)
+ t->atom = MakeAtom(t->name, (unsigned) strlen(t->name), TRUE);
+
+ i = sizeof(fontPropTable) / sizeof(fontProp);
+ for (t = fontPropTable; i; i--, t++)
+ t->atom = MakeAtom(t->name, (unsigned) strlen(t->name), TRUE);
+
+ i = sizeof(rawFontPropTable) / sizeof(fontProp);
+ for (t = rawFontPropTable; i; i--, t++)
+ t->atom = MakeAtom(t->name, (unsigned) strlen(t->name), TRUE);
+}
+
+#if 0
+static FontEntryPtr
+GetScalableEntry (FontPathElementPtr fpe, FontNamePtr name)
+{
+ FontDirectoryPtr dir;
+
+ dir = (FontDirectoryPtr) fpe->private;
+ return FontFileFindNameInDir (&dir->scalable, name);
+}
+#endif
+
+static double
+get_matrix_horizontal_component(double *matrix)
+{
+ return hypot(matrix[0], matrix[1]);
+}
+
+static double
+get_matrix_vertical_component(double *matrix)
+{
+ return hypot(matrix[2], matrix[3]);
+}
+
+
+static Bool
+ComputeScaleFactors(FontScalablePtr from, FontScalablePtr to,
+ double *dx, double *dy, double *sdx, double *sdy,
+ double *rescale_x)
+{
+ double srcpixelset, destpixelset, srcpixel, destpixel;
+
+ srcpixelset = get_matrix_horizontal_component(from->pixel_matrix);
+ destpixelset = get_matrix_horizontal_component(to->pixel_matrix);
+ srcpixel = get_matrix_vertical_component(from->pixel_matrix);
+ destpixel = get_matrix_vertical_component(to->pixel_matrix);
+
+ if (srcpixelset >= EPS)
+ {
+ *dx = destpixelset / srcpixelset;
+ *sdx = 1000.0 / srcpixelset;
+ }
+ else
+ *sdx = *dx = 0;
+
+ *rescale_x = 1.0;
+
+ /* If client specified a width, it overrides setsize; in this
+ context, we interpret width as applying to the font before any
+ rotation, even though that's not what is ultimately returned in
+ the width field. */
+ if (from->width > 0 && to->width > 0 && fabs(*dx) > EPS)
+ {
+ double rescale = (double)to->width / (double)from->width;
+
+ /* If the client specified a transformation matrix, the rescaling
+ for width does *not* override the setsize. Instead, just check
+ for consistency between the setsize from the matrix and the
+ setsize that would result from rescaling according to the width.
+ This assumes (perhaps naively) that the width is correctly
+ reported in the name. As an interesting side effect, this test
+ may result in choosing a different source bitmap (one that
+ scales consistently between the setsize *and* the width) than it
+ would choose if a width were not specified. Sort of a hidden
+ multiple-master functionality. */
+ if ((to->values_supplied & PIXELSIZE_MASK) == PIXELSIZE_ARRAY ||
+ (to->values_supplied & POINTSIZE_MASK) == POINTSIZE_ARRAY)
+ {
+ /* Reject if resulting width difference is >= 1 pixel */
+ if (fabs(rescale * from->width - *dx * from->width) >= 10)
+ return FALSE;
+ }
+ else
+ {
+ *rescale_x = rescale/(*dx);
+ *dx = rescale;
+ }
+ }
+
+ if (srcpixel >= EPS)
+ {
+ *dy = destpixel / srcpixel;
+ *sdy = 1000.0 / srcpixel;
+ }
+ else
+ *sdy = *dy = 0;
+
+ return TRUE;
+}
+
+/* favor enlargement over reduction because of aliasing resulting
+ from reduction */
+#define SCORE(m,s) \
+if (m >= 1.0) { \
+ if (m == 1.0) \
+ score += (16 * s); \
+ else if (m == 2.0) \
+ score += (4 * s); \
+ else \
+ score += (int)(((double)(3 * s)) / m); \
+} else { \
+ score += (int)(((double)(2 * s)) * m); \
+}
+
+/* don't need to favor enlargement when looking for bitmap that can
+ be used unscalable */
+#define SCORE2(m,s) \
+if (m >= 1.0) \
+ score += (int)(((double)(8 * s)) / m); \
+else \
+ score += (int)(((double)(8 * s)) * m);
+
+static FontEntryPtr
+FindBestToScale(FontPathElementPtr fpe, FontEntryPtr entry,
+ FontScalablePtr vals, FontScalablePtr best,
+ double *dxp, double *dyp,
+ double *sdxp, double *sdyp,
+ FontPathElementPtr *fpep)
+{
+ FontScalableRec temp;
+ int source, i;
+ int best_score, best_unscaled_score,
+ score;
+ double dx = 0.0, sdx = 0.0, dx_amount = 0.0,
+ dy = 0.0, sdy = 0.0, dy_amount = 0.0,
+ best_dx = 0.0, best_sdx = 0.0, best_dx_amount = 0.0,
+ best_dy = 0.0, best_sdy = 0.0, best_dy_amount = 0.0,
+ best_unscaled_sdx = 0.0, best_unscaled_sdy = 0.0,
+ rescale_x = 0.0, best_rescale_x = 0.0,
+ best_unscaled_rescale_x = 0.0;
+ FontEntryPtr zero;
+ FontNameRec zeroName;
+ char zeroChars[MAXFONTNAMELEN];
+ FontDirectoryPtr dir;
+ FontScaledPtr scaled;
+ FontScalableExtraPtr extra;
+ FontScaledPtr best_scaled, best_unscaled;
+ FontPathElementPtr best_fpe = NULL, best_unscaled_fpe = NULL;
+ FontEntryPtr bitmap = NULL;
+ FontEntryPtr result;
+ int aliascount = 20;
+ FontPathElementPtr bitmap_fpe = NULL;
+ FontNameRec xlfdName;
+
+ /* find the best match */
+ rescale_x = 1.0;
+ best_scaled = 0;
+ best_score = 0;
+ best_unscaled = 0;
+ best_unscaled_score = -1;
+ best_dx_amount = best_dy_amount = HUGE_VAL;
+ memcpy (zeroChars, entry->name.name, entry->name.length);
+ zeroChars[entry->name.length] = '\0';
+ zeroName.name = zeroChars;
+ FontParseXLFDName (zeroChars, &temp, FONT_XLFD_REPLACE_ZERO);
+ zeroName.length = strlen (zeroChars);
+ zeroName.ndashes = entry->name.ndashes;
+ xlfdName.name = vals->xlfdName;
+ xlfdName.length = strlen(xlfdName.name);
+ xlfdName.ndashes = FontFileCountDashes(xlfdName.name, xlfdName.length);
+ restart_bestscale_loop: ;
+ /*
+ * Look through all the registered bitmap sources for
+ * the same zero name as ours; entries along that one
+ * can be scaled as desired.
+ */
+ for (source = 0; source < FontFileBitmapSources.count; source++)
+ {
+ /* There might already be a bitmap that satisfies the request
+ but didn't have a zero name that was found by the scalable
+ font matching logic. Keep track if there is. */
+ if (bitmap == NULL && vals->xlfdName != NULL)
+ {
+ bitmap_fpe = FontFileBitmapSources.fpe[source];
+ dir = (FontDirectoryPtr) bitmap_fpe->private;
+ bitmap = FontFileFindNameInDir (&dir->nonScalable, &xlfdName);
+ if (bitmap && bitmap->type != FONT_ENTRY_BITMAP)
+ {
+ if (bitmap->type == FONT_ENTRY_ALIAS && aliascount > 0)
+ {
+ aliascount--;
+ xlfdName.name = bitmap->u.alias.resolved;
+ xlfdName.length = strlen(xlfdName.name);
+ xlfdName.ndashes = FontFileCountDashes(xlfdName.name,
+ xlfdName.length);
+ bitmap = NULL;
+ goto restart_bestscale_loop;
+ }
+ else
+ bitmap = NULL;
+ }
+ }
+
+ if (FontFileBitmapSources.fpe[source] == fpe)
+ zero = entry;
+ else
+ {
+ dir = (FontDirectoryPtr) FontFileBitmapSources.fpe[source]->private;
+ zero = FontFileFindNameInDir (&dir->scalable, &zeroName);
+ if (!zero)
+ continue;
+ }
+ extra = zero->u.scalable.extra;
+ for (i = 0; i < extra->numScaled; i++)
+ {
+ scaled = &extra->scaled[i];
+ if (!scaled->bitmap)
+ continue;
+ if (!ComputeScaleFactors(&scaled->vals, vals, &dx, &dy, &sdx, &sdy,
+ &rescale_x))
+ continue;
+ score = 0;
+ dx_amount = dx;
+ dy_amount = dy;
+ SCORE(dy_amount, 10);
+ SCORE(dx_amount, 1);
+ if ((score > best_score) ||
+ ((score == best_score) &&
+ ((dy_amount < best_dy_amount) ||
+ ((dy_amount == best_dy_amount) &&
+ (dx_amount < best_dx_amount)))))
+ {
+ best_fpe = FontFileBitmapSources.fpe[source];
+ best_scaled = scaled;
+ best_score = score;
+ best_dx = dx;
+ best_dy = dy;
+ best_sdx = sdx;
+ best_sdy = sdy;
+ best_dx_amount = dx_amount;
+ best_dy_amount = dy_amount;
+ best_rescale_x = rescale_x;
+ }
+ /* Is this font a candidate for use without ugly rescaling? */
+ if (fabs(dx) > EPS && fabs(dy) > EPS &&
+ fabs(vals->pixel_matrix[0] * rescale_x -
+ scaled->vals.pixel_matrix[0]) < 1 &&
+ fabs(vals->pixel_matrix[1] * rescale_x -
+ scaled->vals.pixel_matrix[1]) < EPS &&
+ fabs(vals->pixel_matrix[2] -
+ scaled->vals.pixel_matrix[2]) < EPS &&
+ fabs(vals->pixel_matrix[3] -
+ scaled->vals.pixel_matrix[3]) < 1)
+ {
+ /* Yes. The pixel sizes are close on the diagonal and
+ extremely close off the diagonal. */
+ score = 0;
+ SCORE2(vals->pixel_matrix[3] /
+ scaled->vals.pixel_matrix[3], 10);
+ SCORE2(vals->pixel_matrix[0] * rescale_x /
+ scaled->vals.pixel_matrix[0], 1);
+ if (score > best_unscaled_score)
+ {
+ best_unscaled_fpe = FontFileBitmapSources.fpe[source];
+ best_unscaled = scaled;
+ best_unscaled_sdx = sdx / dx;
+ best_unscaled_sdy = sdy / dy;
+ best_unscaled_score = score;
+ best_unscaled_rescale_x = rescale_x;
+ }
+ }
+ }
+ }
+ if (best_unscaled)
+ {
+ *best = best_unscaled->vals;
+ *fpep = best_unscaled_fpe;
+ *dxp = 1.0;
+ *dyp = 1.0;
+ *sdxp = best_unscaled_sdx;
+ *sdyp = best_unscaled_sdy;
+ rescale_x = best_unscaled_rescale_x;
+ result = best_unscaled->bitmap;
+ }
+ else if (best_scaled)
+ {
+ *best = best_scaled->vals;
+ *fpep = best_fpe;
+ *dxp = best_dx;
+ *dyp = best_dy;
+ *sdxp = best_sdx;
+ *sdyp = best_sdy;
+ rescale_x = best_rescale_x;
+ result = best_scaled->bitmap;
+ }
+ else
+ result = NULL;
+
+ if (bitmap != NULL && (result == NULL || *dxp != 1.0 || *dyp != 1.0))
+ {
+ *fpep = bitmap_fpe;
+ FontParseXLFDName (bitmap->name.name, best, FONT_XLFD_REPLACE_NONE);
+ if (ComputeScaleFactors(best, best, dxp, dyp, sdxp, sdyp, &rescale_x))
+ result = bitmap;
+ else
+ result = NULL;
+ }
+
+ if (result && rescale_x != 1.0)
+ {
+ /* We have rescaled horizontally due to an XLFD width field. Change
+ the matrix appropriately */
+ vals->pixel_matrix[0] *= rescale_x;
+ vals->pixel_matrix[1] *= rescale_x;
+#ifdef NOTDEF
+ /* This would force the pointsize and pixelsize fields in the
+ FONT property to display as matrices to more accurately
+ report the font being supplied. It might also break existing
+ applications that expect a single number in that field. */
+ vals->values_supplied =
+ vals->values_supplied & ~(PIXELSIZE_MASK | POINTSIZE_MASK) |
+ PIXELSIZE_ARRAY;
+#else /* NOTDEF */
+ vals->values_supplied = vals->values_supplied & ~POINTSIZE_MASK;
+#endif /* NOTDEF */
+ /* Recompute and reround the FontScalablePtr values after
+ rescaling for the new width. */
+ FontFileCompleteXLFD(vals, vals);
+ }
+
+ return result;
+}
+
+static FontEntryPtr
+FindPmfToScale(FontPathElementPtr fpe, FontEntryPtr entry,
+ FontScalablePtr vals, FontScalablePtr best,
+ double *dxp, double *dyp,
+ double *sdxp, double *sdyp,
+ FontPathElementPtr *fpep)
+{
+ FontEntryPtr result = NULL;
+ FontScaledPtr scaled;
+ FontScalableExtraPtr extra;
+ int i;
+
+ extra = entry->u.scalable.extra;
+ for (i = 0; i < extra->numScaled; i++)
+ {
+ double rescale_x;
+
+ scaled = &extra->scaled[i];
+ if (!scaled->bitmap)
+ continue;
+ if (!ComputeScaleFactors(&scaled->vals, vals, dxp, dyp, sdxp, sdyp,
+ &rescale_x))
+ continue;
+ *best = scaled->vals;
+ *fpep = fpe;
+ result = scaled->bitmap;
+ if (rescale_x != 1.0)
+ {
+ /* We have rescaled horizontally due to an XLFD width field. Change
+ the matrix appropriately */
+ vals->pixel_matrix[0] *= rescale_x;
+ vals->pixel_matrix[1] *= rescale_x;
+#ifdef NOTDEF
+ /* This would force the pointsize and pixelsize fields in the
+ FONT property to display as matrices to more accurately
+ report the font being supplied. It might also break existing
+ applications that expect a single number in that field. */
+ vals->values_supplied =
+ vals->values_supplied & ~(PIXELSIZE_MASK | POINTSIZE_MASK) |
+ PIXELSIZE_ARRAY;
+#else /* NOTDEF */
+ vals->values_supplied = vals->values_supplied & ~POINTSIZE_MASK;
+#endif /* NOTDEF */
+ /* Recompute and reround the FontScalablePtr values after
+ rescaling for the new width. */
+ FontFileCompleteXLFD(vals, vals);
+ }
+ break;
+ }
+ return result;
+}
+
+static long
+doround(double x)
+{
+ return (x >= 0) ? (long)(x + .5) : (long)(x - .5);
+}
+
+static int
+computeProps(FontPropPtr pf, char *wasStringProp,
+ FontPropPtr npf, char *isStringProp,
+ unsigned int nprops, double xfactor, double yfactor,
+ double sXfactor, double sYfactor)
+{
+ int n;
+ int count;
+ fontProp *t;
+ double rawfactor = 0.0;
+
+ for (count = 0; nprops > 0; nprops--, pf++, wasStringProp++) {
+ n = sizeof(fontPropTable) / sizeof(fontProp);
+ for (t = fontPropTable; n && (t->atom != pf->name); n--, t++);
+ if (!n)
+ continue;
+
+ switch (t->type) {
+ case scaledX:
+ npf->value = doround(xfactor * (double)pf->value);
+ rawfactor = sXfactor;
+ break;
+ case scaledY:
+ npf->value = doround(yfactor * (double)pf->value);
+ rawfactor = sYfactor;
+ break;
+ case unscaled:
+ npf->value = pf->value;
+ npf->name = pf->name;
+ npf++;
+ count++;
+ *isStringProp++ = *wasStringProp;
+ break;
+ default:
+ break;
+ }
+ if (t->type != unscaled)
+ {
+ npf->name = pf->name;
+ npf++;
+ count++;
+ npf->value = doround(rawfactor * (double)pf->value);
+ npf->name = rawFontPropTable[t - fontPropTable].atom;
+ npf++;
+ count++;
+ *isStringProp++ = *wasStringProp;
+ *isStringProp++ = *wasStringProp;
+ }
+ }
+ return count;
+}
+
+
+static int
+ComputeScaledProperties(FontInfoPtr sourceFontInfo, /* the font to be scaled */
+ char *name, /* name of resulting font */
+ FontScalablePtr vals,
+ double dx, double dy, /* scale factors in x and y */
+ double sdx, double sdy, /* directions */
+ long sWidth, /* 1000-pixel average width */
+ FontPropPtr *pProps, /* returns properties;
+ preallocated */
+ char **pIsStringProp) /* return booleans;
+ preallocated */
+{
+ int n;
+ char *ptr1 = NULL, *ptr2 = NULL;
+ char *ptr3;
+ FontPropPtr fp;
+ fontProp *fpt;
+ char *isStringProp;
+ int nProps;
+
+ if (bitscaleGeneration != serverGeneration) {
+ initFontPropTable();
+ bitscaleGeneration = serverGeneration;
+ }
+ nProps = NPROPS + 1 + sizeof(fontPropTable) / sizeof(fontProp) +
+ sizeof(rawFontPropTable) / sizeof(fontProp);
+ fp = (FontPropPtr) xalloc(sizeof(FontPropRec) * nProps);
+ *pProps = fp;
+ if (!fp) {
+ fprintf(stderr, "Error: Couldn't allocate font properties (%ld*%d)\n",
+ (unsigned long)sizeof(FontPropRec), nProps);
+ return 1;
+ }
+ isStringProp = (char *) xalloc (nProps);
+ *pIsStringProp = isStringProp;
+ if (!isStringProp)
+ {
+ fprintf(stderr, "Error: Couldn't allocate isStringProp (%d)\n", nProps);
+ xfree (fp);
+ return 1;
+ }
+ ptr2 = name;
+ for (fpt = fontNamePropTable, n = NPROPS;
+ n;
+ fp++, fpt++, n--, isStringProp++)
+ {
+
+ if (*ptr2)
+ {
+ ptr1 = ptr2 + 1;
+ if (!(ptr2 = strchr(ptr1, '-'))) ptr2 = strchr(ptr1, '\0');
+ }
+
+ *isStringProp = 0;
+ switch (fpt->type) {
+ case atom:
+ fp->value = MakeAtom(ptr1, ptr2 - ptr1, TRUE);
+ *isStringProp = 1;
+ break;
+ case truncate_atom:
+ for (ptr3 = ptr1; *ptr3; ptr3++)
+ if (*ptr3 == '[')
+ break;
+ if (!*ptr3) ptr3 = ptr2;
+ fp->value = MakeAtom(ptr1, ptr3 - ptr1, TRUE);
+ *isStringProp = 1;
+ break;
+ case pixel_size:
+ fp->value = doround(vals->pixel_matrix[3]);
+ break;
+ case point_size:
+ fp->value = doround(vals->point_matrix[3] * 10.0);
+ break;
+ case resolution_x:
+ fp->value = vals->x;
+ break;
+ case resolution_y:
+ fp->value = vals->y;
+ break;
+ case average_width:
+ fp->value = vals->width;
+ break;
+ case fontname:
+ fp->value = MakeAtom(name, strlen(name), TRUE);
+ *isStringProp = 1;
+ break;
+ case raw_ascent:
+ fp->value = sourceFontInfo->fontAscent * sdy;
+ break;
+ case raw_descent:
+ fp->value = sourceFontInfo->fontDescent * sdy;
+ break;
+ case raw_pointsize:
+ fp->value = (long)(72270.0 / (double)vals->y + .5);
+ break;
+ case raw_pixelsize:
+ fp->value = 1000;
+ break;
+ case raw_average_width:
+ fp->value = sWidth;
+ break;
+ default:
+ break;
+ }
+ fp->name = fpt->atom;
+ }
+ n = NPROPS;
+ n += computeProps(sourceFontInfo->props, sourceFontInfo->isStringProp,
+ fp, isStringProp, sourceFontInfo->nprops, dx, dy,
+ sdx, sdy);
+ return n;
+}
+
+
+static int
+compute_xform_matrix(FontScalablePtr vals, double dx, double dy,
+ double *xform, double *inv_xform,
+ double *xmult, double *ymult)
+{
+ double det;
+ double pixel = get_matrix_vertical_component(vals->pixel_matrix);
+ double pixelset = get_matrix_horizontal_component(vals->pixel_matrix);
+
+ if (pixel < EPS || pixelset < EPS) return 0;
+
+ /* Initialize the transformation matrix to the scaling factors */
+ xform[0] = dx / pixelset;
+ xform[1] = xform[2] = 0.0;
+ xform[3] = dy / pixel;
+
+/* Inline matrix multiply -- somewhat ugly to minimize register usage */
+#define MULTIPLY_XFORM(a,b,c,d) \
+{ \
+ register double aa = (a), bb = (b), cc = (c), dd = (d); \
+ register double temp; \
+ temp = aa * xform[0] + cc * xform[1]; \
+ aa = aa * xform[2] + cc * xform[3]; \
+ xform[1] = bb * xform[0] + dd * xform[1]; \
+ xform[3] = bb * xform[2] + dd * xform[3]; \
+ xform[0] = temp; \
+ xform[2] = aa; \
+}
+
+ /* Rescale the transformation matrix for size of source font */
+ MULTIPLY_XFORM(vals->pixel_matrix[0],
+ vals->pixel_matrix[1],
+ vals->pixel_matrix[2],
+ vals->pixel_matrix[3]);
+
+ *xmult = xform[0];
+ *ymult = xform[3];
+
+
+ if (inv_xform == NULL) return 1;
+
+ /* Compute the determinant for use in inverting the matrix. */
+ det = xform[0] * xform[3] - xform[1] * xform[2];
+
+ /* If the determinant is tiny or zero, give up */
+ if (fabs(det) < EPS) return 0;
+
+ /* Compute the inverse */
+ inv_xform[0] = xform[3] / det;
+ inv_xform[1] = -xform[1] / det;
+ inv_xform[2] = -xform[2] / det;
+ inv_xform[3] = xform[0] / det;
+
+ return 1;
+}
+
+/*
+ * ScaleFont
+ * returns a pointer to the new scaled font, or NULL (due to AllocError).
+ */
+static FontPtr
+ScaleFont(FontPtr opf, /* originating font */
+ double widthMult, /* glyphs width scale factor */
+ double heightMult, /* glyphs height scale factor */
+ double sWidthMult, /* scalable glyphs width scale factor */
+ double sHeightMult, /* scalable glyphs height scale factor */
+ FontScalablePtr vals,
+ double *newWidthMult, /* return: X component of glyphs width
+ scale factor */
+ double *newHeightMult, /* return: Y component of glyphs height
+ scale factor */
+ long *sWidth) /* return: average 1000-pixel width */
+{
+ FontPtr pf;
+ FontInfoPtr pfi,
+ opfi;
+ BitmapFontPtr bitmapFont,
+ obitmapFont;
+ CharInfoPtr pci,
+ opci;
+ int nchars = 0; /* how many characters in the font */
+ int i;
+ int firstCol, lastCol, firstRow, lastRow;
+ double xform[4], inv_xform[4];
+ double xmult, ymult;
+ int totalwidth = 0, totalchars = 0;
+#define OLDINDEX(i) (((i)/(lastCol - firstCol + 1) + \
+ firstRow - opf->info.firstRow) * \
+ (opf->info.lastCol - opf->info.firstCol + 1) + \
+ (i)%(lastCol - firstCol + 1) + \
+ firstCol - opf->info.firstCol)
+
+ *sWidth = 0;
+
+ opfi = &opf->info;
+ obitmapFont = (BitmapFontPtr) opf->fontPrivate;
+
+ bitmapFont = 0;
+ if (!(pf = CreateFontRec())) {
+ fprintf(stderr, "Error: Couldn't allocate FontRec (%ld)\n",
+ (unsigned long)sizeof(FontRec));
+ goto bail;
+ }
+ pf->refcnt = 0;
+ pf->bit = opf->bit;
+ pf->byte = opf->byte;
+ pf->glyph = opf->glyph;
+ pf->scan = opf->scan;
+
+ pf->get_glyphs = bitmapGetGlyphs;
+ pf->get_metrics = bitmapGetMetrics;
+ pf->unload_font = bitmapUnloadScalable;
+ pf->unload_glyphs = NULL;
+
+ pfi = &pf->info;
+ *pfi = *opfi;
+ /* If charset subsetting specified in vals, determine what our range
+ needs to be for the output font */
+ if (vals->nranges)
+ {
+ int i;
+
+ pfi->allExist = 0;
+ firstCol = 255;
+ lastCol = 0;
+ firstRow = 255;
+ lastRow = 0;
+
+ for (i = 0; i < vals->nranges; i++)
+ {
+ if (vals->ranges[i].min_char_high != vals->ranges[i].max_char_high)
+ {
+ firstCol = opfi->firstCol;
+ lastCol = opfi->lastCol;
+ }
+ if (firstCol > vals->ranges[i].min_char_low)
+ firstCol = vals->ranges[i].min_char_low;
+ if (lastCol < vals->ranges[i].max_char_low)
+ lastCol = vals->ranges[i].max_char_low;
+ if (firstRow > vals->ranges[i].min_char_high)
+ firstRow = vals->ranges[i].min_char_high;
+ if (lastRow < vals->ranges[i].max_char_high)
+ lastRow = vals->ranges[i].max_char_high;
+ }
+
+ if (firstCol > lastCol || firstRow > lastRow)
+ goto bail;
+
+ if (firstCol < opfi->firstCol)
+ firstCol = opfi->firstCol;
+ if (lastCol > opfi->lastCol)
+ lastCol = opfi->lastCol;
+ if (firstRow < opfi->firstRow)
+ firstRow = opfi->firstRow;
+ if (lastRow > opfi->lastRow)
+ lastRow = opfi->lastRow;
+ }
+ else
+ {
+ firstCol = opfi->firstCol;
+ lastCol = opfi->lastCol;
+ firstRow = opfi->firstRow;
+ lastRow = opfi->lastRow;
+ }
+
+ bitmapFont = (BitmapFontPtr) xalloc(sizeof(BitmapFontRec));
+ if (!bitmapFont) {
+ fprintf(stderr, "Error: Couldn't allocate bitmapFont (%ld)\n",
+ (unsigned long)sizeof(BitmapFontRec));
+ goto bail;
+ }
+ nchars = (lastRow - firstRow + 1) * (lastCol - firstCol + 1);
+ pfi->firstRow = firstRow;
+ pfi->lastRow = lastRow;
+ pfi->firstCol = firstCol;
+ pfi->lastCol = lastCol;
+ pf->fontPrivate = (pointer) bitmapFont;
+ bitmapFont->version_num = obitmapFont->version_num;
+ bitmapFont->num_chars = nchars;
+ bitmapFont->num_tables = obitmapFont->num_tables;
+ bitmapFont->metrics = 0;
+ bitmapFont->ink_metrics = 0;
+ bitmapFont->bitmaps = 0;
+ bitmapFont->encoding = 0;
+ bitmapFont->bitmapExtra = 0;
+ bitmapFont->pDefault = 0;
+ bitmapFont->metrics = (CharInfoPtr) xalloc(nchars * sizeof(CharInfoRec));
+ if (!bitmapFont->metrics) {
+ fprintf(stderr, "Error: Couldn't allocate metrics (%d*%ld)\n",
+ nchars, (unsigned long)sizeof(CharInfoRec));
+ goto bail;
+ }
+ bitmapFont->encoding =
+ (CharInfoPtr **) xcalloc(NUM_SEGMENTS(nchars),
+ sizeof(CharInfoPtr*));
+ if (!bitmapFont->encoding) {
+ fprintf(stderr, "Error: Couldn't allocate encoding (%d*%ld)\n",
+ nchars, (unsigned long)sizeof(CharInfoPtr));
+ goto bail;
+ }
+
+#undef MAXSHORT
+#define MAXSHORT 32767
+#undef MINSHORT
+#define MINSHORT -32768
+
+ pfi->anamorphic = FALSE;
+ if (heightMult != widthMult)
+ pfi->anamorphic = TRUE;
+ pfi->cachable = TRUE;
+
+ if (!compute_xform_matrix(vals, widthMult, heightMult, xform,
+ inv_xform, &xmult, &ymult))
+ goto bail;
+
+ pfi->fontAscent = opfi->fontAscent * ymult;
+ pfi->fontDescent = opfi->fontDescent * ymult;
+
+ pfi->minbounds.leftSideBearing = MAXSHORT;
+ pfi->minbounds.rightSideBearing = MAXSHORT;
+ pfi->minbounds.ascent = MAXSHORT;
+ pfi->minbounds.descent = MAXSHORT;
+ pfi->minbounds.characterWidth = MAXSHORT;
+ pfi->minbounds.attributes = MAXSHORT;
+
+ pfi->maxbounds.leftSideBearing = MINSHORT;
+ pfi->maxbounds.rightSideBearing = MINSHORT;
+ pfi->maxbounds.ascent = MINSHORT;
+ pfi->maxbounds.descent = MINSHORT;
+ pfi->maxbounds.characterWidth = MINSHORT;
+ pfi->maxbounds.attributes = MINSHORT;
+
+ /* Compute the transformation and inverse transformation matrices.
+ Can fail if the determinant is zero. */
+
+ pci = bitmapFont->metrics;
+ for (i = 0; i < nchars; i++)
+ {
+ if ((opci = ACCESSENCODING(obitmapFont->encoding,OLDINDEX(i))))
+ {
+ double newlsb, newrsb, newdesc, newasc, point[2];
+
+#define minchar(p) ((p).min_char_low + ((p).min_char_high << 8))
+#define maxchar(p) ((p).max_char_low + ((p).max_char_high << 8))
+
+ if (vals->nranges)
+ {
+ int row = i / (lastCol - firstCol + 1) + firstRow;
+ int col = i % (lastCol - firstCol + 1) + firstCol;
+ int ch = (row << 8) + col;
+ int j;
+ for (j = 0; j < vals->nranges; j++)
+ if (ch >= minchar(vals->ranges[j]) &&
+ ch <= maxchar(vals->ranges[j]))
+ break;
+ if (j == vals->nranges)
+ {
+ continue;
+ }
+ }
+
+ if (opci->metrics.leftSideBearing == 0 &&
+ opci->metrics.rightSideBearing == 0 &&
+ opci->metrics.ascent == 0 &&
+ opci->metrics.descent == 0 &&
+ opci->metrics.characterWidth == 0)
+ {
+ continue;
+ }
+
+ if(!bitmapFont->encoding[SEGMENT_MAJOR(i)]) {
+ bitmapFont->encoding[SEGMENT_MAJOR(i)]=
+ (CharInfoPtr*)xcalloc(BITMAP_FONT_SEGMENT_SIZE,
+ sizeof(CharInfoPtr));
+ if(!bitmapFont->encoding[SEGMENT_MAJOR(i)])
+ goto bail;
+ }
+ ACCESSENCODINGL(bitmapFont->encoding, i) = pci;
+
+ /* Compute new extents for this glyph */
+ TRANSFORM_POINT(xform,
+ opci->metrics.leftSideBearing,
+ -opci->metrics.descent,
+ point);
+ newlsb = point[0];
+ newrsb = newlsb;
+ newdesc = -point[1];
+ newasc = -newdesc;
+ TRANSFORM_POINT(xform,
+ opci->metrics.leftSideBearing,
+ opci->metrics.ascent,
+ point);
+ CHECK_EXTENT(newlsb, newrsb, newdesc, newasc, point);
+ TRANSFORM_POINT(xform,
+ opci->metrics.rightSideBearing,
+ -opci->metrics.descent,
+ point);
+ CHECK_EXTENT(newlsb, newrsb, newdesc, newasc, point);
+ TRANSFORM_POINT(xform,
+ opci->metrics.rightSideBearing,
+ opci->metrics.ascent,
+ point);
+ CHECK_EXTENT(newlsb, newrsb, newdesc, newasc, point);
+
+ pci->metrics.leftSideBearing = (int)floor(newlsb);
+ pci->metrics.rightSideBearing = (int)floor(newrsb + .5);
+ pci->metrics.descent = (int)ceil(newdesc);
+ pci->metrics.ascent = (int)floor(newasc + .5);
+ /* Accumulate total width of characters before transformation,
+ to ascertain predominant direction of font. */
+ totalwidth += opci->metrics.characterWidth;
+ pci->metrics.characterWidth =
+ doround((double)opci->metrics.characterWidth * xmult);
+ pci->metrics.attributes =
+ doround((double)opci->metrics.characterWidth * sWidthMult);
+ if (!pci->metrics.characterWidth)
+ {
+ /* Since transformation may shrink width, height, and
+ escapement to zero, make sure existing characters
+ are not mistaken for undefined characters. */
+
+ if (pci->metrics.rightSideBearing ==
+ pci->metrics.leftSideBearing)
+ pci->metrics.rightSideBearing++;
+ if (pci->metrics.ascent == -pci->metrics.descent)
+ pci->metrics.ascent++;
+ }
+
+ pci++;
+ }
+ }
+
+
+ /*
+ * For each character, set the per-character metrics, scale the glyph, and
+ * check per-font minbounds and maxbounds character information.
+ */
+
+ pci = bitmapFont->metrics;
+ for (i = 0; i < nchars; i++)
+ {
+ if ((pci = ACCESSENCODING(bitmapFont->encoding,i)) &&
+ (opci = ACCESSENCODING(obitmapFont->encoding,OLDINDEX(i))))
+ {
+ totalchars++;
+ *sWidth += abs((int)(INT16)pci->metrics.attributes);
+#define MINMAX(field) \
+ if (pfi->minbounds.field > pci->metrics.field) \
+ pfi->minbounds.field = pci->metrics.field; \
+ if (pfi->maxbounds.field < pci->metrics.field) \
+ pfi->maxbounds.field = pci->metrics.field
+
+ MINMAX(leftSideBearing);
+ MINMAX(rightSideBearing);
+ MINMAX(ascent);
+ MINMAX(descent);
+ MINMAX(characterWidth);
+
+ /* Hack: Cast attributes into a signed quantity. Tread lightly
+ for now and don't go changing the global Xproto.h file */
+ if ((INT16)pfi->minbounds.attributes >
+ (INT16)pci->metrics.attributes)
+ pfi->minbounds.attributes = pci->metrics.attributes;
+ if ((INT16)pfi->maxbounds.attributes <
+ (INT16)pci->metrics.attributes)
+ pfi->maxbounds.attributes = pci->metrics.attributes;
+#undef MINMAX
+ }
+ }
+ pfi->ink_minbounds = pfi->minbounds;
+ pfi->ink_maxbounds = pfi->maxbounds;
+ if (totalchars)
+ {
+ *sWidth = (*sWidth * 10 + totalchars / 2) / totalchars;
+ if (totalwidth < 0)
+ {
+ /* Dominant direction is R->L */
+ *sWidth = -*sWidth;
+ }
+
+ if (pfi->minbounds.characterWidth == pfi->maxbounds.characterWidth)
+ vals->width = pfi->minbounds.characterWidth * 10;
+ else
+ vals->width = doround((double)*sWidth * vals->pixel_matrix[0] /
+ 1000.0);
+ }
+ else
+ {
+ vals->width = 0;
+ *sWidth = 0;
+ }
+ FontComputeInfoAccelerators (pfi);
+
+ if (pfi->defaultCh != (unsigned short) NO_SUCH_CHAR) {
+ unsigned int r,
+ c,
+ cols;
+
+ r = pfi->defaultCh >> 8;
+ c = pfi->defaultCh & 0xFF;
+ if (pfi->firstRow <= r && r <= pfi->lastRow &&
+ pfi->firstCol <= c && c <= pfi->lastCol) {
+ cols = pfi->lastCol - pfi->firstCol + 1;
+ r = r - pfi->firstRow;
+ c = c - pfi->firstCol;
+ bitmapFont->pDefault =
+ ACCESSENCODING(bitmapFont->encoding, r * cols + c);
+ }
+ }
+
+ *newWidthMult = xmult;
+ *newHeightMult = ymult;
+ return pf;
+bail:
+ if (pf)
+ xfree(pf);
+ if (bitmapFont) {
+ xfree(bitmapFont->metrics);
+ xfree(bitmapFont->ink_metrics);
+ xfree(bitmapFont->bitmaps);
+ if(bitmapFont->encoding)
+ for(i=0; i<NUM_SEGMENTS(nchars); i++)
+ xfree(bitmapFont->encoding[i]);
+ xfree(bitmapFont->encoding);
+ }
+ return NULL;
+}
+
+static void
+ScaleBitmap(FontPtr pFont, CharInfoPtr opci, CharInfoPtr pci,
+ double *inv_xform, double widthMult, double heightMult)
+{
+ register char *bitmap, /* The bits */
+ *newBitmap;
+ register int bpr, /* Padding information */
+ newBpr;
+ int width, /* Extents information */
+ height,
+ newWidth,
+ newHeight;
+ register int row, /* Loop variables */
+ col;
+ INT32 deltaX, /* Increments for resampling loop */
+ deltaY;
+ INT32 xValue, /* Subscripts for resampling loop */
+ yValue;
+ double point[2];
+ unsigned char *char_grayscale = 0;
+ INT32 *diffusion_workspace = NULL, *thisrow = NULL,
+ *nextrow = NULL, pixmult = 0;
+ int box_x = 0, box_y = 0;
+
+ static unsigned char masklsb[] =
+ { 0x1, 0x2, 0x4, 0x8, 0x10, 0x20, 0x40, 0x80 };
+ static unsigned char maskmsb[] =
+ { 0x80, 0x40, 0x20, 0x10, 0x8, 0x4, 0x2, 0x1 };
+ unsigned char *mask = (pFont->bit == LSBFirst ? masklsb : maskmsb);
+
+
+ bitmap = opci->bits;
+ newBitmap = pci->bits;
+ width = GLYPHWIDTHPIXELS(opci);
+ height = GLYPHHEIGHTPIXELS(opci);
+ newWidth = GLYPHWIDTHPIXELS(pci);
+ newHeight = GLYPHHEIGHTPIXELS(pci);
+ if (!newWidth || !newHeight || !width || !height)
+ return;
+
+ bpr = BYTES_PER_ROW(width, pFont->glyph);
+ newBpr = BYTES_PER_ROW(newWidth, pFont->glyph);
+
+ if (widthMult > 0.0 && heightMult > 0.0 &&
+ (widthMult < 1.0 || heightMult < 1.0))
+ {
+ /* We are reducing in one or both dimensions. In an attempt to
+ reduce aliasing, we'll antialias by passing the original
+ glyph through a low-pass box filter (which results in a
+ grayscale image), then use error diffusion to create bitonal
+ output in the resampling loop. */
+
+ /* First compute the sizes of the box filter */
+ widthMult = ceil(1.0 / widthMult);
+ heightMult = ceil(1.0 / heightMult);
+ box_x = width / 2;
+ box_y = height / 2;
+ if (widthMult < (double)box_x) box_x = (int)widthMult;
+ if (heightMult < (double)box_y) box_y = (int)heightMult;
+ /* The pixmult value (below) is used to darken the image before
+ we perform error diffusion: a necessary concession to the
+ fact that it's very difficult to generate readable halftoned
+ glyphs. The degree of darkening is proportional to the size
+ of the blurring filter, hence inversely proportional to the
+ darkness of the lightest gray that results from antialiasing.
+ The result is that characters that exercise this logic (those
+ generated by reducing from a larger source font) tend to err
+ on the side of being too bold instead of being too light to
+ be readable. */
+ pixmult = box_x * box_y * 192;
+
+ if (box_x > 1 || box_y > 1)
+ {
+ /* Looks like we need to anti-alias. Create a workspace to
+ contain the grayscale character plus an additional row and
+ column for scratch */
+ char_grayscale =
+ (unsigned char *)xalloc((width + 1) * (height + 1));
+ if (char_grayscale)
+ {
+ diffusion_workspace =
+ (INT32 *)xalloc((newWidth + 2) * 2 * sizeof(int));
+ if (!diffusion_workspace)
+ {
+ fprintf(stderr, "Warning: Couldn't allocate diffusion"
+ " workspace (%ld)\n",
+ (newWidth + 2) * 2 * (unsigned long)sizeof(int));
+ xfree(char_grayscale);
+ char_grayscale = (unsigned char *)0;
+ }
+ /* Initialize our error diffusion workspace for later use */
+ bzero((char *)diffusion_workspace + sizeof(INT32),
+ (newWidth + 3) * sizeof(int));
+ thisrow = diffusion_workspace + 1;
+ nextrow = diffusion_workspace + newWidth + 3;
+ } else {
+ fprintf(stderr, "Warning: Couldn't allocate character grayscale (%d)\n", (width + 1) * (height + 1));
+ }
+ }
+ }
+
+ if (char_grayscale)
+ {
+ /* We will be doing antialiasing. First copy the bitmap into
+ our buffer, mapping input range [0,1] to output range
+ [0,255]. */
+ register unsigned char *srcptr, *dstptr;
+ srcptr = (unsigned char *)bitmap;
+ dstptr = char_grayscale;
+ for (row = 0; row < height; row++)
+ {
+ for (col = 0; col < width; col++)
+ *dstptr++ = (srcptr[col >> 3] & mask[col & 0x7]) ? 255 : 0;
+ srcptr += bpr; /* On to next row of source */
+ dstptr++; /* Skip scratch column in dest */
+ }
+ if (box_x > 1)
+ {
+ /* Our box filter has a width > 1... let's filter the rows */
+
+ int right_width = box_x / 2;
+ int left_width = box_x - right_width - 1;
+
+ for (row = 0; row < height; row++)
+ {
+ int sum = 0;
+ int left_size = 0, right_size = 0;
+
+ srcptr = char_grayscale + (width + 1) * row;
+ dstptr = char_grayscale + (width + 1) * height; /* scratch */
+
+ /* We've computed the shape of our full box filter. Now
+ compute the right-hand part of the moving sum */
+ for (right_size = 0; right_size < right_width; right_size++)
+ sum += srcptr[right_size];
+
+ /* Now start moving the sum, growing the box filter, and
+ dropping averages into our scratch buffer */
+ for (left_size = 0; left_size < left_width; left_size++)
+ {
+ sum += srcptr[right_width];
+ *dstptr++ = sum / (left_size + right_width + 1);
+ srcptr++;
+ }
+
+ /* The box filter has reached full width... continue
+ computation of moving average until the right side
+ hits the wall. */
+ for (col = left_size; col + right_size < width; col++)
+ {
+ sum += srcptr[right_width];
+ *dstptr++ = sum / box_x;
+ sum -= srcptr[-left_width];
+ srcptr++;
+ }
+
+ /* Collapse the right side of the box filter */
+ for (; right_size > 0; right_size--)
+ {
+ *dstptr++ = sum / (left_width + right_size);
+ sum -= srcptr[-left_width];
+ srcptr++;
+ }
+
+ /* Done with the row... copy dest back over source */
+ memmove(char_grayscale + (width + 1) * row,
+ char_grayscale + (width + 1) * height,
+ width);
+ }
+ }
+ if (box_y > 1)
+ {
+ /* Our box filter has a height > 1... let's filter the columns */
+
+ int bottom_height = box_y / 2;
+ int top_height = box_y - bottom_height - 1;
+
+ for (col = 0; col < width; col++)
+ {
+ int sum = 0;
+ int top_size = 0, bottom_size = 0;
+
+ srcptr = char_grayscale + col;
+ dstptr = char_grayscale + width; /* scratch */
+
+ /* We've computed the shape of our full box filter. Now
+ compute the bottom part of the moving sum */
+ for (bottom_size = 0;
+ bottom_size < bottom_height;
+ bottom_size++)
+ sum += srcptr[bottom_size * (width + 1)];
+
+ /* Now start moving the sum, growing the box filter, and
+ dropping averages into our scratch buffer */
+ for (top_size = 0; top_size < top_height; top_size++)
+ {
+ sum += srcptr[bottom_height * (width + 1)];
+ *dstptr = sum / (top_size + bottom_height + 1);
+ dstptr += width + 1;
+ srcptr += width + 1;
+ }
+
+ /* The box filter has reached full height... continue
+ computation of moving average until the bottom
+ hits the wall. */
+ for (row = top_size; row + bottom_size < height; row++)
+ {
+ sum += srcptr[bottom_height * (width + 1)];
+ *dstptr = sum / box_y;
+ dstptr += width + 1;
+ sum -= srcptr[-top_height * (width + 1)];
+ srcptr += width + 1;
+ }
+
+ /* Collapse the bottom of the box filter */
+ for (; bottom_size > 0; bottom_size--)
+ {
+ *dstptr = sum / (top_height + bottom_size);
+ dstptr += width + 1;
+ sum -= srcptr[-top_height * (width + 1)];
+ srcptr += width + 1;
+ }
+
+ /* Done with the column... copy dest back over source */
+
+ dstptr = char_grayscale + col;
+ srcptr = char_grayscale + width; /* scratch */
+ for (row = 0; row < height; row++)
+ {
+ *dstptr = *srcptr;
+ dstptr += width + 1;
+ srcptr += width + 1;
+ }
+ }
+ }
+
+ /* Increase the grayvalue to increase ink a bit */
+ srcptr = char_grayscale;
+ for (row = 0; row < height; row++)
+ {
+ for (col = 0; col < width; col++)
+ {
+ register int pixvalue = (int)*srcptr * pixmult / 256;
+ if (pixvalue > 255) pixvalue = 255;
+ *srcptr = pixvalue;
+ srcptr++;
+ }
+ srcptr++;
+ }
+ }
+
+ /* Compute the increment values for the resampling loop */
+ TRANSFORM_POINT(inv_xform, 1, 0, point);
+ deltaX = (INT32)(point[0] * 65536.0);
+ deltaY = (INT32)(-point[1] * 65536.0);
+
+ /* Resampling loop: resamples original glyph for generation of new
+ glyph in transformed coordinate system. */
+
+ for (row = 0; row < newHeight; row++)
+ {
+ /* Compute inverse transformation for start of this row */
+ TRANSFORM_POINT(inv_xform,
+ (double)(pci->metrics.leftSideBearing) + .5,
+ (double)(pci->metrics.ascent - row) - .5,
+ point);
+
+ /* Adjust for coordinate system to get resampling point */
+ point[0] -= opci->metrics.leftSideBearing;
+ point[1] = opci->metrics.ascent - point[1];
+
+ /* Convert to integer coordinates */
+ xValue = (INT32)(point[0] * 65536.0);
+ yValue = (INT32)(point[1] * 65536.0);
+
+ if (char_grayscale)
+ {
+ INT32 *temp;
+ for (col = 0; col < newWidth; col++)
+ {
+ register int x = xValue >> 16, y = yValue >> 16;
+ int pixvalue, error;
+
+ pixvalue = ((x >= 0 && x < width && y >= 0 && y < height) ?
+ char_grayscale[x + y * (width + 1)] : 0) +
+ thisrow[col] / 16;
+ if (pixvalue > 255) pixvalue = 255;
+ else if (pixvalue < 0) pixvalue = 0;
+
+ /* Choose the bit value and set resulting error value */
+ if (pixvalue >= 128)
+ {
+ newBitmap[(col >> 3) + row * newBpr] |= mask[col & 0x7];
+ error = pixvalue - 255;
+ }
+ else
+ error = -pixvalue;
+
+ /* Diffuse the error */
+ thisrow[col + 1] += error * 7;
+ nextrow[col - 1] += error * 3;
+ nextrow[col] += error * 5;
+ nextrow[col + 1] = error;
+
+ xValue += deltaX;
+ yValue += deltaY;
+ }
+
+ /* Add in error values that fell off either end */
+ nextrow[0] += nextrow[-1];
+ nextrow[newWidth - 2] += thisrow[newWidth];
+ nextrow[newWidth - 1] += nextrow[newWidth];
+ nextrow[newWidth] = 0;
+
+ temp = nextrow;
+ nextrow = thisrow;
+ thisrow = temp;
+ nextrow[-1] = nextrow[0] = 0;
+ }
+ else
+ {
+ for (col = 0; col < newWidth; col++)
+ {
+ register int x = xValue >> 16, y = yValue >> 16;
+
+ if (x >= 0 && x < width && y >= 0 && y < height)
+ {
+ /* Use point-sampling for rescaling. */
+
+ if (bitmap[(x >> 3) + y * bpr] & mask[x & 0x7])
+ newBitmap[(col >> 3) + row * newBpr] |= mask[col & 0x7];
+ }
+
+ xValue += deltaX;
+ yValue += deltaY;
+ }
+ }
+ }
+
+
+ if (char_grayscale)
+ {
+ xfree(char_grayscale);
+ xfree(diffusion_workspace);
+ }
+}
+
+static FontPtr
+BitmapScaleBitmaps(FontPtr pf, /* scaled font */
+ FontPtr opf, /* originating font */
+ double widthMult, /* glyphs width scale factor */
+ double heightMult, /* glyphs height scale factor */
+ FontScalablePtr vals)
+{
+ register int i;
+ int nchars = 0;
+ char *glyphBytes;
+ BitmapFontPtr bitmapFont,
+ obitmapFont;
+ CharInfoPtr pci,
+ opci;
+ FontInfoPtr pfi;
+ int glyph;
+ unsigned bytestoalloc = 0;
+ int firstCol, lastCol, firstRow, lastRow;
+
+ double xform[4], inv_xform[4];
+ double xmult, ymult;
+
+ bitmapFont = (BitmapFontPtr) pf->fontPrivate;
+ obitmapFont = (BitmapFontPtr) opf->fontPrivate;
+
+ if (!compute_xform_matrix(vals, widthMult, heightMult, xform,
+ inv_xform, &xmult, &ymult))
+ goto bail;
+
+ pfi = &pf->info;
+ firstCol = pfi->firstCol;
+ lastCol = pfi->lastCol;
+ firstRow = pfi->firstRow;
+ lastRow = pfi->lastRow;
+
+ nchars = (lastRow - firstRow + 1) * (lastCol - firstCol + 1);
+ glyph = pf->glyph;
+ for (i = 0; i < nchars; i++)
+ {
+ if ((pci = ACCESSENCODING(bitmapFont->encoding, i)))
+ bytestoalloc += BYTES_FOR_GLYPH(pci, glyph);
+ }
+
+ /* Do we add the font malloc stuff for VALUE ADDED ? */
+ /* Will need to remember to free in the Unload routine */
+
+
+ bitmapFont->bitmaps = (char *) xalloc(bytestoalloc);
+ if (!bitmapFont->bitmaps) {
+ fprintf(stderr, "Error: Couldn't allocate bitmaps (%d)\n", bytestoalloc);
+ goto bail;
+ }
+ bzero(bitmapFont->bitmaps, bytestoalloc);
+
+ glyphBytes = bitmapFont->bitmaps;
+ for (i = 0; i < nchars; i++)
+ {
+ if ((pci = ACCESSENCODING(bitmapFont->encoding, i)) &&
+ (opci = ACCESSENCODING(obitmapFont->encoding, OLDINDEX(i))))
+ {
+ pci->bits = glyphBytes;
+ ScaleBitmap (pf, opci, pci, inv_xform,
+ widthMult, heightMult);
+ glyphBytes += BYTES_FOR_GLYPH(pci, glyph);
+ }
+ }
+ return pf;
+
+bail:
+ if (pf)
+ xfree(pf);
+ if (bitmapFont) {
+ xfree(bitmapFont->metrics);
+ xfree(bitmapFont->ink_metrics);
+ xfree(bitmapFont->bitmaps);
+ if(bitmapFont->encoding)
+ for(i=0; i<NUM_SEGMENTS(nchars); i++)
+ xfree(bitmapFont->encoding[i]);
+ xfree(bitmapFont->encoding);
+ }
+ return NULL;
+}
+
+static FontPtr
+PrinterScaleBitmaps(FontPtr pf, /* scaled font */
+ FontPtr opf, /* originating font */
+ double widthMult, /* glyphs width scale factor */
+ double heightMult, /* glyphs height scale factor */
+ FontScalablePtr vals)
+{
+ register int i;
+ int nchars = 0;
+ char *glyphBytes;
+ BitmapFontPtr bitmapFont,
+ obitmapFont;
+ CharInfoPtr pci;
+ FontInfoPtr pfi;
+ int glyph;
+ unsigned bytestoalloc = 0;
+ int firstCol, lastCol, firstRow, lastRow;
+
+ double xform[4], inv_xform[4];
+ double xmult, ymult;
+
+ bitmapFont = (BitmapFontPtr) pf->fontPrivate;
+ obitmapFont = (BitmapFontPtr) opf->fontPrivate;
+
+ if (!compute_xform_matrix(vals, widthMult, heightMult, xform,
+ inv_xform, &xmult, &ymult))
+ goto bail;
+
+ pfi = &pf->info;
+ firstCol = pfi->firstCol;
+ lastCol = pfi->lastCol;
+ firstRow = pfi->firstRow;
+ lastRow = pfi->lastRow;
+
+ nchars = (lastRow - firstRow + 1) * (lastCol - firstCol + 1);
+ glyph = pf->glyph;
+ for (i = 0; i < nchars; i++)
+ {
+ if ((pci = ACCESSENCODING(bitmapFont->encoding, i)))
+ bytestoalloc = MAX(bytestoalloc,BYTES_FOR_GLYPH(pci, glyph));
+ }
+
+ /* Do we add the font malloc stuff for VALUE ADDED ? */
+ /* Will need to remember to free in the Unload routine */
+
+
+ bitmapFont->bitmaps = (char *) xalloc(bytestoalloc);
+ if (!bitmapFont->bitmaps) {
+ fprintf(stderr, "Error: Couldn't allocate bitmaps (%d)\n", bytestoalloc);
+ goto bail;
+ }
+ bzero(bitmapFont->bitmaps, bytestoalloc);
+
+ glyphBytes = bitmapFont->bitmaps;
+ for (i = 0; i < nchars; i++)
+ {
+ if ((pci = ACCESSENCODING(bitmapFont->encoding, i)) &&
+ (ACCESSENCODING(obitmapFont->encoding, OLDINDEX(i))))
+ {
+ pci->bits = glyphBytes;
+ }
+ }
+ return pf;
+
+bail:
+ if (pf)
+ xfree(pf);
+ if (bitmapFont) {
+ xfree(bitmapFont->metrics);
+ xfree(bitmapFont->ink_metrics);
+ xfree(bitmapFont->bitmaps);
+ if(bitmapFont->encoding)
+ for(i=0; i<NUM_SEGMENTS(nchars); i++)
+ xfree(bitmapFont->encoding[i]);
+ xfree(bitmapFont->encoding);
+ }
+ return NULL;
+}
+
+#ifdef NOTDEF
+/*
+ * exported interfaces
+ */
+
+FontFileLoadName(FontFileDirPtr *dirs, int ndirs, char *name, FontPtr *pfont,
+ fsBitmapFormat format, fsBitmapFormatMask fmask)
+{
+ FontFileNamePtr fname;
+ char full_name[1024];
+ int ret = BadFontName;
+ int i;
+
+ i = 0;
+ while (i < ndirs) {
+ if (fname = FontFileFindNameInDir(dirs[i], name)) {
+ if (!fname->alias) {
+ if (!fname->font) {
+ strcpy(full_name, dirs[i]->dir);
+ strcat(full_name, fname->file);
+ ret = FontFileLoad(pfont, full_name, format, fmask);
+ if (ret == Successful) {
+ fname->font = *pfont;
+ (*pfont)->fpePrivate = (pointer) fname;
+ }
+ return ret;
+ }
+ *pfont = fname->font;
+ return Successful;
+ }
+ name = fname->file;
+ i = 0;
+ } else
+ i++;
+ }
+ return BadFontName;
+}
+#endif
+
+/* ARGSUSED */
+int
+BitmapOpenScalable (FontPathElementPtr fpe,
+ FontPtr *pFont,
+ int flags,
+ FontEntryPtr entry,
+ char *fileName, /* unused */
+ FontScalablePtr vals,
+ fsBitmapFormat format,
+ fsBitmapFormatMask fmask,
+ FontPtr non_cachable_font) /* We don't do licensing */
+{
+ FontScalableRec best;
+ FontPtr font = NullFont;
+ double dx, sdx,
+ dy, sdy,
+ savedX, savedY;
+ FontPropPtr props;
+ char *isStringProp = NULL;
+ int propCount;
+ int status;
+ long sWidth;
+
+ FontEntryPtr scaleFrom;
+ FontPathElementPtr scaleFPE;
+ FontPtr sourceFont;
+ char fontName[MAXFONTNAMELEN];
+
+ /* Can't deal with mix-endian fonts yet */
+
+#ifdef NOTDEF /* XXX need better test */
+ if ((format & BitmapFormatByteOrderMask) !=
+ (format & BitmapFormatBitOrderMask))
+ return NullFontFileName;
+#endif
+
+ /* Reject outrageously small font sizes to keep the math from
+ blowing up. */
+ if (get_matrix_vertical_component(vals->pixel_matrix) < 1.0 ||
+ get_matrix_horizontal_component(vals->pixel_matrix) < 1.0)
+ return BadFontName;
+
+ scaleFrom = (*find_scale[BitmapGetRenderIndex(entry->u.bitmap.renderer)])
+ (fpe, entry, vals, &best, &dx, &dy, &sdx, &sdy, &scaleFPE);
+
+ if (!scaleFrom)
+ return BadFontName;
+
+ status = FontFileOpenBitmap(scaleFPE, &sourceFont, LoadAll, scaleFrom,
+ format, fmask);
+
+ if (status != Successful)
+ return BadFontName;
+
+ if (!vals->width)
+ vals->width = best.width * dx;
+
+ /* Compute the scaled font */
+
+ savedX = dx;
+ savedY = dy;
+ font = ScaleFont(sourceFont, dx, dy, sdx, sdy, vals, &dx, &dy, &sWidth);
+ if (font)
+ font = (*scale[ BitmapGetRenderIndex(entry->u.bitmap.renderer) ])
+ (font, sourceFont, savedX, savedY, vals);
+
+ if (!font)
+ {
+ if (!sourceFont->refcnt)
+ FontFileCloseFont((FontPathElementPtr) 0, sourceFont);
+ return AllocError;
+ }
+
+ /* Prepare font properties for the new font */
+
+ strcpy (fontName, scaleFrom->name.name);
+ FontParseXLFDName (fontName, vals, FONT_XLFD_REPLACE_VALUE);
+
+ propCount = ComputeScaledProperties(&sourceFont->info, fontName, vals,
+ dx, dy, sdx, sdy, sWidth, &props,
+ &isStringProp);
+
+ if (!sourceFont->refcnt)
+ FontFileCloseFont((FontPathElementPtr) 0, sourceFont);
+
+ if (propCount && (!props || !isStringProp))
+ {
+ font->info.nprops = 0;
+ font->info.props = (FontPropPtr)0;
+ font->info.isStringProp = (char *)0;
+ bitmapUnloadScalable(font);
+ return AllocError;
+ }
+
+ font->info.props = props;
+ font->info.nprops = propCount;
+ font->info.isStringProp = isStringProp;
+
+ *pFont = font;
+ return Successful;
+}
+
+int
+BitmapGetInfoScalable (FontPathElementPtr fpe,
+ FontInfoPtr pFontInfo,
+ FontEntryPtr entry,
+ FontNamePtr fontName,
+ char *fileName,
+ FontScalablePtr vals)
+{
+ FontPtr pfont;
+ int flags = 0;
+ long format = 0; /* It doesn't matter what format for just info */
+ long fmask = 0;
+ int ret;
+
+ ret = BitmapOpenScalable(fpe, &pfont, flags, entry, fileName, vals,
+ format, fmask, NULL);
+ if (ret != Successful)
+ return ret;
+ *pFontInfo = pfont->info;
+
+ pfont->info.nprops = 0;
+ pfont->info.props = NULL;
+ pfont->info.isStringProp = NULL;
+
+ (*pfont->unload_font)(pfont);
+ return Successful;
+}
+
+static void
+bitmapUnloadScalable (FontPtr pFont)
+{
+ BitmapFontPtr bitmapFont;
+ FontInfoPtr pfi;
+ int i, nencoding;
+
+ bitmapFont = (BitmapFontPtr) pFont->fontPrivate;
+ pfi = &pFont->info;
+ xfree (pfi->props);
+ xfree (pfi->isStringProp);
+ if(bitmapFont->encoding) {
+ nencoding = (pFont->info.lastCol - pFont->info.firstCol + 1) *
+ (pFont->info.lastRow - pFont->info.firstRow + 1);
+ for(i=0; i<NUM_SEGMENTS(nencoding); i++)
+ xfree(bitmapFont->encoding[i]);
+ }
+ xfree (bitmapFont->encoding);
+ xfree (bitmapFont->bitmaps);
+ xfree (bitmapFont->ink_metrics);
+ xfree (bitmapFont->metrics);
+ xfree (pFont->fontPrivate);
+ DestroyFontRec (pFont);
+}
diff --git a/libXfont/src/bitmap/fontink.c b/libXfont/src/bitmap/fontink.c
new file mode 100644
index 000000000..a9606f039
--- /dev/null
+++ b/libXfont/src/bitmap/fontink.c
@@ -0,0 +1,219 @@
+/* $Xorg: fontink.c,v 1.4 2001/02/09 02:04:02 xorgcvs Exp $ */
+
+/*
+
+Copyright 1990, 1998 The Open Group
+
+Permission to use, copy, modify, distribute, and sell this software and its
+documentation for any purpose is hereby granted without fee, provided that
+the above copyright notice appear in all copies and that both that
+copyright notice and this permission notice appear in supporting
+documentation.
+
+The above copyright notice and this permission notice shall be included
+in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+IN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR
+OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of The Open Group shall
+not be used in advertising or otherwise to promote the sale, use or
+other dealings in this Software without prior written authorization
+from The Open Group.
+
+*/
+/* $XFree86: xc/lib/font/bitmap/fontink.c,v 1.6 2001/01/17 19:43:27 dawes Exp $ */
+
+/*
+ * Author: Keith Packard, MIT X Consortium
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <X11/fonts/fntfilst.h>
+#include <X11/fonts/bitmap.h>
+#include <X11/fonts/bdfint.h>
+
+static unsigned char ink_mask_msb[8] = {
+ 0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01,
+};
+
+static unsigned char ink_mask_lsb[8] = {
+ 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80,
+};
+
+void
+FontCharInkMetrics(FontPtr pFont, CharInfoPtr pCI, xCharInfo *pInk)
+{
+ int leftBearing,
+ ascent,
+ descent;
+ register int vpos,
+ hpos,
+ bpos = 0;
+ int bitmapByteWidth,
+ bitmapByteWidthPadded;
+ int bitmapBitWidth;
+ int span;
+ register unsigned char *p;
+ unsigned char *ink_mask = 0;
+ register int bmax;
+ register unsigned char charbits;
+
+ if (pFont->bit == MSBFirst)
+ ink_mask = ink_mask_msb;
+ else if (pFont->bit == LSBFirst)
+ ink_mask = ink_mask_lsb;
+ pInk->characterWidth = pCI->metrics.characterWidth;
+ pInk->attributes = pCI->metrics.attributes;
+
+ leftBearing = pCI->metrics.leftSideBearing;
+ ascent = pCI->metrics.ascent;
+ descent = pCI->metrics.descent;
+ bitmapBitWidth = GLYPHWIDTHPIXELS(pCI);
+ bitmapByteWidth = GLYPHWIDTHBYTES(pCI);
+ bitmapByteWidthPadded = BYTES_PER_ROW(bitmapBitWidth, pFont->glyph);
+ span = bitmapByteWidthPadded - bitmapByteWidth;
+
+ p = (unsigned char *) pCI->bits;
+ for (vpos = descent + ascent; --vpos >= 0;) {
+ for (hpos = bitmapByteWidth; --hpos >= 0;) {
+ if (*p++ != 0)
+ goto found_ascent;
+ }
+ p += span;
+ }
+ /*
+ * special case -- font with no bits gets all zeros
+ */
+ pInk->leftSideBearing = leftBearing;
+ pInk->rightSideBearing = leftBearing;
+ pInk->ascent = 0;
+ pInk->descent = 0;
+ return;
+found_ascent:
+ pInk->ascent = vpos - descent + 1;
+
+ p = ((unsigned char *) pCI->bits) + bitmapByteWidthPadded *
+ (descent + ascent - 1) + bitmapByteWidth;
+
+ for (vpos = descent + ascent; --vpos >= 0;) {
+ for (hpos = bitmapByteWidth; --hpos >= 0;) {
+ if (*--p != 0)
+ goto found_descent;
+ }
+ p -= span;
+ }
+found_descent:
+ pInk->descent = vpos - ascent + 1;
+
+ bmax = 8;
+ for (hpos = 0; hpos < bitmapByteWidth; hpos++) {
+ charbits = 0;
+ p = (unsigned char *) pCI->bits + hpos;
+ for (vpos = descent + ascent; --vpos >= 0; p += bitmapByteWidthPadded)
+ charbits |= *p;
+ if (charbits) {
+ if (hpos == bitmapByteWidth - 1)
+ bmax = bitmapBitWidth - (hpos << 3);
+ p = ink_mask;
+ for (bpos = bmax; --bpos >= 0;) {
+ if (charbits & *p++)
+ goto found_left;
+ }
+ }
+ }
+found_left:
+ pInk->leftSideBearing = leftBearing + (hpos << 3) + bmax - bpos - 1;
+
+ bmax = bitmapBitWidth - ((bitmapByteWidth - 1) << 3);
+ for (hpos = bitmapByteWidth; --hpos >= 0;) {
+ charbits = 0;
+ p = (unsigned char *) pCI->bits + hpos;
+ for (vpos = descent + ascent; --vpos >= 0; p += bitmapByteWidthPadded)
+ charbits |= *p;
+ if (charbits) {
+ p = ink_mask + bmax;
+ for (bpos = bmax; --bpos >= 0;) {
+ if (charbits & *--p)
+ goto found_right;
+ }
+ }
+ bmax = 8;
+ }
+found_right:
+ pInk->rightSideBearing = leftBearing + (hpos << 3) + bpos + 1;
+}
+
+#define ISBITONMSB(x, line) ((line)[(x)/8] & (1 << (7-((x)%8))))
+#define SETBITMSB(x, line) ((line)[(x)/8] |= (1 << (7-((x)%8))))
+#define ISBITONLSB(x, line) ((line)[(x)/8] & (1 << ((x)%8)))
+#define SETBITLSB(x, line) ((line)[(x)/8] |= (1 << ((x)%8)))
+
+#define Min(a,b) ((a)<(b)?(a):(b))
+#define Max(a,b) ((a)>(b)?(a):(b))
+
+void
+FontCharReshape(FontPtr pFont, CharInfoPtr pSrc, CharInfoPtr pDst)
+{
+ int x,
+ y;
+ unsigned char *in_line,
+ *out_line;
+ unsigned char *oldglyph,
+ *newglyph;
+ int inwidth;
+ int outwidth,
+ outheight;
+ int out_bytes,
+ in_bytes;
+ int y_min,
+ y_max,
+ x_min,
+ x_max;
+
+ newglyph = (unsigned char *) pDst->bits;
+ outwidth = pDst->metrics.rightSideBearing - pDst->metrics.leftSideBearing;
+ outheight = pDst->metrics.descent + pDst->metrics.ascent;
+ out_bytes = BYTES_PER_ROW(outwidth, pFont->glyph);
+
+ oldglyph = (unsigned char *) pSrc->bits;
+ inwidth = pSrc->metrics.rightSideBearing - pSrc->metrics.leftSideBearing;
+ in_bytes = BYTES_PER_ROW(inwidth, pFont->glyph);
+
+ bzero(newglyph, out_bytes * outheight);
+ in_line = oldglyph;
+ out_line = newglyph;
+ y_min = Max(-pSrc->metrics.ascent, -pDst->metrics.ascent);
+ y_max = Min(pSrc->metrics.descent, pDst->metrics.descent);
+ x_min = Max(pSrc->metrics.leftSideBearing, pDst->metrics.leftSideBearing);
+ x_max = Min(pSrc->metrics.rightSideBearing, pDst->metrics.rightSideBearing);
+ in_line += (y_min + pSrc->metrics.ascent) * in_bytes;
+ out_line += (y_min + pDst->metrics.ascent) * out_bytes;
+ if (pFont->bit == MSBFirst) {
+ for (y = y_min; y < y_max; y++) {
+ for (x = x_min; x < x_max; x++) {
+ if (ISBITONMSB(x - pSrc->metrics.leftSideBearing, in_line))
+ SETBITMSB(x - pDst->metrics.leftSideBearing, out_line);
+ }
+ in_line += in_bytes;
+ out_line += out_bytes;
+ }
+ } else {
+ for (y = y_min; y < y_max; y++) {
+ for (x = x_min; x < x_max; x++) {
+ if (ISBITONLSB(x - pSrc->metrics.leftSideBearing, in_line))
+ SETBITLSB(x - pDst->metrics.leftSideBearing, out_line);
+ }
+ in_line += in_bytes;
+ out_line += out_bytes;
+ }
+ }
+}
diff --git a/libXfont/src/bitmap/pcfread.c b/libXfont/src/bitmap/pcfread.c
new file mode 100644
index 000000000..c5db2555b
--- /dev/null
+++ b/libXfont/src/bitmap/pcfread.c
@@ -0,0 +1,1024 @@
+/* $Xorg: pcfread.c,v 1.5 2001/02/09 02:04:02 xorgcvs Exp $ */
+/*
+
+Copyright 1990, 1998 The Open Group
+
+Permission to use, copy, modify, distribute, and sell this software and its
+documentation for any purpose is hereby granted without fee, provided that
+the above copyright notice appear in all copies and that both that
+copyright notice and this permission notice appear in supporting
+documentation.
+
+The above copyright notice and this permission notice shall be included
+in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+IN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR
+OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of The Open Group shall
+not be used in advertising or otherwise to promote the sale, use or
+other dealings in this Software without prior written authorization
+from The Open Group.
+
+*/
+/* $XFree86: xc/lib/font/bitmap/pcfread.c,v 1.21 2003/11/17 22:20:22 dawes Exp $ */
+
+/*
+ * Author: Keith Packard, MIT X Consortium
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <X11/fonts/fntfilst.h>
+#include <X11/fonts/bitmap.h>
+#include <X11/fonts/pcf.h>
+
+#ifndef MAX
+#define MAX(a,b) (((a)>(b)) ? a : b)
+#endif
+
+#include <stdarg.h>
+#include <stdint.h>
+
+void
+pcfError(const char* message, ...)
+{
+ va_list args;
+
+ va_start(args, message);
+
+ fprintf(stderr, "PCF Error: ");
+ vfprintf(stderr, message, args);
+ va_end(args);
+}
+
+/* Read PCF font files */
+
+static void pcfUnloadFont ( FontPtr pFont );
+static int position;
+
+
+#define IS_EOF(file) ((file)->eof == BUFFILEEOF)
+
+#define FONT_FILE_GETC_ERR(f) (tmp = FontFileGetc(f), BAIL_ON_EOF)
+
+static int
+pcfGetLSB32(FontFilePtr file)
+{
+ int c;
+
+ c = FontFileGetc(file);
+ c |= FontFileGetc(file) << 8;
+ c |= FontFileGetc(file) << 16;
+ c |= FontFileGetc(file) << 24;
+ position += 4;
+ return c;
+}
+
+static int
+pcfGetINT32(FontFilePtr file, CARD32 format)
+{
+ int c;
+
+ if (PCF_BYTE_ORDER(format) == MSBFirst) {
+ c = FontFileGetc(file) << 24;
+ c |= FontFileGetc(file) << 16;
+ c |= FontFileGetc(file) << 8;
+ c |= FontFileGetc(file);
+ } else {
+ c = FontFileGetc(file);
+ c |= FontFileGetc(file) << 8;
+ c |= FontFileGetc(file) << 16;
+ c |= FontFileGetc(file) << 24;
+ }
+ position += 4;
+ return c;
+}
+
+static int
+pcfGetINT16(FontFilePtr file, CARD32 format)
+{
+ int c;
+
+ if (PCF_BYTE_ORDER(format) == MSBFirst) {
+ c = FontFileGetc(file) << 8;
+ c |= FontFileGetc(file);
+ } else {
+ c = FontFileGetc(file);
+ c |= FontFileGetc(file) << 8;
+ }
+ position += 2;
+ return c;
+}
+
+#define pcfGetINT8(file, format) (position++, FontFileGetc(file))
+
+static PCFTablePtr
+pcfReadTOC(FontFilePtr file, int *countp)
+{
+ CARD32 version;
+ PCFTablePtr tables;
+ int count;
+ int i;
+
+ position = 0;
+ version = pcfGetLSB32(file);
+ if (version != PCF_FILE_VERSION)
+ return (PCFTablePtr) NULL;
+ count = pcfGetLSB32(file);
+ if (IS_EOF(file)) return (PCFTablePtr) NULL;
+ if (count < 0 || count > INT32_MAX / sizeof(PCFTableRec)) {
+ pcfError("pcfReadTOC(): invalid file format\n");
+ return NULL;
+ }
+ tables = (PCFTablePtr) xalloc(count * sizeof(PCFTableRec));
+ if (!tables) {
+ pcfError("pcfReadTOC(): Couldn't allocate tables (%d*%d)\n", count, sizeof(PCFTableRec));
+ return (PCFTablePtr) NULL;
+ }
+ for (i = 0; i < count; i++) {
+ tables[i].type = pcfGetLSB32(file);
+ tables[i].format = pcfGetLSB32(file);
+ tables[i].size = pcfGetLSB32(file);
+ tables[i].offset = pcfGetLSB32(file);
+ if (IS_EOF(file)) goto Bail;
+ }
+
+ *countp = count;
+ return tables;
+
+ Bail:
+ xfree(tables);
+ return (PCFTablePtr) NULL;
+}
+
+/*
+ * PCF supports two formats for metrics, both the regular
+ * jumbo size, and 'lite' metrics, which are useful
+ * for most fonts which have even vaguely reasonable
+ * metrics
+ */
+
+static Bool
+pcfGetMetric(FontFilePtr file, CARD32 format, xCharInfo *metric)
+{
+ metric->leftSideBearing = pcfGetINT16(file, format);
+ metric->rightSideBearing = pcfGetINT16(file, format);
+ metric->characterWidth = pcfGetINT16(file, format);
+ metric->ascent = pcfGetINT16(file, format);
+ metric->descent = pcfGetINT16(file, format);
+ metric->attributes = pcfGetINT16(file, format);
+ if (IS_EOF(file)) return FALSE;
+
+ return TRUE;
+}
+
+static Bool
+pcfGetCompressedMetric(FontFilePtr file, CARD32 format, xCharInfo *metric)
+{
+ metric->leftSideBearing = pcfGetINT8(file, format) - 0x80;
+ metric->rightSideBearing = pcfGetINT8(file, format) - 0x80;
+ metric->characterWidth = pcfGetINT8(file, format) - 0x80;
+ metric->ascent = pcfGetINT8(file, format) - 0x80;
+ metric->descent = pcfGetINT8(file, format) - 0x80;
+ metric->attributes = 0;
+ if (IS_EOF(file)) return FALSE;
+
+ return TRUE;
+}
+
+/*
+ * Position the file to the begining of the specified table
+ * in the font file
+ */
+static Bool
+pcfSeekToType(FontFilePtr file, PCFTablePtr tables, int ntables,
+ CARD32 type, CARD32 *formatp, CARD32 *sizep)
+{
+ int i;
+
+ for (i = 0; i < ntables; i++)
+ if (tables[i].type == type) {
+ if (position > tables[i].offset)
+ return FALSE;
+ if (!FontFileSkip(file, tables[i].offset - position))
+ return FALSE;
+ position = tables[i].offset;
+ *sizep = tables[i].size;
+ *formatp = tables[i].format;
+ return TRUE;
+ }
+ return FALSE;
+}
+
+static Bool
+pcfHasType (PCFTablePtr tables, int ntables, CARD32 type)
+{
+ int i;
+
+ for (i = 0; i < ntables; i++)
+ if (tables[i].type == type)
+ return TRUE;
+ return FALSE;
+}
+
+/*
+ * pcfGetProperties
+ *
+ * Reads the font properties from the font file, filling in the FontInfo rec
+ * supplied. Used by by both ReadFont and ReadFontInfo routines.
+ */
+
+static Bool
+pcfGetProperties(FontInfoPtr pFontInfo, FontFilePtr file,
+ PCFTablePtr tables, int ntables)
+{
+ FontPropPtr props = 0;
+ int nprops;
+ char *isStringProp = 0;
+ CARD32 format;
+ int i;
+ CARD32 size;
+ int string_size;
+ char *strings;
+
+ /* font properties */
+
+ if (!pcfSeekToType(file, tables, ntables, PCF_PROPERTIES, &format, &size))
+ goto Bail;
+ format = pcfGetLSB32(file);
+ if (!PCF_FORMAT_MATCH(format, PCF_DEFAULT_FORMAT))
+ goto Bail;
+ nprops = pcfGetINT32(file, format);
+ if (nprops <= 0 || nprops > INT32_MAX / sizeof(FontPropRec)) {
+ pcfError("pcfGetProperties(): invalid nprops value (%d)\n", nprops);
+ goto Bail;
+ }
+ if (IS_EOF(file)) goto Bail;
+ props = (FontPropPtr) xalloc(nprops * sizeof(FontPropRec));
+ if (!props) {
+ pcfError("pcfGetProperties(): Couldn't allocate props (%d*%d)\n", nprops, sizeof(FontPropRec));
+ goto Bail;
+ }
+ isStringProp = (char *) xalloc(nprops * sizeof(char));
+ if (!isStringProp) {
+ pcfError("pcfGetProperties(): Couldn't allocate isStringProp (%d*%d)\n", nprops, sizeof(char));
+ goto Bail;
+ }
+ for (i = 0; i < nprops; i++) {
+ props[i].name = pcfGetINT32(file, format);
+ isStringProp[i] = pcfGetINT8(file, format);
+ props[i].value = pcfGetINT32(file, format);
+ if (props[i].name < 0
+ || (isStringProp[i] != 0 && isStringProp[i] != 1)
+ || (isStringProp[i] && props[i].value < 0)) {
+ pcfError("pcfGetProperties(): invalid file format %d %d %d\n",
+ props[i].name, isStringProp[i], props[i].value);
+ goto Bail;
+ }
+ if (IS_EOF(file)) goto Bail;
+ }
+ /* pad the property array */
+ /*
+ * clever here - nprops is the same as the number of odd-units read, as
+ * only isStringProp are odd length
+ */
+ if (nprops & 3)
+ {
+ i = 4 - (nprops & 3);
+ (void)FontFileSkip(file, i);
+ position += i;
+ }
+ if (IS_EOF(file)) goto Bail;
+ string_size = pcfGetINT32(file, format);
+ if (string_size < 0) goto Bail;
+ if (IS_EOF(file)) goto Bail;
+ strings = (char *) xalloc(string_size);
+ if (!strings) {
+ pcfError("pcfGetProperties(): Couldn't allocate strings (%d)\n", string_size);
+ goto Bail;
+ }
+ FontFileRead(file, strings, string_size);
+ if (IS_EOF(file)) goto Bail;
+ position += string_size;
+ for (i = 0; i < nprops; i++) {
+ props[i].name = MakeAtom(strings + props[i].name,
+ strlen(strings + props[i].name), TRUE);
+ if (isStringProp[i]) {
+ props[i].value = MakeAtom(strings + props[i].value,
+ strlen(strings + props[i].value), TRUE);
+ }
+ }
+ xfree(strings);
+ pFontInfo->isStringProp = isStringProp;
+ pFontInfo->props = props;
+ pFontInfo->nprops = nprops;
+ return TRUE;
+Bail:
+ xfree(isStringProp);
+ xfree(props);
+ return FALSE;
+}
+
+
+/*
+ * pcfReadAccel
+ *
+ * Fill in the accelerator information from the font file; used
+ * to read both BDF_ACCELERATORS and old style ACCELERATORS
+ */
+
+static Bool
+pcfGetAccel(FontInfoPtr pFontInfo, FontFilePtr file,
+ PCFTablePtr tables, int ntables, CARD32 type)
+{
+ CARD32 format;
+ CARD32 size;
+
+ if (!pcfSeekToType(file, tables, ntables, type, &format, &size) ||
+ IS_EOF(file))
+ goto Bail;
+ format = pcfGetLSB32(file);
+ if (!PCF_FORMAT_MATCH(format, PCF_DEFAULT_FORMAT) &&
+ !PCF_FORMAT_MATCH(format, PCF_ACCEL_W_INKBOUNDS))
+ {
+ goto Bail;
+ }
+ pFontInfo->noOverlap = pcfGetINT8(file, format);
+ pFontInfo->constantMetrics = pcfGetINT8(file, format);
+ pFontInfo->terminalFont = pcfGetINT8(file, format);
+ pFontInfo->constantWidth = pcfGetINT8(file, format);
+ pFontInfo->inkInside = pcfGetINT8(file, format);
+ pFontInfo->inkMetrics = pcfGetINT8(file, format);
+ pFontInfo->drawDirection = pcfGetINT8(file, format);
+ pFontInfo->anamorphic = FALSE;
+ pFontInfo->cachable = TRUE;
+ /* natural alignment */ pcfGetINT8(file, format);
+ pFontInfo->fontAscent = pcfGetINT32(file, format);
+ pFontInfo->fontDescent = pcfGetINT32(file, format);
+ pFontInfo->maxOverlap = pcfGetINT32(file, format);
+ if (IS_EOF(file)) goto Bail;
+ if (!pcfGetMetric(file, format, &pFontInfo->minbounds))
+ goto Bail;
+ if (!pcfGetMetric(file, format, &pFontInfo->maxbounds))
+ goto Bail;
+ if (PCF_FORMAT_MATCH(format, PCF_ACCEL_W_INKBOUNDS)) {
+ if (!pcfGetMetric(file, format, &pFontInfo->ink_minbounds))
+ goto Bail;
+ if (!pcfGetMetric(file, format, &pFontInfo->ink_maxbounds))
+ goto Bail;
+ } else {
+ pFontInfo->ink_minbounds = pFontInfo->minbounds;
+ pFontInfo->ink_maxbounds = pFontInfo->maxbounds;
+ }
+ return TRUE;
+Bail:
+ return FALSE;
+}
+
+int
+pcfReadFont(FontPtr pFont, FontFilePtr file,
+ int bit, int byte, int glyph, int scan)
+{
+ CARD32 format;
+ CARD32 size;
+ BitmapFontPtr bitmapFont = 0;
+ int i;
+ PCFTablePtr tables = 0;
+ int ntables;
+ int nmetrics;
+ int nbitmaps;
+ int sizebitmaps;
+ int nink_metrics;
+ CharInfoPtr metrics = 0;
+ xCharInfo *ink_metrics = 0;
+ char *bitmaps = 0;
+ CharInfoPtr **encoding = 0;
+ int nencoding = 0;
+ int encodingOffset;
+ CARD32 bitmapSizes[GLYPHPADOPTIONS];
+ CARD32 *offsets = 0;
+ Bool hasBDFAccelerators;
+
+ pFont->info.nprops = 0;
+ pFont->info.props = 0;
+ if (!(tables = pcfReadTOC(file, &ntables)))
+ goto Bail;
+
+ /* properties */
+
+ if (!pcfGetProperties(&pFont->info, file, tables, ntables))
+ goto Bail;
+
+ /* Use the old accelerators if no BDF accelerators are in the file */
+
+ hasBDFAccelerators = pcfHasType (tables, ntables, PCF_BDF_ACCELERATORS);
+ if (!hasBDFAccelerators)
+ if (!pcfGetAccel (&pFont->info, file, tables, ntables, PCF_ACCELERATORS))
+ goto Bail;
+
+ /* metrics */
+
+ if (!pcfSeekToType(file, tables, ntables, PCF_METRICS, &format, &size)) {
+ goto Bail;
+ }
+ format = pcfGetLSB32(file);
+ if (!PCF_FORMAT_MATCH(format, PCF_DEFAULT_FORMAT) &&
+ !PCF_FORMAT_MATCH(format, PCF_COMPRESSED_METRICS)) {
+ goto Bail;
+ }
+ if (PCF_FORMAT_MATCH(format, PCF_DEFAULT_FORMAT))
+ nmetrics = pcfGetINT32(file, format);
+ else
+ nmetrics = pcfGetINT16(file, format);
+ if (IS_EOF(file)) goto Bail;
+ if (nmetrics < 0 || nmetrics > INT32_MAX / sizeof(CharInfoRec)) {
+ pcfError("pcfReadFont(): invalid file format\n");
+ goto Bail;
+ }
+ metrics = (CharInfoPtr) xalloc(nmetrics * sizeof(CharInfoRec));
+ if (!metrics) {
+ pcfError("pcfReadFont(): Couldn't allocate metrics (%d*%d)\n", nmetrics, sizeof(CharInfoRec));
+ goto Bail;
+ }
+ for (i = 0; i < nmetrics; i++)
+ if (PCF_FORMAT_MATCH(format, PCF_DEFAULT_FORMAT)) {
+ if (!pcfGetMetric(file, format, &(metrics + i)->metrics))
+ goto Bail;
+ } else {
+ if (!pcfGetCompressedMetric(file, format, &(metrics + i)->metrics))
+ goto Bail;
+ }
+
+ /* bitmaps */
+
+ if (!pcfSeekToType(file, tables, ntables, PCF_BITMAPS, &format, &size))
+ goto Bail;
+ format = pcfGetLSB32(file);
+ if (!PCF_FORMAT_MATCH(format, PCF_DEFAULT_FORMAT))
+ goto Bail;
+
+ nbitmaps = pcfGetINT32(file, format);
+ if (nbitmaps != nmetrics || IS_EOF(file))
+ goto Bail;
+ /* nmetrics is already ok, so nbitmap also is */
+ offsets = (CARD32 *) xalloc(nbitmaps * sizeof(CARD32));
+ if (!offsets) {
+ pcfError("pcfReadFont(): Couldn't allocate offsets (%d*%d)\n", nbitmaps, sizeof(CARD32));
+ goto Bail;
+ }
+ for (i = 0; i < nbitmaps; i++) {
+ offsets[i] = pcfGetINT32(file, format);
+ if (IS_EOF(file)) goto Bail;
+ }
+
+ for (i = 0; i < GLYPHPADOPTIONS; i++) {
+ bitmapSizes[i] = pcfGetINT32(file, format);
+ if (IS_EOF(file)) goto Bail;
+ if (bitmapSizes[i] < 0) goto Bail;
+ }
+
+ sizebitmaps = bitmapSizes[PCF_GLYPH_PAD_INDEX(format)];
+ /* guard against completely empty font */
+ bitmaps = xalloc(sizebitmaps ? sizebitmaps : 1);
+ if (!bitmaps) {
+ pcfError("pcfReadFont(): Couldn't allocate bitmaps (%d)\n", sizebitmaps ? sizebitmaps : 1);
+ goto Bail;
+ }
+ FontFileRead(file, bitmaps, sizebitmaps);
+ if (IS_EOF(file)) goto Bail;
+ position += sizebitmaps;
+
+ if (PCF_BIT_ORDER(format) != bit)
+ BitOrderInvert((unsigned char *)bitmaps, sizebitmaps);
+ if ((PCF_BYTE_ORDER(format) == PCF_BIT_ORDER(format)) != (bit == byte)) {
+ switch (bit == byte ? PCF_SCAN_UNIT(format) : scan) {
+ case 1:
+ break;
+ case 2:
+ TwoByteSwap((unsigned char *)bitmaps, sizebitmaps);
+ break;
+ case 4:
+ FourByteSwap((unsigned char *)bitmaps, sizebitmaps);
+ break;
+ }
+ }
+ if (PCF_GLYPH_PAD(format) != glyph) {
+ char *padbitmaps;
+ int sizepadbitmaps;
+ int old,
+ new;
+ xCharInfo *metric;
+
+ sizepadbitmaps = bitmapSizes[PCF_SIZE_TO_INDEX(glyph)];
+ padbitmaps = (char *) xalloc(sizepadbitmaps);
+ if (!padbitmaps) {
+ pcfError("pcfReadFont(): Couldn't allocate padbitmaps (%d)\n", sizepadbitmaps);
+ goto Bail;
+ }
+ new = 0;
+ for (i = 0; i < nbitmaps; i++) {
+ old = offsets[i];
+ metric = &metrics[i].metrics;
+ offsets[i] = new;
+ new += RepadBitmap(bitmaps + old, padbitmaps + new,
+ PCF_GLYPH_PAD(format), glyph,
+ metric->rightSideBearing - metric->leftSideBearing,
+ metric->ascent + metric->descent);
+ }
+ xfree(bitmaps);
+ bitmaps = padbitmaps;
+ }
+ for (i = 0; i < nbitmaps; i++)
+ metrics[i].bits = bitmaps + offsets[i];
+
+ xfree(offsets);
+ offsets = NULL;
+
+ /* ink metrics ? */
+
+ ink_metrics = NULL;
+ if (pcfSeekToType(file, tables, ntables, PCF_INK_METRICS, &format, &size)) {
+ format = pcfGetLSB32(file);
+ if (!PCF_FORMAT_MATCH(format, PCF_DEFAULT_FORMAT) &&
+ !PCF_FORMAT_MATCH(format, PCF_COMPRESSED_METRICS)) {
+ goto Bail;
+ }
+ if (PCF_FORMAT_MATCH(format, PCF_DEFAULT_FORMAT))
+ nink_metrics = pcfGetINT32(file, format);
+ else
+ nink_metrics = pcfGetINT16(file, format);
+ if (IS_EOF(file)) goto Bail;
+ if (nink_metrics != nmetrics)
+ goto Bail;
+ /* nmetrics already checked */
+ ink_metrics = (xCharInfo *) xalloc(nink_metrics * sizeof(xCharInfo));
+ if (!ink_metrics) {
+ pcfError("pcfReadFont(): Couldn't allocate ink_metrics (%d*%d)\n", nink_metrics, sizeof(xCharInfo));
+ goto Bail;
+ }
+ for (i = 0; i < nink_metrics; i++)
+ if (PCF_FORMAT_MATCH(format, PCF_DEFAULT_FORMAT)) {
+ if (!pcfGetMetric(file, format, ink_metrics + i))
+ goto Bail;
+ } else {
+ if (!pcfGetCompressedMetric(file, format, ink_metrics + i))
+ goto Bail;
+ }
+ }
+
+ /* encoding */
+
+ if (!pcfSeekToType(file, tables, ntables, PCF_BDF_ENCODINGS, &format, &size))
+ goto Bail;
+ format = pcfGetLSB32(file);
+ if (!PCF_FORMAT_MATCH(format, PCF_DEFAULT_FORMAT))
+ goto Bail;
+
+ pFont->info.firstCol = pcfGetINT16(file, format);
+ pFont->info.lastCol = pcfGetINT16(file, format);
+ pFont->info.firstRow = pcfGetINT16(file, format);
+ pFont->info.lastRow = pcfGetINT16(file, format);
+ pFont->info.defaultCh = pcfGetINT16(file, format);
+ if (IS_EOF(file)) goto Bail;
+ if (pFont->info.firstCol > pFont->info.lastCol ||
+ pFont->info.firstRow > pFont->info.lastRow ||
+ pFont->info.lastCol-pFont->info.firstCol > 255) goto Bail;
+
+ nencoding = (pFont->info.lastCol - pFont->info.firstCol + 1) *
+ (pFont->info.lastRow - pFont->info.firstRow + 1);
+
+ encoding = (CharInfoPtr **) xcalloc(NUM_SEGMENTS(nencoding),
+ sizeof(CharInfoPtr*));
+ if (!encoding) {
+ pcfError("pcfReadFont(): Couldn't allocate encoding (%d*%d)\n", nencoding, sizeof(CharInfoPtr));
+ goto Bail;
+ }
+
+ pFont->info.allExist = TRUE;
+ for (i = 0; i < nencoding; i++) {
+ encodingOffset = pcfGetINT16(file, format);
+ if (IS_EOF(file)) goto Bail;
+ if (encodingOffset == 0xFFFF) {
+ pFont->info.allExist = FALSE;
+ } else {
+ if(!encoding[SEGMENT_MAJOR(i)]) {
+ encoding[SEGMENT_MAJOR(i)]=
+ (CharInfoPtr*)xcalloc(BITMAP_FONT_SEGMENT_SIZE,
+ sizeof(CharInfoPtr));
+ if(!encoding[SEGMENT_MAJOR(i)])
+ goto Bail;
+ }
+ ACCESSENCODINGL(encoding, i) = metrics + encodingOffset;
+ }
+ }
+
+ /* BDF style accelerators (i.e. bounds based on encoded glyphs) */
+
+ if (hasBDFAccelerators)
+ if (!pcfGetAccel (&pFont->info, file, tables, ntables, PCF_BDF_ACCELERATORS))
+ goto Bail;
+
+ bitmapFont = (BitmapFontPtr) xalloc(sizeof *bitmapFont);
+ if (!bitmapFont) {
+ pcfError("pcfReadFont(): Couldn't allocate bitmapFont (%d)\n", sizeof *bitmapFont);
+ goto Bail;
+ }
+
+ bitmapFont->version_num = PCF_FILE_VERSION;
+ bitmapFont->num_chars = nmetrics;
+ bitmapFont->num_tables = ntables;
+ bitmapFont->metrics = metrics;
+ bitmapFont->ink_metrics = ink_metrics;
+ bitmapFont->bitmaps = bitmaps;
+ bitmapFont->encoding = encoding;
+ bitmapFont->pDefault = (CharInfoPtr) 0;
+ if (pFont->info.defaultCh != (unsigned short) NO_SUCH_CHAR) {
+ unsigned int r,
+ c,
+ cols;
+
+ r = pFont->info.defaultCh >> 8;
+ c = pFont->info.defaultCh & 0xFF;
+ if (pFont->info.firstRow <= r && r <= pFont->info.lastRow &&
+ pFont->info.firstCol <= c && c <= pFont->info.lastCol) {
+ cols = pFont->info.lastCol - pFont->info.firstCol + 1;
+ r = r - pFont->info.firstRow;
+ c = c - pFont->info.firstCol;
+ bitmapFont->pDefault = ACCESSENCODING(encoding, r * cols + c);
+ }
+ }
+ bitmapFont->bitmapExtra = (BitmapExtraPtr) 0;
+ pFont->fontPrivate = (pointer) bitmapFont;
+ pFont->get_glyphs = bitmapGetGlyphs;
+ pFont->get_metrics = bitmapGetMetrics;
+ pFont->unload_font = pcfUnloadFont;
+ pFont->unload_glyphs = NULL;
+ pFont->bit = bit;
+ pFont->byte = byte;
+ pFont->glyph = glyph;
+ pFont->scan = scan;
+ xfree(tables);
+ return Successful;
+Bail:
+ xfree(ink_metrics);
+ if(encoding) {
+ for(i=0; i<NUM_SEGMENTS(nencoding); i++)
+ xfree(encoding[i]);
+ }
+ xfree(encoding);
+ xfree(bitmaps);
+ xfree(metrics);
+ xfree(pFont->info.props);
+ pFont->info.nprops = 0;
+ pFont->info.props = 0;
+ xfree (pFont->info.isStringProp);
+ xfree(bitmapFont);
+ xfree(tables);
+ xfree(offsets);
+ return AllocError;
+}
+
+int
+pcfReadFontInfo(FontInfoPtr pFontInfo, FontFilePtr file)
+{
+ PCFTablePtr tables;
+ int ntables;
+ CARD32 format;
+ CARD32 size;
+ int nencoding;
+ Bool hasBDFAccelerators;
+
+ pFontInfo->isStringProp = NULL;
+ pFontInfo->props = NULL;
+ pFontInfo->nprops = 0;
+
+ if (!(tables = pcfReadTOC(file, &ntables)))
+ goto Bail;
+
+ /* properties */
+
+ if (!pcfGetProperties(pFontInfo, file, tables, ntables))
+ goto Bail;
+
+ /* Use the old accelerators if no BDF accelerators are in the file */
+
+ hasBDFAccelerators = pcfHasType (tables, ntables, PCF_BDF_ACCELERATORS);
+ if (!hasBDFAccelerators)
+ if (!pcfGetAccel (pFontInfo, file, tables, ntables, PCF_ACCELERATORS))
+ goto Bail;
+
+ /* encoding */
+
+ if (!pcfSeekToType(file, tables, ntables, PCF_BDF_ENCODINGS, &format, &size))
+ goto Bail;
+ format = pcfGetLSB32(file);
+ if (!PCF_FORMAT_MATCH(format, PCF_DEFAULT_FORMAT))
+ goto Bail;
+
+ pFontInfo->firstCol = pcfGetINT16(file, format);
+ pFontInfo->lastCol = pcfGetINT16(file, format);
+ pFontInfo->firstRow = pcfGetINT16(file, format);
+ pFontInfo->lastRow = pcfGetINT16(file, format);
+ pFontInfo->defaultCh = pcfGetINT16(file, format);
+ if (IS_EOF(file)) goto Bail;
+ if (pFontInfo->firstCol > pFontInfo->lastCol ||
+ pFontInfo->firstRow > pFontInfo->lastRow ||
+ pFontInfo->lastCol-pFontInfo->firstCol > 255) goto Bail;
+
+ nencoding = (pFontInfo->lastCol - pFontInfo->firstCol + 1) *
+ (pFontInfo->lastRow - pFontInfo->firstRow + 1);
+
+ pFontInfo->allExist = TRUE;
+ while (nencoding--) {
+ if (pcfGetINT16(file, format) == 0xFFFF)
+ pFontInfo->allExist = FALSE;
+ if (IS_EOF(file)) goto Bail;
+ }
+ if (IS_EOF(file)) goto Bail;
+
+ /* BDF style accelerators (i.e. bounds based on encoded glyphs) */
+
+ if (hasBDFAccelerators)
+ if (!pcfGetAccel (pFontInfo, file, tables, ntables, PCF_BDF_ACCELERATORS))
+ goto Bail;
+
+ xfree(tables);
+ return Successful;
+Bail:
+ pFontInfo->nprops = 0;
+ xfree (pFontInfo->props);
+ xfree (pFontInfo->isStringProp);
+ xfree(tables);
+ return AllocError;
+}
+
+static void
+pcfUnloadFont(FontPtr pFont)
+{
+ BitmapFontPtr bitmapFont;
+ int i,nencoding;
+
+ bitmapFont = (BitmapFontPtr) pFont->fontPrivate;
+ xfree(bitmapFont->ink_metrics);
+ if(bitmapFont->encoding) {
+ nencoding = (pFont->info.lastCol - pFont->info.firstCol + 1) *
+ (pFont->info.lastRow - pFont->info.firstRow + 1);
+ for(i=0; i<NUM_SEGMENTS(nencoding); i++)
+ xfree(bitmapFont->encoding[i]);
+ }
+ xfree(bitmapFont->encoding);
+ xfree(bitmapFont->bitmaps);
+ xfree(bitmapFont->metrics);
+ xfree(pFont->info.isStringProp);
+ xfree(pFont->info.props);
+ xfree(bitmapFont);
+ DestroyFontRec(pFont);
+}
+
+int
+pmfReadFont(FontPtr pFont, FontFilePtr file,
+ int bit, int byte, int glyph, int scan)
+{
+ CARD32 format;
+ CARD32 size;
+ BitmapFontPtr bitmapFont = 0;
+ int i;
+ PCFTablePtr tables = 0;
+ int ntables;
+ int nmetrics;
+ int sizebitmaps;
+ int nink_metrics;
+ CharInfoPtr metrics = 0;
+ xCharInfo *ink_metrics = 0;
+ char *bitmaps = 0;
+ CharInfoPtr **encoding = 0;
+ int nencoding = 0;
+ int encodingOffset;
+ Bool hasBDFAccelerators;
+ CharInfoPtr pci;
+
+ pFont->info.nprops = 0;
+ pFont->info.props = 0;
+
+ if (!(tables = pcfReadTOC(file, &ntables)))
+ goto Bail;
+
+ /* properties */
+
+ if (!pcfGetProperties(&pFont->info, file, tables, ntables))
+ goto Bail;
+
+ /* Use the old accelerators if no BDF accelerators are in the file */
+
+ hasBDFAccelerators = pcfHasType (tables, ntables, PCF_BDF_ACCELERATORS);
+ if (!hasBDFAccelerators)
+ if (!pcfGetAccel (&pFont->info, file, tables, ntables, PCF_ACCELERATORS))
+ goto Bail;
+
+ /* metrics */
+
+ if (!pcfSeekToType(file, tables, ntables, PCF_METRICS, &format, &size)) {
+ goto Bail;
+ }
+ format = pcfGetLSB32(file);
+ if (!PCF_FORMAT_MATCH(format, PCF_DEFAULT_FORMAT) &&
+ !PCF_FORMAT_MATCH(format, PCF_COMPRESSED_METRICS)) {
+ goto Bail;
+ }
+ if (PCF_FORMAT_MATCH(format, PCF_DEFAULT_FORMAT))
+ nmetrics = pcfGetINT32(file, format);
+ else
+ nmetrics = pcfGetINT16(file, format);
+ if (IS_EOF(file)) goto Bail;
+ if (nmetrics < 0 || nmetrics > INT32_MAX / sizeof(CharInfoRec)) {
+ pcfError("pmfReadFont(): invalid file format\n");
+ goto Bail;
+ }
+ metrics = (CharInfoPtr) xalloc(nmetrics * sizeof(CharInfoRec));
+ if (!metrics) {
+ pcfError("pmfReadFont(): Couldn't allocate metrics (%d*%d)\n", nmetrics, sizeof(CharInfoRec));
+ goto Bail;
+ }
+ for (i = 0; i < nmetrics; i++)
+ if (PCF_FORMAT_MATCH(format, PCF_DEFAULT_FORMAT)) {
+ if (!pcfGetMetric(file, format, &(metrics + i)->metrics))
+ goto Bail;
+ } else {
+ if (!pcfGetCompressedMetric(file, format, &(metrics + i)->metrics))
+ goto Bail;
+ }
+
+ /* Set the bitmaps to all point to the same zero filled array
+ * that is the size of the largest bitmap.
+ */
+
+ pci = metrics;
+ sizebitmaps = 0;
+ for (i = 0; i < nmetrics; i++)
+ {
+ sizebitmaps = MAX(sizebitmaps,BYTES_FOR_GLYPH(pci, glyph));
+ pci++;
+ }
+
+#ifdef FONTMODULE
+ sizebitmaps = 1024; /* Default - we xalloc the size anyway */
+#else
+ sizebitmaps = BUFSIZ;
+#endif
+ /* guard against completely empty font */
+ bitmaps = (char *) xalloc(sizebitmaps);
+ if (!bitmaps) {
+ pcfError("pmfReadFont(): Couldn't allocate bitmaps (%d)\n", sizebitmaps);
+ goto Bail;
+ }
+
+ memset(bitmaps,0,sizebitmaps);
+ for (i = 0; i < nmetrics; i++)
+ metrics[i].bits = bitmaps;
+
+ /* ink metrics ? */
+
+ ink_metrics = NULL;
+ if (pcfSeekToType(file, tables, ntables, PCF_INK_METRICS, &format, &size)) {
+ format = pcfGetLSB32(file);
+ if (!PCF_FORMAT_MATCH(format, PCF_DEFAULT_FORMAT) &&
+ !PCF_FORMAT_MATCH(format, PCF_COMPRESSED_METRICS)) {
+ goto Bail;
+ }
+ if (PCF_FORMAT_MATCH(format, PCF_DEFAULT_FORMAT))
+ nink_metrics = pcfGetINT32(file, format);
+ else
+ nink_metrics = pcfGetINT16(file, format);
+ if (nink_metrics != nmetrics)
+ goto Bail;
+ if (IS_EOF(file)) goto Bail;
+ ink_metrics = (xCharInfo *) xalloc(nink_metrics * sizeof(xCharInfo));
+ if (!ink_metrics) {
+ pcfError("pmfReadFont(): Couldn't allocate ink_metrics (%d*%d)\n", nink_metrics, sizeof(xCharInfo));
+ goto Bail;
+ }
+ for (i = 0; i < nink_metrics; i++)
+ if (PCF_FORMAT_MATCH(format, PCF_DEFAULT_FORMAT)) {
+ if (!pcfGetMetric(file, format, ink_metrics + i))
+ goto Bail;
+ } else {
+ if (!pcfGetCompressedMetric(file, format, ink_metrics + i))
+ goto Bail;
+ }
+ }
+
+ /* encoding */
+
+ if (!pcfSeekToType(file, tables, ntables, PCF_BDF_ENCODINGS, &format, &size))
+ goto Bail;
+ format = pcfGetLSB32(file);
+ if (!PCF_FORMAT_MATCH(format, PCF_DEFAULT_FORMAT))
+ goto Bail;
+
+ pFont->info.firstCol = pcfGetINT16(file, format);
+ pFont->info.lastCol = pcfGetINT16(file, format);
+ pFont->info.firstRow = pcfGetINT16(file, format);
+ pFont->info.lastRow = pcfGetINT16(file, format);
+ pFont->info.defaultCh = pcfGetINT16(file, format);
+ if (IS_EOF(file)) goto Bail;
+
+ nencoding = (pFont->info.lastCol - pFont->info.firstCol + 1) *
+ (pFont->info.lastRow - pFont->info.firstRow + 1);
+
+ encoding = (CharInfoPtr **) xcalloc(NUM_SEGMENTS(nencoding),
+ sizeof(CharInfoPtr*));
+ if (!encoding) {
+ pcfError("pmfReadFont(): Couldn't allocate encoding (%d*%d)\n", nencoding, sizeof(CharInfoPtr));
+ goto Bail;
+ }
+ pFont->info.allExist = TRUE;
+ for (i = 0; i < nencoding; i++) {
+ encodingOffset = pcfGetINT16(file, format);
+ if (IS_EOF(file)) goto Bail;
+ if (encodingOffset == 0xFFFF) {
+ pFont->info.allExist = FALSE;
+ } else {
+ if(!encoding[SEGMENT_MAJOR(i)]) {
+ encoding[SEGMENT_MAJOR(i)]=
+ (CharInfoPtr*)xcalloc(BITMAP_FONT_SEGMENT_SIZE,
+ sizeof(CharInfoPtr));
+ if(!encoding[SEGMENT_MAJOR(i)])
+ goto Bail;
+ }
+ ACCESSENCODINGL(encoding, i) = metrics + encodingOffset;
+ }
+ }
+ if (IS_EOF(file)) goto Bail;
+
+ /* BDF style accelerators (i.e. bounds based on encoded glyphs) */
+
+ if (hasBDFAccelerators)
+ if (!pcfGetAccel (&pFont->info, file, tables, ntables, PCF_BDF_ACCELERATORS))
+ goto Bail;
+
+ bitmapFont = (BitmapFontPtr) xalloc(sizeof *bitmapFont);
+ if (!bitmapFont) {
+ pcfError("pmfReadFont(): Couldn't allocate bitmapFont (%d)\n", sizeof *bitmapFont);
+ goto Bail;
+ }
+
+ bitmapFont->version_num = PCF_FILE_VERSION;
+ bitmapFont->num_chars = nmetrics;
+ bitmapFont->num_tables = ntables;
+ bitmapFont->metrics = metrics;
+ bitmapFont->ink_metrics = ink_metrics;
+ bitmapFont->bitmaps = bitmaps;
+ bitmapFont->encoding = encoding;
+ bitmapFont->pDefault = (CharInfoPtr) 0;
+ if (pFont->info.defaultCh != (unsigned short) NO_SUCH_CHAR) {
+ unsigned int r,
+ c,
+ cols;
+
+ r = pFont->info.defaultCh >> 8;
+ c = pFont->info.defaultCh & 0xFF;
+ if (pFont->info.firstRow <= r && r <= pFont->info.lastRow &&
+ pFont->info.firstCol <= c && c <= pFont->info.lastCol) {
+ cols = pFont->info.lastCol - pFont->info.firstCol + 1;
+ r = r - pFont->info.firstRow;
+ c = c - pFont->info.firstCol;
+ bitmapFont->pDefault = ACCESSENCODING(encoding, r * cols + c);
+ }
+ }
+ bitmapFont->bitmapExtra = (BitmapExtraPtr) 0;
+ pFont->fontPrivate = (pointer) bitmapFont;
+ pFont->get_glyphs = bitmapGetGlyphs;
+ pFont->get_metrics = bitmapGetMetrics;
+ pFont->unload_font = pcfUnloadFont;
+ pFont->unload_glyphs = NULL;
+ pFont->bit = bit;
+ pFont->byte = byte;
+ pFont->glyph = glyph;
+ pFont->scan = scan;
+ xfree(tables);
+ return Successful;
+Bail:
+ xfree(ink_metrics);
+ if(encoding) {
+ for(i=0; i<NUM_SEGMENTS(nencoding); i++)
+ xfree(encoding[i]);
+ }
+ xfree(encoding);
+ xfree(bitmaps);
+ xfree(metrics);
+ xfree(pFont->info.props);
+ pFont->info.nprops = 0;
+ pFont->info.props = 0;
+ xfree (pFont->info.isStringProp);
+ xfree(bitmapFont);
+ xfree(tables);
+ return AllocError;
+}
diff --git a/libXfont/src/bitmap/pcfwrite.c b/libXfont/src/bitmap/pcfwrite.c
new file mode 100644
index 000000000..8d5e9425f
--- /dev/null
+++ b/libXfont/src/bitmap/pcfwrite.c
@@ -0,0 +1,468 @@
+/* $Xorg: pcfwrite.c,v 1.5 2001/02/09 02:04:02 xorgcvs Exp $ */
+/*
+
+Copyright 1990, 1994, 1998 The Open Group
+
+Permission to use, copy, modify, distribute, and sell this software and its
+documentation for any purpose is hereby granted without fee, provided that
+the above copyright notice appear in all copies and that both that
+copyright notice and this permission notice appear in supporting
+documentation.
+
+The above copyright notice and this permission notice shall be included
+in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+IN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR
+OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of The Open Group shall
+not be used in advertising or otherwise to promote the sale, use or
+other dealings in this Software without prior written authorization
+from The Open Group.
+
+*/
+/* $XFree86: xc/lib/font/bitmap/pcfwrite.c,v 1.11 2003/11/17 22:20:22 dawes Exp $ */
+
+/*
+ * Author: Keith Packard, MIT X Consortium
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <X11/fonts/fntfilst.h>
+#include <X11/fonts/bitmap.h>
+#include <X11/fonts/pcf.h>
+
+/* Write PCF font files */
+
+static CARD32 current_position;
+
+static int
+pcfWrite(FontFilePtr file, char *b, int c)
+{
+ current_position += c;
+ return FontFileWrite(file, b, c);
+}
+
+static int
+pcfPutLSB32(FontFilePtr file, int c)
+{
+ current_position += 4;
+ (void) FontFilePutc(c, file);
+ (void) FontFilePutc(c >> 8, file);
+ (void) FontFilePutc(c >> 16, file);
+ return FontFilePutc(c >> 24, file);
+}
+
+static int
+pcfPutINT32(FontFilePtr file, CARD32 format, int c)
+{
+ current_position += 4;
+ if (PCF_BYTE_ORDER(format) == MSBFirst) {
+ (void) FontFilePutc(c >> 24, file);
+ (void) FontFilePutc(c >> 16, file);
+ (void) FontFilePutc(c >> 8, file);
+ return FontFilePutc(c, file);
+ } else {
+ (void) FontFilePutc(c, file);
+ (void) FontFilePutc(c >> 8, file);
+ (void) FontFilePutc(c >> 16, file);
+ return FontFilePutc(c >> 24, file);
+ }
+}
+
+static int
+pcfPutINT16(FontFilePtr file, CARD32 format, int c)
+{
+ current_position += 2;
+ if (PCF_BYTE_ORDER(format) == MSBFirst) {
+ (void) FontFilePutc(c >> 8, file);
+ return FontFilePutc(c, file);
+ } else {
+ (void) FontFilePutc(c, file);
+ return FontFilePutc(c >> 8, file);
+ }
+}
+
+/*ARGSUSED*/
+static int
+pcfPutINT8(FontFilePtr file, CARD32 format, int c)
+{
+ current_position += 1;
+ return FontFilePutc(c, file);
+}
+
+static void
+pcfWriteTOC(FontFilePtr file, PCFTablePtr table, int count)
+{
+ CARD32 version;
+ int i;
+
+ version = PCF_FILE_VERSION;
+ pcfPutLSB32(file, version);
+ pcfPutLSB32(file, count);
+ for (i = 0; i < count; i++) {
+ pcfPutLSB32(file, table->type);
+ pcfPutLSB32(file, table->format);
+ pcfPutLSB32(file, table->size);
+ pcfPutLSB32(file, table->offset);
+ table++;
+ }
+}
+
+static void
+pcfPutCompressedMetric(FontFilePtr file, CARD32 format, xCharInfo *metric)
+{
+ pcfPutINT8(file, format, metric->leftSideBearing + 0x80);
+ pcfPutINT8(file, format, metric->rightSideBearing + 0x80);
+ pcfPutINT8(file, format, metric->characterWidth + 0x80);
+ pcfPutINT8(file, format, metric->ascent + 0x80);
+ pcfPutINT8(file, format, metric->descent + 0x80);
+}
+
+static void
+pcfPutMetric(FontFilePtr file, CARD32 format, xCharInfo *metric)
+{
+ pcfPutINT16(file, format, metric->leftSideBearing);
+ pcfPutINT16(file, format, metric->rightSideBearing);
+ pcfPutINT16(file, format, metric->characterWidth);
+ pcfPutINT16(file, format, metric->ascent);
+ pcfPutINT16(file, format, metric->descent);
+ pcfPutINT16(file, format, metric->attributes);
+}
+
+static void
+pcfPutBitmap(FontFilePtr file, CARD32 format, CharInfoPtr pCI)
+{
+ int count;
+ unsigned char *bits;
+
+ count = BYTES_FOR_GLYPH(pCI, PCF_GLYPH_PAD(format));
+ bits = (unsigned char *) pCI->bits;
+ current_position += count;
+ while (count--)
+ FontFilePutc(*bits++, file);
+}
+
+static void
+pcfPutAccel(FontFilePtr file, CARD32 format, FontInfoPtr pFontInfo)
+{
+ pcfPutINT8(file, format, pFontInfo->noOverlap);
+ pcfPutINT8(file, format, pFontInfo->constantMetrics);
+ pcfPutINT8(file, format, pFontInfo->terminalFont);
+ pcfPutINT8(file, format, pFontInfo->constantWidth);
+ pcfPutINT8(file, format, pFontInfo->inkInside);
+ pcfPutINT8(file, format, pFontInfo->inkMetrics);
+ pcfPutINT8(file, format, pFontInfo->drawDirection);
+ pcfPutINT8(file, format, 0);
+ pcfPutINT32(file, format, pFontInfo->fontAscent);
+ pcfPutINT32(file, format, pFontInfo->fontDescent);
+ pcfPutINT32(file, format, pFontInfo->maxOverlap);
+ pcfPutMetric(file, format, &pFontInfo->minbounds);
+ pcfPutMetric(file, format, &pFontInfo->maxbounds);
+ if (PCF_FORMAT_MATCH(format, PCF_ACCEL_W_INKBOUNDS)) {
+ pcfPutMetric(file, format, &pFontInfo->ink_minbounds);
+ pcfPutMetric(file, format, &pFontInfo->ink_maxbounds);
+ }
+}
+
+#define S32 4
+#define S16 2
+#define S8 1
+
+#define Pad(s) (RoundUp(s) - (s))
+#define RoundUp(s) (((s) + 3) & ~3)
+
+#define Compressable(i) (-128 <= (i) && (i) <= 127)
+
+#define CanCompressMetric(m) (Compressable((m)->leftSideBearing) && \
+ Compressable((m)->rightSideBearing) && \
+ Compressable((m)->characterWidth) && \
+ Compressable((m)->ascent) && \
+ Compressable((m)->descent) && \
+ (m)->attributes == 0)
+
+#define CanCompressMetrics(min,max) (CanCompressMetric(min) && CanCompressMetric(max))
+
+static char *
+pcfNameForAtom(Atom a)
+{
+ return NameForAtom(a);
+}
+
+int
+pcfWriteFont(FontPtr pFont, FontFilePtr file)
+{
+ PCFTableRec tables[32],
+ *table;
+ CARD32 mask,
+ bit;
+ int ntables;
+ int size;
+ CARD32 format;
+ int i;
+ int cur_table;
+ int prop_string_size;
+ int glyph_string_size;
+ xCharInfo *minbounds,
+ *maxbounds;
+ xCharInfo *ink_minbounds,
+ *ink_maxbounds;
+ BitmapFontPtr bitmapFont;
+ int nencodings = 0;
+ int header_size;
+ FontPropPtr offsetProps;
+ int prop_pad = 0;
+ char *atom_name;
+ int glyph;
+ CARD32 offset;
+
+ bitmapFont = (BitmapFontPtr) pFont->fontPrivate;
+ if (bitmapFont->bitmapExtra) {
+ minbounds = &bitmapFont->bitmapExtra->info.minbounds;
+ maxbounds = &bitmapFont->bitmapExtra->info.maxbounds;
+ ink_minbounds = &bitmapFont->bitmapExtra->info.ink_minbounds;
+ ink_maxbounds = &bitmapFont->bitmapExtra->info.ink_maxbounds;
+ } else {
+ minbounds = &pFont->info.minbounds;
+ maxbounds = &pFont->info.maxbounds;
+ ink_minbounds = &pFont->info.ink_minbounds;
+ ink_maxbounds = &pFont->info.ink_maxbounds;
+ }
+ offsetProps = (FontPropPtr) xalloc(pFont->info.nprops * sizeof(FontPropRec));
+ if (!offsetProps) {
+ pcfError("pcfWriteFont(): Couldn't allocate offsetProps (%d*%d)", pFont->info.nprops, sizeof(FontPropRec));
+ return AllocError;
+ }
+ prop_string_size = 0;
+ for (i = 0; i < pFont->info.nprops; i++) {
+ offsetProps[i].name = prop_string_size;
+ prop_string_size += strlen(pcfNameForAtom(pFont->info.props[i].name)) + 1;
+ if (pFont->info.isStringProp[i]) {
+ offsetProps[i].value = prop_string_size;
+ prop_string_size += strlen(pcfNameForAtom(pFont->info.props[i].value)) + 1;
+ } else
+ offsetProps[i].value = pFont->info.props[i].value;
+ }
+ format = PCF_FORMAT(pFont->bit, pFont->byte, pFont->glyph, pFont->scan);
+ mask = 0xFFFFFFF;
+ ntables = 0;
+ table = tables;
+ while (mask) {
+ bit = lowbit(mask);
+ mask &= ~bit;
+ table->type = bit;
+ switch (bit) {
+ case PCF_PROPERTIES:
+ table->format = PCF_DEFAULT_FORMAT | format;
+ size = S32 + S32 + (S32 + S8 + S32) * pFont->info.nprops;
+ prop_pad = Pad(size);
+ table->size = RoundUp(size) + S32 +
+ RoundUp(prop_string_size);
+ table++;
+ break;
+ case PCF_ACCELERATORS:
+ if (bitmapFont->bitmapExtra->info.inkMetrics)
+ table->format = PCF_ACCEL_W_INKBOUNDS | format;
+ else
+ table->format = PCF_DEFAULT_FORMAT | format;
+ table->size = 100;
+ table++;
+ break;
+ case PCF_METRICS:
+ if (CanCompressMetrics(minbounds, maxbounds)) {
+ table->format = PCF_COMPRESSED_METRICS | format;
+ size = S32 + S16 + bitmapFont->num_chars * (5 * S8);
+ table->size = RoundUp(size);
+ } else {
+ table->format = PCF_DEFAULT_FORMAT | format;
+ table->size = S32 + S32 + bitmapFont->num_chars * (6 * S16);
+ }
+ table++;
+ break;
+ case PCF_BITMAPS:
+ table->format = PCF_DEFAULT_FORMAT | format;
+ size = S32 + S32 + bitmapFont->num_chars * S32 +
+ GLYPHPADOPTIONS * S32 +
+ bitmapFont->bitmapExtra->bitmapsSizes[PCF_GLYPH_PAD_INDEX(format)];
+ table->size = RoundUp(size);
+ table++;
+ break;
+ case PCF_INK_METRICS:
+ if (bitmapFont->ink_metrics) {
+ if (CanCompressMetrics(ink_minbounds, ink_maxbounds)) {
+ table->format = PCF_COMPRESSED_METRICS | format;
+ size = S32 + S16 + bitmapFont->num_chars * (5 * S8);
+ table->size = RoundUp(size);
+ } else {
+ table->format = PCF_DEFAULT_FORMAT | format;
+ table->size = S32 + S32 + bitmapFont->num_chars * (6 * S16);
+ }
+ table++;
+ }
+ break;
+ case PCF_BDF_ENCODINGS:
+ table->format = PCF_DEFAULT_FORMAT | format;
+ nencodings = (pFont->info.lastRow - pFont->info.firstRow + 1) *
+ (pFont->info.lastCol - pFont->info.firstCol + 1);
+ size = S32 + 5 * S16 + nencodings * S16;
+ table->size = RoundUp(size);
+ table++;
+ break;
+ case PCF_SWIDTHS:
+ table->format = PCF_DEFAULT_FORMAT | format;
+ table->size = S32 + S32 + bitmapFont->num_chars * S32;
+ table++;
+ break;
+ case PCF_GLYPH_NAMES:
+ table->format = PCF_DEFAULT_FORMAT | format;
+ glyph_string_size = 0;
+ for (i = 0; i < bitmapFont->num_chars; i++)
+ glyph_string_size += strlen(pcfNameForAtom(bitmapFont->bitmapExtra->glyphNames[i])) + 1;
+ table->size = S32 + S32 + bitmapFont->num_chars * S32 +
+ S32 + RoundUp(glyph_string_size);
+ table++;
+ break;
+ case PCF_BDF_ACCELERATORS:
+ if (pFont->info.inkMetrics)
+ table->format = PCF_ACCEL_W_INKBOUNDS | format;
+ else
+ table->format = PCF_DEFAULT_FORMAT | format;
+ table->size = 100;
+ table++;
+ break;
+ }
+ }
+ ntables = table - tables;
+ offset = 0;
+ header_size = S32 + S32 + ntables * (4 * S32);
+ offset = header_size;
+ for (cur_table = 0, table = tables;
+ cur_table < ntables;
+ cur_table++, table++) {
+ table->offset = offset;
+ offset += table->size;
+ }
+ current_position = 0;
+ pcfWriteTOC(file, tables, ntables);
+ for (cur_table = 0, table = tables;
+ cur_table < ntables;
+ cur_table++, table++) {
+ if (current_position > table->offset) {
+ printf("can't go backwards... %d > %d\n",
+ (int)current_position, (int)table->offset);
+ xfree(offsetProps);
+ return BadFontName;
+ }
+ while (current_position < table->offset)
+ pcfPutINT8(file, format, '\0');
+ pcfPutLSB32(file, table->format);
+ switch (table->type) {
+ case PCF_PROPERTIES:
+ pcfPutINT32(file, format, pFont->info.nprops);
+ for (i = 0; i < pFont->info.nprops; i++) {
+ pcfPutINT32(file, format, offsetProps[i].name);
+ pcfPutINT8(file, format, pFont->info.isStringProp[i]);
+ pcfPutINT32(file, format, offsetProps[i].value);
+ }
+ for (i = 0; i < prop_pad; i++)
+ pcfPutINT8(file, format, 0);
+ pcfPutINT32(file, format, prop_string_size);
+ for (i = 0; i < pFont->info.nprops; i++) {
+ atom_name = pcfNameForAtom(pFont->info.props[i].name);
+ pcfWrite(file, atom_name, strlen(atom_name) + 1);
+ if (pFont->info.isStringProp[i]) {
+ atom_name = pcfNameForAtom(pFont->info.props[i].value);
+ pcfWrite(file, atom_name, strlen(atom_name) + 1);
+ }
+ }
+ break;
+ case PCF_ACCELERATORS:
+ pcfPutAccel(file, table->format, &bitmapFont->bitmapExtra->info);
+ break;
+ case PCF_METRICS:
+ if (PCF_FORMAT_MATCH(table->format, PCF_COMPRESSED_METRICS)) {
+ pcfPutINT16(file, format, bitmapFont->num_chars);
+ for (i = 0; i < bitmapFont->num_chars; i++)
+ pcfPutCompressedMetric(file, format, &bitmapFont->metrics[i].metrics);
+ } else {
+ pcfPutINT32(file, format, bitmapFont->num_chars);
+ for (i = 0; i < bitmapFont->num_chars; i++)
+ pcfPutMetric(file, format, &bitmapFont->metrics[i].metrics);
+ }
+ break;
+ case PCF_BITMAPS:
+ pcfPutINT32(file, format, bitmapFont->num_chars);
+ glyph = PCF_GLYPH_PAD(format);
+ offset = 0;
+ for (i = 0; i < bitmapFont->num_chars; i++) {
+ pcfPutINT32(file, format, offset);
+ offset += BYTES_FOR_GLYPH(&bitmapFont->metrics[i], glyph);
+ }
+ for (i = 0; i < GLYPHPADOPTIONS; i++) {
+ pcfPutINT32(file, format,
+ bitmapFont->bitmapExtra->bitmapsSizes[i]);
+ }
+ for (i = 0; i < bitmapFont->num_chars; i++)
+ pcfPutBitmap(file, format, &bitmapFont->metrics[i]);
+ break;
+ case PCF_INK_METRICS:
+ if (PCF_FORMAT_MATCH(table->format, PCF_COMPRESSED_METRICS)) {
+ pcfPutINT16(file, format, bitmapFont->num_chars);
+ for (i = 0; i < bitmapFont->num_chars; i++)
+ pcfPutCompressedMetric(file, format, &bitmapFont->ink_metrics[i]);
+ } else {
+ pcfPutINT32(file, format, bitmapFont->num_chars);
+ for (i = 0; i < bitmapFont->num_chars; i++)
+ pcfPutMetric(file, format, &bitmapFont->ink_metrics[i]);
+ }
+ break;
+ case PCF_BDF_ENCODINGS:
+ pcfPutINT16(file, format, pFont->info.firstCol);
+ pcfPutINT16(file, format, pFont->info.lastCol);
+ pcfPutINT16(file, format, pFont->info.firstRow);
+ pcfPutINT16(file, format, pFont->info.lastRow);
+ pcfPutINT16(file, format, pFont->info.defaultCh);
+ for (i = 0; i < nencodings; i++) {
+ if (ACCESSENCODING(bitmapFont->encoding,i))
+ pcfPutINT16(file, format,
+ ACCESSENCODING(bitmapFont->encoding, i) -
+ bitmapFont->metrics);
+ else
+ pcfPutINT16(file, format, 0xFFFF);
+ }
+ break;
+ case PCF_SWIDTHS:
+ pcfPutINT32(file, format, bitmapFont->num_chars);
+ for (i = 0; i < bitmapFont->num_chars; i++)
+ pcfPutINT32(file, format, bitmapFont->bitmapExtra->sWidths[i]);
+ break;
+ case PCF_GLYPH_NAMES:
+ pcfPutINT32(file, format, bitmapFont->num_chars);
+ offset = 0;
+ for (i = 0; i < bitmapFont->num_chars; i++) {
+ pcfPutINT32(file, format, offset);
+ offset += strlen(pcfNameForAtom(bitmapFont->bitmapExtra->glyphNames[i])) + 1;
+ }
+ pcfPutINT32(file, format, offset);
+ for (i = 0; i < bitmapFont->num_chars; i++) {
+ atom_name = pcfNameForAtom(bitmapFont->bitmapExtra->glyphNames[i]);
+ pcfWrite(file, atom_name, strlen(atom_name) + 1);
+ }
+ break;
+ case PCF_BDF_ACCELERATORS:
+ pcfPutAccel(file, table->format, &pFont->info);
+ break;
+ }
+ }
+
+ xfree(offsetProps);
+ return Successful;
+}
diff --git a/libXfont/src/bitmap/snfread.c b/libXfont/src/bitmap/snfread.c
new file mode 100644
index 000000000..f48e2d8a7
--- /dev/null
+++ b/libXfont/src/bitmap/snfread.c
@@ -0,0 +1,514 @@
+/* $Xorg: snfread.c,v 1.5 2001/02/09 02:04:02 xorgcvs Exp $ */
+/************************************************************************
+Copyright 1989 by Digital Equipment Corporation, Maynard, Massachusetts.
+
+ All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and its
+documentation for any purpose and without fee is hereby granted,
+provided that the above copyright notice appear in all copies and that
+both that copyright notice and this permission notice appear in
+supporting documentation, and that the name of Digital not be
+used in advertising or publicity pertaining to distribution of the
+software without specific, written prior permission.
+
+DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
+ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
+DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
+ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
+ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+SOFTWARE.
+
+************************************************************************/
+
+/*
+
+Copyright 1994, 1998 The Open Group
+
+Permission to use, copy, modify, distribute, and sell this software and its
+documentation for any purpose is hereby granted without fee, provided that
+the above copyright notice appear in all copies and that both that
+copyright notice and this permission notice appear in supporting
+documentation.
+
+The above copyright notice and this permission notice shall be included
+in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+IN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR
+OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of The Open Group shall
+not be used in advertising or otherwise to promote the sale, use or
+other dealings in this Software without prior written authorization
+from The Open Group.
+
+*/
+/* $XFree86: xc/lib/font/bitmap/snfread.c,v 1.12 2003/11/17 22:20:22 dawes Exp $ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#ifndef FONTMODULE
+#include <ctype.h>
+#endif
+
+#include <X11/fonts/fntfilst.h>
+#include <X11/fonts/bitmap.h>
+#include "snfstr.h"
+
+#include <stdarg.h>
+
+static void
+snfError(const char* message, ...)
+{
+ va_list args;
+
+ va_start(args, message);
+
+ fprintf(stderr, "SNF Error: ");
+ vfprintf(stderr, message, args);
+ va_end(args);
+}
+
+static void snfUnloadFont(FontPtr pFont);
+
+static int
+snfReadCharInfo(FontFilePtr file, CharInfoPtr charInfo, char *base)
+{
+ snfCharInfoRec snfCharInfo;
+
+#define Width(m) ((m).rightSideBearing - (m).leftSideBearing)
+#define Height(m) ((m).ascent + (m).descent)
+
+ if (FontFileRead(file, (char *) &snfCharInfo, sizeof snfCharInfo) !=
+ sizeof(snfCharInfo)) {
+ return BadFontName;
+ }
+ charInfo->metrics = snfCharInfo.metrics;
+ if (snfCharInfo.exists)
+ charInfo->bits = base + snfCharInfo.byteOffset;
+ else
+ charInfo->bits = 0;
+ return Successful;
+}
+
+static int
+snfReadxCharInfo(FontFilePtr file, xCharInfo *charInfo)
+{
+ snfCharInfoRec snfCharInfo;
+
+ if (FontFileRead(file, (char *) &snfCharInfo, sizeof snfCharInfo) !=
+ sizeof(snfCharInfo)) {
+ return BadFontName;
+ }
+ *charInfo = snfCharInfo.metrics;
+ return Successful;
+}
+
+static void
+snfCopyInfo(snfFontInfoPtr snfInfo, FontInfoPtr pFontInfo)
+{
+ pFontInfo->firstCol = snfInfo->firstCol;
+ pFontInfo->lastCol = snfInfo->lastCol;
+ pFontInfo->firstRow = snfInfo->firstRow;
+ pFontInfo->lastRow = snfInfo->lastRow;
+ pFontInfo->defaultCh = snfInfo->chDefault;
+ pFontInfo->noOverlap = snfInfo->noOverlap;
+ pFontInfo->terminalFont = snfInfo->terminalFont;
+ pFontInfo->constantMetrics = snfInfo->constantMetrics;
+ pFontInfo->constantWidth = snfInfo->constantWidth;
+ pFontInfo->inkInside = snfInfo->inkInside;
+ pFontInfo->inkMetrics = snfInfo->inkMetrics;
+ pFontInfo->allExist = snfInfo->allExist;
+ pFontInfo->drawDirection = snfInfo->drawDirection;
+ pFontInfo->anamorphic = FALSE;
+ pFontInfo->cachable = TRUE;
+ pFontInfo->maxOverlap = 0;
+ pFontInfo->minbounds = snfInfo->minbounds.metrics;
+ pFontInfo->maxbounds = snfInfo->maxbounds.metrics;
+ pFontInfo->fontAscent = snfInfo->fontAscent;
+ pFontInfo->fontDescent = snfInfo->fontDescent;
+ pFontInfo->nprops = snfInfo->nProps;
+}
+
+static int
+snfReadProps(snfFontInfoPtr snfInfo, FontInfoPtr pFontInfo, FontFilePtr file)
+{
+ char *strings;
+ FontPropPtr pfp;
+ snfFontPropPtr psnfp;
+ char *propspace;
+ int bytestoalloc;
+ int i;
+
+ bytestoalloc = snfInfo->nProps * sizeof(snfFontPropRec) +
+ BYTESOFSTRINGINFO(snfInfo);
+ propspace = (char *) xalloc(bytestoalloc);
+ if (!propspace) {
+ snfError("snfReadProps(): Couldn't allocate propspace (%d)\n", bytestoalloc);
+ return AllocError;
+ }
+
+ if (FontFileRead(file, propspace, bytestoalloc) != bytestoalloc) {
+ xfree(propspace);
+ return BadFontName;
+ }
+ psnfp = (snfFontPropPtr) propspace;
+
+ strings = propspace + BYTESOFPROPINFO(snfInfo);
+
+ for (i = 0, pfp = pFontInfo->props; i < snfInfo->nProps; i++, pfp++, psnfp++) {
+ pfp->name = MakeAtom(&strings[psnfp->name],
+ (unsigned) strlen(&strings[psnfp->name]), 1);
+ pFontInfo->isStringProp[i] = psnfp->indirect;
+ if (psnfp->indirect)
+ pfp->value = (INT32) MakeAtom(&strings[psnfp->value],
+ (unsigned) strlen(&strings[psnfp->value]), 1);
+ else
+ pfp->value = psnfp->value;
+ }
+
+ xfree(propspace);
+ return Successful;
+}
+
+static int
+snfReadHeader(snfFontInfoPtr snfInfo, FontFilePtr file)
+{
+ if (FontFileRead(file, (char *) snfInfo, sizeof *snfInfo) != sizeof *snfInfo)
+ return BadFontName;
+
+ if (snfInfo->version1 != FONT_FILE_VERSION ||
+ snfInfo->version2 != FONT_FILE_VERSION)
+ return BadFontName;
+ return Successful;
+}
+
+static int snf_set;
+static int snf_bit, snf_byte, snf_glyph, snf_scan;
+
+void
+SnfSetFormat (int bit, int byte, int glyph, int scan)
+{
+ snf_bit = bit;
+ snf_byte = byte;
+ snf_glyph = glyph;
+ snf_scan = scan;
+ snf_set = 1;
+}
+
+static void
+SnfGetFormat (int *bit, int *byte, int *glyph, int *scan)
+{
+ if (!snf_set)
+ FontDefaultFormat (&snf_bit, &snf_byte, &snf_glyph, &snf_scan);
+ *bit = snf_bit;
+ *byte = snf_byte;
+ *glyph = snf_glyph;
+ *scan = snf_scan;
+}
+
+int
+snfReadFont(FontPtr pFont, FontFilePtr file,
+ int bit, int byte, int glyph, int scan)
+{
+ snfFontInfoRec fi;
+ unsigned bytestoalloc;
+ int i, j;
+ char *fontspace;
+ BitmapFontPtr bitmapFont;
+ int num_chars;
+ int bitmapsSize;
+ int ret;
+ int metrics_off;
+ int encoding_off;
+ int props_off;
+ int isStringProp_off;
+ int ink_off;
+ char *bitmaps;
+ int def_bit, def_byte, def_glyph, def_scan;
+
+ ret = snfReadHeader(&fi, file);
+ if (ret != Successful)
+ return ret;
+
+ SnfGetFormat (&def_bit, &def_byte, &def_glyph, &def_scan);
+
+ /*
+ * we'll allocate one chunk of memory and split it among the various parts
+ * of the font:
+ *
+ * BitmapFontRec CharInfoRec's Glyphs Encoding DIX Properties Ink CharInfoRec's
+ *
+ * If the glyphpad is not the same as the font file, then the glyphs
+ * are allocated separately, to be later realloc'ed when we know
+ * how big to make them.
+ */
+
+ bitmapsSize = BYTESOFGLYPHINFO(&fi);
+ num_chars = n2dChars(&fi);
+ bytestoalloc = sizeof(BitmapFontRec); /* bitmapFont */
+ metrics_off = bytestoalloc;
+ bytestoalloc += num_chars * sizeof(CharInfoRec); /* metrics */
+ encoding_off = bytestoalloc;
+ bytestoalloc += NUM_SEGMENTS(num_chars) * sizeof(CharInfoPtr**);
+ /* encoding */
+ props_off = bytestoalloc;
+ bytestoalloc += fi.nProps * sizeof(FontPropRec); /* props */
+ isStringProp_off = bytestoalloc;
+ bytestoalloc += fi.nProps * sizeof(char); /* isStringProp */
+ bytestoalloc = (bytestoalloc + 3) & ~3;
+ ink_off = bytestoalloc;
+ if (fi.inkMetrics)
+ bytestoalloc += num_chars * sizeof(xCharInfo); /* ink_metrics */
+
+ fontspace = (char *) xalloc(bytestoalloc);
+ if (!fontspace) {
+ snfError("snfReadFont(): Couldn't allocate fontspace (%d)\n", bytestoalloc);
+ return AllocError;
+ }
+ bitmaps = (char *) xalloc (bitmapsSize);
+ if (!bitmaps)
+ {
+ snfError("snfReadFont(): Couldn't allocate bitmaps (%d)\n", bitmapsSize);
+ xfree (fontspace);
+ return AllocError;
+ }
+ /*
+ * now fix up pointers
+ */
+
+ bitmapFont = (BitmapFontPtr) fontspace;
+ bitmapFont->num_chars = num_chars;
+ bitmapFont->metrics = (CharInfoPtr) (fontspace + metrics_off);
+ bitmapFont->encoding = (CharInfoPtr **) (fontspace + encoding_off);
+ bitmapFont->bitmaps = bitmaps;
+ bitmapFont->pDefault = NULL;
+ bitmapFont->bitmapExtra = NULL;
+ pFont->info.props = (FontPropPtr) (fontspace + props_off);
+ pFont->info.isStringProp = (char *) (fontspace + isStringProp_off);
+ if (fi.inkMetrics)
+ bitmapFont->ink_metrics = (xCharInfo *) (fontspace + ink_off);
+ else
+ bitmapFont->ink_metrics = 0;
+
+ /*
+ * read the CharInfo
+ */
+
+ ret = Successful;
+ memset(bitmapFont->encoding, 0,
+ NUM_SEGMENTS(num_chars)*sizeof(CharInfoPtr*));
+ for (i = 0; ret == Successful && i < num_chars; i++) {
+ ret = snfReadCharInfo(file, &bitmapFont->metrics[i], bitmaps);
+ if (bitmapFont->metrics[i].bits) {
+ if (!bitmapFont->encoding[SEGMENT_MAJOR(i)]) {
+ bitmapFont->encoding[SEGMENT_MAJOR(i)]=
+ (CharInfoPtr*)xcalloc(BITMAP_FONT_SEGMENT_SIZE,
+ sizeof(CharInfoPtr));
+ if (!bitmapFont->encoding[SEGMENT_MAJOR(i)]) {
+ ret = AllocError;
+ break;
+ }
+ }
+ ACCESSENCODINGL(bitmapFont->encoding,i) = &bitmapFont->metrics[i];
+ }
+ }
+
+ if (ret != Successful) {
+ xfree(bitmaps);
+ if(bitmapFont->encoding) {
+ for(j=0; j<SEGMENT_MAJOR(i); j++)
+ xfree(bitmapFont->encoding[i]);
+ }
+ xfree(fontspace);
+ return ret;
+ }
+ /*
+ * read the glyphs
+ */
+
+ if (FontFileRead(file, bitmaps, bitmapsSize) != bitmapsSize) {
+ xfree(bitmaps);
+ xfree(fontspace);
+ return BadFontName;
+ }
+
+ if (def_bit != bit)
+ BitOrderInvert((unsigned char *)bitmaps, bitmapsSize);
+ if ((def_byte == def_bit) != (bit == byte)) {
+ switch (bit == byte ? def_scan : scan) {
+ case 1:
+ break;
+ case 2:
+ TwoByteSwap((unsigned char *)bitmaps, bitmapsSize);
+ break;
+ case 4:
+ FourByteSwap((unsigned char *)bitmaps, bitmapsSize);
+ break;
+ }
+ }
+ if (def_glyph != glyph) {
+ char *padbitmaps;
+ int sizepadbitmaps;
+ int sizechar;
+ CharInfoPtr metric;
+
+ sizepadbitmaps = 0;
+ metric = bitmapFont->metrics;
+ for (i = 0; i < num_chars; i++)
+ {
+ if (metric->bits)
+ sizepadbitmaps += BYTES_FOR_GLYPH(metric,glyph);
+ metric++;
+ }
+ padbitmaps = (char *) xalloc(sizepadbitmaps);
+ if (!padbitmaps) {
+ snfError("snfReadFont(): Couldn't allocate padbitmaps (%d)\n", sizepadbitmaps);
+ xfree (bitmaps);
+ xfree (fontspace);
+ return AllocError;
+ }
+ metric = bitmapFont->metrics;
+ bitmapFont->bitmaps = padbitmaps;
+ for (i = 0; i < num_chars; i++) {
+ sizechar = RepadBitmap(metric->bits, padbitmaps,
+ def_glyph, glyph,
+ metric->metrics.rightSideBearing -
+ metric->metrics.leftSideBearing,
+ metric->metrics.ascent + metric->metrics.descent);
+ metric->bits = padbitmaps;
+ padbitmaps += sizechar;
+ metric++;
+ }
+ xfree(bitmaps);
+ }
+
+ /* now read and atom'ize properties */
+
+ ret = snfReadProps(&fi, &pFont->info, file);
+ if (ret != Successful) {
+ xfree(fontspace);
+ return ret;
+ }
+ snfCopyInfo(&fi, &pFont->info);
+
+ /* finally, read the ink metrics if the exist */
+
+ if (fi.inkMetrics) {
+ ret = Successful;
+ ret = snfReadxCharInfo(file, &pFont->info.ink_minbounds);
+ ret = snfReadxCharInfo(file, &pFont->info.ink_maxbounds);
+ for (i = 0; ret == Successful && i < num_chars; i++)
+ ret = snfReadxCharInfo(file, &bitmapFont->ink_metrics[i]);
+ if (ret != Successful) {
+ xfree(fontspace);
+ return ret;
+ }
+ } else {
+ pFont->info.ink_minbounds = pFont->info.minbounds;
+ pFont->info.ink_maxbounds = pFont->info.maxbounds;
+ }
+
+ if (pFont->info.defaultCh != (unsigned short) NO_SUCH_CHAR) {
+ unsigned int r,
+ c,
+ cols;
+
+ r = pFont->info.defaultCh >> 8;
+ c = pFont->info.defaultCh & 0xFF;
+ if (pFont->info.firstRow <= r && r <= pFont->info.lastRow &&
+ pFont->info.firstCol <= c && c <= pFont->info.lastCol) {
+ cols = pFont->info.lastCol - pFont->info.firstCol + 1;
+ r = r - pFont->info.firstRow;
+ c = c - pFont->info.firstCol;
+ bitmapFont->pDefault = &bitmapFont->metrics[r * cols + c];
+ }
+ }
+ bitmapFont->bitmapExtra = (BitmapExtraPtr) 0;
+ pFont->fontPrivate = (pointer) bitmapFont;
+ pFont->get_glyphs = bitmapGetGlyphs;
+ pFont->get_metrics = bitmapGetMetrics;
+ pFont->unload_font = snfUnloadFont;
+ pFont->unload_glyphs = NULL;
+ pFont->bit = bit;
+ pFont->byte = byte;
+ pFont->glyph = glyph;
+ pFont->scan = scan;
+ return Successful;
+}
+
+int
+snfReadFontInfo(FontInfoPtr pFontInfo, FontFilePtr file)
+{
+ int ret;
+ snfFontInfoRec fi;
+ int bytestoskip;
+ int num_chars;
+
+ ret = snfReadHeader(&fi, file);
+ if (ret != Successful)
+ return ret;
+ snfCopyInfo(&fi, pFontInfo);
+
+ pFontInfo->props = (FontPropPtr) xalloc(fi.nProps * sizeof(FontPropRec));
+ if (!pFontInfo->props) {
+ snfError("snfReadFontInfo(): Couldn't allocate props (%d*%d)\n", fi.nProps, sizeof(FontPropRec));
+ return AllocError;
+ }
+ pFontInfo->isStringProp = (char *) xalloc(fi.nProps * sizeof(char));
+ if (!pFontInfo->isStringProp) {
+ snfError("snfReadFontInfo(): Couldn't allocate isStringProp (%d*%d)\n", fi.nProps, sizeof(char));
+ xfree(pFontInfo->props);
+ return AllocError;
+ }
+ num_chars = n2dChars(&fi);
+ bytestoskip = num_chars * sizeof(snfCharInfoRec); /* charinfos */
+ bytestoskip += BYTESOFGLYPHINFO(&fi);
+ (void)FontFileSkip(file, bytestoskip);
+
+ ret = snfReadProps(&fi, pFontInfo, file);
+ if (ret != Successful) {
+ xfree(pFontInfo->props);
+ xfree(pFontInfo->isStringProp);
+ return ret;
+ }
+ if (fi.inkMetrics) {
+ ret = snfReadxCharInfo(file, &pFontInfo->ink_minbounds);
+ if (ret != Successful) {
+ xfree(pFontInfo->props);
+ xfree(pFontInfo->isStringProp);
+ return ret;
+ }
+ ret = snfReadxCharInfo(file, &pFontInfo->ink_maxbounds);
+ if (ret != Successful) {
+ xfree(pFontInfo->props);
+ xfree(pFontInfo->isStringProp);
+ return ret;
+ }
+ } else {
+ pFontInfo->ink_minbounds = pFontInfo->minbounds;
+ pFontInfo->ink_maxbounds = pFontInfo->maxbounds;
+ }
+ return Successful;
+
+}
+
+static void
+snfUnloadFont(FontPtr pFont)
+{
+ BitmapFontPtr bitmapFont;
+
+ bitmapFont = (BitmapFontPtr) pFont->fontPrivate;
+ xfree (bitmapFont->bitmaps);
+ xfree (bitmapFont);
+ DestroyFontRec (pFont);
+}
+
diff --git a/libXfont/src/bitmap/snfstr.h b/libXfont/src/bitmap/snfstr.h
new file mode 100644
index 000000000..531b19c62
--- /dev/null
+++ b/libXfont/src/bitmap/snfstr.h
@@ -0,0 +1,184 @@
+/* $Xorg: snfstr.h,v 1.4 2001/02/09 02:04:02 xorgcvs Exp $ */
+/***********************************************************
+Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts.
+
+ All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and its
+documentation for any purpose and without fee is hereby granted,
+provided that the above copyright notice appear in all copies and that
+both that copyright notice and this permission notice appear in
+supporting documentation, and that the name of Digital not be
+used in advertising or publicity pertaining to distribution of the
+software without specific, written prior permission.
+
+DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
+ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
+DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
+ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
+ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+SOFTWARE.
+
+******************************************************************/
+
+/*
+
+Copyright 1994, 1998 The Open Group
+
+Permission to use, copy, modify, distribute, and sell this software and its
+documentation for any purpose is hereby granted without fee, provided that
+the above copyright notice appear in all copies and that both that
+copyright notice and this permission notice appear in supporting
+documentation.
+
+The above copyright notice and this permission notice shall be included
+in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+IN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR
+OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of The Open Group shall
+not be used in advertising or otherwise to promote the sale, use or
+other dealings in this Software without prior written authorization
+from The Open Group.
+
+*/
+/* $XFree86: xc/lib/font/bitmap/snfstr.h,v 1.5 2001/12/14 19:56:47 dawes Exp $ */
+
+#ifndef SNFSTR_H
+#define SNFSTR_H 1
+
+#include <X11/fonts/fntfilio.h>
+
+/*-
+ * This file describes the Server Natural Font format.
+ * SNF fonts are both CPU-dependent and frame buffer bit order dependent.
+ * This file is used by:
+ * 1) the server, to hold font information read out of font files.
+ * 2) font converters
+ *
+ * Each font file contains the following
+ * data structures, with no padding in-between.
+ *
+ * 1) The XFONTINFO structure
+ * hand-padded to a two-short boundary.
+ * maxbounds.byteoffset is the total number of bytes in the
+ * glpyh array
+ * maxbounds.bitOffset is thetotal width of the unpadded font
+ *
+ * 2) The XCHARINFO array
+ * indexed directly with character codes, both on disk
+ * and in memory.
+ *
+ * 3) Character glyphs
+ * padded in the server-natural way, and
+ * ordered in the device-natural way.
+ * End of glyphs padded to 32-bit boundary.
+ *
+ * 4) nProps font properties
+ *
+ * 5) a sequence of null-terminated strings, for font properties
+ */
+
+#define FONT_FILE_VERSION 4
+
+typedef struct _snfFontProp {
+ CARD32 name; /* offset of string */
+ INT32 value; /* number or offset of string */
+ Bool indirect; /* value is a string offset */
+} snfFontPropRec;
+
+/*
+ * the following macro definitions describe a font file image in memory
+ */
+#define ADDRCharInfoRec( pfi) \
+ ((snfCharInfoRec *) &(pfi)[1])
+
+#define ADDRCHARGLYPHS( pfi) \
+ (((char *) &(pfi)[1]) + BYTESOFCHARINFO(pfi))
+
+/*
+ * pad out glyphs to a CARD32 boundary
+ */
+#define ADDRXFONTPROPS( pfi) \
+ ((snfFontPropRec *) ((char *)ADDRCHARGLYPHS( pfi) + BYTESOFGLYPHINFO(pfi)))
+
+#define ADDRSTRINGTAB( pfi) \
+ ((char *)ADDRXFONTPROPS( pfi) + BYTESOFPROPINFO(pfi))
+
+#define n2dChars(pfi) (((pfi)->lastRow - (pfi)->firstRow + 1) * \
+ ((pfi)->lastCol - (pfi)->firstCol + 1))
+#define BYTESOFFONTINFO(pfi) (sizeof(snfFontInfoRec))
+#define BYTESOFCHARINFO(pfi) (sizeof(snfCharInfoRec) * n2dChars(pfi))
+#define BYTESOFPROPINFO(pfi) (sizeof(snfFontPropRec) * (pfi)->nProps)
+#define BYTESOFSTRINGINFO(pfi) ((pfi)->lenStrings)
+#define BYTESOFGLYPHINFO(pfi) (((pfi)->maxbounds.byteOffset+3) & ~0x3)
+#define BYTESOFINKINFO(pfi) (sizeof(snfCharInfoRec) * n2dChars(pfi))
+
+typedef struct _snfFontProp *snfFontPropPtr;
+typedef struct _snfCharInfo *snfCharInfoPtr;
+typedef struct _snfFontInfo *snfFontInfoPtr;
+
+typedef struct _snfCharInfo {
+ xCharInfo metrics; /* info preformatted for Queries */
+ unsigned byteOffset:24; /* byte offset of the raster from pGlyphs */
+ unsigned exists:1; /* true iff glyph exists for this char */
+ unsigned pad:7; /* must be zero for now */
+} snfCharInfoRec;
+
+typedef struct _snfFontInfo {
+ unsigned int version1; /* version stamp */
+ unsigned int allExist;
+ unsigned int drawDirection;
+ unsigned int noOverlap; /* true if:
+ * max(rightSideBearing-characterWidth) <=
+ * minbounds->metrics.leftSideBearing */
+ unsigned int constantMetrics;
+ unsigned int terminalFont; /* Should be deprecated! true if: constant
+ * metrics && leftSideBearing == 0 &&
+ * rightSideBearing == characterWidth &&
+ * ascent == fontAscent && descent ==
+ * fontDescent */
+ unsigned int linear:1; /* true if firstRow == lastRow */
+ unsigned int constantWidth:1; /* true if
+ * minbounds->metrics.characterWidth
+ * ==
+ * maxbounds->metrics.characterWidth */
+ unsigned int inkInside:1; /* true if for all defined glyphs:
+ * leftSideBearing >= 0 && rightSideBearing <=
+ * characterWidth && -fontDescent <= ascent <=
+ * fontAscent && -fontAscent <= descent <=
+ * fontDescent */
+ unsigned int inkMetrics:1; /* ink metrics != bitmap metrics */
+ /* used with terminalFont */
+ /* see font's pInk{CI,Min,Max} */
+ unsigned int padding:28;
+ unsigned int firstCol;
+ unsigned int lastCol;
+ unsigned int firstRow;
+ unsigned int lastRow;
+ unsigned int nProps;
+ unsigned int lenStrings; /* length in bytes of string table */
+ unsigned int chDefault; /* default character */
+ int fontDescent; /* minimum for quality typography */
+ int fontAscent; /* minimum for quality typography */
+ snfCharInfoRec minbounds; /* MIN of glyph metrics over all chars */
+ snfCharInfoRec maxbounds; /* MAX of glyph metrics over all chars */
+ unsigned int pixDepth; /* intensity bits per pixel */
+ unsigned int glyphSets; /* number of sets of glyphs, for sub-pixel
+ * positioning */
+ unsigned int version2; /* version stamp double-check */
+} snfFontInfoRec;
+
+extern void SnfSetFormat ( int bit, int byte, int glyph, int scan );
+extern int snfReadFont ( FontPtr pFont, FontFilePtr file,
+ int bit, int byte, int glyph, int scan );
+extern int snfReadFontInfo ( FontInfoPtr pFontInfo, FontFilePtr file );
+
+#endif /* SNFSTR_H */
diff --git a/libXfont/src/builtins/Makefile.am b/libXfont/src/builtins/Makefile.am
new file mode 100644
index 000000000..b203fda2f
--- /dev/null
+++ b/libXfont/src/builtins/Makefile.am
@@ -0,0 +1,17 @@
+INCLUDES = \
+ -I${top_srcdir}/include \
+ -I${top_srcdir}/src/bitmap
+
+AM_CFLAGS = $(XFONT_CFLAGS) $(OS_CFLAGS) $(CWARNFLAGS)
+
+noinst_LTLIBRARIES = libbuiltins.la
+
+libbuiltins_la_SOURCES = \
+ builtin.h \
+ dir.c \
+ file.c \
+ fonts.c \
+ fpe.c \
+ render.c
+
+EXTRA_DIST = buildfont
diff --git a/libXfont/src/builtins/Makefile.in b/libXfont/src/builtins/Makefile.in
new file mode 100644
index 000000000..3d57cfa88
--- /dev/null
+++ b/libXfont/src/builtins/Makefile.in
@@ -0,0 +1,463 @@
+# Makefile.in generated by automake 1.10 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
+# 2003, 2004, 2005, 2006 Free Software Foundation, Inc.
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+@SET_MAKE@
+
+VPATH = @srcdir@
+pkgdatadir = $(datadir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+install_sh_DATA = $(install_sh) -c -m 644
+install_sh_PROGRAM = $(install_sh) -c
+install_sh_SCRIPT = $(install_sh) -c
+INSTALL_HEADER = $(INSTALL_DATA)
+transform = $(program_transform_name)
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+build_triplet = @build@
+host_triplet = @host@
+subdir = src/builtins
+DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/configure.ac
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+ $(ACLOCAL_M4)
+mkinstalldirs = $(install_sh) -d
+CONFIG_HEADER = $(top_builddir)/config.h \
+ $(top_builddir)/include/X11/fonts/fontconf.h
+CONFIG_CLEAN_FILES =
+LTLIBRARIES = $(noinst_LTLIBRARIES)
+libbuiltins_la_LIBADD =
+am_libbuiltins_la_OBJECTS = dir.lo file.lo fonts.lo fpe.lo render.lo
+libbuiltins_la_OBJECTS = $(am_libbuiltins_la_OBJECTS)
+DEFAULT_INCLUDES = -I. -I$(top_builddir) -I$(top_builddir)/include/X11/fonts@am__isrc@
+depcomp = $(SHELL) $(top_srcdir)/depcomp
+am__depfiles_maybe = depfiles
+COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
+ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+LTCOMPILE = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
+ --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \
+ $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+CCLD = $(CC)
+LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
+ --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \
+ $(LDFLAGS) -o $@
+SOURCES = $(libbuiltins_la_SOURCES)
+DIST_SOURCES = $(libbuiltins_la_SOURCES)
+ETAGS = etags
+CTAGS = ctags
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+ACLOCAL = @ACLOCAL@
+AMTAR = @AMTAR@
+AR = @AR@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+CC = @CC@
+CCDEPMODE = @CCDEPMODE@
+CFLAGS = @CFLAGS@
+CHANGELOG_CMD = @CHANGELOG_CMD@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CWARNFLAGS = @CWARNFLAGS@
+CXX = @CXX@
+CXXCPP = @CXXCPP@
+CXXDEPMODE = @CXXDEPMODE@
+CXXFLAGS = @CXXFLAGS@
+CYGPATH_W = @CYGPATH_W@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+ECHO = @ECHO@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+EGREP = @EGREP@
+ENCODINGSDIR = @ENCODINGSDIR@
+EXEEXT = @EXEEXT@
+F77 = @F77@
+FFLAGS = @FFLAGS@
+FREETYPE_CFLAGS = @FREETYPE_CFLAGS@
+FREETYPE_LIBS = @FREETYPE_LIBS@
+FREETYPE_REQUIRES = @FREETYPE_REQUIRES@
+GREP = @GREP@
+INSTALL = @INSTALL@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+LDFLAGS = @LDFLAGS@
+LIBOBJS = @LIBOBJS@
+LIBS = @LIBS@
+LIBTOOL = @LIBTOOL@
+LN_S = @LN_S@
+LTLIBOBJS = @LTLIBOBJS@
+MAKEINFO = @MAKEINFO@
+MATH_LIBS = @MATH_LIBS@
+MKDIR_P = @MKDIR_P@
+OBJEXT = @OBJEXT@
+OS_CFLAGS = @OS_CFLAGS@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+PKG_CONFIG = @PKG_CONFIG@
+RANLIB = @RANLIB@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+STRIP = @STRIP@
+VERSION = @VERSION@
+XFONT_CFLAGS = @XFONT_CFLAGS@
+XFONT_LIBS = @XFONT_LIBS@
+X_GZIP_FONT_COMPRESSION = @X_GZIP_FONT_COMPRESSION@
+Z_LIBS = @Z_LIBS@
+abs_builddir = @abs_builddir@
+abs_srcdir = @abs_srcdir@
+abs_top_builddir = @abs_top_builddir@
+abs_top_srcdir = @abs_top_srcdir@
+ac_ct_CC = @ac_ct_CC@
+ac_ct_CXX = @ac_ct_CXX@
+ac_ct_F77 = @ac_ct_F77@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+am__tar = @am__tar@
+am__untar = @am__untar@
+bindir = @bindir@
+build = @build@
+build_alias = @build_alias@
+build_cpu = @build_cpu@
+build_os = @build_os@
+build_vendor = @build_vendor@
+builddir = @builddir@
+datadir = @datadir@
+datarootdir = @datarootdir@
+distcleancheck_listfiles = @distcleancheck_listfiles@
+docdir = @docdir@
+dvidir = @dvidir@
+exec_prefix = @exec_prefix@
+ft_config = @ft_config@
+host = @host@
+host_alias = @host_alias@
+host_cpu = @host_cpu@
+host_os = @host_os@
+host_vendor = @host_vendor@
+htmldir = @htmldir@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+libdir = @libdir@
+libexecdir = @libexecdir@
+localedir = @localedir@
+localstatedir = @localstatedir@
+mandir = @mandir@
+mkdir_p = @mkdir_p@
+oldincludedir = @oldincludedir@
+pdfdir = @pdfdir@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+psdir = @psdir@
+sbindir = @sbindir@
+sharedstatedir = @sharedstatedir@
+srcdir = @srcdir@
+sysconfdir = @sysconfdir@
+target_alias = @target_alias@
+top_builddir = @top_builddir@
+top_srcdir = @top_srcdir@
+INCLUDES = \
+ -I${top_srcdir}/include \
+ -I${top_srcdir}/src/bitmap
+
+AM_CFLAGS = $(XFONT_CFLAGS) $(OS_CFLAGS) $(CWARNFLAGS)
+noinst_LTLIBRARIES = libbuiltins.la
+libbuiltins_la_SOURCES = \
+ builtin.h \
+ dir.c \
+ file.c \
+ fonts.c \
+ fpe.c \
+ render.c
+
+EXTRA_DIST = buildfont
+all: all-am
+
+.SUFFIXES:
+.SUFFIXES: .c .lo .o .obj
+$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps)
+ @for dep in $?; do \
+ case '$(am__configure_deps)' in \
+ *$$dep*) \
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh \
+ && exit 0; \
+ exit 1;; \
+ esac; \
+ done; \
+ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign src/builtins/Makefile'; \
+ cd $(top_srcdir) && \
+ $(AUTOMAKE) --foreign src/builtins/Makefile
+.PRECIOUS: Makefile
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+ @case '$?' in \
+ *config.status*) \
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
+ *) \
+ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
+ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
+ esac;
+
+$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+
+$(top_srcdir)/configure: $(am__configure_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(ACLOCAL_M4): $(am__aclocal_m4_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+
+clean-noinstLTLIBRARIES:
+ -test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES)
+ @list='$(noinst_LTLIBRARIES)'; for p in $$list; do \
+ dir="`echo $$p | sed -e 's|/[^/]*$$||'`"; \
+ test "$$dir" != "$$p" || dir=.; \
+ echo "rm -f \"$${dir}/so_locations\""; \
+ rm -f "$${dir}/so_locations"; \
+ done
+libbuiltins.la: $(libbuiltins_la_OBJECTS) $(libbuiltins_la_DEPENDENCIES)
+ $(LINK) $(libbuiltins_la_OBJECTS) $(libbuiltins_la_LIBADD) $(LIBS)
+
+mostlyclean-compile:
+ -rm -f *.$(OBJEXT)
+
+distclean-compile:
+ -rm -f *.tab.c
+
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dir.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/file.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fonts.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fpe.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/render.Plo@am__quote@
+
+.c.o:
+@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
+@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(COMPILE) -c $<
+
+.c.obj:
+@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'`
+@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(COMPILE) -c `$(CYGPATH_W) '$<'`
+
+.c.lo:
+@am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
+@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(LTCOMPILE) -c -o $@ $<
+
+mostlyclean-libtool:
+ -rm -f *.lo
+
+clean-libtool:
+ -rm -rf .libs _libs
+
+ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) ' { files[$$0] = 1; } \
+ END { for (i in files) print i; }'`; \
+ mkid -fID $$unique
+tags: TAGS
+
+TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
+ $(TAGS_FILES) $(LISP)
+ tags=; \
+ here=`pwd`; \
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) ' { files[$$0] = 1; } \
+ END { for (i in files) print i; }'`; \
+ if test -z "$(ETAGS_ARGS)$$tags$$unique"; then :; else \
+ test -n "$$unique" || unique=$$empty_fix; \
+ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+ $$tags $$unique; \
+ fi
+ctags: CTAGS
+CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
+ $(TAGS_FILES) $(LISP)
+ tags=; \
+ here=`pwd`; \
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) ' { files[$$0] = 1; } \
+ END { for (i in files) print i; }'`; \
+ test -z "$(CTAGS_ARGS)$$tags$$unique" \
+ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
+ $$tags $$unique
+
+GTAGS:
+ here=`$(am__cd) $(top_builddir) && pwd` \
+ && cd $(top_srcdir) \
+ && gtags -i $(GTAGS_ARGS) $$here
+
+distclean-tags:
+ -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
+
+distdir: $(DISTFILES)
+ @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ list='$(DISTFILES)'; \
+ dist_files=`for file in $$list; do echo $$file; done | \
+ sed -e "s|^$$srcdirstrip/||;t" \
+ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
+ case $$dist_files in \
+ */*) $(MKDIR_P) `echo "$$dist_files" | \
+ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
+ sort -u` ;; \
+ esac; \
+ for file in $$dist_files; do \
+ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
+ if test -d $$d/$$file; then \
+ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
+ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
+ cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \
+ fi; \
+ cp -pR $$d/$$file $(distdir)$$dir || exit 1; \
+ else \
+ test -f $(distdir)/$$file \
+ || cp -p $$d/$$file $(distdir)/$$file \
+ || exit 1; \
+ fi; \
+ done
+check-am: all-am
+check: check-am
+all-am: Makefile $(LTLIBRARIES)
+installdirs:
+install: install-am
+install-exec: install-exec-am
+install-data: install-data-am
+uninstall: uninstall-am
+
+install-am: all-am
+ @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-am
+install-strip:
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ `test -z '$(STRIP)' || \
+ echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
+mostlyclean-generic:
+
+clean-generic:
+
+distclean-generic:
+ -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
+
+maintainer-clean-generic:
+ @echo "This command is intended for maintainers to use"
+ @echo "it deletes files that may require special tools to rebuild."
+clean: clean-am
+
+clean-am: clean-generic clean-libtool clean-noinstLTLIBRARIES \
+ mostlyclean-am
+
+distclean: distclean-am
+ -rm -rf ./$(DEPDIR)
+ -rm -f Makefile
+distclean-am: clean-am distclean-compile distclean-generic \
+ distclean-tags
+
+dvi: dvi-am
+
+dvi-am:
+
+html: html-am
+
+info: info-am
+
+info-am:
+
+install-data-am:
+
+install-dvi: install-dvi-am
+
+install-exec-am:
+
+install-html: install-html-am
+
+install-info: install-info-am
+
+install-man:
+
+install-pdf: install-pdf-am
+
+install-ps: install-ps-am
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-am
+ -rm -rf ./$(DEPDIR)
+ -rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-am
+
+mostlyclean-am: mostlyclean-compile mostlyclean-generic \
+ mostlyclean-libtool
+
+pdf: pdf-am
+
+pdf-am:
+
+ps: ps-am
+
+ps-am:
+
+uninstall-am:
+
+.MAKE: install-am install-strip
+
+.PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \
+ clean-libtool clean-noinstLTLIBRARIES ctags distclean \
+ distclean-compile distclean-generic distclean-libtool \
+ distclean-tags distdir dvi dvi-am html html-am info info-am \
+ install install-am install-data install-data-am install-dvi \
+ install-dvi-am install-exec install-exec-am install-html \
+ install-html-am install-info install-info-am install-man \
+ install-pdf install-pdf-am install-ps install-ps-am \
+ install-strip installcheck installcheck-am installdirs \
+ maintainer-clean maintainer-clean-generic mostlyclean \
+ mostlyclean-compile mostlyclean-generic mostlyclean-libtool \
+ pdf pdf-am ps ps-am tags uninstall uninstall-am
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/libXfont/src/builtins/buildfont b/libXfont/src/builtins/buildfont
new file mode 100644
index 000000000..aa4602ff8
--- /dev/null
+++ b/libXfont/src/builtins/buildfont
@@ -0,0 +1,14 @@
+#!/bin/sh
+#
+# Convert a bdf file into C-code suitable for inclusion in
+# builtin fonts
+#
+FONT=$1
+NAME=$2
+echo 'static const char file_'$NAME'[] = {'
+bdftopcf -p1 -u1 $1 |
+ compress -b 12 |
+ od -b -v -w8 |
+ sed 's/^[0-9]*\( *\)/\1\1\1\1/' |
+ sed 's/\([0-9][0-9]*\)/'"'"'\\\1'"'"',/g'
+echo '};'
diff --git a/libXfont/src/builtins/builtin.h b/libXfont/src/builtins/builtin.h
new file mode 100644
index 000000000..f12f9b0f2
--- /dev/null
+++ b/libXfont/src/builtins/builtin.h
@@ -0,0 +1,64 @@
+/*
+ * Id: builtin.h,v 1.2 1999/11/02 06:16:47 keithp Exp $
+ *
+ * Copyright 1999 SuSE, Inc.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of SuSE not be used in advertising or
+ * publicity pertaining to distribution of the software without specific,
+ * written prior permission. SuSE makes no representations about the
+ * suitability of this software for any purpose. It is provided "as is"
+ * without express or implied warranty.
+ *
+ * SuSE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL SuSE
+ * BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Author: Keith Packard, SuSE, Inc.
+ */
+/* $XFree86: xc/lib/font/builtins/builtin.h,v 1.3 1999/12/30 02:29:49 robin Exp $ */
+
+#include <X11/Xdefs.h>
+#include <X11/fonts/font.h>
+#include <X11/fonts/fontxlfd.h>
+#include <X11/fonts/fntfil.h>
+#include <X11/fonts/fntfilio.h>
+#include <X11/fonts/fntfilst.h>
+
+typedef struct _BuiltinFile {
+ const char *name;
+ int len;
+ const char *bits;
+} BuiltinFileRec, *BuiltinFilePtr;
+
+typedef struct _BuiltinDir {
+ char *file_name;
+ char *font_name;
+} BuiltinDirRec, *BuiltinDirPtr;
+
+typedef struct _BuiltinAlias {
+ char *alias_name;
+ char *font_name;
+} BuiltinAliasRec, *BuiltinAliasPtr;
+
+extern const BuiltinFileRec builtin_files[];
+extern const int builtin_files_count;
+
+extern const BuiltinDirRec builtin_dir[];
+extern const int builtin_dir_count;
+
+extern const BuiltinAliasRec builtin_alias[];
+extern const int builtin_alias_count;
+
+extern FontFilePtr BuiltinFileOpen (char *);
+extern int BuiltinFileClose (BufFilePtr, int);
+extern int BuiltinReadDirectory (char *, FontDirectoryPtr *);
+extern void BuiltinRegisterFontFileFunctions (void);
+
+extern void BuiltinRegisterFpeFunctions (void);
diff --git a/libXfont/src/builtins/dir.c b/libXfont/src/builtins/dir.c
new file mode 100644
index 000000000..dd2ea1a86
--- /dev/null
+++ b/libXfont/src/builtins/dir.c
@@ -0,0 +1,217 @@
+/*
+ * Id: dir.c,v 1.2 1999/11/02 06:16:47 keithp Exp $
+ *
+ * Copyright 1999 SuSE, Inc.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of SuSE not be used in advertising or
+ * publicity pertaining to distribution of the software without specific,
+ * written prior permission. SuSE makes no representations about the
+ * suitability of this software for any purpose. It is provided "as is"
+ * without express or implied warranty.
+ *
+ * SuSE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL SuSE
+ * BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Author: Keith Packard, SuSE, Inc.
+ */
+/* $XFree86: xc/lib/font/builtins/dir.c,v 1.3 1999/12/30 02:29:49 robin Exp $ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "builtin.h"
+
+static BuiltinDirPtr
+BuiltinDirsDup (const BuiltinDirPtr a_dirs,
+ int a_dirs_len)
+{
+ BuiltinDirPtr dirs=NULL ;
+ int i=0 ;
+
+ if (!a_dirs)
+ return NULL ;
+
+ dirs = xcalloc (a_dirs_len, sizeof (BuiltinDirRec)) ;
+ if (!dirs)
+ return NULL ;
+
+ for (i=0; i < a_dirs_len; i++) {
+ int len = strlen (a_dirs[i].file_name) ;
+ dirs[i].file_name = xcalloc (1, len+1) ;
+ memmove (dirs[i].file_name, a_dirs[i].file_name, len);
+ len = strlen (a_dirs[i].font_name) ;
+ dirs[i].font_name = xcalloc (1, len+1) ;
+ memmove (dirs[i].font_name, a_dirs[i].font_name, len);
+ }
+ return dirs ;
+}
+
+/**
+ * Copy a_save back into a_cur
+ * @param a_cur the instance of BuiltinDir to restore
+ * @param a_saved the saved instance of BuiltinDir to copy into a_cur
+ * @return 0 if went okay, 1 otherwise.
+ */
+static int
+BuiltinDirRestore (BuiltinDirPtr a_cur,
+ const BuiltinDirPtr a_saved)
+{
+ if (!a_cur)
+ return 1 ;
+ if (!a_saved)
+ return 0 ;
+
+ if (a_saved->font_name)
+ memmove (a_cur->font_name, a_saved->font_name, strlen (a_saved->font_name)) ;
+ return 0 ;
+}
+
+
+static int
+BuiltinDirsRestore (BuiltinDirPtr a_cur_tab,
+ const BuiltinDirPtr a_saved_tab,
+ int a_tab_len)
+{
+ int i=0 ;
+
+ if (!a_cur_tab)
+ return 1 ;
+ if (!a_saved_tab)
+ return 0 ;
+
+ for (i=0 ; i < a_tab_len; i++) {
+ if (BuiltinDirRestore (&a_cur_tab[i], &a_saved_tab[i]))
+ return 1 ;
+ }
+ return 0 ;
+}
+
+static BuiltinAliasPtr
+BuiltinAliasesDup (const BuiltinAliasPtr a_aliases,
+ int a_aliases_len)
+{
+ BuiltinAliasPtr aliases=NULL ;
+ int i=0 ;
+
+ if (!a_aliases)
+ return NULL ;
+
+ aliases = xcalloc (a_aliases_len, sizeof (BuiltinAliasRec)) ;
+ if (!aliases)
+ return NULL ;
+
+ for (i=0; i < a_aliases_len; i++) {
+ int len = strlen (a_aliases[i].font_name) ;
+ aliases[i].font_name = xcalloc (1, len+1) ;
+ memmove (aliases[i].font_name, a_aliases[i].font_name, len);
+ }
+ return aliases ;
+}
+
+/**
+ * Copy a_save back into a_cur
+ * @param a_cur the instance of BuiltinAlias to restore
+ * @param a_saved the saved instance of BuiltinAlias to copy into a_cur
+ * @return 0 if went okay, 1 otherwise.
+ */
+static int
+BuiltinAliasRestore (BuiltinAliasPtr a_cur,
+ const BuiltinAliasPtr a_save)
+{
+ if (!a_cur)
+ return 1 ;
+ if (!a_save)
+ return 0 ;
+ if (a_save->alias_name)
+ memmove (a_cur->alias_name, a_save->alias_name, strlen (a_save->alias_name)) ;
+ if (a_save->font_name)
+ memmove (a_cur->font_name, a_save->font_name, strlen (a_save->font_name)) ;
+ return 0 ;
+}
+
+static int
+BuiltinAliasesRestore (BuiltinAliasPtr a_cur_tab,
+ const BuiltinAliasPtr a_saved_tab,
+ int a_tab_len)
+{
+ int i=0 ;
+
+ if (!a_cur_tab)
+ return 1 ;
+ if (!a_saved_tab)
+ return 0 ;
+
+ for (i=0 ; i < a_tab_len; i++) {
+ if (BuiltinAliasRestore (&a_cur_tab[i], &a_saved_tab[i]))
+ return 1 ;
+ }
+ return 0 ;
+}
+
+int
+BuiltinReadDirectory (char *directory, FontDirectoryPtr *pdir)
+{
+ FontDirectoryPtr dir;
+ int i;
+
+ static BuiltinDirPtr saved_builtin_dir;
+ static BuiltinAliasPtr saved_builtin_alias;
+
+ dir = FontFileMakeDir ("", builtin_dir_count);
+
+ if (saved_builtin_dir)
+ {
+ BuiltinDirsRestore ((BuiltinDirPtr) builtin_dir,
+ saved_builtin_dir,
+ builtin_dir_count) ;
+ }
+ else
+ {
+ saved_builtin_dir = BuiltinDirsDup ((const BuiltinDirPtr) builtin_dir,
+ builtin_dir_count) ;
+ }
+
+ if (saved_builtin_alias)
+ {
+ BuiltinAliasesRestore ((BuiltinAliasPtr) builtin_alias,
+ saved_builtin_alias,
+ builtin_alias_count) ;
+ }
+ else
+ {
+ saved_builtin_alias = BuiltinAliasesDup ((const BuiltinAliasPtr) builtin_alias,
+ builtin_alias_count) ;
+ }
+
+ for (i = 0; i < builtin_dir_count; i++)
+ {
+ if (!FontFileAddFontFile (dir,
+ (char *) builtin_dir[i].font_name,
+ (char *) builtin_dir[i].file_name))
+ {
+ FontFileFreeDir (dir);
+ return BadFontPath;
+ }
+ }
+ for (i = 0; i < builtin_alias_count; i++)
+ {
+ if (!FontFileAddFontAlias (dir,
+ (char *) builtin_alias[i].alias_name,
+ (char *) builtin_alias[i].font_name))
+ {
+ FontFileFreeDir (dir);
+ return BadFontPath;
+ }
+ }
+ FontFileSortDir (dir);
+ *pdir = dir;
+ return Successful;
+}
diff --git a/libXfont/src/builtins/file.c b/libXfont/src/builtins/file.c
new file mode 100644
index 000000000..a46b0a65e
--- /dev/null
+++ b/libXfont/src/builtins/file.c
@@ -0,0 +1,133 @@
+/*
+ * Id: file.c,v 1.2 1999/11/02 06:16:47 keithp Exp $
+ *
+ * Copyright 1999 SuSE, Inc.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of SuSE not be used in advertising or
+ * publicity pertaining to distribution of the software without specific,
+ * written prior permission. SuSE makes no representations about the
+ * suitability of this software for any purpose. It is provided "as is"
+ * without express or implied warranty.
+ *
+ * SuSE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL SuSE
+ * BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Author: Keith Packard, SuSE, Inc.
+ */
+/* $XFree86: xc/lib/font/builtins/file.c,v 1.3 1999/12/30 02:29:49 robin Exp $ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include <string.h>
+#include "builtin.h"
+
+typedef struct _BuiltinIO {
+ int offset;
+ BuiltinFilePtr file;
+} BuiltinIORec, *BuiltinIOPtr;
+
+static int
+BuiltinFill (BufFilePtr f)
+{
+ int left, len;
+ BuiltinIOPtr io = ((BuiltinIOPtr) f->private);
+
+ left = io->file->len - io->offset;
+ if (left <= 0)
+ {
+ f->left = 0;
+ return BUFFILEEOF;
+ }
+ len = BUFFILESIZE;
+ if (len > left)
+ len = left;
+ memcpy (f->buffer, io->file->bits + io->offset, len);
+ io->offset += len;
+ f->left = len - 1;
+ f->bufp = f->buffer + 1;
+ return f->buffer[0];
+}
+
+static int
+BuiltinSkip (BufFilePtr f, int count)
+{
+ BuiltinIOPtr io = ((BuiltinIOPtr) f->private);
+ int curoff;
+ int fileoff;
+ int todo;
+
+ curoff = f->bufp - f->buffer;
+ fileoff = curoff + f->left;
+ if (curoff + count <= fileoff) {
+ f->bufp += count;
+ f->left -= count;
+ } else {
+ todo = count - (fileoff - curoff);
+ io->offset += todo;
+ if (io->offset > io->file->len)
+ io->offset = io->file->len;
+ if (io->offset < 0)
+ io->offset = 0;
+ f->left = 0;
+ }
+ return count;
+}
+
+static int
+BuiltinClose (BufFilePtr f, int unused)
+{
+ BuiltinIOPtr io = ((BuiltinIOPtr) f->private);
+
+ xfree (io);
+ return 1;
+}
+
+
+FontFilePtr
+BuiltinFileOpen (char *name)
+{
+ int i;
+ BuiltinIOPtr io;
+ BufFilePtr raw, cooked;
+
+ if (*name == '/') name++;
+ for (i = 0; i < builtin_files_count; i++)
+ if (!strcmp (name, builtin_files[i].name))
+ break;
+ if (i == builtin_files_count)
+ return NULL;
+ io = (BuiltinIOPtr) xalloc (sizeof (BuiltinIORec));
+ if (!io)
+ return NULL;
+ io->offset = 0;
+ io->file = (void *) &builtin_files[i];
+ raw = BufFileCreate ((char *) io, BuiltinFill, 0, BuiltinSkip, BuiltinClose);
+ if (!raw)
+ {
+ xfree (io);
+ return NULL;
+ }
+ if ((cooked = BufFilePushZIP (raw)))
+ raw = cooked;
+ else
+ {
+ raw->left += raw->bufp - raw->buffer;
+ raw->bufp = raw->buffer;
+ }
+ return (FontFilePtr) raw;
+}
+
+int
+BuiltinFileClose (FontFilePtr f, int unused)
+{
+ return BufFileClose ((BufFilePtr) f, TRUE);
+}
diff --git a/libXfont/src/builtins/fonts.c b/libXfont/src/builtins/fonts.c
new file mode 100644
index 000000000..ef5f5efc1
--- /dev/null
+++ b/libXfont/src/builtins/fonts.c
@@ -0,0 +1,1255 @@
+/*
+ * Id: fonts.c,v 1.2 1999/11/02 06:16:47 keithp Exp $
+ *
+ * Copyright 1999 SuSE, Inc.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of SuSE not be used in advertising or
+ * publicity pertaining to distribution of the software without specific,
+ * written prior permission. SuSE makes no representations about the
+ * suitability of this software for any purpose. It is provided "as is"
+ * without express or implied warranty.
+ *
+ * SuSE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL SuSE
+ * BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Author: Keith Packard, SuSE, Inc.
+ */
+/* $XFree86: xc/lib/font/builtins/fonts.c,v 1.3 1999/12/30 02:29:49 robin Exp $ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "builtin.h"
+
+static const char file_cursor[] = {
+ '\037', '\213', '\010', '\010', '\143', '\117', '\054', '\100',
+ '\000', '\003', '\143', '\165', '\162', '\163', '\157', '\162',
+ '\056', '\160', '\143', '\146', '\000', '\355', '\233', '\177',
+ '\160', '\124', '\327', '\165', '\307', '\317', '\112', '\102',
+ '\022', '\130', '\040', '\021', '\300', '\226', '\023', '\031',
+ '\311', '\100', '\034', '\114', '\354', '\104', '\004', '\033',
+ '\013', '\233', '\040', '\141', '\040', '\006', '\327', '\001',
+ '\154', '\213', '\000', '\216', '\143', '\151', '\221', '\026',
+ '\244', '\146', '\365', '\203', '\325', '\352', '\027', '\010',
+ '\264', '\253', '\137', '\273', '\010', '\320', '\217', '\332',
+ '\155', '\035', '\217', '\123', '\323', '\044', '\323', '\361',
+ '\340', '\114', '\207', '\231', '\144', '\062', '\324', '\303',
+ '\324', '\212', '\235', '\232', '\046', '\045', '\305', '\323',
+ '\072', '\143', '\322', '\060', '\365', '\062', '\166', '\143',
+ '\246', '\166', '\221', '\360', '\057', '\224', '\262', '\150',
+ '\373', '\075', '\357', '\234', '\273', '\357', '\355', '\112',
+ '\313', '\217', '\244', '\371', '\057', '\232', '\371', '\274',
+ '\167', '\357', '\271', '\347', '\336', '\167', '\177', '\236',
+ '\173', '\356', '\173', '\053', '\327', '\316', '\252', '\306',
+ '\154', '\042', '\162', '\201', '\064', '\360', '\056', '\010',
+ '\153', '\230', '\251', '\006', '\136', '\044', '\146', '\160',
+ '\034', '\367', '\354', '\164', '\242', '\067', '\370', '\256',
+ '\351', '\147', '\027', '\021', '\235', '\101', '\142', '\221',
+ '\306', '\327', '\042', '\355', '\307', '\167', '\022', '\225',
+ '\151', '\274', '\021', '\227', '\361', '\045', '\104', '\001',
+ '\215', '\237', '\237', '\116', '\124', '\163', '\267', '\074',
+ '\320', '\224', '\277', '\371', '\076', '\011', '\043', '\311',
+ '\372', '\163', '\315', '\300', '\145', '\011', '\207', '\226',
+ '\103', '\353', '\136', '\226', '\334', '\217', '\313', '\152',
+ '\226', '\160', '\322', '\172', '\016', '\174', '\033', '\074',
+ '\316', '\201', '\215', '\240', '\322', '\004', '\352', '\070',
+ '\020', '\303', '\137', '\013', '\007', '\146', '\112', '\171',
+ '\101', '\260', '\146', '\323', '\346', '\355', '\217', '\155',
+ '\170', '\150', '\175', '\071', '\225', '\327', '\170', '\232',
+ '\074', '\105', '\013', '\166', '\171', '\333', '\033', '\153',
+ '\232', '\026', '\024', '\271', '\175', '\236', '\242', '\346',
+ '\172', '\117', '\175', '\125', '\163', '\335', '\016', '\217',
+ '\317', '\123', '\115', '\233', '\067', '\155', '\330', '\130',
+ '\136', '\361', '\370', '\206', '\047', '\326', '\321', '\327',
+ '\066', '\155', '\054', '\247', '\252', '\146', '\137', '\123',
+ '\203', '\217', '\266', '\256', '\263', '\162', '\077', '\266',
+ '\356', '\361', '\115', '\217', '\154', '\051', '\337', '\260',
+ '\151', '\243', '\043', '\130', '\261', '\315', '\031', '\331',
+ '\116', '\333', '\052', '\326', '\213', '\366', '\243', '\133',
+ '\126', '\257', '\255', '\330', '\272', '\141', '\155', '\271',
+ '\125', '\345', '\064', '\262', '\377', '\362', '\300', '\154',
+ '\255', '\353', '\305', '\030', '\267', '\053', '\026', '\263',
+ '\332', '\216', '\224', '\331', '\224', '\153', '\245', '\377',
+ '\076', '\177', '\074', '\106', '\317', '\321', '\236', '\360',
+ '\160', '\137', '\270', '\375', '\300', '\160', '\350', '\100',
+ '\123', '\160', '\070', '\060', '\340', '\353', '\032', '\016',
+ '\016', '\356', '\353', '\035', '\076', '\020', '\354', '\350',
+ '\033', '\356', '\357', '\262', '\103', '\110', '\350', '\356',
+ '\305', '\245', '\247', '\167', '\117', '\210', '\163', '\204',
+ '\221', '\043', '\060', '\060', '\174', '\070', '\330', '\071',
+ '\070', '\074', '\320', '\205', '\274', '\207', '\203', '\110',
+ '\035', '\350', '\102', '\352', '\341', '\040', '\122', '\007',
+ '\272', '\332', '\103', '\310', '\333', '\026', '\106', '\336',
+ '\266', '\320', '\160', '\070', '\214', '\120', '\070', '\214',
+ '\242', '\002', '\003', '\173', '\103', '\170', '\006', '\122',
+ '\103', '\041', '\113', '\206', '\032', '\164', '\037', '\336',
+ '\163', '\000', '\027', '\144', '\073', '\020', '\102', '\135',
+ '\254', '\113', '\110', '\152', '\025', '\017', '\205', '\035',
+ '\262', '\260', '\011', '\355', '\355', '\035', '\356', '\355',
+ '\335', '\323', '\067', '\334', '\327', '\207', '\113', '\157',
+ '\250', '\235', '\253', '\006', '\131', '\050', '\204', '\150',
+ '\070', '\354', '\103', '\213', '\006', '\371', '\062', '\024',
+ '\017', '\015', '\332', '\172', '\166', '\313', '\355', '\272',
+ '\240', '\011', '\135', '\207', '\271', '\251', '\207', '\367',
+ '\017', '\040', '\233', '\165', '\361', '\007', '\315', '\045',
+ '\060', '\210', '\332', '\007', '\206', '\120', '\173', '\124',
+ '\067', '\334', '\147', '\135', '\254', '\154', '\326', '\305',
+ '\052', '\264', '\315', '\352', '\227', '\060', '\364', '\072',
+ '\017', '\100', '\017', '\075', '\324', '\027', '\102', '\017',
+ '\205', '\302', '\201', '\176', '\074', '\243', '\363', '\240',
+ '\121', '\266', '\272', '\004', '\262', '\003', '\101', '\310',
+ '\372', '\273', '\132', '\203', '\010', '\265', '\164', '\111',
+ '\077', '\367', '\036', '\264', '\056', '\266', '\136', '\307',
+ '\301', '\341', '\340', '\341', '\216', '\103', '\050', '\257',
+ '\045', '\070', '\074', '\030', '\154', '\356', '\302', '\005',
+ '\175', '\160', '\250', '\007', '\265', '\077', '\324', '\203',
+ '\076', '\355', '\355', '\105', '\237', '\366', '\365', '\165',
+ '\240', '\345', '\341', '\275', '\334', '\362', '\166', '\036',
+ '\313', '\066', '\036', '\113', '\214', '\114', '\137', '\010',
+ '\345', '\205', '\302', '\170', '\106', '\050', '\204', '\147',
+ '\070', '\153', '\140', '\367', '\001', '\372', '\245', '\163',
+ '\000', '\011', '\201', '\241', '\175', '\075', '\303', '\203',
+ '\001', '\024', '\145', '\075', '\243', '\273', '\007', '\227',
+ '\236', '\336', '\340', '\020', '\102', '\150', '\171', '\117',
+ '\357', '\356', '\000', '\102', '\273', '\203', '\010', '\101',
+ '\257', '\163', '\010', '\172', '\126', '\216', '\120', '\330',
+ '\172', '\170', '\013', '\107', '\233', '\371', '\342', '\030',
+ '\337', '\176', '\056', '\236', '\057', '\255', '\350', '\335',
+ '\201', '\026', '\276', '\130', '\323', '\307', '\214', '\145',
+ '\237', '\065', '\334', '\241', '\075', '\241', '\041', '\204',
+ '\302', '\103', '\350', '\253', '\001', '\356', '\277', '\101',
+ '\351', '\077', '\015', '\331', '\263', '\023', '\063', '\054',
+ '\300', '\005', '\130', '\163', '\050', '\320', '\217', '\147',
+ '\004', '\017', '\242', '\006', '\001', '\251', '\013', '\372',
+ '\064', '\320', '\217', '\076', '\015', '\036', '\104', '\152',
+ '\327', '\041', '\244', '\166', '\015', '\240', '\345', '\201',
+ '\176', '\074', '\067', '\170', '\020', '\025', '\077', '\020',
+ '\262', '\056', '\373', '\172', '\372', '\103', '\241', '\216',
+ '\336', '\376', '\160', '\230', '\327', '\332', '\163', '\272',
+ '\046', '\112', '\100', '\033', '\070', '\006', '\306', '\100',
+ '\076', '\326', '\310', '\172', '\320', '\010', '\216', '\200',
+ '\021', '\360', '\056', '\050', '\100', '\246', '\047', '\301',
+ '\063', '\340', '\115', '\220', '\003', '\133', '\367', '\010',
+ '\350', '\001', '\077', '\003', '\037', '\200', '\002', '\330',
+ '\272', '\047', '\301', '\363', '\340', '\115', '\060', '\167',
+ '\032', '\164', '\300', '\041', '\160', '\012', '\344', '\144',
+ '\042', '\016', '\016', '\201', '\177', '\006', '\331', '\131',
+ '\260', '\211', '\040', '\000', '\116', '\200', '\050', '\050',
+ '\201', '\361', '\154', '\003', '\107', '\300', '\033', '\331',
+ '\142', '\370', '\112', '\100', '\043', '\070', '\006', '\076',
+ '\000', '\167', '\301', '\320', '\325', '\200', '\037', '\200',
+ '\067', '\101', '\316', '\115', '\050', '\007', '\364', '\200',
+ '\023', '\040', '\012', '\112', '\162', '\120', '\016', '\070',
+ '\016', '\306', '\101', '\011', '\354', '\135', '\033', '\070',
+ '\006', '\306', '\300', '\342', '\131', '\260', '\214', '\340',
+ '\010', '\210', '\200', '\374', '\134', '\242', '\155', '\140',
+ '\010', '\274', '\001', '\062', '\140', '\144', '\312', '\100',
+ '\033', '\070', '\016', '\306', '\101', '\011', '\214', '\122',
+ '\045', '\030', '\002', '\307', '\301', '\171', '\260', '\370',
+ '\063', '\250', '\013', '\170', '\021', '\234', '\007', '\105',
+ '\163', '\240', '\003', '\216', '\200', '\010', '\050', '\232',
+ '\213', '\070', '\010', '\203', '\343', '\340', '\143', '\160',
+ '\317', '\074', '\354', '\033', '\340', '\207', '\040', '\002',
+ '\012', '\156', '\046', '\052', '\007', '\317', '\200', '\067',
+ '\301', '\334', '\133', '\320', '\117', '\340', '\020', '\030',
+ '\271', '\205', '\007', '\205', '\150', '\045', '\350', '\000',
+ '\317', '\202', '\023', '\340', '\014', '\210', '\202', '\374',
+ '\133', '\221', '\006', '\332', '\300', '\161', '\360', '\061',
+ '\050', '\376', '\054', '\372', '\013', '\034', '\003', '\347',
+ '\301', '\342', '\317', '\241', '\216', '\340', '\105', '\160',
+ '\036', '\054', '\056', '\100', '\034', '\274', '\010', '\316',
+ '\202', '\271', '\267', '\141', '\314', '\101', '\017', '\070',
+ '\001', '\242', '\340', '\236', '\371', '\104', '\176', '\360',
+ '\103', '\360', '\001', '\130', '\124', '\210', '\375', '\010',
+ '\034', '\002', '\047', '\100', '\024', '\254', '\304', '\306',
+ '\126', '\015', '\236', '\001', '\247', '\100', '\316', '\355',
+ '\310', '\007', '\252', '\301', '\017', '\300', '\273', '\240',
+ '\140', '\001', '\321', '\217', '\320', '\167', '\137', '\102',
+ '\137', '\075', '\211', '\360', '\361', '\265', '\104', '\131',
+ '\230', '\164', '\271', '\053', '\211', '\012', '\127', '\021',
+ '\255', '\342', '\262', '\320', '\337', '\343', '\030', '\373',
+ '\261', '\164', '\201', '\303', '\054', '\343', '\064', '\326',
+ '\141', '\135', '\053', '\017', '\046', '\150', '\341', '\070',
+ '\121', '\151', '\224', '\250', '\163', '\202', '\150', '\242',
+ '\023', '\172', '\245', '\320', '\207', '\336', '\130', '\256',
+ '\300', '\141', '\226', '\161', '\032', '\353', '\260', '\056',
+ '\347', '\341', '\274', '\124', '\014', '\120', '\026', '\101',
+ '\147', '\104', '\363', '\360', '\163', '\106', '\360', '\274',
+ '\010', '\150', '\304', '\263', '\113', '\170', '\036', '\143',
+ '\276', '\317', '\002', '\131', '\146', '\137', '\212', '\000',
+ '\224', '\101', '\050', '\057', '\200', '\162', '\043', '\140',
+ '\274', '\124', '\236', '\303', '\375', '\020', '\321', '\262',
+ '\306', '\101', '\007', '\062', '\255', '\002', '\205', '\310',
+ '\210', '\151', '\145', '\371', '\006', '\061', '\135', '\153',
+ '\061', '\031', '\312', '\004', '\236', '\320', '\052', '\161',
+ '\070', '\226', '\076', '\231', '\066', '\135', '\237', '\023',
+ '\056', '\233', '\250', '\312', '\362', '\065', '\357', '\023',
+ '\123', '\224', '\353', '\174', '\146', '\361', '\024', '\145',
+ '\230', '\162', '\247', '\172', '\146', '\200', '\233', '\214',
+ '\373', '\354', '\114', '\222', '\235', '\067', '\137', '\033',
+ '\222', '\046', '\351', '\334', '\035', '\074', '\116', '\277',
+ '\313', '\222', '\364', '\070', '\350', '\207', '\130', '\226',
+ '\350', '\074', '\204', '\171', '\265', '\066', '\303', '\206',
+ '\323', '\326', '\315', '\115', '\204', '\145', '\116', '\035',
+ '\316', '\363', '\366', '\076', '\233', '\263', '\230', '\207',
+ '\261', '\116', '\033', '\043', '\167', '\312', '\130', '\307',
+ '\231', '\007', '\217', '\266', '\130', '\010', '\333', '\261',
+ '\020', '\145', '\056', '\104', '\235', '\027', '\242', '\275',
+ '\337', '\207', '\254', '\012', '\274', '\223', '\153', '\353',
+ '\060', '\261', '\122', '\001', '\142', '\213', '\121', '\164',
+ '\326', '\050', '\346', '\332', '\050', '\352', '\062', '\212',
+ '\001', '\034', '\105', '\173', '\106', '\241', '\070', '\132',
+ '\152', '\303', '\172', '\011', '\355', '\066', '\235', '\014',
+ '\062', '\226', '\302', '\256', '\201', '\074', '\120', '\004',
+ '\312', '\100', '\000', '\104', '\227', '\332', '\072', '\214',
+ '\171', '\256', '\145', '\164', '\101', '\316', '\045', '\314',
+ '\073', '\120', '\002', '\032', '\101', '\004', '\214', '\200',
+ '\250', '\003', '\326', '\113', '\176', '\156', '\031', '\115',
+ '\015', '\367', '\347', '\172', '\264', '\175', '\263', '\113',
+ '\306', '\253', '\314', '\314', '\207', '\102', '\141', '\304',
+ '\065', '\065', '\247', '\156', '\225', '\076', '\345', '\271',
+ '\074', '\226', '\045', '\363', '\200', '\345', '\316', '\076',
+ '\147', '\106', '\350', '\352', '\230', '\366', '\215', '\244',
+ '\137', '\235', '\344', '\366', '\160', '\331', '\354', '\157',
+ '\137', '\301', '\175', '\032', '\052', '\375', '\111', '\005',
+ '\321', '\274', '\315', '\104', '\277', '\332', '\112', '\264',
+ '\245', '\034', '\154', '\101', '\030', '\314', '\103', '\370',
+ '\023', '\310', '\246', '\041', '\355', '\012', '\164', '\134',
+ '\145', '\132', '\267', '\344', '\362', '\156', '\020', '\063',
+ '\104', '\146', '\175', '\104', '\025', '\263', '\156', '\226',
+ '\241', '\316', '\113', '\323', '\022', '\206', '\322', '\102',
+ '\207', '\221', '\306', '\135', '\102', '\064', '\135', '\230',
+ '\310', '\022', '\142', '\271', '\066', '\227', '\146', '\331',
+ '\372', '\206', '\210', '\313', '\266', '\173', '\363', '\141',
+ '\157', '\147', '\025', '\210', '\315', '\163', '\302', '\062',
+ '\116', '\063', '\366', '\222', '\363', '\260', '\335', '\162',
+ '\332', '\074', '\306', '\330', '\074', '\047', '\054', '\063',
+ '\351', '\306', '\146', '\106', '\364', '\171', '\277', '\305',
+ '\230', '\317', '\131', '\106', '\364', '\163', '\234', '\127',
+ '\332', '\301', '\154', '\330', '\351', '\167', '\060', '\137',
+ '\047', '\240', '\363', '\213', '\271', '\066', '\377', '\215',
+ '\275', '\352', '\137', '\356', '\021', '\173', '\154', '\306',
+ '\227', '\165', '\056', '\255', '\040', '\372', '\115', '\053',
+ '\321', '\377', '\340', '\204', '\161', '\245', '\001', '\166',
+ '\141', '\047', '\321', '\107', '\115', '\222', '\376', '\376',
+ '\275', '\066', '\227', '\161', '\226', '\171', '\277', '\231',
+ '\350', '\164', '\207', '\075', '\217', '\306', '\165', '\257',
+ '\315', '\254', '\204', '\237', '\277', '\215', '\350', '\303',
+ '\207', '\260', '\056', '\313', '\204', '\064', '\345', '\071',
+ '\310', '\277', '\201', '\061', '\177', '\013', '\174', '\163',
+ '\273', '\055', '\267', '\332', '\221', '\053', '\066', '\170',
+ '\042', '\046', '\044', '\217', '\347', '\325', '\344', '\234',
+ '\277', '\314', '\065', '\065', '\235', '\152', '\100', '\371',
+ '\236', '\112', '\207', '\327', '\106', '\062', '\123', '\315',
+ '\251', '\251', '\364', '\230', '\007', '\261', '\077', '\256',
+ '\173', '\224', '\350', '\141', '\234', '\011', '\313', '\321',
+ '\267', '\065', '\360', '\133', '\066', '\303', '\117', '\172',
+ '\145', '\102', '\312', '\347', '\073', '\307', '\131', '\316',
+ '\351', '\254', '\307', '\372', '\234', '\157', '\047', '\306',
+ '\253', '\356', '\067', '\104', '\173', '\321', '\337', '\055',
+ '\350', '\127', '\057', '\366', '\365', '\212', '\053', '\030',
+ '\347', '\011', '\261', '\337', '\174', '\347', '\070', '\313',
+ '\071', '\235', '\365', '\130', '\237', '\363', '\161', '\172',
+ '\052', '\270', '\275', '\127', '\113', '\117', '\145', '\067',
+ '\234', '\355', '\115', '\245', '\063', '\242', '\375', '\126',
+ '\231', '\056', '\355', '\132', '\017', '\137', '\156', '\355',
+ '\154', '\151', '\117', '\147', '\247', '\366', '\167', '\247',
+ '\304', '\131', '\316', '\351', '\254', '\307', '\372', '\246',
+ '\277', '\331', '\046', '\361', '\230', '\263', '\215', '\372',
+ '\127', '\314', '\273', '\223', '\273', '\345', '\231', '\235',
+ '\372', '\154', '\216', '\263', '\174', '\052', '\033', '\346',
+ '\334', '\003', '\223', '\367', '\074', '\347', '\276', '\310',
+ '\353', '\167', '\252', '\165', '\353', '\304', '\244', '\263',
+ '\056', '\307', '\135', '\331', '\211', '\270', '\225', '\144',
+ '\271', '\225', '\277', '\324', '\306', '\254', '\355', '\367',
+ '\126', '\044', '\142', '\344', '\116', '\135', '\143', '\227',
+ '\330', '\036', '\375', '\104', '\155', '\121', '\262', '\035',
+ '\142', '\331', '\117', '\034', '\076', '\202', '\261', '\115',
+ '\306', '\046', '\045', '\267', '\311', '\330', '\237', '\344',
+ '\266', '\261', '\056', '\347', '\341', '\064', '\153', '\363',
+ '\110', '\341', '\073', '\261', '\357', '\136', '\006', '\212',
+ '\240', '\237', '\007', '\262', '\371', '\175', '\210', '\276',
+ '\277', '\140', '\073', '\156', '\275', '\176', '\340', '\212',
+ '\354', '\207', '\156', '\251', '\370', '\112', '\154', '\173',
+ '\046', '\162', '\005', '\266', '\101', '\074', '\106', '\307',
+ '\221', '\367', '\171', '\060', '\200', '\114', '\041', '\227',
+ '\354', '\315', '\256', '\024', '\317', '\266', '\034', '\053',
+ '\370', '\360', '\001', '\354', '\161', '\145', '\372', '\176',
+ '\205', '\337', '\011', '\360', '\161', '\101', '\335', '\224',
+ '\304', '\147', '\257', '\262', '\237', '\315', '\004', '\330',
+ '\347', '\343', '\147', '\147', '\312', '\073', '\030', '\076',
+ '\003', '\025', '\150', '\261', '\354', '\363', '\245', '\153',
+ '\177', '\014', '\243', '\300', '\357', '\140', '\016', '\316',
+ '\304', '\372', '\313', '\232', '\145', '\217', '\051', '\207',
+ '\131', '\306', '\151', '\303', '\111', '\143', '\372', '\321',
+ '\062', '\261', '\163', '\245', '\010', '\277', '\215', '\347',
+ '\216', '\176', '\125', '\340', '\060', '\313', '\070', '\215',
+ '\165', '\214', '\376', '\105', '\074', '\354', '\062', '\373',
+ '\213', '\070', '\243', '\114', '\107', '\131', '\267', '\362',
+ '\332', '\045', '\307', '\037', '\107', '\356', '\100', '\273',
+ '\140', '\227', '\163', '\120', '\306', '\070', '\362', '\217',
+ '\055', '\204', '\175', '\106', '\236', '\113', '\271', '\272',
+ '\237', '\103', '\247', '\224', '\347', '\112', '\261', '\370',
+ '\173', '\226', '\351', '\322', '\100', '\016', '\354', '\100',
+ '\001', '\046', '\103', '\024', '\341', '\161', '\060', '\066',
+ '\212', '\166', '\237', '\224', '\075', '\232', '\367', '\017',
+ '\366', '\343', '\070', '\374', '\063', '\074', '\373', '\365',
+ '\174', '\273', '\136', '\034', '\146', '\031', '\247', '\261',
+ '\016', '\353', '\162', '\330', '\332', '\267', '\325', '\137',
+ '\346', '\071', '\160', '\036', '\347', '\223', '\263', '\017',
+ '\114', '\266', '\171', '\054', '\343', '\264', '\061', '\035',
+ '\143', '\263', '\337', '\323', '\174', '\351', '\150', '\327',
+ '\051', '\354', '\023', '\063', '\245', '\357', '\072', '\321',
+ '\366', '\122', '\220', '\311', '\203', '\240', '\173', '\133',
+ '\036', '\045', '\322', '\146', '\372', '\002', '\244', '\073',
+ '\237', '\125', '\072', '\031', '\336', '\223', '\170', '\355',
+ '\363', '\270', '\226', '\220', '\275', '\207', '\063', '\074',
+ '\077', '\347', '\140', '\314', '\267', '\302', '\256', '\314',
+ '\301', '\144', '\371', '\167', '\334', '\013', '\127', '\112',
+ '\037', '\345', '\275', '\053', '\014', '\175', '\014', '\370',
+ '\216', '\364', '\060', '\372', '\240', '\007', '\025', '\350',
+ '\050', '\224', '\374', '\227', '\221', '\377', '\022', '\333',
+ '\014', '\356', '\177', '\246', '\324', '\366', '\073', '\330',
+ '\107', '\033', '\143', '\142', '\172', '\177', '\317', '\336',
+ '\237', '\070', '\277', '\345', '\107', '\317', '\227', '\065',
+ '\063', '\222', '\156', '\367', '\077', '\267', '\367', '\177',
+ '\265', '\314', '\053', '\346', '\034', '\204', '\064', '\230',
+ '\173', '\302', '\120', '\023', '\216', '\204', '\224', '\103',
+ '\072', '\111', '\013', '\165', '\356', '\146', '\331', '\171',
+ '\047', '\222', '\355', '\223', '\372', '\340', '\061', '\336',
+ '\307', '\264', '\333', '\346', '\253', '\355', '\163', '\241',
+ '\355', '\373', '\321', '\256', '\154', '\264', '\213', '\137',
+ '\156', '\132', '\167', '\354', '\355', '\331', '\330', '\363',
+ '\213', '\127', '\243', '\154', '\054', '\246', '\062', '\234',
+ '\143', '\003', '\274', '\230', '\246', '\311', '\142', '\212',
+ '\333', '\113', '\265', '\035', '\023', '\272', '\206', '\271',
+ '\135', '\326', '\071', '\250', '\123', '\347', '\026', '\356',
+ '\221', '\122', '\131', '\243', '\274', '\306', '\314', '\001',
+ '\212', '\333', '\376', '\072', '\374', '\211', '\356', '\112',
+ '\361', '\323', '\234', '\244', '\103', '\226', '\211', '\171',
+ '\233', '\303', '\147', '\131', '\064', '\262', '\070', '\123',
+ '\354', '\075', '\333', '\153', '\316', '\067', '\121', '\052',
+ '\066', '\235', '\363', '\246', '\053', '\153', '\334', '\260',
+ '\021', '\215', '\230', '\106', '\030', '\334', '\002', '\364',
+ '\111', '\311', '\254', '\044', '\137', '\025', '\165', '\171',
+ '\351', '\050', '\174', '\305', '\137', '\311', '\175', '\332',
+ '\033', '\104', '\067', '\035', '\111', '\175', '\067', '\172',
+ '\174', '\377', '\103', '\375', '\107', '\313', '\267', '\050',
+ '\024', '\333', '\370', '\273', '\057', '\310', '\132', '\147',
+ '\173', '\176', '\332', '\341', '\063', '\161', '\230', '\145',
+ '\234', '\306', '\072', '\121', '\355', '\123', '\247', '\017',
+ '\167', '\335', '\317', '\352', '\264', '\175', '\072', '\227',
+ '\332', '\256', '\054', '\131', '\106', '\074', '\125', '\254',
+ '\261', '\357', '\124', '\163', '\300', '\161', '\270', '\003',
+ '\144', '\216', '\042', '\225', '\312', '\325', '\362', '\304',
+ '\034', '\173', '\045', '\313', '\370', '\030', '\362', '\221',
+ '\332', '\016', '\143', '\023', '\314', '\131', '\252', '\033',
+ '\254', '\321', '\071', '\073', '\207', '\327', '\112', '\251',
+ '\334', '\027', '\252', '\274', '\333', '\241', '\153', '\316',
+ '\133', '\271', '\210', '\014', '\202', '\323', '\050', '\153',
+ '\224', '\022', '\333', '\306', '\161', '\226', '\163', '\072',
+ '\353', '\231', '\074', '\351', '\051', '\060', '\365', '\114',
+ '\225', '\236', '\233', '\202', '\344', '\275', '\075', '\225',
+ '\236', '\013', '\215', '\235', '\170', '\105', '\130', '\360',
+ '\075', '\242', '\357', '\035', '\115', '\204', '\145', '\046',
+ '\075', '\031', '\053', '\257', '\261', '\025', '\277', '\007',
+ '\234', '\067', '\125', '\273', '\222', '\333', '\237', '\252',
+ '\376', '\251', '\332', '\173', '\255', '\202', '\115', '\271',
+ '\327', '\052', '\070', '\271', '\134', '\313', '\347', '\312',
+ '\025', '\337', '\215', '\277', '\063', '\274', '\172', '\216',
+ '\150', '\321', '\277', '\141', '\257', '\347', '\367', '\156',
+ '\260', '\013', '\105', '\151', '\222', '\306', '\167', '\266',
+ '\265', '\354', '\357', '\055', '\236', '\001', '\133', '\305',
+ '\357', '\206', '\242', '\366', '\171', '\210', '\355', '\314',
+ '\153', '\260', '\115', '\357', '\275', '\243', '\176', '\373',
+ '\333', '\142', '\127', '\043', '\131', '\211', '\076', '\041',
+ '\353', '\355', '\057', '\025', '\337', '\227', '\111', '\036',
+ '\257', '\045', '\107', '\023', '\371', '\143', '\217', '\127',
+ '\304', '\261', '\316', '\170', '\235', '\360', '\032', '\167',
+ '\025', '\021', '\375', '\322', '\153', '\343', '\252', '\024',
+ '\062', '\141', '\313', '\362', '\063', '\165', '\117', '\120',
+ '\077', '\324', '\072', '\027', '\152', '\076', '\313', '\166',
+ '\244', '\260', '\001', '\321', '\121', '\373', '\375', '\031',
+ '\347', '\147', '\077', '\146', '\266', '\256', '\363', '\307',
+ '\300', '\123', '\240', '\207', '\344', '\333', '\025', '\357',
+ '\177', '\171', '\240', '\330', '\364', '\177', '\206', '\354',
+ '\107', '\226', '\001', '\300', '\363', '\331', '\201', '\162',
+ '\256', '\177', '\164', '\043', '\105', '\135', '\302', '\170',
+ '\272', '\356', '\115', '\272', '\377', '\107', '\162', '\325',
+ '\326', '\027', '\252', '\341', '\340', '\115', '\246', '\040',
+ '\161', '\137', '\073', '\225', '\043', '\070', '\353', '\167',
+ '\016', '\376', '\375', '\071', '\330', '\360', '\127', '\261',
+ '\257', '\026', '\314', '\322', '\263', '\057', '\316', '\175',
+ '\271', '\035', '\322', '\077', '\316', '\167', '\200', '\334',
+ '\166', '\143', '\117', '\131', '\166', '\021', '\106', '\344',
+ '\042', '\346', '\301', '\107', '\060', '\102', '\243', '\053',
+ '\344', '\074', '\314', '\371', '\047', '\116', '\112', '\137',
+ '\160', '\031', '\311', '\076', '\261', '\231', '\277', '\251',
+ '\316', '\354', '\123', '\371', '\300', '\116', '\337', '\330',
+ '\320', '\241', '\375', '\161', '\022', '\317', '\353', '\126',
+ '\077', '\365', '\165', '\175', '\277', '\302', '\343', '\305',
+ '\276', '\306', '\142', '\345', '\002', '\360', '\252', '\214',
+ '\375', '\227', '\161', '\355', '\307', '\011', '\335', '\107',
+ '\007', '\301', '\013', '\340', '\077', '\035', '\276', '\366',
+ '\170', '\222', '\136', '\124', '\145', '\330', '\352', '\344',
+ '\354', '\245', '\363', '\141', '\314', '\350', '\151', '\175',
+ '\142', '\032', '\077', '\003', '\016', '\221', '\370', '\012',
+ '\231', '\012', '\257', '\337', '\200', '\372', '\136', '\021',
+ '\035', '\077', '\036', '\107', '\353', '\054', '\340', '\130',
+ '\333', '\054', '\073', '\001', '\126', '\246', '\313', '\060',
+ '\316', '\327', '\162', '\114', '\147', '\225', '\201', '\100',
+ '\261', '\116', '\252', '\257', '\040', '\317', '\175', '\162',
+ '\347', '\170', '\100', '\323', '\223', '\073', '\166', '\204',
+ '\271', '\210', '\164', '\336', '\060', '\056', '\045', '\316',
+ '\131', '\216', '\263', '\234', '\323', '\107', '\234', '\235',
+ '\174', '\055', '\033', '\164', '\203', '\306', '\175', '\222',
+ '\255', '\113', '\101', '\262', '\255', '\070', '\232', '\304',
+ '\037', '\333', '\126', '\360', '\372', '\166', '\055', '\260',
+ '\211', '\055', '\224', '\367', '\060', '\116', '\056', '\102',
+ '\147', '\166', '\221', '\115', '\262', '\115', '\310', '\302',
+ '\244', '\213', '\215', '\332', '\264', '\136', '\020', '\056',
+ '\305', '\154', '\132', '\043', '\211', '\171', '\002', '\072',
+ '\267', '\370', '\133', '\017', '\163', '\214', '\111', '\227',
+ '\363', '\030', '\163', '\102', '\277', '\315', '\374', '\043',
+ '\203', '\176', '\052', '\064', '\007', '\044', '\375', '\156',
+ '\063', '\142', '\316', '\122', '\271', '\372', '\036', '\134',
+ '\141', '\277', '\060', '\376', '\216', '\074', '\246', '\357',
+ '\140', '\012', '\345', '\154', '\011', '\167', '\363', '\272',
+ '\141', '\073', '\264', '\112', '\314', '\212', '\165', '\276',
+ '\353', '\270', '\116', '\054', '\277', '\305', '\045', '\353',
+ '\243', '\303', '\261', '\016', '\331', '\337', '\145', '\137',
+ '\223', '\373', '\074', '\267', '\115', '\356', '\034', '\147',
+ '\071', '\373', '\237', '\354', '\117', '\046', '\217', '\045',
+ '\307', '\131', '\316', '\351', '\331', '\272', '\056', '\330',
+ '\347', '\312', '\325', '\173', '\216', '\326', '\255', '\130',
+ '\237', '\023', '\157', '\257', '\336', '\071', '\136', '\242',
+ '\351', '\226', '\242', '\236', '\263', '\330', '\150', '\130',
+ '\367', '\174', '\262', '\013', '\056', '\320', '\161', '\355',
+ '\244', '\370', '\373', '\120', '\113', '\247', '\100', '\322',
+ '\263', '\065', '\270', '\112', '\373', '\346', '\106', '\372',
+ '\062', '\117', '\353', '\147', '\354', '\230', '\351', '\243',
+ '\353', '\355', '\323', '\033', '\171', '\166', '\362', '\270',
+ '\135', '\357', '\163', '\247', '\032', '\067', '\353', '\120',
+ '\317', '\233', '\032', '\357', '\065', '\173', '\061', '\117',
+ '\301', '\020', '\010', '\047', '\161', '\010', '\014', '\200',
+ '\127', '\100', '\076', '\157', '\200', '\306', '\210', '\071',
+ '\053', '\215', '\076', '\255', '\004', '\215', '\240', '\055',
+ '\211', '\016', '\260', '\077', '\046', '\357', '\222', '\366',
+ '\103', '\267', '\170', '\077', '\131', '\357', '\035', '\330',
+ '\134', '\271', '\034', '\360', '\231', '\175', '\166', '\232',
+ '\275', '\056', '\363', '\026', '\310', '\231', '\234', '\160',
+ '\106', '\267', '\214', '\077', '\006', '\172', '\244', '\224',
+ '\022', '\336', '\057', '\361', '\262', '\341', '\363', '\272',
+ '\205', '\163', '\155', '\216', '\312', '\231', '\174', '\114',
+ '\215', '\370', '\110', '\314', '\046', '\203', '\317', '\147',
+ '\031', '\102', '\136', '\232', '\160', '\356', '\234', '\274',
+ '\257', '\345', '\275', '\220', '\341', '\060', '\313', '\114',
+ '\272', '\321', '\347', '\274', '\231', '\230', '\127', '\071',
+ '\071', '\022', '\147', '\337', '\202', '\367', '\116', '\336',
+ '\067', '\077', '\175', '\100', '\375', '\052', '\344', '\377',
+ '\264', '\120', '\144', '\234', '\226', '\237', '\046', '\172',
+ '\234', '\207', '\363', '\362', '\006', '\302', '\266', '\341',
+ '\056', '\334', '\377', '\006', '\367', '\233', '\063', '\305',
+ '\067', '\300', '\366', '\115', '\070', '\266', '\320', '\347',
+ '\223', '\356', '\137', '\320', '\064', '\206', '\365', '\270',
+ '\357', '\363', '\161', '\306', '\357', '\120', '\366', '\317',
+ '\244', '\370', '\373', '\211', '\353', '\201', '\237', '\355',
+ '\174', '\337', '\132', '\224', '\146', '\363', '\174', '\201',
+ '\234', '\005', '\171', '\135', '\032', '\337', '\161', '\021',
+ '\316', '\255', '\163', '\347', '\312', '\172', '\346', '\167',
+ '\312', '\234', '\337', '\274', '\167', '\344', '\063', '\045',
+ '\303', '\347', '\313', '\022', '\314', '\213', '\027', '\060',
+ '\271', '\322', '\043', '\230', '\122', '\035', '\122', '\026',
+ '\177', '\367', '\340', '\167', '\243', '\313', '\227', '\213',
+ '\377', '\311', '\147', '\113', '\316', '\307', '\276', '\016',
+ '\237', '\057', '\271', '\114', '\076', '\247', '\166', '\127',
+ '\312', '\371', '\223', '\357', '\346', '\334', '\152', '\316',
+ '\237', '\043', '\111', '\357', '\050', '\127', '\316', '\227',
+ '\162', '\370', '\254', '\372', '\032', '\306', '\250', '\352',
+ '\035', '\271', '\233', '\263', '\053', '\247', '\133', '\176',
+ '\154', '\172', '\352', '\357', '\070', '\154', '\063', '\123',
+ '\245', '\245', '\174', '\027', '\353', '\260', '\135', '\251',
+ '\164', '\314', '\226', '\271', '\112', '\327', '\244', '\365',
+ '\275', '\042', '\327', '\366', '\101', '\212', '\215', '\217',
+ '\310', '\357', '\327', '\170', '\001', '\263', '\361', '\050',
+ '\222', '\171', '\134', '\250', '\113', '\151', '\102', '\337',
+ '\223', '\106', '\325', '\316', '\133', '\066', '\137', '\333',
+ '\077', '\306', '\176', '\035', '\373', '\202', '\150', '\147',
+ '\204', '\035', '\230', '\010', '\131', '\016', '\214', '\071',
+ '\003', '\073', '\267', '\156', '\376', '\046', '\127', '\105',
+ '\362', '\215', '\216', '\277', '\325', '\131', '\337', '\354',
+ '\062', '\344', '\033', '\136', '\374', '\154', '\023', '\113',
+ '\204', '\353', '\356', '\374', '\046', '\147', '\175', '\243',
+ '\313', '\322', '\157', '\166', '\005', '\372', '\015', '\257',
+ '\330', '\161', '\346', '\321', '\347', '\072', '\035', '\300',
+ '\250', '\176', '\233', '\053', '\323', '\157', '\165', '\171',
+ '\372', '\355', '\056', '\303', '\361', '\255', '\156', '\322',
+ '\167', '\276', '\261', '\304', '\157', '\162', '\043', '\372',
+ '\255', '\256', '\121', '\277', '\335', '\361', '\067', '\274',
+ '\034', '\375', '\126', '\147', '\175', '\257', '\053', '\024',
+ '\110', '\307', '\214', '\273', '\201', '\277', '\311', '\361',
+ '\267', '\071', '\376', '\106', '\227', '\162', '\334', '\073',
+ '\047', '\217', '\143', '\362', '\373', '\157', '\236', '\263',
+ '\051', '\347', '\200', '\266', '\167', '\204', '\256', '\361',
+ '\235', '\056', '\251', '\175', '\327', '\372', '\136', '\227',
+ '\055', '\115', '\111', '\060', '\251', '\255', '\064', '\331',
+ '\336', '\177', '\213', '\344', '\147', '\150', '\033', '\110',
+ '\176', '\234', '\146', '\060', '\357', '\344', '\222', '\367',
+ '\002', '\247', '\315', '\177', '\071', '\111', '\376', '\226',
+ '\162', '\322', '\361', '\056', '\342', '\232', '\147', '\341',
+ '\353', '\074', '\323', '\033', '\302', '\074', '\317', '\161',
+ '\366', '\374', '\071', '\174', '\332', '\017', '\247', '\313',
+ '\357', '\124', '\326', '\344', '\247', '\030', '\037', '\265',
+ '\107', '\001', '\204', '\317', '\267', '\020', '\135', '\176',
+ '\233', '\350', '\112', '\251', '\356', '\371', '\352', '\223',
+ '\235', '\156', '\237', '\142', '\134', '\262', '\022', '\011',
+ '\134', '\217', '\137', '\153', '\374', '\337', '\353', '\364',
+ '\143', '\015', '\146', '\177', '\060', '\347', '\250', '\076',
+ '\264', '\245', '\033', '\363', '\071', '\210', '\011', '\370',
+ '\323', '\163', '\302', '\355', '\010', '\317', '\051', '\026',
+ '\133', '\037', '\235', '\042', '\217', '\341', '\132', '\347',
+ '\117', '\363', '\316', '\325', '\231', '\247', '\325', '\061',
+ '\027', '\256', '\207', '\002', '\235', '\107', '\243', '\216',
+ '\161', '\067', '\373', '\377', '\325', '\160', '\372', '\014',
+ '\234', '\127', '\176', '\107', '\370', '\035', '\062', '\177',
+ '\056', '\110', '\322', '\341', '\100', '\114', '\303', '\146',
+ '\226', '\205', '\047', '\115', '\247', '\031', '\164', '\023',
+ '\066', '\246', '\231', '\160', '\050', '\162', '\255', '\337',
+ '\023', '\176', '\206', '\346', '\300', '\143', '\231', '\107',
+ '\067', '\323', '\055', '\160', '\304', '\156', '\245', '\317',
+ '\322', '\347', '\120', '\233', '\333', '\340', '\074', '\024',
+ '\302', '\340', '\335', '\116', '\013', '\150', '\041', '\066',
+ '\366', '\317', '\323', '\035', '\330', '\337', '\026', '\323',
+ '\235', '\264', '\204', '\276', '\110', '\167', '\321', '\335',
+ '\364', '\045', '\372', '\062', '\014', '\304', '\122', '\034',
+ '\202', '\226', '\321', '\075', '\164', '\057', '\055', '\247',
+ '\373', '\120', '\243', '\025', '\164', '\077', '\075', '\000',
+ '\247', '\341', '\253', '\130', '\015', '\245', '\230', '\055',
+ '\253', '\351', '\101', '\132', '\103', '\153', '\151', '\035',
+ '\175', '\215', '\036', '\242', '\365', '\130', '\017', '\017',
+ '\323', '\237', '\321', '\043', '\364', '\165', '\332', '\110',
+ '\233', '\150', '\063', '\075', '\212', '\023', '\372', '\343',
+ '\124', '\116', '\133', '\350', '\033', '\264', '\225', '\266',
+ '\321', '\166', '\172', '\202', '\276', '\111', '\117', '\142',
+ '\375', '\074', '\105', '\025', '\124', '\111', '\156', '\332',
+ '\001', '\333', '\130', '\115', '\036', '\332', '\111', '\273',
+ '\250', '\206', '\152', '\351', '\317', '\261', '\256', '\274',
+ '\124', '\107', '\365', '\324', '\200', '\223', '\341', '\156',
+ '\362', '\121', '\023', '\371', '\251', '\231', '\132', '\320',
+ '\177', '\155', '\324', '\116', '\173', '\150', '\057', '\172',
+ '\145', '\037', '\355', '\307', '\232', '\014', '\120', '\220',
+ '\272', '\250', '\033', '\247', '\377', '\136', '\352', '\243',
+ '\020', '\205', '\351', '\000', '\365', '\323', '\101', '\234',
+ '\022', '\017', '\323', '\000', '\015', '\322', '\020', '\015',
+ '\323', '\137', '\320', '\323', '\364', '\014', '\375', '\045',
+ '\375', '\025', '\375', '\065', '\075', '\153', '\365', '\234',
+ '\371', '\175', '\330', '\242', '\264', '\077', '\361', '\047',
+ '\260', '\037', '\052', '\377', '\337', '\345', '\076', '\350',
+ '\022', '\322', '\310', '\376', '\075', '\042', '\377', '\316',
+ '\231', '\177', '\362', '\206', '\355', '\315', '\162', '\245',
+ '\127', '\200', '\115', '\044', '\357', '\260', '\174', '\152',
+ '\043', '\370', '\135', '\142', '\077', '\170', '\026', '\274',
+ '\004', '\136', '\003', '\157', '\221', '\154', '\271', '\374',
+ '\116', '\144', '\246', '\113', '\176', '\307', '\270', '\030',
+ '\054', '\003', '\153', '\300', '\106', '\360', '\024', '\360',
+ '\200', '\335', '\240', '\025', '\164', '\201', '\303', '\340',
+ '\273', '\340', '\373', '\340', '\357', '\301', '\011', '\227',
+ '\274', '\163', '\376', '\065', '\070', '\017', '\076', '\005',
+ '\323', '\121', '\301', '\231', '\340', '\146', '\160', '\033',
+ '\270', '\023', '\054', '\117', '\223', '\075', '\274', '\034',
+ '\170', '\300', '\156', '\320', '\005', '\016', '\203', '\357',
+ '\202', '\277', '\003', '\077', '\006', '\057', '\203', '\177',
+ '\002', '\277', '\004', '\377', '\001', '\042', '\340', '\175',
+ '\160', '\021', '\104', '\101', '\032', '\154', '\373', '\114',
+ '\060', '\207', '\337', '\273', '\200', '\205', '\340', '\356',
+ '\164', '\371', '\035', '\332', '\172', '\360', '\050', '\250',
+ '\000', '\265', '\240', '\015', '\004', '\323', '\345', '\175',
+ '\370', '\163', '\340', '\050', '\370', '\021', '\370', '\051',
+ '\370', '\005', '\070', '\003', '\316', '\202', '\377', '\002',
+ '\037', '\202', '\014', '\354', '\151', '\063', '\300', '\274',
+ '\014', '\371', '\155', '\346', '\142', '\360', '\145', '\360',
+ '\200', '\176', '\067', '\175', '\030', '\154', '\007', '\165',
+ '\240', '\025', '\364', '\201', '\141', '\360', '\267', '\340',
+ '\045', '\360', '\062', '\170', '\035', '\274', '\005', '\042',
+ '\340', '\002', '\270', '\004', '\246', '\361', '\267', '\063',
+ '\160', '\007', '\050', '\001', '\233', '\300', '\267', '\100',
+ '\043', '\350', '\004', '\117', '\203', '\027', '\300', '\061',
+ '\360', '\052', '\370', '\065', '\070', '\007', '\056', '\200',
+ '\117', '\200', '\213', '\177', '\373', '\011', '\346', '\202',
+ '\333', '\300', '\027', '\063', '\305', '\057', '\277', '\037',
+ '\254', '\006', '\137', '\007', '\345', '\374', '\035', '\010',
+ '\064', '\200', '\156', '\360', '\064', '\170', '\021', '\374',
+ '\003', '\070', '\015', '\316', '\200', '\337', '\202', '\013',
+ '\340', '\062', '\277', '\350', '\302', '\236', '\065', '\003',
+ '\314', '\001', '\267', '\203', '\045', '\354', '\267', '\203',
+ '\325', '\140', '\023', '\330', '\002', '\052', '\301', '\116',
+ '\260', '\033', '\154', '\253', '\320', '\337', '\256', '\233',
+ '\100', '\105', '\235', '\273', '\351', '\333', '\344', '\366',
+ '\371', '\032', '\132', '\345', '\052', '\202', '\035', '\356',
+ '\046', '\117', '\165', '\205', '\010', '\252', '\033', '\132',
+ '\353', '\047', '\011', '\046', '\253', '\065', '\067', '\046',
+ '\105', '\125', '\245', '\301', '\355', '\267', '\056', '\046',
+ '\272', '\253', '\241', '\251', '\326', '\337', '\036', '\017',
+ '\030', '\261', '\337', '\337', '\120', '\127', '\341', '\365',
+ '\354', '\364', '\127', '\124', '\065', '\370', '\352', '\075',
+ '\276', '\051', '\104', '\011', '\252', '\276', '\332', '\135',
+ '\065', '\311', '\272', '\116', '\131', '\202', '\162', '\123',
+ '\155', '\265', '\307', '\031', '\116', '\110', '\364', '\173',
+ '\074', '\216', '\240', '\111', '\152', '\253', '\150', '\152',
+ '\254', '\365', '\271', '\275', '\216', '\240', '\044', '\125',
+ '\171', '\352', '\375', '\050', '\276', '\321', '\357', '\163',
+ '\004', '\065', '\251', '\326', '\127', '\345', '\365', '\350',
+ '\115', '\105', '\336', '\206', '\052', '\275', '\252', '\240',
+ '\141', '\347', '\116', '\176', '\112', '\363', '\056', '\107',
+ '\120', '\223', '\174', '\015', '\115', '\115', '\162', '\165',
+ '\010', '\052', '\174', '\236', '\026', '\217', '\257', '\311',
+ '\223', '\030', '\163', '\050', '\324', '\270', '\153', '\175',
+ '\166', '\110', '\022', '\252', '\153', '\335', '\165', '\015',
+ '\365', '\325', '\025', '\122', '\144', '\102', '\114', '\025',
+ '\032', '\374', '\114', '\074', '\202', '\126', '\352', '\315',
+ '\210', '\232', '\167', '\240', '\015', '\062', '\061', '\234',
+ '\021', '\115', '\366', '\271', '\061', '\054', '\136', '\267',
+ '\157', '\227', '\307', '\031', '\166', '\046', '\066', '\325',
+ '\271', '\275', '\136', '\147', '\070', '\236', '\330', '\210',
+ '\111', '\142', '\075', '\057', '\036', '\224', '\044', '\117',
+ '\133', '\125', '\215', '\273', '\036', '\045', '\232', '\200',
+ '\210', '\167', '\172', '\075', '\315', '\076', '\271', '\212',
+ '\140', '\127', '\303', '\016', '\124', '\307', '\147', '\356',
+ '\052', '\154', '\256', '\333', '\321', '\056', '\127', '\021',
+ '\240', '\204', '\352', '\245', '\162', '\265', '\005', '\137',
+ '\221', '\253', '\012', '\074', '\156', '\237', '\137', '\256',
+ '\042', '\250', '\255', '\152', '\250', '\267', '\056', '\032',
+ '\365', '\041', '\044', '\075', '\150', '\007', '\045', '\311',
+ '\232', '\225', '\074', '\005', '\114', '\300', '\041', '\266',
+ '\046', '\133', '\074', '\344', '\110', '\340', '\211', '\146',
+ '\002', '\266', '\170', '\107', '\063', '\246', '\136', '\275',
+ '\043', '\250', '\111', '\336', '\012', '\164', '\001', '\146',
+ '\223', '\011', '\250', '\330', '\147', '\304', '\076', '\247',
+ '\270', '\316', '\135', '\317', '\150', '\244', '\266', '\272',
+ '\332', '\353', '\321', '\162', '\235', '\021', '\115', '\156',
+ '\150', '\306', '\154', '\262', '\256', '\042', '\150', '\364',
+ '\324', '\127', '\325', '\172', '\365', '\246', '\042', '\314',
+ '\167', '\277', '\107', '\157', '\052', '\362', '\066', '\067',
+ '\131', '\027', '\211', '\356', '\156', '\366', '\064', '\371',
+ '\153', '\121', '\246', '\114', '\221', '\304', '\250', '\250',
+ '\310', '\162', '\344', '\136', '\212', '\207', '\234', '\011',
+ '\126', '\077', '\331', '\101', '\147', '\022', '\367', '\124',
+ '\074', '\344', '\110', '\320', '\066', '\071', '\302', '\232',
+ '\350', '\367', '\126', '\170', '\141', '\120', '\342', '\001',
+ '\021', '\067', '\271', '\153', '\275', '\226', '\375', '\061',
+ '\001', '\025', '\357', '\020', '\023', '\046', '\065', '\117',
+ '\210', '\305', '\025', '\152', '\052', '\022', '\126', '\300',
+ '\044', '\111', '\134', '\321', '\032', '\320', '\270', '\222',
+ '\035', '\213', '\053', '\110', '\073', '\342', '\032', '\216',
+ '\150', '\134', '\005', '\266', '\062', '\236', '\156', '\302',
+ '\361', '\304', '\226', '\111', '\065', '\151', '\231', '\252',
+ '\046', '\065', '\350', '\016', '\114', '\013', '\275', '\253',
+ '\260', '\166', '\117', '\155', '\375', '\056', '\275', '\251',
+ '\250', '\021', '\135', '\355', '\323', '\233', '\021', '\371',
+ '\334', '\355', '\125', '\230', '\100', '\046', '\240', '\142',
+ '\277', '\333', '\147', '\135', '\044', '\352', '\347', '\365',
+ '\355', '\327', '\233', '\212', '\144', '\155', '\370', '\035',
+ '\353', '\302', '\337', '\320', '\350', '\354', '\221', '\304',
+ '\150', '\222', '\212', '\332', '\356', '\244', '\270', '\255',
+ '\224', '\140', '\341', '\223', '\005', '\266', '\232', '\065',
+ '\215', '\114', '\300', '\026', '\363', '\024', '\322', '\273',
+ '\012', '\175', '\036', '\271', '\110', '\264', '\331', '\254',
+ '\257', '\346', '\204', '\365', '\005', '\373', '\341', '\363',
+ '\170', '\275', '\356', '\170', '\100', '\305', '\146', '\331',
+ '\065', '\047', '\054', '\273', '\126', '\267', '\277', '\252',
+ '\106', '\256', '\042', '\150', '\303', '\176', '\120', '\047',
+ '\127', '\021', '\320', '\215', '\377', '\217', '\327', '\377',
+ '\001', '\226', '\047', '\030', '\162', '\200', '\067', '\000',
+ '\000',
+
+};
+
+static const char file_6x13[] = {
+ '\037', '\213', '\010', '\010', '\126', '\121', '\054', '\100',
+ '\000', '\003', '\066', '\170', '\061', '\063', '\055', '\111',
+ '\123', '\117', '\070', '\070', '\065', '\071', '\055', '\061',
+ '\056', '\160', '\143', '\146', '\000', '\355', '\234', '\177',
+ '\170', '\024', '\307', '\171', '\307', '\277', '\002', '\001',
+ '\002', '\013', '\020', '\106', '\004', '\141', '\203', '\045',
+ '\333', '\330', '\306', '\066', '\262', '\045', '\014', '\030',
+ '\073', '\330', '\346', '\054', '\035', '\240', '\104', '\110',
+ '\030', '\111', '\061', '\070', '\151', '\345', '\343', '\156',
+ '\045', '\155', '\270', '\037', '\362', '\375', '\300', '\222',
+ '\215', '\101', '\010', '\044', '\204', '\114', '\012', '\051',
+ '\216', '\103', '\034', '\222', '\100', '\203', '\123', '\334',
+ '\342', '\032', '\327', '\264', '\265', '\023', '\307', '\165',
+ '\152', '\047', '\301', '\055', '\165', '\150', '\202', '\133',
+ '\352', '\322', '\230', '\076', '\365', '\037', '\364', '\251',
+ '\363', '\074', '\116', '\037', '\047', '\161', '\373', '\270',
+ '\245', '\337', '\331', '\335', '\071', '\215', '\206', '\335',
+ '\273', '\225', '\340', '\111', '\237', '\247', '\017', '\003',
+ '\237', '\331', '\331', '\335', '\171', '\147', '\346', '\175',
+ '\347', '\335', '\231', '\331', '\071', '\335', '\025', '\264',
+ '\205', '\073', '\047', '\002', '\050', '\040', '\143', '\110',
+ '\007', '\243', '\175', '\116', '\172', '\014', '\057', '\106',
+ '\170', '\304', '\130', '\240', '\120', '\236', '\063', '\021',
+ '\341', '\171', '\221', '\223', '\347', '\154', '\025', '\160',
+ '\174', '\002', '\120', '\242', '\334', '\077', '\274', '\004',
+ '\250', '\160', '\356', '\227', '\060', '\052', '\276', '\007',
+ '\130', '\346', '\234', '\157', '\247', '\354', '\354', '\373',
+ '\200', '\036', '\347', '\174', '\037', '\053', '\077', '\160',
+ '\277', '\335', '\000', '\131', '\337', '\222', '\172', '\373',
+ '\336', '\247', '\140', '\207', '\202', '\053', '\031', '\115',
+ '\027', '\211', '\253', '\141', '\227', '\134', '\060', '\237',
+ '\321', '\002', '\221', '\270', '\227', '\121', '\120', '\044',
+ '\076', '\313', '\150', '\225', '\110', '\174', '\236', '\221',
+ '\051', '\022', '\135', '\214', '\272', '\205', '\374', '\144',
+ '\121', '\257', '\110', '\210', '\053', '\273', '\105', '\102',
+ '\144', '\336', '\057', '\023', '\317', '\211', '\314', '\057',
+ '\062', '\172', '\111', '\134', '\131', '\112', '\176', '\040',
+ '\256', '\374', '\224', '\321', '\273', '\042', '\361', '\357',
+ '\214', '\176', '\041', '\022', '\277', '\141', '\064', '\107',
+ '\030', '\112', '\030', '\154', '\236', '\110', '\214', '\047',
+ '\325', '\114', '\024', '\054', '\146', '\264', '\121', '\134',
+ '\231', '\104', '\236', '\020', '\211', '\166', '\062', '\040',
+ '\363', '\000', '\173', '\231', '\134', '\336', '\330', '\320',
+ '\334', '\020', '\130', '\025', '\154', '\135', '\023', '\134',
+ '\121', '\327', '\324', '\274', '\146', '\235', '\270', '\324',
+ '\322', '\120', '\313', '\304', '\052', '\063', '\025', '\306',
+ '\362', '\300', '\252', '\272', '\372', '\165', '\255', '\042',
+ '\013', '\226', '\233', '\135', '\106', '\004', '\017', '\006',
+ '\353', '\126', '\254', '\154', '\266', '\257', '\254', '\062',
+ '\042', '\146', '\046', '\206', '\246', '\372', '\100', '\103',
+ '\063', '\326', '\240', '\051', '\330', '\374', '\140', '\135',
+ '\155', '\363', '\112', '\373', '\146', '\223', '\021', '\063',
+ '\153', '\022', '\361', '\210', '\021', '\117', '\121', '\054',
+ '\120', '\133', '\333', '\332', '\324', '\274', '\256', '\076',
+ '\150', '\337', '\304', '\352', '\272', '\265', '\301', '\372',
+ '\326', '\246', '\272', '\207', '\202', '\130', '\335', '\130',
+ '\327', '\320', '\154', '\047', '\327', '\004', '\233', '\032',
+ '\353', '\133', '\232', '\353', '\032', '\033', '\132', '\327',
+ '\252', '\047', '\353', '\320', '\264', '\072', '\120', '\123',
+ '\327', '\260', '\002', '\065', '\010', '\174', '\056', '\270',
+ '\046', '\260', '\042', '\330', '\152', '\125', '\205', '\232',
+ '\225', '\201', '\065', '\254', '\167', '\250', '\375', '\165',
+ '\115', '\215', '\113', '\226', '\054', '\272', '\053', '\173',
+ '\043', '\330', '\120', '\323', '\130', '\053', '\044', '\253',
+ '\121', '\323', '\270', '\172', '\335', '\032', '\321', '\172',
+ '\254', '\316', '\254', '\217', '\232', '\341', '\212', '\110',
+ '\042', '\026', '\062', '\343', '\025', '\155', '\211', '\170',
+ '\372', '\266', '\212', '\212', '\246', '\216', '\120', '\322',
+ '\250', '\010', '\305', '\043', '\025', '\106', '\374', '\213',
+ '\211', '\356', '\333', '\120', '\023', '\130', '\335', '\272',
+ '\322', '\122', '\027', '\153', '\145', '\102', '\030', '\014',
+ '\225', '\302', '\066', '\225', '\226', '\075', '\052', '\155',
+ '\033', '\124', '\256', '\251', '\034', '\246', '\157', '\145',
+ '\145', '\365', '\035', '\225', '\325', '\013', '\252', '\052',
+ '\357', '\134', '\044', '\376', '\327', '\124', '\056', '\256',
+ '\252', '\164', '\132', '\126', '\131', '\355', '\330', '\120',
+ '\121', '\020', '\017', '\264', '\004', '\152', '\035', '\215',
+ '\054', '\237', '\053', '\260', '\002', '\160', '\205', '\343',
+ '\223', '\166', '\030', '\317', '\177', '\127', '\070', '\347',
+ '\152', '\132', '\234', '\235', '\077', '\377', '\353', '\363',
+ '\042', '\357', '\360', '\353', '\136', '\101', '\324', '\361',
+ '\036', '\172', '\372', '\373', '\237', '\354', '\275', '\034',
+ '\135', '\216', '\056', '\107', '\227', '\243', '\113', '\033',
+ '\071', '\343', '\326', '\173', '\316', '\170', '\263', '\120',
+ '\314', '\343', '\316', '\014', '\167', '\222', '\024', '\162',
+ '\374', '\131', '\102', '\242', '\344', '\000', '\071', '\105',
+ '\212', '\050', '\260', '\224', '\164', '\222', '\103', '\344',
+ '\264', '\230', '\247', '\071', '\067', '\057', '\043', '\151',
+ '\162', '\230', '\234', '\041', '\045', '\234', '\317', '\153',
+ '\111', '\027', '\071', '\102', '\316', '\222', '\322', '\161',
+ '\300', '\112', '\262', '\211', '\034', '\045', '\357', '\223',
+ '\062', '\116', '\163', '\365', '\244', '\207', '\034', '\043',
+ '\347', '\310', '\154', '\256', '\013', '\126', '\223', '\355',
+ '\344', '\145', '\362', '\001', '\251', '\340', '\302', '\241',
+ '\231', '\014', '\220', '\127', '\311', '\207', '\144', '\056',
+ '\347', '\323', '\265', '\144', '\027', '\171', '\235', '\174',
+ '\104', '\346', '\161', '\042', '\375', '\002', '\331', '\103',
+ '\336', '\044', '\037', '\223', '\371', '\034', '\240', '\037',
+ '\046', '\117', '\221', '\343', '\344', '\023', '\122', '\125',
+ '\314', '\065', '\003', '\331', '\107', '\116', '\024', '\333',
+ '\223', '\375', '\102', '\322', '\101', '\366', '\223', '\223',
+ '\244', '\160', '\012', '\365', '\047', '\121', '\162', '\200',
+ '\234', '\042', '\105', '\123', '\251', '\077', '\351', '\044',
+ '\207', '\310', '\151', '\122', '\314', '\105', '\314', '\062',
+ '\222', '\046', '\207', '\311', '\031', '\122', '\062', '\215',
+ '\372', '\223', '\056', '\162', '\204', '\234', '\045', '\245',
+ '\134', '\217', '\254', '\044', '\233', '\310', '\121', '\362',
+ '\076', '\051', '\343', '\372', '\244', '\236', '\364', '\220',
+ '\143', '\344', '\034', '\231', '\135', '\112', '\375', '\311',
+ '\166', '\362', '\062', '\371', '\200', '\124', '\314', '\240',
+ '\376', '\144', '\200', '\274', '\112', '\076', '\044', '\163',
+ '\271', '\320', '\131', '\113', '\166', '\221', '\327', '\311',
+ '\107', '\144', '\336', '\114', '\352', '\117', '\366', '\220',
+ '\067', '\311', '\307', '\144', '\176', '\031', '\365', '\047',
+ '\117', '\221', '\343', '\344', '\023', '\122', '\065', '\213',
+ '\372', '\223', '\175', '\344', '\004', '\301', '\125', '\324',
+ '\237', '\164', '\220', '\375', '\344', '\044', '\051', '\344',
+ '\262', '\151', '\011', '\211', '\222', '\003', '\344', '\024',
+ '\051', '\232', '\115', '\375', '\111', '\047', '\071', '\104',
+ '\116', '\223', '\342', '\071', '\324', '\237', '\244', '\311',
+ '\141', '\162', '\206', '\224', '\134', '\103', '\375', '\111',
+ '\027', '\071', '\102', '\316', '\222', '\322', '\162', '\352',
+ '\117', '\066', '\221', '\243', '\344', '\175', '\122', '\306',
+ '\145', '\131', '\075', '\351', '\041', '\307', '\310', '\071',
+ '\062', '\373', '\132', '\352', '\117', '\266', '\223', '\227',
+ '\311', '\007', '\244', '\342', '\072', '\352', '\117', '\006',
+ '\310', '\253', '\344', '\103', '\062', '\367', '\172', '\352',
+ '\117', '\166', '\221', '\327', '\311', '\107', '\144', '\336',
+ '\134', '\352', '\117', '\366', '\220', '\067', '\311', '\307',
+ '\144', '\376', '\015', '\324', '\237', '\074', '\105', '\216',
+ '\223', '\117', '\110', '\325', '\215', '\324', '\237', '\354',
+ '\043', '\047', '\010', '\156', '\242', '\376', '\244', '\203',
+ '\354', '\047', '\047', '\111', '\341', '\074', '\352', '\117',
+ '\242', '\344', '\000', '\071', '\105', '\212', '\156', '\246',
+ '\376', '\244', '\223', '\034', '\042', '\247', '\111', '\361',
+ '\055', '\324', '\237', '\244', '\311', '\141', '\162', '\206',
+ '\224', '\334', '\112', '\375', '\111', '\027', '\071', '\102',
+ '\316', '\222', '\122', '\256', '\076', '\127', '\222', '\115',
+ '\344', '\050', '\171', '\237', '\224', '\125', '\002', '\115',
+ '\364', '\307', '\357', '\260', '\357', '\352', '\231', '\336',
+ '\367', '\320', '\320', '\374', '\077', '\303', '\071', '\116',
+ '\363', '\070', '\316', '\200', '\167', '\020', '\353', '\156',
+ '\272', '\053', '\312', '\235', '\143', '\241', '\113', '\036',
+ '\041', '\177', '\313', '\010', '\217', '\062', '\214', '\163',
+ '\230', '\240', '\244', '\351', '\012', '\326', '\372', '\136',
+ '\242', '\007', '\221', '\127', '\254', '\154', '\307', '\072',
+ '\307', '\071', '\116', '\273', '\212', '\235', '\243', '\133',
+ '\033', '\307', '\073', '\171', '\345', '\212', '\130', '\344',
+ '\055', '\125', '\216', '\245', '\056', '\062', '\005', '\012',
+ '\023', '\234', '\166', '\345', '\253', '\107', '\334', '\273',
+ '\322', '\241', '\330', '\345', '\276', '\127', '\220', '\345',
+ '\225', '\153', '\145', '\227', '\173', '\344', '\027', '\257',
+ '\000', '\142', '\275', '\070', '\331', '\111', '\027', '\152',
+ '\314', '\166', '\221', '\031', '\247', '\060', '\306', '\301',
+ '\313', '\326', '\172', '\171', '\222', '\011', '\043', '\320',
+ '\111', '\206', '\011', '\071', '\312', '\363', '\012', '\113',
+ '\163', '\310', '\170', '\261', '\064', '\107', '\171', '\136',
+ '\062', '\367', '\345', '\271', '\167', '\061', '\341', '\377',
+ '\203', '\174', '\056', '\133', '\217', '\264', '\177', '\162',
+ '\371', '\301', '\245', '\354', '\203', '\134', '\355', '\036',
+ '\015', '\152', '\340', '\224', '\227', '\035', '\113', '\306',
+ '\073', '\347', '\042', '\170', '\075', '\247', '\042', '\210',
+ '\161', '\112', '\214', '\005', '\045', '\316', '\161', '\254',
+ '\017', '\031', '\031', '\104', '\236', '\111', '\056', '\344',
+ '\012', '\045', '\030', '\032', '\107', '\312', '\235', '\266',
+ '\272', '\005', '\071', '\126', '\311', '\261', '\140', '\202',
+ '\222', '\026', '\327', '\047', '\373', '\150', '\337', '\110',
+ '\306', '\270', '\221', '\204', '\174', '\375', '\341', '\066',
+ '\166', '\370', '\265', '\217', '\227', '\134', '\271', '\166',
+ '\364', '\052', '\107', '\324', '\315', '\145', '\110', '\166',
+ '\054', '\025', '\363', '\242', '\234', '\103', '\246', '\172',
+ '\264', '\115', '\330', '\163', '\206', '\123', '\146', '\221',
+ '\223', '\147', '\214', '\163', '\056', '\256', '\117', '\364',
+ '\250', '\153', '\014', '\206', '\217', '\331', '\342', '\070',
+ '\313', '\311', '\377', '\051', '\227', '\374', '\176', '\306',
+ '\126', '\065', '\310', '\266', '\310', '\366', '\350', '\310',
+ '\173', '\352', '\334', '\240', '\137', '\327', '\121', '\313',
+ '\323', '\333', '\046', '\164', '\235', '\342', '\034', '\375',
+ '\266', '\121', '\325', '\113', '\237', '\037', '\107', '\032',
+ '\344', '\334', '\235', '\157', '\317', '\304', '\317', '\263',
+ '\231', '\053', '\210', '\072', '\334', '\326', '\113', '\045',
+ '\016', '\252', '\255', '\244', '\255', '\345', '\132', '\303',
+ '\255', '\054', '\341', '\047', '\323', '\134', '\230', '\344',
+ '\122', '\207', '\224', '\021', '\343', '\323', '\070', '\270',
+ '\077', '\103', '\156', '\372', '\115', '\121', '\312', '\225',
+ '\155', '\224', '\355', '\053', '\360', '\220', '\051', '\327',
+ '\362', '\116', '\121', '\164', '\234', '\346', '\234', '\353',
+ '\101', '\352', '\136', '\214', '\241', '\347', '\154', '\242',
+ '\123', '\226', '\327', '\232', '\117', '\216', '\143', '\002',
+ '\061', '\056', '\115', '\367', '\121', '\217', '\324', '\107',
+ '\312', '\115', '\305', '\160', '\333', '\271', '\311', '\250',
+ '\372', '\170', '\075', '\033', '\136', '\365', '\250', '\345',
+ '\346', '\253', '\107', '\317', '\163', '\215', '\017', '\175',
+ '\144', '\160', '\363', '\055', '\057', '\177', '\313', '\165',
+ '\337', '\353', '\131', '\160', '\353', '\173', '\371', '\314',
+ '\027', '\071', '\367', '\163', '\205', '\162', '\217', '\264',
+ '\036', '\334', '\312', '\325', '\353', '\325', '\203', '\227',
+ '\217', '\346', '\232', '\027', '\124', '\031', '\061', '\166',
+ '\316', '\160', '\230', '\354', '\324', '\161', '\215', '\213',
+ '\214', '\333', '\063', '\127', '\256', '\235', '\353', '\101',
+ '\370', '\327', '\225', '\012', '\123', '\264', '\363', '\251',
+ '\071', '\332', '\126', '\340', '\202', '\227', '\037', '\350',
+ '\365', '\350', '\270', '\325', '\243', '\076', '\077', '\362',
+ '\131', '\120', '\317', '\275', '\236', '\355', '\134', '\062',
+ '\271', '\372', '\107', '\315', '\063', '\013', '\271', '\237',
+ '\005', '\175', '\114', '\323', '\355', '\354', '\146', '\153',
+ '\351', '\313', '\136', '\270', '\325', '\243', '\277', '\353',
+ '\250', '\210', '\361', '\147', '\174', '\216', '\266', '\211',
+ '\373', '\142', '\054', '\035', '\353', '\034', '\047', '\346',
+ '\150', '\233', '\133', '\137', '\346', '\263', '\265', '\054',
+ '\113', '\174', '\302', '\044', '\375', '\063', '\237', '\015',
+ '\304', '\265', '\351', '\016', '\122', '\146', '\026', '\206',
+ '\333', '\133', '\017', '\372', '\270', '\243', '\343', '\345',
+ '\157', '\152', '\236', '\221', '\370', '\201', '\033', '\162',
+ '\015', '\240', '\217', '\043', '\156', '\365', '\344', '\263',
+ '\265', '\356', '\157', '\176', '\346', '\037', '\165', '\015',
+ '\341', '\147', '\315', '\217', '\034', '\272', '\214', '\304',
+ '\257', '\325', '\365', '\251', '\337', '\172', '\146', '\150',
+ '\270', '\255', '\111', '\365', '\362', '\013', '\225', '\164',
+ '\056', '\337', '\321', '\145', '\362', '\331', '\300', '\155',
+ '\156', '\124', '\327', '\056', '\272', '\137', '\117', '\201',
+ '\373', '\232', '\122', '\107', '\267', '\235', '\354', '\113',
+ '\165', '\015', '\052', '\353', '\224', '\175', '\253', '\327',
+ '\343', '\365', '\134', '\253', '\350', '\365', '\250', '\143',
+ '\374', '\245', '\014', '\252', '\035', '\364', '\265', '\363',
+ '\150', '\202', '\364', '\151', '\061', '\117', '\311', '\071',
+ '\314', '\155', '\355', '\257', '\217', '\325', '\272', '\057',
+ '\271', '\315', '\013', '\172', '\075', '\352', '\263', '\344',
+ '\345', '\327', '\045', '\012', '\262', '\115', '\372', '\132',
+ '\306', '\117', '\075', '\162', '\176', '\361', '\252', '\107',
+ '\177', '\077', '\235', '\212', '\013', '\175', '\307', '\117',
+ '\075', '\372', '\032', '\113', '\257', '\117', '\265', '\233',
+ '\134', '\133', '\346', '\033', '\173', '\105', '\220', '\317',
+ '\310', '\170', '\370', '\233', '\177', '\104', '\220', '\276',
+ '\120', '\014', '\367', '\071', '\110', '\237', '\207', '\324',
+ '\266', '\171', '\315', '\101', '\172', '\160', '\153', '\217',
+ '\237', '\266', '\311', '\040', '\366', '\025', '\365', '\161',
+ '\047', '\337', '\063', '\062', '\022', '\273', '\311', '\340',
+ '\066', '\107', '\344', '\153', '\133', '\276', '\271', '\310',
+ '\055', '\350', '\076', '\252', '\256', '\265', '\275', '\326',
+ '\262', '\122', '\237', '\174', '\363', '\234', '\233', '\076',
+ '\302', '\376', '\105', '\171', '\364', '\361', '\362', '\151',
+ '\077', '\373', '\306', '\272', '\315', '\274', '\306', '\003',
+ '\057', '\031', '\165', '\314', '\367', '\043', '\223', '\157',
+ '\376', '\321', '\145', '\324', '\371', '\304', '\317', '\370',
+ '\352', '\246', '\113', '\276', '\367', '\040', '\371', '\256',
+ '\230', '\353', '\375', '\264', '\014', '\027', '\372', '\376',
+ '\130', '\227', '\153', '\145', '\232', '\334', '\110', '\367',
+ '\004', '\275', '\312', '\164', '\253', '\133', '\015', '\162',
+ '\117', '\310', '\153', '\357', '\347', '\122', '\005', '\365',
+ '\335', '\310', '\357', '\172', '\107', '\216', '\023', '\242',
+ '\175', '\162', '\377', '\111', '\256', '\333', '\274', '\374',
+ '\346', '\142', '\366', '\023', '\145', '\137', '\113', '\337',
+ '\224', '\317', '\222', '\127', '\136', '\325', '\217', '\325',
+ '\275', '\316', '\134', '\372', '\350', '\372', '\346', '\262',
+ '\201', '\252', '\213', '\376', '\231', '\116', '\011', '\334',
+ '\237', '\323', '\321', '\354', '\075', '\112', '\075', '\205',
+ '\155', '\305', '\332', '\177', '\072', '\206', '\336', '\001',
+ '\162', '\371', '\277', '\276', '\046', '\220', '\163', '\256',
+ '\237', '\175', '\253', '\122', '\247', '\235', '\262', '\137',
+ '\047', '\301', '\375', '\363', '\057', '\267', '\040', '\327',
+ '\200', '\371', '\366', '\000', '\364', '\266', '\346', '\273',
+ '\057', '\164', '\230', '\011', '\133', '\367', '\253', '\225',
+ '\164', '\276', '\061', '\140', '\244', '\341', '\267', '\361',
+ '\371', '\234', '\334', '\247', '\225', '\143', '\223', '\237',
+ '\317', '\314', '\244', '\214', '\134', '\357', '\352', '\143',
+ '\205', '\133', '\220', '\343', '\337', '\305', '\004', '\267',
+ '\271', '\104', '\330', '\136', '\237', '\357', '\256', '\161',
+ '\256', '\253', '\210', '\161', '\272', '\024', '\336', '\237',
+ '\237', '\352', '\341', '\122', '\175', '\126', '\240', '\352',
+ '\055', '\354', '\065', '\026', '\303', '\307', '\034', '\077',
+ '\301', '\153', '\217', '\316', '\217', '\117', '\251', '\317',
+ '\214', '\372', '\054', '\351', '\301', '\255', '\155', '\342',
+ '\271', '\051', '\163', '\344', '\146', '\343', '\302', '\347',
+ '\310', '\115', '\246', '\310', '\311', '\057', '\337', '\275',
+ '\364', '\317', '\166', '\165', '\337', '\021', '\351', '\053',
+ '\363', '\324', '\003', '\134', '\070', '\016', '\312', '\171',
+ '\324', '\153', '\055', '\066', '\106', '\223', '\121', '\337',
+ '\057', '\325', '\075', '\033', '\065', '\024', '\215', '\102',
+ '\106', '\076', '\243', '\043', '\221', '\221', '\375', '\060',
+ '\022', '\231', '\111', '\243', '\220', '\221', '\371', '\364',
+ '\365', '\115', '\056', '\031', '\021', '\256', '\302', '\360',
+ '\317', '\337', '\305', '\134', '\250', '\376', '\315', '\303',
+ '\034', '\027', '\031', '\077', '\173', '\203', '\352', '\376',
+ '\255', '\332', '\077', '\352', '\336', '\235', '\272', '\106',
+ '\326', '\375', '\273', '\150', '\024', '\062', '\152', '\377',
+ '\370', '\225', '\121', '\155', '\355', '\127', '\106', '\325',
+ '\307', '\153', '\277', '\117', '\367', '\321', '\242', '\121',
+ '\310', '\250', '\372', '\370', '\225', '\121', '\365', '\361',
+ '\053', '\003', '\134', '\270', '\167', '\073', '\023', '\271',
+ '\367', '\156', '\125', '\277', '\226', '\276', '\045', '\367',
+ '\373', '\274', '\366', '\371', '\164', '\273', '\371', '\331',
+ '\257', '\322', '\355', '\346', '\107', '\106', '\267', '\233',
+ '\037', '\031', '\125', '\037', '\277', '\062', '\272', '\255',
+ '\375', '\310', '\350', '\101', '\175', '\057', '\361', '\172',
+ '\047', '\051', '\161', '\312', '\221', '\173', '\250', '\352',
+ '\173', '\217', '\334', '\147', '\025', '\367', '\325', '\171',
+ '\121', '\265', '\265', '\133', '\273', '\362', '\331', '\332',
+ '\257', '\214', '\152', '\153', '\277', '\062', '\252', '\335',
+ '\056', '\246', '\155', '\156', '\373', '\203', '\172', '\160',
+ '\333', '\163', '\312', '\367', '\156', '\056', '\336', '\223',
+ '\345', '\236', '\207', '\034', '\007', '\325', '\275', '\136',
+ '\267', '\367', '\005', '\335', '\267', '\375', '\354', '\213',
+ '\351', '\276', '\355', '\107', '\106', '\367', '\155', '\077',
+ '\062', '\272', '\157', '\373', '\221', '\321', '\175', '\073',
+ '\237', '\214', '\154', '\127', '\361', '\010', '\144', '\364',
+ '\040', '\377', '\136', '\101', '\034', '\345', '\173', '\135',
+ '\276', '\367', '\026', '\257', '\275', '\101', '\165', '\376',
+ '\001', '\334', '\307', '\236', '\174', '\373', '\174', '\156',
+ '\143', '\217', '\337', '\275', '\301', '\221', '\310', '\270',
+ '\215', '\043', '\371', '\144', '\124', '\175', '\374', '\356',
+ '\363', '\025', '\215', '\102', '\106', '\325', '\307', '\257',
+ '\214', '\252', '\217', '\037', '\031', '\371', '\034', '\313',
+ '\375', '\051', '\277', '\373', '\157', '\252', '\137', '\373',
+ '\335', '\347', '\313', '\067', '\007', '\371', '\365', '\203',
+ '\174', '\062', '\371', '\346', '\240', '\174', '\372', '\370',
+ '\225', '\311', '\067', '\007', '\171', '\315', '\077', '\156',
+ '\357', '\212', '\136', '\143', '\250', '\032', '\324', '\271',
+ '\110', '\235', '\203', '\364', '\371', '\107', '\204', '\134',
+ '\163', '\220', '\237', '\061', '\321', '\257', '\114', '\256',
+ '\071', '\310', '\317', '\370', '\166', '\261', '\155', '\313',
+ '\267', '\067', '\350', '\265', '\207', '\077', '\035', '\103',
+ '\237', '\365', '\253', '\266', '\363', '\152', '\233', '\133',
+ '\075', '\316', '\167', '\250', '\372', '\372', '\167', '\366',
+ '\060', '\332', '\261', '\331', '\376', '\362', '\203', '\163',
+ '\252', '\106', '\133', '\031', '\075', '\316', '\324', '\300',
+ '\026', '\345', '\306', '\266', '\376', '\047', '\067', '\061',
+ '\352', '\353', '\355', '\355', '\267', '\043', '\236', '\312',
+ '\157', '\117', '\154', '\144', '\064', '\320', '\315', '\250',
+ '\117', '\134', '\353', '\335', '\302', '\150', '\213', '\225',
+ '\245', '\127', '\210', '\131', '\131', '\304', '\015', '\212',
+ '\155', '\263', '\253', '\264', '\112', '\266', '\242', '\176',
+ '\121', '\174', '\277', '\135', '\121', '\357', '\166', '\121',
+ '\100', '\017', '\057', '\061', '\037', '\233', '\261', '\275',
+ '\177', '\347', '\143', '\172', '\063', '\170', '\152', '\335',
+ '\175', '\214', '\167', '\007', '\267', '\132', '\221', '\270',
+ '\261', '\311', '\322', '\210', '\247', '\275', '\342', '\264',
+ '\157', '\223', '\114', '\135', '\240', '\233', '\217', '\210',
+ '\262', '\073', '\266', '\132', '\221', '\274', '\326', '\277',
+ '\171', '\364', '\105', '\371', '\316', '\074', '\262', '\346',
+ '\146', '\065', '\037', '\112', '\011', '\133', '\365', '\154',
+ '\245', '\021', '\007', '\273', '\244', '\141', '\355', '\326',
+ '\273', '\245', '\172', '\245', '\354', '\100', '\117', '\017',
+ '\243', '\336', '\141', '\315', '\355', '\327', '\242', '\336',
+ '\154', '\224', '\275', '\066', '\340', '\226', '\257', '\147',
+ '\130', '\276', '\301', '\255', '\126', '\067', '\132', '\051',
+ '\273', '\175', '\331', '\256', '\025', '\247', '\331', '\136',
+ '\335', '\341', '\364', '\376', '\066', '\333', '\365', '\006',
+ '\055', '\215', '\204', '\012', '\203', '\326', '\215', '\315',
+ '\062', '\113', '\237', '\350', '\337', '\276', '\115', '\331',
+ '\033', '\135', '\212', '\237', '\156', '\353', '\037', '\174',
+ '\334', '\212', '\262', '\352', '\367', '\016', '\271', '\024',
+ '\243', '\236', '\136', '\073', '\213', '\132', '\336', '\140',
+ '\317', '\260', '\150', '\147', '\317', '\205', '\327', '\334',
+ '\262', '\354', '\354', '\165', '\273', '\053', '\332', '\354',
+ '\104', '\331', '\123', '\177', '\205', '\132', '\316', '\157',
+ '\131', '\050', '\117', '\275', '\071', '\243', '\301', '\341',
+ '\035', '\340', '\356', '\211', '\166', '\244', '\366', '\264',
+ '\217', '\342', '\255', '\307', '\157', '\207', '\247', '\167',
+ '\132', '\217', '\263', '\125', '\245', '\374', '\016', '\025',
+ '\160', '\136', '\031', '\317', '\306', '\140', '\054', '\107',
+ '\302', '\161', '\234', '\261', '\047', '\160', '\124', '\234',
+ '\310', '\321', '\352', '\012', '\216', '\302', '\223', '\071',
+ '\042', '\115', '\345', '\350', '\064', '\215', '\243', '\361',
+ '\164', '\316', '\146', '\063', '\070', '\132', '\315', '\104',
+ '\031', '\307', '\255', '\253', '\160', '\065', '\146', '\143',
+ '\016', '\127', '\203', '\345', '\250', '\300', '\265', '\270',
+ '\016', '\327', '\143', '\056', '\156', '\300', '\215', '\270',
+ '\011', '\363', '\160', '\063', '\156', '\301', '\255', '\230',
+ '\217', '\112', '\334', '\206', '\333', '\121', '\205', '\152',
+ '\054', '\300', '\035', '\130', '\210', '\105', '\130', '\214',
+ '\073', '\261', '\004', '\167', '\341', '\156', '\174', '\032',
+ '\113', '\161', '\017', '\356', '\305', '\175', '\130', '\206',
+ '\000', '\356', '\107', '\015', '\152', '\021', '\304', '\162',
+ '\254', '\300', '\112', '\324', '\341', '\063', '\370', '\054',
+ '\352', '\261', '\012', '\015', '\150', '\304', '\152', '\074',
+ '\040', '\276', '\006', '\214', '\146', '\264', '\340', '\163',
+ '\170', '\020', '\153', '\261', '\016', '\017', '\341', '\363',
+ '\370', '\002', '\176', '\007', '\277', '\213', '\126', '\074',
+ '\214', '\020', '\326', '\043', '\214', '\010', '\014', '\264',
+ '\241', '\035', '\035', '\060', '\361', '\105', '\154', '\100',
+ '\024', '\061', '\304', '\221', '\100', '\047', '\036', '\101',
+ '\022', '\051', '\244', '\221', '\301', '\106', '\074', '\212',
+ '\056', '\164', '\343', '\061', '\074', '\216', '\115', '\170',
+ '\002', '\233', '\161', '\376', '\242', '\303', '\026', '\364',
+ '\140', '\053', '\172', '\261', '\015', '\333', '\321', '\207',
+ '\176', '\354', '\300', '\000', '\166', '\142', '\020', '\117',
+ '\142', '\027', '\276', '\204', '\337', '\303', '\156', '\354',
+ '\301', '\227', '\361', '\373', '\330', '\213', '\247', '\360',
+ '\025', '\074', '\215', '\257', '\142', '\037', '\276', '\206',
+ '\147', '\360', '\165', '\354', '\307', '\067', '\360', '\115',
+ '\174', '\013', '\007', '\160', '\020', '\177', '\200', '\157',
+ '\343', '\020', '\236', '\305', '\167', '\360', '\207', '\070',
+ '\214', '\347', '\360', '\107', '\370', '\143', '\034', '\301',
+ '\363', '\370', '\023', '\274', '\200', '\243', '\170', '\021',
+ '\177', '\212', '\227', '\160', '\014', '\177', '\206', '\077',
+ '\307', '\137', '\340', '\145', '\274', '\202', '\357', '\342',
+ '\173', '\170', '\025', '\337', '\307', '\153', '\370', '\113',
+ '\274', '\216', '\037', '\340', '\257', '\360', '\006', '\336',
+ '\304', '\017', '\361', '\043', '\374', '\030', '\307', '\361',
+ '\026', '\376', '\032', '\177', '\203', '\023', '\370', '\133',
+ '\274', '\215', '\237', '\340', '\044', '\376', '\016', '\077',
+ '\305', '\317', '\160', '\012', '\357', '\340', '\357', '\361',
+ '\017', '\070', '\215', '\177', '\304', '\273', '\370', '\047',
+ '\234', '\301', '\077', '\343', '\347', '\030', '\372', '\116',
+ '\335', '\331', '\202', '\313', '\134', '\346', '\062', '\377',
+ '\027', '\250', '\337', '\153', '\225', '\337', '\025', '\023',
+ '\173', '\271', '\327', '\301', '\376', '\056', '\233', '\370',
+ '\021', '\210', '\273', '\111', '\000', '\366', '\217', '\071',
+ '\064', '\021', '\361', '\013', '\020', '\021', '\022', '\043',
+ '\033', '\311', '\026', '\062', '\100', '\366', '\300', '\376',
+ '\155', '\213', '\203', '\260', '\177', '\364', '\341', '\105',
+ '\362', '\135', '\362', '\006', '\071', '\101', '\336', '\041',
+ '\342', '\271', '\077', '\107', '\176', '\105', '\076', '\026',
+ '\163', '\000', '\333', '\060', '\211', '\314', '\042', '\345',
+ '\344', '\106', '\162', '\073', '\271', '\233', '\004', '\110',
+ '\035', '\151', '\042', '\255', '\304', '\044', '\351', '\002',
+ '\373', '\367', '\037', '\172', '\013', '\354', '\237', '\177',
+ '\330', '\115', '\236', '\046', '\373', '\311', '\101', '\362',
+ '\054', '\171', '\216', '\274', '\100', '\216', '\221', '\127',
+ '\310', '\367', '\311', '\033', '\344', '\055', '\362', '\166',
+ '\201', '\375', '\375', '\334', '\237', '\223', '\177', '\045',
+ '\377', '\106', '\176', '\111', '\376', '\213', '\374', '\067',
+ '\071', '\117', '\012', '\150', '\224', '\261', '\144', '\034',
+ '\231', '\100', '\046', '\222', '\053', '\310', '\144', '\062',
+ '\225', '\114', '\043', '\323', '\311', '\014', '\062', '\223',
+ '\314', '\042', '\127', '\223', '\071', '\244', '\234', '\134',
+ '\113', '\256', '\047', '\067', '\220', '\233', '\310', '\315',
+ '\344', '\126', '\122', '\111', '\156', '\047', '\325', '\344',
+ '\036', '\262', '\202', '\064', '\223', '\207', '\311', '\006',
+ '\362', '\010', '\111', '\221', '\014', '\171', '\224', '\164',
+ '\223', '\307', '\311', '\023', '\144', '\013', '\331', '\112',
+ '\266', '\221', '\076', '\262', '\203', '\354', '\044', '\117',
+ '\222', '\057', '\221', '\335', '\344', '\313', '\144', '\057',
+ '\371', '\012', '\371', '\052', '\371', '\032', '\371', '\072',
+ '\371', '\006', '\371', '\026', '\071', '\110', '\276', '\115',
+ '\236', '\045', '\057', '\220', '\227', '\310', '\153', '\344',
+ '\055', '\362', '\023', '\362', '\056', '\171', '\217', '\234',
+ '\043', '\277', '\044', '\277', '\042', '\347', '\205', '\015',
+ '\304', '\367', '\224', '\311', '\125', '\344', '\106', '\262',
+ '\220', '\334', '\107', '\226', '\223', '\007', '\310', '\132',
+ '\322', '\112', '\114', '\222', '\041', '\333', '\310', '\116',
+ '\262', '\213', '\074', '\115', '\236', '\045', '\317', '\223',
+ '\127', '\310', '\217', '\310', '\073', '\344', '\054', '\071',
+ '\107', '\176', '\115', '\306', '\362', '\145', '\150', '\022',
+ '\231', '\106', '\346', '\220', '\271', '\344', '\066', '\262',
+ '\220', '\334', '\111', '\226', '\221', '\025', '\244', '\201',
+ '\074', '\124', '\150', '\377', '\006', '\312', '\006', '\222',
+ '\044', '\233', '\311', '\000', '\331', '\105', '\366', '\222',
+ '\147', '\310', '\101', '\362', '\074', '\071', '\106', '\136',
+ '\043', '\077', '\046', '\157', '\223', '\167', '\310', '\031',
+ '\162', '\216', '\374', '\007', '\371', '\117', '\162', '\136',
+ '\324', '\075', '\216', '\165', '\213', '\357', '\130', '\223',
+ '\271', '\344', '\126', '\262', '\210', '\174', '\232', '\334',
+ '\113', '\126', '\220', '\006', '\322', '\102', '\102', '\144',
+ '\003', '\111', '\222', '\156', '\322', '\107', '\166', '\223',
+ '\275', '\344', '\031', '\162', '\220', '\034', '\046', '\307',
+ '\310', '\367', '\310', '\017', '\311', '\011', '\362', '\063',
+ '\362', '\056', '\371', '\027', '\362', '\013', '\362', '\033',
+ '\362', '\077', '\244', '\160', '\074', '\337', '\277', '\110',
+ '\304', '\150', '\013', '\145', '\242', '\351', '\160', '\107',
+ '\050', '\211', '\114', '\334', '\134', '\260', '\250', '\146',
+ '\061', '\122', '\035', '\241', '\210', '\141', '\235', '\055',
+ '\254', '\272', '\313', '\071', '\326', '\070', '\307', '\132',
+ '\347', '\030', '\240', '\144', '\173', '\322', '\060', '\320',
+ '\031', '\315', '\244', '\142', '\146', '\074', '\223', '\262',
+ '\157', '\054', '\130', '\350', '\144', '\270', '\037', '\115',
+ '\313', '\253', '\026', '\126', '\061', '\210', '\304', '\035',
+ '\062', '\121', '\055', '\023', '\013', '\144', '\142', '\221',
+ '\225', '\020', '\102', '\167', '\334', '\037', '\160', '\216',
+ '\102', '\330', '\312', '\051', '\157', '\324', '\070', '\307',
+ '\132', '\041', '\261', '\104', '\212', '\336', '\045', '\023',
+ '\167', '\312', '\304', '\142', '\047', '\121', '\155', '\327',
+ '\023', '\065', '\122', '\051', '\343', '\221', '\114', '\050',
+ '\012', '\266', '\065', '\224', '\066', '\222', '\366', '\111',
+ '\247', '\211', '\170', '\042', '\155', '\247', '\123', '\274',
+ '\032', '\065', '\343', '\355', '\350', '\064', '\222', '\146',
+ '\042', '\022', '\066', '\342', '\042', '\133', '\004', '\251',
+ '\316', '\120', '\330', '\200', '\321', '\025', '\216', '\206',
+ '\142', '\170', '\044', '\303', '\354', '\221', '\365', '\121',
+ '\304', '\063', '\261', '\365', '\106', '\062', '\145', '\266',
+ '\307', '\021', '\111', '\104', '\243', '\064', '\032', '\305',
+ '\204', '\014', '\102', '\061', '\246', '\122', '\241', '\170',
+ '\304', '\316', '\234', '\142', '\221', '\121', '\132', '\047',
+ '\224', '\064', '\342', '\121', '\243', '\055', '\155', '\247',
+ '\222', '\146', '\173', '\007', '\263', '\212', '\072', '\315',
+ '\324', '\006', '\313', '\166', '\010', '\047', '\142', '\261',
+ '\020', '\072', '\272', '\073', '\073', '\214', '\270', '\323',
+ '\010', '\244', '\242', '\241', '\124', '\007', '\036', '\063',
+ '\222', '\011', '\044', '\342', '\006', '\322', '\217', '\046',
+ '\220', '\356', '\020', '\326', '\156', '\113', '\144', '\222',
+ '\150', '\063', '\067', '\032', '\110', '\231', '\135', '\110',
+ '\031', '\033', '\051', '\143', '\130', '\205', '\306', '\115',
+ '\146', '\014', '\047', '\242', '\211', '\070', '\057', '\307',
+ '\114', '\073', '\045', '\364', '\307', '\060', '\003', '\260',
+ '\165', '\106', '\052', '\155', '\362', '\136', '\050', '\075',
+ '\252', '\205', '\350', '\372', '\144', '\050', '\274', '\301',
+ '\110', '\133', '\072', '\255', '\147', '\322', '\156', '\252',
+ '\163', '\125', '\352', '\027', '\066', '\315', '\260', '\231',
+ '\014', '\147', '\142', '\354', '\266', '\010', '\315', '\022',
+ '\116', '\044', '\015', '\266', '\040', '\304', '\166', '\217',
+ '\146', '\361', '\052', '\112', '\067', '\234', '\032', '\223',
+ '\366', '\231', '\122', '\123', '\332', '\214', '\322', '\135',
+ '\325', '\376', '\212', '\044', '\036', '\215', '\303', '\352',
+ '\225', '\154', '\357', '\206', '\063', '\111', '\332', '\077',
+ '\334', '\215', '\156', '\132', '\154', '\175', '\062', '\261',
+ '\301', '\210', '\213', '\262', '\122', '\106', '\330', '\062',
+ '\106', '\304', '\144', '\247', '\247', '\114', '\321', '\033',
+ '\235', '\335', '\166', '\331', '\211', '\144', '\244', '\215',
+ '\206', '\264', '\354', '\332', '\236', '\061', '\243', '\121',
+ '\043', '\226', '\260', '\325', '\216', '\046', '\332', '\315',
+ '\160', '\050', '\112', '\027', '\222', '\335', '\226', '\064',
+ '\332', '\315', '\224', '\355', '\067', '\261', '\120', '\070',
+ '\051', '\012', '\324', '\237', '\016', '\366', '\141', '\052',
+ '\143', '\165', '\157', '\322', '\356', '\313', '\354', '\131',
+ '\050', '\234', '\111', '\033', '\210', '\145', '\204', '\213',
+ '\204', '\150', '\244', '\316', '\016', '\335', '\027', '\303',
+ '\106', '\204', '\365', '\207', '\204', '\057', '\144', '\245',
+ '\330', '\274', '\030', '\325', '\317', '\104', '\207', '\265',
+ '\317', '\151', '\172', '\134', '\364', '\171', '\122', '\164',
+ '\067', '\223', '\035', '\241', '\150', '\233', '\135', '\245',
+ '\163', '\061', '\225', '\165', '\002', '\313', '\120', '\001',
+ '\273', '\143', '\002', '\166', '\073', '\002', '\166', '\307',
+ '\265', '\105', '\215', '\056', '\004', '\154', '\323', '\006',
+ '\262', '\326', '\011', '\044', '\205', '\055', '\003', '\101',
+ '\324', '\310', '\046', '\005', '\155', '\341', '\240', '\055',
+ '\034', '\124', '\204', '\203', '\131', '\251', '\072', '\073',
+ '\117', '\235', '\235', '\247', '\116', '\311', '\123', '\227',
+ '\315', '\023', '\114', '\167', '\240', '\301', '\256', '\256',
+ '\321', '\316', '\336', '\150', '\147', '\157', '\124', '\262',
+ '\067', '\072', '\031', '\262', '\122', '\061', '\016', '\135',
+ '\146', '\147', '\264', '\033', '\215', '\266', '\033', '\266',
+ '\330', '\242', '\055', '\266', '\150', '\213', '\042', '\332',
+ '\222', '\225', '\131', '\147', '\337', '\154', '\356', '\110',
+ '\044', '\343', '\150', '\067', '\222', '\061', '\076', '\263',
+ '\353', '\243', '\051', '\204', '\034', '\377', '\264', '\157',
+ '\207', '\024', '\331', '\220', '\135', '\155', '\050', '\133',
+ '\104', '\310', '\062', '\103', '\210', '\317', '\233', '\064',
+ '\203', '\141', '\013', '\033', '\266', '\260', '\241', '\010',
+ '\033', '\131', '\051', '\323', '\316', '\143', '\332', '\171',
+ '\114', '\045', '\217', '\231', '\315', '\143', '\320', '\014',
+ '\161', '\273', '\272', '\204', '\235', '\075', '\141', '\147',
+ '\117', '\050', '\331', '\023', '\116', '\206', '\254', '\124',
+ '\304', '\334', '\150', '\212', '\013', '\266', '\021', '\062',
+ '\266', '\140', '\306', '\026', '\314', '\050', '\202', '\231',
+ '\254', '\104', '\267', '\175', '\063', '\155', '\031', '\241',
+ '\073', '\173', '\371', '\322', '\375', '\156', '\322', '\377',
+ '\002', '\174', '\155', '\142', '\140', '\200', '\114', '\000',
+ '\000',
+
+};
+
+static char name_6x13[] = "-misc-fixed-medium-r-semicondensed--13-120-75-75-c-60-iso8859-1";
+static char name_cursor[] = "cursor";
+
+const BuiltinFileRec builtin_files[] = {
+ { "6x13.builtin", sizeof file_6x13, file_6x13, },
+ { "cursor.builtin", sizeof file_cursor, file_cursor, }
+};
+
+const int builtin_files_count = sizeof (builtin_files) / sizeof (builtin_files[0]);
+
+const BuiltinDirRec builtin_dir[] = {
+ { "6x13.builtin", name_6x13, },
+ { "cursor.builtin", name_cursor, }
+};
+
+const int builtin_dir_count = sizeof (builtin_dir) / sizeof (builtin_dir[0]);
+
+static char alias_fixed[] = "fixed";
+static char alias_6x13[] = "6x13";
+static char alias_6x13_100[] = "-misc-fixed-medium-r-semicondensed--13-100-100-100-c-60-iso8859-1";
+
+const BuiltinAliasRec builtin_alias[] = {
+ { alias_fixed, name_6x13, },
+ { alias_6x13, name_6x13, },
+ { alias_6x13_100, name_6x13, }
+};
+
+const int builtin_alias_count = sizeof (builtin_alias) / sizeof (builtin_alias[0]);
diff --git a/libXfont/src/builtins/fpe.c b/libXfont/src/builtins/fpe.c
new file mode 100644
index 000000000..5fce45ba7
--- /dev/null
+++ b/libXfont/src/builtins/fpe.c
@@ -0,0 +1,95 @@
+/* $XdotOrg: $ */
+/*
+ * Id: fpe.c,v 1.2 1999/11/02 06:16:48 keithp Exp $
+ *
+ * Copyright 1999 SuSE, Inc.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of SuSE not be used in advertising or
+ * publicity pertaining to distribution of the software without specific,
+ * written prior permission. SuSE makes no representations about the
+ * suitability of this software for any purpose. It is provided "as is"
+ * without express or implied warranty.
+ *
+ * SuSE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL SuSE
+ * BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Author: Keith Packard, SuSE, Inc.
+ */
+/* $XFree86: xc/lib/font/builtins/fpe.c,v 1.3 1999/12/30 02:29:51 robin Exp $ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include <X11/fonts/fntfilst.h>
+#include "builtin.h"
+
+static int font_file_type;
+
+static const char builtin_fonts[] = "built-ins";
+
+static int
+BuiltinNameCheck (char *name)
+{
+ return (strcmp (name, builtin_fonts) == 0);
+}
+
+static int
+BuiltinInitFPE (FontPathElementPtr fpe)
+{
+ int status;
+ FontDirectoryPtr dir;
+
+ status = BuiltinReadDirectory (fpe->name, &dir);
+
+ if (status == Successful)
+ fpe->private = (pointer) dir;
+ return status;
+}
+
+/* ARGSUSED */
+static int
+BuiltinResetFPE (FontPathElementPtr fpe)
+{
+ FontDirectoryPtr dir;
+
+ dir = (FontDirectoryPtr) fpe->private;
+ /* builtins can't change! */
+ return Successful;
+}
+
+static int
+BuiltinFreeFPE (FontPathElementPtr fpe)
+{
+ FontFileFreeDir ((FontDirectoryPtr) fpe->private);
+ return Successful;
+}
+
+void
+BuiltinRegisterFpeFunctions(void)
+{
+ BuiltinRegisterFontFileFunctions ();
+
+ font_file_type = RegisterFPEFunctions(BuiltinNameCheck,
+ BuiltinInitFPE,
+ BuiltinFreeFPE,
+ BuiltinResetFPE,
+ FontFileOpenFont,
+ FontFileCloseFont,
+ FontFileListFonts,
+ FontFileStartListFontsWithInfo,
+ FontFileListNextFontWithInfo,
+ (WakeupFpeFunc) 0,
+ (ClientDiedFunc) 0,
+ (LoadGlyphsFunc) 0,
+ (StartLaFunc) 0,
+ (NextLaFunc) 0,
+ (SetPathFunc) 0);
+}
diff --git a/libXfont/src/builtins/render.c b/libXfont/src/builtins/render.c
new file mode 100644
index 000000000..871665f89
--- /dev/null
+++ b/libXfont/src/builtins/render.c
@@ -0,0 +1,136 @@
+/* $XdotOrg: $ */
+/*
+ * Id: render.c,v 1.2 1999/11/02 06:16:48 keithp Exp $
+ *
+ * Copyright 1999 SuSE, Inc.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of SuSE not be used in advertising or
+ * publicity pertaining to distribution of the software without specific,
+ * written prior permission. SuSE makes no representations about the
+ * suitability of this software for any purpose. It is provided "as is"
+ * without express or implied warranty.
+ *
+ * SuSE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL SuSE
+ * BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Author: Keith Packard, SuSE, Inc.
+ */
+/* $XFree86: xc/lib/font/builtins/render.c,v 1.3 1999/12/30 02:29:51 robin Exp $ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include <X11/fonts/fntfilst.h>
+#include <X11/fonts/fontutil.h>
+#include <X11/fonts/pcf.h>
+#include "builtin.h"
+
+static int
+BuiltinOpenBitmap (FontPathElementPtr fpe, FontPtr *ppFont, int flags,
+ FontEntryPtr entry, char *fileName, fsBitmapFormat format,
+ fsBitmapFormatMask fmask, FontPtr unused)
+{
+ FontFilePtr file;
+ FontPtr pFont;
+ int ret;
+ int bit,
+ byte,
+ glyph,
+ scan,
+ image;
+
+ file = BuiltinFileOpen (fileName);
+ if (!file)
+ return BadFontName;
+ pFont = (FontPtr) xalloc(sizeof(FontRec));
+ if (!pFont) {
+ BuiltinFileClose (file, 0);
+ return AllocError;
+ }
+ /* set up default values */
+ FontDefaultFormat(&bit, &byte, &glyph, &scan);
+ /* get any changes made from above */
+ ret = CheckFSFormat(format, fmask, &bit, &byte, &scan, &glyph, &image);
+
+ /* Fill in font record. Data format filled in by reader. */
+ pFont->refcnt = 0;
+ pFont->maxPrivate = -1;
+ pFont->devPrivates = (pointer *) 0;
+
+ ret = pcfReadFont (pFont, file, bit, byte, glyph, scan);
+
+ BuiltinFileClose (file, 0);
+ if (ret != Successful)
+ xfree(pFont);
+ else
+ *ppFont = pFont;
+ return ret;
+}
+
+static int
+BuiltinGetInfoBitmap (FontPathElementPtr fpe, FontInfoPtr pFontInfo,
+ FontEntryPtr entry, char *fileName)
+{
+ FontFilePtr file;
+ int ret;
+
+ file = BuiltinFileOpen (fileName);
+ if (!file)
+ return BadFontName;
+ ret = pcfReadFontInfo (pFontInfo, file);
+ BuiltinFileClose (file, 0);
+ return ret;
+}
+
+static int
+BuiltinOpenScalable (FontPathElementPtr fpe,
+ FontPtr *pFont,
+ int flags,
+ FontEntryPtr entry,
+ char *fileName,
+ FontScalablePtr vals,
+ fsBitmapFormat format,
+ fsBitmapFormatMask fmask,
+ FontPtr non_cachable_font) /* We don't do licensing */
+{
+ return BadFontName;
+}
+
+static int
+BuiltinGetInfoScalable (FontPathElementPtr fpe,
+ FontInfoPtr pFontInfo,
+ FontEntryPtr entry,
+ FontNamePtr fontName,
+ char *fileName,
+ FontScalablePtr vals)
+{
+ return BadFontName;
+}
+
+static FontRendererRec renderers[] = {
+ { ".builtin", 8,
+ BuiltinOpenBitmap,
+ BuiltinOpenScalable,
+ BuiltinGetInfoBitmap,
+ BuiltinGetInfoScalable,
+ 0 }
+};
+
+#define numRenderers (sizeof renderers / sizeof renderers[0])
+
+void
+BuiltinRegisterFontFileFunctions(void)
+{
+ int i;
+ for (i = 0; i < numRenderers; i++)
+ FontFileRegisterRenderer ((FontRendererRec *) &renderers[i]);
+}
+
diff --git a/libXfont/src/dummy.c b/libXfont/src/dummy.c
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/libXfont/src/dummy.c
diff --git a/libXfont/src/fc/Makefile.am b/libXfont/src/fc/Makefile.am
new file mode 100644
index 000000000..3bfd231f2
--- /dev/null
+++ b/libXfont/src/fc/Makefile.am
@@ -0,0 +1,16 @@
+INCLUDES = \
+ -I${top_srcdir}/include
+
+AM_CFLAGS = $(XFONT_CFLAGS) $(OS_CFLAGS) $(CWARNFLAGS)
+
+noinst_LTLIBRARIES = libfc.la
+
+libfc_la_SOURCES = \
+ fsconvert.c \
+ fserve.c \
+ fserve.h \
+ fservestr.h \
+ fsio.c \
+ fsio.h \
+ fslibos.h \
+ fstrans.c
diff --git a/libXfont/src/fc/Makefile.in b/libXfont/src/fc/Makefile.in
new file mode 100644
index 000000000..77afa8db3
--- /dev/null
+++ b/libXfont/src/fc/Makefile.in
@@ -0,0 +1,462 @@
+# Makefile.in generated by automake 1.10 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
+# 2003, 2004, 2005, 2006 Free Software Foundation, Inc.
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+@SET_MAKE@
+
+VPATH = @srcdir@
+pkgdatadir = $(datadir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+install_sh_DATA = $(install_sh) -c -m 644
+install_sh_PROGRAM = $(install_sh) -c
+install_sh_SCRIPT = $(install_sh) -c
+INSTALL_HEADER = $(INSTALL_DATA)
+transform = $(program_transform_name)
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+build_triplet = @build@
+host_triplet = @host@
+subdir = src/fc
+DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/configure.ac
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+ $(ACLOCAL_M4)
+mkinstalldirs = $(install_sh) -d
+CONFIG_HEADER = $(top_builddir)/config.h \
+ $(top_builddir)/include/X11/fonts/fontconf.h
+CONFIG_CLEAN_FILES =
+LTLIBRARIES = $(noinst_LTLIBRARIES)
+libfc_la_LIBADD =
+am_libfc_la_OBJECTS = fsconvert.lo fserve.lo fsio.lo fstrans.lo
+libfc_la_OBJECTS = $(am_libfc_la_OBJECTS)
+DEFAULT_INCLUDES = -I. -I$(top_builddir) -I$(top_builddir)/include/X11/fonts@am__isrc@
+depcomp = $(SHELL) $(top_srcdir)/depcomp
+am__depfiles_maybe = depfiles
+COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
+ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+LTCOMPILE = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
+ --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \
+ $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+CCLD = $(CC)
+LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
+ --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \
+ $(LDFLAGS) -o $@
+SOURCES = $(libfc_la_SOURCES)
+DIST_SOURCES = $(libfc_la_SOURCES)
+ETAGS = etags
+CTAGS = ctags
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+ACLOCAL = @ACLOCAL@
+AMTAR = @AMTAR@
+AR = @AR@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+CC = @CC@
+CCDEPMODE = @CCDEPMODE@
+CFLAGS = @CFLAGS@
+CHANGELOG_CMD = @CHANGELOG_CMD@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CWARNFLAGS = @CWARNFLAGS@
+CXX = @CXX@
+CXXCPP = @CXXCPP@
+CXXDEPMODE = @CXXDEPMODE@
+CXXFLAGS = @CXXFLAGS@
+CYGPATH_W = @CYGPATH_W@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+ECHO = @ECHO@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+EGREP = @EGREP@
+ENCODINGSDIR = @ENCODINGSDIR@
+EXEEXT = @EXEEXT@
+F77 = @F77@
+FFLAGS = @FFLAGS@
+FREETYPE_CFLAGS = @FREETYPE_CFLAGS@
+FREETYPE_LIBS = @FREETYPE_LIBS@
+FREETYPE_REQUIRES = @FREETYPE_REQUIRES@
+GREP = @GREP@
+INSTALL = @INSTALL@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+LDFLAGS = @LDFLAGS@
+LIBOBJS = @LIBOBJS@
+LIBS = @LIBS@
+LIBTOOL = @LIBTOOL@
+LN_S = @LN_S@
+LTLIBOBJS = @LTLIBOBJS@
+MAKEINFO = @MAKEINFO@
+MATH_LIBS = @MATH_LIBS@
+MKDIR_P = @MKDIR_P@
+OBJEXT = @OBJEXT@
+OS_CFLAGS = @OS_CFLAGS@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+PKG_CONFIG = @PKG_CONFIG@
+RANLIB = @RANLIB@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+STRIP = @STRIP@
+VERSION = @VERSION@
+XFONT_CFLAGS = @XFONT_CFLAGS@
+XFONT_LIBS = @XFONT_LIBS@
+X_GZIP_FONT_COMPRESSION = @X_GZIP_FONT_COMPRESSION@
+Z_LIBS = @Z_LIBS@
+abs_builddir = @abs_builddir@
+abs_srcdir = @abs_srcdir@
+abs_top_builddir = @abs_top_builddir@
+abs_top_srcdir = @abs_top_srcdir@
+ac_ct_CC = @ac_ct_CC@
+ac_ct_CXX = @ac_ct_CXX@
+ac_ct_F77 = @ac_ct_F77@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+am__tar = @am__tar@
+am__untar = @am__untar@
+bindir = @bindir@
+build = @build@
+build_alias = @build_alias@
+build_cpu = @build_cpu@
+build_os = @build_os@
+build_vendor = @build_vendor@
+builddir = @builddir@
+datadir = @datadir@
+datarootdir = @datarootdir@
+distcleancheck_listfiles = @distcleancheck_listfiles@
+docdir = @docdir@
+dvidir = @dvidir@
+exec_prefix = @exec_prefix@
+ft_config = @ft_config@
+host = @host@
+host_alias = @host_alias@
+host_cpu = @host_cpu@
+host_os = @host_os@
+host_vendor = @host_vendor@
+htmldir = @htmldir@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+libdir = @libdir@
+libexecdir = @libexecdir@
+localedir = @localedir@
+localstatedir = @localstatedir@
+mandir = @mandir@
+mkdir_p = @mkdir_p@
+oldincludedir = @oldincludedir@
+pdfdir = @pdfdir@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+psdir = @psdir@
+sbindir = @sbindir@
+sharedstatedir = @sharedstatedir@
+srcdir = @srcdir@
+sysconfdir = @sysconfdir@
+target_alias = @target_alias@
+top_builddir = @top_builddir@
+top_srcdir = @top_srcdir@
+INCLUDES = \
+ -I${top_srcdir}/include
+
+AM_CFLAGS = $(XFONT_CFLAGS) $(OS_CFLAGS) $(CWARNFLAGS)
+noinst_LTLIBRARIES = libfc.la
+libfc_la_SOURCES = \
+ fsconvert.c \
+ fserve.c \
+ fserve.h \
+ fservestr.h \
+ fsio.c \
+ fsio.h \
+ fslibos.h \
+ fstrans.c
+
+all: all-am
+
+.SUFFIXES:
+.SUFFIXES: .c .lo .o .obj
+$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps)
+ @for dep in $?; do \
+ case '$(am__configure_deps)' in \
+ *$$dep*) \
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh \
+ && exit 0; \
+ exit 1;; \
+ esac; \
+ done; \
+ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign src/fc/Makefile'; \
+ cd $(top_srcdir) && \
+ $(AUTOMAKE) --foreign src/fc/Makefile
+.PRECIOUS: Makefile
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+ @case '$?' in \
+ *config.status*) \
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
+ *) \
+ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
+ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
+ esac;
+
+$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+
+$(top_srcdir)/configure: $(am__configure_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(ACLOCAL_M4): $(am__aclocal_m4_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+
+clean-noinstLTLIBRARIES:
+ -test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES)
+ @list='$(noinst_LTLIBRARIES)'; for p in $$list; do \
+ dir="`echo $$p | sed -e 's|/[^/]*$$||'`"; \
+ test "$$dir" != "$$p" || dir=.; \
+ echo "rm -f \"$${dir}/so_locations\""; \
+ rm -f "$${dir}/so_locations"; \
+ done
+libfc.la: $(libfc_la_OBJECTS) $(libfc_la_DEPENDENCIES)
+ $(LINK) $(libfc_la_OBJECTS) $(libfc_la_LIBADD) $(LIBS)
+
+mostlyclean-compile:
+ -rm -f *.$(OBJEXT)
+
+distclean-compile:
+ -rm -f *.tab.c
+
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fsconvert.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fserve.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fsio.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fstrans.Plo@am__quote@
+
+.c.o:
+@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
+@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(COMPILE) -c $<
+
+.c.obj:
+@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'`
+@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(COMPILE) -c `$(CYGPATH_W) '$<'`
+
+.c.lo:
+@am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
+@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(LTCOMPILE) -c -o $@ $<
+
+mostlyclean-libtool:
+ -rm -f *.lo
+
+clean-libtool:
+ -rm -rf .libs _libs
+
+ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) ' { files[$$0] = 1; } \
+ END { for (i in files) print i; }'`; \
+ mkid -fID $$unique
+tags: TAGS
+
+TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
+ $(TAGS_FILES) $(LISP)
+ tags=; \
+ here=`pwd`; \
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) ' { files[$$0] = 1; } \
+ END { for (i in files) print i; }'`; \
+ if test -z "$(ETAGS_ARGS)$$tags$$unique"; then :; else \
+ test -n "$$unique" || unique=$$empty_fix; \
+ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+ $$tags $$unique; \
+ fi
+ctags: CTAGS
+CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
+ $(TAGS_FILES) $(LISP)
+ tags=; \
+ here=`pwd`; \
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) ' { files[$$0] = 1; } \
+ END { for (i in files) print i; }'`; \
+ test -z "$(CTAGS_ARGS)$$tags$$unique" \
+ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
+ $$tags $$unique
+
+GTAGS:
+ here=`$(am__cd) $(top_builddir) && pwd` \
+ && cd $(top_srcdir) \
+ && gtags -i $(GTAGS_ARGS) $$here
+
+distclean-tags:
+ -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
+
+distdir: $(DISTFILES)
+ @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ list='$(DISTFILES)'; \
+ dist_files=`for file in $$list; do echo $$file; done | \
+ sed -e "s|^$$srcdirstrip/||;t" \
+ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
+ case $$dist_files in \
+ */*) $(MKDIR_P) `echo "$$dist_files" | \
+ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
+ sort -u` ;; \
+ esac; \
+ for file in $$dist_files; do \
+ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
+ if test -d $$d/$$file; then \
+ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
+ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
+ cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \
+ fi; \
+ cp -pR $$d/$$file $(distdir)$$dir || exit 1; \
+ else \
+ test -f $(distdir)/$$file \
+ || cp -p $$d/$$file $(distdir)/$$file \
+ || exit 1; \
+ fi; \
+ done
+check-am: all-am
+check: check-am
+all-am: Makefile $(LTLIBRARIES)
+installdirs:
+install: install-am
+install-exec: install-exec-am
+install-data: install-data-am
+uninstall: uninstall-am
+
+install-am: all-am
+ @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-am
+install-strip:
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ `test -z '$(STRIP)' || \
+ echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
+mostlyclean-generic:
+
+clean-generic:
+
+distclean-generic:
+ -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
+
+maintainer-clean-generic:
+ @echo "This command is intended for maintainers to use"
+ @echo "it deletes files that may require special tools to rebuild."
+clean: clean-am
+
+clean-am: clean-generic clean-libtool clean-noinstLTLIBRARIES \
+ mostlyclean-am
+
+distclean: distclean-am
+ -rm -rf ./$(DEPDIR)
+ -rm -f Makefile
+distclean-am: clean-am distclean-compile distclean-generic \
+ distclean-tags
+
+dvi: dvi-am
+
+dvi-am:
+
+html: html-am
+
+info: info-am
+
+info-am:
+
+install-data-am:
+
+install-dvi: install-dvi-am
+
+install-exec-am:
+
+install-html: install-html-am
+
+install-info: install-info-am
+
+install-man:
+
+install-pdf: install-pdf-am
+
+install-ps: install-ps-am
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-am
+ -rm -rf ./$(DEPDIR)
+ -rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-am
+
+mostlyclean-am: mostlyclean-compile mostlyclean-generic \
+ mostlyclean-libtool
+
+pdf: pdf-am
+
+pdf-am:
+
+ps: ps-am
+
+ps-am:
+
+uninstall-am:
+
+.MAKE: install-am install-strip
+
+.PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \
+ clean-libtool clean-noinstLTLIBRARIES ctags distclean \
+ distclean-compile distclean-generic distclean-libtool \
+ distclean-tags distdir dvi dvi-am html html-am info info-am \
+ install install-am install-data install-data-am install-dvi \
+ install-dvi-am install-exec install-exec-am install-html \
+ install-html-am install-info install-info-am install-man \
+ install-pdf install-pdf-am install-ps install-ps-am \
+ install-strip installcheck installcheck-am installdirs \
+ maintainer-clean maintainer-clean-generic mostlyclean \
+ mostlyclean-compile mostlyclean-generic mostlyclean-libtool \
+ pdf pdf-am ps ps-am tags uninstall uninstall-am
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/libXfont/src/fc/fsconvert.c b/libXfont/src/fc/fsconvert.c
new file mode 100644
index 000000000..8cdda2a79
--- /dev/null
+++ b/libXfont/src/fc/fsconvert.c
@@ -0,0 +1,724 @@
+/* $Xorg: fsconvert.c,v 1.3 2000/08/17 19:46:36 cpqbld Exp $ */
+/*
+ * Copyright 1990 Network Computing Devices
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and
+ * its documentation for any purpose is hereby granted without fee, provided
+ * that the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of Network Computing Devices not be used
+ * in advertising or publicity pertaining to distribution of the software
+ * without specific, written prior permission. Network Computing Devices
+ * makes no representations about the suitability of this software for any
+ * purpose. It is provided "as is" without express or implied warranty.
+ *
+ * NETWORK COMPUTING DEVICES DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
+ * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS,
+ * IN NO EVENT SHALL NETWORK COMPUTING DEVICES BE LIABLE FOR ANY SPECIAL,
+ * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+ * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+ * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE
+ * OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Author: Dave Lemke, Network Computing Devices, Inc
+ */
+/* $XFree86: xc/lib/font/fc/fsconvert.c,v 1.14 2003/08/30 18:06:29 dawes Exp $ */
+/*
+ * FS data conversion
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include <X11/X.h>
+#include <X11/Xtrans/Xtrans.h>
+#include <X11/Xpoll.h>
+#include <X11/fonts/FS.h>
+#include <X11/fonts/FSproto.h>
+#include <X11/fonts/fontmisc.h>
+#include <X11/fonts/fontstruct.h>
+#include "fservestr.h"
+#include <X11/fonts/fontutil.h>
+#include "fslibos.h"
+
+extern char _fs_glyph_undefined;
+extern char _fs_glyph_requested;
+
+/*
+ * converts data from font server form to X server form
+ */
+
+void
+_fs_convert_char_info(fsXCharInfo *src, xCharInfo *dst)
+{
+ dst->ascent = src->ascent;
+ dst->descent = src->descent;
+ dst->leftSideBearing = src->left;
+ dst->rightSideBearing = src->right;
+ dst->characterWidth = src->width;
+ dst->attributes = src->attributes;
+}
+
+void
+_fs_init_fontinfo(FSFpePtr conn, FontInfoPtr pfi)
+{
+ if (conn->fsMajorVersion == 1) {
+ unsigned short n;
+ n = pfi->firstCol;
+ pfi->firstCol = pfi->firstRow;
+ pfi->firstRow = n;
+ n = pfi->lastCol;
+ pfi->lastCol = pfi->lastRow;
+ pfi->lastRow = n;
+ pfi->defaultCh = ((pfi->defaultCh >> 8) & 0xff)
+ + ((pfi->defaultCh & 0xff) << 8);
+ }
+
+ if (FontCouldBeTerminal (pfi))
+ {
+ pfi->terminalFont = TRUE;
+ pfi->minbounds.ascent = pfi->fontAscent;
+ pfi->minbounds.descent = pfi->fontDescent;
+ pfi->minbounds.leftSideBearing = 0;
+ pfi->minbounds.rightSideBearing = pfi->minbounds.characterWidth;
+ pfi->maxbounds = pfi->minbounds;
+ }
+
+ FontComputeInfoAccelerators (pfi);
+}
+
+int
+_fs_convert_props(fsPropInfo *pi, fsPropOffset *po, pointer pd,
+ FontInfoPtr pfi)
+{
+ FontPropPtr dprop;
+ int i,
+ nprops;
+ char *is_str;
+ fsPropOffset local_off;
+ char *off_adr;
+ char *pdc = pd;
+
+/* stolen from server/include/resource.h */
+#define BAD_RESOURCE 0xe0000000
+
+ nprops = pfi->nprops = pi->num_offsets;
+
+ if (nprops < 0
+ || nprops > SIZE_MAX/(sizeof(FontPropRec) + sizeof(char)))
+ return -1;
+
+ dprop = (FontPropPtr) xalloc(sizeof(FontPropRec) * nprops +
+ sizeof (char) * nprops);
+ if (!dprop)
+ return -1;
+
+ is_str = (char *) (dprop + nprops);
+ pfi->props = dprop;
+ pfi->isStringProp = is_str;
+
+ off_adr = (char *)po;
+ for (i = 0; i < nprops; i++, dprop++, is_str++)
+ {
+ memcpy(&local_off, off_adr, SIZEOF(fsPropOffset));
+ dprop->name = MakeAtom(&pdc[local_off.name.position],
+ local_off.name.length, 1);
+ if (local_off.type != PropTypeString) {
+ *is_str = FALSE;
+ dprop->value = local_off.value.position;
+ } else {
+ *is_str = TRUE;
+ dprop->value = (INT32) MakeAtom(&pdc[local_off.value.position],
+ local_off.value.length, 1);
+ if (dprop->value == BAD_RESOURCE)
+ {
+ xfree (pfi->props);
+ pfi->nprops = 0;
+ pfi->props = 0;
+ pfi->isStringProp = 0;
+ return -1;
+ }
+ }
+ off_adr += SIZEOF(fsPropOffset);
+ }
+
+ return nprops;
+}
+
+void
+_fs_free_props (FontInfoPtr pfi)
+{
+ if (pfi->props)
+ {
+ xfree (pfi->props);
+ pfi->nprops = 0;
+ pfi->props = 0;
+ }
+}
+
+int
+_fs_convert_lfwi_reply(FSFpePtr conn, FontInfoPtr pfi,
+ fsListFontsWithXInfoReply *fsrep,
+ fsPropInfo *pi, fsPropOffset *po, pointer pd)
+{
+ fsUnpack_XFontInfoHeader(fsrep, pfi);
+ _fs_init_fontinfo(conn, pfi);
+
+ if (_fs_convert_props(pi, po, pd, pfi) == -1)
+ return AllocError;
+
+ return Successful;
+}
+
+
+#define ENCODING_UNDEFINED(enc) \
+ ((enc)->bits == &_fs_glyph_undefined ? \
+ TRUE : \
+ (access_done = access_done && (enc)->bits != &_fs_glyph_requested, \
+ FALSE))
+
+#define GLYPH_UNDEFINED(loc) ENCODING_UNDEFINED(encoding + (loc))
+
+/*
+ * figures out what glyphs to request
+ *
+ * Includes logic to attempt to reduce number of round trips to the font
+ * server: when a glyph is requested, fs_build_range() requests a
+ * 16-glyph range of glyphs that contains the requested glyph. This is
+ * predicated on the belief that using a glyph increases the chances
+ * that nearby glyphs will be used: a good assumption for phonetic
+ * alphabets, but a questionable one for ideographic/pictographic ones.
+ */
+/* ARGSUSED */
+int
+fs_build_range(FontPtr pfont, Bool range_flag, unsigned int count,
+ int item_size, unsigned char *data, int *nranges,
+ fsRange **ranges)
+{
+ FSFontDataPtr fsd = (FSFontDataPtr) (pfont->fpePrivate);
+ FSFontPtr fsfont = (FSFontPtr) (pfont->fontPrivate);
+ register CharInfoPtr encoding = fsfont->encoding;
+ FontInfoPtr pfi = &(pfont->info);
+ fsRange range;
+ int access_done = TRUE;
+ int err;
+ register unsigned long firstrow, lastrow, firstcol, lastcol;
+ register unsigned long row;
+ register unsigned long col;
+ register unsigned long loc;
+
+ if (!fsd->glyphs_to_get)
+ return AccessDone;
+
+ firstrow = pfi->firstRow;
+ lastrow = pfi->lastRow;
+ firstcol = pfi->firstCol;
+ lastcol = pfi->lastCol;
+
+ /* Make sure we have default char */
+ if (fsfont->pDefault && ENCODING_UNDEFINED(fsfont->pDefault))
+ {
+ loc = fsfont->pDefault - encoding;
+ row = loc / (lastcol - firstcol + 1) + firstrow;
+ col = loc % (lastcol - firstcol + 1) + firstcol;
+
+ range.min_char_low = range.max_char_low = col;
+ range.min_char_high = range.max_char_high = row;
+
+ if ((err = add_range(&range, nranges, ranges, FALSE)) !=
+ Successful) return err;
+ encoding[loc].bits = &_fs_glyph_requested;
+ access_done = FALSE;
+ }
+
+ if (!range_flag && item_size == 1)
+ {
+ if (firstrow != 0) return AccessDone;
+ while (count--)
+ {
+ col = *data++;
+ if (col >= firstcol && col <= lastcol &&
+ GLYPH_UNDEFINED(col - firstcol))
+ {
+ int col1, col2;
+ col1 = col & 0xf0;
+ col2 = col1 + 15;
+ if (col1 < firstcol) col1 = firstcol;
+ if (col2 > lastcol) col2 = lastcol;
+ /* Collect a 16-glyph neighborhood containing the requested
+ glyph... should in most cases reduce the number of round
+ trips to the font server. */
+ for (col = col1; col <= col2; col++)
+ {
+ if (!GLYPH_UNDEFINED(col - firstcol)) continue;
+ range.min_char_low = range.max_char_low = col;
+ range.min_char_high = range.max_char_high = 0;
+ if ((err = add_range(&range, nranges, ranges, FALSE)) !=
+ Successful) return err;
+ encoding[col - firstcol].bits = &_fs_glyph_requested;
+ access_done = FALSE;
+ }
+ }
+ }
+ }
+ else
+ {
+ fsRange fullrange[1];
+
+ if (range_flag && count == 0)
+ {
+ count = 2;
+ data = (unsigned char *)fullrange;
+ fullrange[0].min_char_high = firstrow;
+ fullrange[0].min_char_low = firstcol;
+ fullrange[0].max_char_high = lastrow;
+ fullrange[0].max_char_low = lastcol;
+ }
+
+ while (count--)
+ {
+ int row1, col1, row2, col2;
+ row1 = row2 = *data++;
+ col1 = col2 = *data++;
+ if (range_flag)
+ {
+ if (count)
+ {
+ row2 = *data++;
+ col2 = *data++;
+ count--;
+ }
+ else
+ {
+ row2 = lastrow;
+ col2 = lastcol;
+ }
+ if (row1 < firstrow) row1 = firstrow;
+ if (row2 > lastrow) row2 = lastrow;
+ if (col1 < firstcol) col1 = firstcol;
+ if (col2 > lastcol) col2 = lastcol;
+ }
+ else
+ {
+ if (row1 < firstrow || row1 > lastrow ||
+ col1 < firstcol || col1 > lastcol)
+ continue;
+ }
+ for (row = row1; row <= row2; row++)
+ {
+ expand_glyph_range: ;
+ loc = (row - firstrow) * (lastcol + 1 - firstcol) +
+ (col1 - firstcol);
+ for (col = col1; col <= col2; col++, loc++)
+ {
+ if (GLYPH_UNDEFINED(loc))
+ {
+ if (row1 == row2 &&
+ (((col1 & 0xf) && col1 > firstcol) ||
+ (col2 & 0xf) != 0xf) && (col2 < lastcol))
+ {
+ /* If we're loading from a single row, expand
+ range of glyphs loaded to a multiple of
+ a 16-glyph range -- attempt to reduce number
+ of round trips to the font server. */
+ col1 &= 0xf0;
+ col2 = (col2 & 0xf0) + 15;
+ if (col1 < firstcol) col1 = firstcol;
+ if (col2 > lastcol) col2 = lastcol;
+ goto expand_glyph_range;
+ }
+ range.min_char_low = range.max_char_low = col;
+ range.min_char_high = range.max_char_high = row;
+ if ((err = add_range(&range, nranges, ranges, FALSE)) !=
+ Successful) return err;
+ encoding[loc].bits = &_fs_glyph_requested;
+ access_done = FALSE;
+ }
+ }
+ }
+ }
+ }
+
+ return access_done ?
+ AccessDone :
+ Successful;
+}
+
+#undef GLYPH_UNDEFINED
+#undef ENCODING_UNDEFINED
+
+
+/* _fs_clean_aborted_loadglyphs(): Undoes the changes to the encoding array
+ performed by fs_build_range(); for use if the associated LoadGlyphs
+ requests needs to be cancelled. */
+
+void
+_fs_clean_aborted_loadglyphs(FontPtr pfont, int num_expected_ranges,
+ fsRange *expected_ranges)
+{
+ register FSFontPtr fsfont;
+ register int i;
+
+ fsfont = (FSFontPtr) pfont->fontPrivate;
+ if (fsfont->encoding)
+ {
+ fsRange full_range[1];
+ if (!num_expected_ranges)
+ {
+ full_range[0].min_char_low = pfont->info.firstCol;
+ full_range[0].min_char_high = pfont->info.firstRow;
+ full_range[0].max_char_low = pfont->info.lastCol;
+ full_range[0].max_char_high = pfont->info.lastRow;
+ num_expected_ranges = 1;
+ expected_ranges = full_range;
+ }
+
+ for (i = 0; i < num_expected_ranges; i++)
+ {
+ int row, col;
+ for (row = expected_ranges[i].min_char_high;
+ row <= expected_ranges[i].max_char_high;
+ row++)
+ {
+ register CharInfoPtr encoding = fsfont->encoding +
+ ((row - pfont->info.firstRow) *
+ (pfont->info.lastCol -
+ pfont->info.firstCol + 1) +
+ expected_ranges[i].min_char_low -
+ pfont->info.firstCol);
+ for (col = expected_ranges[i].min_char_low;
+ col <= expected_ranges[i].max_char_low;
+ encoding++, col++)
+ {
+ if (encoding->bits == &_fs_glyph_requested)
+ encoding->bits = &_fs_glyph_undefined;
+ }
+ }
+ }
+ }
+}
+
+static int
+_fs_get_glyphs(FontPtr pFont, unsigned long count, unsigned char *chars,
+ FontEncoding charEncoding,
+ unsigned long *glyphCount, /* RETURN */
+ CharInfoPtr *glyphs) /* RETURN */
+{
+ FSFontPtr fsdata;
+ unsigned int firstCol;
+ register unsigned int numCols;
+ unsigned int firstRow;
+ unsigned int numRows;
+ CharInfoPtr *glyphsBase;
+ register unsigned int c;
+ register CharInfoPtr pci;
+ unsigned int r;
+ CharInfoPtr encoding;
+ CharInfoPtr pDefault;
+ FSFontDataPtr fsd = (FSFontDataPtr) pFont->fpePrivate;
+ int err = Successful;
+
+ fsdata = (FSFontPtr) pFont->fontPrivate;
+ encoding = fsdata->encoding;
+ pDefault = fsdata->pDefault;
+ firstCol = pFont->info.firstCol;
+ numCols = pFont->info.lastCol - firstCol + 1;
+ glyphsBase = glyphs;
+
+ /* In this age of glyph caching, any glyphs gotten through this
+ procedure should already be loaded. If they are not, we are
+ dealing with someone (perhaps a ddx driver optimizing a font)
+ that doesn't understand the finer points of glyph caching. The
+ CHECK_ENCODING macro checks for this condition... if found, it
+ calls fs_load_all_glyphs(), which corrects it. Since the caller
+ of this code will not know how to handle a return value of
+ Suspended, the fs_load_all_glyphs() procedure will block and
+ freeze the server until the load operation is done. Moral: the
+ glyphCachingMode flag really must indicate the capabilities of
+ the ddx drivers. */
+
+#define CHECK_ENCODING(cnum) \
+ ( pci = encoding + (cnum), \
+ fsd->glyphs_to_get ? \
+ ( pci->bits == &_fs_glyph_undefined || pci->bits == &_fs_glyph_requested ? \
+ ((err = fs_load_all_glyphs(pFont)), pci) : \
+ pci ) : \
+ pci )
+
+ switch (charEncoding) {
+
+ case Linear8Bit:
+ case TwoD8Bit:
+ if (pFont->info.firstRow > 0)
+ break;
+ if (pFont->info.allExist && pDefault) {
+ while (err == Successful && count--) {
+ c = (*chars++) - firstCol;
+ if (c < numCols)
+ *glyphs++ = CHECK_ENCODING(c);
+ else
+ *glyphs++ = pDefault;
+ }
+ } else {
+ while (err == Successful && count--) {
+ c = (*chars++) - firstCol;
+ if (c < numCols && CHECK_ENCODING(c)->bits)
+ *glyphs++ = pci;
+ else if (pDefault)
+ *glyphs++ = pDefault;
+ }
+ }
+ break;
+ case Linear16Bit:
+ if (pFont->info.allExist && pDefault) {
+ while (err == Successful && count--) {
+ c = *chars++ << 8;
+ c = (c | *chars++) - firstCol;
+ if (c < numCols)
+ *glyphs++ = CHECK_ENCODING(c);
+ else
+ *glyphs++ = pDefault;
+ }
+ } else {
+ while (err == Successful && count--) {
+ c = *chars++ << 8;
+ c = (c | *chars++) - firstCol;
+ if (c < numCols && CHECK_ENCODING(c)->bits)
+ *glyphs++ = pci;
+ else if (pDefault)
+ *glyphs++ = pDefault;
+ }
+ }
+ break;
+
+ case TwoD16Bit:
+ firstRow = pFont->info.firstRow;
+ numRows = pFont->info.lastRow - firstRow + 1;
+ while (err == Successful && count--) {
+ r = (*chars++) - firstRow;
+ c = (*chars++) - firstCol;
+ if (r < numRows && c < numCols &&
+ CHECK_ENCODING(r * numCols + c)->bits)
+ *glyphs++ = pci;
+ else if (pDefault)
+ *glyphs++ = pDefault;
+ }
+ break;
+ }
+ *glyphCount = glyphs - glyphsBase;
+ return err;
+}
+
+
+static int
+_fs_get_metrics(FontPtr pFont, unsigned long count, unsigned char *chars,
+ FontEncoding charEncoding,
+ unsigned long *glyphCount, /* RETURN */
+ xCharInfo **glyphs) /* RETURN */
+{
+ FSFontPtr fsdata;
+ unsigned int firstCol;
+ register unsigned int numCols;
+ unsigned int firstRow;
+ unsigned int numRows;
+ xCharInfo **glyphsBase;
+ register unsigned int c;
+ unsigned int r;
+ CharInfoPtr encoding;
+ CharInfoPtr pDefault;
+
+ fsdata = (FSFontPtr) pFont->fontPrivate;
+ encoding = fsdata->inkMetrics;
+ pDefault = fsdata->pDefault;
+ /* convert default bitmap metric to default ink metric */
+ if (pDefault)
+ pDefault = encoding + (pDefault - fsdata->encoding);
+ firstCol = pFont->info.firstCol;
+ numCols = pFont->info.lastCol - firstCol + 1;
+ glyphsBase = glyphs;
+
+
+ /* XXX - this should be much smarter */
+ /* make sure the glyphs are there */
+ switch (charEncoding) {
+
+ case Linear8Bit:
+ case TwoD8Bit:
+ if (pFont->info.firstRow > 0)
+ break;
+ if (pFont->info.allExist && pDefault) {
+ while (count--) {
+ c = (*chars++) - firstCol;
+ if (c < numCols)
+ *glyphs++ = (xCharInfo *)&encoding[c];
+ else
+ *glyphs++ = (xCharInfo *)pDefault;
+ }
+ } else {
+ while (count--) {
+ c = (*chars++) - firstCol;
+ if (c < numCols)
+ *glyphs++ = (xCharInfo *)(encoding + c);
+ else if (pDefault)
+ *glyphs++ = (xCharInfo *)pDefault;
+ }
+ }
+ break;
+ case Linear16Bit:
+ if (pFont->info.allExist && pDefault) {
+ while (count--) {
+ c = *chars++ << 8;
+ c = (c | *chars++) - firstCol;
+ if (c < numCols)
+ *glyphs++ = (xCharInfo *)(encoding + c);
+ else
+ *glyphs++ = (xCharInfo *)pDefault;
+ }
+ } else {
+ while (count--) {
+ c = *chars++ << 8;
+ c = (c | *chars++) - firstCol;
+ if (c < numCols)
+ *glyphs++ = (xCharInfo *)(encoding + c);
+ else if (pDefault)
+ *glyphs++ = (xCharInfo *)pDefault;
+ }
+ }
+ break;
+
+ case TwoD16Bit:
+ firstRow = pFont->info.firstRow;
+ numRows = pFont->info.lastRow - firstRow + 1;
+ while (count--) {
+ r = (*chars++) - firstRow;
+ c = (*chars++) - firstCol;
+ if (r < numRows && c < numCols)
+ *glyphs++ = (xCharInfo *)(encoding + (r * numCols + c));
+ else if (pDefault)
+ *glyphs++ = (xCharInfo *)pDefault;
+ }
+ break;
+ }
+ *glyphCount = glyphs - glyphsBase;
+ return Successful;
+}
+
+
+static void
+_fs_unload_font(FontPtr pfont)
+{
+ FSFontPtr fsdata = (FSFontPtr) pfont->fontPrivate;
+ FSFontDataPtr fsd = (FSFontDataPtr) pfont->fpePrivate;
+ CharInfoPtr encoding = fsdata->encoding;
+ FSGlyphPtr glyphs;
+
+ /*
+ * fsdata points at FSFontRec, FSFontDataRec and name
+ */
+ if (encoding)
+ xfree(encoding);
+
+ while ((glyphs = fsdata->glyphs))
+ {
+ fsdata->glyphs = glyphs->next;
+ xfree (glyphs);
+ }
+
+ /* XXX we may get called after the resource DB has been cleaned out */
+ if (find_old_font(fsd->fontid))
+ DeleteFontClientID (fsd->fontid);
+
+ _fs_free_props (&pfont->info);
+
+ xfree(fsdata);
+
+ DestroyFontRec(pfont);
+}
+
+FontPtr
+fs_create_font (FontPathElementPtr fpe,
+ char *name,
+ int namelen,
+ fsBitmapFormat format,
+ fsBitmapFormatMask fmask)
+{
+ FontPtr pfont;
+ FSFontPtr fsfont;
+ FSFontDataPtr fsd;
+ int bit, byte, scan, glyph;
+
+ pfont = CreateFontRec ();
+ if (!pfont)
+ return 0;
+ fsfont = (FSFontPtr) xalloc (sizeof (FSFontRec) +
+ sizeof (FSFontDataRec) +
+ namelen + 1);
+ if (!fsfont)
+ {
+ DestroyFontRec (pfont);
+ return 0;
+ }
+ fsd = (FSFontDataPtr) (fsfont + 1);
+ bzero((char *) fsfont, sizeof(FSFontRec));
+ bzero((char *) fsd, sizeof(FSFontDataRec));
+
+ pfont->fpe = fpe;
+ pfont->fontPrivate = (pointer) fsfont;
+ pfont->fpePrivate = (pointer) fsd;
+
+ /* These font components will be needed in packGlyphs */
+ CheckFSFormat(format, BitmapFormatMaskBit |
+ BitmapFormatMaskByte |
+ BitmapFormatMaskScanLineUnit |
+ BitmapFormatMaskScanLinePad,
+ &bit,
+ &byte,
+ &scan,
+ &glyph,
+ NULL);
+ pfont->format = format;
+ pfont->bit = bit;
+ pfont->byte = byte;
+ pfont->scan = scan;
+ pfont->glyph = glyph;
+
+ pfont->info.nprops = 0;
+ pfont->info.props = 0;
+ pfont->info.isStringProp = 0;
+
+ /* set font function pointers */
+ pfont->get_glyphs = _fs_get_glyphs;
+ pfont->get_metrics = _fs_get_metrics;
+ pfont->unload_font = _fs_unload_font;
+ pfont->unload_glyphs = NULL;
+
+ /* set the FPE private information */
+ fsd->format = format;
+ fsd->fmask = fmask;
+ fsd->name = (char *) (fsd + 1);
+ memcpy (fsd->name, name, namelen);
+ fsd->name[namelen] = '\0';
+ fsd->fontid = GetNewFontClientID ();
+
+ /* save the ID */
+ if (!StoreFontClientFont(pfont, fsd->fontid))
+ {
+ xfree (fsfont);
+ DestroyFontRec (pfont);
+ return 0;
+ }
+
+ return pfont;
+}
+
+pointer
+fs_alloc_glyphs (FontPtr pFont, int size)
+{
+ FSGlyphPtr glyphs;
+ FSFontPtr fsfont = (FSFontPtr) pFont->fontPrivate;
+
+ glyphs = xalloc (sizeof (FSGlyphRec) + size);
+ glyphs->next = fsfont->glyphs;
+ fsfont->glyphs = glyphs;
+ return (pointer) (glyphs + 1);
+}
diff --git a/libXfont/src/fc/fserve.c b/libXfont/src/fc/fserve.c
new file mode 100644
index 000000000..07ada34b6
--- /dev/null
+++ b/libXfont/src/fc/fserve.c
@@ -0,0 +1,3269 @@
+/* $XdotOrg: lib/Xfont/src/fc/fserve.c,v 1.8 2005/07/09 06:36:12 keithp Exp $ */
+/* $Xorg: fserve.c,v 1.4 2001/02/09 02:04:02 xorgcvs Exp $ */
+/*
+
+Copyright 1990, 1998 The Open Group
+
+Permission to use, copy, modify, distribute, and sell this software and its
+documentation for any purpose is hereby granted without fee, provided that
+the above copyright notice appear in all copies and that both that
+copyright notice and this permission notice appear in supporting
+documentation.
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of The Open Group shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from The Open Group.
+
+*/
+/* $XFree86: xc/lib/font/fc/fserve.c,v 3.26tsi Exp $ */
+
+/*
+ * Copyright 1990 Network Computing Devices
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and
+ * its documentation for any purpose is hereby granted without fee, provided
+ * that the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the names of Network Computing Devices, or Digital
+ * not be used in advertising or publicity pertaining to distribution
+ * of the software without specific, written prior permission.
+ *
+ * NETWORK COMPUTING DEVICES, AND DIGITAL AND DISCLAIM ALL WARRANTIES WITH
+ * REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL NETWORK COMPUTING DEVICES,
+ * OR DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
+ * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
+ * THIS SOFTWARE.
+ *
+ * Author: Dave Lemke, Network Computing Devices, Inc
+ */
+/*
+ * font server specific font access
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#ifdef WIN32
+#define _WILLWINSOCK_
+#endif
+#define FONT_t
+#define TRANS_CLIENT
+#include "X11/Xtrans/Xtrans.h"
+#include "X11/Xpoll.h"
+#include <X11/fonts/FS.h>
+#include <X11/fonts/FSproto.h>
+#include <X11/X.h>
+#include <X11/Xos.h>
+#include <X11/fonts/fontmisc.h>
+#include <X11/fonts/fontstruct.h>
+#include "fservestr.h"
+#include <X11/fonts/fontutil.h>
+#include <errno.h>
+
+#include <time.h>
+#define Time_t time_t
+
+#ifdef NCD
+#include <ncd/nvram.h>
+#endif
+
+#include <stddef.h>
+
+#ifndef MIN
+#define MIN(a,b) ((a)<(b)?(a):(b))
+#endif
+#define TimeCmp(a,c,b) ((int) ((a) - (b)) c 0)
+
+#define NONZEROMETRICS(pci) ((pci)->leftSideBearing || \
+ (pci)->rightSideBearing || \
+ (pci)->ascent || \
+ (pci)->descent || \
+ (pci)->characterWidth)
+
+extern void ErrorF(const char *f, ...);
+
+static int fs_read_glyphs ( FontPathElementPtr fpe, FSBlockDataPtr blockrec );
+static int fs_read_list ( FontPathElementPtr fpe, FSBlockDataPtr blockrec );
+static int fs_read_list_info ( FontPathElementPtr fpe,
+ FSBlockDataPtr blockrec );
+
+extern fd_set _fs_fd_mask;
+
+static void fs_block_handler ( pointer data, OSTimePtr wt,
+ pointer LastSelectMask );
+static int fs_wakeup ( FontPathElementPtr fpe, unsigned long *mask );
+
+/*
+ * List of all FPEs
+ */
+static FSFpePtr fs_fpes;
+/*
+ * Union of all FPE blockStates
+ */
+static CARD32 fs_blockState;
+
+static int _fs_restart_connection ( FSFpePtr conn );
+static void fs_send_query_bitmaps ( FontPathElementPtr fpe,
+ FSBlockDataPtr blockrec );
+static int fs_send_close_font ( FontPathElementPtr fpe, Font id );
+static void fs_client_died ( pointer client, FontPathElementPtr fpe );
+static void _fs_client_access ( FSFpePtr conn, pointer client, Bool sync );
+static void _fs_client_resolution ( FSFpePtr conn );
+static fsGenericReply *fs_get_reply (FSFpePtr conn, int *error);
+static int fs_await_reply (FSFpePtr conn);
+static void _fs_do_blocked (FSFpePtr conn);
+static void fs_cleanup_bfont (FSBlockedFontPtr bfont);
+
+char _fs_glyph_undefined;
+char _fs_glyph_requested;
+static char _fs_glyph_zero_length;
+
+static int generationCount;
+
+static int FontServerRequestTimeout = 30 * 1000;
+
+static void
+_fs_close_server (FSFpePtr conn);
+
+static FSFpePtr
+_fs_init_conn (char *servername);
+
+static int
+_fs_wait_connect (FSFpePtr conn);
+
+static int
+_fs_send_init_packets (FSFpePtr conn);
+
+static void
+_fs_check_reconnect (FSFpePtr conn);
+
+static void
+_fs_start_reconnect (FSFpePtr conn);
+
+static void
+_fs_free_conn (FSFpePtr conn);
+
+static int
+fs_free_fpe(FontPathElementPtr fpe);
+
+/*
+ * Font server access
+ *
+ * the basic idea for the non-blocking access is to have the function
+ * called multiple times until the actual data is returned, instead
+ * of ClientBlocked.
+ *
+ * the first call to the function will cause the request to be sent to
+ * the font server, and a block record to be stored in the fpe's list
+ * of outstanding requests. the FS block handler also sticks the
+ * proper set of fd's into the select mask. when data is ready to be
+ * read in, the FS wakup handler will be hit. this will read the
+ * data off the wire into the proper block record, and then signal the
+ * client that caused the block so that it can restart. it will then
+ * call the access function again, which will realize that the data has
+ * arrived and return it.
+ */
+
+
+#ifdef DEBUG
+static void
+_fs_add_req_log(FSFpePtr conn, int opcode)
+{
+ conn->current_seq++;
+ fprintf (stderr, "\t\tRequest: %5d Opcode: %2d\n",
+ conn->current_seq, opcode);
+ conn->reqbuffer[conn->reqindex].opcode = opcode;
+ conn->reqbuffer[conn->reqindex].sequence = conn->current_seq;
+ conn->reqindex++;
+ if (conn->reqindex == REQUEST_LOG_SIZE)
+ conn->reqindex = 0;
+}
+
+static void
+_fs_add_rep_log (FSFpePtr conn, fsGenericReply *rep)
+{
+ int i;
+
+ for (i = 0; i < REQUEST_LOG_SIZE; i++)
+ if (conn->reqbuffer[i].sequence == rep->sequenceNumber)
+ break;
+ if (i == REQUEST_LOG_SIZE)
+ fprintf (stderr, "\t\t\t\t\tReply: %5d Opcode: unknown\n",
+ rep->sequenceNumber);
+ else
+ fprintf (stderr, "\t\t\t\t\tReply: %5d Opcode: %d\n",
+ rep->sequenceNumber,
+ conn->reqbuffer[i].opcode);
+}
+#else
+#define _fs_add_req_log(conn,op) ((conn)->current_seq++)
+#define _fs_add_rep_log(conn,rep)
+#endif
+
+static Bool
+fs_name_check(char *name)
+{
+#ifdef __UNIXOS2__
+ /* OS/2 uses D:/usr/X11R6/.... as fontfile pathnames, so check that
+ * there is not only a protocol/ prefix, but also that the first chars
+ * are not a drive letter
+ */
+ if (name && isalpha(*name) && name[1] == ':')
+ return FALSE;
+#endif
+ /* Just make sure there is a protocol/ prefix */
+ return (name && *name != '/' && strchr(name, '/'));
+}
+
+static void
+_fs_client_resolution(FSFpePtr conn)
+{
+ fsSetResolutionReq srreq;
+ int num_res;
+ FontResolutionPtr res;
+
+ res = GetClientResolutions(&num_res);
+
+ if (num_res) {
+ srreq.reqType = FS_SetResolution;
+ srreq.num_resolutions = num_res;
+ srreq.length = (SIZEOF(fsSetResolutionReq) +
+ (num_res * SIZEOF(fsResolution)) + 3) >> 2;
+
+ _fs_add_req_log(conn, FS_SetResolution);
+ if (_fs_write(conn, (char *) &srreq, SIZEOF(fsSetResolutionReq)) != -1)
+ (void)_fs_write_pad(conn, (char *) res,
+ (num_res * SIZEOF(fsResolution)));
+ }
+}
+
+/*
+ * close font server and remove any state associated with
+ * this connection - this includes any client records.
+ */
+
+static void
+fs_close_conn(FSFpePtr conn)
+{
+ FSClientPtr client, nclient;
+
+ _fs_close_server (conn);
+
+ for (client = conn->clients; client; client = nclient)
+ {
+ nclient = client->next;
+ xfree (client);
+ }
+ conn->clients = NULL;
+}
+
+/*
+ * the wakeup handlers have to be set when the FPE is open, and not
+ * removed until it is freed, in order to handle unexpected data, like
+ * events
+ */
+/* ARGSUSED */
+static int
+fs_init_fpe(FontPathElementPtr fpe)
+{
+ FSFpePtr conn;
+ char *name;
+ int err;
+ int ret;
+
+ /* open font server */
+ /* create FS specific fpe info */
+ name = fpe->name;
+
+ /* hack for old style names */
+ if (*name == ':')
+ name++; /* skip ':' */
+
+ conn = _fs_init_conn (name);
+ if (!conn)
+ err = AllocError;
+ else
+ {
+ err = init_fs_handlers (fpe, fs_block_handler);
+ if (err != Successful)
+ {
+ _fs_free_conn (conn);
+ err = AllocError;
+ }
+ else
+ {
+ fpe->private = conn;
+ conn->next = fs_fpes;
+ fs_fpes = conn;
+ ret = _fs_wait_connect (conn);
+ if (ret != FSIO_READY)
+ {
+ fs_free_fpe (fpe);
+ err = BadFontPath;
+ }
+ else
+ err = Successful;
+ }
+ }
+
+ if (err == Successful)
+ {
+#ifdef NCD
+ if (configData.ExtendedFontDiags)
+ printf("Connected to font server \"%s\"\n", name);
+#endif
+#ifdef DEBUG
+ fprintf (stderr, "connected to FS \"%s\"\n", name);
+#endif
+ }
+ else
+ {
+#ifdef DEBUG
+ fprintf(stderr, "failed to connect to FS \"%s\" %d\n", name, err);
+#endif
+#ifdef NCD
+ if (configData.ExtendedFontDiags)
+ printf("Failed to connect to font server \"%s\"\n", name);
+#endif
+ ;
+ }
+ return err;
+}
+
+static int
+fs_reset_fpe(FontPathElementPtr fpe)
+{
+ (void) _fs_send_init_packets((FSFpePtr) fpe->private);
+ return Successful;
+}
+
+/*
+ * this shouldn't be called till all refs to the FPE are gone
+ */
+
+static int
+fs_free_fpe(FontPathElementPtr fpe)
+{
+ FSFpePtr conn = (FSFpePtr) fpe->private, *prev;
+
+ /* unhook from chain of all font servers */
+ for (prev = &fs_fpes; *prev; prev = &(*prev)->next)
+ {
+ if (*prev == conn)
+ {
+ *prev = conn->next;
+ break;
+ }
+ }
+ _fs_unmark_block (conn, conn->blockState);
+ fs_close_conn(conn);
+ remove_fs_handlers(fpe, fs_block_handler, fs_fpes == 0);
+ _fs_free_conn (conn);
+ fpe->private = (pointer) 0;
+
+#ifdef NCD
+ if (configData.ExtendedFontDiags)
+ printf("Disconnected from font server \"%s\"\n", fpe->name);
+#endif
+#ifdef DEBUG
+ fprintf (stderr, "disconnect from FS \"%s\"\n", fpe->name);
+#endif
+
+ return Successful;
+}
+
+static FSBlockDataPtr
+fs_new_block_rec(FontPathElementPtr fpe, pointer client, int type)
+{
+ FSBlockDataPtr blockrec,
+ *prev;
+ FSFpePtr conn = (FSFpePtr) fpe->private;
+ int size;
+
+ switch (type) {
+ case FS_OPEN_FONT:
+ size = sizeof(FSBlockedFontRec);
+ break;
+ case FS_LOAD_GLYPHS:
+ size = sizeof(FSBlockedGlyphRec);
+ break;
+ case FS_LIST_FONTS:
+ size = sizeof(FSBlockedListRec);
+ break;
+ case FS_LIST_WITH_INFO:
+ size = sizeof(FSBlockedListInfoRec);
+ break;
+ default:
+ size = 0;
+ break;
+ }
+ blockrec = (FSBlockDataPtr) xalloc(sizeof(FSBlockDataRec) + size);
+ if (!blockrec)
+ return (FSBlockDataPtr) 0;
+ blockrec->data = (pointer) (blockrec + 1);
+ blockrec->client = client;
+ blockrec->sequenceNumber = -1;
+ blockrec->errcode = StillWorking;
+ blockrec->type = type;
+ blockrec->depending = 0;
+ blockrec->next = (FSBlockDataPtr) 0;
+
+ /* stick it on the end of the list (since its expected last) */
+ for (prev = &conn->blockedRequests; *prev; prev = &(*prev)->next)
+ ;
+ *prev = blockrec;
+
+ return blockrec;
+}
+
+static void
+_fs_set_pending_reply (FSFpePtr conn)
+{
+ FSBlockDataPtr blockrec;
+
+ for (blockrec = conn->blockedRequests; blockrec; blockrec = blockrec->next)
+ if (blockrec->errcode == StillWorking)
+ break;
+ if (blockrec)
+ {
+ conn->blockedReplyTime = GetTimeInMillis () + FontServerRequestTimeout;
+ _fs_mark_block (conn, FS_PENDING_REPLY);
+ }
+ else
+ _fs_unmark_block (conn, FS_PENDING_REPLY);
+}
+
+static void
+_fs_remove_block_rec(FSFpePtr conn, FSBlockDataPtr blockrec)
+{
+ FSBlockDataPtr *prev;
+
+ for (prev = &conn->blockedRequests; *prev; prev = &(*prev)->next)
+ if (*prev == blockrec)
+ {
+ *prev = blockrec->next;
+ break;
+ }
+ if (blockrec->type == FS_LOAD_GLYPHS)
+ {
+ FSBlockedGlyphPtr bglyph = (FSBlockedGlyphPtr)blockrec->data;
+ if (bglyph->num_expected_ranges)
+ xfree(bglyph->expected_ranges);
+ }
+ xfree(blockrec);
+ _fs_set_pending_reply (conn);
+}
+
+static void
+_fs_signal_clients_depending(FSClientsDependingPtr *clients_depending)
+{
+ FSClientsDependingPtr p;
+
+ while ((p = *clients_depending))
+ {
+ *clients_depending = p->next;
+ ClientSignal(p->client);
+ xfree(p);
+ }
+}
+
+static int
+_fs_add_clients_depending(FSClientsDependingPtr *clients_depending, pointer client)
+{
+ FSClientsDependingPtr new, cd;
+
+ for (; (cd = *clients_depending);
+ clients_depending = &(*clients_depending)->next)
+ {
+ if (cd->client == client)
+ return Suspended;
+ }
+
+ new = (FSClientsDependingPtr)xalloc (sizeof (FSClientsDependingRec));
+ if (!new)
+ return BadAlloc;
+
+ new->client = client;
+ new->next = 0;
+ *clients_depending = new;
+ return Suspended;
+}
+
+/*
+ * When a request is aborted due to a font server failure,
+ * signal any depending clients to restart their dependant
+ * requests
+ */
+static void
+_fs_clean_aborted_blockrec(FSFpePtr conn, FSBlockDataPtr blockrec)
+{
+ switch(blockrec->type) {
+ case FS_OPEN_FONT: {
+ FSBlockedFontPtr bfont = (FSBlockedFontPtr)blockrec->data;
+
+ fs_cleanup_bfont (bfont);
+ _fs_signal_clients_depending(&bfont->clients_depending);
+ break;
+ }
+ case FS_LOAD_GLYPHS: {
+ FSBlockedGlyphPtr bglyph = (FSBlockedGlyphPtr)blockrec->data;
+
+ _fs_clean_aborted_loadglyphs(bglyph->pfont,
+ bglyph->num_expected_ranges,
+ bglyph->expected_ranges);
+ _fs_signal_clients_depending(&bglyph->clients_depending);
+ break;
+ }
+ case FS_LIST_FONTS:
+ break;
+ case FS_LIST_WITH_INFO: {
+ FSBlockedListInfoPtr binfo;
+ binfo = (FSBlockedListInfoPtr) blockrec->data;
+ if (binfo->status == FS_LFWI_REPLY)
+ FD_SET(conn->fs_fd, &_fs_fd_mask);
+ _fs_free_props (&binfo->info);
+ }
+ default:
+ break;
+ }
+}
+
+static void
+fs_abort_blockrec(FSFpePtr conn, FSBlockDataPtr blockrec)
+{
+ _fs_clean_aborted_blockrec (conn, blockrec);
+ _fs_remove_block_rec (conn, blockrec);
+}
+
+/*
+ * Tell the font server we've failed to complete an open and
+ * then unload the partially created font
+ */
+static void
+fs_cleanup_bfont (FSBlockedFontPtr bfont)
+{
+ FSFontDataRec *fsd;
+
+ if (bfont->pfont)
+ {
+ fsd = (FSFontDataRec *) bfont->pfont->fpePrivate;
+
+ /* make sure the FS knows we choked on it */
+ fs_send_close_font(bfont->pfont->fpe, bfont->fontid);
+
+ /*
+ * Either unload the font if it's being opened for
+ * the first time, or smash the generation field to
+ * mark this font as an orphan
+ */
+ if (!(bfont->flags & FontReopen))
+ {
+ if (bfont->freeFont)
+ (*bfont->pfont->unload_font) (bfont->pfont);
+#ifdef DEBUG
+ else
+ fprintf (stderr, "Not freeing other font in cleanup_bfont\n");
+#endif
+ bfont->pfont = 0;
+ }
+ else
+ fsd->generation = -1;
+ }
+}
+
+/*
+ * Check to see if a complete reply is waiting
+ */
+static fsGenericReply *
+fs_get_reply (FSFpePtr conn, int *error)
+{
+ char *buf;
+ fsGenericReply *rep;
+ int ret;
+
+ /* block if the connection is down or paused in lfwi */
+ if (conn->fs_fd == -1 || !FD_ISSET (conn->fs_fd, &_fs_fd_mask))
+ {
+ *error = FSIO_BLOCK;
+ return 0;
+ }
+
+ ret = _fs_start_read (conn, sizeof (fsGenericReply), &buf);
+ if (ret != FSIO_READY)
+ {
+ *error = FSIO_BLOCK;
+ return 0;
+ }
+
+ rep = (fsGenericReply *) buf;
+
+ ret = _fs_start_read (conn, rep->length << 2, &buf);
+ if (ret != FSIO_READY)
+ {
+ *error = FSIO_BLOCK;
+ return 0;
+ }
+
+ *error = FSIO_READY;
+
+ return (fsGenericReply *) buf;
+}
+
+static Bool
+fs_reply_ready (FSFpePtr conn)
+{
+ fsGenericReply *rep;
+
+ if (conn->fs_fd == -1 || !FD_ISSET (conn->fs_fd, &_fs_fd_mask))
+ return FALSE;
+ if (fs_data_read (conn) < sizeof (fsGenericReply))
+ return FALSE;
+ rep = (fsGenericReply *) (conn->inBuf.buf + conn->inBuf.remove);
+ if (fs_data_read (conn) < rep->length << 2)
+ return FALSE;
+ return TRUE;
+}
+
+static void
+_fs_pending_reply (FSFpePtr conn)
+{
+ if (!(conn->blockState & FS_PENDING_REPLY))
+ {
+ _fs_mark_block (conn, FS_PENDING_REPLY);
+ conn->blockedReplyTime = GetTimeInMillis () + FontServerRequestTimeout;
+ }
+}
+
+static void
+_fs_prepare_for_reply (FSFpePtr conn)
+{
+ _fs_pending_reply (conn);
+ _fs_flush (conn);
+}
+
+/*
+ * Block (for a while) awaiting a complete reply
+ */
+static int
+fs_await_reply (FSFpePtr conn)
+{
+ int ret;
+
+ if (conn->blockState & FS_COMPLETE_REPLY)
+ return FSIO_READY;
+
+ while (!fs_get_reply (conn, &ret))
+ {
+ if (ret != FSIO_BLOCK)
+ return ret;
+ if (_fs_wait_for_readable (conn, FontServerRequestTimeout) != FSIO_READY)
+ {
+ _fs_connection_died (conn);
+ return FSIO_ERROR;
+ }
+ }
+ return FSIO_READY;
+}
+
+/*
+ * Process the reply to an OpenBitmapFont request
+ */
+static int
+fs_read_open_font(FontPathElementPtr fpe, FSBlockDataPtr blockrec)
+{
+ FSFpePtr conn = (FSFpePtr) fpe->private;
+ FSBlockedFontPtr bfont = (FSBlockedFontPtr) blockrec->data;
+ fsOpenBitmapFontReply *rep;
+ FSBlockDataPtr blockOrig;
+ FSBlockedFontPtr origBfont;
+ int ret;
+
+ rep = (fsOpenBitmapFontReply *) fs_get_reply (conn, &ret);
+ if (!rep || rep->type == FS_Error)
+ {
+ if (ret == FSIO_BLOCK)
+ return StillWorking;
+ if (rep)
+ _fs_done_read (conn, rep->length << 2);
+ fs_cleanup_bfont (bfont);
+ return BadFontName;
+ }
+
+ /* If we're not reopening a font and FS detected a duplicate font
+ open request, replace our reference to the new font with a
+ reference to an existing font (possibly one not finished
+ opening). If this is a reopen, keep the new font reference...
+ it's got the metrics and extents we read when the font was opened
+ before. This also gives us the freedom to easily close the font
+ if we we decide (in fs_read_query_info()) that we don't like what
+ we got. */
+
+ if (rep->otherid && !(bfont->flags & FontReopen))
+ {
+ fs_cleanup_bfont (bfont);
+
+ /* Find old font if we're completely done getting it from server. */
+ bfont->pfont = find_old_font(rep->otherid);
+ bfont->freeFont = FALSE;
+ bfont->fontid = rep->otherid;
+ bfont->state = FS_DONE_REPLY;
+ /*
+ * look for a blocked request to open the same font
+ */
+ for (blockOrig = conn->blockedRequests;
+ blockOrig;
+ blockOrig = blockOrig->next)
+ {
+ if (blockOrig != blockrec && blockOrig->type == FS_OPEN_FONT)
+ {
+ origBfont = (FSBlockedFontPtr) blockOrig->data;
+ if (origBfont->fontid == rep->otherid)
+ {
+ blockrec->depending = blockOrig->depending;
+ blockOrig->depending = blockrec;
+ bfont->state = FS_DEPENDING;
+ bfont->pfont = origBfont->pfont;
+ break;
+ }
+ }
+ }
+ if (bfont->pfont == NULL)
+ {
+ /* XXX - something nasty happened */
+ ret = BadFontName;
+ }
+ else
+ ret = AccessDone;
+ }
+ else
+ {
+ bfont->pfont->info.cachable = rep->cachable != 0;
+ bfont->state = FS_INFO_REPLY;
+ /*
+ * Reset the blockrec for the next reply
+ */
+ blockrec->sequenceNumber = bfont->queryInfoSequence;
+ conn->blockedReplyTime = GetTimeInMillis () + FontServerRequestTimeout;
+ ret = StillWorking;
+ }
+ _fs_done_read (conn, rep->length << 2);
+ return ret;
+}
+
+static Bool
+fs_fonts_match (FontInfoPtr pInfo1, FontInfoPtr pInfo2)
+{
+ int i;
+
+ if (pInfo1->firstCol != pInfo2->firstCol ||
+ pInfo1->lastCol != pInfo2->lastCol ||
+ pInfo1->firstRow != pInfo2->firstRow ||
+ pInfo1->lastRow != pInfo2->lastRow ||
+ pInfo1->defaultCh != pInfo2->defaultCh ||
+ pInfo1->noOverlap != pInfo2->noOverlap ||
+ pInfo1->terminalFont != pInfo2->terminalFont ||
+ pInfo1->constantMetrics != pInfo2->constantMetrics ||
+ pInfo1->constantWidth != pInfo2->constantWidth ||
+ pInfo1->inkInside != pInfo2->inkInside ||
+ pInfo1->inkMetrics != pInfo2->inkMetrics ||
+ pInfo1->allExist != pInfo2->allExist ||
+ pInfo1->drawDirection != pInfo2->drawDirection ||
+ pInfo1->cachable != pInfo2->cachable ||
+ pInfo1->anamorphic != pInfo2->anamorphic ||
+ pInfo1->maxOverlap != pInfo2->maxOverlap ||
+ pInfo1->fontAscent != pInfo2->fontAscent ||
+ pInfo1->fontDescent != pInfo2->fontDescent ||
+ pInfo1->nprops != pInfo2->nprops)
+ return FALSE;
+
+#define MATCH(xci1, xci2) \
+ (((xci1).leftSideBearing == (xci2).leftSideBearing) && \
+ ((xci1).rightSideBearing == (xci2).rightSideBearing) && \
+ ((xci1).characterWidth == (xci2).characterWidth) && \
+ ((xci1).ascent == (xci2).ascent) && \
+ ((xci1).descent == (xci2).descent) && \
+ ((xci1).attributes == (xci2).attributes))
+
+ if (!MATCH(pInfo1->maxbounds, pInfo2->maxbounds) ||
+ !MATCH(pInfo1->minbounds, pInfo2->minbounds) ||
+ !MATCH(pInfo1->ink_maxbounds, pInfo2->ink_maxbounds) ||
+ !MATCH(pInfo1->ink_minbounds, pInfo2->ink_minbounds))
+ return FALSE;
+
+#undef MATCH
+
+ for (i = 0; i < pInfo1->nprops; i++)
+ if (pInfo1->isStringProp[i] !=
+ pInfo2->isStringProp[i] ||
+ pInfo1->props[i].name !=
+ pInfo2->props[i].name ||
+ pInfo1->props[i].value !=
+ pInfo2->props[i].value)
+ {
+ return FALSE;
+ }
+ return TRUE;
+}
+
+static int
+fs_read_query_info(FontPathElementPtr fpe, FSBlockDataPtr blockrec)
+{
+ FSBlockedFontPtr bfont = (FSBlockedFontPtr) blockrec->data;
+ FSFpePtr conn = (FSFpePtr) fpe->private;
+ fsQueryXInfoReply *rep;
+ char *buf;
+ fsPropInfo *pi;
+ fsPropOffset *po;
+ pointer pd;
+ FontInfoPtr pInfo;
+ FontInfoRec tempInfo;
+ int err;
+ int ret;
+
+ rep = (fsQueryXInfoReply *) fs_get_reply (conn, &ret);
+ if (!rep || rep->type == FS_Error)
+ {
+ if (ret == FSIO_BLOCK)
+ return StillWorking;
+ if (rep)
+ _fs_done_read (conn, rep->length << 2);
+ fs_cleanup_bfont (bfont);
+ return BadFontName;
+ }
+
+ /* If this is a reopen, accumulate the query info into a dummy
+ font and compare to our original data. */
+ if (bfont->flags & FontReopen)
+ pInfo = &tempInfo;
+ else
+ pInfo = &bfont->pfont->info;
+
+ buf = (char *) rep;
+ buf += SIZEOF(fsQueryXInfoReply);
+
+ /* move the data over */
+ fsUnpack_XFontInfoHeader(rep, pInfo);
+
+ /* compute accelerators */
+ _fs_init_fontinfo(conn, pInfo);
+
+ /* Compute offsets into the reply */
+ pi = (fsPropInfo *) buf;
+ buf += SIZEOF (fsPropInfo);
+
+ po = (fsPropOffset *) buf;
+ buf += pi->num_offsets * SIZEOF(fsPropOffset);
+
+ pd = (pointer) buf;
+ buf += pi->data_len;
+
+ /* convert the properties and step over the reply */
+ ret = _fs_convert_props(pi, po, pd, pInfo);
+ _fs_done_read (conn, rep->length << 2);
+
+ if (ret == -1)
+ {
+ fs_cleanup_bfont (bfont);
+ return AllocError;
+ }
+
+ if (bfont->flags & FontReopen)
+ {
+ /* We're reopening a font that we lost because of a downed
+ connection. In the interest of avoiding corruption from
+ opening a different font than the old one (we already have
+ its metrics, extents, and probably some of its glyphs),
+ verify that the metrics and properties all match. */
+
+ if (fs_fonts_match (pInfo, &bfont->pfont->info))
+ {
+ err = Successful;
+ bfont->state = FS_DONE_REPLY;
+ }
+ else
+ {
+ fs_cleanup_bfont (bfont);
+ err = BadFontName;
+ }
+ _fs_free_props (pInfo);
+
+ return err;
+ }
+
+ /*
+ * Ask for terminal format fonts if possible
+ */
+ if (bfont->pfont->info.terminalFont)
+ bfont->format = ((bfont->format & ~ (BitmapFormatImageRectMask)) |
+ BitmapFormatImageRectMax);
+
+ /*
+ * Figure out if the whole font should get loaded right now.
+ */
+ if (glyphCachingMode == CACHING_OFF ||
+ (glyphCachingMode == CACHE_16_BIT_GLYPHS
+ && !bfont->pfont->info.lastRow))
+ {
+ bfont->flags |= FontLoadAll;
+ }
+
+ /*
+ * Ready to send the query bitmaps; the terminal font bit has
+ * been computed and glyphCaching has been considered
+ */
+ if (bfont->flags & FontLoadBitmaps)
+ {
+ fs_send_query_bitmaps (fpe, blockrec);
+ _fs_flush (conn);
+ }
+
+ bfont->state = FS_EXTENT_REPLY;
+
+ /*
+ * Reset the blockrec for the next reply
+ */
+ blockrec->sequenceNumber = bfont->queryExtentsSequence;
+ conn->blockedReplyTime = GetTimeInMillis () + FontServerRequestTimeout;
+
+ return StillWorking;
+}
+
+static int
+fs_read_extent_info(FontPathElementPtr fpe, FSBlockDataPtr blockrec)
+{
+ FSFpePtr conn = (FSFpePtr) fpe->private;
+ FSBlockedFontPtr bfont = (FSBlockedFontPtr) blockrec->data;
+ FSFontDataPtr fsd = (FSFontDataPtr) bfont->pfont->fpePrivate;
+ FSFontPtr fsfont = (FSFontPtr) bfont->pfont->fontPrivate;
+ fsQueryXExtents16Reply *rep;
+ char *buf;
+ int i;
+ int numExtents;
+ int numInfos;
+ int ret;
+ Bool haveInk = FALSE; /* need separate ink metrics? */
+ CharInfoPtr ci, pCI;
+ char *fsci;
+ fsXCharInfo fscilocal;
+ FontInfoRec *fi = &bfont->pfont->info;
+
+ rep = (fsQueryXExtents16Reply *) fs_get_reply (conn, &ret);
+ if (!rep || rep->type == FS_Error)
+ {
+ if (ret == FSIO_BLOCK)
+ return StillWorking;
+ if (rep)
+ _fs_done_read (conn, rep->length << 2);
+ fs_cleanup_bfont (bfont);
+ return BadFontName;
+ }
+
+ /* move the data over */
+ /* need separate inkMetrics for fixed font server protocol version */
+ numExtents = rep->num_extents;
+ numInfos = numExtents;
+ if (bfont->pfont->info.terminalFont && conn->fsMajorVersion > 1)
+ {
+ numInfos *= 2;
+ haveInk = TRUE;
+ }
+ ci = pCI = (CharInfoPtr) xalloc(sizeof(CharInfoRec) * numInfos);
+
+ if (!pCI)
+ {
+ _fs_done_read (conn, rep->length << 2);
+ fs_cleanup_bfont(bfont);
+ return AllocError;
+ }
+ fsfont->encoding = pCI;
+ if (haveInk)
+ fsfont->inkMetrics = pCI + numExtents;
+ else
+ fsfont->inkMetrics = pCI;
+
+ buf = (char *) rep;
+ buf += SIZEOF (fsQueryXExtents16Reply);
+ fsci = buf;
+
+ fsd->glyphs_to_get = 0;
+ ci = fsfont->inkMetrics;
+ for (i = 0; i < numExtents; i++)
+ {
+ memcpy(&fscilocal, fsci, SIZEOF(fsXCharInfo)); /* align it */
+ _fs_convert_char_info(&fscilocal, &ci->metrics);
+ /* Bounds check. */
+ if (ci->metrics.ascent > fi->maxbounds.ascent)
+ {
+ ErrorF("fserve: warning: %s %s ascent (%d) > maxascent (%d)\n",
+ fpe->name, fsd->name,
+ ci->metrics.ascent, fi->maxbounds.ascent);
+ ci->metrics.ascent = fi->maxbounds.ascent;
+ }
+ if (ci->metrics.descent > fi->maxbounds.descent)
+ {
+ ErrorF("fserve: warning: %s %s descent (%d) > maxdescent (%d)\n",
+ fpe->name, fsd->name,
+ ci->metrics.descent, fi->maxbounds.descent);
+ ci->metrics.descent = fi->maxbounds.descent;
+ }
+ fsci = fsci + SIZEOF(fsXCharInfo);
+ /* Initialize the bits field for later glyph-caching use */
+ if (NONZEROMETRICS(&ci->metrics))
+ {
+ if (!haveInk &&
+ (ci->metrics.leftSideBearing == ci->metrics.rightSideBearing ||
+ ci->metrics.ascent == -ci->metrics.descent))
+ pCI[i].bits = &_fs_glyph_zero_length;
+ else
+ {
+ pCI[i].bits = &_fs_glyph_undefined;
+ fsd->glyphs_to_get++;
+ }
+ }
+ else
+ pCI[i].bits = (char *)0;
+ ci++;
+ }
+
+ /* Done with reply */
+ _fs_done_read (conn, rep->length << 2);
+
+ /* build bitmap metrics, ImageRectMax style */
+ if (haveInk)
+ {
+ CharInfoPtr ii;
+
+ ci = fsfont->encoding;
+ ii = fsfont->inkMetrics;
+ for (i = 0; i < numExtents; i++, ci++, ii++)
+ {
+ if (NONZEROMETRICS(&ii->metrics))
+ {
+ ci->metrics.leftSideBearing = FONT_MIN_LEFT(fi);
+ ci->metrics.rightSideBearing = FONT_MAX_RIGHT(fi);
+ ci->metrics.ascent = FONT_MAX_ASCENT(fi);
+ ci->metrics.descent = FONT_MAX_DESCENT(fi);
+ ci->metrics.characterWidth = FONT_MAX_WIDTH(fi);
+ ci->metrics.attributes = ii->metrics.attributes;
+ }
+ else
+ {
+ ci->metrics = ii->metrics;
+ }
+ /* Bounds check. */
+ if (ci->metrics.ascent > fi->maxbounds.ascent)
+ {
+ ErrorF("fserve: warning: %s %s ascent (%d) "
+ "> maxascent (%d)\n",
+ fpe->name, fsd->name,
+ ci->metrics.ascent, fi->maxbounds.ascent);
+ ci->metrics.ascent = fi->maxbounds.ascent;
+ }
+ if (ci->metrics.descent > fi->maxbounds.descent)
+ {
+ ErrorF("fserve: warning: %s %s descent (%d) "
+ "> maxdescent (%d)\n",
+ fpe->name, fsd->name,
+ ci->metrics.descent, fi->maxbounds.descent);
+ ci->metrics.descent = fi->maxbounds.descent;
+ }
+ }
+ }
+ {
+ unsigned int r, c, numCols, firstCol;
+
+ firstCol = bfont->pfont->info.firstCol;
+ numCols = bfont->pfont->info.lastCol - firstCol + 1;
+ c = bfont->pfont->info.defaultCh;
+ fsfont->pDefault = 0;
+ if (bfont->pfont->info.lastRow)
+ {
+ r = c >> 8;
+ r -= bfont->pfont->info.firstRow;
+ c &= 0xff;
+ c -= firstCol;
+ if (r < bfont->pfont->info.lastRow-bfont->pfont->info.firstRow+1 &&
+ c < numCols)
+ fsfont->pDefault = &pCI[r * numCols + c];
+ }
+ else
+ {
+ c -= firstCol;
+ if (c < numCols)
+ fsfont->pDefault = &pCI[c];
+ }
+ }
+ bfont->state = FS_GLYPHS_REPLY;
+
+ if (bfont->flags & FontLoadBitmaps)
+ {
+ /*
+ * Reset the blockrec for the next reply
+ */
+ blockrec->sequenceNumber = bfont->queryBitmapsSequence;
+ conn->blockedReplyTime = GetTimeInMillis () + FontServerRequestTimeout;
+ return StillWorking;
+ }
+ return Successful;
+}
+
+#ifdef DEBUG
+static char *fs_open_states[] = {
+ "OPEN_REPLY ",
+ "INFO_REPLY ",
+ "EXTENT_REPLY",
+ "GLYPHS_REPLY",
+ "DONE_REPLY ",
+ "DEPENDING ",
+};
+#endif
+
+static int
+fs_do_open_font(FontPathElementPtr fpe, FSBlockDataPtr blockrec)
+{
+ FSBlockedFontPtr bfont = (FSBlockedFontPtr) blockrec->data;
+ int err;
+
+#ifdef DEBUG
+ fprintf (stderr, "fs_do_open_font state %s %s\n",
+ fs_open_states[bfont->state],
+ ((FSFontDataPtr) (bfont->pfont->fpePrivate))->name);
+#endif
+ err = BadFontName;
+ switch (bfont->state) {
+ case FS_OPEN_REPLY:
+ err = fs_read_open_font(fpe, blockrec);
+ if (err != StillWorking) { /* already loaded, or error */
+ /* if font's already loaded, massage error code */
+ switch (bfont->state) {
+ case FS_DONE_REPLY:
+ err = Successful;
+ break;
+ case FS_DEPENDING:
+ err = StillWorking;
+ break;
+ }
+ }
+ break;
+ case FS_INFO_REPLY:
+ err = fs_read_query_info(fpe, blockrec);
+ break;
+ case FS_EXTENT_REPLY:
+ err = fs_read_extent_info(fpe, blockrec);
+ break;
+ case FS_GLYPHS_REPLY:
+ if (bfont->flags & FontLoadBitmaps)
+ err = fs_read_glyphs(fpe, blockrec);
+ break;
+ case FS_DEPENDING: /* can't happen */
+ default:
+ break;
+ }
+#ifdef DEBUG
+ fprintf (stderr, "fs_do_open_font err %d\n", err);
+#endif
+ if (err != StillWorking)
+ {
+ bfont->state = FS_DONE_REPLY; /* for _fs_load_glyphs() */
+ while ((blockrec = blockrec->depending))
+ {
+ bfont = (FSBlockedFontPtr) blockrec->data;
+ bfont->state = FS_DONE_REPLY; /* for _fs_load_glyphs() */
+ }
+ }
+ return err;
+}
+
+void
+_fs_mark_block (FSFpePtr conn, CARD32 mask)
+{
+ conn->blockState |= mask;
+ fs_blockState |= mask;
+}
+
+void
+_fs_unmark_block (FSFpePtr conn, CARD32 mask)
+{
+ FSFpePtr c;
+
+ if (conn->blockState & mask)
+ {
+ conn->blockState &= ~mask;
+ fs_blockState = 0;
+ for (c = fs_fpes; c; c = c->next)
+ fs_blockState |= c->blockState;
+ }
+}
+
+/* ARGSUSED */
+static void
+fs_block_handler(pointer data, OSTimePtr wt, pointer LastSelectMask)
+{
+ static struct timeval block_timeout;
+ CARD32 now, earliest, wakeup;
+ int soonest;
+ FSFpePtr conn;
+
+ XFD_ORSET((fd_set *)LastSelectMask, (fd_set *)LastSelectMask,
+ &_fs_fd_mask);
+ /*
+ * Flush all pending output
+ */
+ if (fs_blockState & FS_PENDING_WRITE)
+ for (conn = fs_fpes; conn; conn = conn->next)
+ if (conn->blockState & FS_PENDING_WRITE)
+ _fs_flush (conn);
+ /*
+ * Check for any fpe with a complete reply, set sleep time to zero
+ */
+ if (fs_blockState & FS_COMPLETE_REPLY)
+ {
+ block_timeout.tv_sec = 0;
+ block_timeout.tv_usec = 0;
+ if (*wt == NULL)
+ *wt = &block_timeout;
+ else
+ **wt = block_timeout;
+ }
+ /*
+ * Walk through fpe list computing sleep time
+ */
+ else if (fs_blockState & (FS_BROKEN_WRITE|
+ FS_BROKEN_CONNECTION|
+ FS_PENDING_REPLY|
+ FS_RECONNECTING))
+ {
+ now = GetTimeInMillis ();
+ earliest = now + 10000000;
+ for (conn = fs_fpes; conn; conn = conn->next)
+ {
+ if (conn->blockState & FS_RECONNECTING)
+ {
+ wakeup = conn->blockedConnectTime;
+ if (TimeCmp (wakeup, <, earliest))
+ earliest = wakeup;
+ }
+ if (conn->blockState & FS_BROKEN_CONNECTION)
+ {
+ wakeup = conn->brokenConnectionTime;
+ if (TimeCmp (wakeup, <, earliest))
+ earliest = wakeup;
+ }
+ if (conn->blockState & FS_BROKEN_WRITE)
+ {
+ wakeup = conn->brokenWriteTime;
+ if (TimeCmp (wakeup, <, earliest))
+ earliest = wakeup;
+ }
+ if (conn->blockState & FS_PENDING_REPLY)
+ {
+ wakeup = conn->blockedReplyTime;
+ if (TimeCmp (wakeup, <, earliest))
+ earliest = wakeup;
+ }
+ }
+ soonest = earliest - now;
+ if (soonest < 0)
+ soonest = 0;
+ block_timeout.tv_sec = soonest / 1000;
+ block_timeout.tv_usec = (soonest % 1000) * 1000;
+ if (*wt == NULL)
+ *wt = &block_timeout;
+ else if (soonest < (*wt)->tv_sec * 1000 + (*wt)->tv_usec / 1000)
+ **wt = block_timeout;
+ }
+}
+
+static void
+fs_handle_unexpected(FSFpePtr conn, fsGenericReply *rep)
+{
+ if (rep->type == FS_Event && rep->data1 == KeepAlive)
+ {
+ fsNoopReq req;
+
+ /* ping it back */
+ req.reqType = FS_Noop;
+ req.length = SIZEOF(fsNoopReq) >> 2;
+ _fs_add_req_log(conn, FS_Noop);
+ _fs_write(conn, (char *) &req, SIZEOF(fsNoopReq));
+ }
+ /* this should suck up unexpected replies and events */
+ _fs_done_read (conn, rep->length << 2);
+}
+
+static void
+fs_read_reply (FontPathElementPtr fpe, pointer client)
+{
+ FSFpePtr conn = (FSFpePtr) fpe->private;
+ FSBlockDataPtr blockrec;
+ int ret;
+ int err;
+ fsGenericReply *rep;
+
+ if ((rep = fs_get_reply (conn, &ret)))
+ {
+ _fs_add_rep_log (conn, rep);
+ for (blockrec = conn->blockedRequests;
+ blockrec;
+ blockrec = blockrec->next)
+ {
+ if (blockrec->sequenceNumber == rep->sequenceNumber)
+ break;
+ }
+ err = Successful;
+ if (!blockrec)
+ {
+ fs_handle_unexpected(conn, rep);
+ }
+ else
+ {
+ /*
+ * go read it, and if we're done,
+ * wake up the appropriate client
+ */
+ switch (blockrec->type) {
+ case FS_OPEN_FONT:
+ blockrec->errcode = fs_do_open_font(fpe, blockrec);
+ break;
+ case FS_LOAD_GLYPHS:
+ blockrec->errcode = fs_read_glyphs(fpe, blockrec);
+ break;
+ case FS_LIST_FONTS:
+ blockrec->errcode = fs_read_list(fpe, blockrec);
+ break;
+ case FS_LIST_WITH_INFO:
+ blockrec->errcode = fs_read_list_info(fpe, blockrec);
+ break;
+ default:
+ break;
+ }
+ err = blockrec->errcode;
+ if (err != StillWorking)
+ {
+ while (blockrec)
+ {
+ blockrec->errcode = err;
+ if (client != blockrec->client)
+ ClientSignal(blockrec->client);
+ blockrec = blockrec->depending;
+ }
+ _fs_unmark_block (conn, FS_PENDING_REPLY);
+ }
+ }
+ if (fs_reply_ready (conn))
+ _fs_mark_block (conn, FS_COMPLETE_REPLY);
+ else
+ _fs_unmark_block (conn, FS_COMPLETE_REPLY);
+ }
+}
+
+static int
+fs_wakeup(FontPathElementPtr fpe, unsigned long *mask)
+{
+ fd_set *LastSelectMask = (fd_set *) mask;
+ FSFpePtr conn = (FSFpePtr) fpe->private;
+
+ /*
+ * Don't continue if the fd is -1 (which will be true when the
+ * font server terminates
+ */
+ if ((conn->blockState & FS_RECONNECTING))
+ _fs_check_reconnect (conn);
+ else if ((conn->blockState & FS_COMPLETE_REPLY) ||
+ (conn->fs_fd != -1 && FD_ISSET(conn->fs_fd, LastSelectMask)))
+ fs_read_reply (fpe, 0);
+ if (conn->blockState & (FS_PENDING_REPLY|FS_BROKEN_CONNECTION|FS_BROKEN_WRITE))
+ _fs_do_blocked (conn);
+#ifdef DEBUG
+ {
+ FSBlockDataPtr blockrec;
+ FSBlockedFontPtr bfont;
+ FSBlockedListPtr blist;
+ static CARD32 lastState;
+ static FSBlockDataPtr lastBlock;
+
+ if (conn->blockState || conn->blockedRequests || lastState || lastBlock)
+ {
+ fprintf (stderr, " Block State 0x%x\n", (int) conn->blockState);
+ lastState = conn->blockState;
+ lastBlock = conn->blockedRequests;
+ }
+ for (blockrec = conn->blockedRequests; blockrec; blockrec = blockrec->next)
+ {
+ switch (blockrec->type) {
+ case FS_OPEN_FONT:
+ bfont = (FSBlockedFontPtr) blockrec->data;
+ fprintf (stderr, " Blocked font errcode %d sequence %d state %s %s\n",
+ blockrec->errcode,
+ blockrec->sequenceNumber,
+ fs_open_states[bfont->state],
+ bfont->pfont ?
+ ((FSFontDataPtr) (bfont->pfont->fpePrivate))->name :
+ "<freed>");
+ break;
+ case FS_LIST_FONTS:
+ blist = (FSBlockedListPtr) blockrec->data;
+ fprintf (stderr, " Blocked list errcode %d sequence %d\n",
+ blockrec->errcode, blockrec->sequenceNumber);
+ break;
+ default:
+ fprintf (stderr, " Blocked type %d errcode %d sequence %d\n",
+ blockrec->type,
+ blockrec->errcode,
+ blockrec->sequenceNumber);
+ break;
+ }
+ }
+ }
+#endif
+ return FALSE;
+}
+
+/*
+ * Notice a dead connection and prepare for reconnect
+ */
+
+void
+_fs_connection_died(FSFpePtr conn)
+{
+ if (conn->blockState & FS_BROKEN_CONNECTION)
+ return;
+ fs_close_conn(conn);
+ conn->brokenConnectionTime = GetTimeInMillis ();
+ _fs_mark_block (conn, FS_BROKEN_CONNECTION);
+ _fs_unmark_block (conn, FS_BROKEN_WRITE|FS_PENDING_WRITE|FS_RECONNECTING);
+}
+
+/*
+ * Signal clients that the connection has come back up
+ */
+static int
+_fs_restart_connection(FSFpePtr conn)
+{
+ FSBlockDataPtr block;
+
+ _fs_unmark_block (conn, FS_GIVE_UP);
+ while ((block = (FSBlockDataPtr) conn->blockedRequests))
+ {
+ if (block->errcode == StillWorking)
+ {
+ ClientSignal(block->client);
+ fs_abort_blockrec(conn, block);
+ }
+ }
+ return TRUE;
+}
+
+/*
+ * Declare this font server connection useless
+ */
+static void
+_fs_giveup (FSFpePtr conn)
+{
+ FSBlockDataPtr block;
+
+ if (conn->blockState & FS_GIVE_UP)
+ return;
+#ifdef DEBUG
+ fprintf (stderr, "give up on FS \"%s\"\n", conn->servername);
+#endif
+ _fs_mark_block (conn, FS_GIVE_UP);
+ while ((block = (FSBlockDataPtr) conn->blockedRequests))
+ {
+ if (block->errcode == StillWorking)
+ {
+ ClientSignal (block->client);
+ fs_abort_blockrec (conn, block);
+ }
+ }
+ if (conn->fs_fd >= 0)
+ _fs_connection_died (conn);
+}
+
+static void
+_fs_do_blocked (FSFpePtr conn)
+{
+ CARD32 now;
+
+ now = GetTimeInMillis ();
+ if ((conn->blockState & FS_PENDING_REPLY) &&
+ TimeCmp (conn->blockedReplyTime, <=, now))
+ {
+ _fs_giveup (conn);
+ }
+ else
+ {
+ if (conn->blockState & FS_BROKEN_CONNECTION)
+ {
+ /* Try to reconnect broken connections */
+ if (TimeCmp (conn->brokenConnectionTime, <=, now))
+ _fs_start_reconnect (conn);
+ }
+ else if (conn->blockState & FS_BROKEN_WRITE)
+ {
+ /* Try to flush blocked connections */
+ if (TimeCmp (conn->brokenWriteTime, <=, now))
+ _fs_flush (conn);
+ }
+ }
+}
+
+/*
+ * sends the actual request out
+ */
+/* ARGSUSED */
+static int
+fs_send_open_font(pointer client, FontPathElementPtr fpe, Mask flags,
+ char *name, int namelen,
+ fsBitmapFormat format, fsBitmapFormatMask fmask,
+ XID id, FontPtr *ppfont)
+{
+ FSFpePtr conn = (FSFpePtr) fpe->private;
+ FontPtr font;
+ FSBlockDataPtr blockrec = NULL;
+ FSBlockedFontPtr bfont;
+ FSFontDataPtr fsd;
+ fsOpenBitmapFontReq openreq;
+ fsQueryXInfoReq inforeq;
+ fsQueryXExtents16Req extreq;
+ int err;
+ unsigned char buf[1024];
+
+ if (conn->blockState & FS_GIVE_UP)
+ return BadFontName;
+
+ if (namelen <= 0 || namelen > sizeof (buf) - 1)
+ return BadFontName;
+
+ /*
+ * Get the font structure put together, either by reusing
+ * the existing one or creating a new one
+ */
+ if (flags & FontReopen)
+ {
+ Atom nameatom, fn = None;
+ int i;
+
+ font = *ppfont;
+ fsd = (FSFontDataPtr)font->fpePrivate;
+ /* This is an attempt to reopen a font. Did the font have a
+ NAME property? */
+ if ((nameatom = MakeAtom("FONT", 4, 0)) != None)
+ {
+ for (i = 0; i < font->info.nprops; i++)
+ if (font->info.props[i].name == nameatom &&
+ font->info.isStringProp[i])
+ {
+ fn = font->info.props[i].value;
+ break;
+ }
+ }
+ if (fn == None || !(name = NameForAtom(fn)))
+ {
+ name = fsd->name;
+ namelen = fsd->namelen;
+ }
+ else
+ namelen = strlen(name);
+ }
+ else
+ {
+ font = fs_create_font (fpe, name, namelen, format, fmask);
+ if (!font)
+ return AllocError;
+
+ fsd = (FSFontDataPtr)font->fpePrivate;
+ }
+
+ /* make a new block record, and add it to the end of the list */
+ blockrec = fs_new_block_rec(font->fpe, client, FS_OPEN_FONT);
+ if (!blockrec)
+ {
+ if (!(flags & FontReopen))
+ (*font->unload_font) (font);
+ return AllocError;
+ }
+
+ /*
+ * Must check this before generating any protocol, otherwise we'll
+ * mess up a reconnect in progress
+ */
+ if (conn->blockState & (FS_BROKEN_CONNECTION | FS_RECONNECTING))
+ {
+ _fs_pending_reply (conn);
+ return Suspended;
+ }
+
+ fsd->generation = conn->generation;
+
+ bfont = (FSBlockedFontPtr) blockrec->data;
+ bfont->fontid = fsd->fontid;
+ bfont->pfont = font;
+ bfont->state = FS_OPEN_REPLY;
+ bfont->flags = flags;
+ bfont->format = fsd->format;
+ bfont->clients_depending = (FSClientsDependingPtr)0;
+ bfont->freeFont = (flags & FontReopen) == 0;
+
+ _fs_client_access (conn, client, (flags & FontOpenSync) != 0);
+ _fs_client_resolution(conn);
+
+ /* do an FS_OpenFont, FS_QueryXInfo and FS_QueryXExtents */
+ buf[0] = (unsigned char) namelen;
+ memcpy(&buf[1], name, namelen);
+ openreq.reqType = FS_OpenBitmapFont;
+ openreq.fid = fsd->fontid;
+ openreq.format_hint = fsd->format;
+ openreq.format_mask = fsd->fmask;
+ openreq.length = (SIZEOF(fsOpenBitmapFontReq) + namelen + 4) >> 2;
+
+ _fs_add_req_log(conn, FS_OpenBitmapFont);
+ _fs_write(conn, (char *) &openreq, SIZEOF(fsOpenBitmapFontReq));
+ _fs_write_pad(conn, (char *) buf, namelen + 1);
+
+ blockrec->sequenceNumber = conn->current_seq;
+
+ inforeq.reqType = FS_QueryXInfo;
+ inforeq.id = fsd->fontid;
+ inforeq.length = SIZEOF(fsQueryXInfoReq) >> 2;
+
+ bfont->queryInfoSequence = conn->current_seq + 1;
+
+ _fs_add_req_log(conn, FS_QueryXInfo);
+ _fs_write(conn, (char *) &inforeq, SIZEOF(fsQueryXInfoReq));
+
+ if (!(bfont->flags & FontReopen))
+ {
+ extreq.reqType = FS_QueryXExtents16;
+ extreq.range = fsTrue;
+ extreq.fid = fsd->fontid;
+ extreq.num_ranges = 0;
+ extreq.length = SIZEOF(fsQueryXExtents16Req) >> 2;
+
+ bfont->queryExtentsSequence = conn->current_seq + 1;
+
+ _fs_add_req_log(conn, FS_QueryXExtents16);
+ _fs_write(conn, (char *) &extreq, SIZEOF(fsQueryXExtents16Req));
+ }
+
+#ifdef NCD
+ if (configData.ExtendedFontDiags)
+ {
+ memcpy(buf, name, MIN(256, namelen));
+ buf[MIN(256, namelen)] = '\0';
+ printf("Requesting font \"%s\" from font server \"%s\"\n",
+ buf, font->fpe->name);
+ }
+#endif
+ _fs_prepare_for_reply (conn);
+
+ err = blockrec->errcode;
+ if (bfont->flags & FontOpenSync)
+ {
+ while (blockrec->errcode == StillWorking)
+ {
+ if (fs_await_reply (conn) != FSIO_READY)
+ {
+ blockrec->errcode = BadFontName;
+ break;
+ }
+ fs_read_reply (font->fpe, client);
+ }
+ err = blockrec->errcode;
+ if (err == Successful)
+ *ppfont = bfont->pfont;
+ else
+ fs_cleanup_bfont (bfont);
+ bfont->freeFont = FALSE;
+ _fs_remove_block_rec (conn, blockrec);
+ }
+ return err == StillWorking ? Suspended : err;
+}
+
+static void
+fs_send_query_bitmaps(FontPathElementPtr fpe, FSBlockDataPtr blockrec)
+{
+ FSFpePtr conn = (FSFpePtr) fpe->private;
+ FSBlockedFontPtr bfont = (FSBlockedFontPtr) blockrec->data;
+ fsQueryXBitmaps16Req bitreq;
+
+ /* send the request */
+ bitreq.reqType = FS_QueryXBitmaps16;
+ bitreq.fid = bfont->fontid;
+ bitreq.format = bfont->format;
+ bitreq.range = TRUE;
+ bitreq.length = SIZEOF(fsQueryXBitmaps16Req) >> 2;
+ bitreq.num_ranges = 0;
+
+ bfont->queryBitmapsSequence = conn->current_seq + 1;
+
+ _fs_add_req_log(conn, FS_QueryXBitmaps16);
+ _fs_write(conn, (char *) &bitreq, SIZEOF(fsQueryXBitmaps16Req));
+}
+
+/* ARGSUSED */
+static int
+fs_open_font(pointer client, FontPathElementPtr fpe, Mask flags,
+ char *name, int namelen,
+ fsBitmapFormat format, fsBitmapFormatMask fmask,
+ XID id, FontPtr *ppfont,
+ char **alias, FontPtr non_cachable_font)
+{
+ FSFpePtr conn = (FSFpePtr) fpe->private;
+ FSBlockDataPtr blockrec;
+ FSBlockedFontPtr bfont;
+ int err;
+
+ /* libfont interface expects ImageRectMin glyphs */
+ format = (format & ~BitmapFormatImageRectMask) | BitmapFormatImageRectMin;
+
+ *alias = (char *) 0;
+ for (blockrec = conn->blockedRequests; blockrec; blockrec = blockrec->next)
+ {
+ if (blockrec->type == FS_OPEN_FONT && blockrec->client == client)
+ {
+ err = blockrec->errcode;
+ if (err == StillWorking)
+ return Suspended;
+
+ bfont = (FSBlockedFontPtr) blockrec->data;
+ if (err == Successful)
+ *ppfont = bfont->pfont;
+ else
+ fs_cleanup_bfont (bfont);
+ _fs_remove_block_rec (conn, blockrec);
+ return err;
+ }
+ }
+ return fs_send_open_font(client, fpe, flags, name, namelen, format, fmask,
+ id, ppfont);
+}
+
+/* ARGSUSED */
+static int
+fs_send_close_font(FontPathElementPtr fpe, Font id)
+{
+ FSFpePtr conn = (FSFpePtr) fpe->private;
+ fsCloseReq req;
+
+ if (conn->blockState & FS_GIVE_UP)
+ return Successful;
+ /* tell the font server to close the font */
+ req.reqType = FS_CloseFont;
+ req.length = SIZEOF(fsCloseReq) >> 2;
+ req.id = id;
+ _fs_add_req_log(conn, FS_CloseFont);
+ _fs_write(conn, (char *) &req, SIZEOF(fsCloseReq));
+
+ return Successful;
+}
+
+/* ARGSUSED */
+static void
+fs_close_font(FontPathElementPtr fpe, FontPtr pfont)
+{
+ FSFontDataPtr fsd = (FSFontDataPtr) pfont->fpePrivate;
+ FSFpePtr conn = (FSFpePtr) fpe->private;
+
+ if (conn->generation == fsd->generation)
+ fs_send_close_font(fpe, fsd->fontid);
+
+#ifdef DEBUG
+ {
+ FSBlockDataPtr blockrec;
+ FSBlockedFontPtr bfont;
+
+ for (blockrec = conn->blockedRequests; blockrec; blockrec = blockrec->next)
+ {
+ if (blockrec->type == FS_OPEN_FONT)
+ {
+ bfont = (FSBlockedFontPtr) blockrec->data;
+ if (bfont->pfont == pfont)
+ fprintf (stderr, "closing font which hasn't been opened\n");
+ }
+ }
+ }
+#endif
+ (*pfont->unload_font) (pfont);
+}
+
+static int
+fs_read_glyphs(FontPathElementPtr fpe, FSBlockDataPtr blockrec)
+{
+ FSBlockedGlyphPtr bglyph = (FSBlockedGlyphPtr) blockrec->data;
+ FSBlockedFontPtr bfont = (FSBlockedFontPtr) blockrec->data;
+ FSFpePtr conn = (FSFpePtr) fpe->private;
+ FontPtr pfont = bglyph->pfont;
+ /* works for either blocked font
+ or glyph rec... pfont is at
+ the very beginning of both
+ blockrec->data structures */
+ FSFontDataPtr fsd = (FSFontDataPtr) (pfont->fpePrivate);
+ FSFontPtr fsdata = (FSFontPtr) pfont->fontPrivate;
+ FontInfoPtr pfi = &pfont->info;
+ fsQueryXBitmaps16Reply *rep;
+ char *buf;
+ fsOffset32 *ppbits;
+ fsOffset32 local_off;
+ char *off_adr;
+ pointer pbitmaps;
+ char *bits, *allbits;
+#ifdef DEBUG
+ char *origallbits;
+#endif
+ int i,
+ err;
+ int nranges = 0;
+ int ret;
+ fsRange *nextrange = 0;
+ unsigned long minchar, maxchar;
+
+ rep = (fsQueryXBitmaps16Reply *) fs_get_reply (conn, &ret);
+ if (!rep || rep->type == FS_Error)
+ {
+ if (ret == FSIO_BLOCK)
+ return StillWorking;
+ if (rep)
+ _fs_done_read (conn, rep->length << 2);
+ err = AllocError;
+ goto bail;
+ }
+
+ buf = (char *) rep;
+ buf += SIZEOF (fsQueryXBitmaps16Reply);
+
+ ppbits = (fsOffset32 *) buf;
+ buf += SIZEOF (fsOffset32) * (rep->num_chars);
+
+ pbitmaps = (pointer ) buf;
+
+ if (blockrec->type == FS_LOAD_GLYPHS)
+ {
+ nranges = bglyph->num_expected_ranges;
+ nextrange = bglyph->expected_ranges;
+ }
+
+ /* place the incoming glyphs */
+ if (nranges)
+ {
+ /* We're operating under the assumption that the ranges
+ requested in the LoadGlyphs call were all legal for this
+ font, and that individual ranges do not cover multiple
+ rows... fs_build_range() is designed to ensure this. */
+ minchar = (nextrange->min_char_high - pfi->firstRow) *
+ (pfi->lastCol - pfi->firstCol + 1) +
+ nextrange->min_char_low - pfi->firstCol;
+ maxchar = (nextrange->max_char_high - pfi->firstRow) *
+ (pfi->lastCol - pfi->firstCol + 1) +
+ nextrange->max_char_low - pfi->firstCol;
+ nextrange++;
+ }
+ else
+ {
+ minchar = 0;
+ maxchar = rep->num_chars;
+ }
+
+ off_adr = (char *)ppbits;
+
+ allbits = fs_alloc_glyphs (pfont, rep->nbytes);
+
+ if (!allbits)
+ {
+ err = AllocError;
+ goto bail;
+ }
+
+#ifdef DEBUG
+ origallbits = allbits;
+ fprintf (stderr, "Reading %d glyphs in %d bytes for %s\n",
+ (int) rep->num_chars, (int) rep->nbytes, fsd->name);
+#endif
+
+ for (i = 0; i < rep->num_chars; i++)
+ {
+ memcpy(&local_off, off_adr, SIZEOF(fsOffset32)); /* align it */
+ if (blockrec->type == FS_OPEN_FONT ||
+ fsdata->encoding[minchar].bits == &_fs_glyph_requested)
+ {
+ /*
+ * Broken X font server returns bits for missing characters
+ * when font is padded
+ */
+ if (NONZEROMETRICS(&fsdata->encoding[minchar].metrics))
+ {
+ if (local_off.length)
+ {
+ bits = allbits;
+ allbits += local_off.length;
+ memcpy(bits, (char *)pbitmaps + local_off.position,
+ local_off.length);
+ }
+ else
+ bits = &_fs_glyph_zero_length;
+ }
+ else
+ bits = 0;
+ if (fsdata->encoding[minchar].bits == &_fs_glyph_requested)
+ fsd->glyphs_to_get--;
+ fsdata->encoding[minchar].bits = bits;
+ }
+ if (minchar++ == maxchar)
+ {
+ if (!--nranges) break;
+ minchar = (nextrange->min_char_high - pfi->firstRow) *
+ (pfi->lastCol - pfi->firstCol + 1) +
+ nextrange->min_char_low - pfi->firstCol;
+ maxchar = (nextrange->max_char_high - pfi->firstRow) *
+ (pfi->lastCol - pfi->firstCol + 1) +
+ nextrange->max_char_low - pfi->firstCol;
+ nextrange++;
+ }
+ off_adr += SIZEOF(fsOffset32);
+ }
+#ifdef DEBUG
+ fprintf (stderr, "Used %d bytes instead of %d\n",
+ (int) (allbits - origallbits), (int) rep->nbytes);
+#endif
+
+ if (blockrec->type == FS_OPEN_FONT)
+ {
+ fsd->glyphs_to_get = 0;
+ bfont->state = FS_DONE_REPLY;
+ }
+ err = Successful;
+
+bail:
+ _fs_done_read (conn, rep->length << 2);
+ return err;
+}
+
+static int
+fs_send_load_glyphs(pointer client, FontPtr pfont,
+ int nranges, fsRange *ranges)
+{
+ FontPathElementPtr fpe = pfont->fpe;
+ FSFpePtr conn = (FSFpePtr) fpe->private;
+ FSBlockedGlyphPtr blockedglyph;
+ fsQueryXBitmaps16Req req;
+ FSBlockDataPtr blockrec;
+
+ if (conn->blockState & FS_GIVE_UP)
+ return BadCharRange;
+
+ /* make a new block record, and add it to the end of the list */
+ blockrec = fs_new_block_rec(fpe, client, FS_LOAD_GLYPHS);
+ if (!blockrec)
+ return AllocError;
+ blockedglyph = (FSBlockedGlyphPtr) blockrec->data;
+ blockedglyph->pfont = pfont;
+ blockedglyph->num_expected_ranges = nranges;
+ /* Assumption: it's our job to free ranges */
+ blockedglyph->expected_ranges = ranges;
+ blockedglyph->clients_depending = (FSClientsDependingPtr)0;
+
+ if (conn->blockState & (FS_BROKEN_CONNECTION|FS_RECONNECTING))
+ {
+ _fs_pending_reply (conn);
+ return Suspended;
+ }
+
+ /* send the request */
+ req.reqType = FS_QueryXBitmaps16;
+ req.fid = ((FSFontDataPtr) pfont->fpePrivate)->fontid;
+ req.format = pfont->format;
+ if (pfont->info.terminalFont)
+ req.format = (req.format & ~(BitmapFormatImageRectMask)) |
+ BitmapFormatImageRectMax;
+ req.range = TRUE;
+ /* each range takes up 4 bytes */
+ req.length = (SIZEOF(fsQueryXBitmaps16Req) >> 2) + nranges;
+ req.num_ranges = nranges * 2; /* protocol wants count of fsChar2bs */
+ _fs_add_req_log(conn, FS_QueryXBitmaps16);
+ _fs_write(conn, (char *) &req, SIZEOF(fsQueryXBitmaps16Req));
+
+ blockrec->sequenceNumber = conn->current_seq;
+
+ /* Send ranges to the server... pack into a char array by hand
+ to avoid structure-packing portability problems and to
+ handle swapping for version1 protocol */
+ if (nranges)
+ {
+#define RANGE_BUFFER_SIZE 64
+#define RANGE_BUFFER_SIZE_MASK 63
+ int i;
+ char range_buffer[RANGE_BUFFER_SIZE * 4];
+ char *range_buffer_p;
+
+ range_buffer_p = range_buffer;
+ for (i = 0; i < nranges;)
+ {
+ if (conn->fsMajorVersion > 1)
+ {
+ *range_buffer_p++ = ranges[i].min_char_high;
+ *range_buffer_p++ = ranges[i].min_char_low;
+ *range_buffer_p++ = ranges[i].max_char_high;
+ *range_buffer_p++ = ranges[i].max_char_low;
+ }
+ else
+ {
+ *range_buffer_p++ = ranges[i].min_char_low;
+ *range_buffer_p++ = ranges[i].min_char_high;
+ *range_buffer_p++ = ranges[i].max_char_low;
+ *range_buffer_p++ = ranges[i].max_char_high;
+ }
+
+ if (!(++i & RANGE_BUFFER_SIZE_MASK))
+ {
+ _fs_write(conn, range_buffer, RANGE_BUFFER_SIZE * 4);
+ range_buffer_p = range_buffer;
+ }
+ }
+ if (i &= RANGE_BUFFER_SIZE_MASK)
+ _fs_write(conn, range_buffer, i * 4);
+ }
+
+ _fs_prepare_for_reply (conn);
+ return Suspended;
+}
+
+
+extern pointer serverClient; /* This could be any number that
+ doesn't conflict with existing
+ client values. */
+
+static int
+_fs_load_glyphs(pointer client, FontPtr pfont, Bool range_flag,
+ unsigned int nchars, int item_size, unsigned char *data)
+{
+ FSFpePtr conn = (FSFpePtr) pfont->fpe->private;
+ int nranges = 0;
+ fsRange *ranges = NULL;
+ int res;
+ FSBlockDataPtr blockrec;
+ FSBlockedGlyphPtr blockedglyph;
+ FSClientsDependingPtr *clients_depending = NULL;
+ int err;
+
+ /* see if the result is already there */
+ for (blockrec = conn->blockedRequests; blockrec; blockrec = blockrec->next)
+ {
+ if (blockrec->type == FS_LOAD_GLYPHS)
+ {
+ blockedglyph = (FSBlockedGlyphPtr) blockrec->data;
+ if (blockedglyph->pfont == pfont)
+ {
+ /* Look for this request */
+ if (blockrec->client == client)
+ {
+ err = blockrec->errcode;
+ if (err == StillWorking)
+ return Suspended;
+ _fs_signal_clients_depending(&blockedglyph->clients_depending);
+ _fs_remove_block_rec(conn, blockrec);
+ return err;
+ }
+ /* We've found an existing LoadGlyphs blockrec for this
+ font but for another client. Rather than build a
+ blockrec for it now (which entails some complex
+ maintenance), we'll add it to a queue of clients to
+ be signalled when the existing LoadGlyphs is
+ completed. */
+ clients_depending = &blockedglyph->clients_depending;
+ break;
+ }
+ }
+ else if (blockrec->type == FS_OPEN_FONT)
+ {
+ FSBlockedFontPtr bfont;
+ bfont = (FSBlockedFontPtr) blockrec->data;
+ if (bfont->pfont == pfont)
+ {
+ /*
+ * An OpenFont is pending for this font, this must
+ * be from a reopen attempt, so finish the open
+ * attempt and retry the LoadGlyphs
+ */
+ if (blockrec->client == client)
+ {
+ err = blockrec->errcode;
+ if (err == StillWorking)
+ return Suspended;
+
+ _fs_signal_clients_depending(&bfont->clients_depending);
+ _fs_remove_block_rec(conn, blockrec);
+ if (err != Successful)
+ return err;
+ break;
+ }
+ /* We've found an existing OpenFont blockrec for this
+ font but for another client. Rather than build a
+ blockrec for it now (which entails some complex
+ maintenance), we'll add it to a queue of clients to
+ be signalled when the existing OpenFont is
+ completed. */
+ if (blockrec->errcode == StillWorking)
+ {
+ clients_depending = &bfont->clients_depending;
+ break;
+ }
+ }
+ }
+ }
+
+ /*
+ * see if the desired glyphs already exist, and return Successful if they
+ * do, otherwise build up character range/character string
+ */
+ res = fs_build_range(pfont, range_flag, nchars, item_size, data,
+ &nranges, &ranges);
+
+ switch (res)
+ {
+ case AccessDone:
+ return Successful;
+
+ case Successful:
+ break;
+
+ default:
+ return res;
+ }
+
+ /*
+ * If clients_depending is not null, this request must wait for
+ * some prior request(s) to complete.
+ */
+ if (clients_depending)
+ {
+ /* Since we're not ready to send the load_glyphs request yet,
+ clean up the damage (if any) caused by the fs_build_range()
+ call. */
+ if (nranges)
+ {
+ _fs_clean_aborted_loadglyphs(pfont, nranges, ranges);
+ xfree(ranges);
+ }
+ return _fs_add_clients_depending(clients_depending, client);
+ }
+
+ /*
+ * If fsd->generation != conn->generation, the font has been closed
+ * due to a lost connection. We will reopen it, which will result
+ * in one of three things happening:
+ * 1) The open will succeed and obtain the same font. Life
+ * is wonderful.
+ * 2) The open will fail. There is code above to recognize this
+ * and flunk the LoadGlyphs request. The client might not be
+ * thrilled.
+ * 3) Worst case: the open will succeed but the font we open will
+ * be different. The fs_read_query_info() procedure attempts
+ * to detect this by comparing the existing metrics and
+ * properties against those of the reopened font... if they
+ * don't match, we flunk the reopen, which eventually results
+ * in flunking the LoadGlyphs request. We could go a step
+ * further and compare the extents, but this should be
+ * sufficient.
+ */
+ if (((FSFontDataPtr)pfont->fpePrivate)->generation != conn->generation)
+ {
+ /* Since we're not ready to send the load_glyphs request yet,
+ clean up the damage caused by the fs_build_range() call. */
+ _fs_clean_aborted_loadglyphs(pfont, nranges, ranges);
+ xfree(ranges);
+
+ /* Now try to reopen the font. */
+ return fs_send_open_font(client, pfont->fpe,
+ (Mask)FontReopen, (char *)0, 0,
+ (fsBitmapFormat)0, (fsBitmapFormatMask)0,
+ (XID)0, &pfont);
+ }
+
+ return fs_send_load_glyphs(client, pfont, nranges, ranges);
+}
+
+int
+fs_load_all_glyphs(FontPtr pfont)
+{
+ int err;
+ FSFpePtr conn = (FSFpePtr) pfont->fpe->private;
+
+ /*
+ * The purpose of this procedure is to load all glyphs in the event
+ * that we're dealing with someone who doesn't understand the finer
+ * points of glyph caching... it is called from _fs_get_glyphs() if
+ * the latter is called to get glyphs that have not yet been loaded.
+ * We assume that the caller will not know how to handle a return
+ * value of Suspended (usually the case for a GetGlyphs() caller),
+ * so this procedure hangs around, freezing the server, for the
+ * request to complete. This is an unpleasant kluge called to
+ * perform an unpleasant job that, we hope, will never be required.
+ */
+
+ while ((err = _fs_load_glyphs(serverClient, pfont, TRUE, 0, 0, NULL)) ==
+ Suspended)
+ {
+ if (fs_await_reply (conn) != FSIO_READY)
+ {
+ /* Get rid of blockrec */
+ fs_client_died(serverClient, pfont->fpe);
+ err = BadCharRange;
+ break;
+ }
+ fs_read_reply (pfont->fpe, serverClient);
+ }
+ return err;
+}
+
+static int
+fs_read_list(FontPathElementPtr fpe, FSBlockDataPtr blockrec)
+{
+ FSFpePtr conn = (FSFpePtr) fpe->private;
+ FSBlockedListPtr blist = (FSBlockedListPtr) blockrec->data;
+ fsListFontsReply *rep;
+ char *data;
+ int length,
+ i,
+ ret;
+ int err;
+
+ rep = (fsListFontsReply *) fs_get_reply (conn, &ret);
+ if (!rep || rep->type == FS_Error)
+ {
+ if (ret == FSIO_BLOCK)
+ return StillWorking;
+ if (rep)
+ _fs_done_read (conn, rep->length << 2);
+ return AllocError;
+ }
+ data = (char *) rep + SIZEOF (fsListFontsReply);
+
+ err = Successful;
+ /* copy data into FontPathRecord */
+ for (i = 0; i < rep->nFonts; i++)
+ {
+ length = *(unsigned char *)data++;
+ err = AddFontNamesName(blist->names, data, length);
+ if (err != Successful)
+ break;
+ data += length;
+ }
+ _fs_done_read (conn, rep->length << 2);
+ return err;
+}
+
+static int
+fs_send_list_fonts(pointer client, FontPathElementPtr fpe, char *pattern,
+ int patlen, int maxnames, FontNamesPtr newnames)
+{
+ FSFpePtr conn = (FSFpePtr) fpe->private;
+ FSBlockDataPtr blockrec;
+ FSBlockedListPtr blockedlist;
+ fsListFontsReq req;
+
+ if (conn->blockState & FS_GIVE_UP)
+ return BadFontName;
+
+ /* make a new block record, and add it to the end of the list */
+ blockrec = fs_new_block_rec(fpe, client, FS_LIST_FONTS);
+ if (!blockrec)
+ return AllocError;
+ blockedlist = (FSBlockedListPtr) blockrec->data;
+ blockedlist->names = newnames;
+
+ if (conn->blockState & (FS_BROKEN_CONNECTION | FS_RECONNECTING))
+ {
+ _fs_pending_reply (conn);
+ return Suspended;
+ }
+
+ _fs_client_access (conn, client, FALSE);
+ _fs_client_resolution(conn);
+
+ /* send the request */
+ req.reqType = FS_ListFonts;
+ req.maxNames = maxnames;
+ req.nbytes = patlen;
+ req.length = (SIZEOF(fsListFontsReq) + patlen + 3) >> 2;
+ _fs_add_req_log(conn, FS_ListFonts);
+ _fs_write(conn, (char *) &req, SIZEOF(fsListFontsReq));
+ _fs_write_pad(conn, (char *) pattern, patlen);
+
+ blockrec->sequenceNumber = conn->current_seq;
+
+#ifdef NCD
+ if (configData.ExtendedFontDiags) {
+ char buf[256];
+
+ memcpy(buf, pattern, MIN(256, patlen));
+ buf[MIN(256, patlen)] = '\0';
+ printf("Listing fonts on pattern \"%s\" from font server \"%s\"\n",
+ buf, fpe->name);
+ }
+#endif
+
+ _fs_prepare_for_reply (conn);
+ return Suspended;
+}
+
+static int
+fs_list_fonts(pointer client, FontPathElementPtr fpe,
+ char *pattern, int patlen, int maxnames, FontNamesPtr newnames)
+{
+ FSFpePtr conn = (FSFpePtr) fpe->private;
+ FSBlockDataPtr blockrec;
+ int err;
+
+ /* see if the result is already there */
+ for (blockrec = conn->blockedRequests; blockrec; blockrec = blockrec->next)
+ {
+ if (blockrec->type == FS_LIST_FONTS && blockrec->client == client)
+ {
+ err = blockrec->errcode;
+ if (err == StillWorking)
+ return Suspended;
+ _fs_remove_block_rec(conn, blockrec);
+ return err;
+ }
+ }
+
+ /* didn't find waiting record, so send a new one */
+ return fs_send_list_fonts(client, fpe, pattern, patlen, maxnames, newnames);
+}
+
+/*
+ * Read a single list info reply and restart for the next reply
+ */
+static int
+fs_read_list_info(FontPathElementPtr fpe, FSBlockDataPtr blockrec)
+{
+ FSBlockedListInfoPtr binfo = (FSBlockedListInfoPtr) blockrec->data;
+ fsListFontsWithXInfoReply *rep;
+ char *buf;
+ FSFpePtr conn = (FSFpePtr) fpe->private;
+ fsPropInfo *pi;
+ fsPropOffset *po;
+ pointer pd;
+ int ret;
+ int err;
+
+ /* clean up anything from the last trip */
+ _fs_free_props (&binfo->info);
+
+ rep = (fsListFontsWithXInfoReply *) fs_get_reply (conn, &ret);
+ if (!rep || rep->type == FS_Error)
+ {
+ if (ret == FSIO_BLOCK)
+ return StillWorking;
+ binfo->status = FS_LFWI_FINISHED;
+ err = AllocError;
+ goto done;
+ }
+ /*
+ * Normal termination -- the list ends with a name of length 0
+ */
+ if (rep->nameLength == 0)
+ {
+#ifdef DEBUG
+ fprintf (stderr, "fs_read_list_info done\n");
+#endif
+ binfo->status = FS_LFWI_FINISHED;
+ err = BadFontName;
+ goto done;
+ }
+
+ buf = (char *) rep + SIZEOF (fsListFontsWithXInfoReply);
+
+ /*
+ * The original FS implementation didn't match
+ * the spec, version 1 was respecified to match the FS.
+ * Version 2 matches the original intent
+ */
+ if (conn->fsMajorVersion <= 1)
+ {
+ memcpy (binfo->name, buf, rep->nameLength);
+ buf += _fs_pad_length (rep->nameLength);
+ }
+ pi = (fsPropInfo *) buf;
+ buf += SIZEOF (fsPropInfo);
+ po = (fsPropOffset *) buf;
+ buf += pi->num_offsets * SIZEOF (fsPropOffset);
+ pd = (pointer) buf;
+ buf += pi->data_len;
+ if (conn->fsMajorVersion > 1)
+ {
+ memcpy (binfo->name, buf, rep->nameLength);
+ buf += _fs_pad_length (rep->nameLength);
+ }
+
+#ifdef DEBUG
+ binfo->name[rep->nameLength] = '\0';
+ fprintf (stderr, "fs_read_list_info %s\n", binfo->name);
+#endif
+ err = _fs_convert_lfwi_reply(conn, &binfo->info, rep, pi, po, pd);
+ if (err != Successful)
+ {
+ binfo->status = FS_LFWI_FINISHED;
+ goto done;
+ }
+ binfo->namelen = rep->nameLength;
+ binfo->remaining = rep->nReplies;
+
+ binfo->status = FS_LFWI_REPLY;
+
+ /* disable this font server until we've processed this response */
+ _fs_unmark_block (conn, FS_COMPLETE_REPLY);
+ FD_CLR(conn->fs_fd, &_fs_fd_mask);
+done:
+ _fs_done_read (conn, rep->length << 2);
+ return err;
+}
+
+/* ARGSUSED */
+static int
+fs_start_list_with_info(pointer client, FontPathElementPtr fpe,
+ char *pattern, int len, int maxnames, pointer *pdata)
+{
+ FSFpePtr conn = (FSFpePtr) fpe->private;
+ FSBlockDataPtr blockrec;
+ FSBlockedListInfoPtr binfo;
+ fsListFontsWithXInfoReq req;
+
+ if (conn->blockState & FS_GIVE_UP)
+ return BadFontName;
+
+ /* make a new block record, and add it to the end of the list */
+ blockrec = fs_new_block_rec(fpe, client, FS_LIST_WITH_INFO);
+ if (!blockrec)
+ return AllocError;
+
+ binfo = (FSBlockedListInfoPtr) blockrec->data;
+ bzero((char *) binfo, sizeof(FSBlockedListInfoRec));
+ binfo->status = FS_LFWI_WAITING;
+
+ if (conn->blockState & (FS_BROKEN_CONNECTION | FS_RECONNECTING))
+ {
+ _fs_pending_reply (conn);
+ return Suspended;
+ }
+
+ _fs_client_access (conn, client, FALSE);
+ _fs_client_resolution(conn);
+
+ /* send the request */
+ req.reqType = FS_ListFontsWithXInfo;
+ req.maxNames = maxnames;
+ req.nbytes = len;
+ req.length = (SIZEOF(fsListFontsWithXInfoReq) + len + 3) >> 2;
+ _fs_add_req_log(conn, FS_ListFontsWithXInfo);
+ (void) _fs_write(conn, (char *) &req, SIZEOF(fsListFontsWithXInfoReq));
+ (void) _fs_write_pad(conn, pattern, len);
+
+ blockrec->sequenceNumber = conn->current_seq;
+
+#ifdef NCD
+ if (configData.ExtendedFontDiags) {
+ char buf[256];
+
+ memcpy(buf, pattern, MIN(256, len));
+ buf[MIN(256, len)] = '\0';
+ printf("Listing fonts with info on pattern \"%s\" from font server \"%s\"\n",
+ buf, fpe->name);
+ }
+#endif
+
+ _fs_prepare_for_reply (conn);
+ return Successful;
+}
+
+/* ARGSUSED */
+static int
+fs_next_list_with_info(pointer client, FontPathElementPtr fpe,
+ char **namep, int *namelenp,
+ FontInfoPtr *pFontInfo, int *numFonts,
+ pointer private)
+{
+ FSFpePtr conn = (FSFpePtr) fpe->private;
+ FSBlockDataPtr blockrec;
+ FSBlockedListInfoPtr binfo;
+ int err;
+
+ /* see if the result is already there */
+ for (blockrec = conn->blockedRequests; blockrec; blockrec = blockrec->next)
+ if (blockrec->type == FS_LIST_WITH_INFO && blockrec->client == client)
+ break;
+
+ if (!blockrec)
+ {
+ /* The only good reason for not finding a blockrec would be if
+ disconnect/reconnect to the font server wiped it out and the
+ code that called us didn't do the right thing to create
+ another one. Under those circumstances, we need to return an
+ error to prevent that code from attempting to interpret the
+ information we don't return. */
+ return BadFontName;
+ }
+
+ binfo = (FSBlockedListInfoPtr) blockrec->data;
+
+ if (binfo->status == FS_LFWI_WAITING)
+ return Suspended;
+
+ *namep = binfo->name;
+ *namelenp = binfo->namelen;
+ *pFontInfo = &binfo->info;
+ *numFonts = binfo->remaining;
+
+ /* Restart reply processing from this font server */
+ FD_SET(conn->fs_fd, &_fs_fd_mask);
+ if (fs_reply_ready (conn))
+ _fs_mark_block (conn, FS_COMPLETE_REPLY);
+
+ err = blockrec->errcode;
+ switch (binfo->status) {
+ case FS_LFWI_FINISHED:
+ _fs_remove_block_rec(conn, blockrec);
+ break;
+ case FS_LFWI_REPLY:
+ binfo->status = FS_LFWI_WAITING;
+ blockrec->errcode = StillWorking;
+ conn->blockedReplyTime = GetTimeInMillis () + FontServerRequestTimeout;
+ _fs_mark_block (conn, FS_PENDING_REPLY);
+ break;
+ }
+
+ return err;
+}
+
+/*
+ * Called when client exits
+ */
+
+static void
+fs_client_died(pointer client, FontPathElementPtr fpe)
+{
+ FSFpePtr conn = (FSFpePtr) fpe->private;
+ FSBlockDataPtr blockrec,
+ depending;
+ FSClientPtr *prev, cur;
+ fsFreeACReq freeac;
+
+ for (prev = &conn->clients; (cur = *prev); prev = &cur->next)
+ {
+ if (cur->client == client) {
+ freeac.reqType = FS_FreeAC;
+ freeac.id = cur->acid;
+ freeac.length = sizeof (fsFreeACReq) >> 2;
+ _fs_add_req_log(conn, FS_FreeAC);
+ _fs_write (conn, (char *) &freeac, sizeof (fsFreeACReq));
+ *prev = cur->next;
+ xfree (cur);
+ break;
+ }
+ }
+ /* find a pending requests */
+ for (blockrec = conn->blockedRequests; blockrec; blockrec = blockrec->next)
+ if (blockrec->client == client)
+ break;
+
+ if (!blockrec)
+ return;
+
+ /* replace the client pointers in this block rec with the chained one */
+ if ((depending = blockrec->depending))
+ {
+ blockrec->client = depending->client;
+ blockrec->depending = depending->depending;
+ blockrec = depending;
+ }
+ fs_abort_blockrec(conn, blockrec);
+}
+
+static void
+_fs_client_access (FSFpePtr conn, pointer client, Bool sync)
+{
+ FSClientPtr *prev, cur;
+ fsCreateACReq crac;
+ fsSetAuthorizationReq setac;
+ char *authorizations;
+ int authlen;
+ Bool new_cur = FALSE;
+ char padding[4] = { 0, 0, 0, 0 };
+
+#ifdef DEBUG
+ if (conn->blockState & (FS_RECONNECTING|FS_BROKEN_CONNECTION))
+ {
+ fprintf (stderr, "Sending requests without a connection\n");
+ }
+#endif
+ for (prev = &conn->clients; (cur = *prev); prev = &cur->next)
+ {
+ if (cur->client == client)
+ {
+ if (prev != &conn->clients)
+ {
+ *prev = cur->next;
+ cur->next = conn->clients;
+ conn->clients = cur;
+ }
+ break;
+ }
+ }
+ if (!cur)
+ {
+ cur = (FSClientPtr) xalloc (sizeof (FSClientRec));
+ if (!cur)
+ return;
+ cur->client = client;
+ cur->next = conn->clients;
+ conn->clients = cur;
+ cur->acid = GetNewFontClientID ();
+ new_cur = TRUE;
+ }
+ if (new_cur || cur->auth_generation != client_auth_generation(client))
+ {
+ if (!new_cur)
+ {
+ fsFreeACReq freeac;
+ freeac.reqType = FS_FreeAC;
+ freeac.id = cur->acid;
+ freeac.length = sizeof (fsFreeACReq) >> 2;
+ _fs_add_req_log(conn, FS_FreeAC);
+ _fs_write (conn, (char *) &freeac, sizeof (fsFreeACReq));
+ }
+ crac.reqType = FS_CreateAC;
+ crac.num_auths = set_font_authorizations(&authorizations, &authlen,
+ client);
+ /* Work around bug in xfs versions up through modular release 1.0.8
+ which rejects CreateAC packets with num_auths = 0 & authlen < 4 */
+ if (crac.num_auths == 0) {
+ authorizations = padding;
+ authlen = 4;
+ } else {
+ authlen = (authlen + 3) & ~0x3;
+ }
+ crac.length = (sizeof (fsCreateACReq) + authlen) >> 2;
+ crac.acid = cur->acid;
+ _fs_add_req_log(conn, FS_CreateAC);
+ _fs_write(conn, (char *) &crac, sizeof (fsCreateACReq));
+ _fs_write(conn, authorizations, authlen);
+ /* ignore reply; we don't even care about it */
+ conn->curacid = 0;
+ cur->auth_generation = client_auth_generation(client);
+ }
+ if (conn->curacid != cur->acid)
+ {
+ setac.reqType = FS_SetAuthorization;
+ setac.length = sizeof (fsSetAuthorizationReq) >> 2;
+ setac.id = cur->acid;
+ _fs_add_req_log(conn, FS_SetAuthorization);
+ _fs_write(conn, (char *) &setac, sizeof (fsSetAuthorizationReq));
+ conn->curacid = cur->acid;
+ }
+}
+
+/*
+ * Poll a pending connect
+ */
+
+static int
+_fs_check_connect (FSFpePtr conn)
+{
+ int ret;
+
+ ret = _fs_poll_connect (conn->trans_conn, 0);
+ switch (ret) {
+ case FSIO_READY:
+ conn->fs_fd = _FontTransGetConnectionNumber (conn->trans_conn);
+ FD_SET (conn->fs_fd, &_fs_fd_mask);
+ break;
+ case FSIO_BLOCK:
+ break;
+ }
+ return ret;
+}
+
+/*
+ * Return an FSIO status while waiting for the completed connection
+ * reply to arrive
+ */
+
+static fsConnSetup *
+_fs_get_conn_setup (FSFpePtr conn, int *error, int *setup_len)
+{
+ int ret;
+ char *data;
+ int headlen;
+ int len;
+ fsConnSetup *setup;
+ fsConnSetupAccept *accept;
+
+ ret = _fs_start_read (conn, SIZEOF (fsConnSetup), &data);
+ if (ret != FSIO_READY)
+ {
+ *error = ret;
+ return 0;
+ }
+
+ setup = (fsConnSetup *) data;
+ if (setup->major_version > FS_PROTOCOL)
+ {
+ *error = FSIO_ERROR;
+ return 0;
+ }
+
+ headlen = (SIZEOF (fsConnSetup) +
+ (setup->alternate_len << 2) +
+ (setup->auth_len << 2));
+ /* On anything but Success, no extra data is sent */
+ if (setup->status != AuthSuccess)
+ {
+ len = headlen;
+ }
+ else
+ {
+ ret = _fs_start_read (conn, headlen + SIZEOF (fsConnSetupAccept), &data);
+ if (ret != FSIO_READY)
+ {
+ *error = ret;
+ return 0;
+ }
+ setup = (fsConnSetup *) data;
+ accept = (fsConnSetupAccept *) (data + headlen);
+ len = headlen + (accept->length << 2);
+ }
+ ret = _fs_start_read (conn, len, &data);
+ if (ret != FSIO_READY)
+ {
+ *error = ret;
+ return 0;
+ }
+ *setup_len = len;
+ return (fsConnSetup *) data;
+}
+
+static int
+_fs_send_conn_client_prefix (FSFpePtr conn)
+{
+ fsConnClientPrefix req;
+ int endian;
+ int ret;
+
+ /* send setup prefix */
+ endian = 1;
+ if (*(char *) &endian)
+ req.byteOrder = 'l';
+ else
+ req.byteOrder = 'B';
+
+ req.major_version = FS_PROTOCOL;
+ req.minor_version = FS_PROTOCOL_MINOR;
+
+/* XXX add some auth info here */
+ req.num_auths = 0;
+ req.auth_len = 0;
+ ret = _fs_write (conn, (char *) &req, SIZEOF (fsConnClientPrefix));
+ if (ret != FSIO_READY)
+ return FSIO_ERROR;
+ conn->blockedConnectTime = GetTimeInMillis () + FontServerRequestTimeout;
+ return ret;
+}
+
+static int
+_fs_recv_conn_setup (FSFpePtr conn)
+{
+ int ret = FSIO_ERROR;
+ fsConnSetup *setup;
+ FSFpeAltPtr alts;
+ int i, alt_len;
+ int setup_len;
+ char *alt_save, *alt_names;
+
+ setup = _fs_get_conn_setup (conn, &ret, &setup_len);
+ if (!setup)
+ return ret;
+ conn->current_seq = 0;
+ conn->fsMajorVersion = setup->major_version;
+ /*
+ * Create an alternate list from the initial server, but
+ * don't chain looking for alternates.
+ */
+ if (conn->alternate == 0)
+ {
+ /*
+ * free any existing alternates list, allowing the list to
+ * be updated
+ */
+ if (conn->alts)
+ {
+ xfree (conn->alts);
+ conn->alts = 0;
+ conn->numAlts = 0;
+ }
+ if (setup->num_alternates)
+ {
+ alts = (FSFpeAltPtr) xalloc (setup->num_alternates *
+ sizeof (FSFpeAltRec) +
+ (setup->alternate_len << 2));
+ if (alts)
+ {
+ alt_names = (char *) (setup + 1);
+ alt_save = (char *) (alts + setup->num_alternates);
+ for (i = 0; i < setup->num_alternates; i++)
+ {
+ alts[i].subset = alt_names[0];
+ alt_len = alt_names[1];
+ alts[i].name = alt_save;
+ memcpy (alt_save, alt_names + 2, alt_len);
+ alt_save[alt_len] = '\0';
+ alt_save += alt_len + 1;
+ alt_names += _fs_pad_length (alt_len + 2);
+ }
+ conn->numAlts = setup->num_alternates;
+ conn->alts = alts;
+ }
+ }
+ }
+ _fs_done_read (conn, setup_len);
+ if (setup->status != AuthSuccess)
+ return FSIO_ERROR;
+ return FSIO_READY;
+}
+
+static int
+_fs_open_server (FSFpePtr conn)
+{
+ int ret;
+ char *servername;
+
+ if (conn->alternate == 0)
+ servername = conn->servername;
+ else
+ servername = conn->alts[conn->alternate-1].name;
+ conn->trans_conn = _fs_connect (servername, &ret);
+ conn->blockedConnectTime = GetTimeInMillis () + FS_RECONNECT_WAIT;
+ return ret;
+}
+
+static char *
+_fs_catalog_name (char *servername)
+{
+ char *sp;
+
+ sp = strchr (servername, '/');
+ if (!sp)
+ return 0;
+ return strrchr (sp + 1, '/');
+}
+
+static int
+_fs_send_init_packets (FSFpePtr conn)
+{
+ fsSetResolutionReq srreq;
+ fsSetCataloguesReq screq;
+ int num_cats,
+ clen;
+ char *catalogues;
+ char *cat;
+ char len;
+ char *end;
+ int num_res;
+ FontResolutionPtr res;
+
+#define CATALOGUE_SEP '+'
+
+ res = GetClientResolutions(&num_res);
+ if (num_res)
+ {
+ srreq.reqType = FS_SetResolution;
+ srreq.num_resolutions = num_res;
+ srreq.length = (SIZEOF(fsSetResolutionReq) +
+ (num_res * SIZEOF(fsResolution)) + 3) >> 2;
+
+ _fs_add_req_log(conn, FS_SetResolution);
+ if (_fs_write(conn, (char *) &srreq, SIZEOF(fsSetResolutionReq)) != FSIO_READY)
+ return FSIO_ERROR;
+ if (_fs_write_pad(conn, (char *) res, (num_res * SIZEOF(fsResolution))) != FSIO_READY)
+ return FSIO_ERROR;
+ }
+
+ catalogues = 0;
+ if (conn->alternate != 0)
+ catalogues = _fs_catalog_name (conn->alts[conn->alternate-1].name);
+ if (!catalogues)
+ catalogues = _fs_catalog_name (conn->servername);
+
+ if (!catalogues)
+ {
+ conn->has_catalogues = FALSE;
+ return FSIO_READY;
+ }
+ conn->has_catalogues = TRUE;
+
+ /* turn cats into counted list */
+ catalogues++;
+
+ cat = catalogues;
+ num_cats = 0;
+ clen = 0;
+ while (*cat)
+ {
+ num_cats++;
+ end = strchr(cat, CATALOGUE_SEP);
+ if (!end)
+ end = cat + strlen (cat);
+ clen += (end - cat) + 1; /* length byte + string */
+ cat = end;
+ }
+
+ screq.reqType = FS_SetCatalogues;
+ screq.num_catalogues = num_cats;
+ screq.length = (SIZEOF(fsSetCataloguesReq) + clen + 3) >> 2;
+
+ _fs_add_req_log(conn, FS_SetCatalogues);
+ if (_fs_write(conn, (char *) &screq, SIZEOF(fsSetCataloguesReq)) != FSIO_READY)
+ return FSIO_ERROR;
+
+ while (*cat)
+ {
+ num_cats++;
+ end = strchr(cat, CATALOGUE_SEP);
+ if (!end)
+ end = cat + strlen (cat);
+ len = end - cat;
+ if (_fs_write (conn, &len, 1) != FSIO_READY)
+ return FSIO_ERROR;
+ if (_fs_write (conn, cat, (int) len) != FSIO_READY)
+ return FSIO_ERROR;
+ cat = end;
+ }
+
+ if (_fs_write (conn, "....", _fs_pad_length (clen) - clen) != FSIO_READY)
+ return FSIO_ERROR;
+
+ return FSIO_READY;
+}
+
+static int
+_fs_send_cat_sync (FSFpePtr conn)
+{
+ fsListCataloguesReq lcreq;
+
+ /*
+ * now sync up with the font server, to see if an error was generated
+ * by a bogus catalogue
+ */
+ lcreq.reqType = FS_ListCatalogues;
+ lcreq.length = (SIZEOF(fsListCataloguesReq)) >> 2;
+ lcreq.maxNames = 0;
+ lcreq.nbytes = 0;
+ _fs_add_req_log(conn, FS_SetCatalogues);
+ if (_fs_write(conn, (char *) &lcreq, SIZEOF(fsListCataloguesReq)) != FSIO_READY)
+ return FSIO_ERROR;
+ conn->blockedConnectTime = GetTimeInMillis () + FontServerRequestTimeout;
+ return FSIO_READY;
+}
+
+static int
+_fs_recv_cat_sync (FSFpePtr conn)
+{
+ fsGenericReply *reply;
+ fsError *error;
+ int err;
+ int ret;
+
+ reply = fs_get_reply (conn, &err);
+ if (!reply)
+ return err;
+
+ ret = FSIO_READY;
+ if (reply->type == FS_Error)
+ {
+ error = (fsError *) reply;
+ if (error->major_opcode == FS_SetCatalogues)
+ ret = FSIO_ERROR;
+ }
+ _fs_done_read (conn, reply->length << 2);
+ return ret;
+}
+
+static void
+_fs_close_server (FSFpePtr conn)
+{
+ _fs_unmark_block (conn, FS_PENDING_WRITE|FS_BROKEN_WRITE|FS_COMPLETE_REPLY|FS_BROKEN_CONNECTION);
+ if (conn->trans_conn)
+ {
+ _FontTransClose (conn->trans_conn);
+ conn->trans_conn = 0;
+ _fs_io_reinit (conn);
+ }
+ if (conn->fs_fd >= 0)
+ {
+ FD_CLR (conn->fs_fd, &_fs_fd_mask);
+ conn->fs_fd = -1;
+ }
+ conn->fs_conn_state = FS_CONN_UNCONNECTED;
+}
+
+static int
+_fs_do_setup_connection (FSFpePtr conn)
+{
+ int ret;
+
+ do
+ {
+#ifdef DEBUG
+ fprintf (stderr, "fs_do_setup_connection state %d\n", conn->fs_conn_state);
+#endif
+ switch (conn->fs_conn_state) {
+ case FS_CONN_UNCONNECTED:
+ ret = _fs_open_server (conn);
+ if (ret == FSIO_BLOCK)
+ conn->fs_conn_state = FS_CONN_CONNECTING;
+ break;
+ case FS_CONN_CONNECTING:
+ ret = _fs_check_connect (conn);
+ break;
+ case FS_CONN_CONNECTED:
+ ret = _fs_send_conn_client_prefix (conn);
+ break;
+ case FS_CONN_SENT_PREFIX:
+ ret = _fs_recv_conn_setup (conn);
+ break;
+ case FS_CONN_RECV_INIT:
+ ret = _fs_send_init_packets (conn);
+ if (conn->has_catalogues)
+ ret = _fs_send_cat_sync (conn);
+ break;
+ case FS_CONN_SENT_CAT:
+ if (conn->has_catalogues)
+ ret = _fs_recv_cat_sync (conn);
+ else
+ ret = FSIO_READY;
+ break;
+ default:
+ ret = FSIO_READY;
+ break;
+ }
+ switch (ret) {
+ case FSIO_READY:
+ if (conn->fs_conn_state < FS_CONN_RUNNING)
+ conn->fs_conn_state++;
+ break;
+ case FSIO_BLOCK:
+ if (TimeCmp (GetTimeInMillis (), <, conn->blockedConnectTime))
+ break;
+ ret = FSIO_ERROR;
+ /* fall through... */
+ case FSIO_ERROR:
+ _fs_close_server (conn);
+ /*
+ * Try the next alternate
+ */
+ if (conn->alternate < conn->numAlts)
+ {
+ conn->alternate++;
+ ret = FSIO_READY;
+ }
+ else
+ conn->alternate = 0;
+ break;
+ }
+ } while (conn->fs_conn_state != FS_CONN_RUNNING && ret == FSIO_READY);
+ if (ret == FSIO_READY)
+ conn->generation = ++generationCount;
+ return ret;
+}
+
+static int
+_fs_wait_connect (FSFpePtr conn)
+{
+ int ret;
+
+ for (;;)
+ {
+ ret = _fs_do_setup_connection (conn);
+ if (ret != FSIO_BLOCK)
+ break;
+ if (conn->fs_conn_state <= FS_CONN_CONNECTING)
+ ret = _fs_poll_connect (conn->trans_conn, 1000);
+ else
+ ret = _fs_wait_for_readable (conn, 1000);
+ if (ret == FSIO_ERROR)
+ break;
+ }
+ return ret;
+}
+
+/*
+ * Poll a connection in the process of reconnecting
+ */
+static void
+_fs_check_reconnect (FSFpePtr conn)
+{
+ int ret;
+
+ ret = _fs_do_setup_connection (conn);
+ switch (ret) {
+ case FSIO_READY:
+ _fs_unmark_block (conn, FS_RECONNECTING|FS_GIVE_UP);
+ _fs_restart_connection (conn);
+ break;
+ case FSIO_BLOCK:
+ break;
+ case FSIO_ERROR:
+ conn->brokenConnectionTime = GetTimeInMillis () + FS_RECONNECT_POLL;
+ break;
+ }
+}
+
+/*
+ * Start the reconnection process
+ */
+static void
+_fs_start_reconnect (FSFpePtr conn)
+{
+ if (conn->blockState & FS_RECONNECTING)
+ return;
+ conn->alternate = 0;
+ _fs_mark_block (conn, FS_RECONNECTING);
+ _fs_unmark_block (conn, FS_BROKEN_CONNECTION);
+ _fs_check_reconnect (conn);
+}
+
+
+static FSFpePtr
+_fs_init_conn (char *servername)
+{
+ FSFpePtr conn;
+
+ conn = xalloc (sizeof (FSFpeRec) + strlen (servername) + 1);
+ if (!conn)
+ return 0;
+ memset (conn, '\0', sizeof (FSFpeRec));
+ if (!_fs_io_init (conn))
+ {
+ xfree (conn);
+ return 0;
+ }
+ conn->servername = (char *) (conn + 1);
+ conn->fs_conn_state = FS_CONN_UNCONNECTED;
+ conn->fs_fd = -1;
+ strcpy (conn->servername, servername);
+ return conn;
+}
+
+static void
+_fs_free_conn (FSFpePtr conn)
+{
+ _fs_close_server (conn);
+ _fs_io_fini (conn);
+ if (conn->alts)
+ xfree (conn->alts);
+ xfree (conn);
+}
+
+/*
+ * called at server init time
+ */
+
+void
+fs_register_fpe_functions(void)
+{
+ RegisterFPEFunctions(fs_name_check,
+ fs_init_fpe,
+ fs_free_fpe,
+ fs_reset_fpe,
+ fs_open_font,
+ fs_close_font,
+ fs_list_fonts,
+ fs_start_list_with_info,
+ fs_next_list_with_info,
+ fs_wakeup,
+ fs_client_died,
+ _fs_load_glyphs,
+ NULL,
+ NULL,
+ NULL);
+}
+
+static int
+check_fs_open_font(pointer client, FontPathElementPtr fpe, Mask flags,
+ char *name, int namelen,
+ fsBitmapFormat format, fsBitmapFormatMask fmask,
+ XID id, FontPtr *ppfont,
+ char **alias, FontPtr non_cachable_font)
+{
+ if (XpClientIsBitmapClient(client))
+ return (fs_open_font(client, fpe, flags, name, namelen, format,
+ fmask, id, ppfont, alias, non_cachable_font) );
+ return BadFontName;
+}
+
+static int
+check_fs_list_fonts(pointer client, FontPathElementPtr fpe,
+ char *pattern, int patlen, int maxnames,
+ FontNamesPtr newnames)
+{
+ if (XpClientIsBitmapClient(client))
+ return (fs_list_fonts(client, fpe, pattern, patlen, maxnames,
+ newnames));
+ return BadFontName;
+}
+
+static int
+check_fs_start_list_with_info(pointer client, FontPathElementPtr fpe,
+ char *pattern, int len, int maxnames,
+ pointer *pdata)
+{
+ if (XpClientIsBitmapClient(client))
+ return (fs_start_list_with_info(client, fpe, pattern, len, maxnames,
+ pdata));
+ return BadFontName;
+}
+
+static int
+check_fs_next_list_with_info(pointer client, FontPathElementPtr fpe,
+ char **namep, int *namelenp,
+ FontInfoPtr *pFontInfo, int *numFonts,
+ pointer private)
+{
+ if (XpClientIsBitmapClient(client))
+ return (fs_next_list_with_info(client, fpe, namep, namelenp, pFontInfo,
+ numFonts,private));
+ return BadFontName;
+}
+
+void
+check_fs_register_fpe_functions(void)
+{
+ RegisterFPEFunctions(fs_name_check,
+ fs_init_fpe,
+ fs_free_fpe,
+ fs_reset_fpe,
+ check_fs_open_font,
+ fs_close_font,
+ check_fs_list_fonts,
+ check_fs_start_list_with_info,
+ check_fs_next_list_with_info,
+ fs_wakeup,
+ fs_client_died,
+ _fs_load_glyphs,
+ NULL,
+ NULL,
+ NULL);
+}
diff --git a/libXfont/src/fc/fserve.h b/libXfont/src/fc/fserve.h
new file mode 100644
index 000000000..3b08526f9
--- /dev/null
+++ b/libXfont/src/fc/fserve.h
@@ -0,0 +1,93 @@
+/* $Xorg: fserve.h,v 1.3 2000/08/17 19:46:36 cpqbld Exp $ */
+/*
+ * Copyright 1990 Network Computing Devices
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of Network Computing Devices not be
+ * used in advertising or publicity pertaining to distribution of the
+ * software without specific, written prior permission. Network Computing
+ * Devices makes no representations about the suitability of this software
+ * for any purpose. It is provided "as is" without express or implied
+ * warranty.
+ *
+ * NETWORK COMPUTING DEVICES DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
+ * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS,
+ * IN NO EVENT SHALL NETWORK COMPUTING DEVICES BE LIABLE FOR ANY SPECIAL,
+ * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+ * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+ * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE
+ * OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Author: Dave Lemke, Network Computing Devices, Inc
+ *
+ */
+/* $XFree86: xc/lib/font/fc/fserve.h,v 1.4 2001/01/17 19:43:29 dawes Exp $ */
+
+#ifndef _FSERVE_H_
+#define _FSERVE_H_
+/*
+ * font server data structures
+ */
+
+/* types of block records */
+#define FS_OPEN_FONT 1
+#define FS_LOAD_GLYPHS 2
+#define FS_LIST_FONTS 3
+#define FS_LIST_WITH_INFO 4
+
+/* states of OpenFont */
+#define FS_OPEN_REPLY 0
+#define FS_INFO_REPLY 1
+#define FS_EXTENT_REPLY 2
+#define FS_GLYPHS_REPLY 3
+#define FS_DONE_REPLY 4
+#define FS_DEPENDING 5
+
+/* status of ListFontsWithInfo */
+#define FS_LFWI_WAITING 0
+#define FS_LFWI_REPLY 1
+#define FS_LFWI_FINISHED 2
+
+/* states of connection */
+#define FS_CONN_CLOSED 0
+#define FS_CONN_CONNECTING 1
+#define FS_CONN_READ_HEADER 2
+#define FS_CONN_READ_DATA 3
+
+#define AccessDone 0x400
+
+typedef struct _fs_font_data *FSFontDataPtr;
+typedef struct _fs_blocked_font *FSBlockedFontPtr;
+typedef struct _fs_blocked_glyphs *FSBlockedGlyphPtr;
+typedef struct _fs_blocked_list *FSBlockedListPtr;
+typedef struct _fs_blocked_list_info *FSBlockedListInfoPtr;
+typedef struct _fs_block_data *FSBlockDataPtr;
+typedef struct _fs_font_table *FSFontTablePtr;
+typedef struct _fs_fpe_data *FSFpePtr;
+
+typedef struct _fs_blocked_bitmaps *FSBlockedBitmapPtr;
+typedef struct _fs_blocked_extents *FSBlockedExtentPtr;
+
+extern void _fs_convert_char_info ( fsXCharInfo *src, xCharInfo *dst );
+extern void _fs_free_props (FontInfoPtr pfi);
+extern FontPtr fs_create_font (FontPathElementPtr fpe,
+ char *name,
+ int namelen,
+ fsBitmapFormat format,
+ fsBitmapFormatMask fmask);
+
+extern int fs_load_all_glyphs ( FontPtr pfont );
+
+/*
+ * These should be declared elsewhere, but I'm concerned that moving them
+ * would cause problems building other pieces
+ */
+extern FontPtr find_old_font (Font id);
+extern int set_font_authorizations (char **a, int *len, pointer client);
+extern long GetTimeInMillis (void);
+
+
+#endif /* _FSERVE_H_ */
diff --git a/libXfont/src/fc/fservestr.h b/libXfont/src/fc/fservestr.h
new file mode 100644
index 000000000..1993de867
--- /dev/null
+++ b/libXfont/src/fc/fservestr.h
@@ -0,0 +1,202 @@
+/* $Xorg: fservestr.h,v 1.3 2000/08/17 19:46:36 cpqbld Exp $ */
+/*
+ * Copyright 1990 Network Computing Devices
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and
+ * its documentation for any purpose is hereby granted without fee, provided
+ * that the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of Network Computing Devices not be
+ * used in advertising or publicity pertaining to distribution of the
+ * software without specific, written prior permission. Network Computing
+ * Devices makes no representations about the suitability of this software
+ * for any purpose. It is provided "as is" without express or implied
+ * warranty.
+ *
+ * NETWORK COMPUTING DEVICES DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
+ * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS,
+ * IN NO EVENT SHALL NETWORK COMPUTING DEVICES BE LIABLE FOR ANY SPECIAL,
+ * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+ * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+ * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE
+ * OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Author: Dave Lemke, Network Computing Devices, Inc
+ */
+/* $XFree86: xc/lib/font/fc/fservestr.h,v 3.3 2001/01/17 19:43:29 dawes Exp $ */
+
+#ifndef _FSERVESTR_H_
+#define _FSERVESTR_H_
+
+#include "fserve.h"
+#include "fsio.h"
+
+/*
+ * font server data structures
+ */
+/*
+ * font server private storage
+ */
+
+typedef struct _fs_glyph {
+ struct _fs_glyph *next;
+} FSGlyphRec, *FSGlyphPtr;
+
+typedef struct _fs_font {
+ CharInfoPtr pDefault;
+ CharInfoPtr encoding;
+ CharInfoPtr inkMetrics;
+ FSGlyphPtr glyphs;
+} FSFontRec, *FSFontPtr;
+
+/* FS special data for the font */
+typedef struct _fs_font_data {
+ long fontid;
+ int generation; /* FS generation when opened */
+ unsigned long glyphs_to_get; /* # glyphs remaining to be gotten */
+
+ /* Following data needed in case font needs to be reopened. */
+ int namelen;
+ char *name;
+ fsBitmapFormat format;
+ fsBitmapFormatMask fmask;
+} FSFontDataRec;
+
+typedef struct fs_clients_depending {
+ pointer client;
+ struct fs_clients_depending *next;
+} FSClientsDependingRec, *FSClientsDependingPtr;
+
+/* OpenFont specific data for blocked request */
+typedef struct _fs_blocked_font {
+ FontPtr pfont; /* must be first for fs_read_glyphs */
+ long fontid;
+ int state; /* how many of the replies have landed */
+ int flags;
+ Bool freeFont; /* free this font on failure */
+ CARD16 queryInfoSequence;
+ CARD16 queryExtentsSequence;
+ CARD16 queryBitmapsSequence;
+ fsBitmapFormat format;
+ FSClientsDependingPtr clients_depending;
+} FSBlockedFontRec;
+
+/* LoadGlyphs data for blocked request */
+typedef struct _fs_blocked_glyphs {
+ FontPtr pfont; /* must be first for fs_read_glyphs */
+ int num_expected_ranges;
+ fsRange *expected_ranges;
+ FSClientsDependingPtr clients_depending;
+} FSBlockedGlyphRec;
+
+/* LoadExtents data for blocked request */
+typedef struct _fs_blocked_extents {
+ FontPtr pfont;
+ fsRange *expected_ranges;
+ int nranges;
+ unsigned long nextents;
+ fsXCharInfo *extents;
+} FSBlockedExtentRec;
+
+/* LoadBitmaps data for blocked request */
+typedef struct _fs_blocked_bitmaps {
+ FontPtr pfont;
+ fsRange *expected_ranges;
+ int nranges;
+ unsigned long size;
+ unsigned long nglyphs;
+ fsOffset32 *offsets;
+ pointer gdata;
+} FSBlockedBitmapRec;
+
+/* state for blocked ListFonts */
+typedef struct _fs_blocked_list {
+ FontNamesPtr names;
+} FSBlockedListRec;
+
+/* state for blocked ListFontsWithInfo */
+typedef struct _fs_blocked_list_info {
+ int status;
+ int namelen;
+ FontInfoRec info;
+ char name[256];
+ int remaining;
+} FSBlockedListInfoRec;
+
+/* state for blocked request */
+typedef struct _fs_block_data {
+ int type; /* Open Font, LoadGlyphs, ListFonts,
+ * ListWithInfo */
+ pointer client; /* who wants it */
+ CARD16 sequenceNumber; /* expected */
+ pointer data; /* type specific data */
+ int errcode; /* Suspended, et al. */
+ struct _fs_block_data *depending; /* clients depending on this one */
+ struct _fs_block_data *next;
+} FSBlockDataRec;
+
+/* state for reconnected to dead font server */
+typedef struct _fs_reconnect {
+ int i;
+} FSReconnectRec, *FSReconnectPtr;
+
+
+#if !defined(UNIXCPP) || defined(ANSICPP)
+#define fsCat(x,y) x##_##y
+#else
+#define fsCat(x,y) x/**/_/**/y
+#endif
+
+
+/* copy XCharInfo parts of a protocol reply into a xCharInfo */
+
+#define fsUnpack_XCharInfo(packet, structure) \
+ (structure)->leftSideBearing = fsCat(packet,left); \
+ (structure)->rightSideBearing = fsCat(packet,right); \
+ (structure)->characterWidth = fsCat(packet,width); \
+ (structure)->ascent = fsCat(packet,ascent); \
+ (structure)->descent = fsCat(packet,descent); \
+ (structure)->attributes = fsCat(packet,attributes)
+
+
+/* copy XFontInfoHeader parts of a protocol reply into a FontInfoRec */
+
+#define fsUnpack_XFontInfoHeader(packet, structure) \
+ (structure)->allExist = ((packet)->font_header_flags & FontInfoAllCharsExist) != 0; \
+ (structure)->drawDirection = \
+ ((packet)->font_header_draw_direction == LeftToRightDrawDirection) ? \
+ LeftToRight : RightToLeft; \
+ (structure)->inkInside = ((packet)->font_header_flags & FontInfoInkInside) != 0; \
+ \
+ (structure)->firstRow = (packet)->font_hdr_char_range_min_char_high; \
+ (structure)->firstCol = (packet)->font_hdr_char_range_min_char_low; \
+ (structure)->lastRow = (packet)->font_hdr_char_range_max_char_high; \
+ (structure)->lastCol = (packet)->font_hdr_char_range_max_char_low; \
+ (structure)->defaultCh = (packet)->font_header_default_char_low \
+ + ((packet)->font_header_default_char_high << 8); \
+ \
+ (structure)->fontDescent = (packet)->font_header_font_descent; \
+ (structure)->fontAscent = (packet)->font_header_font_ascent; \
+ \
+ fsUnpack_XCharInfo((packet)->font_header_min_bounds, &(structure)->minbounds); \
+ fsUnpack_XCharInfo((packet)->font_header_min_bounds, &(structure)->ink_minbounds); \
+ fsUnpack_XCharInfo((packet)->font_header_max_bounds, &(structure)->maxbounds); \
+ fsUnpack_XCharInfo((packet)->font_header_max_bounds, &(structure)->ink_maxbounds)
+
+extern void _fs_init_fontinfo ( FSFpePtr conn, FontInfoPtr pfi );
+extern int _fs_convert_props ( fsPropInfo *pi, fsPropOffset *po, pointer pd,
+ FontInfoPtr pfi );
+extern int _fs_convert_lfwi_reply ( FSFpePtr conn, FontInfoPtr pfi,
+ fsListFontsWithXInfoReply *fsrep,
+ fsPropInfo *pi, fsPropOffset *po,
+ pointer pd );
+extern int fs_build_range ( FontPtr pfont, Bool range_flag,
+ unsigned int count, int item_size,
+ unsigned char *data, int *nranges,
+ fsRange **ranges );
+extern void _fs_clean_aborted_loadglyphs ( FontPtr pfont,
+ int num_expected_ranges,
+ fsRange *expected_ranges );
+extern void _fs_init_font ( FontPtr pfont );
+extern pointer fs_alloc_glyphs (FontPtr pFont, int size);
+#endif /* _FSERVESTR_H_ */
diff --git a/libXfont/src/fc/fsio.c b/libXfont/src/fc/fsio.c
new file mode 100644
index 000000000..2b55f8520
--- /dev/null
+++ b/libXfont/src/fc/fsio.c
@@ -0,0 +1,454 @@
+/* $Xorg: fsio.c,v 1.3 2000/08/17 19:46:36 cpqbld Exp $ */
+/*
+ * Copyright 1990 Network Computing Devices
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of Network Computing Devices not be
+ * used in advertising or publicity pertaining to distribution of the
+ * software without specific, written prior permission. Network Computing
+ * Devices makes no representations about the suitability of this software
+ * for any purpose. It is provided "as is" without express or implied
+ * warranty.
+ *
+ * NETWORK COMPUTING DEVICES DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
+ * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS,
+ * IN NO EVENT SHALL NETWORK COMPUTING DEVICES BE LIABLE FOR ANY SPECIAL,
+ * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+ * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+ * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE
+ * OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Author: Dave Lemke, Network Computing Devices, Inc
+ */
+/* $XFree86: xc/lib/font/fc/fsio.c,v 3.16tsi Exp $ */
+/*
+ * font server i/o routines
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#ifdef WIN32
+#define _WILLWINSOCK_
+#include "X11/Xwindows.h"
+#endif
+
+#define FONT_t
+#define TRANS_CLIENT
+#include "X11/Xtrans/Xtrans.h"
+#include "X11/Xpoll.h"
+#include <X11/fonts/FS.h>
+#include <X11/fonts/FSproto.h>
+#include <X11/fonts/fontmisc.h>
+#include <X11/fonts/fontstruct.h>
+#include "fservestr.h"
+
+#include <stdio.h>
+#include <signal.h>
+#include <sys/types.h>
+#if !defined(WIN32)
+#ifndef Lynx
+#include <sys/socket.h>
+#else
+#include <socket.h>
+#endif
+#endif
+#include <errno.h>
+#ifdef WIN32
+#define EWOULDBLOCK WSAEWOULDBLOCK
+#undef EINTR
+#define EINTR WSAEINTR
+#endif
+
+#ifdef __UNIXOS2__
+#define select(n,r,w,x,t) os2PseudoSelect(n,r,w,x,t)
+#endif
+
+
+static int padlength[4] = {0, 3, 2, 1};
+fd_set _fs_fd_mask;
+
+static int
+_fs_resize (FSBufPtr buf, long size);
+
+static void
+_fs_downsize (FSBufPtr buf, long size);
+
+int
+_fs_poll_connect (XtransConnInfo trans_conn, int timeout)
+{
+ fd_set w_mask;
+ struct timeval tv;
+ int fs_fd = _FontTransGetConnectionNumber (trans_conn);
+ int ret;
+
+ do
+ {
+ tv.tv_usec = 0;
+ tv.tv_sec = timeout;
+ FD_ZERO (&w_mask);
+ FD_SET (fs_fd, &w_mask);
+ ret = Select (fs_fd + 1, NULL, &w_mask, NULL, &tv);
+ } while (ret < 0 && ECHECK(EINTR));
+ if (ret == 0)
+ return FSIO_BLOCK;
+ if (ret < 0)
+ return FSIO_ERROR;
+ return FSIO_READY;
+}
+
+XtransConnInfo
+_fs_connect(char *servername, int *err)
+{
+ XtransConnInfo trans_conn; /* transport connection object */
+ int ret;
+ int i = 0;
+ int retries = 5;
+
+ /*
+ * Open the network connection.
+ */
+ if( (trans_conn=_FontTransOpenCOTSClient(servername)) == NULL )
+ {
+ *err = FSIO_ERROR;
+ return 0;
+ }
+
+ /*
+ * Set the connection non-blocking since we use select() to block.
+ */
+
+ _FontTransSetOption(trans_conn, TRANS_NONBLOCKING, 1);
+
+ do {
+ i = _FontTransConnect(trans_conn,servername);
+ } while ((i == TRANS_TRY_CONNECT_AGAIN) && (retries-- > 0));
+
+ if (i < 0)
+ {
+ if (i == TRANS_IN_PROGRESS)
+ ret = FSIO_BLOCK;
+ else
+ ret = FSIO_ERROR;
+ }
+ else
+ ret = FSIO_READY;
+
+ if (ret == FSIO_ERROR)
+ {
+ _FontTransClose(trans_conn);
+ trans_conn = 0;
+ }
+
+ *err = ret;
+ return trans_conn;
+}
+
+static int
+_fs_fill (FSFpePtr conn)
+{
+ long avail;
+ long bytes_read;
+ Bool waited = FALSE;
+
+ if (_fs_flush (conn) < 0)
+ return FSIO_ERROR;
+ /*
+ * Don't go overboard here; stop reading when we've
+ * got enough to satisfy the pending request
+ */
+ while ((conn->inNeed - (conn->inBuf.insert - conn->inBuf.remove)) > 0)
+ {
+ avail = conn->inBuf.size - conn->inBuf.insert;
+ /*
+ * For SVR4 with a unix-domain connection, ETEST() after selecting
+ * readable means the server has died. To do this here, we look for
+ * two consecutive reads returning ETEST().
+ */
+ ESET (0);
+ bytes_read =_FontTransRead(conn->trans_conn,
+ conn->inBuf.buf + conn->inBuf.insert,
+ avail);
+ if (bytes_read > 0) {
+ conn->inBuf.insert += bytes_read;
+ waited = FALSE;
+ }
+ else
+ {
+ if (bytes_read == 0 || ETEST ())
+ {
+ if (!waited)
+ {
+ waited = TRUE;
+ if (_fs_wait_for_readable (conn, 0) == FSIO_BLOCK)
+ return FSIO_BLOCK;
+ continue;
+ }
+ }
+ _fs_connection_died (conn);
+ return FSIO_ERROR;
+ }
+ }
+ return FSIO_READY;
+}
+
+/*
+ * Make space and return whether data have already arrived
+ */
+
+int
+_fs_start_read (FSFpePtr conn, long size, char **buf)
+{
+ int ret;
+
+ conn->inNeed = size;
+ if (fs_inqueued(conn) < size)
+ {
+ if (_fs_resize (&conn->inBuf, size) != FSIO_READY)
+ {
+ _fs_connection_died (conn);
+ return FSIO_ERROR;
+ }
+ ret = _fs_fill (conn);
+ if (ret == FSIO_ERROR)
+ return ret;
+ if (ret == FSIO_BLOCK || fs_inqueued(conn) < size)
+ return FSIO_BLOCK;
+ }
+ if (buf)
+ *buf = conn->inBuf.buf + conn->inBuf.remove;
+ return FSIO_READY;
+}
+
+void
+_fs_done_read (FSFpePtr conn, long size)
+{
+ if (conn->inBuf.insert - conn->inBuf.remove < size)
+ {
+#ifdef DEBUG
+ fprintf (stderr, "_fs_done_read skipping to many bytes\n");
+#endif
+ return;
+ }
+ conn->inBuf.remove += size;
+ conn->inNeed -= size;
+ _fs_downsize (&conn->inBuf, FS_BUF_MAX);
+}
+
+long
+_fs_pad_length (long len)
+{
+ return len + padlength[len&3];
+}
+
+int
+_fs_flush (FSFpePtr conn)
+{
+ long bytes_written;
+ long remain;
+
+ /* XXX - hack. The right fix is to remember that the font server
+ has gone away when we first discovered it. */
+ if (conn->fs_fd < 0)
+ return FSIO_ERROR;
+
+ while ((remain = conn->outBuf.insert - conn->outBuf.remove) > 0)
+ {
+ bytes_written = _FontTransWrite(conn->trans_conn,
+ conn->outBuf.buf + conn->outBuf.remove,
+ (int) remain);
+ if (bytes_written > 0)
+ {
+ conn->outBuf.remove += bytes_written;
+ }
+ else
+ {
+ if (bytes_written == 0 || ETEST ())
+ {
+ conn->brokenWriteTime = GetTimeInMillis () + FS_FLUSH_POLL;
+ _fs_mark_block (conn, FS_BROKEN_WRITE);
+ break;
+ }
+ if (!ECHECK (EINTR))
+ {
+ _fs_connection_died (conn);
+ return FSIO_ERROR;
+ }
+ }
+ }
+ if (conn->outBuf.remove == conn->outBuf.insert)
+ {
+ _fs_unmark_block (conn, FS_BROKEN_WRITE|FS_PENDING_WRITE);
+ if (conn->outBuf.size > FS_BUF_INC)
+ conn->outBuf.buf = xrealloc (conn->outBuf.buf, FS_BUF_INC);
+ conn->outBuf.remove = conn->outBuf.insert = 0;
+ }
+ return FSIO_READY;
+}
+
+static int
+_fs_resize (FSBufPtr buf, long size)
+{
+ char *new;
+ long new_size;
+
+ if (buf->remove)
+ {
+ if (buf->remove != buf->insert)
+ {
+ memmove (buf->buf,
+ buf->buf + buf->remove,
+ buf->insert - buf->remove);
+ }
+ buf->insert -= buf->remove;
+ buf->remove = 0;
+ }
+ if (buf->size - buf->remove < size)
+ {
+ new_size = ((buf->remove + size + FS_BUF_INC) / FS_BUF_INC) * FS_BUF_INC;
+ new = xrealloc (buf->buf, new_size);
+ if (!new)
+ return FSIO_ERROR;
+ buf->buf = new;
+ buf->size = new_size;
+ }
+ return FSIO_READY;
+}
+
+static void
+_fs_downsize (FSBufPtr buf, long size)
+{
+ if (buf->insert == buf->remove)
+ {
+ buf->insert = buf->remove = 0;
+ if (buf->size > size)
+ {
+ buf->buf = xrealloc (buf->buf, size);
+ buf->size = size;
+ }
+ }
+}
+
+void
+_fs_io_reinit (FSFpePtr conn)
+{
+ conn->outBuf.insert = conn->outBuf.remove = 0;
+ _fs_downsize (&conn->outBuf, FS_BUF_INC);
+ conn->inBuf.insert = conn->inBuf.remove = 0;
+ _fs_downsize (&conn->inBuf, FS_BUF_MAX);
+}
+
+Bool
+_fs_io_init (FSFpePtr conn)
+{
+ conn->outBuf.insert = conn->outBuf.remove = 0;
+ conn->outBuf.buf = xalloc (FS_BUF_INC);
+ if (!conn->outBuf.buf)
+ return FALSE;
+ conn->outBuf.size = FS_BUF_INC;
+
+ conn->inBuf.insert = conn->inBuf.remove = 0;
+ conn->inBuf.buf = xalloc (FS_BUF_INC);
+ if (!conn->inBuf.buf)
+ {
+ xfree (conn->outBuf.buf);
+ conn->outBuf.buf = 0;
+ return FALSE;
+ }
+ conn->inBuf.size = FS_BUF_INC;
+
+ return TRUE;
+}
+
+void
+_fs_io_fini (FSFpePtr conn)
+{
+ if (conn->outBuf.buf)
+ xfree (conn->outBuf.buf);
+ if (conn->inBuf.buf)
+ xfree (conn->inBuf.buf);
+}
+
+static int
+_fs_do_write(FSFpePtr conn, char *data, long len, long size)
+{
+ if (size == 0) {
+#ifdef DEBUG
+ fprintf(stderr, "tried to write 0 bytes \n");
+#endif
+ return FSIO_READY;
+ }
+
+ if (conn->fs_fd == -1)
+ return FSIO_ERROR;
+
+ while (conn->outBuf.insert + size > conn->outBuf.size)
+ {
+ if (_fs_flush (conn) < 0)
+ return FSIO_ERROR;
+ if (_fs_resize (&conn->outBuf, size) < 0)
+ {
+ _fs_connection_died (conn);
+ return FSIO_ERROR;
+ }
+ }
+ memcpy (conn->outBuf.buf + conn->outBuf.insert, data, len);
+ conn->outBuf.insert += size;
+ _fs_mark_block (conn, FS_PENDING_WRITE);
+ return FSIO_READY;
+}
+
+/*
+ * Write the indicated bytes
+ */
+int
+_fs_write (FSFpePtr conn, char *data, long len)
+{
+ return _fs_do_write (conn, data, len, len);
+}
+
+/*
+ * Write the indicated bytes adding any appropriate pad
+ */
+int
+_fs_write_pad(FSFpePtr conn, char *data, long len)
+{
+ return _fs_do_write (conn, data, len, len + padlength[len & 3]);
+}
+
+int
+_fs_wait_for_readable(FSFpePtr conn, int ms)
+{
+ fd_set r_mask;
+ fd_set e_mask;
+ int result;
+ struct timeval tv;
+
+ for (;;) {
+ if (conn->fs_fd < 0)
+ return FSIO_ERROR;
+ FD_ZERO(&r_mask);
+ FD_ZERO(&e_mask);
+ tv.tv_sec = ms / 1000;
+ tv.tv_usec = (ms % 1000) * 1000;
+ FD_SET(conn->fs_fd, &r_mask);
+ FD_SET(conn->fs_fd, &e_mask);
+ result = Select(conn->fs_fd + 1, &r_mask, NULL, &e_mask, &tv);
+ if (result < 0)
+ {
+ if (ECHECK(EINTR) || ECHECK(EAGAIN))
+ continue;
+ else
+ return FSIO_ERROR;
+ }
+ if (result == 0)
+ return FSIO_BLOCK;
+ if (FD_ISSET(conn->fs_fd, &r_mask))
+ return FSIO_READY;
+ return FSIO_ERROR;
+ }
+}
diff --git a/libXfont/src/fc/fsio.h b/libXfont/src/fc/fsio.h
new file mode 100644
index 000000000..1454b44bc
--- /dev/null
+++ b/libXfont/src/fc/fsio.h
@@ -0,0 +1,180 @@
+/* $Xorg: fsio.h,v 1.3 2000/08/17 19:46:36 cpqbld Exp $ */
+/*
+ * Copyright 1990 Network Computing Devices
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of Network Computing Devices not be
+ * used in advertising or publicity pertaining to distribution of the
+ * software without specific, written prior permission. Network Computing
+ * Devices makes no representations about the suitability of this software
+ * for any purpose. It is provided "as is" without express or implied
+ * warranty.
+ *
+ * NETWORK COMPUTING DEVICES DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
+ * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS,
+ * IN NO EVENT SHALL NETWORK COMPUTING DEVICES BE LIABLE FOR ANY SPECIAL,
+ * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+ * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+ * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE
+ * OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Author: Dave Lemke, Network Computing Devices, Inc
+ */
+/* $XFree86: xc/lib/font/fc/fsio.h,v 1.5 1999/12/30 02:39:06 robin Exp $ */
+
+#ifndef _FSIO_H_
+#define _FSIO_H_
+
+#undef DEBUG
+#define REQUEST_LOG_SIZE 100
+
+typedef struct _fs_fpe_alternate {
+ char *name;
+ Bool subset;
+} FSFpeAltRec, *FSFpeAltPtr;
+
+
+/* Per client access contexts */
+typedef struct _fs_client_data {
+ pointer client;
+ struct _fs_client_data *next;
+ XID acid;
+ int auth_generation;
+} FSClientRec, *FSClientPtr;
+
+#define FS_RECONNECT_POLL 1000
+#define FS_RECONNECT_WAIT 5000
+#define FS_GIVEUP_WAIT 20000
+#define FS_REQUEST_TIMEOUT 20000
+#define FS_OPEN_TIMEOUT 30000
+#define FS_REOPEN_TIMEOUT 10000
+#define FS_FLUSH_POLL 1000
+
+typedef struct _fs_buf {
+ char *buf; /* data */
+ long size; /* sizeof data */
+ long insert; /* where to insert new data */
+ long remove; /* where to remove old data */
+} FSBufRec, *FSBufPtr;
+
+#define FS_BUF_INC 1024
+#define FS_BUF_MAX 32768
+
+#define FS_PENDING_WRITE 0x01 /* some write data is queued */
+#define FS_BROKEN_WRITE 0x02 /* writes are broken */
+#define FS_BROKEN_CONNECTION 0x04 /* connection is broken */
+#define FS_PENDING_REPLY 0x08 /* waiting for a reply */
+#define FS_GIVE_UP 0x10 /* font server declared useless */
+#define FS_COMPLETE_REPLY 0x20 /* complete reply ready */
+#define FS_RECONNECTING 0x40
+
+#define FS_CONN_UNCONNECTED 0
+#define FS_CONN_CONNECTING 1
+#define FS_CONN_CONNECTED 2
+#define FS_CONN_SENT_PREFIX 3
+#define FS_CONN_RECV_INIT 4
+#define FS_CONN_SENT_CAT 5
+#define FS_CONN_RUNNING 6
+
+/* FS specific font FontPathElement data */
+typedef struct _fs_fpe_data {
+ FSFpePtr next; /* list of all active fs fpes */
+ int fs_fd; /* < 0 when not running */
+ int fs_conn_state; /* connection state */
+ int current_seq;
+ char *servername;
+ Bool has_catalogues;
+
+ int generation;
+ int numAlts;
+ int alternate; /* which alternate is in use +1 */
+ int fsMajorVersion; /* font server major version number */
+ FSFpeAltPtr alts;
+
+ FSClientPtr clients;
+ XID curacid;
+#ifdef DEBUG
+ int reqindex;
+ struct {
+ int opcode;
+ int sequence;
+ } reqbuffer[REQUEST_LOG_SIZE];
+#endif
+ FSBufRec outBuf; /* request queue */
+ FSBufRec inBuf; /* reply queue */
+ long inNeed; /* amount needed for reply */
+
+ CARD32 blockState;
+ CARD32 blockedReplyTime; /* time to abort blocked read */
+ CARD32 brokenWriteTime; /* time to retry broken write */
+ CARD32 blockedConnectTime; /* time to abort blocked connect */
+ CARD32 brokenConnectionTime; /* time to retry broken connection */
+
+ FSBlockDataPtr blockedRequests;
+
+ struct _XtransConnInfo *trans_conn; /* transport connection object */
+} FSFpeRec;
+
+#define fs_outspace(conn) ((conn)->outBuf.size - (conn)->outBuf.insert)
+#define fs_outqueued(conn) ((conn)->outBuf.insert - (conn)->outBuf.remove)
+#define fs_inqueued(conn) ((conn)->inBuf.insert - (conn)->inBuf.remove)
+#define fs_needsflush(conn) (fs_outqueued(conn) != 0)
+#define fs_needsfill(conn) (fs_inqueued(conn) < (conn)->inNeed)
+#define fs_needsconnect(conn) ((conn)->fs_fd < 0)
+#define fs_data_read(conn) ((conn)->inBuf.insert - (conn)->inBuf.remove)
+
+#define FSIO_READY 1
+#define FSIO_BLOCK 0
+#define FSIO_ERROR -1
+
+extern Bool _fs_reopen_server ( FSFpePtr conn );
+extern int _fs_write ( FSFpePtr conn, char *data, long size );
+extern int _fs_write_pad ( FSFpePtr conn, char *data, long len );
+extern int _fs_wait_for_readable ( FSFpePtr conn, int ms );
+extern long _fs_pad_length (long len);
+
+extern void _fs_connection_died ( FSFpePtr conn );
+
+extern int _fs_flush (FSFpePtr conn);
+extern void _fs_mark_block (FSFpePtr conn, CARD32 mask);
+extern void _fs_unmark_block (FSFpePtr conn, CARD32 mask);
+extern void _fs_done_read (FSFpePtr conn, long size);
+extern void _fs_io_reinit (FSFpePtr conn);
+extern int _fs_start_read (FSFpePtr conn, long size, char **buf);
+extern Bool _fs_io_init (FSFpePtr conn);
+extern void _fs_io_fini (FSFpePtr conn);
+extern int _fs_poll_connect (XtransConnInfo trans_conn, int timeout);
+extern XtransConnInfo _fs_connect(char *servername, int *ret);
+
+/* check for both EAGAIN and EWOULDBLOCK, because some supposedly POSIX
+ * systems are broken and return EWOULDBLOCK when they should return EAGAIN
+ */
+#ifdef WIN32
+#define ETEST() (WSAGetLastError() == WSAEWOULDBLOCK)
+#else
+#if defined(EAGAIN) && defined(EWOULDBLOCK)
+#define ETEST() (errno == EAGAIN || errno == EWOULDBLOCK)
+#else
+#ifdef EAGAIN
+#define ETEST() (errno == EAGAIN)
+#else
+#define ETEST() (errno == EWOULDBLOCK)
+#endif
+#endif
+#endif
+#ifdef WIN32
+#define ECHECK(err) (WSAGetLastError() == err)
+#define ESET(val) WSASetLastError(val)
+#else
+#ifdef ISC
+#define ECHECK(err) ((errno == err) || ETEST())
+#else
+#define ECHECK(err) (errno == err)
+#endif
+#define ESET(val) errno = val
+#endif
+
+#endif /* _FSIO_H_ */
diff --git a/libXfont/src/fc/fslibos.h b/libXfont/src/fc/fslibos.h
new file mode 100644
index 000000000..acc1f16dc
--- /dev/null
+++ b/libXfont/src/fc/fslibos.h
@@ -0,0 +1,220 @@
+/* $Xorg: fslibos.h,v 1.4 2001/02/09 02:04:03 xorgcvs Exp $ */
+/*
+ * Copyright 1990 Network Computing Devices;
+ * Portions Copyright 1987 by Digital Equipment Corporation
+ */
+
+/*
+
+Copyright 1987, 1994, 1998 The Open Group
+
+Permission to use, copy, modify, distribute, and sell this software and its
+documentation for any purpose is hereby granted without fee, provided that
+the above copyright notice appear in all copies and that both that
+copyright notice and this permission notice appear in supporting
+documentation.
+
+The above copyright notice and this permission notice shall be included
+in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+IN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR
+OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of The Open Group shall
+not be used in advertising or otherwise to promote the sale, use or
+other dealings in this Software without prior written authorization
+from The Open Group.
+
+*/
+/* $XFree86: xc/lib/font/fc/fslibos.h,v 3.8 2003/08/29 18:01:14 herrb Exp $ */
+
+/*
+ * FSlib networking & os include file
+ */
+
+#include <X11/Xtrans/Xtrans.h>
+
+#ifndef WIN32
+
+/*
+ * makedepend screws up on #undef OPEN_MAX, so we define a new symbol
+ */
+
+#ifndef FONT_OPEN_MAX
+
+#ifndef X_NOT_POSIX
+# ifdef _POSIX_SOURCE
+# include <limits.h>
+# else
+# define _POSIX_SOURCE
+# include <limits.h>
+# undef _POSIX_SOURCE
+# endif
+#endif
+#ifndef SIZE_MAX
+# ifdef ULONG_MAX
+# define SIZE_MAX ULONG_MAX
+# else
+# define SIZE_MAX UINT_MAX
+# endif
+#endif
+#ifndef OPEN_MAX
+#if defined(SVR4) || defined(__UNIXOS2__)
+#define OPEN_MAX 256
+#else
+#include <sys/param.h>
+#ifndef OPEN_MAX
+#ifdef __OSF1__
+#define OPEN_MAX 256
+#else
+#ifdef NOFILE
+#define OPEN_MAX NOFILE
+#else
+#define OPEN_MAX NOFILES_MAX
+#endif
+#endif
+#endif
+#endif
+#endif
+
+#if OPEN_MAX > 256
+#define FONT_OPEN_MAX 256
+#else
+#define FONT_OPEN_MAX OPEN_MAX
+#endif
+
+#endif /* FONT_OPEN_MAX */
+
+#ifdef WORD64
+#define NMSKBITS 64
+#else
+#define NMSKBITS 32
+#endif
+
+#define MSKCNT ((FONT_OPEN_MAX + NMSKBITS - 1) / NMSKBITS)
+
+typedef unsigned long FdSet[MSKCNT];
+typedef FdSet FdSetPtr;
+
+#if (MSKCNT==1)
+#define BITMASK(i) (1 << (i))
+#define MASKIDX(i) 0
+#endif
+
+#if (MSKCNT>1)
+#define BITMASK(i) (1 << ((i) & (NMSKBITS - 1)))
+#define MASKIDX(i) ((i) / NMSKBITS)
+#endif
+
+#define MASKWORD(buf, i) buf[MASKIDX(i)]
+#define BITSET(buf, i) MASKWORD(buf, i) |= BITMASK(i)
+#define BITCLEAR(buf, i) MASKWORD(buf, i) &= ~BITMASK(i)
+#define GETBIT(buf, i) (MASKWORD(buf, i) & BITMASK(i))
+
+#if (MSKCNT==1)
+#define COPYBITS(src, dst) dst[0] = src[0]
+#define CLEARBITS(buf) buf[0] = 0
+#define MASKANDSETBITS(dst, b1, b2) dst[0] = (b1[0] & b2[0])
+#define ORBITS(dst, b1, b2) dst[0] = (b1[0] | b2[0])
+#define UNSETBITS(dst, b1) (dst[0] &= ~b1[0])
+#define ANYSET(src) (src[0])
+#endif
+
+#if (MSKCNT==2)
+#define COPYBITS(src, dst) { dst[0] = src[0]; dst[1] = src[1]; }
+#define CLEARBITS(buf) { buf[0] = 0; buf[1] = 0; }
+#define MASKANDSETBITS(dst, b1, b2) {\
+ dst[0] = (b1[0] & b2[0]);\
+ dst[1] = (b1[1] & b2[1]); }
+#define ORBITS(dst, b1, b2) {\
+ dst[0] = (b1[0] | b2[0]);\
+ dst[1] = (b1[1] | b2[1]); }
+#define UNSETBITS(dst, b1) {\
+ dst[0] &= ~b1[0]; \
+ dst[1] &= ~b1[1]; }
+#define ANYSET(src) (src[0] || src[1])
+#endif
+
+#if (MSKCNT==3)
+#define COPYBITS(src, dst) { dst[0] = src[0]; dst[1] = src[1]; \
+ dst[2] = src[2]; }
+#define CLEARBITS(buf) { buf[0] = 0; buf[1] = 0; buf[2] = 0; }
+#define MASKANDSETBITS(dst, b1, b2) {\
+ dst[0] = (b1[0] & b2[0]);\
+ dst[1] = (b1[1] & b2[1]);\
+ dst[2] = (b1[2] & b2[2]); }
+#define ORBITS(dst, b1, b2) {\
+ dst[0] = (b1[0] | b2[0]);\
+ dst[1] = (b1[1] | b2[1]);\
+ dst[2] = (b1[2] | b2[2]); }
+#define UNSETBITS(dst, b1) {\
+ dst[0] &= ~b1[0]; \
+ dst[1] &= ~b1[1]; \
+ dst[2] &= ~b1[2]; }
+#define ANYSET(src) (src[0] || src[1] || src[2])
+#endif
+
+#if (MSKCNT==4)
+#define COPYBITS(src, dst) dst[0] = src[0]; dst[1] = src[1]; \
+ dst[2] = src[2]; dst[3] = src[3]
+#define CLEARBITS(buf) buf[0] = 0; buf[1] = 0; buf[2] = 0; buf[3] = 0
+#define MASKANDSETBITS(dst, b1, b2) \
+ dst[0] = (b1[0] & b2[0]);\
+ dst[1] = (b1[1] & b2[1]);\
+ dst[2] = (b1[2] & b2[2]);\
+ dst[3] = (b1[3] & b2[3])
+#define ORBITS(dst, b1, b2) \
+ dst[0] = (b1[0] | b2[0]);\
+ dst[1] = (b1[1] | b2[1]);\
+ dst[2] = (b1[2] | b2[2]);\
+ dst[3] = (b1[3] | b2[3])
+#define UNSETBITS(dst, b1) \
+ dst[0] &= ~b1[0]; \
+ dst[1] &= ~b1[1]; \
+ dst[2] &= ~b1[2]; \
+ dst[3] &= ~b1[3]
+#define ANYSET(src) (src[0] || src[1] || src[2] || src[3])
+#endif
+
+#if (MSKCNT>4)
+#define COPYBITS(src, dst) memmove((caddr_t) dst, (caddr_t) src,\
+ MSKCNT*sizeof(long))
+#define CLEARBITS(buf) bzero((caddr_t) buf, MSKCNT*sizeof(long))
+#define MASKANDSETBITS(dst, b1, b2) \
+ { int cri; \
+ for (cri=MSKCNT; --cri>=0; ) \
+ dst[cri] = (b1[cri] & b2[cri]); }
+#define ORBITS(dst, b1, b2) \
+ { int cri; \
+ for (cri=MSKCNT; --cri>=0; ) \
+ dst[cri] = (b1[cri] | b2[cri]); }
+#define UNSETBITS(dst, b1) \
+ { int cri; \
+ for (cri=MSKCNT; --cri>=0; ) \
+ dst[cri] &= ~b1[cri]; }
+#if (MSKCNT==8)
+#define ANYSET(src) (src[0] || src[1] || src[2] || src[3] || \
+ src[4] || src[5] || src[6] || src[7])
+#endif
+#endif
+
+#else /* not WIN32 */
+
+#include <X11/Xwinsock.h>
+#include <X11/Xw32defs.h>
+
+typedef fd_set FdSet;
+typedef FdSet *FdSetPtr;
+
+#define CLEARBITS(set) FD_ZERO(&set)
+#define BITSET(set,s) FD_SET(s,&set)
+#define BITCLEAR(set,s) FD_CLR(s,&set)
+#define GETBIT(set,s) FD_ISSET(s,&set)
+#define ANYSET(set) set->fd_count
+
+#endif
diff --git a/libXfont/src/fc/fstrans.c b/libXfont/src/fc/fstrans.c
new file mode 100644
index 000000000..c334c2504
--- /dev/null
+++ b/libXfont/src/fc/fstrans.c
@@ -0,0 +1,28 @@
+/*
+ * Copyright © 2004 Keith Packard
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of Keith Packard not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission. Keith Packard makes no
+ * representations about the suitability of this software for any purpose. It
+ * is provided "as is" without express or implied warranty.
+ *
+ * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#define FONT_t
+#define TRANS_CLIENT
+#include <X11/Xtrans/transport.c>
diff --git a/libXfont/src/fontfile/Makefile.am b/libXfont/src/fontfile/Makefile.am
new file mode 100644
index 000000000..45d1dbaa4
--- /dev/null
+++ b/libXfont/src/fontfile/Makefile.am
@@ -0,0 +1,36 @@
+FONTENCDIR=@ENCODINGSDIR@
+FONTENCDEFS = -DFONT_ENCODINGS_DIRECTORY=\"$(FONTENCDIR)/encodings.dir\"
+
+INCLUDES = \
+ -I${top_srcdir}/include \
+ $(FONTENCDEFS)
+
+AM_CFLAGS = $(XFONT_CFLAGS) $(OS_CFLAGS) $(CWARNFLAGS)
+
+noinst_LTLIBRARIES = libfontfile.la
+
+libfontfile_la_LIBADD = \
+ $(Z_LIBS)
+
+libfontfile_la_SOURCES = \
+ bitsource.c \
+ bufio.c \
+ decompress.c \
+ defaults.c \
+ dirfile.c \
+ ffcheck.c \
+ fileio.c \
+ filewr.c \
+ fontdir.c \
+ fontencc.c \
+ fontfile.c \
+ fontscale.c \
+ gunzip.c \
+ printerfont.c \
+ register.c \
+ renderers.c \
+ catalogue.c
+
+if X_BZIP2_FONT_COMPRESSION
+libfontfile_la_SOURCES += bunzip2.c
+endif
diff --git a/libXfont/src/fontfile/Makefile.in b/libXfont/src/fontfile/Makefile.in
new file mode 100644
index 000000000..dca443eaa
--- /dev/null
+++ b/libXfont/src/fontfile/Makefile.in
@@ -0,0 +1,487 @@
+# Makefile.in generated by automake 1.10 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
+# 2003, 2004, 2005, 2006 Free Software Foundation, Inc.
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+@SET_MAKE@
+
+VPATH = @srcdir@
+pkgdatadir = $(datadir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+install_sh_DATA = $(install_sh) -c -m 644
+install_sh_PROGRAM = $(install_sh) -c
+install_sh_SCRIPT = $(install_sh) -c
+INSTALL_HEADER = $(INSTALL_DATA)
+transform = $(program_transform_name)
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+build_triplet = @build@
+host_triplet = @host@
+@X_BZIP2_FONT_COMPRESSION_TRUE@am__append_1 = bunzip2.c
+subdir = src/fontfile
+DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/configure.ac
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+ $(ACLOCAL_M4)
+mkinstalldirs = $(install_sh) -d
+CONFIG_HEADER = $(top_builddir)/config.h \
+ $(top_builddir)/include/X11/fonts/fontconf.h
+CONFIG_CLEAN_FILES =
+LTLIBRARIES = $(noinst_LTLIBRARIES)
+am__DEPENDENCIES_1 =
+libfontfile_la_DEPENDENCIES = $(am__DEPENDENCIES_1)
+am__libfontfile_la_SOURCES_DIST = bitsource.c bufio.c decompress.c \
+ defaults.c dirfile.c ffcheck.c fileio.c filewr.c fontdir.c \
+ fontencc.c fontfile.c fontscale.c gunzip.c printerfont.c \
+ register.c renderers.c catalogue.c bunzip2.c
+@X_BZIP2_FONT_COMPRESSION_TRUE@am__objects_1 = bunzip2.lo
+am_libfontfile_la_OBJECTS = bitsource.lo bufio.lo decompress.lo \
+ defaults.lo dirfile.lo ffcheck.lo fileio.lo filewr.lo \
+ fontdir.lo fontencc.lo fontfile.lo fontscale.lo gunzip.lo \
+ printerfont.lo register.lo renderers.lo catalogue.lo \
+ $(am__objects_1)
+libfontfile_la_OBJECTS = $(am_libfontfile_la_OBJECTS)
+DEFAULT_INCLUDES = -I. -I$(top_builddir) -I$(top_builddir)/include/X11/fonts@am__isrc@
+depcomp = $(SHELL) $(top_srcdir)/depcomp
+am__depfiles_maybe = depfiles
+COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
+ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+LTCOMPILE = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
+ --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \
+ $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+CCLD = $(CC)
+LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
+ --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \
+ $(LDFLAGS) -o $@
+SOURCES = $(libfontfile_la_SOURCES)
+DIST_SOURCES = $(am__libfontfile_la_SOURCES_DIST)
+ETAGS = etags
+CTAGS = ctags
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+ACLOCAL = @ACLOCAL@
+AMTAR = @AMTAR@
+AR = @AR@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+CC = @CC@
+CCDEPMODE = @CCDEPMODE@
+CFLAGS = @CFLAGS@
+CHANGELOG_CMD = @CHANGELOG_CMD@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CWARNFLAGS = @CWARNFLAGS@
+CXX = @CXX@
+CXXCPP = @CXXCPP@
+CXXDEPMODE = @CXXDEPMODE@
+CXXFLAGS = @CXXFLAGS@
+CYGPATH_W = @CYGPATH_W@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+ECHO = @ECHO@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+EGREP = @EGREP@
+ENCODINGSDIR = @ENCODINGSDIR@
+EXEEXT = @EXEEXT@
+F77 = @F77@
+FFLAGS = @FFLAGS@
+FREETYPE_CFLAGS = @FREETYPE_CFLAGS@
+FREETYPE_LIBS = @FREETYPE_LIBS@
+FREETYPE_REQUIRES = @FREETYPE_REQUIRES@
+GREP = @GREP@
+INSTALL = @INSTALL@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+LDFLAGS = @LDFLAGS@
+LIBOBJS = @LIBOBJS@
+LIBS = @LIBS@
+LIBTOOL = @LIBTOOL@
+LN_S = @LN_S@
+LTLIBOBJS = @LTLIBOBJS@
+MAKEINFO = @MAKEINFO@
+MATH_LIBS = @MATH_LIBS@
+MKDIR_P = @MKDIR_P@
+OBJEXT = @OBJEXT@
+OS_CFLAGS = @OS_CFLAGS@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+PKG_CONFIG = @PKG_CONFIG@
+RANLIB = @RANLIB@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+STRIP = @STRIP@
+VERSION = @VERSION@
+XFONT_CFLAGS = @XFONT_CFLAGS@
+XFONT_LIBS = @XFONT_LIBS@
+X_GZIP_FONT_COMPRESSION = @X_GZIP_FONT_COMPRESSION@
+Z_LIBS = @Z_LIBS@
+abs_builddir = @abs_builddir@
+abs_srcdir = @abs_srcdir@
+abs_top_builddir = @abs_top_builddir@
+abs_top_srcdir = @abs_top_srcdir@
+ac_ct_CC = @ac_ct_CC@
+ac_ct_CXX = @ac_ct_CXX@
+ac_ct_F77 = @ac_ct_F77@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+am__tar = @am__tar@
+am__untar = @am__untar@
+bindir = @bindir@
+build = @build@
+build_alias = @build_alias@
+build_cpu = @build_cpu@
+build_os = @build_os@
+build_vendor = @build_vendor@
+builddir = @builddir@
+datadir = @datadir@
+datarootdir = @datarootdir@
+distcleancheck_listfiles = @distcleancheck_listfiles@
+docdir = @docdir@
+dvidir = @dvidir@
+exec_prefix = @exec_prefix@
+ft_config = @ft_config@
+host = @host@
+host_alias = @host_alias@
+host_cpu = @host_cpu@
+host_os = @host_os@
+host_vendor = @host_vendor@
+htmldir = @htmldir@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+libdir = @libdir@
+libexecdir = @libexecdir@
+localedir = @localedir@
+localstatedir = @localstatedir@
+mandir = @mandir@
+mkdir_p = @mkdir_p@
+oldincludedir = @oldincludedir@
+pdfdir = @pdfdir@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+psdir = @psdir@
+sbindir = @sbindir@
+sharedstatedir = @sharedstatedir@
+srcdir = @srcdir@
+sysconfdir = @sysconfdir@
+target_alias = @target_alias@
+top_builddir = @top_builddir@
+top_srcdir = @top_srcdir@
+FONTENCDIR = @ENCODINGSDIR@
+FONTENCDEFS = -DFONT_ENCODINGS_DIRECTORY=\"$(FONTENCDIR)/encodings.dir\"
+INCLUDES = \
+ -I${top_srcdir}/include \
+ $(FONTENCDEFS)
+
+AM_CFLAGS = $(XFONT_CFLAGS) $(OS_CFLAGS) $(CWARNFLAGS)
+noinst_LTLIBRARIES = libfontfile.la
+libfontfile_la_LIBADD = \
+ $(Z_LIBS)
+
+libfontfile_la_SOURCES = bitsource.c bufio.c decompress.c defaults.c \
+ dirfile.c ffcheck.c fileio.c filewr.c fontdir.c fontencc.c \
+ fontfile.c fontscale.c gunzip.c printerfont.c register.c \
+ renderers.c catalogue.c $(am__append_1)
+all: all-am
+
+.SUFFIXES:
+.SUFFIXES: .c .lo .o .obj
+$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps)
+ @for dep in $?; do \
+ case '$(am__configure_deps)' in \
+ *$$dep*) \
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh \
+ && exit 0; \
+ exit 1;; \
+ esac; \
+ done; \
+ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign src/fontfile/Makefile'; \
+ cd $(top_srcdir) && \
+ $(AUTOMAKE) --foreign src/fontfile/Makefile
+.PRECIOUS: Makefile
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+ @case '$?' in \
+ *config.status*) \
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
+ *) \
+ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
+ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
+ esac;
+
+$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+
+$(top_srcdir)/configure: $(am__configure_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(ACLOCAL_M4): $(am__aclocal_m4_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+
+clean-noinstLTLIBRARIES:
+ -test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES)
+ @list='$(noinst_LTLIBRARIES)'; for p in $$list; do \
+ dir="`echo $$p | sed -e 's|/[^/]*$$||'`"; \
+ test "$$dir" != "$$p" || dir=.; \
+ echo "rm -f \"$${dir}/so_locations\""; \
+ rm -f "$${dir}/so_locations"; \
+ done
+libfontfile.la: $(libfontfile_la_OBJECTS) $(libfontfile_la_DEPENDENCIES)
+ $(LINK) $(libfontfile_la_OBJECTS) $(libfontfile_la_LIBADD) $(LIBS)
+
+mostlyclean-compile:
+ -rm -f *.$(OBJEXT)
+
+distclean-compile:
+ -rm -f *.tab.c
+
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/bitsource.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/bufio.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/bunzip2.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/catalogue.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/decompress.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/defaults.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dirfile.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ffcheck.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fileio.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/filewr.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fontdir.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fontencc.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fontfile.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fontscale.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gunzip.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/printerfont.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/register.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/renderers.Plo@am__quote@
+
+.c.o:
+@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
+@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(COMPILE) -c $<
+
+.c.obj:
+@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'`
+@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(COMPILE) -c `$(CYGPATH_W) '$<'`
+
+.c.lo:
+@am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
+@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(LTCOMPILE) -c -o $@ $<
+
+mostlyclean-libtool:
+ -rm -f *.lo
+
+clean-libtool:
+ -rm -rf .libs _libs
+
+ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) ' { files[$$0] = 1; } \
+ END { for (i in files) print i; }'`; \
+ mkid -fID $$unique
+tags: TAGS
+
+TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
+ $(TAGS_FILES) $(LISP)
+ tags=; \
+ here=`pwd`; \
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) ' { files[$$0] = 1; } \
+ END { for (i in files) print i; }'`; \
+ if test -z "$(ETAGS_ARGS)$$tags$$unique"; then :; else \
+ test -n "$$unique" || unique=$$empty_fix; \
+ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+ $$tags $$unique; \
+ fi
+ctags: CTAGS
+CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
+ $(TAGS_FILES) $(LISP)
+ tags=; \
+ here=`pwd`; \
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) ' { files[$$0] = 1; } \
+ END { for (i in files) print i; }'`; \
+ test -z "$(CTAGS_ARGS)$$tags$$unique" \
+ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
+ $$tags $$unique
+
+GTAGS:
+ here=`$(am__cd) $(top_builddir) && pwd` \
+ && cd $(top_srcdir) \
+ && gtags -i $(GTAGS_ARGS) $$here
+
+distclean-tags:
+ -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
+
+distdir: $(DISTFILES)
+ @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ list='$(DISTFILES)'; \
+ dist_files=`for file in $$list; do echo $$file; done | \
+ sed -e "s|^$$srcdirstrip/||;t" \
+ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
+ case $$dist_files in \
+ */*) $(MKDIR_P) `echo "$$dist_files" | \
+ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
+ sort -u` ;; \
+ esac; \
+ for file in $$dist_files; do \
+ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
+ if test -d $$d/$$file; then \
+ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
+ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
+ cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \
+ fi; \
+ cp -pR $$d/$$file $(distdir)$$dir || exit 1; \
+ else \
+ test -f $(distdir)/$$file \
+ || cp -p $$d/$$file $(distdir)/$$file \
+ || exit 1; \
+ fi; \
+ done
+check-am: all-am
+check: check-am
+all-am: Makefile $(LTLIBRARIES)
+installdirs:
+install: install-am
+install-exec: install-exec-am
+install-data: install-data-am
+uninstall: uninstall-am
+
+install-am: all-am
+ @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-am
+install-strip:
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ `test -z '$(STRIP)' || \
+ echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
+mostlyclean-generic:
+
+clean-generic:
+
+distclean-generic:
+ -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
+
+maintainer-clean-generic:
+ @echo "This command is intended for maintainers to use"
+ @echo "it deletes files that may require special tools to rebuild."
+clean: clean-am
+
+clean-am: clean-generic clean-libtool clean-noinstLTLIBRARIES \
+ mostlyclean-am
+
+distclean: distclean-am
+ -rm -rf ./$(DEPDIR)
+ -rm -f Makefile
+distclean-am: clean-am distclean-compile distclean-generic \
+ distclean-tags
+
+dvi: dvi-am
+
+dvi-am:
+
+html: html-am
+
+info: info-am
+
+info-am:
+
+install-data-am:
+
+install-dvi: install-dvi-am
+
+install-exec-am:
+
+install-html: install-html-am
+
+install-info: install-info-am
+
+install-man:
+
+install-pdf: install-pdf-am
+
+install-ps: install-ps-am
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-am
+ -rm -rf ./$(DEPDIR)
+ -rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-am
+
+mostlyclean-am: mostlyclean-compile mostlyclean-generic \
+ mostlyclean-libtool
+
+pdf: pdf-am
+
+pdf-am:
+
+ps: ps-am
+
+ps-am:
+
+uninstall-am:
+
+.MAKE: install-am install-strip
+
+.PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \
+ clean-libtool clean-noinstLTLIBRARIES ctags distclean \
+ distclean-compile distclean-generic distclean-libtool \
+ distclean-tags distdir dvi dvi-am html html-am info info-am \
+ install install-am install-data install-data-am install-dvi \
+ install-dvi-am install-exec install-exec-am install-html \
+ install-html-am install-info install-info-am install-man \
+ install-pdf install-pdf-am install-ps install-ps-am \
+ install-strip installcheck installcheck-am installdirs \
+ maintainer-clean maintainer-clean-generic mostlyclean \
+ mostlyclean-compile mostlyclean-generic mostlyclean-libtool \
+ pdf pdf-am ps ps-am tags uninstall uninstall-am
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/libXfont/src/fontfile/bitsource.c b/libXfont/src/fontfile/bitsource.c
new file mode 100644
index 000000000..ae27de8fe
--- /dev/null
+++ b/libXfont/src/fontfile/bitsource.c
@@ -0,0 +1,174 @@
+/* $Xorg: bitsource.c,v 1.4 2001/02/09 02:04:03 xorgcvs Exp $ */
+
+/*
+
+Copyright 1991, 1998 The Open Group
+
+Permission to use, copy, modify, distribute, and sell this software and its
+documentation for any purpose is hereby granted without fee, provided that
+the above copyright notice appear in all copies and that both that
+copyright notice and this permission notice appear in supporting
+documentation.
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of The Open Group shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from The Open Group.
+
+*/
+/* $XFree86: xc/lib/font/fontfile/bitsource.c,v 1.3 2001/01/17 19:43:29 dawes Exp $ */
+
+/*
+ * Author: Keith Packard, MIT X Consortium
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include <X11/fonts/fntfilst.h>
+
+BitmapSourcesRec FontFileBitmapSources;
+
+Bool
+FontFileRegisterBitmapSource (FontPathElementPtr fpe)
+{
+ FontPathElementPtr *new;
+ int i;
+ int newsize;
+
+ for (i = 0; i < FontFileBitmapSources.count; i++)
+ if (FontFileBitmapSources.fpe[i] == fpe)
+ return TRUE;
+ if (FontFileBitmapSources.count == FontFileBitmapSources.size)
+ {
+ newsize = FontFileBitmapSources.size + 4;
+ new = (FontPathElementPtr *) xrealloc (FontFileBitmapSources.fpe, newsize * sizeof *new);
+ if (!new)
+ return FALSE;
+ FontFileBitmapSources.size = newsize;
+ FontFileBitmapSources.fpe = new;
+ }
+ FontFileBitmapSources.fpe[FontFileBitmapSources.count++] = fpe;
+ return TRUE;
+}
+
+void
+FontFileUnregisterBitmapSource (FontPathElementPtr fpe)
+{
+ int i;
+
+ for (i = 0; i < FontFileBitmapSources.count; i++)
+ if (FontFileBitmapSources.fpe[i] == fpe)
+ {
+ FontFileBitmapSources.count--;
+ if (FontFileBitmapSources.count == 0)
+ {
+ FontFileBitmapSources.size = 0;
+ xfree (FontFileBitmapSources.fpe);
+ FontFileBitmapSources.fpe = 0;
+ }
+ else
+ {
+ for (; i < FontFileBitmapSources.count; i++)
+ FontFileBitmapSources.fpe[i] = FontFileBitmapSources.fpe[i+1];
+ }
+ break;
+ }
+}
+
+/*
+ * Our set_path_hook: unregister all bitmap sources.
+ * This is necessary because already open fonts will keep their FPEs
+ * allocated, but they may not be on the new font path.
+ * The bitmap sources in the new path will be registered by the init_func.
+ */
+void
+FontFileEmptyBitmapSource(void)
+{
+ if (FontFileBitmapSources.count == 0)
+ return;
+
+ FontFileBitmapSources.count = 0;
+ FontFileBitmapSources.size = 0;
+ xfree (FontFileBitmapSources.fpe);
+ FontFileBitmapSources.fpe = 0;
+}
+
+int
+FontFileMatchBitmapSource (FontPathElementPtr fpe,
+ FontPtr *pFont,
+ int flags,
+ FontEntryPtr entry,
+ FontNamePtr zeroPat,
+ FontScalablePtr vals,
+ fsBitmapFormat format,
+ fsBitmapFormatMask fmask,
+ Bool noSpecificSize)
+{
+ int source;
+ FontEntryPtr zero;
+ FontBitmapEntryPtr bitmap;
+ int ret;
+ FontDirectoryPtr dir;
+ FontScaledPtr scaled;
+
+ /*
+ * Look through all the registered bitmap sources for
+ * the same zero name as ours; entries along that one
+ * can be scaled as desired.
+ */
+ ret = BadFontName;
+ for (source = 0; source < FontFileBitmapSources.count; source++)
+ {
+ if (FontFileBitmapSources.fpe[source] == fpe)
+ continue;
+ dir = (FontDirectoryPtr) FontFileBitmapSources.fpe[source]->private;
+ zero = FontFileFindNameInDir (&dir->scalable, zeroPat);
+ if (!zero)
+ continue;
+ scaled = FontFileFindScaledInstance (zero, vals, noSpecificSize);
+ if (scaled)
+ {
+ if (scaled->pFont)
+ {
+ *pFont = scaled->pFont;
+ (*pFont)->fpe = FontFileBitmapSources.fpe[source];
+ ret = Successful;
+ }
+ else if (scaled->bitmap)
+ {
+ entry = scaled->bitmap;
+ bitmap = &entry->u.bitmap;
+ if (bitmap->pFont)
+ {
+ *pFont = bitmap->pFont;
+ (*pFont)->fpe = FontFileBitmapSources.fpe[source];
+ ret = Successful;
+ }
+ else
+ {
+ ret = FontFileOpenBitmap (
+ FontFileBitmapSources.fpe[source],
+ pFont, flags, entry, format, fmask);
+ if (ret == Successful && *pFont)
+ (*pFont)->fpe = FontFileBitmapSources.fpe[source];
+ }
+ }
+ else /* "cannot" happen */
+ {
+ ret = BadFontName;
+ }
+ break;
+ }
+ }
+ return ret;
+}
diff --git a/libXfont/src/fontfile/bufio.c b/libXfont/src/fontfile/bufio.c
new file mode 100644
index 000000000..a5746e3bd
--- /dev/null
+++ b/libXfont/src/fontfile/bufio.c
@@ -0,0 +1,206 @@
+/* $Xorg: bufio.c,v 1.4 2001/02/09 02:04:03 xorgcvs Exp $ */
+
+/*
+
+Copyright 1991, 1998 The Open Group
+
+Permission to use, copy, modify, distribute, and sell this software and its
+documentation for any purpose is hereby granted without fee, provided that
+the above copyright notice appear in all copies and that both that
+copyright notice and this permission notice appear in supporting
+documentation.
+
+The above copyright notice and this permission notice shall be included
+in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+IN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR
+OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of The Open Group shall
+not be used in advertising or otherwise to promote the sale, use or
+other dealings in this Software without prior written authorization
+from The Open Group.
+
+*/
+/* $XFree86: xc/lib/font/fontfile/bufio.c,v 3.9 2001/12/14 19:56:50 dawes Exp $ */
+
+/*
+ * Author: Keith Packard, MIT X Consortium
+ */
+
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include <X11/Xos.h>
+#include <X11/fonts/fontmisc.h>
+#include <X11/fonts/bufio.h>
+#include <errno.h>
+
+BufFilePtr
+BufFileCreate (char *private,
+ int (*input)(BufFilePtr),
+ int (*output)(int, BufFilePtr),
+ int (*skip)(BufFilePtr, int),
+ int (*close)(BufFilePtr, int))
+{
+ BufFilePtr f;
+
+ f = (BufFilePtr) xalloc (sizeof *f);
+ if (!f)
+ return 0;
+ f->private = private;
+ f->bufp = f->buffer;
+ f->left = 0;
+ f->input = input;
+ f->output = output;
+ f->skip = skip;
+ f->eof = 0;
+ f->close = close;
+ return f;
+}
+
+#define FileDes(f) ((int)(long) (f)->private)
+
+static int
+BufFileRawFill (BufFilePtr f)
+{
+ int left;
+
+ left = read (FileDes(f), (char *)f->buffer, BUFFILESIZE);
+ if (left <= 0) {
+ f->left = 0;
+ return BUFFILEEOF;
+ }
+ f->left = left - 1;
+ f->bufp = f->buffer + 1;
+ return f->buffer[0];
+}
+
+static int
+BufFileRawSkip (BufFilePtr f, int count)
+{
+ int curoff;
+ int fileoff;
+ int todo;
+
+ curoff = f->bufp - f->buffer;
+ fileoff = curoff + f->left;
+ if (curoff + count <= fileoff) {
+ f->bufp += count;
+ f->left -= count;
+ } else {
+ todo = count - (fileoff - curoff);
+ if (lseek (FileDes(f), todo, 1) == -1) {
+ if (errno != ESPIPE)
+ return BUFFILEEOF;
+ while (todo) {
+ curoff = BUFFILESIZE;
+ if (curoff > todo)
+ curoff = todo;
+ fileoff = read (FileDes(f), (char *)f->buffer, curoff);
+ if (fileoff <= 0)
+ return BUFFILEEOF;
+ todo -= fileoff;
+ }
+ }
+ f->left = 0;
+ }
+ return count;
+}
+
+static int
+BufFileRawClose (BufFilePtr f, int doClose)
+{
+ if (doClose)
+ close (FileDes (f));
+ return 1;
+}
+
+BufFilePtr
+BufFileOpenRead (int fd)
+{
+#if defined(__UNIXOS2__) || defined (WIN32)
+ /* hv: I'd bet WIN32 has the same effect here */
+ setmode(fd,O_BINARY);
+#endif
+ return BufFileCreate ((char *)(long) fd, BufFileRawFill, 0, BufFileRawSkip, BufFileRawClose);
+}
+
+static int
+BufFileRawFlush (int c, BufFilePtr f)
+{
+ int cnt;
+
+ if (c != BUFFILEEOF)
+ *f->bufp++ = c;
+ cnt = f->bufp - f->buffer;
+ f->bufp = f->buffer;
+ f->left = BUFFILESIZE;
+ if (write (FileDes(f), (char *)f->buffer, cnt) != cnt)
+ return BUFFILEEOF;
+ return c;
+}
+
+static int
+BufFileFlush (BufFilePtr f, int doClose)
+{
+ if (f->bufp != f->buffer)
+ return (*f->output) (BUFFILEEOF, f);
+ return 0;
+}
+
+BufFilePtr
+BufFileOpenWrite (int fd)
+{
+ BufFilePtr f;
+
+#if defined(__UNIXOS2__) || defined(WIN32)
+ /* hv: I'd bet WIN32 has the same effect here */
+ setmode(fd,O_BINARY);
+#endif
+ f = BufFileCreate ((char *)(long) fd, 0, BufFileRawFlush, 0, BufFileFlush);
+ f->bufp = f->buffer;
+ f->left = BUFFILESIZE;
+ return f;
+}
+
+int
+BufFileRead (BufFilePtr f, char *b, int n)
+{
+ int c, cnt;
+ cnt = n;
+ while (cnt--) {
+ c = BufFileGet (f);
+ if (c == BUFFILEEOF)
+ break;
+ *b++ = c;
+ }
+ return n - cnt - 1;
+}
+
+int
+BufFileWrite (BufFilePtr f, char *b, int n)
+{
+ int cnt;
+ cnt = n;
+ while (cnt--) {
+ if (BufFilePut (*b++, f) == BUFFILEEOF)
+ return BUFFILEEOF;
+ }
+ return n;
+}
+
+int
+BufFileClose (BufFilePtr f, int doClose)
+{
+ int ret;
+ ret = (*f->close) (f, doClose);
+ xfree (f);
+ return ret;
+}
diff --git a/libXfont/src/fontfile/bunzip2.c b/libXfont/src/fontfile/bunzip2.c
new file mode 100644
index 000000000..9964de6e9
--- /dev/null
+++ b/libXfont/src/fontfile/bunzip2.c
@@ -0,0 +1,179 @@
+/* Based on src/fontfile/gunzip.c
+ written by Mark Eichin <eichin@kitten.gen.ma.us> September 1996.
+ intended for inclusion in X11 public releases. */
+
+/* Copyright 2008 Sun Microsystems, Inc. All rights reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, and/or sell copies of the Software, and to permit persons
+ * to whom the Software is furnished to do so, provided that the above
+ * copyright notice(s) and this permission notice appear in all copies of
+ * the Software and that both the above copyright notice(s) and this
+ * permission notice appear in supporting documentation.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT
+ * OF THIRD PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+ * HOLDERS INCLUDED IN THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL
+ * INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING
+ * FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
+ * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
+ * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Except as contained in this notice, the name of a copyright holder
+ * shall not be used in advertising or otherwise to promote the sale, use
+ * or other dealings in this Software without prior written authorization
+ * of the copyright holder.
+ */
+
+
+#include "config.h"
+
+#include <X11/fonts/fontmisc.h>
+#include <X11/fonts/bufio.h>
+#include <bzlib.h>
+
+typedef struct _xzip_buf {
+ bz_stream z;
+ int zstat;
+ BufChar b[BUFFILESIZE];
+ BufChar b_in[BUFFILESIZE];
+ BufFilePtr f;
+} xzip_buf;
+
+static int BufBzip2FileClose ( BufFilePtr f, int flag );
+static int BufBzip2FileFill ( BufFilePtr f );
+static int BufBzip2FileSkip ( BufFilePtr f, int c );
+
+_X_HIDDEN BufFilePtr
+BufFilePushBZIP2 (BufFilePtr f)
+{
+ xzip_buf *x;
+
+ x = (xzip_buf *) xalloc (sizeof (xzip_buf));
+ if (!x) return NULL;
+
+ bzero(&(x->z), sizeof(bz_stream));
+ x->f = f;
+
+ x->zstat = BZ2_bzDecompressInit(&(x->z),
+ 0, /* verbosity: 0 silent, 4 max */
+ 0); /* 0: go faster, 1: use less memory */
+ if (x->zstat != BZ_OK) {
+ xfree(x);
+ return NULL;
+ }
+
+ /* now that the history buffer is allocated, we provide the data buffer */
+ x->z.next_out = (char *) x->b;
+ x->z.avail_out = BUFFILESIZE;
+ x->z.next_in = (char *) x->b_in;
+ x->z.avail_in = 0;
+
+ return BufFileCreate((char *)x,
+ BufBzip2FileFill,
+ NULL,
+ BufBzip2FileSkip,
+ BufBzip2FileClose);
+}
+
+static int
+BufBzip2FileClose(BufFilePtr f, int flag)
+{
+ xzip_buf *x = (xzip_buf *)f->private;
+ BZ2_bzDecompressEnd (&(x->z));
+ BufFileClose (x->f, flag);
+ xfree (x);
+ return 1;
+}
+
+/* here's the real work.
+ -- we need to put stuff in f.buffer, update f.left and f.bufp,
+ then return the first byte (or BUFFILEEOF).
+ -- to do this, we need to get stuff into avail_in, and next_in,
+ and call BZ2_bzDecompress appropriately.
+ -- we may also need to add CRC maintenance - if BZ2_bzDecompress tells us
+ BZ_STREAM_END, we then have 4bytes CRC and 4bytes length...
+*/
+static int
+BufBzip2FileFill (BufFilePtr f)
+{
+ xzip_buf *x = (xzip_buf *)f->private;
+
+ /* we only get called when left == 0... */
+ /* but just in case, deal */
+ if (f->left >= 0) {
+ f->left--;
+ return *(f->bufp++);
+ }
+ /* did we run out last time? */
+ switch (x->zstat) {
+ case BZ_OK:
+ break;
+ case BZ_STREAM_END:
+ case BZ_DATA_ERROR:
+ case BZ_DATA_ERROR_MAGIC:
+ f->left = 0;
+ return BUFFILEEOF;
+ default:
+ return BUFFILEEOF;
+ }
+ /* now we work to consume what we can */
+ /* let libbz2 know what we can handle */
+ x->z.next_out = (char *) x->b;
+ x->z.avail_out = BUFFILESIZE;
+
+ /* and try to consume all of it */
+ while (x->z.avail_out > 0) {
+ /* if we don't have anything to work from... */
+ if (x->z.avail_in == 0) {
+ /* ... fill the z buf from underlying file */
+ int i, c;
+ for (i = 0; i < sizeof(x->b_in); i++) {
+ c = BufFileGet(x->f);
+ if (c == BUFFILEEOF) break;
+ x->b_in[i] = c;
+ }
+ x->z.avail_in += i;
+ x->z.next_in = (char *) x->b_in;
+ }
+ /* so now we have some output space and some input data */
+ x->zstat = BZ2_bzDecompress(&(x->z));
+ /* the inflation output happens in the f buffer directly... */
+ if (x->zstat == BZ_STREAM_END) {
+ /* deal with EOF, crc */
+ break;
+ }
+ if (x->zstat != BZ_OK) {
+ break;
+ }
+ }
+ f->bufp = x->b;
+ f->left = BUFFILESIZE - x->z.avail_out;
+
+ if (f->left >= 0) {
+ f->left--;
+ return *(f->bufp++);
+ } else {
+ return BUFFILEEOF;
+ }
+}
+
+/* there should be a BufCommonSkip... */
+static int
+BufBzip2FileSkip (BufFilePtr f, int c)
+{
+ /* BufFileRawSkip returns the count unchanged.
+ BufCompressedSkip returns 0.
+ That means it probably never gets called... */
+ int retval = c;
+ while(c--) {
+ int get = BufFileGet(f);
+ if (get == BUFFILEEOF) return get;
+ }
+ return retval;
+}
diff --git a/libXfont/src/fontfile/catalogue.c b/libXfont/src/fontfile/catalogue.c
new file mode 100644
index 000000000..d49423617
--- /dev/null
+++ b/libXfont/src/fontfile/catalogue.c
@@ -0,0 +1,478 @@
+/*
+ * Copyright © 2007 Red Hat, Inc
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ *
+ * Author:
+ * Kristian Høgsberg <krh@redhat.com>
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include <X11/fonts/fntfilst.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <dirent.h>
+#include <unistd.h>
+
+static const char CataloguePrefix[] = "catalogue:";
+
+static int CatalogueFreeFPE (FontPathElementPtr fpe);
+
+static int
+CatalogueNameCheck (char *name)
+{
+ return strncmp(name, CataloguePrefix, sizeof(CataloguePrefix) - 1) == 0;
+}
+
+typedef struct _CatalogueRec {
+ time_t mtime;
+ int fpeCount, fpeAlloc;
+ FontPathElementPtr *fpeList;
+} CatalogueRec, *CataloguePtr;
+
+static int
+CatalogueAddFPE (CataloguePtr cat, FontPathElementPtr fpe)
+{
+ FontPathElementPtr *new;
+
+ if (cat->fpeCount >= cat->fpeAlloc)
+ {
+ if (cat->fpeAlloc == 0)
+ cat->fpeAlloc = 16;
+ else
+ cat->fpeAlloc *= 2;
+
+ new = xrealloc(cat->fpeList,
+ cat->fpeAlloc * sizeof(FontPathElementPtr));
+ if (new == NULL)
+ return AllocError;
+
+ cat->fpeList = new;
+ }
+
+ cat->fpeList[cat->fpeCount++] = fpe;
+
+ return Successful;
+}
+
+static const char PriorityAttribute[] = "pri=";
+
+static int
+ComparePriority(const void *p1, const void *p2)
+{
+ FontDirectoryPtr dir1 = (*(FontPathElementPtr*) p1)->private;
+ FontDirectoryPtr dir2 = (*(FontPathElementPtr*) p2)->private;
+ const char *pri1 = NULL;
+ const char *pri2 = NULL;
+
+ if (dir1->attributes != NULL)
+ pri1 = strstr(dir1->attributes, PriorityAttribute);
+ if (dir2->attributes != NULL)
+ pri2 = strstr(dir2->attributes, PriorityAttribute);
+
+ if (pri1 == NULL && pri2 == NULL)
+ return 0;
+ else if (pri1 == NULL)
+ return 1;
+ else if (pri2 == NULL)
+ return -1;
+ else
+ return
+ atoi(pri1 + strlen(PriorityAttribute)) -
+ atoi(pri2 + strlen(PriorityAttribute));
+}
+
+static void
+CatalogueUnrefFPEs (FontPathElementPtr fpe)
+{
+ CataloguePtr cat = fpe->private;
+ FontPathElementPtr subfpe;
+ int i;
+
+ for (i = 0; i < cat->fpeCount; i++)
+ {
+ subfpe = cat->fpeList[i];
+ subfpe->refcount--;
+ if (subfpe->refcount == 0)
+ {
+ FontFileFreeFPE (subfpe);
+ xfree(subfpe->name);
+ xfree(subfpe);
+ }
+ }
+
+ cat->fpeCount = 0;
+}
+
+/* Rescan catalogue directory if modified timestamp has changed or
+ * the forceScan argument says to do it anyway (like on first load). */
+static int
+CatalogueRescan (FontPathElementPtr fpe, Bool forceScan)
+{
+ CataloguePtr cat = fpe->private;
+ char link[MAXFONTFILENAMELEN];
+ char dest[MAXFONTFILENAMELEN];
+ char *attrib;
+ FontPathElementPtr subfpe;
+ struct stat statbuf;
+ const char *path;
+ DIR *dir;
+ struct dirent *entry;
+ int len;
+ int pathlen;
+
+ path = fpe->name + strlen(CataloguePrefix);
+ if (stat(path, &statbuf) < 0 || !S_ISDIR(statbuf.st_mode))
+ return BadFontPath;
+
+ if ((forceScan == FALSE) && (statbuf.st_mtime <= cat->mtime))
+ return Successful;
+
+ dir = opendir(path);
+ if (dir == NULL)
+ {
+ xfree(cat);
+ return BadFontPath;
+ }
+
+ CatalogueUnrefFPEs (fpe);
+ while (entry = readdir(dir), entry != NULL)
+ {
+ snprintf(link, sizeof link, "%s/%s", path, entry->d_name);
+ len = readlink(link, dest, sizeof dest - 1);
+ if (len < 0)
+ continue;
+
+ dest[len] = '\0';
+
+ if (dest[0] != '/')
+ {
+ pathlen = strlen(path);
+ memmove(dest + pathlen + 1, dest, sizeof dest - pathlen - 1);
+ memcpy(dest, path, pathlen);
+ memcpy(dest + pathlen, "/", 1);
+ len += pathlen + 1;
+ }
+
+ attrib = strchr(link, ':');
+ if (attrib && len + strlen(attrib) < sizeof dest)
+ {
+ memcpy(dest + len, attrib, strlen(attrib));
+ len += strlen(attrib);
+ }
+
+ subfpe = xalloc(sizeof *subfpe);
+ if (subfpe == NULL)
+ continue;
+
+ /* The fonts returned by OpenFont will point back to the
+ * subfpe they come from. So set the type of the subfpe to
+ * what the catalogue fpe was assigned, so calls to CloseFont
+ * (which uses font->fpe->type) goes to CatalogueCloseFont. */
+ subfpe->type = fpe->type;
+ subfpe->name_length = len;
+ subfpe->name = xalloc (len + 1);
+ if (subfpe == NULL)
+ {
+ xfree(subfpe);
+ continue;
+ }
+
+ memcpy(subfpe->name, dest, len);
+ subfpe->name[len] = '\0';
+
+ /* The X server will manipulate the subfpe ref counts
+ * associated with the font in OpenFont and CloseFont, so we
+ * have to make sure it's valid. */
+ subfpe->refcount = 1;
+
+ if (FontFileInitFPE (subfpe) != Successful)
+ {
+ xfree(subfpe->name);
+ xfree(subfpe);
+ continue;
+ }
+
+ if (CatalogueAddFPE(cat, subfpe) != Successful)
+ {
+ FontFileFreeFPE (subfpe);
+ xfree(subfpe);
+ continue;
+ }
+ }
+
+ closedir(dir);
+
+ qsort(cat->fpeList,
+ cat->fpeCount, sizeof cat->fpeList[0], ComparePriority);
+
+ cat->mtime = statbuf.st_mtime;
+
+ return Successful;
+}
+
+static int
+CatalogueInitFPE (FontPathElementPtr fpe)
+{
+ CataloguePtr cat;
+
+ cat = (CataloguePtr) xalloc(sizeof *cat);
+ if (cat == NULL)
+ return AllocError;
+
+ fpe->private = (pointer) cat;
+ cat->fpeCount = 0;
+ cat->fpeAlloc = 0;
+ cat->fpeList = NULL;
+ cat->mtime = 0;
+
+ return CatalogueRescan (fpe, TRUE);
+}
+
+static int
+CatalogueResetFPE (FontPathElementPtr fpe)
+{
+ /* Always just tell the caller to close and re-open */
+ return FPEResetFailed;
+}
+
+static int
+CatalogueFreeFPE (FontPathElementPtr fpe)
+{
+ CataloguePtr cat = fpe->private;
+
+ /* If the catalogue is modified while the xserver has fonts open
+ * from the previous subfpes, we'll unref the old subfpes when we
+ * reload the catalogue, and the xserver will the call FreeFPE on
+ * them once it drops its last reference. Thus, the FreeFPE call
+ * for the subfpe ends up here and we just forward it to
+ * FontFileFreeFPE. */
+
+ if (!CatalogueNameCheck (fpe->name))
+ return FontFileFreeFPE (fpe);
+
+ CatalogueUnrefFPEs (fpe);
+ xfree(cat->fpeList);
+ xfree(cat);
+
+ return Successful;
+}
+
+static int
+CatalogueOpenFont (pointer client, FontPathElementPtr fpe, Mask flags,
+ char *name, int namelen,
+ fsBitmapFormat format, fsBitmapFormatMask fmask,
+ XID id, FontPtr *pFont, char **aliasName,
+ FontPtr non_cachable_font)
+{
+ CataloguePtr cat = fpe->private;
+ FontPathElementPtr subfpe;
+ FontDirectoryPtr dir;
+ int i, status;
+
+ CatalogueRescan (fpe, FALSE);
+
+ for (i = 0; i < cat->fpeCount; i++)
+ {
+ subfpe = cat->fpeList[i];
+ dir = subfpe->private;
+ status = FontFileOpenFont(client, subfpe, flags,
+ name, namelen, format, fmask, id,
+ pFont, aliasName, non_cachable_font);
+ if (status == Successful || status == FontNameAlias)
+ return status;
+ }
+
+ return BadFontName;
+}
+
+static void
+CatalogueCloseFont (FontPathElementPtr fpe, FontPtr pFont)
+{
+ /* Note: this gets called with the actual subfpe where we found
+ * the font, not the catalogue fpe. */
+
+ FontFileCloseFont(fpe, pFont);
+}
+
+static int
+CatalogueListFonts (pointer client, FontPathElementPtr fpe, char *pat,
+ int len, int max, FontNamesPtr names)
+{
+ CataloguePtr cat = fpe->private;
+ FontPathElementPtr subfpe;
+ FontDirectoryPtr dir;
+ int i;
+
+ CatalogueRescan (fpe, FALSE);
+
+ for (i = 0; i < cat->fpeCount; i++)
+ {
+ subfpe = cat->fpeList[i];
+ dir = subfpe->private;
+ FontFileListFonts(client, subfpe, pat, len, max, names);
+ }
+
+ return Successful;
+}
+
+int
+FontFileStartListFonts(pointer client, FontPathElementPtr fpe,
+ char *pat, int len, int max,
+ pointer *privatep, int mark_aliases);
+
+typedef struct _LFWIData {
+ pointer *privates;
+ int current;
+} LFWIDataRec, *LFWIDataPtr;
+
+static int
+CatalogueStartListFonts(pointer client, FontPathElementPtr fpe,
+ char *pat, int len, int max, pointer *privatep,
+ int mark_aliases)
+{
+ CataloguePtr cat = fpe->private;
+ LFWIDataPtr data;
+ int ret, i, j;
+
+ CatalogueRescan (fpe, FALSE);
+
+ data = (LFWIDataPtr) xalloc (sizeof *data +
+ sizeof data->privates[0] * cat->fpeCount);
+ if (!data)
+ return AllocError;
+ data->privates = (pointer *) (data + 1);
+
+ for (i = 0; i < cat->fpeCount; i++)
+ {
+ ret = FontFileStartListFonts(client, cat->fpeList[i], pat, len,
+ max, &data->privates[i], mark_aliases);
+ if (ret != Successful)
+ goto bail;
+ }
+
+ data->current = 0;
+ *privatep = (pointer) data;
+ return Successful;
+
+ bail:
+ for (j = 0; j < i; j++)
+ /* FIXME: we have no way to free the per-fpe privates. */;
+ xfree (data);
+
+ return AllocError;
+}
+
+static int
+CatalogueStartListFontsWithInfo(pointer client, FontPathElementPtr fpe,
+ char *pat, int len, int max,
+ pointer *privatep)
+{
+ return CatalogueStartListFonts(client, fpe, pat, len, max, privatep, 0);
+}
+
+static int
+CatalogueListNextFontWithInfo(pointer client, FontPathElementPtr fpe,
+ char **namep, int *namelenp,
+ FontInfoPtr *pFontInfo,
+ int *numFonts, pointer private)
+{
+ LFWIDataPtr data = private;
+ CataloguePtr cat = fpe->private;
+ int ret;
+
+ if (data->current == cat->fpeCount)
+ {
+ xfree(data);
+ return BadFontName;
+ }
+
+ ret = FontFileListNextFontWithInfo(client, cat->fpeList[data->current],
+ namep, namelenp,
+ pFontInfo, numFonts,
+ data->privates[data->current]);
+ if (ret == BadFontName)
+ {
+ data->current++;
+ return CatalogueListNextFontWithInfo(client, fpe, namep, namelenp,
+ pFontInfo, numFonts, private);
+ }
+
+ return ret;
+}
+
+static int
+CatalogueStartListFontsAndAliases(pointer client, FontPathElementPtr fpe,
+ char *pat, int len, int max,
+ pointer *privatep)
+{
+ return CatalogueStartListFonts(client, fpe, pat, len, max, privatep, 1);
+}
+
+static int
+CatalogueListNextFontOrAlias(pointer client, FontPathElementPtr fpe,
+ char **namep, int *namelenp, char **resolvedp,
+ int *resolvedlenp, pointer private)
+{
+ LFWIDataPtr data = private;
+ CataloguePtr cat = fpe->private;
+ int ret;
+
+ if (data->current == cat->fpeCount)
+ {
+ xfree(data);
+ return BadFontName;
+ }
+
+ ret = FontFileListNextFontOrAlias(client, cat->fpeList[data->current],
+ namep, namelenp,
+ resolvedp, resolvedlenp,
+ data->privates[data->current]);
+ if (ret == BadFontName)
+ {
+ data->current++;
+ return CatalogueListNextFontOrAlias(client, fpe, namep, namelenp,
+ resolvedp, resolvedlenp, private);
+ }
+
+ return ret;
+}
+
+void
+CatalogueRegisterLocalFpeFunctions (void)
+{
+ RegisterFPEFunctions(CatalogueNameCheck,
+ CatalogueInitFPE,
+ CatalogueFreeFPE,
+ CatalogueResetFPE,
+ CatalogueOpenFont,
+ CatalogueCloseFont,
+ CatalogueListFonts,
+ CatalogueStartListFontsWithInfo,
+ CatalogueListNextFontWithInfo,
+ NULL,
+ NULL,
+ NULL,
+ CatalogueStartListFontsAndAliases,
+ CatalogueListNextFontOrAlias,
+ FontFileEmptyBitmapSource);
+}
diff --git a/libXfont/src/fontfile/decompress.c b/libXfont/src/fontfile/decompress.c
new file mode 100644
index 000000000..a4c546871
--- /dev/null
+++ b/libXfont/src/fontfile/decompress.c
@@ -0,0 +1,410 @@
+/* $Xorg: decompress.c,v 1.4 2001/02/09 02:04:03 xorgcvs Exp $ */
+/*
+ * Copyright 1985, 1986 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * James A. Woods, derived from original work by Spencer Thomas
+ * and Joseph Orost.
+ *
+ * Redistribution and use in source and binary forms are permitted
+ * provided that the above copyright notice and this paragraph are
+ * duplicated in all such forms and that any documentation,
+ * advertising materials, and other materials related to such
+ * distribution and use acknowledge that the software was developed
+ * by the University of California, Berkeley. The name of the
+ * University may not be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
+ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ */
+
+/*
+
+Copyright 1993, 1998 The Open Group
+
+Permission to use, copy, modify, distribute, and sell this software and its
+documentation for any purpose is hereby granted without fee, provided that
+the above copyright notice appear in all copies and that both that
+copyright notice and this permission notice appear in supporting
+documentation.
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of The Open Group shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from The Open Group.
+
+*/
+/* $XFree86: xc/lib/font/fontfile/decompress.c,v 1.4 2001/01/17 19:43:29 dawes Exp $ */
+/*
+ * decompress - cat a compressed file
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include <X11/fonts/fontmisc.h>
+#include <X11/fonts/bufio.h>
+
+#define BITS 16
+
+/*
+ * a code_int must be able to hold 2**BITS values of type int, and also -1
+ */
+#if BITS > 15
+typedef long int code_int;
+#else
+typedef int code_int;
+#endif
+
+typedef long int count_int;
+
+#ifdef NO_UCHAR
+ typedef char char_type;
+#else
+ typedef unsigned char char_type;
+#endif /* UCHAR */
+
+static char_type magic_header[] = { "\037\235" }; /* 1F 9D */
+
+/* Defines for third byte of header */
+#define BIT_MASK 0x1f
+#define BLOCK_MASK 0x80
+/* Masks 0x40 and 0x20 are free. I think 0x20 should mean that there is
+ a fourth header byte (for expansion).
+*/
+
+#define INIT_BITS 9 /* initial number of bits/code */
+
+#ifdef COMPATIBLE /* But wrong! */
+# define MAXCODE(n_bits) (1 << (n_bits) - 1)
+#else
+# define MAXCODE(n_bits) ((1 << (n_bits)) - 1)
+#endif /* COMPATIBLE */
+
+/*
+ * the next two codes should not be changed lightly, as they must not
+ * lie within the contiguous general code space.
+ */
+#define FIRST 257 /* first free entry */
+#define CLEAR 256 /* table clear output code */
+
+#define STACK_SIZE 8192
+
+typedef struct _compressedFILE {
+ BufFilePtr file;
+
+ char_type *stackp;
+ code_int oldcode;
+ char_type finchar;
+
+ int block_compress;
+ int maxbits;
+ code_int maxcode, maxmaxcode;
+
+ code_int free_ent;
+ int clear_flg;
+ int n_bits;
+
+ /* bit buffer */
+ int offset, size;
+ char_type buf[BITS];
+
+ char_type de_stack[STACK_SIZE];
+ char_type *tab_suffix;
+ unsigned short *tab_prefix;
+} CompressedFile;
+
+
+static int hsize_table[] = {
+ 5003, /* 12 bits - 80% occupancy */
+ 9001, /* 13 bits - 91% occupancy */
+ 18013, /* 14 bits - 91% occupancy */
+ 35023, /* 15 bits - 94% occupancy */
+ 69001 /* 16 bits - 95% occupancy */
+};
+
+static int BufCompressedClose ( BufFilePtr f, int doClose );
+static int BufCompressedFill ( BufFilePtr f );
+static code_int getcode ( CompressedFile *file );
+static int BufCompressedSkip ( BufFilePtr f, int bytes );
+
+BufFilePtr
+BufFilePushCompressed (BufFilePtr f)
+{
+ int code;
+ int maxbits;
+ int hsize;
+ CompressedFile *file;
+ int extra;
+
+ if ((BufFileGet(f) != (magic_header[0] & 0xFF)) ||
+ (BufFileGet(f) != (magic_header[1] & 0xFF)))
+ {
+ return 0;
+ }
+ code = BufFileGet (f);
+ if (code == BUFFILEEOF) return 0;
+
+ maxbits = code & BIT_MASK;
+ if (maxbits > BITS || maxbits < 12)
+ return 0;
+ hsize = hsize_table[maxbits - 12];
+ extra = (1 << maxbits) * sizeof (char_type) +
+ hsize * sizeof (unsigned short);
+ file = (CompressedFile *) xalloc (sizeof (CompressedFile) + extra);
+ if (!file)
+ return 0;
+ file->file = f;
+ file->maxbits = maxbits;
+ file->block_compress = code & BLOCK_MASK;
+ file->maxmaxcode = 1 << file->maxbits;
+ file->tab_suffix = (char_type *) &file[1];
+ file->tab_prefix = (unsigned short *) (file->tab_suffix + file->maxmaxcode);
+ /*
+ * As above, initialize the first 256 entries in the table.
+ */
+ file->maxcode = MAXCODE(file->n_bits = INIT_BITS);
+ for ( code = 255; code >= 0; code-- ) {
+ file->tab_prefix[code] = 0;
+ file->tab_suffix[code] = (char_type) code;
+ }
+ file->free_ent = ((file->block_compress) ? FIRST : 256 );
+ file->clear_flg = 0;
+ file->offset = 0;
+ file->size = 0;
+ file->stackp = file->de_stack;
+ bzero(file->buf, BITS);
+ file->finchar = file->oldcode = getcode (file);
+ if (file->oldcode != -1)
+ *file->stackp++ = file->finchar;
+ return BufFileCreate ((char *) file,
+ BufCompressedFill,
+ 0,
+ BufCompressedSkip,
+ BufCompressedClose);
+}
+
+static int
+BufCompressedClose (BufFilePtr f, int doClose)
+{
+ CompressedFile *file;
+ BufFilePtr raw;
+
+ file = (CompressedFile *) f->private;
+ raw = file->file;
+ xfree (file);
+ BufFileClose (raw, doClose);
+ return 1;
+}
+
+static int
+BufCompressedFill (BufFilePtr f)
+{
+ CompressedFile *file;
+ register char_type *stackp, *de_stack;
+ register char_type finchar;
+ register code_int code, oldcode, incode;
+ BufChar *buf, *bufend;
+
+ file = (CompressedFile *) f->private;
+
+ buf = f->buffer;
+ bufend = buf + BUFFILESIZE;
+ stackp = file->stackp;
+ de_stack = file->de_stack;
+ finchar = file->finchar;
+ oldcode = file->oldcode;
+ while (buf < bufend) {
+ while (stackp > de_stack && buf < bufend)
+ *buf++ = *--stackp;
+
+ if (buf == bufend)
+ break;
+
+ if (oldcode == -1)
+ break;
+
+ code = getcode (file);
+ if (code == -1)
+ break;
+
+ if ( (code == CLEAR) && file->block_compress ) {
+ for ( code = 255; code >= 0; code-- )
+ file->tab_prefix[code] = 0;
+ file->clear_flg = 1;
+ file->free_ent = FIRST - 1;
+ if ( (code = getcode (file)) == -1 ) /* O, untimely death! */
+ break;
+ }
+ incode = code;
+ /*
+ * Special case for KwKwK string.
+ */
+ if ( code >= file->free_ent ) {
+ *stackp++ = finchar;
+ code = oldcode;
+ }
+
+ /*
+ * Generate output characters in reverse order
+ */
+ while ( code >= 256 )
+ {
+ *stackp++ = file->tab_suffix[code];
+ code = file->tab_prefix[code];
+ }
+ finchar = file->tab_suffix[code];
+ *stackp++ = finchar;
+
+ /*
+ * Generate the new entry.
+ */
+ if ( (code=file->free_ent) < file->maxmaxcode ) {
+ file->tab_prefix[code] = (unsigned short)oldcode;
+ file->tab_suffix[code] = finchar;
+ file->free_ent = code+1;
+ }
+ /*
+ * Remember previous code.
+ */
+ oldcode = incode;
+ }
+ file->oldcode = oldcode;
+ file->stackp = stackp;
+ file->finchar = finchar;
+ if (buf == f->buffer) {
+ f->left = 0;
+ return BUFFILEEOF;
+ }
+ f->bufp = f->buffer + 1;
+ f->left = (buf - f->buffer) - 1;
+ return f->buffer[0];
+}
+
+/*****************************************************************
+ * TAG( getcode )
+ *
+ * Read one code from the standard input. If BUFFILEEOF, return -1.
+ * Inputs:
+ * stdin
+ * Outputs:
+ * code or -1 is returned.
+ */
+
+static char_type rmask[9] = {0x00, 0x01, 0x03, 0x07, 0x0f, 0x1f, 0x3f, 0x7f, 0xff};
+
+static code_int
+getcode(CompressedFile *file)
+{
+ register code_int code;
+ register int r_off, bits;
+ register char_type *bp = file->buf;
+ register BufFilePtr raw;
+
+ if ( file->clear_flg > 0 || file->offset >= file->size ||
+ file->free_ent > file->maxcode )
+ {
+ /*
+ * If the next entry will be too big for the current code
+ * size, then we must increase the size. This implies reading
+ * a new buffer full, too.
+ */
+ if ( file->free_ent > file->maxcode ) {
+ file->n_bits++;
+ if ( file->n_bits == file->maxbits )
+ file->maxcode = file->maxmaxcode; /* won't get any bigger now */
+ else
+ file->maxcode = MAXCODE(file->n_bits);
+ }
+ if ( file->clear_flg > 0) {
+ file->maxcode = MAXCODE (file->n_bits = INIT_BITS);
+ file->clear_flg = 0;
+ }
+ bits = file->n_bits;
+ raw = file->file;
+ while (bits > 0 && (code = BufFileGet (raw)) != BUFFILEEOF)
+ {
+ *bp++ = code;
+ --bits;
+ }
+ bp = file->buf;
+ if (bits == file->n_bits)
+ return -1; /* end of file */
+ file->size = file->n_bits - bits;
+ file->offset = 0;
+ /* Round size down to integral number of codes */
+ file->size = (file->size << 3) - (file->n_bits - 1);
+ }
+ r_off = file->offset;
+ bits = file->n_bits;
+ /*
+ * Get to the first byte.
+ */
+ bp += (r_off >> 3);
+ r_off &= 7;
+ /* Get first part (low order bits) */
+#ifdef NO_UCHAR
+ code = ((*bp++ >> r_off) & rmask[8 - r_off]) & 0xff;
+#else
+ code = (*bp++ >> r_off);
+#endif /* NO_UCHAR */
+ bits -= (8 - r_off);
+ r_off = 8 - r_off; /* now, offset into code word */
+ /* Get any 8 bit parts in the middle (<=1 for up to 16 bits). */
+ if ( bits >= 8 ) {
+#ifdef NO_UCHAR
+ code |= (*bp++ & 0xff) << r_off;
+#else
+ code |= *bp++ << r_off;
+#endif /* NO_UCHAR */
+ r_off += 8;
+ bits -= 8;
+ }
+ /* high order bits. */
+ code |= (*bp & rmask[bits]) << r_off;
+ file->offset += file->n_bits;
+
+ return code;
+}
+
+static int
+BufCompressedSkip (BufFilePtr f, int bytes)
+{
+ int c;
+ while (bytes--)
+ {
+ c = BufFileGet(f);
+ if (c == BUFFILEEOF)
+ return BUFFILEEOF;
+ }
+ return 0;
+}
+
+#ifdef TEST
+int
+main (int argc, char *argv[])
+{
+ BufFilePtr inputraw, input, output;
+ int c;
+
+ inputraw = BufFileOpenRead (0);
+ input = BufFilePushCompressed (inputraw);
+ output = BufFileOpenWrite (1);
+ while ((c = BufFileGet (input)) != BUFFILEEOF)
+ BufFilePut (c, output);
+ BufFileClose (input, FALSE);
+ BufFileClose (output, FALSE);
+ return 0;
+}
+#endif
diff --git a/libXfont/src/fontfile/defaults.c b/libXfont/src/fontfile/defaults.c
new file mode 100644
index 000000000..7f20cab67
--- /dev/null
+++ b/libXfont/src/fontfile/defaults.c
@@ -0,0 +1,77 @@
+/* $Xorg: defaults.c,v 1.4 2001/02/09 02:04:03 xorgcvs Exp $ */
+
+/*
+
+Copyright 1990, 1998 The Open Group
+
+Permission to use, copy, modify, distribute, and sell this software and its
+documentation for any purpose is hereby granted without fee, provided that
+the above copyright notice appear in all copies and that both that
+copyright notice and this permission notice appear in supporting
+documentation.
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of The Open Group shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from The Open Group.
+
+*/
+/* $XFree86: xc/lib/font/fontfile/defaults.c,v 1.7 2001/01/17 19:43:29 dawes Exp $ */
+
+/*
+ * Author: Keith Packard, MIT X Consortium
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include <X11/X.h>
+#include <X11/Xproto.h>
+
+#ifndef DEFAULT_BIT_ORDER
+#ifdef BITMAP_BIT_ORDER
+#define DEFAULT_BIT_ORDER BITMAP_BIT_ORDER
+#else
+#define DEFAULT_BIT_ORDER MSBFirst
+#endif
+#endif
+
+#ifndef DEFAULT_BYTE_ORDER
+#ifdef IMAGE_BYTE_ORDER
+#define DEFAULT_BYTE_ORDER IMAGE_BYTE_ORDER
+#else
+#define DEFAULT_BYTE_ORDER MSBFirst
+#endif
+#endif
+
+#ifndef DEFAULT_GLYPH_PAD
+#ifdef GLYPHPADBYTES
+#define DEFAULT_GLYPH_PAD GLYPHPADBYTES
+#else
+#define DEFAULT_GLYPH_PAD 4
+#endif
+#endif
+
+#ifndef DEFAULT_SCAN_UNIT
+#define DEFAULT_SCAN_UNIT 1
+#endif
+
+#include <X11/fonts/fntfilst.h>
+
+void
+FontDefaultFormat (int *bit, int *byte, int *glyph, int *scan)
+{
+ *bit = DEFAULT_BIT_ORDER;
+ *byte = DEFAULT_BYTE_ORDER;
+ *glyph = DEFAULT_GLYPH_PAD;
+ *scan = DEFAULT_SCAN_UNIT;
+}
diff --git a/libXfont/src/fontfile/dirfile.c b/libXfont/src/fontfile/dirfile.c
new file mode 100644
index 000000000..148993896
--- /dev/null
+++ b/libXfont/src/fontfile/dirfile.c
@@ -0,0 +1,495 @@
+/* $Xorg: dirfile.c,v 1.4 2001/02/09 02:04:03 xorgcvs Exp $ */
+
+/*
+
+Copyright 1991, 1998 The Open Group
+
+Permission to use, copy, modify, distribute, and sell this software and its
+documentation for any purpose is hereby granted without fee, provided that
+the above copyright notice appear in all copies and that both that
+copyright notice and this permission notice appear in supporting
+documentation.
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of The Open Group shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from The Open Group.
+
+*/
+/* $XFree86: xc/lib/font/fontfile/dirfile.c,v 3.17 2004/02/08 01:52:27 dawes Exp $ */
+
+/*
+ * Author: Keith Packard, MIT X Consortium
+ */
+
+/*
+ * dirfile.c
+ *
+ * Read fonts.dir and fonts.alias files
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include <X11/fonts/fntfilst.h>
+#include <stdio.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <errno.h>
+
+static Bool AddFileNameAliases ( FontDirectoryPtr dir );
+static int ReadFontAlias ( char *directory, Bool isFile,
+ FontDirectoryPtr *pdir );
+static int lexAlias ( FILE *file, char **lexToken );
+static int lexc ( FILE *file );
+
+int
+FontFileReadDirectory (char *directory, FontDirectoryPtr *pdir)
+{
+ char file_name[MAXFONTFILENAMELEN];
+ char font_name[MAXFONTNAMELEN];
+ char dir_file[MAXFONTFILENAMELEN];
+ char dir_path[MAXFONTFILENAMELEN];
+ char *ptr;
+ FILE *file;
+ int count,
+ num_fonts,
+ status;
+ struct stat statb;
+ static char format[24] = "";
+#if defined(__UNIXOS2__) || defined(WIN32)
+ int i;
+#endif
+
+ FontDirectoryPtr dir = NullFontDirectory;
+
+ if (strlen(directory) + 1 + sizeof(FontDirFile) > sizeof(dir_file))
+ return BadFontPath;
+
+ /* Check for font directory attributes */
+#if !defined(__UNIXOS2__) && !defined(WIN32)
+ if ((ptr = strchr(directory, ':'))) {
+#else
+ /* OS/2 and WIN32 path might start with a drive letter, don't clip this */
+ if ((ptr = strchr(directory+2, ':'))) {
+#endif
+ strncpy(dir_path, directory, ptr - directory);
+ dir_path[ptr - directory] = '\0';
+ } else {
+ strcpy(dir_path, directory);
+ }
+ strcpy(dir_file, dir_path);
+ if (dir_file[strlen(dir_file) - 1] != '/')
+ strcat(dir_file, "/");
+ strcat(dir_file, FontDirFile);
+ file = fopen(dir_file, "rt");
+ if (file) {
+#ifndef WIN32
+ if (fstat (fileno(file), &statb) == -1)
+#else
+ if (stat (dir_file, &statb) == -1)
+#endif
+ {
+ fclose(file);
+ return BadFontPath;
+ }
+ count = fscanf(file, "%d\n", &num_fonts);
+ if ((count == EOF) || (count != 1)) {
+ fclose(file);
+ return BadFontPath;
+ }
+ dir = FontFileMakeDir(directory, num_fonts);
+ if (dir == NULL) {
+ fclose(file);
+ return BadFontPath;
+ }
+ dir->dir_mtime = statb.st_mtime;
+ if (format[0] == '\0')
+ sprintf(format, "%%%ds %%%d[^\n]\n",
+ MAXFONTFILENAMELEN-1, MAXFONTNAMELEN-1);
+
+ while ((count = fscanf(file, format, file_name, font_name)) != EOF) {
+#if defined(__UNIXOS2__) || defined(WIN32)
+ /* strip any existing trailing CR */
+ for (i=0; i<strlen(font_name); i++) {
+ if (font_name[i]=='\r') font_name[i] = '\0';
+ }
+#endif
+ if (count != 2) {
+ FontFileFreeDir (dir);
+ fclose(file);
+ return BadFontPath;
+ }
+
+ /*
+ * We blindly try to load all the font files specified.
+ * In theory, we might want to warn that some of the fonts
+ * couldn't be loaded.
+ */
+ FontFileAddFontFile (dir, font_name, file_name);
+ }
+ fclose(file);
+
+ } else if (errno != ENOENT) {
+ return BadFontPath;
+ }
+ status = ReadFontAlias(dir_path, FALSE, &dir);
+ if (status != Successful) {
+ if (dir)
+ FontFileFreeDir (dir);
+ return status;
+ }
+ if (!dir)
+ return BadFontPath;
+
+ FontFileSortDir(dir);
+
+ *pdir = dir;
+ return Successful;
+}
+
+Bool
+FontFileDirectoryChanged(FontDirectoryPtr dir)
+{
+ char dir_file[MAXFONTFILENAMELEN];
+ struct stat statb;
+
+ if (strlen(dir->directory) + sizeof(FontDirFile) > sizeof(dir_file))
+ return FALSE;
+
+ strcpy (dir_file, dir->directory);
+ strcat (dir_file, FontDirFile);
+ if (stat (dir_file, &statb) == -1)
+ {
+ if (errno != ENOENT || dir->dir_mtime != 0)
+ return TRUE;
+ return FALSE; /* doesn't exist and never did: no change */
+ }
+ if (dir->dir_mtime != statb.st_mtime)
+ return TRUE;
+
+ if ((strlen(dir->directory) + sizeof(FontAliasFile)) > sizeof(dir_file))
+ return FALSE;
+ strcpy (dir_file, dir->directory);
+ strcat (dir_file, FontAliasFile);
+ if (stat (dir_file, &statb) == -1)
+ {
+ if (errno != ENOENT || dir->alias_mtime != 0)
+ return TRUE;
+ return FALSE; /* doesn't exist and never did: no change */
+ }
+ if (dir->alias_mtime != statb.st_mtime)
+ return TRUE;
+ return FALSE;
+}
+
+/*
+ * Make each of the file names an automatic alias for each of the files.
+ */
+
+static Bool
+AddFileNameAliases(FontDirectoryPtr dir)
+{
+ int i;
+ char copy[MAXFONTFILENAMELEN];
+ char *fileName;
+ FontTablePtr table;
+ FontRendererPtr renderer;
+ int len;
+ FontNameRec name;
+
+ table = &dir->nonScalable;
+ for (i = 0; i < table->used; i++) {
+ if (table->entries[i].type != FONT_ENTRY_BITMAP)
+ continue;
+ fileName = table->entries[i].u.bitmap.fileName;
+ renderer = FontFileMatchRenderer (fileName);
+ if (!renderer)
+ continue;
+
+ len = strlen (fileName) - renderer->fileSuffixLen;
+ if (len >= sizeof(copy))
+ continue;
+ CopyISOLatin1Lowered (copy, fileName, len);
+ copy[len] = '\0';
+ name.name = copy;
+ name.length = len;
+ name.ndashes = FontFileCountDashes (copy, len);
+
+ if (!FontFileFindNameInDir(table, &name)) {
+ if (!FontFileAddFontAlias (dir, copy, table->entries[i].name.name))
+ return FALSE;
+ }
+ }
+ return TRUE;
+}
+
+/*
+ * parse the font.alias file. Format is:
+ *
+ * alias font-name
+ *
+ * To imbed white-space in an alias name, enclose it like "font name"
+ * in double quotes. \ escapes and character, so
+ * "font name \"With Double Quotes\" \\ and \\ back-slashes"
+ * works just fine.
+ *
+ * A line beginning with a ! denotes a newline-terminated comment.
+ */
+
+/*
+ * token types
+ */
+
+#define NAME 0
+#define NEWLINE 1
+#define DONE 2
+#define EALLOC 3
+
+static int
+ReadFontAlias(char *directory, Bool isFile, FontDirectoryPtr *pdir)
+{
+ char alias[MAXFONTNAMELEN];
+ char font_name[MAXFONTNAMELEN];
+ char alias_file[MAXFONTFILENAMELEN];
+ FILE *file;
+ FontDirectoryPtr dir;
+ int token;
+ char *lexToken;
+ int status = Successful;
+ struct stat statb;
+
+ if (strlen(directory) >= sizeof(alias_file))
+ return BadFontPath;
+ dir = *pdir;
+ strcpy(alias_file, directory);
+ if (!isFile) {
+ if (strlen(directory) + 1 + sizeof(FontAliasFile) > sizeof(alias_file))
+ return BadFontPath;
+ if (directory[strlen(directory) - 1] != '/')
+ strcat(alias_file, "/");
+ strcat(alias_file, FontAliasFile);
+ }
+ file = fopen(alias_file, "rt");
+ if (!file)
+ return ((errno == ENOENT) ? Successful : BadFontPath);
+ if (!dir)
+ *pdir = dir = FontFileMakeDir(directory, 10);
+ if (!dir)
+ {
+ fclose (file);
+ return AllocError;
+ }
+#ifndef WIN32
+ if (fstat (fileno (file), &statb) == -1)
+#else
+ if (stat (alias_file, &statb) == -1)
+#endif
+ {
+ fclose (file);
+ return BadFontPath;
+ }
+ dir->alias_mtime = statb.st_mtime;
+ while (status == Successful) {
+ token = lexAlias(file, &lexToken);
+ switch (token) {
+ case NEWLINE:
+ break;
+ case DONE:
+ fclose(file);
+ return Successful;
+ case EALLOC:
+ status = AllocError;
+ break;
+ case NAME:
+ if (strlen(lexToken) >= sizeof(alias)) {
+ status = BadFontPath;
+ break;
+ }
+ strcpy(alias, lexToken);
+ token = lexAlias(file, &lexToken);
+ switch (token) {
+ case NEWLINE:
+ if (strcmp(alias, "FILE_NAMES_ALIASES"))
+ status = BadFontPath;
+ else if (!AddFileNameAliases(dir))
+ status = AllocError;
+ break;
+ case DONE:
+ status = BadFontPath;
+ break;
+ case EALLOC:
+ status = AllocError;
+ break;
+ case NAME:
+ if (strlen(lexToken) >= sizeof(font_name)) {
+ status = BadFontPath;
+ break;
+ }
+ CopyISOLatin1Lowered(alias, alias, strlen(alias));
+ CopyISOLatin1Lowered(font_name, lexToken, strlen(lexToken));
+ if (!FontFileAddFontAlias (dir, alias, font_name))
+ status = AllocError;
+ break;
+ }
+ }
+ }
+ fclose(file);
+ return status;
+}
+
+#define QUOTE 0
+#define WHITE 1
+#define NORMAL 2
+#define END 3
+#define NL 4
+#define BANG 5
+
+static int charClass;
+
+static int
+lexAlias(FILE *file, char **lexToken)
+{
+ int c;
+ char *t;
+ enum state {
+ Begin, Normal, Quoted, Comment
+ } state;
+ int count;
+
+ static char *tokenBuf = (char *) NULL;
+ static int tokenSize = 0;
+
+ t = tokenBuf;
+ count = 0;
+ state = Begin;
+ for (;;) {
+ if (count == tokenSize) {
+ int nsize;
+ char *nbuf;
+
+ nsize = tokenSize ? (tokenSize << 1) : 64;
+ nbuf = (char *) xrealloc(tokenBuf, nsize);
+ if (!nbuf)
+ return EALLOC;
+ tokenBuf = nbuf;
+ tokenSize = nsize;
+ t = tokenBuf + count;
+ }
+ c = lexc(file);
+ switch (charClass) {
+ case QUOTE:
+ switch (state) {
+ case Begin:
+ case Normal:
+ state = Quoted;
+ break;
+ case Quoted:
+ state = Normal;
+ break;
+ case Comment:
+ break;
+ }
+ break;
+ case WHITE:
+ switch (state) {
+ case Begin:
+ case Comment:
+ continue;
+ case Normal:
+ *t = '\0';
+ *lexToken = tokenBuf;
+ return NAME;
+ case Quoted:
+ break;
+ }
+ /* fall through */
+ case NORMAL:
+ switch (state) {
+ case Begin:
+ state = Normal;
+ break;
+ case Comment:
+ continue;
+ default:
+ break;
+ }
+ *t++ = c;
+ ++count;
+ break;
+ case END:
+ case NL:
+ switch (state) {
+ case Begin:
+ case Comment:
+ *lexToken = (char *) NULL;
+ return charClass == END ? DONE : NEWLINE;
+ default:
+ *t = '\0';
+ *lexToken = tokenBuf;
+ ungetc(c, file);
+ return NAME;
+ }
+ break;
+ case BANG:
+ switch (state) {
+ case Begin:
+ state = Comment;
+ break;
+ case Comment:
+ break;
+ default:
+ *t++ = c;
+ ++count;
+ }
+ break;
+ }
+ }
+}
+
+static int
+lexc(FILE *file)
+{
+ int c;
+
+ c = getc(file);
+ switch (c) {
+ case EOF:
+ charClass = END;
+ break;
+ case '\\':
+ c = getc(file);
+ if (c == EOF)
+ charClass = END;
+ else
+ charClass = NORMAL;
+ break;
+ case '"':
+ charClass = QUOTE;
+ break;
+ case ' ':
+ case '\t':
+ charClass = WHITE;
+ break;
+ case '\r':
+ case '\n':
+ charClass = NL;
+ break;
+ case '!':
+ charClass = BANG;
+ break;
+ default:
+ charClass = NORMAL;
+ break;
+ }
+ return c;
+}
diff --git a/libXfont/src/fontfile/ffcheck.c b/libXfont/src/fontfile/ffcheck.c
new file mode 100644
index 000000000..70d117e46
--- /dev/null
+++ b/libXfont/src/fontfile/ffcheck.c
@@ -0,0 +1,188 @@
+/* $Xorg: ffcheck.c,v 1.4 2001/02/09 02:04:03 xorgcvs Exp $ */
+
+/*
+
+Copyright 1991, 1998 The Open Group
+
+Permission to use, copy, modify, distribute, and sell this software and its
+documentation for any purpose is hereby granted without fee, provided that
+the above copyright notice appear in all copies and that both that
+copyright notice and this permission notice appear in supporting
+documentation.
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of The Open Group shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from The Open Group.
+
+*/
+/* $XFree86: xc/lib/font/fontfile/ffcheck.c,v 1.15tsi Exp $ */
+
+/*
+ * Author: Keith Packard, MIT X Consortium
+ */
+/* $NCDXorg: @(#)fontfile.c,v 1.6 1991/07/02 17:00:46 lemke Exp $ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include <X11/fonts/fntfilst.h>
+#include <X11/fonts/bitmap.h>
+#include <X11/fonts/fontmod.h>
+
+/*
+ * Map FPE functions to renderer functions
+ */
+
+
+/* Here we must check the client to see if it has a context attached to
+ * it that allows us to access the printer fonts
+ */
+
+static int
+FontFileCheckOpenFont (pointer client, FontPathElementPtr fpe, Mask flags,
+ char *name, int namelen,
+ fsBitmapFormat format, fsBitmapFormatMask fmask,
+ XID id, FontPtr *pFont, char **aliasName,
+ FontPtr non_cachable_font)
+{
+ if (XpClientIsBitmapClient(client))
+ return (FontFileOpenFont (client, fpe, flags, name, namelen, format,
+ fmask, id, pFont, aliasName, non_cachable_font));
+ return BadFontName;
+}
+
+static int
+FontFileCheckListFonts (pointer client, FontPathElementPtr fpe,
+ char *pat, int len, int max, FontNamesPtr names)
+{
+ if (XpClientIsBitmapClient(client))
+ return FontFileListFonts (client, fpe, pat, len, max, names);
+ return BadFontName;
+}
+
+static int
+FontFileCheckStartListFontsWithInfo(pointer client, FontPathElementPtr fpe,
+ char *pat, int len, int max,
+ pointer *privatep)
+{
+ if (XpClientIsBitmapClient(client))
+ return FontFileStartListFontsWithInfo(client, fpe, pat, len,
+ max, privatep);
+ return BadFontName;
+}
+
+static int
+FontFileCheckListNextFontWithInfo(pointer client, FontPathElementPtr fpe,
+ char **namep, int *namelenp,
+ FontInfoPtr *pFontInfo,
+ int *numFonts, pointer private)
+{
+ if (XpClientIsBitmapClient(client))
+ return FontFileListNextFontWithInfo(client, fpe, namep, namelenp,
+ pFontInfo, numFonts, private);
+ return BadFontName;
+}
+
+static int
+FontFileCheckStartListFontsAndAliases(pointer client, FontPathElementPtr fpe,
+ char *pat, int len, int max,
+ pointer *privatep)
+{
+ if (XpClientIsBitmapClient(client))
+ return FontFileStartListFontsAndAliases(client, fpe, pat, len,
+ max, privatep);
+ return BadFontName;
+}
+
+static int
+FontFileCheckListNextFontOrAlias(pointer client, FontPathElementPtr fpe,
+ char **namep, int *namelenp,
+ char **resolvedp, int *resolvedlenp,
+ pointer private)
+{
+ if (XpClientIsBitmapClient(client))
+ return FontFileListNextFontOrAlias(client, fpe, namep, namelenp,
+ resolvedp, resolvedlenp, private);
+ return BadFontName;
+}
+
+/* Font renderers to initialize when not linked into something like
+ Xorg that provides its own module configuration options */
+static const FontModule builtinFontModuleList[] = {
+#ifdef XFONT_SPEEDO
+ {
+ SpeedoRegisterFontFileFunctions,
+ "speedo",
+ NULL
+ },
+#endif
+#ifdef XFONT_TYPE1
+ {
+ Type1RegisterFontFileFunctions,
+ "type1",
+ NULL
+ },
+#endif
+#ifdef XFONT_FREETYPE
+ {
+ FreeTypeRegisterFontFileFunctions,
+ "freetype",
+ NULL
+ },
+#endif
+ /* List terminator - must be last entry */
+ { NULL, NULL, NULL }
+};
+
+void
+FontFileCheckRegisterFpeFunctions (void)
+{
+ const FontModule *fmlist = builtinFontModuleList;
+
+#ifdef XFONT_BITMAP
+ /* bitmap is always builtin to libXfont now */
+ BitmapRegisterFontFileFunctions ();
+#endif
+
+#ifdef LOADABLEFONTS
+ if (FontModuleList) {
+ fmlist = FontModuleList;
+ }
+#endif
+
+ if (fmlist) {
+ int i;
+
+ for (i = 0; fmlist[i].name; i++) {
+ if (fmlist[i].initFunc) {
+ fmlist[i].initFunc();
+ }
+ }
+ }
+
+ RegisterFPEFunctions(FontFileNameCheck,
+ FontFileInitFPE,
+ FontFileFreeFPE,
+ FontFileResetFPE,
+ FontFileCheckOpenFont,
+ FontFileCloseFont,
+ FontFileCheckListFonts,
+ FontFileCheckStartListFontsWithInfo,
+ FontFileCheckListNextFontWithInfo,
+ NULL,
+ NULL,
+ NULL,
+ FontFileCheckStartListFontsAndAliases,
+ FontFileCheckListNextFontOrAlias,
+ FontFileEmptyBitmapSource);
+}
diff --git a/libXfont/src/fontfile/fileio.c b/libXfont/src/fontfile/fileio.c
new file mode 100644
index 000000000..3733148a5
--- /dev/null
+++ b/libXfont/src/fontfile/fileio.c
@@ -0,0 +1,99 @@
+/* $Xorg: fileio.c,v 1.4 2001/02/09 02:04:03 xorgcvs Exp $ */
+
+/*
+
+Copyright 1991, 1998 The Open Group
+
+Permission to use, copy, modify, distribute, and sell this software and its
+documentation for any purpose is hereby granted without fee, provided that
+the above copyright notice appear in all copies and that both that
+copyright notice and this permission notice appear in supporting
+documentation.
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of The Open Group shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from The Open Group.
+
+*/
+/* $XFree86: xc/lib/font/fontfile/fileio.c,v 3.9 2001/12/14 19:56:51 dawes Exp $ */
+
+/*
+ * Author: Keith Packard, MIT X Consortium
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include <X11/fonts/fntfilio.h>
+#include <X11/Xos.h>
+#ifndef O_BINARY
+#define O_BINARY O_RDONLY
+#endif
+
+FontFilePtr
+FontFileOpen (const char *name)
+{
+ int fd;
+ int len;
+ BufFilePtr raw, cooked;
+
+ fd = open (name, O_BINARY);
+ if (fd < 0)
+ return 0;
+ raw = BufFileOpenRead (fd);
+ if (!raw)
+ {
+ close (fd);
+ return 0;
+ }
+ len = strlen (name);
+#ifndef __UNIXOS2__
+ if (len > 2 && !strcmp (name + len - 2, ".Z")) {
+#else
+ if (len > 2 && (!strcmp (name + len - 4, ".pcz") ||
+ !strcmp (name + len - 2, ".Z"))) {
+#endif
+ cooked = BufFilePushCompressed (raw);
+ if (!cooked) {
+ BufFileClose (raw, TRUE);
+ return 0;
+ }
+ raw = cooked;
+#ifdef X_GZIP_FONT_COMPRESSION
+ } else if (len > 3 && !strcmp (name + len - 3, ".gz")) {
+ cooked = BufFilePushZIP (raw);
+ if (!cooked) {
+ BufFileClose (raw, TRUE);
+ return 0;
+ }
+ raw = cooked;
+#endif
+#ifdef X_BZIP2_FONT_COMPRESSION
+ } else if (len > 4 && !strcmp (name + len - 4, ".bz2")) {
+ cooked = BufFilePushBZIP2 (raw);
+ if (!cooked) {
+ BufFileClose (raw, TRUE);
+ return 0;
+ }
+ raw = cooked;
+#endif
+ }
+ return (FontFilePtr) raw;
+}
+
+int
+FontFileClose (FontFilePtr f)
+{
+ return BufFileClose ((BufFilePtr) f, TRUE);
+}
+
diff --git a/libXfont/src/fontfile/filewr.c b/libXfont/src/fontfile/filewr.c
new file mode 100644
index 000000000..d076f166a
--- /dev/null
+++ b/libXfont/src/fontfile/filewr.c
@@ -0,0 +1,65 @@
+/* $Xorg: filewr.c,v 1.4 2001/02/09 02:04:03 xorgcvs Exp $ */
+
+/*
+
+Copyright 1991, 1998 The Open Group
+
+Permission to use, copy, modify, distribute, and sell this software and its
+documentation for any purpose is hereby granted without fee, provided that
+the above copyright notice appear in all copies and that both that
+copyright notice and this permission notice appear in supporting
+documentation.
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of The Open Group shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from The Open Group.
+
+*/
+/* $XFree86: xc/lib/font/fontfile/filewr.c,v 3.6 2001/12/14 19:56:51 dawes Exp $ */
+
+/*
+ * Author: Keith Packard, MIT X Consortium
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include <X11/fonts/fntfilio.h>
+#include <X11/Xos.h>
+
+FontFilePtr
+FontFileOpenWrite (const char *name)
+{
+ int fd;
+
+#if defined(WIN32) || defined(__UNIXOS2__) || defined(__CYGWIN__)
+ fd = open (name, O_CREAT|O_TRUNC|O_RDWR|O_BINARY, 0666);
+#else
+ fd = creat (name, 0666);
+#endif
+ if (fd < 0)
+ return 0;
+ return (FontFilePtr) BufFileOpenWrite (fd);
+}
+
+FontFilePtr
+FontFileOpenWriteFd (int fd)
+{
+ return (FontFilePtr) BufFileOpenWrite (fd);
+}
+
+FontFilePtr
+FontFileOpenFd (int fd)
+{
+ return (FontFilePtr) BufFileOpenRead (fd);
+}
diff --git a/libXfont/src/fontfile/fontdir.c b/libXfont/src/fontfile/fontdir.c
new file mode 100644
index 000000000..00c751153
--- /dev/null
+++ b/libXfont/src/fontfile/fontdir.c
@@ -0,0 +1,833 @@
+/* $XdotOrg: xc/lib/font/fontfile/fontdir.c,v 1.4 2005/07/03 07:01:00 daniels Exp $ */
+/* $Xorg: fontdir.c,v 1.4 2001/02/09 02:04:03 xorgcvs Exp $ */
+
+/*
+
+Copyright 1991, 1998 The Open Group
+
+Permission to use, copy, modify, distribute, and sell this software and its
+documentation for any purpose is hereby granted without fee, provided that
+the above copyright notice appear in all copies and that both that
+copyright notice and this permission notice appear in supporting
+documentation.
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of The Open Group shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from The Open Group.
+
+*/
+/* $XFree86: xc/lib/font/fontfile/fontdir.c,v 3.22 2003/07/07 16:40:11 eich Exp $ */
+
+/*
+ * Author: Keith Packard, MIT X Consortium
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include <X11/fonts/fntfilst.h>
+#include <X11/keysym.h>
+
+#if HAVE_STDINT_H
+#include <stdint.h>
+#elif !defined(INT32_MAX)
+#define INT32_MAX 0x7fffffff
+#endif
+
+Bool
+FontFileInitTable (FontTablePtr table, int size)
+{
+ if (size < 0 || (size > INT32_MAX/sizeof(FontEntryRec)))
+ return FALSE;
+ if (size)
+ {
+ table->entries = (FontEntryPtr) xalloc(sizeof(FontEntryRec) * size);
+ if (!table->entries)
+ return FALSE;
+ }
+ else
+ table->entries = 0;
+ table->used = 0;
+ table->size = size;
+ table->sorted = FALSE;
+ return TRUE;
+}
+
+void
+FontFileFreeEntry (FontEntryPtr entry)
+{
+ FontScalableExtraPtr extra;
+ int i;
+
+ if (entry->name.name)
+ xfree(entry->name.name);
+ entry->name.name = NULL;
+
+ switch (entry->type)
+ {
+ case FONT_ENTRY_SCALABLE:
+ xfree (entry->u.scalable.fileName);
+ extra = entry->u.scalable.extra;
+ for (i = 0; i < extra->numScaled; i++)
+ if (extra->scaled[i].vals.ranges)
+ xfree (extra->scaled[i].vals.ranges);
+ xfree (extra->scaled);
+ xfree (extra);
+ break;
+ case FONT_ENTRY_BITMAP:
+ xfree (entry->u.bitmap.fileName);
+ entry->u.bitmap.fileName = NULL;
+ break;
+ case FONT_ENTRY_ALIAS:
+ xfree (entry->u.alias.resolved);
+ entry->u.alias.resolved = NULL;
+ break;
+#ifdef NOTYET
+ case FONT_ENTRY_BC:
+ break;
+#endif
+ }
+}
+
+void
+FontFileFreeTable (FontTablePtr table)
+{
+ int i;
+
+ for (i = 0; i < table->used; i++)
+ FontFileFreeEntry (&table->entries[i]);
+ xfree (table->entries);
+}
+
+FontDirectoryPtr
+FontFileMakeDir(char *dirName, int size)
+{
+ FontDirectoryPtr dir;
+ int dirlen;
+ int needslash = 0;
+ char *attrib;
+ int attriblen;
+
+#if !defined(__UNIXOS2__) && !defined(WIN32)
+ attrib = strchr(dirName, ':');
+#else
+ /* OS/2 uses the colon in the drive letter descriptor, skip this */
+ attrib = strchr(dirName+2, ':');
+#endif
+ if (attrib) {
+ dirlen = attrib - dirName;
+ attriblen = strlen(attrib);
+ } else {
+ dirlen = strlen(dirName);
+ attriblen = 0;
+ }
+ if (dirName[dirlen - 1] != '/')
+#ifdef NCD
+ if (dirlen) /* leave out slash for builtins */
+#endif
+ needslash = 1;
+ dir = (FontDirectoryPtr) xalloc(sizeof *dir + dirlen + needslash + 1 +
+ (attriblen ? attriblen + 1 : 0));
+ if (!dir)
+ return (FontDirectoryPtr)0;
+ if (!FontFileInitTable (&dir->scalable, 0))
+ {
+ xfree (dir);
+ return (FontDirectoryPtr)0;
+ }
+ if (!FontFileInitTable (&dir->nonScalable, size))
+ {
+ FontFileFreeTable (&dir->scalable);
+ xfree (dir);
+ return (FontDirectoryPtr)0;
+ }
+ dir->directory = (char *) (dir + 1);
+ dir->dir_mtime = 0;
+ dir->alias_mtime = 0;
+ if (attriblen)
+ dir->attributes = dir->directory + dirlen + needslash + 1;
+ else
+ dir->attributes = NULL;
+ strncpy(dir->directory, dirName, dirlen);
+ dir->directory[dirlen] = '\0';
+ if (dir->attributes)
+ strcpy(dir->attributes, attrib);
+ if (needslash)
+ strcat(dir->directory, "/");
+ return dir;
+}
+
+void
+FontFileFreeDir (FontDirectoryPtr dir)
+{
+ FontFileFreeTable (&dir->scalable);
+ FontFileFreeTable (&dir->nonScalable);
+ xfree(dir);
+}
+
+FontEntryPtr
+FontFileAddEntry(FontTablePtr table, FontEntryPtr prototype)
+{
+ FontEntryPtr entry;
+ int newsize;
+
+ /* can't add entries to a sorted table, pointers get broken! */
+ if (table->sorted)
+ return (FontEntryPtr) 0; /* "cannot" happen */
+ if (table->used == table->size) {
+ newsize = table->size + 100;
+ entry = (FontEntryPtr) xrealloc(table->entries,
+ newsize * sizeof(FontEntryRec));
+ if (!entry)
+ return (FontEntryPtr)0;
+ table->size = newsize;
+ table->entries = entry;
+ }
+ entry = &table->entries[table->used];
+ *entry = *prototype;
+ entry->name.name = (char *) xalloc(prototype->name.length + 1);
+ if (!entry->name.name)
+ return (FontEntryPtr)0;
+ memcpy (entry->name.name, prototype->name.name, prototype->name.length);
+ entry->name.name[entry->name.length] = '\0';
+ table->used++;
+ return entry;
+}
+
+/*
+ * Compare two strings just like strcmp, but preserve decimal integer
+ * sorting order, i.e. "2" < "10" or "iso8859-2" < "iso8859-10" <
+ * "iso10646-1". Strings are sorted as if sequences of digits were
+ * prefixed by a length indicator (i.e., does not ignore leading zeroes).
+ *
+ * Markus Kuhn <Markus.Kuhn@cl.cam.ac.uk>
+ */
+#define Xisdigit(c) ('\060' <= (c) && (c) <= '\071')
+
+static int strcmpn(const char *s1, const char *s2)
+{
+ int digits, predigits = 0;
+ const char *ss1, *ss2;
+
+ while (1) {
+ if (*s1 == 0 && *s2 == 0)
+ return 0;
+ digits = Xisdigit(*s1) && Xisdigit(*s2);
+ if (digits && !predigits) {
+ ss1 = s1;
+ ss2 = s2;
+ while (Xisdigit(*ss1) && Xisdigit(*ss2))
+ ss1++, ss2++;
+ if (!Xisdigit(*ss1) && Xisdigit(*ss2))
+ return -1;
+ if (Xisdigit(*ss1) && !Xisdigit(*ss2))
+ return 1;
+ }
+ if ((unsigned char)*s1 < (unsigned char)*s2)
+ return -1;
+ if ((unsigned char)*s1 > (unsigned char)*s2)
+ return 1;
+ predigits = digits;
+ s1++, s2++;
+ }
+}
+
+
+static int
+FontFileNameCompare(const void* a, const void* b)
+{
+ FontEntryPtr a_name = (FontEntryPtr) a,
+ b_name = (FontEntryPtr) b;
+
+ return strcmpn(a_name->name.name, b_name->name.name);
+}
+
+void
+FontFileSortTable (FontTablePtr table)
+{
+ if (!table->sorted) {
+ qsort((char *) table->entries, table->used, sizeof(FontEntryRec),
+ FontFileNameCompare);
+ table->sorted = TRUE;
+ }
+}
+
+void
+FontFileSortDir(FontDirectoryPtr dir)
+{
+ FontFileSortTable (&dir->scalable);
+ FontFileSortTable (&dir->nonScalable);
+ /* now that the table is fixed in size, swizzle the pointers */
+ FontFileSwitchStringsToBitmapPointers (dir);
+}
+
+/*
+ Given a Font Table, SetupWildMatch() sets up various pointers and state
+ information so the table can be searched for name(s) that match a given
+ fontname pattern -- which may contain wildcards. Under certain
+ circumstances, SetupWildMatch() will find the one table entry that
+ matches the pattern. If those circumstances do not pertain,
+ SetupWildMatch() returns a range within the the table that should be
+ searched for matching name(s). With the information established by
+ SetupWildMatch(), including state information in "private", the
+ PatternMatch() procedure is then used to test names in the range for a
+ match.
+*/
+
+#define isWild(c) ((c) == XK_asterisk || (c) == XK_question)
+#define isDigit(c) (XK_0 <= (c) && (c) <= XK_9)
+
+static int
+SetupWildMatch(FontTablePtr table, FontNamePtr pat,
+ int *leftp, int *rightp, int *privatep)
+{
+ int nDashes;
+ char c;
+ char *t;
+ char *firstWild;
+ char *firstDigit;
+ int first;
+ int center,
+ left,
+ right;
+ int result;
+ char *name;
+
+ name = pat->name;
+ nDashes = pat->ndashes;
+ firstWild = 0;
+ firstDigit = 0;
+ t = name;
+ while ((c = *t++)) {
+ if (isWild(c)) {
+ if (!firstWild)
+ firstWild = t - 1;
+ }
+ if (isDigit(c)) {
+ if (!firstDigit)
+ firstDigit = t - 1;
+ }
+ }
+ left = 0;
+ right = table->used;
+ if (firstWild)
+ *privatep = nDashes;
+ else
+ *privatep = -1;
+ if (!table->sorted) {
+ *leftp = left;
+ *rightp = right;
+ return -1;
+ } else if (firstWild) {
+ if (firstDigit && firstDigit < firstWild)
+ first = firstDigit - name;
+ else
+ first = firstWild - name;
+ while (left < right) {
+ center = (left + right) / 2;
+ result = strncmp(name, table->entries[center].name.name, first);
+ if (result == 0)
+ break;
+ if (result < 0)
+ right = center;
+ else
+ left = center + 1;
+ }
+ *leftp = left;
+ *rightp = right;
+ return -1;
+ } else {
+ while (left < right) {
+ center = (left + right) / 2;
+ result = strcmpn(name, table->entries[center].name.name);
+ if (result == 0)
+ return center;
+ if (result < 0)
+ right = center;
+ else
+ left = center + 1;
+ }
+ *leftp = 1;
+ *rightp = 0;
+ return -1;
+ }
+}
+
+static int
+PatternMatch(char *pat, int patdashes, char *string, int stringdashes)
+{
+ char c,
+ t;
+
+ if (stringdashes < patdashes)
+ return 0;
+ for (;;) {
+ switch (c = *pat++) {
+ case '*':
+ if (!(c = *pat++))
+ return 1;
+ if (c == XK_minus) {
+ patdashes--;
+ for (;;) {
+ while ((t = *string++) != XK_minus)
+ if (!t)
+ return 0;
+ stringdashes--;
+ if (PatternMatch(pat, patdashes, string, stringdashes))
+ return 1;
+ if (stringdashes == patdashes)
+ return 0;
+ }
+ } else {
+ for (;;) {
+ while ((t = *string++) != c) {
+ if (!t)
+ return 0;
+ if (t == XK_minus) {
+ if (stringdashes-- < patdashes)
+ return 0;
+ }
+ }
+ if (PatternMatch(pat, patdashes, string, stringdashes))
+ return 1;
+ }
+ }
+ case '?':
+ if (*string++ == XK_minus)
+ stringdashes--;
+ break;
+ case '\0':
+ return (*string == '\0');
+ case XK_minus:
+ if (*string++ == XK_minus) {
+ patdashes--;
+ stringdashes--;
+ break;
+ }
+ return 0;
+ default:
+ if (c == *string++)
+ break;
+ return 0;
+ }
+ }
+}
+
+int
+FontFileCountDashes (char *name, int namelen)
+{
+ int ndashes = 0;
+
+ while (namelen--)
+ if (*name++ == '\055') /* avoid non ascii systems */
+ ++ndashes;
+ return ndashes;
+}
+
+char *
+FontFileSaveString (char *s)
+{
+ char *n;
+
+ n = (char *) xalloc (strlen (s) + 1);
+ if (!n)
+ return 0;
+ strcpy (n, s);
+ return n;
+}
+
+FontEntryPtr
+FontFileFindNameInScalableDir(FontTablePtr table, FontNamePtr pat,
+ FontScalablePtr vals)
+{
+ int i,
+ start,
+ stop,
+ res,
+ private;
+ FontNamePtr name;
+
+ if (!table->entries)
+ return NULL;
+ if ((i = SetupWildMatch(table, pat, &start, &stop, &private)) >= 0)
+ return &table->entries[i];
+ for (i = start; i < stop; i++) {
+ name = &table->entries[i].name;
+ res = PatternMatch(pat->name, private, name->name, name->ndashes);
+ if (res > 0)
+ {
+ /* Check to see if enhancements requested are available */
+ if (vals)
+ {
+ int vs = vals->values_supplied;
+ int cap;
+
+ if (table->entries[i].type == FONT_ENTRY_SCALABLE)
+ cap = table->entries[i].u.scalable.renderer->capabilities;
+ else if (table->entries[i].type == FONT_ENTRY_ALIAS)
+ cap = ~0; /* Calling code will have to see if true */
+ else
+ cap = 0;
+ if ((((vs & PIXELSIZE_MASK) == PIXELSIZE_ARRAY ||
+ (vs & POINTSIZE_MASK) == POINTSIZE_ARRAY) &&
+ !(cap & CAP_MATRIX)) ||
+ ((vs & CHARSUBSET_SPECIFIED) &&
+ !(cap & CAP_CHARSUBSETTING)))
+ continue;
+ }
+ return &table->entries[i];
+ }
+ if (res < 0)
+ break;
+ }
+ return (FontEntryPtr)0;
+}
+
+FontEntryPtr
+FontFileFindNameInDir(FontTablePtr table, FontNamePtr pat)
+{
+ return FontFileFindNameInScalableDir(table, pat, (FontScalablePtr)0);
+}
+
+int
+FontFileFindNamesInScalableDir(FontTablePtr table, FontNamePtr pat, int max,
+ FontNamesPtr names, FontScalablePtr vals,
+ int alias_behavior, int *newmax)
+{
+ int i,
+ start,
+ stop,
+ res,
+ private;
+ int ret = Successful;
+ FontEntryPtr fname;
+ FontNamePtr name;
+
+ if (max <= 0)
+ return Successful;
+ if ((i = SetupWildMatch(table, pat, &start, &stop, &private)) >= 0) {
+ if (alias_behavior == NORMAL_ALIAS_BEHAVIOR ||
+ table->entries[i].type != FONT_ENTRY_ALIAS)
+ {
+ name = &table->entries[i].name;
+ if (newmax) *newmax = max - 1;
+ return AddFontNamesName(names, name->name, name->length);
+ }
+ start = i;
+ stop = i + 1;
+ }
+ for (i = start, fname = &table->entries[start]; i < stop; i++, fname++) {
+ res = PatternMatch(pat->name, private, fname->name.name, fname->name.ndashes);
+ if (res > 0) {
+ if (vals)
+ {
+ int vs = vals->values_supplied;
+ int cap;
+
+ if (fname->type == FONT_ENTRY_SCALABLE)
+ cap = fname->u.scalable.renderer->capabilities;
+ else if (fname->type == FONT_ENTRY_ALIAS)
+ cap = ~0; /* Calling code will have to see if true */
+ else
+ cap = 0;
+ if ((((vs & PIXELSIZE_MASK) == PIXELSIZE_ARRAY ||
+ (vs & POINTSIZE_MASK) == POINTSIZE_ARRAY) &&
+ !(cap & CAP_MATRIX)) ||
+ ((vs & CHARSUBSET_SPECIFIED) &&
+ !(cap & CAP_CHARSUBSETTING)))
+ continue;
+ }
+
+ if ((alias_behavior & IGNORE_SCALABLE_ALIASES) &&
+ fname->type == FONT_ENTRY_ALIAS)
+ {
+ FontScalableRec tmpvals;
+ if (FontParseXLFDName (fname->name.name, &tmpvals,
+ FONT_XLFD_REPLACE_NONE) &&
+ !(tmpvals.values_supplied & SIZE_SPECIFY_MASK))
+ continue;
+ }
+
+ ret = AddFontNamesName(names, fname->name.name, fname->name.length);
+ if (ret != Successful)
+ goto bail;
+
+ /* If alias_behavior is LIST_ALIASES_AND_TARGET_NAMES, mark
+ this entry as an alias by negating its length and follow
+ it by the resolved name */
+ if ((alias_behavior & LIST_ALIASES_AND_TARGET_NAMES) &&
+ fname->type == FONT_ENTRY_ALIAS)
+ {
+ names->length[names->nnames - 1] =
+ -names->length[names->nnames - 1];
+ ret = AddFontNamesName(names, fname->u.alias.resolved,
+ strlen(fname->u.alias.resolved));
+ if (ret != Successful)
+ goto bail;
+ }
+
+ if (--max <= 0)
+ break;
+ } else if (res < 0)
+ break;
+ }
+ bail: ;
+ if (newmax) *newmax = max;
+ return ret;
+}
+
+int
+FontFileFindNamesInDir(FontTablePtr table, FontNamePtr pat,
+ int max, FontNamesPtr names)
+{
+ return FontFileFindNamesInScalableDir(table, pat, max, names,
+ (FontScalablePtr)0,
+ NORMAL_ALIAS_BEHAVIOR, (int *)0);
+}
+
+Bool
+FontFileMatchName(char *name, int length, FontNamePtr pat)
+{
+ /* Perform a fontfile-type name match on a single name */
+ FontTableRec table;
+ FontEntryRec entries[1];
+
+ /* Dummy up a table */
+ table.used = 1;
+ table.size = 1;
+ table.sorted = TRUE;
+ table.entries = entries;
+ entries[0].name.name = name;
+ entries[0].name.length = length;
+ entries[0].name.ndashes = FontFileCountDashes(name, length);
+
+ return FontFileFindNameInDir(&table, pat) != (FontEntryPtr)0;
+}
+
+/*
+ * Add a font file to a directory. This handles bitmap and
+ * scalable names both
+ */
+
+Bool
+FontFileAddFontFile (FontDirectoryPtr dir, char *fontName, char *fileName)
+{
+ FontEntryRec entry;
+ FontScalableRec vals, zeroVals;
+ FontRendererPtr renderer;
+ FontEntryPtr existing;
+ FontScalableExtraPtr extra;
+ FontEntryPtr bitmap = 0, scalable;
+ Bool isscale;
+ Bool scalable_xlfd;
+
+ renderer = FontFileMatchRenderer (fileName);
+ if (!renderer)
+ return FALSE;
+ entry.name.length = strlen (fontName);
+ if (entry.name.length > MAXFONTNAMELEN)
+ entry.name.length = MAXFONTNAMELEN;
+ entry.name.name = fontName;
+ CopyISOLatin1Lowered (entry.name.name, fontName, entry.name.length);
+ entry.name.ndashes = FontFileCountDashes (entry.name.name, entry.name.length);
+ entry.name.name[entry.name.length] = '\0';
+ /*
+ * Add a bitmap name if the incoming name isn't an XLFD name, or
+ * if it isn't a scalable name (i.e. non-zero scalable fields)
+ *
+ * If name of bitmapped font contains XLFD enhancements, do not add
+ * a scalable version of the name... this can lead to confusion and
+ * ambiguity between the font name and the field enhancements.
+ */
+ isscale = entry.name.ndashes == 14 &&
+ FontParseXLFDName(entry.name.name,
+ &vals, FONT_XLFD_REPLACE_NONE) &&
+ (vals.values_supplied & PIXELSIZE_MASK) != PIXELSIZE_ARRAY &&
+ (vals.values_supplied & POINTSIZE_MASK) != POINTSIZE_ARRAY &&
+ !(vals.values_supplied & ENHANCEMENT_SPECIFY_MASK);
+#define UNSCALED_ATTRIB "unscaled"
+ scalable_xlfd = (isscale &&
+ (((vals.values_supplied & PIXELSIZE_MASK) == 0) ||
+ ((vals.values_supplied & POINTSIZE_MASK) == 0)));
+ /*
+ * For scalable fonts without a scalable XFLD, check if the "unscaled"
+ * attribute is present.
+ */
+ if (isscale && !scalable_xlfd &&
+ dir->attributes && dir->attributes[0] == ':') {
+ char *ptr1 = dir->attributes + 1;
+ char *ptr2;
+ int length;
+ int uslength = strlen(UNSCALED_ATTRIB);
+
+ do {
+ ptr2 = strchr(ptr1, ':');
+ if (ptr2)
+ length = ptr2 - ptr1;
+ else
+ length = dir->attributes + strlen(dir->attributes) - ptr1;
+ if (length == uslength && !strncmp(ptr1, UNSCALED_ATTRIB, uslength))
+ isscale = FALSE;
+ if (ptr2)
+ ptr1 = ptr2 + 1;
+ } while (ptr2);
+ }
+ if (!isscale || (vals.values_supplied & SIZE_SPECIFY_MASK))
+ {
+ /*
+ * If the renderer doesn't support OpenBitmap, FontFileOpenFont
+ * will still do the right thing.
+ */
+ entry.type = FONT_ENTRY_BITMAP;
+ entry.u.bitmap.renderer = renderer;
+ entry.u.bitmap.pFont = NullFont;
+ if (!(entry.u.bitmap.fileName = FontFileSaveString (fileName)))
+ return FALSE;
+ if (!(bitmap = FontFileAddEntry (&dir->nonScalable, &entry)))
+ {
+ xfree (entry.u.bitmap.fileName);
+ return FALSE;
+ }
+ }
+ /*
+ * Parse out scalable fields from XLFD names - a scalable name
+ * just gets inserted, a scaled name has more things to do.
+ */
+ if (isscale)
+ {
+ if (vals.values_supplied & SIZE_SPECIFY_MASK)
+ {
+ bzero((char *)&zeroVals, sizeof(zeroVals));
+ zeroVals.x = vals.x;
+ zeroVals.y = vals.y;
+ zeroVals.values_supplied = PIXELSIZE_SCALAR | POINTSIZE_SCALAR;
+ FontParseXLFDName (entry.name.name, &zeroVals,
+ FONT_XLFD_REPLACE_VALUE);
+ entry.name.length = strlen (entry.name.name);
+ existing = FontFileFindNameInDir (&dir->scalable, &entry.name);
+ if (existing)
+ {
+ if ((vals.values_supplied & POINTSIZE_MASK) ==
+ POINTSIZE_SCALAR &&
+ (int)(vals.point_matrix[3] * 10) == GetDefaultPointSize())
+ {
+ existing->u.scalable.extra->defaults = vals;
+
+ xfree (existing->u.scalable.fileName);
+ if (!(existing->u.scalable.fileName = FontFileSaveString (fileName)))
+ return FALSE;
+ }
+ if(bitmap)
+ {
+ FontFileCompleteXLFD(&vals, &vals);
+ FontFileAddScaledInstance (existing, &vals, NullFont,
+ bitmap->name.name);
+ return TRUE;
+ }
+ }
+ }
+ if (!(entry.u.scalable.fileName = FontFileSaveString (fileName)))
+ return FALSE;
+ extra = (FontScalableExtraPtr) xalloc (sizeof (FontScalableExtraRec));
+ if (!extra)
+ {
+ xfree (entry.u.scalable.fileName);
+ return FALSE;
+ }
+ bzero((char *)&extra->defaults, sizeof(extra->defaults));
+ if ((vals.values_supplied & POINTSIZE_MASK) == POINTSIZE_SCALAR &&
+ (int)(vals.point_matrix[3] * 10) == GetDefaultPointSize())
+ extra->defaults = vals;
+ else
+ {
+ FontResolutionPtr resolution;
+ int num;
+
+ extra->defaults.point_matrix[0] =
+ extra->defaults.point_matrix[3] =
+ (double)GetDefaultPointSize() / 10.0;
+ extra->defaults.point_matrix[1] =
+ extra->defaults.point_matrix[2] = 0.0;
+ extra->defaults.values_supplied =
+ POINTSIZE_SCALAR | PIXELSIZE_UNDEFINED;
+ extra->defaults.width = -1;
+ if (vals.x <= 0 || vals.y <= 0)
+ {
+ resolution = GetClientResolutions (&num);
+ if (resolution && num > 0)
+ {
+ extra->defaults.x = resolution->x_resolution;
+ extra->defaults.y = resolution->y_resolution;
+ }
+ else
+ {
+ extra->defaults.x = 75;
+ extra->defaults.y = 75;
+ }
+ }
+ else
+ {
+ extra->defaults.x = vals.x;
+ extra->defaults.y = vals.y;
+ }
+ FontFileCompleteXLFD (&extra->defaults, &extra->defaults);
+ }
+ extra->numScaled = 0;
+ extra->sizeScaled = 0;
+ extra->scaled = 0;
+ extra->private = 0;
+ entry.type = FONT_ENTRY_SCALABLE;
+ entry.u.scalable.renderer = renderer;
+ entry.u.scalable.extra = extra;
+ if (!(scalable = FontFileAddEntry (&dir->scalable, &entry)))
+ {
+ xfree (extra);
+ xfree (entry.u.scalable.fileName);
+ return FALSE;
+ }
+ if (vals.values_supplied & SIZE_SPECIFY_MASK)
+ {
+ if(bitmap)
+ {
+ FontFileCompleteXLFD(&vals, &vals);
+ FontFileAddScaledInstance (scalable, &vals, NullFont,
+ bitmap->name.name);
+ }
+ }
+ }
+ return TRUE;
+}
+
+Bool
+FontFileAddFontAlias (FontDirectoryPtr dir, char *aliasName, char *fontName)
+{
+ FontEntryRec entry;
+
+ if (strcmp(aliasName,fontName) == 0) {
+ /* Don't allow an alias to point to itself and create a loop */
+ return FALSE;
+ }
+ entry.name.length = strlen (aliasName);
+ CopyISOLatin1Lowered (aliasName, aliasName, entry.name.length);
+ entry.name.name = aliasName;
+ entry.name.ndashes = FontFileCountDashes (entry.name.name, entry.name.length);
+ entry.type = FONT_ENTRY_ALIAS;
+ if (!(entry.u.alias.resolved = FontFileSaveString (fontName)))
+ return FALSE;
+ if (!FontFileAddEntry (&dir->nonScalable, &entry))
+ {
+ xfree (entry.u.alias.resolved);
+ return FALSE;
+ }
+ return TRUE;
+}
diff --git a/libXfont/src/fontfile/fontencc.c b/libXfont/src/fontfile/fontencc.c
new file mode 100644
index 000000000..b54079acf
--- /dev/null
+++ b/libXfont/src/fontfile/fontencc.c
@@ -0,0 +1,77 @@
+/*
+Copyright (c) 1998-2001 by Juliusz Chroboczek
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
+*/
+/* $XFree86: xc/lib/font/fontfile/fontencc.c,v 1.1 2001/08/13 21:46:47 dawes Exp $ */
+
+/* Binary compatibility code. */
+
+/* This file includes code to make modules compiled for earlier
+ versions of the fontenc interfaces link with this one. It does
+ *not* provide source compatibility, as many of the data structures
+ now have different names. */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include <X11/fonts/fontenc.h>
+#include <X11/fonts/fontencc.h>
+
+extern void ErrorF(const char *f, ...);
+
+char *
+font_encoding_from_xlfd(const char * name, int length)
+{
+ return FontEncFromXLFD(name, length);
+}
+
+FontEncPtr
+font_encoding_find(const char *encoding_name, const char *filename)
+{
+ return FontEncFind(encoding_name, filename);
+}
+
+unsigned
+font_encoding_recode(unsigned code,
+ FontEncPtr encoding, FontMapPtr mapping)
+{
+ if(encoding != mapping->encoding) {
+ ErrorF("Inconsistent mapping/encoding\n");
+ return 0;
+ }
+ return FontEncRecode(code, mapping);
+}
+
+char *
+font_encoding_name(unsigned code,
+ FontEncPtr encoding, FontMapPtr mapping)
+{
+ if(encoding != mapping->encoding) {
+ ErrorF("Inconsistent mapping/encoding\n");
+ return 0;
+ }
+ return FontEncName(code, mapping);
+}
+
+char **
+identifyEncodingFile(const char *filename)
+{
+ return FontEncIdentify(filename);
+}
diff --git a/libXfont/src/fontfile/fontfile.c b/libXfont/src/fontfile/fontfile.c
new file mode 100644
index 000000000..f900f7508
--- /dev/null
+++ b/libXfont/src/fontfile/fontfile.c
@@ -0,0 +1,1152 @@
+/* $XdotOrg: xc/lib/font/fontfile/fontfile.c,v 1.4 2005/07/03 07:01:00 daniels Exp $ */
+/* $Xorg: fontfile.c,v 1.4 2001/02/09 02:04:03 xorgcvs Exp $ */
+
+/*
+
+Copyright 1991, 1998 The Open Group
+
+Permission to use, copy, modify, distribute, and sell this software and its
+documentation for any purpose is hereby granted without fee, provided that
+the above copyright notice appear in all copies and that both that
+copyright notice and this permission notice appear in supporting
+documentation.
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of The Open Group shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from The Open Group.
+
+*/
+/* $XFree86: xc/lib/font/fontfile/fontfile.c,v 3.21 2003/12/02 19:50:40 dawes Exp $ */
+
+/*
+ * Author: Keith Packard, MIT X Consortium
+ */
+/* $NCDXorg: @(#)fontfile.c,v 1.6 1991/07/02 17:00:46 lemke Exp $ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include <X11/fonts/fntfilst.h>
+#ifdef WIN32
+#include <ctype.h>
+#endif
+
+/*
+ * Map FPE functions to renderer functions
+ */
+
+static int FontFileOpenBitmapNCF (FontPathElementPtr fpe, FontPtr *pFont,
+ int flags, FontEntryPtr entry,
+ fsBitmapFormat format,
+ fsBitmapFormatMask fmask,
+ FontPtr non_cachable_font);
+
+int
+FontFileNameCheck (char *name)
+{
+#ifndef NCD
+#if defined(__UNIXOS2__) || defined(WIN32)
+ /* OS/2 uses D:/... as a path name for fonts, so accept this as a valid
+ * path if it starts with a letter and a colon. Same applies for WIN32
+ */
+ if (isalpha(*name) && name[1]==':')
+ return TRUE;
+#endif
+ return *name == '/';
+#else
+ return ((strcmp(name, "built-ins") == 0) || (*name == '/'));
+#endif
+}
+
+int
+FontFileInitFPE (FontPathElementPtr fpe)
+{
+ int status;
+ FontDirectoryPtr dir;
+
+ status = FontFileReadDirectory (fpe->name, &dir);
+ if (status == Successful)
+ {
+ if (dir->nonScalable.used > 0)
+ if (!FontFileRegisterBitmapSource (fpe))
+ {
+ FontFileFreeFPE (fpe);
+ return AllocError;
+ }
+ fpe->private = (pointer) dir;
+ }
+ return status;
+}
+
+/* ARGSUSED */
+int
+FontFileResetFPE (FontPathElementPtr fpe)
+{
+ FontDirectoryPtr dir;
+
+ dir = (FontDirectoryPtr) fpe->private;
+ /*
+ * The reset must fail for bitmap fonts because they get cleared when
+ * the path is set.
+ */
+ if (FontFileDirectoryChanged (dir))
+ {
+ /* can't do it, so tell the caller to close and re-open */
+ return FPEResetFailed;
+ }
+ else
+ {
+ if (dir->nonScalable.used > 0)
+ if (!FontFileRegisterBitmapSource (fpe))
+ {
+ return FPEResetFailed;
+ }
+ return Successful;
+ }
+}
+
+int
+FontFileFreeFPE (FontPathElementPtr fpe)
+{
+ FontFileUnregisterBitmapSource (fpe);
+ FontFileFreeDir ((FontDirectoryPtr) fpe->private);
+ return Successful;
+}
+
+static int
+transfer_values_to_alias(char *entryname, int entrynamelength,
+ char *resolvedname,
+ char **aliasName, FontScalablePtr vals)
+{
+ static char aliasname[MAXFONTNAMELEN];
+ int nameok = 1, len;
+ char lowerName[MAXFONTNAMELEN];
+
+ *aliasName = resolvedname;
+ if ((len = strlen(*aliasName)) <= MAXFONTNAMELEN &&
+ (entrynamelength < MAXFONTNAMELEN) &&
+ FontFileCountDashes (*aliasName, len) == 14)
+ {
+ FontScalableRec tmpVals;
+ FontScalableRec tmpVals2;
+
+ tmpVals2 = *vals;
+
+ /* If we're aliasing a scalable name, transfer values
+ from the name into the destination alias, multiplying
+ by matrices that appear in the alias. */
+
+ CopyISOLatin1Lowered (lowerName, entryname,
+ entrynamelength);
+ lowerName[entrynamelength] = '\0';
+
+ if (FontParseXLFDName(lowerName, &tmpVals,
+ FONT_XLFD_REPLACE_NONE) &&
+ !tmpVals.values_supplied &&
+ FontParseXLFDName(*aliasName, &tmpVals,
+ FONT_XLFD_REPLACE_NONE))
+ {
+ double *matrix = 0, tempmatrix[4];
+
+ /* Use a matrix iff exactly one is defined */
+ if ((tmpVals.values_supplied & PIXELSIZE_MASK) ==
+ PIXELSIZE_ARRAY &&
+ !(tmpVals.values_supplied & POINTSIZE_MASK))
+ matrix = tmpVals.pixel_matrix;
+ else if ((tmpVals.values_supplied & POINTSIZE_MASK) ==
+ POINTSIZE_ARRAY &&
+ !(tmpVals.values_supplied & PIXELSIZE_MASK))
+ matrix = tmpVals.point_matrix;
+
+ /* If matrix given in the alias, compute new point
+ and/or pixel matrices */
+ if (matrix)
+ {
+ /* Complete the XLFD name to avoid potential
+ gotchas */
+ if (FontFileCompleteXLFD(&tmpVals2, &tmpVals2))
+ {
+ tempmatrix[0] =
+ matrix[0] * tmpVals2.point_matrix[0] +
+ matrix[1] * tmpVals2.point_matrix[2];
+ tempmatrix[1] =
+ matrix[0] * tmpVals2.point_matrix[1] +
+ matrix[1] * tmpVals2.point_matrix[3];
+ tempmatrix[2] =
+ matrix[2] * tmpVals2.point_matrix[0] +
+ matrix[3] * tmpVals2.point_matrix[2];
+ tempmatrix[3] =
+ matrix[2] * tmpVals2.point_matrix[1] +
+ matrix[3] * tmpVals2.point_matrix[3];
+ tmpVals2.point_matrix[0] = tempmatrix[0];
+ tmpVals2.point_matrix[1] = tempmatrix[1];
+ tmpVals2.point_matrix[2] = tempmatrix[2];
+ tmpVals2.point_matrix[3] = tempmatrix[3];
+
+ tempmatrix[0] =
+ matrix[0] * tmpVals2.pixel_matrix[0] +
+ matrix[1] * tmpVals2.pixel_matrix[2];
+ tempmatrix[1] =
+ matrix[0] * tmpVals2.pixel_matrix[1] +
+ matrix[1] * tmpVals2.pixel_matrix[3];
+ tempmatrix[2] =
+ matrix[2] * tmpVals2.pixel_matrix[0] +
+ matrix[3] * tmpVals2.pixel_matrix[2];
+ tempmatrix[3] =
+ matrix[2] * tmpVals2.pixel_matrix[1] +
+ matrix[3] * tmpVals2.pixel_matrix[3];
+ tmpVals2.pixel_matrix[0] = tempmatrix[0];
+ tmpVals2.pixel_matrix[1] = tempmatrix[1];
+ tmpVals2.pixel_matrix[2] = tempmatrix[2];
+ tmpVals2.pixel_matrix[3] = tempmatrix[3];
+
+ tmpVals2.values_supplied =
+ (tmpVals2.values_supplied &
+ ~(PIXELSIZE_MASK | POINTSIZE_MASK)) |
+ PIXELSIZE_ARRAY | POINTSIZE_ARRAY;
+ }
+ else
+ nameok = 0;
+ }
+
+ CopyISOLatin1Lowered (aliasname, *aliasName, len + 1);
+ if (nameok && FontParseXLFDName(aliasname, &tmpVals2,
+ FONT_XLFD_REPLACE_VALUE))
+ /* Return a version of the aliasname that has
+ had the vals stuffed into it. To avoid
+ memory leak, this alias name lives in a
+ static buffer. The caller needs to be done
+ with this buffer before this procedure is
+ called again to avoid reentrancy problems. */
+ *aliasName = aliasname;
+ }
+ }
+ return nameok;
+}
+
+/* ARGSUSED */
+int
+FontFileOpenFont (pointer client, FontPathElementPtr fpe, Mask flags,
+ char *name, int namelen,
+ fsBitmapFormat format, fsBitmapFormatMask fmask,
+ XID id, FontPtr *pFont, char **aliasName,
+ FontPtr non_cachable_font)
+{
+ FontDirectoryPtr dir;
+ char lowerName[MAXFONTNAMELEN];
+ char fileName[MAXFONTFILENAMELEN*2 + 1];
+ FontNameRec tmpName;
+ FontEntryPtr entry;
+ FontScalableRec vals;
+ FontScalableEntryPtr scalable;
+ FontScaledPtr scaled;
+ FontBitmapEntryPtr bitmap;
+ int ret;
+ Bool noSpecificSize;
+ int nranges;
+ fsRange *ranges;
+
+ if (namelen >= MAXFONTNAMELEN)
+ return AllocError;
+ dir = (FontDirectoryPtr) fpe->private;
+
+ /* Match non-scalable pattern */
+ CopyISOLatin1Lowered (lowerName, name, namelen);
+ lowerName[namelen] = '\0';
+ ranges = FontParseRanges(lowerName, &nranges);
+ tmpName.name = lowerName;
+ tmpName.length = namelen;
+ tmpName.ndashes = FontFileCountDashes (lowerName, namelen);
+ if (!FontParseXLFDName(lowerName, &vals, FONT_XLFD_REPLACE_NONE))
+ bzero(&vals, sizeof(vals));
+ if (!(entry = FontFileFindNameInDir (&dir->nonScalable, &tmpName)) &&
+ tmpName.ndashes == 14 &&
+ FontParseXLFDName (lowerName, &vals, FONT_XLFD_REPLACE_ZERO))
+ {
+ tmpName.length = strlen(lowerName);
+ entry = FontFileFindNameInDir (&dir->nonScalable, &tmpName);
+ }
+
+ if (entry)
+ {
+ switch (entry->type) {
+ case FONT_ENTRY_BITMAP:
+ bitmap = &entry->u.bitmap;
+ if (bitmap->pFont)
+ {
+ *pFont = bitmap->pFont;
+ (*pFont)->fpe = fpe;
+ ret = Successful;
+ }
+ else
+ {
+ ret = FontFileOpenBitmapNCF (fpe, pFont, flags, entry, format,
+ fmask, non_cachable_font);
+ if (ret == Successful && *pFont)
+ (*pFont)->fpe = fpe;
+ }
+ break;
+ case FONT_ENTRY_ALIAS:
+ vals.nranges = nranges;
+ vals.ranges = ranges;
+ transfer_values_to_alias(entry->name.name, entry->name.length,
+ entry->u.alias.resolved, aliasName, &vals);
+ ret = FontNameAlias;
+ break;
+#ifdef NOTYET
+ case FONT_ENTRY_BC:
+ bc = &entry->u.bc;
+ entry = bc->entry;
+ ret = (*scalable->renderer->OpenScalable)
+ (fpe, pFont, flags, entry, &bc->vals, format, fmask,
+ non_cachable_font);
+ if (ret == Successful && *pFont)
+ (*pFont)->fpe = fpe;
+ break;
+#endif
+ default:
+ ret = BadFontName;
+ }
+ }
+ else
+ {
+ ret = BadFontName;
+ }
+
+ if (ret != BadFontName)
+ {
+ if (ranges) xfree(ranges);
+ return ret;
+ }
+
+ /* Match XLFD patterns */
+ CopyISOLatin1Lowered (lowerName, name, namelen);
+ lowerName[namelen] = '\0';
+ tmpName.name = lowerName;
+ tmpName.length = namelen;
+ tmpName.ndashes = FontFileCountDashes (lowerName, namelen);
+ if (!FontParseXLFDName (lowerName, &vals, FONT_XLFD_REPLACE_ZERO) ||
+ !(tmpName.length = strlen (lowerName),
+ entry = FontFileFindNameInScalableDir (&dir->scalable, &tmpName,
+ &vals))) {
+ CopyISOLatin1Lowered (lowerName, name, namelen);
+ lowerName[namelen] = '\0';
+ tmpName.name = lowerName;
+ tmpName.length = namelen;
+ tmpName.ndashes = FontFileCountDashes (lowerName, namelen);
+ entry = FontFileFindNameInScalableDir (&dir->scalable, &tmpName, &vals);
+ if (entry)
+ {
+ strcpy(lowerName, entry->name.name);
+ tmpName.name = lowerName;
+ tmpName.length = entry->name.length;
+ tmpName.ndashes = entry->name.ndashes;
+ }
+ }
+
+ if (entry)
+ {
+ noSpecificSize = FALSE; /* TRUE breaks XLFD enhancements */
+ if (entry->type == FONT_ENTRY_SCALABLE &&
+ FontFileCompleteXLFD (&vals, &entry->u.scalable.extra->defaults))
+ {
+ scalable = &entry->u.scalable;
+ if ((vals.values_supplied & PIXELSIZE_MASK) == PIXELSIZE_ARRAY ||
+ (vals.values_supplied & POINTSIZE_MASK) == POINTSIZE_ARRAY ||
+ (vals.values_supplied &
+ ~SIZE_SPECIFY_MASK & ~CHARSUBSET_SPECIFIED))
+ scaled = 0;
+ else
+ scaled = FontFileFindScaledInstance (entry, &vals,
+ noSpecificSize);
+ /*
+ * A scaled instance can occur one of two ways:
+ *
+ * Either the font has been scaled to this
+ * size already, in which case scaled->pFont
+ * will point at that font.
+ *
+ * Or a bitmap instance in this size exists,
+ * which is handled as if we got a pattern
+ * matching the bitmap font name.
+ */
+ if (scaled)
+ {
+ if (scaled->pFont)
+ {
+ *pFont = scaled->pFont;
+ (*pFont)->fpe = fpe;
+ ret = Successful;
+ }
+ else if (scaled->bitmap)
+ {
+ entry = scaled->bitmap;
+ bitmap = &entry->u.bitmap;
+ if (bitmap->pFont)
+ {
+ *pFont = bitmap->pFont;
+ (*pFont)->fpe = fpe;
+ ret = Successful;
+ }
+ else
+ {
+ ret = FontFileOpenBitmapNCF (fpe, pFont, flags, entry,
+ format, fmask,
+ non_cachable_font);
+ if (ret == Successful && *pFont)
+ (*pFont)->fpe = fpe;
+ }
+ }
+ else /* "cannot" happen */
+ {
+ ret = BadFontName;
+ }
+ }
+ else
+ {
+ ret = FontFileMatchBitmapSource (fpe, pFont, flags, entry, &tmpName, &vals, format, fmask, noSpecificSize);
+ if (ret != Successful)
+ {
+ char origName[MAXFONTNAMELEN];
+
+ CopyISOLatin1Lowered (origName, name, namelen);
+ origName[namelen] = '\0';
+
+ /* Pass the original XLFD name in the vals
+ structure; the rasterizer is free to examine it
+ for hidden meanings. This information will not
+ be saved in the scaled-instances table. */
+
+ vals.xlfdName = origName;
+ vals.ranges = ranges;
+ vals.nranges = nranges;
+
+ if (strlen(dir->directory) + strlen(scalable->fileName) >=
+ sizeof(fileName)) {
+ ret = BadFontName;
+ } else {
+ strcpy (fileName, dir->directory);
+ strcat (fileName, scalable->fileName);
+ if (scalable->renderer->OpenScalable) {
+ ret = (*scalable->renderer->OpenScalable) (fpe, pFont,
+ flags, entry, fileName, &vals, format, fmask,
+ non_cachable_font);
+ }
+ else if (scalable->renderer->OpenBitmap) {
+ ret = (*scalable->renderer->OpenBitmap) (fpe, pFont,
+ flags, entry, fileName, format, fmask,
+ non_cachable_font);
+ }
+ }
+
+ /* In case rasterizer does something bad because of
+ charset subsetting... */
+ if (ret == Successful &&
+ ((*pFont)->info.firstCol > (*pFont)->info.lastCol ||
+ (*pFont)->info.firstRow > (*pFont)->info.lastRow))
+ {
+ (*(*pFont)->unload_font)(*pFont);
+ ret = BadFontName;
+ }
+ /* Save the instance */
+ if (ret == Successful)
+ {
+ if (FontFileAddScaledInstance (entry, &vals,
+ *pFont, (char *) 0))
+ ranges = 0;
+ else
+ (*pFont)->fpePrivate = (pointer) 0;
+ (*pFont)->fpe = fpe;
+ }
+ }
+ }
+ }
+ }
+ else
+ ret = BadFontName;
+
+ if (ranges)
+ xfree(ranges);
+ return ret;
+}
+
+/* ARGSUSED */
+void
+FontFileCloseFont (FontPathElementPtr fpe, FontPtr pFont)
+{
+ FontEntryPtr entry;
+
+ if ((entry = (FontEntryPtr) pFont->fpePrivate)) {
+ switch (entry->type) {
+ case FONT_ENTRY_SCALABLE:
+ FontFileRemoveScaledInstance (entry, pFont);
+ break;
+ case FONT_ENTRY_BITMAP:
+ entry->u.bitmap.pFont = 0;
+ break;
+ default:
+ /* "cannot" happen */
+ break;
+ }
+ pFont->fpePrivate = 0;
+ }
+ (*pFont->unload_font) (pFont);
+}
+
+static int
+FontFileOpenBitmapNCF (FontPathElementPtr fpe, FontPtr *pFont,
+ int flags, FontEntryPtr entry,
+ fsBitmapFormat format, fsBitmapFormatMask fmask,
+ FontPtr non_cachable_font)
+{
+ FontBitmapEntryPtr bitmap;
+ char fileName[MAXFONTFILENAMELEN*2+1];
+ int ret;
+ FontDirectoryPtr dir;
+
+ dir = (FontDirectoryPtr) fpe->private;
+ bitmap = &entry->u.bitmap;
+ if(!bitmap || !bitmap->renderer->OpenBitmap)
+ return BadFontName;
+ if (strlen(dir->directory) + strlen(bitmap->fileName) >= sizeof(fileName))
+ return BadFontName;
+ strcpy (fileName, dir->directory);
+ strcat (fileName, bitmap->fileName);
+ ret = (*bitmap->renderer->OpenBitmap)
+ (fpe, pFont, flags, entry, fileName, format, fmask,
+ non_cachable_font);
+ if (ret == Successful)
+ {
+ bitmap->pFont = *pFont;
+ (*pFont)->fpePrivate = (pointer) entry;
+ }
+ return ret;
+}
+
+int
+FontFileOpenBitmap (FontPathElementPtr fpe, FontPtr *pFont,
+ int flags, FontEntryPtr entry,
+ fsBitmapFormat format, fsBitmapFormatMask fmask)
+{
+ return FontFileOpenBitmapNCF (fpe, pFont, flags, entry, format, fmask,
+ (FontPtr)0);
+}
+
+static int
+FontFileGetInfoBitmap (FontPathElementPtr fpe, FontInfoPtr pFontInfo,
+ FontEntryPtr entry)
+{
+ FontBitmapEntryPtr bitmap;
+ char fileName[MAXFONTFILENAMELEN*2+1];
+ int ret;
+ FontDirectoryPtr dir;
+
+ dir = (FontDirectoryPtr) fpe->private;
+ bitmap = &entry->u.bitmap;
+ if (!bitmap || !bitmap->renderer->GetInfoBitmap)
+ return BadFontName;
+ if (strlen(dir->directory) + strlen(bitmap->fileName) >= sizeof(fileName))
+ return BadFontName;
+ strcpy (fileName, dir->directory);
+ strcat (fileName, bitmap->fileName);
+ ret = (*bitmap->renderer->GetInfoBitmap) (fpe, pFontInfo, entry, fileName);
+ return ret;
+}
+
+static void
+_FontFileAddScalableNames(FontNamesPtr names, FontNamesPtr scaleNames,
+ FontNamePtr nameptr, char *zeroChars,
+ FontScalablePtr vals, fsRange *ranges,
+ int nranges, int *max)
+{
+ int i;
+ FontScalableRec zeroVals, tmpVals;
+ for (i = 0; i < scaleNames->nnames; i++)
+ {
+ char nameChars[MAXFONTNAMELEN];
+ if (!*max)
+ return;
+ FontParseXLFDName (scaleNames->names[i], &zeroVals,
+ FONT_XLFD_REPLACE_NONE);
+ tmpVals = *vals;
+ if (FontFileCompleteXLFD (&tmpVals, &zeroVals))
+ {
+ --*max;
+
+ strcpy (nameChars, scaleNames->names[i]);
+ if ((vals->values_supplied & PIXELSIZE_MASK) ||
+ !(vals->values_supplied & PIXELSIZE_WILDCARD) ||
+ vals->y == 0)
+ {
+ tmpVals.values_supplied =
+ (tmpVals.values_supplied & ~PIXELSIZE_MASK) |
+ (vals->values_supplied & PIXELSIZE_MASK);
+ tmpVals.pixel_matrix[0] = vals->pixel_matrix[0];
+ tmpVals.pixel_matrix[1] = vals->pixel_matrix[1];
+ tmpVals.pixel_matrix[2] = vals->pixel_matrix[2];
+ tmpVals.pixel_matrix[3] = vals->pixel_matrix[3];
+ }
+ if ((vals->values_supplied & POINTSIZE_MASK) ||
+ !(vals->values_supplied & POINTSIZE_WILDCARD) ||
+ vals->y == 0)
+ {
+ tmpVals.values_supplied =
+ (tmpVals.values_supplied & ~POINTSIZE_MASK) |
+ (vals->values_supplied & POINTSIZE_MASK);
+ tmpVals.point_matrix[0] = vals->point_matrix[0];
+ tmpVals.point_matrix[1] = vals->point_matrix[1];
+ tmpVals.point_matrix[2] = vals->point_matrix[2];
+ tmpVals.point_matrix[3] = vals->point_matrix[3];
+ }
+ if (vals->width <= 0)
+ tmpVals.width = 0;
+ if (vals->x == 0)
+ tmpVals.x = 0;
+ if (vals->y == 0)
+ tmpVals.y = 0;
+ tmpVals.ranges = ranges;
+ tmpVals.nranges = nranges;
+ FontParseXLFDName (nameChars, &tmpVals,
+ FONT_XLFD_REPLACE_VALUE);
+ /* If we're marking aliases with negative lengths, we
+ need to concoct a valid target name to follow it.
+ Otherwise we're done. */
+ if (scaleNames->length[i] >= 0)
+ {
+ (void) AddFontNamesName (names, nameChars,
+ strlen (nameChars));
+ /* If our original pattern matches the name from
+ the table and that name doesn't duplicate what
+ we just added, add the name from the table */
+ if (strcmp(nameChars, scaleNames->names[i]) &&
+ FontFileMatchName(scaleNames->names[i],
+ scaleNames->length[i],
+ nameptr) &&
+ *max)
+ {
+ --*max;
+ (void) AddFontNamesName (names, scaleNames->names[i],
+ scaleNames->length[i]);
+ }
+ }
+ else
+ {
+ char *aliasName;
+ vals->ranges = ranges;
+ vals->nranges = nranges;
+ if (transfer_values_to_alias(zeroChars,
+ strlen(zeroChars),
+ scaleNames->names[++i],
+ &aliasName, vals))
+ {
+ (void) AddFontNamesName (names, nameChars,
+ strlen (nameChars));
+ names->length[names->nnames - 1] =
+ -names->length[names->nnames - 1];
+ (void) AddFontNamesName (names, aliasName,
+ strlen (aliasName));
+ /* If our original pattern matches the name from
+ the table and that name doesn't duplicate what
+ we just added, add the name from the table */
+ if (strcmp(nameChars, scaleNames->names[i - 1]) &&
+ FontFileMatchName(scaleNames->names[i - 1],
+ -scaleNames->length[i - 1],
+ nameptr) &&
+ *max)
+ {
+ --*max;
+ (void) AddFontNamesName (names,
+ scaleNames->names[i - 1],
+ -scaleNames->length[i - 1]);
+ names->length[names->nnames - 1] =
+ -names->length[names->nnames - 1];
+ (void) AddFontNamesName (names, aliasName,
+ strlen (aliasName));
+ }
+ }
+ }
+ }
+ }
+}
+
+/* ARGSUSED */
+static int
+_FontFileListFonts (pointer client, FontPathElementPtr fpe,
+ char *pat, int len, int max, FontNamesPtr names,
+ int mark_aliases)
+{
+ FontDirectoryPtr dir;
+ char lowerChars[MAXFONTNAMELEN], zeroChars[MAXFONTNAMELEN];
+ FontNameRec lowerName;
+ FontNameRec zeroName;
+ FontNamesPtr scaleNames;
+ FontScalableRec vals;
+ fsRange *ranges;
+ int nranges;
+ int result = BadFontName;
+
+ if (len >= MAXFONTNAMELEN)
+ return AllocError;
+ dir = (FontDirectoryPtr) fpe->private;
+ CopyISOLatin1Lowered (lowerChars, pat, len);
+ lowerChars[len] = '\0';
+ lowerName.name = lowerChars;
+ lowerName.length = len;
+ lowerName.ndashes = FontFileCountDashes (lowerChars, len);
+
+ /* Match XLFD patterns */
+
+ strcpy (zeroChars, lowerChars);
+ if (lowerName.ndashes == 14 &&
+ FontParseXLFDName (zeroChars, &vals, FONT_XLFD_REPLACE_ZERO))
+ {
+ ranges = FontParseRanges(lowerChars, &nranges);
+ result = FontFileFindNamesInScalableDir (&dir->nonScalable,
+ &lowerName, max, names,
+ (FontScalablePtr)0,
+ (mark_aliases ?
+ LIST_ALIASES_AND_TARGET_NAMES :
+ NORMAL_ALIAS_BEHAVIOR) |
+ IGNORE_SCALABLE_ALIASES,
+ &max);
+ zeroName.name = zeroChars;
+ zeroName.length = strlen (zeroChars);
+ zeroName.ndashes = lowerName.ndashes;
+
+ /* Look for scalable names and aliases, adding scaled instances of
+ them to the output */
+
+ /* Scalable names... */
+ scaleNames = MakeFontNamesRecord (0);
+ if (!scaleNames)
+ {
+ if (ranges) xfree(ranges);
+ return AllocError;
+ }
+ FontFileFindNamesInScalableDir (&dir->scalable, &zeroName, max,
+ scaleNames, &vals,
+ mark_aliases ?
+ LIST_ALIASES_AND_TARGET_NAMES :
+ NORMAL_ALIAS_BEHAVIOR, (int *)0);
+ _FontFileAddScalableNames(names, scaleNames, &lowerName,
+ zeroChars, &vals, ranges, nranges,
+ &max);
+ FreeFontNames (scaleNames);
+
+ /* Scalable aliases... */
+ scaleNames = MakeFontNamesRecord (0);
+ if (!scaleNames)
+ {
+ if (ranges) xfree(ranges);
+ return AllocError;
+ }
+ FontFileFindNamesInScalableDir (&dir->nonScalable, &zeroName,
+ max, scaleNames, &vals,
+ mark_aliases ?
+ LIST_ALIASES_AND_TARGET_NAMES :
+ NORMAL_ALIAS_BEHAVIOR, (int *)0);
+ _FontFileAddScalableNames(names, scaleNames, &lowerName,
+ zeroChars, &vals, ranges, nranges,
+ &max);
+ FreeFontNames (scaleNames);
+
+ if (ranges) xfree(ranges);
+ }
+ else
+ {
+ result = FontFileFindNamesInScalableDir (&dir->nonScalable,
+ &lowerName, max, names,
+ (FontScalablePtr)0,
+ mark_aliases ?
+ LIST_ALIASES_AND_TARGET_NAMES :
+ NORMAL_ALIAS_BEHAVIOR,
+ &max);
+ if (result == Successful)
+ result = FontFileFindNamesInScalableDir (&dir->scalable,
+ &lowerName, max, names,
+ (FontScalablePtr)0,
+ mark_aliases ?
+ LIST_ALIASES_AND_TARGET_NAMES :
+ NORMAL_ALIAS_BEHAVIOR, (int *)0);
+ }
+ return result;
+}
+
+typedef struct _LFWIData {
+ FontNamesPtr names;
+ int current;
+} LFWIDataRec, *LFWIDataPtr;
+
+int
+FontFileListFonts (pointer client, FontPathElementPtr fpe, char *pat,
+ int len, int max, FontNamesPtr names)
+{
+ return _FontFileListFonts (client, fpe, pat, len, max, names, 0);
+}
+
+int
+FontFileStartListFonts(pointer client, FontPathElementPtr fpe,
+ char *pat, int len, int max,
+ pointer *privatep, int mark_aliases)
+{
+ LFWIDataPtr data;
+ int ret;
+
+ data = (LFWIDataPtr) xalloc (sizeof *data);
+ if (!data)
+ return AllocError;
+ data->names = MakeFontNamesRecord (0);
+ if (!data->names)
+ {
+ xfree (data);
+ return AllocError;
+ }
+ ret = _FontFileListFonts (client, fpe, pat, len,
+ max, data->names, mark_aliases);
+ if (ret != Successful)
+ {
+ FreeFontNames (data->names);
+ xfree (data);
+ return ret;
+ }
+ data->current = 0;
+ *privatep = (pointer) data;
+ return Successful;
+}
+
+
+int
+FontFileStartListFontsWithInfo(pointer client, FontPathElementPtr fpe,
+ char *pat, int len, int max,
+ pointer *privatep)
+{
+ return FontFileStartListFonts(client, fpe, pat, len, max, privatep, 0);
+}
+
+/* ARGSUSED */
+static int
+FontFileListOneFontWithInfo (pointer client, FontPathElementPtr fpe,
+ char **namep, int *namelenp,
+ FontInfoPtr *pFontInfo)
+{
+ FontDirectoryPtr dir;
+ char lowerName[MAXFONTNAMELEN];
+ char fileName[MAXFONTFILENAMELEN*2 + 1];
+ FontNameRec tmpName;
+ FontEntryPtr entry;
+ FontScalableRec vals;
+ FontScalableEntryPtr scalable;
+ FontScaledPtr scaled;
+ FontBitmapEntryPtr bitmap;
+ int ret;
+ Bool noSpecificSize;
+ int nranges;
+ fsRange *ranges;
+
+ char *name = *namep;
+ int namelen = *namelenp;
+
+ if (namelen >= MAXFONTNAMELEN)
+ return AllocError;
+ dir = (FontDirectoryPtr) fpe->private;
+
+ /* Match non-scalable pattern */
+ CopyISOLatin1Lowered (lowerName, name, namelen);
+ lowerName[namelen] = '\0';
+ ranges = FontParseRanges(lowerName, &nranges);
+ tmpName.name = lowerName;
+ tmpName.length = namelen;
+ tmpName.ndashes = FontFileCountDashes (lowerName, namelen);
+ if (!FontParseXLFDName(lowerName, &vals, FONT_XLFD_REPLACE_NONE))
+ bzero(&vals, sizeof(vals));
+ if (!(entry = FontFileFindNameInDir (&dir->nonScalable, &tmpName)) &&
+ tmpName.ndashes == 14 &&
+ FontParseXLFDName (lowerName, &vals, FONT_XLFD_REPLACE_ZERO))
+ {
+ tmpName.length = strlen(lowerName);
+ entry = FontFileFindNameInDir (&dir->nonScalable, &tmpName);
+ }
+
+ if (entry)
+ {
+ switch (entry->type) {
+ case FONT_ENTRY_BITMAP:
+ bitmap = &entry->u.bitmap;
+ if (bitmap->pFont)
+ {
+ *pFontInfo = &bitmap->pFont->info;
+ ret = Successful;
+ }
+ else
+ {
+ ret = FontFileGetInfoBitmap (fpe, *pFontInfo, entry);
+ }
+ break;
+ case FONT_ENTRY_ALIAS:
+ vals.nranges = nranges;
+ vals.ranges = ranges;
+ transfer_values_to_alias(entry->name.name, entry->name.length,
+ entry->u.alias.resolved, namep, &vals);
+ *namelenp = strlen (*namep);
+ ret = FontNameAlias;
+ break;
+#ifdef NOTYET
+ case FONT_ENTRY_BC:
+ /* no LFWI for this yet */
+ bc = &entry->u.bc;
+ entry = bc->entry;
+ /* Make a new scaled instance */
+ if (strlen(dir->directory) + strlen(scalable->fileName) >=
+ sizeof(fileName)) {
+ ret = BadFontName;
+ } else {
+ strcpy (fileName, dir->directory);
+ strcat (fileName, scalable->fileName);
+ ret = (*scalable->renderer->GetInfoScalable)
+ (fpe, *pFontInfo, entry, tmpName, fileName, &bc->vals);
+ }
+ break;
+#endif
+ default:
+ ret = BadFontName;
+ }
+ }
+ else
+ {
+ ret = BadFontName;
+ }
+
+ if (ret != BadFontName)
+ {
+ if (ranges) xfree(ranges);
+ return ret;
+ }
+
+ /* Match XLFD patterns */
+ CopyISOLatin1Lowered (lowerName, name, namelen);
+ lowerName[namelen] = '\0';
+ tmpName.name = lowerName;
+ tmpName.length = namelen;
+ tmpName.ndashes = FontFileCountDashes (lowerName, namelen);
+ if (!FontParseXLFDName (lowerName, &vals, FONT_XLFD_REPLACE_ZERO) ||
+ !(tmpName.length = strlen (lowerName),
+ entry = FontFileFindNameInScalableDir (&dir->scalable, &tmpName,
+ &vals))) {
+ CopyISOLatin1Lowered (lowerName, name, namelen);
+ lowerName[namelen] = '\0';
+ tmpName.name = lowerName;
+ tmpName.length = namelen;
+ tmpName.ndashes = FontFileCountDashes (lowerName, namelen);
+ entry = FontFileFindNameInScalableDir (&dir->scalable, &tmpName, &vals);
+ if (entry)
+ {
+ strcpy(lowerName, entry->name.name);
+ tmpName.name = lowerName;
+ tmpName.length = entry->name.length;
+ tmpName.ndashes = entry->name.ndashes;
+ }
+ }
+
+ if (entry)
+ {
+ noSpecificSize = FALSE; /* TRUE breaks XLFD enhancements */
+ if (entry && entry->type == FONT_ENTRY_SCALABLE &&
+ FontFileCompleteXLFD (&vals, &entry->u.scalable.extra->defaults))
+ {
+ scalable = &entry->u.scalable;
+ scaled = FontFileFindScaledInstance (entry, &vals, noSpecificSize);
+ /*
+ * A scaled instance can occur one of two ways:
+ *
+ * Either the font has been scaled to this
+ * size already, in which case scaled->pFont
+ * will point at that font.
+ *
+ * Or a bitmap instance in this size exists,
+ * which is handled as if we got a pattern
+ * matching the bitmap font name.
+ */
+ if (scaled)
+ {
+ if (scaled->pFont)
+ {
+ *pFontInfo = &scaled->pFont->info;
+ ret = Successful;
+ }
+ else if (scaled->bitmap)
+ {
+ entry = scaled->bitmap;
+ bitmap = &entry->u.bitmap;
+ if (bitmap->pFont)
+ {
+ *pFontInfo = &bitmap->pFont->info;
+ ret = Successful;
+ }
+ else
+ {
+ ret = FontFileGetInfoBitmap (fpe, *pFontInfo, entry);
+ }
+ }
+ else /* "cannot" happen */
+ {
+ ret = BadFontName;
+ }
+ }
+ else
+ {
+#ifdef NOTDEF
+ /* no special case yet */
+ ret = FontFileMatchBitmapSource (fpe, pFont, flags, entry, &vals, format, fmask, noSpecificSize);
+ if (ret != Successful)
+#endif
+ {
+ char origName[MAXFONTNAMELEN];
+
+ CopyISOLatin1Lowered (origName, name, namelen);
+ origName[namelen] = '\0';
+ vals.xlfdName = origName;
+ vals.ranges = ranges;
+ vals.nranges = nranges;
+
+ /* Make a new scaled instance */
+ if (strlen(dir->directory) + strlen(scalable->fileName) >=
+ sizeof(fileName)) {
+ ret = BadFontName;
+ } else {
+ strcpy (fileName, dir->directory);
+ strcat (fileName, scalable->fileName);
+ if (scalable->renderer->GetInfoScalable)
+ ret = (*scalable->renderer->GetInfoScalable)
+ (fpe, *pFontInfo, entry, &tmpName, fileName,
+ &vals);
+ else if (scalable->renderer->GetInfoBitmap)
+ ret = (*scalable->renderer->GetInfoBitmap)
+ (fpe, *pFontInfo, entry, fileName);
+ }
+ if (ranges) {
+ xfree(ranges);
+ ranges = NULL;
+ }
+ }
+ }
+ if (ret == Successful) return ret;
+ }
+ CopyISOLatin1Lowered (lowerName, name, namelen);
+ tmpName.length = namelen;
+ }
+ else
+ ret = BadFontName;
+
+ if (ranges)
+ xfree(ranges);
+ return ret;
+}
+
+int
+FontFileListNextFontWithInfo(pointer client, FontPathElementPtr fpe,
+ char **namep, int *namelenp,
+ FontInfoPtr *pFontInfo,
+ int *numFonts, pointer private)
+{
+ LFWIDataPtr data = (LFWIDataPtr) private;
+ int ret;
+ char *name;
+ int namelen;
+
+ if (data->current == data->names->nnames)
+ {
+ FreeFontNames (data->names);
+ xfree (data);
+ return BadFontName;
+ }
+ name = data->names->names[data->current];
+ namelen = data->names->length[data->current];
+ ret = FontFileListOneFontWithInfo (client, fpe, &name, &namelen, pFontInfo);
+ if (ret == BadFontName)
+ ret = AllocError;
+ *namep = name;
+ *namelenp = namelen;
+ ++data->current;
+ *numFonts = data->names->nnames - data->current;
+ return ret;
+}
+
+int
+FontFileStartListFontsAndAliases(pointer client, FontPathElementPtr fpe,
+ char *pat, int len, int max,
+ pointer *privatep)
+{
+ return FontFileStartListFonts(client, fpe, pat, len, max, privatep, 1);
+}
+
+int
+FontFileListNextFontOrAlias(pointer client, FontPathElementPtr fpe,
+ char **namep, int *namelenp, char **resolvedp,
+ int *resolvedlenp, pointer private)
+{
+ LFWIDataPtr data = (LFWIDataPtr) private;
+ int ret;
+ char *name;
+ int namelen;
+
+ if (data->current == data->names->nnames)
+ {
+ FreeFontNames (data->names);
+ xfree (data);
+ return BadFontName;
+ }
+ name = data->names->names[data->current];
+ namelen = data->names->length[data->current];
+
+ /* If this is a real font name... */
+ if (namelen >= 0)
+ {
+ *namep = name;
+ *namelenp = namelen;
+ ret = Successful;
+ }
+ /* Else if an alias */
+ else
+ {
+ /* Tell the caller that this is an alias... let him resolve it to
+ see if it's valid */
+ *namep = name;
+ *namelenp = -namelen;
+ *resolvedp = data->names->names[++data->current];
+ *resolvedlenp = data->names->length[data->current];
+ ret = FontNameAlias;
+ }
+
+ ++data->current;
+ return ret;
+}
+
+void
+FontFileRegisterLocalFpeFunctions (void)
+{
+ RegisterFPEFunctions(FontFileNameCheck,
+ FontFileInitFPE,
+ FontFileFreeFPE,
+ FontFileResetFPE,
+ FontFileOpenFont,
+ FontFileCloseFont,
+ FontFileListFonts,
+ FontFileStartListFontsWithInfo,
+ FontFileListNextFontWithInfo,
+ NULL,
+ NULL,
+ NULL,
+ FontFileStartListFontsAndAliases,
+ FontFileListNextFontOrAlias,
+ FontFileEmptyBitmapSource);
+}
diff --git a/libXfont/src/fontfile/fontscale.c b/libXfont/src/fontfile/fontscale.c
new file mode 100644
index 000000000..8e9de513d
--- /dev/null
+++ b/libXfont/src/fontfile/fontscale.c
@@ -0,0 +1,447 @@
+/* $Xorg: fontscale.c,v 1.5 2001/02/09 02:04:03 xorgcvs Exp $ */
+
+/*
+
+Copyright 1991, 1998 The Open Group
+
+Permission to use, copy, modify, distribute, and sell this software and its
+documentation for any purpose is hereby granted without fee, provided that
+the above copyright notice appear in all copies and that both that
+copyright notice and this permission notice appear in supporting
+documentation.
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of The Open Group shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from The Open Group.
+
+*/
+/* $XFree86: xc/lib/font/fontfile/fontscale.c,v 3.9 2001/08/27 19:49:54 dawes Exp $ */
+
+/*
+ * Author: Keith Packard, MIT X Consortium
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include <X11/fonts/fntfilst.h>
+#ifdef _XOPEN_SOURCE
+#include <math.h>
+#else
+#define _XOPEN_SOURCE /* to get prototype for hypot on some systems */
+#include <math.h>
+#undef _XOPEN_SOURCE
+#endif
+
+Bool
+FontFileAddScaledInstance (FontEntryPtr entry, FontScalablePtr vals,
+ FontPtr pFont, char *bitmapName)
+{
+ FontScalableEntryPtr scalable;
+ FontScalableExtraPtr extra;
+ FontScaledPtr new;
+ int newsize;
+
+ scalable = &entry->u.scalable;
+ extra = scalable->extra;
+ if (extra->numScaled == extra->sizeScaled)
+ {
+ newsize = extra->sizeScaled + 4;
+ new = (FontScaledPtr) xrealloc (extra->scaled,
+ newsize * sizeof (FontScaledRec));
+ if (!new)
+ return FALSE;
+ extra->sizeScaled = newsize;
+ extra->scaled = new;
+ }
+ new = &extra->scaled[extra->numScaled++];
+ new->vals = *vals;
+ new->pFont = pFont;
+ new->bitmap = (FontEntryPtr) bitmapName;
+ if (pFont)
+ pFont->fpePrivate = (pointer) entry;
+ return TRUE;
+}
+
+/* Must call this after the directory is sorted */
+
+void
+FontFileSwitchStringsToBitmapPointers (FontDirectoryPtr dir)
+{
+ int s;
+ int b;
+ int i;
+ FontEntryPtr scalable;
+ FontEntryPtr nonScalable;
+ FontScaledPtr scaled;
+ FontScalableExtraPtr extra;
+
+ scalable = dir->scalable.entries;
+ nonScalable = dir->nonScalable.entries;
+ for (s = 0; s < dir->scalable.used; s++)
+ {
+ extra = scalable[s].u.scalable.extra;
+ scaled = extra->scaled;
+ for (i = 0; i < extra->numScaled; i++)
+ for (b = 0; b < dir->nonScalable.used; b++)
+ if (nonScalable[b].name.name == (char *) scaled[i].bitmap)
+ scaled[i].bitmap = &nonScalable[b];
+ }
+}
+
+void
+FontFileRemoveScaledInstance (FontEntryPtr entry, FontPtr pFont)
+{
+ FontScalableEntryPtr scalable;
+ FontScalableExtraPtr extra;
+ int i;
+
+ scalable = &entry->u.scalable;
+ extra = scalable->extra;
+ for (i = 0; i < extra->numScaled; i++)
+ {
+ if (extra->scaled[i].pFont == pFont)
+ {
+ if (extra->scaled[i].vals.ranges)
+ xfree (extra->scaled[i].vals.ranges);
+ extra->numScaled--;
+ for (; i < extra->numScaled; i++)
+ extra->scaled[i] = extra->scaled[i+1];
+ }
+ }
+}
+
+Bool
+FontFileCompleteXLFD (FontScalablePtr vals, FontScalablePtr def)
+{
+ FontResolutionPtr res;
+ int num_res;
+ double sx, sy, temp_matrix[4];
+ double pixel_setsize_adjustment = 1.0;
+ /*
+ * If two of the three vertical scale values are specified, compute the
+ * third. If all three are specified, make sure they are consistent
+ * (within a pixel)
+ *
+ * One purpose of this procedure is to complete XLFD names in a
+ * repeatable manner. That is, if the user partially specifies
+ * a name (say, pixelsize but not pointsize), the results generated
+ * here result in a fully specified name that will result in the
+ * same font.
+ */
+
+ res = GetClientResolutions(&num_res);
+
+ if (!(vals->values_supplied & PIXELSIZE_MASK) ||
+ !(vals->values_supplied & POINTSIZE_MASK))
+ {
+ /* If resolution(s) unspecified and cannot be computed from
+ pixelsize and pointsize, get appropriate defaults. */
+
+ if (num_res)
+ {
+ if (vals->x <= 0)
+ vals->x = res->x_resolution;
+ if (vals->y <= 0)
+ vals->y = res->y_resolution;
+ }
+
+ if (vals->x <= 0)
+ vals->x = def->x;
+ if (vals->y <= 0)
+ vals->y = def->y;
+ }
+ else
+ {
+ /* If needed, compute resolution values from the pixel and
+ pointsize information we were given. This problem is
+ overdetermined (four equations, two unknowns), but we don't
+ check for inconsistencies here. If they exist, they will
+ show up in later tests for the point and pixel sizes. */
+
+ if (vals->y <= 0)
+ {
+ double x = hypot(vals->pixel_matrix[1], vals->pixel_matrix[3]);
+ double y = hypot(vals->point_matrix[1], vals->point_matrix[3]);
+ if (y < EPS) return FALSE;
+ vals->y = (int)(x * 72.27 / y + .5);
+ }
+ if (vals->x <= 0)
+ {
+ /* If the pixelsize was given as an array, or as a scalar that
+ has been normalized for the pixel shape, we have enough
+ information to compute a separate horizontal resolution */
+
+ if ((vals->values_supplied & PIXELSIZE_MASK) == PIXELSIZE_ARRAY ||
+ (vals->values_supplied & PIXELSIZE_MASK) ==
+ PIXELSIZE_SCALAR_NORMALIZED)
+ {
+ double x = hypot(vals->pixel_matrix[0], vals->pixel_matrix[2]);
+ double y = hypot(vals->point_matrix[0], vals->point_matrix[2]);
+ if (y < EPS) return FALSE;
+ vals->x = (int)(x * 72.27 / y + .5);
+ }
+ else
+ {
+ /* Not enough information in the pixelsize array. Just
+ assume the pixels are square. */
+ vals->x = vals->y;
+ }
+ }
+ }
+
+ if (vals->x <= 0 || vals->y <= 0) return FALSE;
+
+ /* If neither pixelsize nor pointsize is defined, take the pointsize
+ from the defaults structure we've been passed. */
+ if (!(vals->values_supplied & PIXELSIZE_MASK) &&
+ !(vals->values_supplied & POINTSIZE_MASK))
+ {
+ if (num_res)
+ {
+ vals->point_matrix[0] =
+ vals->point_matrix[3] = (double)res->point_size / 10.0;
+ vals->point_matrix[1] =
+ vals->point_matrix[2] = 0;
+ vals->values_supplied = (vals->values_supplied & ~POINTSIZE_MASK) |
+ POINTSIZE_SCALAR;
+ }
+ else if (def->values_supplied & POINTSIZE_MASK)
+ {
+ vals->point_matrix[0] = def->point_matrix[0];
+ vals->point_matrix[1] = def->point_matrix[1];
+ vals->point_matrix[2] = def->point_matrix[2];
+ vals->point_matrix[3] = def->point_matrix[3];
+ vals->values_supplied = (vals->values_supplied & ~POINTSIZE_MASK) |
+ (def->values_supplied & POINTSIZE_MASK);
+ }
+ else return FALSE;
+ }
+
+ /* At this point, at least two of the three vertical scale values
+ should be specified. Our job now is to compute the missing ones
+ and check for agreement between overspecified values */
+
+ /* If pixelsize was specified by a scalar, we need to fix the matrix
+ now that we know the resolutions. */
+ if ((vals->values_supplied & PIXELSIZE_MASK) == PIXELSIZE_SCALAR)
+ {
+ /* pixel_setsize_adjustment used below to modify permissible
+ error in pixel/pointsize matching, since multiplying a
+ number rounded to integer changes the amount of the error
+ caused by the rounding */
+
+ pixel_setsize_adjustment = (double)vals->x / (double)vals->y;
+ vals->pixel_matrix[0] *= pixel_setsize_adjustment;
+ vals->values_supplied = (vals->values_supplied & ~PIXELSIZE_MASK) |
+ PIXELSIZE_SCALAR_NORMALIZED;
+ }
+
+ sx = (double)vals->x / 72.27;
+ sy = (double)vals->y / 72.27;
+
+ /* If a pointsize was specified, make sure pixelsize is consistent
+ to within 1 pixel, then replace pixelsize with a consistent
+ floating-point value. */
+
+ if (vals->values_supplied & POINTSIZE_MASK)
+ {
+ recompute_pixelsize: ;
+ temp_matrix[0] = vals->point_matrix[0] * sx;
+ temp_matrix[1] = vals->point_matrix[1] * sy;
+ temp_matrix[2] = vals->point_matrix[2] * sx;
+ temp_matrix[3] = vals->point_matrix[3] * sy;
+ if (vals->values_supplied & PIXELSIZE_MASK)
+ {
+ if (fabs(vals->pixel_matrix[0] - temp_matrix[0]) >
+ pixel_setsize_adjustment ||
+ fabs(vals->pixel_matrix[1] - temp_matrix[1]) > 1 ||
+ fabs(vals->pixel_matrix[2] - temp_matrix[2]) > 1 ||
+ fabs(vals->pixel_matrix[3] - temp_matrix[3]) > 1)
+ return FALSE;
+ }
+ if ((vals->values_supplied & PIXELSIZE_MASK) == PIXELSIZE_ARRAY &&
+ (vals->values_supplied & POINTSIZE_MASK) == POINTSIZE_SCALAR)
+ {
+ /* In the special case that pixelsize came as an array and
+ pointsize as a scalar, recompute the pointsize matrix
+ from the pixelsize matrix. */
+ goto recompute_pointsize;
+ }
+
+ /* Refresh pixel matrix with precise values computed from
+ pointsize and resolution. */
+ vals->pixel_matrix[0] = temp_matrix[0];
+ vals->pixel_matrix[1] = temp_matrix[1];
+ vals->pixel_matrix[2] = temp_matrix[2];
+ vals->pixel_matrix[3] = temp_matrix[3];
+
+ /* Set values_supplied for pixel to match that for point */
+ vals->values_supplied =
+ (vals->values_supplied & ~PIXELSIZE_MASK) |
+ (((vals->values_supplied & POINTSIZE_MASK) == POINTSIZE_ARRAY) ?
+ PIXELSIZE_ARRAY : PIXELSIZE_SCALAR_NORMALIZED);
+ }
+ else
+ {
+ /* Pointsize unspecified... compute from pixel size and
+ resolutions */
+ recompute_pointsize: ;
+ if (fabs(sx) < EPS || fabs(sy) < EPS) return FALSE;
+ vals->point_matrix[0] = vals->pixel_matrix[0] / sx;
+ vals->point_matrix[1] = vals->pixel_matrix[1] / sy;
+ vals->point_matrix[2] = vals->pixel_matrix[2] / sx;
+ vals->point_matrix[3] = vals->pixel_matrix[3] / sy;
+
+ /* Set values_supplied for pixel to match that for point */
+ vals->values_supplied =
+ (vals->values_supplied & ~POINTSIZE_MASK) |
+ (((vals->values_supplied & PIXELSIZE_MASK) == PIXELSIZE_ARRAY) ?
+ POINTSIZE_ARRAY : POINTSIZE_SCALAR);
+
+ /* If we computed scalar pointsize from scalar pixelsize, round
+ pointsize to decipoints and recompute pixelsize so we end up
+ with a repeatable name */
+ if ((vals->values_supplied & POINTSIZE_MASK) == POINTSIZE_SCALAR)
+ {
+ /* Off-diagonal elements should be zero since no matrix was
+ specified. */
+ vals->point_matrix[0] =
+ (double)(int)(vals->point_matrix[0] * 10.0 + .5) / 10.0;
+ vals->point_matrix[3] =
+ (double)(int)(vals->point_matrix[3] * 10.0 + .5) / 10.0;
+ goto recompute_pixelsize;
+ }
+ }
+
+ /* We've succeeded. Round everything to a few decimal places
+ for repeatability. */
+
+ vals->pixel_matrix[0] = xlfd_round_double(vals->pixel_matrix[0]);
+ vals->pixel_matrix[1] = xlfd_round_double(vals->pixel_matrix[1]);
+ vals->pixel_matrix[2] = xlfd_round_double(vals->pixel_matrix[2]);
+ vals->pixel_matrix[3] = xlfd_round_double(vals->pixel_matrix[3]);
+ vals->point_matrix[0] = xlfd_round_double(vals->point_matrix[0]);
+ vals->point_matrix[1] = xlfd_round_double(vals->point_matrix[1]);
+ vals->point_matrix[2] = xlfd_round_double(vals->point_matrix[2]);
+ vals->point_matrix[3] = xlfd_round_double(vals->point_matrix[3]);
+
+ /* Fill in the deprecated fields for the benefit of rasterizers
+ that do not handle the matrices. */
+ vals->point = vals->point_matrix[3] * 10;
+ vals->pixel = vals->pixel_matrix[3];
+
+ return TRUE;
+}
+
+static Bool
+MatchScalable (FontScalablePtr a, FontScalablePtr b)
+{
+ int i;
+
+ /* Some asymmetry here: we assume that the first argument (a) is
+ the table entry and the second (b) the item we're trying to match
+ (the key). We'll consider the fonts matched if the relevant
+ metrics match *and* if a) the table entry doesn't have charset
+ subsetting or b) the table entry has identical charset subsetting
+ to that in the key. We could add logic to check if the table
+ entry has a superset of the charset required by the key, but
+ we'll resist the urge for now. */
+
+#define EQUAL(a,b) ((a)[0] == (b)[0] && \
+ (a)[1] == (b)[1] && \
+ (a)[2] == (b)[2] && \
+ (a)[3] == (b)[3])
+
+ if (!(a->x == b->x &&
+ a->y == b->y &&
+ (a->width == b->width || a->width == 0 || b->width == 0 || b->width == -1) &&
+ (!(b->values_supplied & PIXELSIZE_MASK) ||
+ ((a->values_supplied & PIXELSIZE_MASK) ==
+ (b->values_supplied & PIXELSIZE_MASK) &&
+ EQUAL(a->pixel_matrix, b->pixel_matrix))) &&
+ (!(b->values_supplied & POINTSIZE_MASK) ||
+ ((a->values_supplied & POINTSIZE_MASK) ==
+ (b->values_supplied & POINTSIZE_MASK) &&
+ EQUAL(a->point_matrix, b->point_matrix))) &&
+ (a->nranges == 0 || a->nranges == b->nranges)))
+ return FALSE;
+
+ for (i = 0; i < a->nranges; i++)
+ if (a->ranges[i].min_char_low != b->ranges[i].min_char_low ||
+ a->ranges[i].min_char_high != b->ranges[i].min_char_high ||
+ a->ranges[i].max_char_low != b->ranges[i].max_char_low ||
+ a->ranges[i].max_char_high != b->ranges[i].max_char_high)
+ return FALSE;
+
+ return TRUE;
+}
+
+FontScaledPtr
+FontFileFindScaledInstance (FontEntryPtr entry, FontScalablePtr vals,
+ int noSpecificSize)
+{
+ FontScalableEntryPtr scalable;
+ FontScalableExtraPtr extra;
+ FontScalablePtr mvals;
+ int dist, i;
+ int mini;
+ double mindist;
+ register double temp, sum=0.0;
+
+#define NORMDIFF(a, b) ( \
+ temp = (a)[0] - (b)[0], \
+ sum = temp * temp, \
+ temp = (a)[1] - (b)[1], \
+ sum += temp * temp, \
+ temp = (a)[2] - (b)[2], \
+ sum += temp * temp, \
+ temp = (a)[3] - (b)[3], \
+ sum + temp * temp )
+
+ scalable = &entry->u.scalable;
+ extra = scalable->extra;
+ if (noSpecificSize && extra->numScaled)
+ {
+ mini = 0;
+ mindist = NORMDIFF(extra->scaled[0].vals.point_matrix,
+ vals->point_matrix);
+ for (i = 1; i < extra->numScaled; i++)
+ {
+ if (extra->scaled[i].pFont &&
+ !extra->scaled[i].pFont->info.cachable) continue;
+ mvals = &extra->scaled[i].vals;
+ dist = NORMDIFF(mvals->point_matrix, vals->point_matrix);
+ if (dist < mindist)
+ {
+ mindist = dist;
+ mini = i;
+ }
+ }
+ if (extra->scaled[mini].pFont &&
+ !extra->scaled[mini].pFont->info.cachable) return 0;
+ return &extra->scaled[mini];
+ }
+ else
+ {
+ /* See if we've scaled to this value yet */
+ for (i = 0; i < extra->numScaled; i++)
+ {
+ if (extra->scaled[i].pFont &&
+ !extra->scaled[i].pFont->info.cachable) continue;
+ if (MatchScalable (&extra->scaled[i].vals, vals))
+ return &extra->scaled[i];
+ }
+ }
+ return 0;
+}
diff --git a/libXfont/src/fontfile/gunzip.c b/libXfont/src/fontfile/gunzip.c
new file mode 100644
index 000000000..8c9c317aa
--- /dev/null
+++ b/libXfont/src/fontfile/gunzip.c
@@ -0,0 +1,227 @@
+/* $Xorg: gunzip.c,v 1.3 2000/08/17 19:46:37 cpqbld Exp $ */
+/* lib/font/fontfile/gunzip.c
+ written by Mark Eichin <eichin@kitten.gen.ma.us> September 1996.
+ intended for inclusion in X11 public releases. */
+/* $XFree86: xc/lib/font/fontfile/gunzip.c,v 1.4 2000/09/19 12:46:08 eich Exp $ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include <X11/fonts/fontmisc.h>
+#include <X11/fonts/bufio.h>
+#include <zlib.h>
+
+typedef struct _xzip_buf {
+ z_stream z;
+ int zstat;
+ BufChar b[BUFFILESIZE];
+ BufChar b_in[BUFFILESIZE];
+ BufFilePtr f;
+} xzip_buf;
+
+static int BufZipFileClose ( BufFilePtr f, int flag );
+static int BufZipFileFill ( BufFilePtr f );
+static int BufZipFileSkip ( BufFilePtr f, int c );
+static int BufCheckZipHeader ( BufFilePtr f );
+
+BufFilePtr
+BufFilePushZIP (BufFilePtr f)
+{
+ xzip_buf *x;
+
+ x = (xzip_buf *) xalloc (sizeof (xzip_buf));
+ if (!x) return 0;
+ /* these are just for raw calloc/free */
+ x->z.zalloc = Z_NULL;
+ x->z.zfree = Z_NULL;
+ x->z.opaque = Z_NULL;
+ x->f = f;
+
+ /* force inflateInit to allocate it's own history buffer */
+ x->z.next_in = Z_NULL;
+ x->z.next_out = Z_NULL;
+ x->z.avail_in = x->z.avail_out = 0;
+
+ /* using negative windowBits sets "nowrap" mode, which turns off
+ zlib header checking [undocumented, for gzip compatibility only?] */
+ x->zstat = inflateInit2(&(x->z), -MAX_WBITS);
+ if (x->zstat != Z_OK) {
+ xfree(x);
+ return 0;
+ }
+
+ /* now that the history buffer is allocated, we provide the data buffer */
+ x->z.next_out = x->b;
+ x->z.avail_out = BUFFILESIZE;
+ x->z.next_out = x->b_in;
+ x->z.avail_in = 0;
+
+ if (BufCheckZipHeader(x->f)) {
+ xfree(x);
+ return 0;
+ }
+
+ return BufFileCreate((char *)x,
+ BufZipFileFill,
+ 0,
+ BufZipFileSkip,
+ BufZipFileClose);
+}
+
+static int
+BufZipFileClose(BufFilePtr f, int flag)
+{
+ xzip_buf *x = (xzip_buf *)f->private;
+ inflateEnd (&(x->z));
+ BufFileClose (x->f, flag);
+ xfree (x);
+ return 1;
+}
+
+/* here's the real work.
+ -- we need to put stuff in f.buffer, update f.left and f.bufp,
+ then return the first byte (or BUFFILEEOF).
+ -- to do this, we need to get stuff into avail_in, and next_in,
+ and call inflate appropriately.
+ -- we may also need to add CRC maintenance - if inflate tells us
+ Z_STREAM_END, we then have 4bytes CRC and 4bytes length...
+ gzio.c:gzread shows most of the mechanism.
+ */
+static int
+BufZipFileFill (BufFilePtr f)
+{
+ xzip_buf *x = (xzip_buf *)f->private;
+
+ /* we only get called when left == 0... */
+ /* but just in case, deal */
+ if (f->left >= 0) {
+ f->left--;
+ return *(f->bufp++);
+ }
+ /* did we run out last time? */
+ switch (x->zstat) {
+ case Z_OK:
+ break;
+ case Z_STREAM_END:
+ case Z_DATA_ERROR:
+ case Z_ERRNO:
+ f->left = 0;
+ return BUFFILEEOF;
+ default:
+ return BUFFILEEOF;
+ }
+ /* now we work to consume what we can */
+ /* let zlib know what we can handle */
+ x->z.next_out = x->b;
+ x->z.avail_out = BUFFILESIZE;
+
+ /* and try to consume all of it */
+ while (x->z.avail_out > 0) {
+ /* if we don't have anything to work from... */
+ if (x->z.avail_in == 0) {
+ /* ... fill the z buf from underlying file */
+ int i, c;
+ for (i = 0; i < sizeof(x->b_in); i++) {
+ c = BufFileGet(x->f);
+ if (c == BUFFILEEOF) break;
+ x->b_in[i] = c;
+ }
+ x->z.avail_in += i;
+ x->z.next_in = x->b_in;
+ }
+ /* so now we have some output space and some input data */
+ x->zstat = inflate(&(x->z), Z_NO_FLUSH);
+ /* the inflation output happens in the f buffer directly... */
+ if (x->zstat == Z_STREAM_END) {
+ /* deal with EOF, crc */
+ break;
+ }
+ if (x->zstat != Z_OK) {
+ break;
+ }
+ }
+ f->bufp = x->b;
+ f->left = BUFFILESIZE - x->z.avail_out;
+
+ if (f->left >= 0) {
+ f->left--;
+ return *(f->bufp++);
+ } else {
+ return BUFFILEEOF;
+ }
+}
+
+/* there should be a BufCommonSkip... */
+static int
+BufZipFileSkip (BufFilePtr f, int c)
+{
+ /* BufFileRawSkip returns the count unchanged.
+ BufCompressedSkip returns 0.
+ That means it probably never gets called... */
+ int retval = c;
+ while(c--) {
+ int get = BufFileGet(f);
+ if (get == BUFFILEEOF) return get;
+ }
+ return retval;
+}
+
+/* now we need to duplicate check_header */
+/* contents:
+ 0x1f, 0x8b -- magic number
+ 1 byte -- method (Z_DEFLATED)
+ 1 byte -- flags (mask with RESERVED -> fail)
+ 4 byte -- time (discard)
+ 1 byte -- xflags (discard)
+ 1 byte -- "os" code (discard)
+ [if flags & EXTRA_FIELD:
+ 2 bytes -- LSBfirst length n
+ n bytes -- extra data (discard)]
+ [if flags & ORIG_NAME:
+ n bytes -- null terminated name (discard)]
+ [if flags & COMMENT:
+ n bytes -- null terminated comment (discard)]
+ [if flags & HEAD_CRC:
+ 2 bytes -- crc of headers? (discard)]
+ */
+
+/* gzip flag byte -- from gzio.c */
+#define ASCII_FLAG 0x01 /* bit 0 set: file probably ascii text */
+#define HEAD_CRC 0x02 /* bit 1 set: header CRC present */
+#define EXTRA_FIELD 0x04 /* bit 2 set: extra field present */
+#define ORIG_NAME 0x08 /* bit 3 set: original file name present */
+#define COMMENT 0x10 /* bit 4 set: file comment present */
+#define RESERVED 0xE0 /* bits 5..7: reserved */
+
+#define GET(f) do {c = BufFileGet(f); if (c == BUFFILEEOF) return c;} while(0)
+static int
+BufCheckZipHeader(BufFilePtr f)
+{
+ int c, flags;
+ GET(f); if (c != 0x1f) return 1; /* magic 1 */
+ GET(f); if (c != 0x8b) return 2; /* magic 2 */
+ GET(f); if (c != Z_DEFLATED) return 3; /* method */
+ GET(f); if (c & RESERVED) return 4; /* reserved flags */
+ flags = c;
+ GET(f); GET(f); GET(f); GET(f); /* time */
+ GET(f); /* xflags */
+ GET(f); /* os code */
+ if (flags & EXTRA_FIELD) {
+ int len;
+ GET(f); len = c;
+ GET(f); len += (c<<8);
+ while (len-- >= 0) {
+ GET(f);
+ }
+ }
+ if (flags & ORIG_NAME) {
+ do { GET(f); } while (c != 0);
+ }
+ if (flags & COMMENT) {
+ do { GET(f); } while (c != 0);
+ }
+ if (flags & HEAD_CRC) {
+ GET(f); GET(f); /* header crc */
+ }
+ return 0;
+}
diff --git a/libXfont/src/fontfile/printerfont.c b/libXfont/src/fontfile/printerfont.c
new file mode 100644
index 000000000..0b6c19c62
--- /dev/null
+++ b/libXfont/src/fontfile/printerfont.c
@@ -0,0 +1,178 @@
+/* $Xorg: printerfont.c,v 1.4 2001/02/09 02:04:03 xorgcvs Exp $ */
+
+/*
+
+Copyright 1991, 1998 The Open Group
+
+Permission to use, copy, modify, distribute, and sell this software and its
+documentation for any purpose is hereby granted without fee, provided that
+the above copyright notice appear in all copies and that both that
+copyright notice and this permission notice appear in supporting
+documentation.
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of The Open Group shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from The Open Group.
+
+*/
+/* $XFree86: xc/lib/font/fontfile/printerfont.c,v 1.5tsi Exp $ */
+
+/*
+ * Author: Keith Packard, MIT X Consortium
+ */
+/* $NCDXorg: @(#)fontfile.c,v 1.6 1991/07/02 17:00:46 lemke Exp $ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include <X11/fonts/fntfilst.h>
+
+/*
+ * Map FPE functions to renderer functions
+ */
+
+#define PRINTERPATHPREFIX "PRINTER:"
+
+/* STUB
+int XpClientIsPrintClient(client,fpe)
+pointer client;
+FontPathElementPtr fpe;
+{ return 1; }
+ */
+
+static int
+PrinterFontNameCheck (char *name)
+{
+ if (strncmp(name,PRINTERPATHPREFIX,strlen(PRINTERPATHPREFIX)) != 0)
+ return 0;
+ name += strlen(PRINTERPATHPREFIX);
+#ifndef NCD
+ return *name == '/';
+#else
+ return ((strcmp(name, "built-ins") == 0) || (*name == '/'));
+#endif
+}
+
+static int
+PrinterFontInitFPE (FontPathElementPtr fpe)
+{
+ int status;
+ FontDirectoryPtr dir;
+ char * name;
+
+ name = fpe->name + strlen(PRINTERPATHPREFIX);
+ status = FontFileReadDirectory (name, &dir);
+ if (status == Successful)
+ {
+ if (dir->nonScalable.used > 0)
+ if (!FontFileRegisterBitmapSource (fpe))
+ {
+ FontFileFreeFPE (fpe);
+ return AllocError;
+ }
+ fpe->private = (pointer) dir;
+ }
+ return status;
+}
+
+/* Here we must check the client to see if it has a context attached to
+ * it that allows us to access the printer fonts
+ */
+
+static int
+PrinterFontOpenFont (pointer client, FontPathElementPtr fpe, Mask flags,
+ char *name, int namelen,
+ fsBitmapFormat format, fsBitmapFormatMask fmask,
+ XID id, FontPtr *pFont, char **aliasName,
+ FontPtr non_cachable_font)
+{
+ if (XpClientIsPrintClient(client,fpe))
+ return (FontFileOpenFont (client, fpe, flags, name, namelen, format,
+ fmask, id, pFont, aliasName, non_cachable_font));
+ return BadFontName;
+}
+
+static int
+PrinterFontListFonts (pointer client, FontPathElementPtr fpe, char *pat,
+ int len, int max, FontNamesPtr names)
+{
+ if (XpClientIsPrintClient(client,fpe))
+ return FontFileListFonts (client, fpe, pat, len, max, names);
+ return BadFontName;
+}
+
+static int
+PrinterFontStartListFontsWithInfo(pointer client, FontPathElementPtr fpe,
+ char *pat, int len, int max,
+ pointer *privatep)
+{
+ if (XpClientIsPrintClient(client,fpe))
+ return FontFileStartListFontsWithInfo(client, fpe, pat, len,
+ max, privatep);
+ return BadFontName;
+}
+
+static int
+PrinterFontListNextFontWithInfo(pointer client, FontPathElementPtr fpe,
+ char **namep, int *namelenp,
+ FontInfoPtr *pFontInfo,
+ int *numFonts, pointer private)
+{
+ if (XpClientIsPrintClient(client,fpe))
+ return FontFileListNextFontWithInfo(client, fpe, namep, namelenp,
+ pFontInfo, numFonts, private);
+ return BadFontName;
+}
+
+static int
+PrinterFontStartListFontsAndAliases(pointer client, FontPathElementPtr fpe,
+ char *pat, int len, int max,
+ pointer *privatep)
+{
+ if (XpClientIsPrintClient(client,fpe))
+ return FontFileStartListFontsAndAliases(client, fpe, pat, len,
+ max, privatep);
+ return BadFontName;
+}
+
+static int
+PrinterFontListNextFontOrAlias(pointer client, FontPathElementPtr fpe,
+ char **namep, int *namelenp,
+ char **resolvedp, int *resolvedlenp,
+ pointer private)
+{
+ if (XpClientIsPrintClient(client,fpe))
+ return FontFileListNextFontOrAlias(client, fpe, namep, namelenp,
+ resolvedp, resolvedlenp, private);
+ return BadFontName;
+}
+
+void
+PrinterFontRegisterFpeFunctions (void)
+{
+ RegisterFPEFunctions(PrinterFontNameCheck,
+ PrinterFontInitFPE,
+ FontFileFreeFPE,
+ FontFileResetFPE,
+ PrinterFontOpenFont,
+ FontFileCloseFont,
+ PrinterFontListFonts,
+ PrinterFontStartListFontsWithInfo,
+ PrinterFontListNextFontWithInfo,
+ NULL,
+ NULL,
+ NULL,
+ PrinterFontStartListFontsAndAliases,
+ PrinterFontListNextFontOrAlias,
+ FontFileEmptyBitmapSource);
+}
diff --git a/libXfont/src/fontfile/register.c b/libXfont/src/fontfile/register.c
new file mode 100644
index 000000000..5b70df76a
--- /dev/null
+++ b/libXfont/src/fontfile/register.c
@@ -0,0 +1,124 @@
+/* $Xorg: register.c,v 1.4 2001/02/09 02:04:03 xorgcvs Exp $ */
+
+/*
+
+Copyright 1994, 1998 The Open Group
+
+Permission to use, copy, modify, distribute, and sell this software and its
+documentation for any purpose is hereby granted without fee, provided that
+the above copyright notice appear in all copies and that both that
+copyright notice and this permission notice appear in supporting
+documentation.
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of The Open Group shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from The Open Group.
+
+*/
+/* $XFree86: xc/lib/font/fontfile/register.c,v 1.14 2001/01/17 19:43:30 dawes Exp $ */
+
+/*
+ * This is in a separate source file so that small programs
+ * such as mkfontdir that want to use the fontfile utilities don't
+ * end up dragging in code from all the renderers, which is not small.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#else
+#define XFONT_BITMAP 1
+#endif
+
+#include <X11/fonts/fontmisc.h>
+#include <X11/fonts/fntfilst.h>
+#include <X11/fonts/bitmap.h>
+#include <X11/fonts/fontmod.h>
+
+/*
+ * Translate monolithic build symbols to modular build symbols.
+ * I chose to make the modular symbols 'canonical' because they
+ * are prefixed with XFONT_, neatly avoiding name collisions
+ * with other packages.
+ */
+
+#ifndef CRAY
+# ifdef BUILD_SPEEDO
+# define XFONT_SPEEDO 1
+# endif
+# ifdef BUILD_TYPE1
+# define XFONT_TYPE1 1
+# endif
+#endif
+
+#ifdef BUILD_FREETYPE
+# define XFONT_FREETYPE 1
+#endif
+
+/* Font renderers to initialize when not linked into something like
+ Xorg that provides its own module configuration options */
+static const FontModule builtinFontModuleList[] = {
+#ifdef XFONT_SPEEDO
+ {
+ SpeedoRegisterFontFileFunctions,
+ "speedo",
+ NULL
+ },
+#endif
+#ifdef XFONT_TYPE1
+ {
+ Type1RegisterFontFileFunctions,
+ "type1",
+ NULL
+ },
+#endif
+#ifdef XFONT_FREETYPE
+ {
+ FreeTypeRegisterFontFileFunctions,
+ "freetype",
+ NULL
+ },
+#endif
+ /* List terminator - must be last entry */
+ { NULL, NULL, NULL }
+};
+
+void
+FontFileRegisterFpeFunctions(void)
+{
+ const FontModule *fmlist = builtinFontModuleList;
+
+#ifdef XFONT_BITMAP
+ /* bitmap is always builtin to libXfont now */
+ BitmapRegisterFontFileFunctions ();
+#endif
+
+#ifdef LOADABLEFONTS
+ if (FontModuleList) {
+ fmlist = FontModuleList;
+ }
+#endif
+
+ if (fmlist) {
+ int i;
+
+ for (i = 0; fmlist[i].name; i++) {
+ if (fmlist[i].initFunc) {
+ fmlist[i].initFunc();
+ }
+ }
+ }
+
+ FontFileRegisterLocalFpeFunctions ();
+ CatalogueRegisterLocalFpeFunctions ();
+}
+
diff --git a/libXfont/src/fontfile/renderers.c b/libXfont/src/fontfile/renderers.c
new file mode 100644
index 000000000..f110ba817
--- /dev/null
+++ b/libXfont/src/fontfile/renderers.c
@@ -0,0 +1,117 @@
+/* $Xorg: renderers.c,v 1.4 2001/02/09 02:04:03 xorgcvs Exp $ */
+
+/*
+
+Copyright 1991, 1998 The Open Group
+
+Permission to use, copy, modify, distribute, and sell this software and its
+documentation for any purpose is hereby granted without fee, provided that
+the above copyright notice appear in all copies and that both that
+copyright notice and this permission notice appear in supporting
+documentation.
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of The Open Group shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from The Open Group.
+
+*/
+/* $XFree86: xc/lib/font/fontfile/renderers.c,v 1.7 2002/12/09 17:30:00 dawes Exp $ */
+
+/*
+ * Author: Keith Packard, MIT X Consortium
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include <X11/fonts/fntfilst.h>
+extern void ErrorF(const char *f, ...);
+
+static FontRenderersRec renderers;
+
+/*
+ * XXX Maybe should allow unregistering renders. For now, just clear the
+ * list at each new generation.
+ */
+extern unsigned long serverGeneration;
+static unsigned long rendererGeneration = 0;
+
+Bool
+FontFileRegisterRenderer (FontRendererPtr renderer)
+{
+ return FontFilePriorityRegisterRenderer(renderer, 0);
+}
+
+Bool
+FontFilePriorityRegisterRenderer (FontRendererPtr renderer, int priority)
+{
+ int i;
+ struct _FontRenderersElement *new;
+
+ if (rendererGeneration != serverGeneration) {
+ rendererGeneration = serverGeneration;
+ renderers.number = 0;
+ if (renderers.renderers)
+ xfree(renderers.renderers);
+ renderers.renderers = NULL;
+ }
+
+ for (i = 0; i < renderers.number; i++) {
+ if (!strcmp (renderers.renderers[i].renderer->fileSuffix,
+ renderer->fileSuffix)) {
+ if(renderers.renderers[i].priority >= priority) {
+ if(renderers.renderers[i].priority == priority) {
+ if (rendererGeneration == 1)
+ ErrorF("Warning: font renderer for \"%s\" "
+ "already registered at priority %d\n",
+ renderer->fileSuffix, priority);
+ }
+ return TRUE;
+ } else {
+ break;
+ }
+ }
+ }
+
+ if(i >= renderers.number) {
+ new = xrealloc (renderers.renderers, sizeof(*new) * (i + 1));
+ if (!new)
+ return FALSE;
+ renderers.renderers = new;
+ renderers.number = i + 1;
+ }
+ renderer->number = i;
+ renderers.renderers[i].renderer = renderer;
+ renderers.renderers[i].priority = priority;
+ return TRUE;
+}
+
+FontRendererPtr
+FontFileMatchRenderer (char *fileName)
+{
+ int i;
+ int fileLen;
+ FontRendererPtr r;
+
+ fileLen = strlen (fileName);
+ for (i = 0; i < renderers.number; i++)
+ {
+ r = renderers.renderers[i].renderer;
+ if (fileLen >= r->fileSuffixLen &&
+ !strcmp (fileName + fileLen - r->fileSuffixLen, r->fileSuffix))
+ {
+ return r;
+ }
+ }
+ return 0;
+}
diff --git a/libXfont/src/stubs/Makefile.am b/libXfont/src/stubs/Makefile.am
new file mode 100644
index 000000000..963470f52
--- /dev/null
+++ b/libXfont/src/stubs/Makefile.am
@@ -0,0 +1,27 @@
+INCLUDES = \
+ -I${top_srcdir}/include
+
+AM_CFLAGS = $(XFONT_CFLAGS) $(OS_CFLAGS) $(CWARNFLAGS)
+
+noinst_LTLIBRARIES = libstubs.la
+
+libstubs_la_SOURCES = \
+ cauthgen.c \
+ csignal.c \
+ delfntcid.c \
+ errorf.c \
+ fatalerror.c \
+ findoldfnt.c \
+ fontmod.c \
+ getcres.c \
+ getdefptsize.c \
+ getnewfntcid.c \
+ gettime.c \
+ initfshdl.c \
+ regfpefunc.c \
+ rmfshdl.c \
+ servclient.c \
+ setfntauth.c \
+ stfntcfnt.c \
+ stubs.h \
+ xpstubs.c
diff --git a/libXfont/src/stubs/Makefile.in b/libXfont/src/stubs/Makefile.in
new file mode 100644
index 000000000..53363bb45
--- /dev/null
+++ b/libXfont/src/stubs/Makefile.in
@@ -0,0 +1,491 @@
+# Makefile.in generated by automake 1.10 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
+# 2003, 2004, 2005, 2006 Free Software Foundation, Inc.
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+@SET_MAKE@
+
+VPATH = @srcdir@
+pkgdatadir = $(datadir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+install_sh_DATA = $(install_sh) -c -m 644
+install_sh_PROGRAM = $(install_sh) -c
+install_sh_SCRIPT = $(install_sh) -c
+INSTALL_HEADER = $(INSTALL_DATA)
+transform = $(program_transform_name)
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+build_triplet = @build@
+host_triplet = @host@
+subdir = src/stubs
+DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/configure.ac
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+ $(ACLOCAL_M4)
+mkinstalldirs = $(install_sh) -d
+CONFIG_HEADER = $(top_builddir)/config.h \
+ $(top_builddir)/include/X11/fonts/fontconf.h
+CONFIG_CLEAN_FILES =
+LTLIBRARIES = $(noinst_LTLIBRARIES)
+libstubs_la_LIBADD =
+am_libstubs_la_OBJECTS = cauthgen.lo csignal.lo delfntcid.lo errorf.lo \
+ fatalerror.lo findoldfnt.lo fontmod.lo getcres.lo \
+ getdefptsize.lo getnewfntcid.lo gettime.lo initfshdl.lo \
+ regfpefunc.lo rmfshdl.lo servclient.lo setfntauth.lo \
+ stfntcfnt.lo xpstubs.lo
+libstubs_la_OBJECTS = $(am_libstubs_la_OBJECTS)
+DEFAULT_INCLUDES = -I. -I$(top_builddir) -I$(top_builddir)/include/X11/fonts@am__isrc@
+depcomp = $(SHELL) $(top_srcdir)/depcomp
+am__depfiles_maybe = depfiles
+COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
+ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+LTCOMPILE = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
+ --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \
+ $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+CCLD = $(CC)
+LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
+ --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \
+ $(LDFLAGS) -o $@
+SOURCES = $(libstubs_la_SOURCES)
+DIST_SOURCES = $(libstubs_la_SOURCES)
+ETAGS = etags
+CTAGS = ctags
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+ACLOCAL = @ACLOCAL@
+AMTAR = @AMTAR@
+AR = @AR@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+CC = @CC@
+CCDEPMODE = @CCDEPMODE@
+CFLAGS = @CFLAGS@
+CHANGELOG_CMD = @CHANGELOG_CMD@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CWARNFLAGS = @CWARNFLAGS@
+CXX = @CXX@
+CXXCPP = @CXXCPP@
+CXXDEPMODE = @CXXDEPMODE@
+CXXFLAGS = @CXXFLAGS@
+CYGPATH_W = @CYGPATH_W@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+ECHO = @ECHO@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+EGREP = @EGREP@
+ENCODINGSDIR = @ENCODINGSDIR@
+EXEEXT = @EXEEXT@
+F77 = @F77@
+FFLAGS = @FFLAGS@
+FREETYPE_CFLAGS = @FREETYPE_CFLAGS@
+FREETYPE_LIBS = @FREETYPE_LIBS@
+FREETYPE_REQUIRES = @FREETYPE_REQUIRES@
+GREP = @GREP@
+INSTALL = @INSTALL@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+LDFLAGS = @LDFLAGS@
+LIBOBJS = @LIBOBJS@
+LIBS = @LIBS@
+LIBTOOL = @LIBTOOL@
+LN_S = @LN_S@
+LTLIBOBJS = @LTLIBOBJS@
+MAKEINFO = @MAKEINFO@
+MATH_LIBS = @MATH_LIBS@
+MKDIR_P = @MKDIR_P@
+OBJEXT = @OBJEXT@
+OS_CFLAGS = @OS_CFLAGS@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+PKG_CONFIG = @PKG_CONFIG@
+RANLIB = @RANLIB@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+STRIP = @STRIP@
+VERSION = @VERSION@
+XFONT_CFLAGS = @XFONT_CFLAGS@
+XFONT_LIBS = @XFONT_LIBS@
+X_GZIP_FONT_COMPRESSION = @X_GZIP_FONT_COMPRESSION@
+Z_LIBS = @Z_LIBS@
+abs_builddir = @abs_builddir@
+abs_srcdir = @abs_srcdir@
+abs_top_builddir = @abs_top_builddir@
+abs_top_srcdir = @abs_top_srcdir@
+ac_ct_CC = @ac_ct_CC@
+ac_ct_CXX = @ac_ct_CXX@
+ac_ct_F77 = @ac_ct_F77@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+am__tar = @am__tar@
+am__untar = @am__untar@
+bindir = @bindir@
+build = @build@
+build_alias = @build_alias@
+build_cpu = @build_cpu@
+build_os = @build_os@
+build_vendor = @build_vendor@
+builddir = @builddir@
+datadir = @datadir@
+datarootdir = @datarootdir@
+distcleancheck_listfiles = @distcleancheck_listfiles@
+docdir = @docdir@
+dvidir = @dvidir@
+exec_prefix = @exec_prefix@
+ft_config = @ft_config@
+host = @host@
+host_alias = @host_alias@
+host_cpu = @host_cpu@
+host_os = @host_os@
+host_vendor = @host_vendor@
+htmldir = @htmldir@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+libdir = @libdir@
+libexecdir = @libexecdir@
+localedir = @localedir@
+localstatedir = @localstatedir@
+mandir = @mandir@
+mkdir_p = @mkdir_p@
+oldincludedir = @oldincludedir@
+pdfdir = @pdfdir@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+psdir = @psdir@
+sbindir = @sbindir@
+sharedstatedir = @sharedstatedir@
+srcdir = @srcdir@
+sysconfdir = @sysconfdir@
+target_alias = @target_alias@
+top_builddir = @top_builddir@
+top_srcdir = @top_srcdir@
+INCLUDES = \
+ -I${top_srcdir}/include
+
+AM_CFLAGS = $(XFONT_CFLAGS) $(OS_CFLAGS) $(CWARNFLAGS)
+noinst_LTLIBRARIES = libstubs.la
+libstubs_la_SOURCES = \
+ cauthgen.c \
+ csignal.c \
+ delfntcid.c \
+ errorf.c \
+ fatalerror.c \
+ findoldfnt.c \
+ fontmod.c \
+ getcres.c \
+ getdefptsize.c \
+ getnewfntcid.c \
+ gettime.c \
+ initfshdl.c \
+ regfpefunc.c \
+ rmfshdl.c \
+ servclient.c \
+ setfntauth.c \
+ stfntcfnt.c \
+ stubs.h \
+ xpstubs.c
+
+all: all-am
+
+.SUFFIXES:
+.SUFFIXES: .c .lo .o .obj
+$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps)
+ @for dep in $?; do \
+ case '$(am__configure_deps)' in \
+ *$$dep*) \
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh \
+ && exit 0; \
+ exit 1;; \
+ esac; \
+ done; \
+ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign src/stubs/Makefile'; \
+ cd $(top_srcdir) && \
+ $(AUTOMAKE) --foreign src/stubs/Makefile
+.PRECIOUS: Makefile
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+ @case '$?' in \
+ *config.status*) \
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
+ *) \
+ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
+ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
+ esac;
+
+$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+
+$(top_srcdir)/configure: $(am__configure_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(ACLOCAL_M4): $(am__aclocal_m4_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+
+clean-noinstLTLIBRARIES:
+ -test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES)
+ @list='$(noinst_LTLIBRARIES)'; for p in $$list; do \
+ dir="`echo $$p | sed -e 's|/[^/]*$$||'`"; \
+ test "$$dir" != "$$p" || dir=.; \
+ echo "rm -f \"$${dir}/so_locations\""; \
+ rm -f "$${dir}/so_locations"; \
+ done
+libstubs.la: $(libstubs_la_OBJECTS) $(libstubs_la_DEPENDENCIES)
+ $(LINK) $(libstubs_la_OBJECTS) $(libstubs_la_LIBADD) $(LIBS)
+
+mostlyclean-compile:
+ -rm -f *.$(OBJEXT)
+
+distclean-compile:
+ -rm -f *.tab.c
+
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cauthgen.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/csignal.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/delfntcid.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/errorf.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fatalerror.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/findoldfnt.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fontmod.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/getcres.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/getdefptsize.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/getnewfntcid.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gettime.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/initfshdl.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/regfpefunc.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/rmfshdl.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/servclient.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/setfntauth.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/stfntcfnt.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/xpstubs.Plo@am__quote@
+
+.c.o:
+@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
+@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(COMPILE) -c $<
+
+.c.obj:
+@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'`
+@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(COMPILE) -c `$(CYGPATH_W) '$<'`
+
+.c.lo:
+@am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
+@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(LTCOMPILE) -c -o $@ $<
+
+mostlyclean-libtool:
+ -rm -f *.lo
+
+clean-libtool:
+ -rm -rf .libs _libs
+
+ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) ' { files[$$0] = 1; } \
+ END { for (i in files) print i; }'`; \
+ mkid -fID $$unique
+tags: TAGS
+
+TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
+ $(TAGS_FILES) $(LISP)
+ tags=; \
+ here=`pwd`; \
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) ' { files[$$0] = 1; } \
+ END { for (i in files) print i; }'`; \
+ if test -z "$(ETAGS_ARGS)$$tags$$unique"; then :; else \
+ test -n "$$unique" || unique=$$empty_fix; \
+ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+ $$tags $$unique; \
+ fi
+ctags: CTAGS
+CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
+ $(TAGS_FILES) $(LISP)
+ tags=; \
+ here=`pwd`; \
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) ' { files[$$0] = 1; } \
+ END { for (i in files) print i; }'`; \
+ test -z "$(CTAGS_ARGS)$$tags$$unique" \
+ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
+ $$tags $$unique
+
+GTAGS:
+ here=`$(am__cd) $(top_builddir) && pwd` \
+ && cd $(top_srcdir) \
+ && gtags -i $(GTAGS_ARGS) $$here
+
+distclean-tags:
+ -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
+
+distdir: $(DISTFILES)
+ @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ list='$(DISTFILES)'; \
+ dist_files=`for file in $$list; do echo $$file; done | \
+ sed -e "s|^$$srcdirstrip/||;t" \
+ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
+ case $$dist_files in \
+ */*) $(MKDIR_P) `echo "$$dist_files" | \
+ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
+ sort -u` ;; \
+ esac; \
+ for file in $$dist_files; do \
+ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
+ if test -d $$d/$$file; then \
+ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
+ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
+ cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \
+ fi; \
+ cp -pR $$d/$$file $(distdir)$$dir || exit 1; \
+ else \
+ test -f $(distdir)/$$file \
+ || cp -p $$d/$$file $(distdir)/$$file \
+ || exit 1; \
+ fi; \
+ done
+check-am: all-am
+check: check-am
+all-am: Makefile $(LTLIBRARIES)
+installdirs:
+install: install-am
+install-exec: install-exec-am
+install-data: install-data-am
+uninstall: uninstall-am
+
+install-am: all-am
+ @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-am
+install-strip:
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ `test -z '$(STRIP)' || \
+ echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
+mostlyclean-generic:
+
+clean-generic:
+
+distclean-generic:
+ -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
+
+maintainer-clean-generic:
+ @echo "This command is intended for maintainers to use"
+ @echo "it deletes files that may require special tools to rebuild."
+clean: clean-am
+
+clean-am: clean-generic clean-libtool clean-noinstLTLIBRARIES \
+ mostlyclean-am
+
+distclean: distclean-am
+ -rm -rf ./$(DEPDIR)
+ -rm -f Makefile
+distclean-am: clean-am distclean-compile distclean-generic \
+ distclean-tags
+
+dvi: dvi-am
+
+dvi-am:
+
+html: html-am
+
+info: info-am
+
+info-am:
+
+install-data-am:
+
+install-dvi: install-dvi-am
+
+install-exec-am:
+
+install-html: install-html-am
+
+install-info: install-info-am
+
+install-man:
+
+install-pdf: install-pdf-am
+
+install-ps: install-ps-am
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-am
+ -rm -rf ./$(DEPDIR)
+ -rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-am
+
+mostlyclean-am: mostlyclean-compile mostlyclean-generic \
+ mostlyclean-libtool
+
+pdf: pdf-am
+
+pdf-am:
+
+ps: ps-am
+
+ps-am:
+
+uninstall-am:
+
+.MAKE: install-am install-strip
+
+.PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \
+ clean-libtool clean-noinstLTLIBRARIES ctags distclean \
+ distclean-compile distclean-generic distclean-libtool \
+ distclean-tags distdir dvi dvi-am html html-am info info-am \
+ install install-am install-data install-data-am install-dvi \
+ install-dvi-am install-exec install-exec-am install-html \
+ install-html-am install-info install-info-am install-man \
+ install-pdf install-pdf-am install-ps install-ps-am \
+ install-strip installcheck installcheck-am installdirs \
+ maintainer-clean maintainer-clean-generic mostlyclean \
+ mostlyclean-compile mostlyclean-generic mostlyclean-libtool \
+ pdf pdf-am ps ps-am tags uninstall uninstall-am
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/libXfont/src/stubs/cauthgen.c b/libXfont/src/stubs/cauthgen.c
new file mode 100644
index 000000000..026c52d17
--- /dev/null
+++ b/libXfont/src/stubs/cauthgen.c
@@ -0,0 +1,14 @@
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "stubs.h"
+
+#ifdef __SUNPRO_C
+#pragma weak client_auth_generation
+#endif
+
+weak int
+client_auth_generation(ClientPtr client)
+{
+ return 0;
+}
diff --git a/libXfont/src/stubs/csignal.c b/libXfont/src/stubs/csignal.c
new file mode 100644
index 000000000..e6fdeae1b
--- /dev/null
+++ b/libXfont/src/stubs/csignal.c
@@ -0,0 +1,14 @@
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "stubs.h"
+
+#ifdef __SUNPRO_C
+#pragma weak ClientSignal
+#endif
+
+weak Bool
+ClientSignal(ClientPtr client)
+{
+ return True;
+}
diff --git a/libXfont/src/stubs/delfntcid.c b/libXfont/src/stubs/delfntcid.c
new file mode 100644
index 000000000..ca713286c
--- /dev/null
+++ b/libXfont/src/stubs/delfntcid.c
@@ -0,0 +1,13 @@
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "stubs.h"
+
+#ifdef __SUNPRO_C
+#pragma weak DeleteFontClientID
+#endif
+
+weak void
+DeleteFontClientID(Font id)
+{
+}
diff --git a/libXfont/src/stubs/errorf.c b/libXfont/src/stubs/errorf.c
new file mode 100644
index 000000000..fd32965a4
--- /dev/null
+++ b/libXfont/src/stubs/errorf.c
@@ -0,0 +1,13 @@
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "stubs.h"
+
+#ifdef __SUNPRO_C
+#pragma weak ErrorF
+#endif
+
+weak void
+ErrorF(const char *f, ...)
+{
+}
diff --git a/libXfont/src/stubs/fatalerror.c b/libXfont/src/stubs/fatalerror.c
new file mode 100644
index 000000000..1549ad3ea
--- /dev/null
+++ b/libXfont/src/stubs/fatalerror.c
@@ -0,0 +1,13 @@
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "stubs.h"
+
+#ifdef __SUNPRO_C
+#pragma weak FatalError
+#endif
+
+weak void
+FatalError(const char *f, ...)
+{
+}
diff --git a/libXfont/src/stubs/findoldfnt.c b/libXfont/src/stubs/findoldfnt.c
new file mode 100644
index 000000000..7a0008409
--- /dev/null
+++ b/libXfont/src/stubs/findoldfnt.c
@@ -0,0 +1,14 @@
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "stubs.h"
+
+#ifdef __SUNPRO_C
+#pragma weak find_old_font
+#endif
+
+weak FontPtr
+find_old_font(FSID id)
+{
+ return (FontPtr)NULL;
+}
diff --git a/libXfont/src/stubs/fontmod.c b/libXfont/src/stubs/fontmod.c
new file mode 100644
index 000000000..5a0bd0e9d
--- /dev/null
+++ b/libXfont/src/stubs/fontmod.c
@@ -0,0 +1,14 @@
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#ifdef LOADABLEFONTS
+#include "stubs.h"
+#include <X11/fonts/fontmod.h>
+
+#ifdef __SUNPRO_C
+#pragma weak FontModuleList
+#endif
+
+weak FontModule *FontModuleList;
+#endif /* LOADABLEFONTS */
diff --git a/libXfont/src/stubs/getcres.c b/libXfont/src/stubs/getcres.c
new file mode 100644
index 000000000..0b98f46e3
--- /dev/null
+++ b/libXfont/src/stubs/getcres.c
@@ -0,0 +1,14 @@
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "stubs.h"
+
+#ifdef __SUNPRO_C
+#pragma weak GetClientResolutions
+#endif
+
+weak FontResolutionPtr
+GetClientResolutions(int *num)
+{
+ return (FontResolutionPtr) 0;
+}
diff --git a/libXfont/src/stubs/getdefptsize.c b/libXfont/src/stubs/getdefptsize.c
new file mode 100644
index 000000000..0b9e40999
--- /dev/null
+++ b/libXfont/src/stubs/getdefptsize.c
@@ -0,0 +1,14 @@
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "stubs.h"
+
+#ifdef __SUNPRO_C
+#pragma weak GetDefaultPointSize
+#endif
+
+weak int
+GetDefaultPointSize(void)
+{
+ return 0;
+}
diff --git a/libXfont/src/stubs/getnewfntcid.c b/libXfont/src/stubs/getnewfntcid.c
new file mode 100644
index 000000000..e2fe8bb15
--- /dev/null
+++ b/libXfont/src/stubs/getnewfntcid.c
@@ -0,0 +1,14 @@
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "stubs.h"
+
+#ifdef __SUNPRO_C
+#pragma weak GetNewFontClientID
+#endif
+
+weak Font
+GetNewFontClientID(void)
+{
+ return (Font)0;
+}
diff --git a/libXfont/src/stubs/gettime.c b/libXfont/src/stubs/gettime.c
new file mode 100644
index 000000000..7b2d3b34c
--- /dev/null
+++ b/libXfont/src/stubs/gettime.c
@@ -0,0 +1,14 @@
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "stubs.h"
+
+#ifdef __SUNPRO_C
+#pragma weak GetTimeInMillis
+#endif
+
+weak unsigned long
+GetTimeInMillis (void)
+{
+ return 0;
+}
diff --git a/libXfont/src/stubs/initfshdl.c b/libXfont/src/stubs/initfshdl.c
new file mode 100644
index 000000000..a14dafffc
--- /dev/null
+++ b/libXfont/src/stubs/initfshdl.c
@@ -0,0 +1,15 @@
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "stubs.h"
+
+#ifdef __SUNPRO_C
+#pragma weak init_fs_handlers
+#endif
+
+weak int
+init_fs_handlers(FontPathElementPtr fpe,
+ BlockHandlerProcPtr block_handler)
+{
+ return Successful;
+}
diff --git a/libXfont/src/stubs/regfpefunc.c b/libXfont/src/stubs/regfpefunc.c
new file mode 100644
index 000000000..a79b4bf92
--- /dev/null
+++ b/libXfont/src/stubs/regfpefunc.c
@@ -0,0 +1,28 @@
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "stubs.h"
+
+#ifdef __SUNPRO_C
+#pragma weak RegisterFPEFunctions
+#endif
+
+weak int
+RegisterFPEFunctions(NameCheckFunc name_func,
+ InitFpeFunc init_func,
+ FreeFpeFunc free_func,
+ ResetFpeFunc reset_func,
+ OpenFontFunc open_func,
+ CloseFontFunc close_func,
+ ListFontsFunc list_func,
+ StartLfwiFunc start_lfwi_func,
+ NextLfwiFunc next_lfwi_func,
+ WakeupFpeFunc wakeup_func,
+ ClientDiedFunc client_died,
+ LoadGlyphsFunc load_glyphs,
+ StartLaFunc start_list_alias_func,
+ NextLaFunc next_list_alias_func,
+ SetPathFunc set_path_func)
+{
+ return 0;
+}
diff --git a/libXfont/src/stubs/rmfshdl.c b/libXfont/src/stubs/rmfshdl.c
new file mode 100644
index 000000000..d0bdd3d98
--- /dev/null
+++ b/libXfont/src/stubs/rmfshdl.c
@@ -0,0 +1,15 @@
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "stubs.h"
+
+#ifdef __SUNPRO_C
+#pragma weak remove_fs_handlers
+#endif
+
+weak void
+remove_fs_handlers(FontPathElementPtr fpe,
+ BlockHandlerProcPtr blockHandler,
+ Bool all)
+{
+}
diff --git a/libXfont/src/stubs/servclient.c b/libXfont/src/stubs/servclient.c
new file mode 100644
index 000000000..9b6cebb3f
--- /dev/null
+++ b/libXfont/src/stubs/servclient.c
@@ -0,0 +1,10 @@
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "stubs.h"
+
+#ifdef __SUNPRO_C
+#pragma weak serverClient
+#endif
+
+weak void *serverClient = 0;
diff --git a/libXfont/src/stubs/setfntauth.c b/libXfont/src/stubs/setfntauth.c
new file mode 100644
index 000000000..0c7ecccde
--- /dev/null
+++ b/libXfont/src/stubs/setfntauth.c
@@ -0,0 +1,14 @@
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "stubs.h"
+
+#ifdef __SUNPRO_C
+#pragma weak set_font_authorizations
+#endif
+
+weak int
+set_font_authorizations(char **authorizations, int *authlen, ClientPtr client)
+{
+ return 0;
+}
diff --git a/libXfont/src/stubs/stfntcfnt.c b/libXfont/src/stubs/stfntcfnt.c
new file mode 100644
index 000000000..5fc17452f
--- /dev/null
+++ b/libXfont/src/stubs/stfntcfnt.c
@@ -0,0 +1,14 @@
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "stubs.h"
+
+#ifdef __SUNPRO_C
+#pragma weak StoreFontClientFont
+#endif
+
+weak int
+StoreFontClientFont(FontPtr pfont, Font id)
+{
+ return 0;
+}
diff --git a/libXfont/src/stubs/stubs.h b/libXfont/src/stubs/stubs.h
new file mode 100644
index 000000000..41cde58df
--- /dev/null
+++ b/libXfont/src/stubs/stubs.h
@@ -0,0 +1,31 @@
+/* $XFree86: xc/lib/font/stubs/stubs.h,v 1.3 1999/12/15 01:14:36 robin Exp $ */
+
+#include <stdio.h>
+#include <X11/fonts/fntfilst.h>
+#include <X11/fonts/font.h>
+
+#ifndef True
+#define True (-1)
+#endif
+#ifndef False
+#define False (0)
+#endif
+
+/* this probably works for Mach-O too, but probably not for PE */
+#if defined(__ELF__) && defined(__GNUC__) && (__GNUC__ >= 3)
+#define weak __attribute__((weak))
+#else
+#define weak
+#endif
+
+extern FontPtr find_old_font ( FSID id );
+extern int set_font_authorizations ( char **authorizations,
+ int *authlen,
+ ClientPtr client );
+
+extern unsigned long GetTimeInMillis (void);
+
+extern void ErrorF(const char *format, ...);
+extern void FatalError(const char *format, ...);
+
+/* end of file */
diff --git a/libXfont/src/stubs/xpstubs.c b/libXfont/src/stubs/xpstubs.c
new file mode 100644
index 000000000..939b34f21
--- /dev/null
+++ b/libXfont/src/stubs/xpstubs.c
@@ -0,0 +1,21 @@
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "stubs.h"
+
+#ifdef __SUNPRO_C
+#pragma weak XpClientIsBitmapClient
+#pragma weak XpClientIsPrintClient
+#endif
+
+weak Bool
+XpClientIsBitmapClient(ClientPtr client)
+{
+ return True;
+}
+
+weak Bool
+XpClientIsPrintClient(ClientPtr client, FontPathElementPtr fpe)
+{
+ return False;
+}
diff --git a/libXfont/src/util/Makefile.am b/libXfont/src/util/Makefile.am
new file mode 100644
index 000000000..055fc9d45
--- /dev/null
+++ b/libXfont/src/util/Makefile.am
@@ -0,0 +1,19 @@
+INCLUDES = \
+ -I${top_srcdir}/include \
+ -I$(top_srcdir)/src/stubs
+
+AM_CFLAGS = $(XFONT_CFLAGS) $(OS_CFLAGS) $(CWARNFLAGS)
+
+noinst_LTLIBRARIES = libutil.la
+
+libutil_la_SOURCES = \
+ atom.c \
+ fontaccel.c \
+ fontnames.c \
+ fontutil.c \
+ fontxlfd.c \
+ format.c \
+ miscutil.c \
+ patcache.c \
+ private.c \
+ utilbitmap.c
diff --git a/libXfont/src/util/Makefile.in b/libXfont/src/util/Makefile.in
new file mode 100644
index 000000000..a86e54064
--- /dev/null
+++ b/libXfont/src/util/Makefile.in
@@ -0,0 +1,473 @@
+# Makefile.in generated by automake 1.10 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
+# 2003, 2004, 2005, 2006 Free Software Foundation, Inc.
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+@SET_MAKE@
+
+VPATH = @srcdir@
+pkgdatadir = $(datadir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+install_sh_DATA = $(install_sh) -c -m 644
+install_sh_PROGRAM = $(install_sh) -c
+install_sh_SCRIPT = $(install_sh) -c
+INSTALL_HEADER = $(INSTALL_DATA)
+transform = $(program_transform_name)
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+build_triplet = @build@
+host_triplet = @host@
+subdir = src/util
+DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/configure.ac
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+ $(ACLOCAL_M4)
+mkinstalldirs = $(install_sh) -d
+CONFIG_HEADER = $(top_builddir)/config.h \
+ $(top_builddir)/include/X11/fonts/fontconf.h
+CONFIG_CLEAN_FILES =
+LTLIBRARIES = $(noinst_LTLIBRARIES)
+libutil_la_LIBADD =
+am_libutil_la_OBJECTS = atom.lo fontaccel.lo fontnames.lo fontutil.lo \
+ fontxlfd.lo format.lo miscutil.lo patcache.lo private.lo \
+ utilbitmap.lo
+libutil_la_OBJECTS = $(am_libutil_la_OBJECTS)
+DEFAULT_INCLUDES = -I. -I$(top_builddir) -I$(top_builddir)/include/X11/fonts@am__isrc@
+depcomp = $(SHELL) $(top_srcdir)/depcomp
+am__depfiles_maybe = depfiles
+COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
+ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+LTCOMPILE = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
+ --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \
+ $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+CCLD = $(CC)
+LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
+ --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \
+ $(LDFLAGS) -o $@
+SOURCES = $(libutil_la_SOURCES)
+DIST_SOURCES = $(libutil_la_SOURCES)
+ETAGS = etags
+CTAGS = ctags
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+ACLOCAL = @ACLOCAL@
+AMTAR = @AMTAR@
+AR = @AR@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+CC = @CC@
+CCDEPMODE = @CCDEPMODE@
+CFLAGS = @CFLAGS@
+CHANGELOG_CMD = @CHANGELOG_CMD@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CWARNFLAGS = @CWARNFLAGS@
+CXX = @CXX@
+CXXCPP = @CXXCPP@
+CXXDEPMODE = @CXXDEPMODE@
+CXXFLAGS = @CXXFLAGS@
+CYGPATH_W = @CYGPATH_W@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+ECHO = @ECHO@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+EGREP = @EGREP@
+ENCODINGSDIR = @ENCODINGSDIR@
+EXEEXT = @EXEEXT@
+F77 = @F77@
+FFLAGS = @FFLAGS@
+FREETYPE_CFLAGS = @FREETYPE_CFLAGS@
+FREETYPE_LIBS = @FREETYPE_LIBS@
+FREETYPE_REQUIRES = @FREETYPE_REQUIRES@
+GREP = @GREP@
+INSTALL = @INSTALL@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+LDFLAGS = @LDFLAGS@
+LIBOBJS = @LIBOBJS@
+LIBS = @LIBS@
+LIBTOOL = @LIBTOOL@
+LN_S = @LN_S@
+LTLIBOBJS = @LTLIBOBJS@
+MAKEINFO = @MAKEINFO@
+MATH_LIBS = @MATH_LIBS@
+MKDIR_P = @MKDIR_P@
+OBJEXT = @OBJEXT@
+OS_CFLAGS = @OS_CFLAGS@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+PKG_CONFIG = @PKG_CONFIG@
+RANLIB = @RANLIB@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+STRIP = @STRIP@
+VERSION = @VERSION@
+XFONT_CFLAGS = @XFONT_CFLAGS@
+XFONT_LIBS = @XFONT_LIBS@
+X_GZIP_FONT_COMPRESSION = @X_GZIP_FONT_COMPRESSION@
+Z_LIBS = @Z_LIBS@
+abs_builddir = @abs_builddir@
+abs_srcdir = @abs_srcdir@
+abs_top_builddir = @abs_top_builddir@
+abs_top_srcdir = @abs_top_srcdir@
+ac_ct_CC = @ac_ct_CC@
+ac_ct_CXX = @ac_ct_CXX@
+ac_ct_F77 = @ac_ct_F77@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+am__tar = @am__tar@
+am__untar = @am__untar@
+bindir = @bindir@
+build = @build@
+build_alias = @build_alias@
+build_cpu = @build_cpu@
+build_os = @build_os@
+build_vendor = @build_vendor@
+builddir = @builddir@
+datadir = @datadir@
+datarootdir = @datarootdir@
+distcleancheck_listfiles = @distcleancheck_listfiles@
+docdir = @docdir@
+dvidir = @dvidir@
+exec_prefix = @exec_prefix@
+ft_config = @ft_config@
+host = @host@
+host_alias = @host_alias@
+host_cpu = @host_cpu@
+host_os = @host_os@
+host_vendor = @host_vendor@
+htmldir = @htmldir@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+libdir = @libdir@
+libexecdir = @libexecdir@
+localedir = @localedir@
+localstatedir = @localstatedir@
+mandir = @mandir@
+mkdir_p = @mkdir_p@
+oldincludedir = @oldincludedir@
+pdfdir = @pdfdir@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+psdir = @psdir@
+sbindir = @sbindir@
+sharedstatedir = @sharedstatedir@
+srcdir = @srcdir@
+sysconfdir = @sysconfdir@
+target_alias = @target_alias@
+top_builddir = @top_builddir@
+top_srcdir = @top_srcdir@
+INCLUDES = \
+ -I${top_srcdir}/include \
+ -I$(top_srcdir)/src/stubs
+
+AM_CFLAGS = $(XFONT_CFLAGS) $(OS_CFLAGS) $(CWARNFLAGS)
+noinst_LTLIBRARIES = libutil.la
+libutil_la_SOURCES = \
+ atom.c \
+ fontaccel.c \
+ fontnames.c \
+ fontutil.c \
+ fontxlfd.c \
+ format.c \
+ miscutil.c \
+ patcache.c \
+ private.c \
+ utilbitmap.c
+
+all: all-am
+
+.SUFFIXES:
+.SUFFIXES: .c .lo .o .obj
+$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps)
+ @for dep in $?; do \
+ case '$(am__configure_deps)' in \
+ *$$dep*) \
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh \
+ && exit 0; \
+ exit 1;; \
+ esac; \
+ done; \
+ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign src/util/Makefile'; \
+ cd $(top_srcdir) && \
+ $(AUTOMAKE) --foreign src/util/Makefile
+.PRECIOUS: Makefile
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+ @case '$?' in \
+ *config.status*) \
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
+ *) \
+ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
+ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
+ esac;
+
+$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+
+$(top_srcdir)/configure: $(am__configure_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(ACLOCAL_M4): $(am__aclocal_m4_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+
+clean-noinstLTLIBRARIES:
+ -test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES)
+ @list='$(noinst_LTLIBRARIES)'; for p in $$list; do \
+ dir="`echo $$p | sed -e 's|/[^/]*$$||'`"; \
+ test "$$dir" != "$$p" || dir=.; \
+ echo "rm -f \"$${dir}/so_locations\""; \
+ rm -f "$${dir}/so_locations"; \
+ done
+libutil.la: $(libutil_la_OBJECTS) $(libutil_la_DEPENDENCIES)
+ $(LINK) $(libutil_la_OBJECTS) $(libutil_la_LIBADD) $(LIBS)
+
+mostlyclean-compile:
+ -rm -f *.$(OBJEXT)
+
+distclean-compile:
+ -rm -f *.tab.c
+
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/atom.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fontaccel.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fontnames.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fontutil.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fontxlfd.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/format.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/miscutil.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/patcache.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/private.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/utilbitmap.Plo@am__quote@
+
+.c.o:
+@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
+@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(COMPILE) -c $<
+
+.c.obj:
+@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'`
+@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(COMPILE) -c `$(CYGPATH_W) '$<'`
+
+.c.lo:
+@am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
+@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(LTCOMPILE) -c -o $@ $<
+
+mostlyclean-libtool:
+ -rm -f *.lo
+
+clean-libtool:
+ -rm -rf .libs _libs
+
+ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) ' { files[$$0] = 1; } \
+ END { for (i in files) print i; }'`; \
+ mkid -fID $$unique
+tags: TAGS
+
+TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
+ $(TAGS_FILES) $(LISP)
+ tags=; \
+ here=`pwd`; \
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) ' { files[$$0] = 1; } \
+ END { for (i in files) print i; }'`; \
+ if test -z "$(ETAGS_ARGS)$$tags$$unique"; then :; else \
+ test -n "$$unique" || unique=$$empty_fix; \
+ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+ $$tags $$unique; \
+ fi
+ctags: CTAGS
+CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
+ $(TAGS_FILES) $(LISP)
+ tags=; \
+ here=`pwd`; \
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) ' { files[$$0] = 1; } \
+ END { for (i in files) print i; }'`; \
+ test -z "$(CTAGS_ARGS)$$tags$$unique" \
+ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
+ $$tags $$unique
+
+GTAGS:
+ here=`$(am__cd) $(top_builddir) && pwd` \
+ && cd $(top_srcdir) \
+ && gtags -i $(GTAGS_ARGS) $$here
+
+distclean-tags:
+ -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
+
+distdir: $(DISTFILES)
+ @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ list='$(DISTFILES)'; \
+ dist_files=`for file in $$list; do echo $$file; done | \
+ sed -e "s|^$$srcdirstrip/||;t" \
+ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
+ case $$dist_files in \
+ */*) $(MKDIR_P) `echo "$$dist_files" | \
+ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
+ sort -u` ;; \
+ esac; \
+ for file in $$dist_files; do \
+ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
+ if test -d $$d/$$file; then \
+ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
+ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
+ cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \
+ fi; \
+ cp -pR $$d/$$file $(distdir)$$dir || exit 1; \
+ else \
+ test -f $(distdir)/$$file \
+ || cp -p $$d/$$file $(distdir)/$$file \
+ || exit 1; \
+ fi; \
+ done
+check-am: all-am
+check: check-am
+all-am: Makefile $(LTLIBRARIES)
+installdirs:
+install: install-am
+install-exec: install-exec-am
+install-data: install-data-am
+uninstall: uninstall-am
+
+install-am: all-am
+ @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-am
+install-strip:
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ `test -z '$(STRIP)' || \
+ echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
+mostlyclean-generic:
+
+clean-generic:
+
+distclean-generic:
+ -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
+
+maintainer-clean-generic:
+ @echo "This command is intended for maintainers to use"
+ @echo "it deletes files that may require special tools to rebuild."
+clean: clean-am
+
+clean-am: clean-generic clean-libtool clean-noinstLTLIBRARIES \
+ mostlyclean-am
+
+distclean: distclean-am
+ -rm -rf ./$(DEPDIR)
+ -rm -f Makefile
+distclean-am: clean-am distclean-compile distclean-generic \
+ distclean-tags
+
+dvi: dvi-am
+
+dvi-am:
+
+html: html-am
+
+info: info-am
+
+info-am:
+
+install-data-am:
+
+install-dvi: install-dvi-am
+
+install-exec-am:
+
+install-html: install-html-am
+
+install-info: install-info-am
+
+install-man:
+
+install-pdf: install-pdf-am
+
+install-ps: install-ps-am
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-am
+ -rm -rf ./$(DEPDIR)
+ -rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-am
+
+mostlyclean-am: mostlyclean-compile mostlyclean-generic \
+ mostlyclean-libtool
+
+pdf: pdf-am
+
+pdf-am:
+
+ps: ps-am
+
+ps-am:
+
+uninstall-am:
+
+.MAKE: install-am install-strip
+
+.PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \
+ clean-libtool clean-noinstLTLIBRARIES ctags distclean \
+ distclean-compile distclean-generic distclean-libtool \
+ distclean-tags distdir dvi dvi-am html html-am info info-am \
+ install install-am install-data install-data-am install-dvi \
+ install-dvi-am install-exec install-exec-am install-html \
+ install-html-am install-info install-info-am install-man \
+ install-pdf install-pdf-am install-ps install-ps-am \
+ install-strip installcheck installcheck-am installdirs \
+ maintainer-clean maintainer-clean-generic mostlyclean \
+ mostlyclean-compile mostlyclean-generic mostlyclean-libtool \
+ pdf pdf-am ps ps-am tags uninstall uninstall-am
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/libXfont/src/util/atom.c b/libXfont/src/util/atom.c
new file mode 100644
index 000000000..b770dc9de
--- /dev/null
+++ b/libXfont/src/util/atom.c
@@ -0,0 +1,246 @@
+/* $Xorg: atom.c,v 1.5 2001/02/09 02:04:04 xorgcvs Exp $ */
+
+/*
+
+Copyright 1990, 1994, 1998 The Open Group
+
+Permission to use, copy, modify, distribute, and sell this software and its
+documentation for any purpose is hereby granted without fee, provided that
+the above copyright notice appear in all copies and that both that
+copyright notice and this permission notice appear in supporting
+documentation.
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of The Open Group shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from The Open Group.
+
+*/
+/* $XFree86: xc/lib/font/util/atom.c,v 1.9 2002/09/19 13:22:00 tsi Exp $ */
+
+/*
+ * Author: Keith Packard, MIT X Consortium
+ */
+
+/* lame atom replacement routines for font applications */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include <X11/fonts/fontmisc.h>
+#include "stubs.h"
+
+typedef struct _AtomList {
+ char *name;
+ int len;
+ int hash;
+ Atom atom;
+} AtomListRec, *AtomListPtr;
+
+static AtomListPtr *hashTable;
+
+static int hashSize, hashUsed;
+static int hashMask;
+static int rehash;
+
+static AtomListPtr *reverseMap;
+static int reverseMapSize;
+static Atom lastAtom;
+
+static int
+Hash(char *string, int len)
+{
+ int h;
+
+ h = 0;
+ while (len--)
+ h = (h << 3) ^ *string++;
+ if (h < 0)
+ return -h;
+ return h;
+}
+
+static int
+ResizeHashTable (void)
+{
+ int newHashSize;
+ int newHashMask;
+ AtomListPtr *newHashTable;
+ int i;
+ int h;
+ int newRehash;
+ int r;
+
+ if (hashSize == 0)
+ newHashSize = 1024;
+ else
+ newHashSize = hashSize * 2;
+ newHashTable = (AtomListPtr *) xalloc (newHashSize * sizeof (AtomListPtr));
+ if (!newHashTable) {
+ fprintf(stderr, "ResizeHashTable(): Error: Couldn't allocate"
+ " newHashTable (%ld)\n",
+ newHashSize * (unsigned long)sizeof (AtomListPtr));
+ return FALSE;
+ }
+ bzero ((char *) newHashTable, newHashSize * sizeof (AtomListPtr));
+ newHashMask = newHashSize - 1;
+ newRehash = (newHashMask - 2);
+ for (i = 0; i < hashSize; i++)
+ {
+ if (hashTable[i])
+ {
+ h = (hashTable[i]->hash) & newHashMask;
+ if (newHashTable[h])
+ {
+ r = hashTable[i]->hash % newRehash | 1;
+ do {
+ h += r;
+ if (h >= newHashSize)
+ h -= newHashSize;
+ } while (newHashTable[h]);
+ }
+ newHashTable[h] = hashTable[i];
+ }
+ }
+ xfree (hashTable);
+ hashTable = newHashTable;
+ hashSize = newHashSize;
+ hashMask = newHashMask;
+ rehash = newRehash;
+ return TRUE;
+}
+
+static int
+ResizeReverseMap (void)
+{
+ int ret = TRUE;
+ if (reverseMapSize == 0)
+ reverseMapSize = 1000;
+ else
+ reverseMapSize *= 2;
+ reverseMap = (AtomListPtr *) xrealloc (reverseMap, reverseMapSize * sizeof (AtomListPtr));
+ if (!reverseMap) {
+ fprintf(stderr, "ResizeReverseMap(): Error: Couldn't reallocate"
+ " reverseMap (%ld)\n",
+ reverseMapSize * (unsigned long)sizeof(AtomListPtr));
+ ret = FALSE;
+ }
+ return ret;
+}
+
+static int
+NameEqual (const char *a, const char *b, int l)
+{
+ while (l--)
+ if (*a++ != *b++)
+ return FALSE;
+ return TRUE;
+}
+
+#ifdef __SUNPRO_C
+#pragma weak MakeAtom
+#endif
+
+weak Atom
+MakeAtom(char *string, unsigned len, int makeit)
+{
+ AtomListPtr a;
+ int hash;
+ int h = 0;
+ int r;
+
+ hash = Hash (string, len);
+ if (hashTable)
+ {
+ h = hash & hashMask;
+ if (hashTable[h])
+ {
+ if (hashTable[h]->hash == hash && hashTable[h]->len == len &&
+ NameEqual (hashTable[h]->name, string, len))
+ {
+ return hashTable[h]->atom;
+ }
+ r = (hash % rehash) | 1;
+ for (;;)
+ {
+ h += r;
+ if (h >= hashSize)
+ h -= hashSize;
+ if (!hashTable[h])
+ break;
+ if (hashTable[h]->hash == hash && hashTable[h]->len == len &&
+ NameEqual (hashTable[h]->name, string, len))
+ {
+ return hashTable[h]->atom;
+ }
+ }
+ }
+ }
+ if (!makeit)
+ return None;
+ a = (AtomListPtr) xalloc (sizeof (AtomListRec) + len + 1);
+ if (a == NULL) {
+ fprintf(stderr, "MakeAtom(): Error: Couldn't allocate AtomListRec"
+ " (%ld)\n", (unsigned long)sizeof (AtomListRec) + len + 1);
+ return None;
+ }
+ a->name = (char *) (a + 1);
+ a->len = len;
+ strncpy (a->name, string, len);
+ a->name[len] = '\0';
+ a->atom = ++lastAtom;
+ a->hash = hash;
+ if (hashUsed >= hashSize / 2)
+ {
+ ResizeHashTable ();
+ h = hash & hashMask;
+ if (hashTable[h])
+ {
+ r = (hash % rehash) | 1;
+ do {
+ h += r;
+ if (h >= hashSize)
+ h -= hashSize;
+ } while (hashTable[h]);
+ }
+ }
+ hashTable[h] = a;
+ hashUsed++;
+ if (reverseMapSize <= a->atom) {
+ if (!ResizeReverseMap())
+ return None;
+ }
+ reverseMap[a->atom] = a;
+ return a->atom;
+}
+
+#ifdef __SUNPRO_C
+#pragma weak ValidAtom
+#endif
+
+weak int
+ValidAtom(Atom atom)
+{
+ return (atom != None) && (atom <= lastAtom);
+}
+
+#ifdef __SUNPRO_C
+#pragma weak NameForAtom
+#endif
+
+weak char *
+NameForAtom(Atom atom)
+{
+ if (atom != None && atom <= lastAtom)
+ return reverseMap[atom]->name;
+ return NULL;
+}
diff --git a/libXfont/src/util/fontaccel.c b/libXfont/src/util/fontaccel.c
new file mode 100644
index 000000000..c37f69a39
--- /dev/null
+++ b/libXfont/src/util/fontaccel.c
@@ -0,0 +1,107 @@
+/* $Xorg: fontaccel.c,v 1.4 2001/02/09 02:04:04 xorgcvs Exp $ */
+
+/*
+
+Copyright 1990, 1998 The Open Group
+
+Permission to use, copy, modify, distribute, and sell this software and its
+documentation for any purpose is hereby granted without fee, provided that
+the above copyright notice appear in all copies and that both that
+copyright notice and this permission notice appear in supporting
+documentation.
+
+The above copyright notice and this permission notice shall be included
+in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+IN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR
+OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of The Open Group shall
+not be used in advertising or otherwise to promote the sale, use or
+other dealings in this Software without prior written authorization
+from The Open Group.
+
+*/
+/* $XFree86: xc/lib/font/util/fontaccel.c,v 1.6 2001/01/17 19:43:33 dawes Exp $ */
+
+/*
+ * Author: Keith Packard, MIT X Consortium
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include <X11/fonts/fontmisc.h>
+#include <X11/fonts/fontstruct.h>
+#include <X11/fonts/fontutil.h>
+
+void
+FontComputeInfoAccelerators(FontInfoPtr pFontInfo)
+{
+ pFontInfo->noOverlap = FALSE;
+ if (pFontInfo->maxOverlap <= pFontInfo->minbounds.leftSideBearing)
+ pFontInfo->noOverlap = TRUE;
+
+ if ((pFontInfo->minbounds.ascent == pFontInfo->maxbounds.ascent) &&
+ (pFontInfo->minbounds.descent == pFontInfo->maxbounds.descent) &&
+ (pFontInfo->minbounds.leftSideBearing ==
+ pFontInfo->maxbounds.leftSideBearing) &&
+ (pFontInfo->minbounds.rightSideBearing ==
+ pFontInfo->maxbounds.rightSideBearing) &&
+ (pFontInfo->minbounds.characterWidth ==
+ pFontInfo->maxbounds.characterWidth) &&
+ (pFontInfo->minbounds.attributes == pFontInfo->maxbounds.attributes)) {
+ pFontInfo->constantMetrics = TRUE;
+ if ((pFontInfo->maxbounds.leftSideBearing == 0) &&
+ (pFontInfo->maxbounds.rightSideBearing ==
+ pFontInfo->maxbounds.characterWidth) &&
+ (pFontInfo->maxbounds.ascent == pFontInfo->fontAscent) &&
+ (pFontInfo->maxbounds.descent == pFontInfo->fontDescent))
+ pFontInfo->terminalFont = TRUE;
+ else
+ pFontInfo->terminalFont = FALSE;
+ } else {
+ pFontInfo->constantMetrics = FALSE;
+ pFontInfo->terminalFont = FALSE;
+ }
+ if (pFontInfo->minbounds.characterWidth == pFontInfo->maxbounds.characterWidth)
+ pFontInfo->constantWidth = TRUE;
+ else
+ pFontInfo->constantWidth = FALSE;
+
+ if ((pFontInfo->minbounds.leftSideBearing >= 0) &&
+ (pFontInfo->maxOverlap <= 0) &&
+ (pFontInfo->minbounds.ascent >= -pFontInfo->fontDescent) &&
+ (pFontInfo->maxbounds.ascent <= pFontInfo->fontAscent) &&
+ (-pFontInfo->minbounds.descent <= pFontInfo->fontAscent) &&
+ (pFontInfo->maxbounds.descent <= pFontInfo->fontDescent))
+ pFontInfo->inkInside = TRUE;
+ else
+ pFontInfo->inkInside = FALSE;
+}
+
+int
+FontCouldBeTerminal(FontInfoPtr pFontInfo)
+{
+ if ((pFontInfo->minbounds.leftSideBearing >= 0) &&
+ (pFontInfo->maxbounds.rightSideBearing <= pFontInfo->maxbounds.characterWidth) &&
+ (pFontInfo->minbounds.characterWidth == pFontInfo->maxbounds.characterWidth) &&
+ (pFontInfo->maxbounds.ascent <= pFontInfo->fontAscent) &&
+ (pFontInfo->maxbounds.descent <= pFontInfo->fontDescent) &&
+ (pFontInfo->maxbounds.leftSideBearing != 0 ||
+ pFontInfo->minbounds.rightSideBearing != pFontInfo->minbounds.characterWidth ||
+ pFontInfo->minbounds.ascent != pFontInfo->fontAscent ||
+ pFontInfo->minbounds.descent != pFontInfo->fontDescent)) {
+ /* blow off font with nothing but a SPACE */
+ if (pFontInfo->maxbounds.ascent == 0 &&
+ pFontInfo->maxbounds.descent == 0)
+ return FALSE;
+ return TRUE;
+ }
+ return FALSE;
+}
diff --git a/libXfont/src/util/fontnames.c b/libXfont/src/util/fontnames.c
new file mode 100644
index 000000000..2d3a51752
--- /dev/null
+++ b/libXfont/src/util/fontnames.c
@@ -0,0 +1,123 @@
+/* $Xorg: fontnames.c,v 1.4 2001/02/09 02:04:04 xorgcvs Exp $ */
+
+/*
+
+Copyright 1991, 1998 The Open Group
+
+Permission to use, copy, modify, distribute, and sell this software and its
+documentation for any purpose is hereby granted without fee, provided that
+the above copyright notice appear in all copies and that both that
+copyright notice and this permission notice appear in supporting
+documentation.
+
+The above copyright notice and this permission notice shall be included
+in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+IN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR
+OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of The Open Group shall
+not be used in advertising or otherwise to promote the sale, use or
+other dealings in this Software without prior written authorization
+from The Open Group.
+
+*/
+/* $XFree86: xc/lib/font/util/fontnames.c,v 1.4 2001/01/17 19:43:33 dawes Exp $ */
+
+/*
+ * Author: Keith Packard, MIT X Consortium
+ *
+ * @(#)fontnames.c 3.1 91/04/10
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include <X11/fonts/fontmisc.h>
+#include <X11/fonts/fontstruct.h>
+
+void
+FreeFontNames(FontNamesPtr pFN)
+{
+ int i;
+
+ if (!pFN)
+ return;
+ for (i = 0; i < pFN->nnames; i++) {
+ xfree(pFN->names[i]);
+ }
+ xfree(pFN->names);
+ xfree(pFN->length);
+ xfree(pFN);
+}
+
+FontNamesPtr
+MakeFontNamesRecord(unsigned int size)
+{
+ FontNamesPtr pFN;
+
+ pFN = (FontNamesPtr) xalloc(sizeof(FontNamesRec));
+ if (pFN) {
+ pFN->nnames = 0;
+ pFN->size = size;
+ if (size)
+ {
+ pFN->length = (int *) xalloc(size * sizeof(int));
+ pFN->names = (char **) xalloc(size * sizeof(char *));
+ if (!pFN->length || !pFN->names) {
+ xfree(pFN->length);
+ xfree(pFN->names);
+ xfree(pFN);
+ pFN = (FontNamesPtr) 0;
+ }
+ }
+ else
+ {
+ pFN->length = 0;
+ pFN->names = 0;
+ }
+ }
+ return pFN;
+}
+
+int
+AddFontNamesName(FontNamesPtr names, char *name, int length)
+{
+ int index = names->nnames;
+ char *nelt;
+
+ nelt = (char *) xalloc(length + 1);
+ if (!nelt)
+ return AllocError;
+ if (index >= names->size) {
+ int size = names->size << 1;
+ int *nlength;
+ char **nnames;
+
+ if (size == 0)
+ size = 8;
+ nlength = (int *) xrealloc(names->length, size * sizeof(int));
+ nnames = (char **) xrealloc(names->names, size * sizeof(char *));
+ if (nlength && nnames) {
+ names->size = size;
+ names->length = nlength;
+ names->names = nnames;
+ } else {
+ xfree(nelt);
+ xfree(nlength);
+ xfree(nnames);
+ return AllocError;
+ }
+ }
+ names->length[index] = length;
+ names->names[index] = nelt;
+ strncpy(nelt, name, length);
+ nelt[length] = '\0';
+ names->nnames++;
+ return Successful;
+}
diff --git a/libXfont/src/util/fontutil.c b/libXfont/src/util/fontutil.c
new file mode 100644
index 000000000..05fe5c2f2
--- /dev/null
+++ b/libXfont/src/util/fontutil.c
@@ -0,0 +1,443 @@
+/* $Xorg: fontutil.c,v 1.4 2001/02/09 02:04:04 xorgcvs Exp $ */
+
+/*
+
+Copyright 1991, 1998 The Open Group
+
+Permission to use, copy, modify, distribute, and sell this software and its
+documentation for any purpose is hereby granted without fee, provided that
+the above copyright notice appear in all copies and that both that
+copyright notice and this permission notice appear in supporting
+documentation.
+
+The above copyright notice and this permission notice shall be included
+in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+IN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR
+OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of The Open Group shall
+not be used in advertising or otherwise to promote the sale, use or
+other dealings in this Software without prior written authorization
+from The Open Group.
+
+*/
+/* $XFree86: xc/lib/font/util/fontutil.c,v 3.6 2001/10/28 03:32:46 tsi Exp $ */
+
+/*
+ * Author: Keith Packard, MIT X Consortium
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include <X11/fonts/fontmisc.h>
+#include <X11/fonts/fontstruct.h>
+#include <X11/fonts/FSproto.h>
+#include <X11/fonts/fontutil.h>
+
+/* Define global here... doesn't hurt the servers, and avoids
+ unresolved references in font clients. */
+
+static int defaultGlyphCachingMode = DEFAULT_GLYPH_CACHING_MODE;
+int glyphCachingMode = DEFAULT_GLYPH_CACHING_MODE;
+
+void
+GetGlyphs(FontPtr font,
+ unsigned long count,
+ unsigned char *chars,
+ FontEncoding fontEncoding,
+ unsigned long *glyphcount, /* RETURN */
+ CharInfoPtr *glyphs) /* RETURN */
+{
+ (*font->get_glyphs) (font, count, chars, fontEncoding, glyphcount, glyphs);
+}
+
+#define MIN(a,b) ((a)<(b)?(a):(b))
+#define MAX(a,b) ((a)>(b)?(a):(b))
+
+void
+QueryGlyphExtents(FontPtr pFont,
+ CharInfoPtr *charinfo,
+ unsigned long count,
+ ExtentInfoRec *info)
+{
+ register unsigned long i;
+ xCharInfo *pCI;
+
+ info->drawDirection = pFont->info.drawDirection;
+
+ info->fontAscent = pFont->info.fontAscent;
+ info->fontDescent = pFont->info.fontDescent;
+
+ if (count != 0) {
+
+ pCI = &((*charinfo)->metrics); charinfo++;
+ /* ignore nonexisting characters when calculating text extents */
+ if ( !((pCI->characterWidth == 0)
+ && (pCI->rightSideBearing == 0)
+ && (pCI->leftSideBearing == 0)
+ && (pCI->ascent == 0)
+ && (pCI->descent == 0)) ) {
+ info->overallAscent = pCI->ascent;
+ info->overallDescent = pCI->descent;
+ info->overallLeft = pCI->leftSideBearing;
+ info->overallRight = pCI->rightSideBearing;
+ info->overallWidth = pCI->characterWidth;
+ }
+
+ if (pFont->info.constantMetrics && pFont->info.noOverlap) {
+ info->overallWidth *= count;
+ info->overallRight += (info->overallWidth -
+ pCI->characterWidth);
+ } else {
+ for (i = 1; i < count; i++) {
+ pCI = &((*charinfo)->metrics); charinfo++;
+ /* ignore nonexisting characters when calculating extents */
+ if ( !((pCI->characterWidth == 0)
+ && (pCI->rightSideBearing == 0)
+ && (pCI->leftSideBearing == 0)
+ && (pCI->ascent == 0)
+ && (pCI->descent == 0)) ) {
+ info->overallAscent = MAX(
+ info->overallAscent,
+ pCI->ascent);
+ info->overallDescent = MAX(
+ info->overallDescent,
+ pCI->descent);
+ info->overallLeft = MIN(
+ info->overallLeft,
+ info->overallWidth + pCI->leftSideBearing);
+ info->overallRight = MAX(
+ info->overallRight,
+ info->overallWidth + pCI->rightSideBearing);
+ /*
+ * yes, this order is correct; overallWidth IS incremented
+ * last
+ */
+ info->overallWidth += pCI->characterWidth;
+ }
+ }
+ }
+ } else {
+ info->overallAscent = 0;
+ info->overallDescent = 0;
+ info->overallWidth = 0;
+ info->overallLeft = 0;
+ info->overallRight = 0;
+ }
+}
+
+Bool
+QueryTextExtents(FontPtr pFont,
+ unsigned long count,
+ unsigned char *chars,
+ ExtentInfoRec *info)
+{
+ xCharInfo **charinfo;
+ unsigned long n;
+ FontEncoding encoding;
+ int cm;
+ int i;
+ unsigned long t;
+ xCharInfo *defaultChar = 0;
+ unsigned char defc[2];
+ int firstReal;
+
+ charinfo = (xCharInfo **) xalloc(count * sizeof(xCharInfo *));
+ if (!charinfo)
+ return FALSE;
+ encoding = TwoD16Bit;
+ if (pFont->info.lastRow == 0)
+ encoding = Linear16Bit;
+ (*pFont->get_metrics) (pFont, count, chars, encoding, &n, charinfo);
+
+ /* Do default character substitution as get_metrics doesn't */
+
+#define IsNonExistentChar(ci) (!(ci) || \
+ ((ci)->ascent == 0 && \
+ (ci)->descent == 0 && \
+ (ci)->leftSideBearing == 0 && \
+ (ci)->rightSideBearing == 0 && \
+ (ci)->characterWidth == 0))
+
+ firstReal = n;
+ defc[0] = pFont->info.defaultCh >> 8;
+ defc[1] = pFont->info.defaultCh;
+ (*pFont->get_metrics) (pFont, 1, defc, encoding, &t, &defaultChar);
+ if ((IsNonExistentChar (defaultChar)))
+ defaultChar = 0;
+ for (i = 0; i < n; i++)
+ {
+ if ((IsNonExistentChar (charinfo[i])))
+ {
+ if (!defaultChar)
+ continue;
+ charinfo[i] = defaultChar;
+ }
+ if (firstReal == n)
+ firstReal = i;
+ }
+ cm = pFont->info.constantMetrics;
+ pFont->info.constantMetrics = FALSE;
+ QueryGlyphExtents(pFont, (CharInfoPtr*) charinfo + firstReal,
+ n - firstReal, info);
+ pFont->info.constantMetrics = cm;
+ xfree(charinfo);
+ return TRUE;
+}
+
+Bool
+ParseGlyphCachingMode(char *str)
+{
+ if (!strcmp(str, "none")) defaultGlyphCachingMode = CACHING_OFF;
+ else if (!strcmp(str, "all")) defaultGlyphCachingMode = CACHE_ALL_GLYPHS;
+ else if (!strcmp(str, "16")) defaultGlyphCachingMode = CACHE_16_BIT_GLYPHS;
+ else return FALSE;
+ return TRUE;
+}
+
+void
+InitGlyphCaching(void)
+{
+ /* Set glyphCachingMode to the mode the server hopes to
+ support. DDX drivers that do not support the requested level
+ of glyph caching can call SetGlyphCachingMode to lower the
+ level of support.
+ */
+
+ glyphCachingMode = defaultGlyphCachingMode;
+}
+
+/* ddxen can call SetGlyphCachingMode to inform us of what level of glyph
+ * caching they can support.
+ */
+void
+SetGlyphCachingMode(int newmode)
+{
+ if ( (glyphCachingMode > newmode) && (newmode >= 0) )
+ glyphCachingMode = newmode;
+}
+
+#define range_alloc_granularity 16
+#define mincharp(p) ((p)->min_char_low + ((p)->min_char_high << 8))
+#define maxcharp(p) ((p)->max_char_low + ((p)->max_char_high << 8))
+
+/* add_range(): Add range to a list of ranges, with coalescence */
+int
+add_range(fsRange *newrange,
+ int *nranges,
+ fsRange **range,
+ Bool charset_subset)
+{
+ int first, last, middle;
+ unsigned long keymin, keymax;
+ unsigned long ptrmin = 0, ptrmax = 0;
+ fsRange *ptr = NULL, *ptr1, *ptr2, *endptr;
+
+ /* There are two different ways to treat ranges:
+
+ 1) Charset subsetting (support of the HP XLFD enhancements), in
+ which a range of 0x1234,0x3456 means all numbers between
+ 0x1234 and 0x3456, and in which min and max might be swapped.
+
+ 2) Row/column ranges, in which a range of 0x1234,0x3456 means the
+ ranges 0x1234-0x1256, 0x1334-0x1356, ... , 0x3434-0x3456.
+ This is for support of glyph caching.
+
+ The choice of treatment is selected with the "charset_subset"
+ flag */
+
+ /* If newrange covers multiple rows; break up the rows */
+ if (!charset_subset && newrange->min_char_high != newrange->max_char_high)
+ {
+ int i, err = 0;
+ fsRange temprange;
+ for (i = newrange->min_char_high;
+ i <= newrange->max_char_high;
+ i++)
+ {
+ temprange.min_char_low = newrange->min_char_low;
+ temprange.max_char_low = newrange->max_char_low;
+ temprange.min_char_high = temprange.max_char_high = i;
+ err = add_range(&temprange, nranges, range, charset_subset);
+ if (err != Successful) break;
+ }
+ return err;
+ }
+
+ keymin = mincharp(newrange);
+ keymax = maxcharp(newrange);
+
+ if (charset_subset && keymin > keymax)
+ {
+ unsigned long temp = keymin;
+ keymin = keymax;
+ keymax = temp;
+ }
+
+ /* add_range() maintains a sorted list; this makes possible coalescence
+ and binary searches */
+
+ /* Binary search for a range with which the new range can merge */
+
+ first = middle = 0;
+ last = *nranges - 1;
+ while (last >= first)
+ {
+ middle = (first + last) / 2;
+ ptr = (*range) + middle;
+ ptrmin = mincharp(ptr);
+ ptrmax = maxcharp(ptr);
+
+ if (ptrmin > 0 && keymax < ptrmin - 1) last = middle - 1;
+ else if (keymin > ptrmax + 1) first = middle + 1;
+ else if (!charset_subset)
+ {
+ /* We might have a range with which to merge... IF the
+ result doesn't cross rows */
+ if (newrange->min_char_high != ptr->min_char_high)
+ last = first - 1; /* Force adding a new range */
+ break;
+ }
+ else break; /* We have at least one range with which we can merge */
+ }
+
+ if (last < first)
+ {
+ /* Search failed; we need to add a new range to the list. */
+
+ /* Grow the list if necessary */
+ if (*nranges == 0 || *range == (fsRange *)0)
+ {
+ *range = (fsRange *)xalloc(range_alloc_granularity *
+ SIZEOF(fsRange));
+ *nranges = 0;
+ }
+ else if (!(*nranges % range_alloc_granularity))
+ {
+ *range = (fsRange *)xrealloc((char *)*range,
+ (*nranges + range_alloc_granularity) *
+ SIZEOF(fsRange));
+ }
+
+ /* If alloc failed, just return a null list */
+ if (*range == (fsRange *)0)
+ {
+ *nranges = 0;
+ return AllocError;
+ }
+
+ /* Should new entry go *at* or *after* ptr? */
+ ptr = (*range) + middle;
+ if (middle < *nranges && keymin > ptrmin) ptr++; /* after */
+
+ /* Open up a space for our new range */
+ memmove((char *)(ptr + 1),
+ (char *)ptr,
+ (char *)(*range + *nranges) - (char *)ptr);
+
+ /* Insert the new range */
+ ptr->min_char_low = keymin & 0xff;
+ ptr->min_char_high = keymin >> 8;
+ ptr->max_char_low = keymax & 0xff;
+ ptr->max_char_high = keymax >> 8;
+
+ /* Update range count */
+ (*nranges)++;
+
+ /* Done */
+ return Successful;
+ }
+
+ /* Join our new range to that pointed to by "ptr" */
+ if (keymin < ptrmin)
+ {
+ ptr->min_char_low = keymin & 0xff;
+ ptr->min_char_high = keymin >> 8;
+ }
+ if (keymax > ptrmax)
+ {
+ ptr->max_char_low = keymax & 0xff;
+ ptr->max_char_high = keymax >> 8;
+ }
+
+ ptrmin = mincharp(ptr);
+ ptrmax = maxcharp(ptr);
+
+ endptr = *range + *nranges;
+
+ for (ptr1 = ptr; ptr1 >= *range; ptr1--)
+ {
+ if (ptrmin <= maxcharp(ptr1) + 1)
+ {
+ if (!charset_subset && ptr->min_char_high != ptr1->min_char_high)
+ break;
+ if (ptrmin >= mincharp(ptr1))
+ ptrmin = mincharp(ptr1);
+ }
+ else break;
+ }
+ for (ptr2 = ptr; ptr2 < endptr; ptr2++)
+ {
+ if ((ptr2->min_char_low == 0 && ptr2->min_char_high == 0) ||
+ ptrmax >= mincharp(ptr2) - 1)
+ {
+ if (!charset_subset && ptr->min_char_high != ptr2->min_char_high)
+ break;
+ if (ptrmax <= maxcharp(ptr2))
+ ptrmax = maxcharp(ptr2);
+ }
+ else break;
+ }
+
+ /* We need to coalesce ranges between ptr1 and ptr2 exclusive */
+ ptr1++;
+ ptr2--;
+ if (ptr1 != ptr2)
+ {
+ memmove(ptr1, ptr2, (char *)endptr - (char *)ptr2);
+ *nranges -= (ptr2 - ptr1);
+ }
+
+ /* Write the new range into the range list */
+ ptr1->min_char_low = ptrmin & 0xff;
+ ptr1->min_char_high = ptrmin >> 8;
+ ptr1->max_char_low = ptrmax & 0xff;
+ ptr1->max_char_high = ptrmax >> 8;
+
+ return Successful;
+}
+
+/* It is difficult to find a good place for this. */
+#ifdef NEED_STRCASECMP
+int
+f_strcasecmp(const char *s1, const char *s2)
+{
+ char c1, c2;
+
+ if (*s1 == 0)
+ if (*s2 == 0)
+ return 0;
+ else
+ return 1;
+
+ c1 = (isupper (*s1) ? tolower (*s1) : *s1);
+ c2 = (isupper (*s2) ? tolower (*s2) : *s2);
+ while (c1 == c2) {
+ if (c1 == '\0')
+ return 0;
+ s1++;
+ s2++;
+ c1 = (isupper (*s1) ? tolower (*s1) : *s1);
+ c2 = (isupper (*s2) ? tolower (*s2) : *s2);
+ }
+ return c1 - c2;
+}
+#endif
+
diff --git a/libXfont/src/util/fontxlfd.c b/libXfont/src/util/fontxlfd.c
new file mode 100644
index 000000000..7adf74f4c
--- /dev/null
+++ b/libXfont/src/util/fontxlfd.c
@@ -0,0 +1,637 @@
+/* $Xorg: fontxlfd.c,v 1.4 2001/02/09 02:04:04 xorgcvs Exp $ */
+
+/*
+
+Copyright 1990, 1998 The Open Group
+
+Permission to use, copy, modify, distribute, and sell this software and its
+documentation for any purpose is hereby granted without fee, provided that
+the above copyright notice appear in all copies and that both that
+copyright notice and this permission notice appear in supporting
+documentation.
+
+The above copyright notice and this permission notice shall be included
+in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+IN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR
+OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of The Open Group shall
+not be used in advertising or otherwise to promote the sale, use or
+other dealings in this Software without prior written authorization
+from The Open Group.
+
+*/
+/* $XFree86: xc/lib/font/util/fontxlfd.c,v 3.16tsi Exp $ */
+
+/*
+ * Author: Keith Packard, MIT X Consortium
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include <X11/fonts/fontmisc.h>
+#include <X11/fonts/fontstruct.h>
+#include <X11/fonts/fontxlfd.h>
+#include <X11/fonts/fontutil.h>
+#include <X11/Xos.h>
+#include <math.h>
+#include <stdlib.h>
+#if defined(sony) && !defined(SYSTYPE_SYSV) && !defined(_SYSTYPE_SYSV)
+#define NO_LOCALE
+#endif
+#ifndef NO_LOCALE
+#include <locale.h>
+#endif
+#include <ctype.h>
+#include <stdio.h> /* for sprintf() */
+
+static char *
+GetInt(char *ptr, int *val)
+{
+ if (*ptr == '*') {
+ *val = -1;
+ ptr++;
+ } else
+ for (*val = 0; *ptr >= '0' && *ptr <= '9';)
+ *val = *val * 10 + *ptr++ - '0';
+ if (*ptr == '-')
+ return ptr;
+ return (char *) 0;
+}
+
+#define minchar(p) ((p).min_char_low + ((p).min_char_high << 8))
+#define maxchar(p) ((p).max_char_low + ((p).max_char_high << 8))
+
+
+#ifndef NO_LOCALE
+static struct lconv *locale = 0;
+#endif
+static char *radix = ".", *plus = "+", *minus = "-";
+
+static char *
+readreal(char *ptr, double *result)
+{
+ char buffer[80], *p1, *p2;
+
+#ifndef NO_LOCALE
+ /* Figure out what symbols apply in this locale */
+
+ if (!locale)
+ {
+ locale = localeconv();
+ if (locale->decimal_point && *locale->decimal_point)
+ radix = locale->decimal_point;
+ if (locale->positive_sign && *locale->positive_sign)
+ plus = locale->positive_sign;
+ if (locale->negative_sign && *locale->negative_sign)
+ minus = locale->negative_sign;
+ }
+#endif
+ /* Copy the first 80 chars of ptr into our local buffer, changing
+ symbols as needed. */
+ for (p1 = ptr, p2 = buffer;
+ *p1 && (p2 - buffer) < sizeof(buffer) - 1;
+ p1++, p2++)
+ {
+ switch(*p1)
+ {
+ case '~': *p2 = *minus; break;
+ case '+': *p2 = *plus; break;
+ case '.': *p2 = *radix; break;
+ default: *p2 = *p1;
+ }
+ }
+ *p2 = 0;
+
+ /* Now we have something that strtod() can interpret... do it. */
+ *result = strtod(buffer, &p1);
+ /* Return NULL if failure, pointer past number if success */
+ return (p1 == buffer) ? (char *)0 : (ptr + (p1 - buffer));
+}
+
+static char *
+xlfd_double_to_text(double value, char *buffer, int space_required)
+{
+ char formatbuf[40];
+ register char *p1;
+ int ndigits, exponent;
+
+#ifndef NO_LOCALE
+ if (!locale)
+ {
+ locale = localeconv();
+ if (locale->decimal_point && *locale->decimal_point)
+ radix = locale->decimal_point;
+ if (locale->positive_sign && *locale->positive_sign)
+ plus = locale->positive_sign;
+ if (locale->negative_sign && *locale->negative_sign)
+ minus = locale->negative_sign;
+ }
+#endif
+ /* Compute a format to use to render the number */
+ sprintf(formatbuf, "%%.%dle", XLFD_NDIGITS);
+
+ if (space_required)
+ *buffer++ = ' ';
+
+ /* Render the number using printf's idea of formatting */
+ sprintf(buffer, formatbuf, value);
+
+ /* Find and read the exponent value */
+ for (p1 = buffer + strlen(buffer);
+ *p1-- != 'e' && p1[1] != 'E';);
+ exponent = atoi(p1 + 2);
+ if (value == 0.0) exponent = 0;
+
+ /* Figure out how many digits are significant */
+ while (p1 >= buffer && (!isdigit(*p1) || *p1 == '0')) p1--;
+ ndigits = 0;
+ while (p1 >= buffer) if (isdigit(*p1--)) ndigits++;
+
+ /* Figure out notation to use */
+ if (exponent >= XLFD_NDIGITS || ndigits - exponent > XLFD_NDIGITS + 1)
+ {
+ /* Scientific */
+ sprintf(formatbuf, "%%.%dle", ndigits - 1);
+ sprintf(buffer, formatbuf, value);
+ }
+ else
+ {
+ /* Fixed */
+ ndigits -= exponent + 1;
+ if (ndigits < 0) ndigits = 0;
+ sprintf(formatbuf, "%%.%dlf", ndigits);
+ sprintf(buffer, formatbuf, value);
+ if (exponent < 0)
+ {
+ p1 = buffer;
+ while (*p1 && *p1 != '0') p1++;
+ while (*p1++) p1[-1] = *p1;
+ }
+ }
+
+ /* Last step, convert the locale-specific sign and radix characters
+ to our own. */
+ for (p1 = buffer; *p1; p1++)
+ {
+ if (*p1 == *minus) *p1 = '~';
+ else if (*p1 == *plus) *p1 = '+';
+ else if (*p1 == *radix) *p1 = '.';
+ }
+
+ return buffer - space_required;
+}
+
+double
+xlfd_round_double(double x)
+{
+ /* Utility for XLFD users to round numbers to XLFD_NDIGITS
+ significant digits. How do you round to n significant digits on
+ a binary machine? */
+
+#if defined(i386) || defined(__i386__) || \
+ defined(ia64) || defined(__ia64__) || \
+ defined(__alpha__) || defined(__alpha) || \
+ defined(__hppa__) || \
+ defined(__amd64__) || defined(__amd64) || \
+ defined(sgi)
+#if !defined(__UNIXOS2__)
+#include <float.h>
+
+/* if we have IEEE 754 fp, we can round to binary digits... */
+
+#if (FLT_RADIX == 2) && (DBL_DIG == 15) && (DBL_MANT_DIG == 53)
+
+#ifndef M_LN2
+#define M_LN2 0.69314718055994530942
+#endif
+#ifndef M_LN10
+#define M_LN10 2.30258509299404568402
+#endif
+
+/* convert # of decimal digits to # of binary digits */
+#define XLFD_NDIGITS_2 ((int)(XLFD_NDIGITS * M_LN10 / M_LN2 + 0.5))
+
+ union conv_d {
+ double d;
+ unsigned char b[8];
+ } d;
+ int i,j,k,d_exp;
+
+ if (x == 0)
+ return x;
+
+ /* do minor sanity check for IEEE 754 fp and correct byte order */
+ d.d = 1.0;
+ if (sizeof(double) == 8 && d.b[7] == 0x3f && d.b[6] == 0xf0) {
+
+ /*
+ * this code will round IEEE 754 double to XLFD_NDIGITS_2 binary digits
+ */
+
+ d.d = x;
+ d_exp = (d.b[7] << 4) | (d.b[6] >> 4);
+
+ i = (DBL_MANT_DIG-XLFD_NDIGITS_2) >> 3;
+ j = 1 << ((DBL_MANT_DIG-XLFD_NDIGITS_2) & 0x07);
+ for (; i<7; i++) {
+ k = d.b[i] + j;
+ d.b[i] = k;
+ if (k & 0x100) j = 1;
+ else break;
+ }
+ if ((i==7) && ((d.b[6] & 0xf0) != ((d_exp<<4) & 0xf0))) {
+ /* mantissa overflow: increment exponent */
+ d_exp = (d_exp & 0x800 ) | ((d_exp & 0x7ff) + 1);
+ d.b[7] = d_exp >> 4;
+ d.b[6] = (d.b[6] & 0x0f) | (d_exp << 4);
+ }
+
+ i = (DBL_MANT_DIG-XLFD_NDIGITS_2) >> 3;
+ j = 1 << ((DBL_MANT_DIG-XLFD_NDIGITS_2) & 0x07);
+ d.b[i] &= ~(j-1);
+ for (;--i>=0;) d.b[i] = 0;
+
+ return d.d;
+ }
+ else
+#endif
+#endif /* !__UNIXOS2__ */
+#endif /* i386 || __i386__ */
+ {
+ /*
+ * If not IEEE 754: Let printf() do it for you.
+ */
+
+ char formatbuf[40], buffer[40];
+
+ sprintf(formatbuf, "%%.%dlg", XLFD_NDIGITS);
+ sprintf(buffer, formatbuf, x);
+ return atof(buffer);
+ }
+}
+
+static char *
+GetMatrix(char *ptr, FontScalablePtr vals, int which)
+{
+ double *matrix;
+
+ if (which == PIXELSIZE_MASK)
+ matrix = vals->pixel_matrix;
+ else if (which == POINTSIZE_MASK)
+ matrix = vals->point_matrix;
+ else return (char *)0;
+
+ while (isspace(*ptr)) ptr++;
+ if (*ptr == '[')
+ {
+ /* This is a matrix containing real numbers. It would be nice
+ to use strtod() or sscanf() to read the numbers, but those
+ don't handle '~' for minus and we cannot force them to use a
+ "." for the radix. We'll have to do the hard work ourselves
+ (in readreal()). */
+
+ if ((ptr = readreal(++ptr, matrix + 0)) &&
+ (ptr = readreal(ptr, matrix + 1)) &&
+ (ptr = readreal(ptr, matrix + 2)) &&
+ (ptr = readreal(ptr, matrix + 3)))
+ {
+ while (isspace(*ptr)) ptr++;
+ if (*ptr != ']')
+ ptr = (char *)0;
+ else
+ {
+ ptr++;
+ while (isspace(*ptr)) ptr++;
+ if (*ptr == '-')
+ {
+ if (which == POINTSIZE_MASK)
+ vals->values_supplied |= POINTSIZE_ARRAY;
+ else
+ vals->values_supplied |= PIXELSIZE_ARRAY;
+ }
+ else ptr = (char *)0;
+ }
+ }
+ }
+ else
+ {
+ int value;
+ if ((ptr = GetInt(ptr, &value)))
+ {
+ vals->values_supplied &= ~which;
+ if (value > 0)
+ {
+ matrix[3] = (double)value;
+ if (which == POINTSIZE_MASK)
+ {
+ matrix[3] /= 10.0;
+ vals->values_supplied |= POINTSIZE_SCALAR;
+ }
+ else
+ vals->values_supplied |= PIXELSIZE_SCALAR;
+ /* If we're concocting the pixelsize array from a scalar,
+ we will need to normalize element 0 for the pixel shape.
+ This is done in FontFileCompleteXLFD(). */
+ matrix[0] = matrix[3];
+ matrix[1] = matrix[2] = 0.0;
+ }
+ else if (value < 0)
+ {
+ if (which == POINTSIZE_MASK)
+ vals->values_supplied |= POINTSIZE_WILDCARD;
+ else
+ vals->values_supplied |= PIXELSIZE_WILDCARD;
+ }
+ }
+ }
+ return ptr;
+}
+
+
+static void
+append_ranges(char *fname, int nranges, fsRange *ranges)
+{
+ if (nranges)
+ {
+ int i;
+
+ strcat(fname, "[");
+ for (i = 0; i < nranges && strlen(fname) < 1010; i++)
+ {
+ if (i) strcat(fname, " ");
+ sprintf(fname + strlen(fname), "%d",
+ minchar(ranges[i]));
+ if (ranges[i].min_char_low ==
+ ranges[i].max_char_low &&
+ ranges[i].min_char_high ==
+ ranges[i].max_char_high) continue;
+ sprintf(fname + strlen(fname), "_%d",
+ maxchar(ranges[i]));
+ }
+ strcat(fname, "]");
+ }
+}
+
+Bool
+FontParseXLFDName(char *fname, FontScalablePtr vals, int subst)
+{
+ register char *ptr;
+ register char *ptr1,
+ *ptr2,
+ *ptr3,
+ *ptr4;
+ register char *ptr5;
+ FontScalableRec tmpvals;
+ char replaceChar = '0';
+ char tmpBuf[1024];
+ int spacingLen;
+ int l;
+ char *p;
+
+ bzero(&tmpvals, sizeof(tmpvals));
+ if (subst != FONT_XLFD_REPLACE_VALUE)
+ *vals = tmpvals;
+
+ if (!(*(ptr = fname) == '-' || (*ptr++ == '*' && *ptr == '-')) || /* fndry */
+ !(ptr = strchr(ptr + 1, '-')) || /* family_name */
+ !(ptr1 = ptr = strchr(ptr + 1, '-')) || /* weight_name */
+ !(ptr = strchr(ptr + 1, '-')) || /* slant */
+ !(ptr = strchr(ptr + 1, '-')) || /* setwidth_name */
+ !(ptr = strchr(ptr + 1, '-')) || /* add_style_name */
+ !(ptr = strchr(ptr + 1, '-')) || /* pixel_size */
+ !(ptr = GetMatrix(ptr + 1, &tmpvals, PIXELSIZE_MASK)) ||
+ !(ptr2 = ptr = GetMatrix(ptr + 1, &tmpvals, POINTSIZE_MASK)) ||
+ !(ptr = GetInt(ptr + 1, &tmpvals.x)) || /* resolution_x */
+ !(ptr3 = ptr = GetInt(ptr + 1, &tmpvals.y)) || /* resolution_y */
+ !(ptr4 = ptr = strchr(ptr + 1, '-')) || /* spacing */
+ !(ptr5 = ptr = GetInt(ptr + 1, &tmpvals.width)) || /* average_width */
+ !(ptr = strchr(ptr + 1, '-')) || /* charset_registry */
+ strchr(ptr + 1, '-'))/* charset_encoding */
+ return FALSE;
+
+ /* Lop off HP charset subsetting enhancement. Interpreting this
+ field requires allocating some space in which to return the
+ results. So, to prevent memory leaks, this procedure will simply
+ lop off and ignore charset subsetting, and initialize the
+ relevant vals fields to zero. It's up to the caller to make its
+ own call to FontParseRanges() if it's interested in the charset
+ subsetting. */
+
+ if (subst != FONT_XLFD_REPLACE_NONE &&
+ (p = strchr(strrchr(fname, '-'), '[')))
+ {
+ tmpvals.values_supplied |= CHARSUBSET_SPECIFIED;
+ *p = '\0';
+ }
+
+ /* Fill in deprecated fields for the benefit of rasterizers that care
+ about them. */
+ tmpvals.pixel = (tmpvals.pixel_matrix[3] >= 0) ?
+ (int)(tmpvals.pixel_matrix[3] + .5) :
+ (int)(tmpvals.pixel_matrix[3] - .5);
+ tmpvals.point = (tmpvals.point_matrix[3] >= 0) ?
+ (int)(tmpvals.point_matrix[3] * 10 + .5) :
+ (int)(tmpvals.point_matrix[3] * 10 - .5);
+
+ spacingLen = ptr4 - ptr3 + 1;
+
+ switch (subst) {
+ case FONT_XLFD_REPLACE_NONE:
+ *vals = tmpvals;
+ break;
+ case FONT_XLFD_REPLACE_STAR:
+ replaceChar = '*';
+ case FONT_XLFD_REPLACE_ZERO:
+ strcpy(tmpBuf, ptr2);
+ ptr5 = tmpBuf + (ptr5 - ptr2);
+ ptr3 = tmpBuf + (ptr3 - ptr2);
+ ptr2 = tmpBuf;
+ ptr = ptr1 + 1;
+
+ ptr = strchr(ptr, '-') + 1; /* skip weight */
+ ptr = strchr(ptr, '-') + 1; /* skip slant */
+ ptr = strchr(ptr, '-') + 1; /* skip setwidth_name */
+ ptr = strchr(ptr, '-') + 1; /* skip add_style_name */
+
+ if ((ptr - fname) + spacingLen + strlen(ptr5) + 10 >= (unsigned)1024)
+ return FALSE;
+ *ptr++ = replaceChar;
+ *ptr++ = '-';
+ *ptr++ = replaceChar;
+ *ptr++ = '-';
+ *ptr++ = '*';
+ *ptr++ = '-';
+ *ptr++ = '*';
+ if (spacingLen > 2)
+ {
+ memmove(ptr, ptr3, spacingLen);
+ ptr += spacingLen;
+ }
+ else
+ {
+ *ptr++ = '-';
+ *ptr++ = '*';
+ *ptr++ = '-';
+ }
+ *ptr++ = replaceChar;
+ strcpy(ptr, ptr5);
+ *vals = tmpvals;
+ break;
+ case FONT_XLFD_REPLACE_VALUE:
+ if (vals->values_supplied & PIXELSIZE_MASK)
+ {
+ tmpvals.values_supplied =
+ (tmpvals.values_supplied & ~PIXELSIZE_MASK) |
+ (vals->values_supplied & PIXELSIZE_MASK);
+ tmpvals.pixel_matrix[0] = vals->pixel_matrix[0];
+ tmpvals.pixel_matrix[1] = vals->pixel_matrix[1];
+ tmpvals.pixel_matrix[2] = vals->pixel_matrix[2];
+ tmpvals.pixel_matrix[3] = vals->pixel_matrix[3];
+ }
+ if (vals->values_supplied & POINTSIZE_MASK)
+ {
+ tmpvals.values_supplied =
+ (tmpvals.values_supplied & ~POINTSIZE_MASK) |
+ (vals->values_supplied & POINTSIZE_MASK);
+ tmpvals.point_matrix[0] = vals->point_matrix[0];
+ tmpvals.point_matrix[1] = vals->point_matrix[1];
+ tmpvals.point_matrix[2] = vals->point_matrix[2];
+ tmpvals.point_matrix[3] = vals->point_matrix[3];
+ }
+ if (vals->x >= 0)
+ tmpvals.x = vals->x;
+ if (vals->y >= 0)
+ tmpvals.y = vals->y;
+ if (vals->width >= 0)
+ tmpvals.width = vals->width;
+ else if (vals->width < -1) /* overload: -1 means wildcard */
+ tmpvals.width = -vals->width;
+
+
+ p = ptr1 + 1; /* weight field */
+ l = strchr(p, '-') - p;
+ sprintf(tmpBuf, "%*.*s", l, l, p);
+
+ p += l + 1; /* slant field */
+ l = strchr(p, '-') - p;
+ sprintf(tmpBuf + strlen(tmpBuf), "-%*.*s", l, l, p);
+
+ p += l + 1; /* setwidth_name */
+ l = strchr(p, '-') - p;
+ sprintf(tmpBuf + strlen(tmpBuf), "-%*.*s", l, l, p);
+
+ p += l + 1; /* add_style_name field */
+ l = strchr(p, '-') - p;
+ sprintf(tmpBuf + strlen(tmpBuf), "-%*.*s", l, l, p);
+
+ strcat(tmpBuf, "-");
+ if ((tmpvals.values_supplied & PIXELSIZE_MASK) == PIXELSIZE_ARRAY)
+ {
+ char buffer[80];
+ strcat(tmpBuf, "[");
+ strcat(tmpBuf, xlfd_double_to_text(tmpvals.pixel_matrix[0],
+ buffer, 0));
+ strcat(tmpBuf, xlfd_double_to_text(tmpvals.pixel_matrix[1],
+ buffer, 1));
+ strcat(tmpBuf, xlfd_double_to_text(tmpvals.pixel_matrix[2],
+ buffer, 1));
+ strcat(tmpBuf, xlfd_double_to_text(tmpvals.pixel_matrix[3],
+ buffer, 1));
+ strcat(tmpBuf, "]");
+ }
+ else
+ {
+ sprintf(tmpBuf + strlen(tmpBuf), "%d",
+ (int)(tmpvals.pixel_matrix[3] + .5));
+ }
+ strcat(tmpBuf, "-");
+ if ((tmpvals.values_supplied & POINTSIZE_MASK) == POINTSIZE_ARRAY)
+ {
+ char buffer[80];
+ strcat(tmpBuf, "[");
+ strcat(tmpBuf, xlfd_double_to_text(tmpvals.point_matrix[0],
+ buffer, 0));
+ strcat(tmpBuf, xlfd_double_to_text(tmpvals.point_matrix[1],
+ buffer, 1));
+ strcat(tmpBuf, xlfd_double_to_text(tmpvals.point_matrix[2],
+ buffer, 1));
+ strcat(tmpBuf, xlfd_double_to_text(tmpvals.point_matrix[3],
+ buffer, 1));
+ strcat(tmpBuf, "]");
+ }
+ else
+ {
+ sprintf(tmpBuf + strlen(tmpBuf), "%d",
+ (int)(tmpvals.point_matrix[3] * 10.0 + .5));
+ }
+ sprintf(tmpBuf + strlen(tmpBuf), "-%d-%d%*.*s%d%s",
+ tmpvals.x, tmpvals.y,
+ spacingLen, spacingLen, ptr3, tmpvals.width, ptr5);
+ strcpy(ptr1 + 1, tmpBuf);
+ if ((vals->values_supplied & CHARSUBSET_SPECIFIED) && !vals->nranges)
+ strcat(fname, "[]");
+ else
+ append_ranges(fname, vals->nranges, vals->ranges);
+ break;
+ }
+ return TRUE;
+}
+
+fsRange *FontParseRanges(char *name, int *nranges)
+{
+ int n;
+ unsigned long l;
+ char *p1, *p2;
+ fsRange *result = (fsRange *)0;
+
+ name = strchr(name, '-');
+ for (n = 1; name && n < 14; n++)
+ name = strchr(name + 1, '-');
+
+ *nranges = 0;
+ if (!name || !(p1 = strchr(name, '['))) return (fsRange *)0;
+ p1++;
+
+ while (*p1 && *p1 != ']')
+ {
+ fsRange thisrange;
+
+ l = strtol(p1, &p2, 0);
+ if (p2 == p1 || l > 0xffff) break;
+ thisrange.max_char_low = thisrange.min_char_low = l & 0xff;
+ thisrange.max_char_high = thisrange.min_char_high = l >> 8;
+
+ p1 = p2;
+ if (*p1 == ']' || *p1 == ' ')
+ {
+ while (*p1 == ' ') p1++;
+ if (add_range(&thisrange, nranges, &result, TRUE) != Successful)
+ break;
+ }
+ else if (*p1 == '_')
+ {
+ l = strtol(++p1, &p2, 0);
+ if (p2 == p1 || l > 0xffff) break;
+ thisrange.max_char_low = l & 0xff;
+ thisrange.max_char_high = l >> 8;
+ p1 = p2;
+ if (*p1 == ']' || *p1 == ' ')
+ {
+ while (*p1 == ' ') p1++;
+ if (add_range(&thisrange, nranges, &result, TRUE) != Successful)
+ break;
+ }
+ }
+ else break;
+ }
+
+ return result;
+}
diff --git a/libXfont/src/util/format.c b/libXfont/src/util/format.c
new file mode 100644
index 000000000..6700721f9
--- /dev/null
+++ b/libXfont/src/util/format.c
@@ -0,0 +1,126 @@
+/* $Xorg: format.c,v 1.4 2001/02/09 02:04:04 xorgcvs Exp $ */
+/*
+ * Copyright 1990, 1991 Network Computing Devices;
+ * Portions Copyright 1987 by Digital Equipment Corporation
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the names of Network Computing Devices or Digital
+ * not be used in advertising or publicity pertaining to distribution of the
+ * software without specific, written prior permission. Network Computing
+ * Devices and Digital make no representations about the suitability of
+ * this software for any purpose. It is provided "as is" without express
+ * or implied warranty.
+ *
+ * NETWORK COMPUTING DEVICES AND DIGITAL DISCLAIM ALL WARRANTIES WITH
+ * REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS, IN NO EVENT SHALL NETWORK COMPUTING DEVICES OR DIGITAL BE
+ * LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/*
+
+Copyright 1987, 1998 The Open Group
+
+Permission to use, copy, modify, distribute, and sell this software and its
+documentation for any purpose is hereby granted without fee, provided that
+the above copyright notice appear in all copies and that both that
+copyright notice and this permission notice appear in supporting
+documentation.
+
+The above copyright notice and this permission notice shall be included
+in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+IN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR
+OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of The Open Group shall
+not be used in advertising or otherwise to promote the sale, use or
+other dealings in this Software without prior written authorization
+from The Open Group.
+
+*/
+/* $XFree86: xc/lib/font/util/format.c,v 1.4 2001/01/17 19:43:33 dawes Exp $ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include <X11/fonts/FSproto.h>
+#include <X11/fonts/font.h>
+#include <X11/fonts/fontstruct.h>
+#include <X11/fonts/fontutil.h>
+
+int
+CheckFSFormat(fsBitmapFormat format,
+ fsBitmapFormatMask fmask,
+ int *bit_order,
+ int *byte_order,
+ int *scan,
+ int *glyph,
+ int *image)
+{
+ /* convert format to what the low levels want */
+ if (fmask & BitmapFormatMaskBit) {
+ *bit_order = format & BitmapFormatBitOrderMask;
+ *bit_order = (*bit_order == BitmapFormatBitOrderMSB)
+ ? MSBFirst : LSBFirst;
+ }
+ if (fmask & BitmapFormatMaskByte) {
+ *byte_order = format & BitmapFormatByteOrderMask;
+ *byte_order = (*byte_order == BitmapFormatByteOrderMSB)
+ ? MSBFirst : LSBFirst;
+ }
+ if (fmask & BitmapFormatMaskScanLineUnit) {
+ *scan = format & BitmapFormatScanlineUnitMask;
+ /* convert byte paddings into byte counts */
+ switch (*scan) {
+ case BitmapFormatScanlineUnit8:
+ *scan = 1;
+ break;
+ case BitmapFormatScanlineUnit16:
+ *scan = 2;
+ break;
+ case BitmapFormatScanlineUnit32:
+ *scan = 4;
+ break;
+ default:
+ return BadFontFormat;
+ }
+ }
+ if (fmask & BitmapFormatMaskScanLinePad) {
+ *glyph = format & BitmapFormatScanlinePadMask;
+ /* convert byte paddings into byte counts */
+ switch (*glyph) {
+ case BitmapFormatScanlinePad8:
+ *glyph = 1;
+ break;
+ case BitmapFormatScanlinePad16:
+ *glyph = 2;
+ break;
+ case BitmapFormatScanlinePad32:
+ *glyph = 4;
+ break;
+ default:
+ return BadFontFormat;
+ }
+ }
+ if (fmask & BitmapFormatMaskImageRectangle) {
+ *image = format & BitmapFormatImageRectMask;
+
+ if (*image != BitmapFormatImageRectMin &&
+ *image != BitmapFormatImageRectMaxWidth &&
+ *image != BitmapFormatImageRectMax)
+ return BadFontFormat;
+ }
+ return Successful;
+}
diff --git a/libXfont/src/util/miscutil.c b/libXfont/src/util/miscutil.c
new file mode 100644
index 000000000..c44527a29
--- /dev/null
+++ b/libXfont/src/util/miscutil.c
@@ -0,0 +1,109 @@
+/* $Xorg: miscutil.c,v 1.4 2001/02/09 02:04:04 xorgcvs Exp $ */
+
+/*
+
+Copyright 1991, 1994, 1998 The Open Group
+
+Permission to use, copy, modify, distribute, and sell this software and its
+documentation for any purpose is hereby granted without fee, provided that
+the above copyright notice appear in all copies and that both that
+copyright notice and this permission notice appear in supporting
+documentation.
+
+The above copyright notice and this permission notice shall be included
+in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+IN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR
+OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of The Open Group shall
+not be used in advertising or otherwise to promote the sale, use or
+other dealings in this Software without prior written authorization
+from The Open Group.
+
+*/
+/* $XFree86: xc/lib/font/util/miscutil.c,v 1.7 2001/07/25 15:04:57 dawes Exp $ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include <X11/Xosdefs.h>
+#include <stdlib.h>
+#include <X11/fonts/fontmisc.h>
+#include "stubs.h"
+
+#define XK_LATIN1
+#include <X11/keysymdef.h>
+
+
+#ifdef __SUNPRO_C
+#pragma weak serverGeneration
+#pragma weak Xalloc
+#pragma weak Xrealloc
+#pragma weak Xfree
+#pragma weak Xcalloc
+#pragma weak CopyISOLatin1Lowered
+#pragma weak register_fpe_functions
+#endif
+
+/* make sure everything initializes themselves at least once */
+weak long serverGeneration = 1;
+
+weak void *
+Xalloc (unsigned long m)
+{
+ return malloc (m);
+}
+
+weak void *
+Xrealloc (void *n, unsigned long m)
+{
+ if (!n)
+ return malloc (m);
+ else
+ return realloc (n, m);
+}
+
+weak void
+Xfree (void *n)
+{
+ if (n)
+ free (n);
+}
+
+weak void *
+Xcalloc (unsigned long n)
+{
+ return calloc (n, 1);
+}
+
+weak void
+CopyISOLatin1Lowered (char *dst, char *src, int len)
+{
+ register unsigned char *dest, *source;
+
+ for (dest = (unsigned char *)dst, source = (unsigned char *)src;
+ *source && len > 0;
+ source++, dest++, len--)
+ {
+ if ((*source >= XK_A) && (*source <= XK_Z))
+ *dest = *source + (XK_a - XK_A);
+ else if ((*source >= XK_Agrave) && (*source <= XK_Odiaeresis))
+ *dest = *source + (XK_agrave - XK_Agrave);
+ else if ((*source >= XK_Ooblique) && (*source <= XK_Thorn))
+ *dest = *source + (XK_oslash - XK_Ooblique);
+ else
+ *dest = *source;
+ }
+ *dest = '\0';
+}
+
+weak void
+register_fpe_functions (void)
+{
+}
diff --git a/libXfont/src/util/patcache.c b/libXfont/src/util/patcache.c
new file mode 100644
index 000000000..0351b1ac2
--- /dev/null
+++ b/libXfont/src/util/patcache.c
@@ -0,0 +1,221 @@
+/* $Xorg: patcache.c,v 1.4 2001/02/09 02:04:04 xorgcvs Exp $ */
+
+/*
+
+Copyright 1991, 1998 The Open Group
+
+Permission to use, copy, modify, distribute, and sell this software and its
+documentation for any purpose is hereby granted without fee, provided that
+the above copyright notice appear in all copies and that both that
+copyright notice and this permission notice appear in supporting
+documentation.
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of The Open Group shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from The Open Group.
+
+*/
+/* $XFree86: xc/lib/font/util/patcache.c,v 3.4 2001/01/17 19:43:33 dawes Exp $ */
+
+/*
+ * Author: Keith Packard, MIT X Consortium
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include <X11/fonts/fontmisc.h>
+#include <X11/fonts/fontstruct.h>
+
+/*
+ * Static sized hash table for looking up font name patterns
+ *
+ * LRU entries, reusing old entries
+ */
+
+#define NBUCKETS 16
+#define NENTRIES 64
+
+#define UNSET (NENTRIES+1)
+
+typedef unsigned char EntryPtr;
+
+typedef struct _FontPatternCacheEntry {
+ struct _FontPatternCacheEntry *next, **prev;
+ short patlen;
+ char *pattern;
+ int hash;
+ FontPtr pFont; /* associated font */
+} FontPatternCacheEntryRec, *FontPatternCacheEntryPtr;
+
+typedef struct _FontPatternCache {
+ FontPatternCacheEntryPtr buckets[NBUCKETS];
+ FontPatternCacheEntryRec entries[NENTRIES];
+ FontPatternCacheEntryPtr free;
+} FontPatternCacheRec;
+
+/* Empty cache (for rehash) */
+void
+EmptyFontPatternCache (FontPatternCachePtr cache)
+{
+ int i;
+
+ for (i = 0; i < NBUCKETS; i++)
+ cache->buckets[i] = 0;
+ for (i = 0; i < NENTRIES; i++)
+ {
+ cache->entries[i].next = &cache->entries[i+1];
+ cache->entries[i].prev = 0;
+ cache->entries[i].pFont = 0;
+ xfree (cache->entries[i].pattern);
+ cache->entries[i].pattern = 0;
+ cache->entries[i].patlen = 0;
+ }
+ cache->free = &cache->entries[0];
+ cache->entries[NENTRIES - 1].next = 0;
+}
+
+/* Create and initialize cache */
+FontPatternCachePtr
+MakeFontPatternCache (void)
+{
+ FontPatternCachePtr cache;
+ int i;
+ cache = (FontPatternCachePtr) xalloc (sizeof *cache);
+ if (!cache)
+ return 0;
+ for (i = 0; i < NENTRIES; i++) {
+ cache->entries[i].patlen = 0;
+ cache->entries[i].pattern = 0;
+ cache->entries[i].pFont = 0;
+ }
+ EmptyFontPatternCache (cache);
+ return cache;
+}
+
+/* toss cache */
+void
+FreeFontPatternCache (FontPatternCachePtr cache)
+{
+ int i;
+
+ for (i = 0; i < NENTRIES; i++)
+ xfree (cache->entries[i].pattern);
+ xfree (cache);
+}
+
+/* compute id for string */
+static int
+Hash (const char *string, int len)
+{
+ int hash;
+
+ hash = 0;
+ while (len--)
+ hash = (hash << 1) ^ *string++;
+ if (hash < 0)
+ hash = -hash;
+ return hash;
+}
+
+/* add entry */
+void
+CacheFontPattern (FontPatternCachePtr cache,
+ char *pattern,
+ int patlen,
+ FontPtr pFont)
+{
+ FontPatternCacheEntryPtr e;
+ char *newpat;
+ int i;
+
+ newpat = (char *) xalloc (patlen);
+ if (!newpat)
+ return;
+ if (cache->free)
+ {
+ e = cache->free;
+ cache->free = e->next;
+ }
+ else
+ {
+ i = rand ();
+ if (i < 0)
+ i = -i;
+ i %= NENTRIES;
+ e = &cache->entries[i];
+ if (e->next)
+ e->next->prev = e->prev;
+ *e->prev = e->next;
+ xfree (e->pattern);
+ }
+ /* set pattern */
+ memcpy (newpat, pattern, patlen);
+ e->pattern = newpat;
+ e->patlen = patlen;
+ /* link to new hash chain */
+ e->hash = Hash (pattern, patlen);
+ i = e->hash % NBUCKETS;
+ e->next = cache->buckets[i];
+ if (e->next)
+ e->next->prev = &(e->next);
+ cache->buckets[i] = e;
+ e->prev = &(cache->buckets[i]);
+ e->pFont = pFont;
+}
+
+/* find matching entry */
+FontPtr
+FindCachedFontPattern (FontPatternCachePtr cache,
+ char *pattern,
+ int patlen)
+{
+ int hash;
+ int i;
+ FontPatternCacheEntryPtr e;
+
+ hash = Hash (pattern, patlen);
+ i = hash % NBUCKETS;
+ for (e = cache->buckets[i]; e; e = e->next)
+ {
+ if (e->patlen == patlen && e->hash == hash &&
+ !memcmp (e->pattern, pattern, patlen))
+ {
+ return e->pFont;
+ }
+ }
+ return 0;
+}
+
+void
+RemoveCachedFontPattern (FontPatternCachePtr cache,
+ FontPtr pFont)
+{
+ FontPatternCacheEntryPtr e;
+ int i;
+
+ for (i = 0; i < NENTRIES; i++)
+ {
+ if ((e = &cache->entries[i])->pFont == pFont)
+ {
+ e->pFont = 0;
+ if (e->next)
+ e->next->prev = e->prev;
+ *e->prev = e->next;
+ e->next = cache->free;
+ cache->free = e;
+ xfree (e->pattern);
+ e->pattern = 0;
+ }
+ }
+}
diff --git a/libXfont/src/util/private.c b/libXfont/src/util/private.c
new file mode 100644
index 000000000..85e90e57b
--- /dev/null
+++ b/libXfont/src/util/private.c
@@ -0,0 +1,107 @@
+/* $Xorg: private.c,v 1.4 2001/02/09 02:04:04 xorgcvs Exp $ */
+
+/*
+
+Copyright 1991, 1998 The Open Group
+
+Permission to use, copy, modify, distribute, and sell this software and its
+documentation for any purpose is hereby granted without fee, provided that
+the above copyright notice appear in all copies and that both that
+copyright notice and this permission notice appear in supporting
+documentation.
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of The Open Group shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from The Open Group.
+
+*/
+/* $XFree86: xc/lib/font/util/private.c,v 1.8tsi Exp $ */
+
+/*
+ * Author: Keith Packard, MIT X Consortium
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include <X11/fonts/fontmisc.h>
+#include <X11/fonts/fontstruct.h>
+
+static int _FontPrivateAllocateIndex = 0;
+
+int
+AllocateFontPrivateIndex (void)
+{
+ return _FontPrivateAllocateIndex++;
+}
+
+FontPtr
+CreateFontRec (void)
+{
+ FontPtr pFont;
+ int size;
+
+ size = sizeof(FontRec) + (sizeof(pointer) * _FontPrivateAllocateIndex);
+
+ pFont = (FontPtr)xalloc(size);
+
+ if(pFont) {
+ bzero((char*)pFont, size);
+ pFont->maxPrivate = _FontPrivateAllocateIndex - 1;
+ if(_FontPrivateAllocateIndex)
+ pFont->devPrivates = (pointer)(&pFont[1]);
+ }
+
+ return pFont;
+}
+
+void
+DestroyFontRec (FontPtr pFont)
+{
+ if (pFont->devPrivates && pFont->devPrivates != (pointer)(&pFont[1]))
+ xfree(pFont->devPrivates);
+ xfree(pFont);
+}
+
+void
+ResetFontPrivateIndex (void)
+{
+ _FontPrivateAllocateIndex = 0;
+}
+
+Bool
+_FontSetNewPrivate (FontPtr pFont, int n, pointer ptr)
+{
+ pointer *new;
+
+ if (n > pFont->maxPrivate) {
+ if (pFont->devPrivates && pFont->devPrivates != (pointer)(&pFont[1])) {
+ new = (pointer *) xrealloc (pFont->devPrivates, (n + 1) * sizeof (pointer));
+ if (!new)
+ return FALSE;
+ } else {
+ new = (pointer *) xalloc ((n + 1) * sizeof (pointer));
+ if (!new)
+ return FALSE;
+ if (pFont->devPrivates)
+ memcpy (new, pFont->devPrivates, (pFont->maxPrivate + 1) * sizeof (pointer));
+ }
+ pFont->devPrivates = new;
+ /* zero out new, uninitialized privates */
+ while(++pFont->maxPrivate < n)
+ pFont->devPrivates[pFont->maxPrivate] = (pointer)0;
+ }
+ pFont->devPrivates[n] = ptr;
+ return TRUE;
+}
+
diff --git a/libXfont/src/util/utilbitmap.c b/libXfont/src/util/utilbitmap.c
new file mode 100644
index 000000000..a817a4ec6
--- /dev/null
+++ b/libXfont/src/util/utilbitmap.c
@@ -0,0 +1,188 @@
+/* $Xorg: utilbitmap.c,v 1.4 2001/02/09 02:04:04 xorgcvs Exp $ */
+
+/*
+
+Copyright 1990, 1994, 1998 The Open Group
+
+Permission to use, copy, modify, distribute, and sell this software and its
+documentation for any purpose is hereby granted without fee, provided that
+the above copyright notice appear in all copies and that both that
+copyright notice and this permission notice appear in supporting
+documentation.
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of The Open Group shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from The Open Group.
+
+*/
+/* $XFree86: xc/lib/font/util/utilbitmap.c,v 1.4 2001/01/17 19:43:34 dawes Exp $ */
+
+/*
+ * Author: Keith Packard, MIT X Consortium
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include <X11/fonts/fontmisc.h>
+
+/* Utility functions for reformating font bitmaps */
+
+static unsigned char _reverse_byte[0x100] = {
+ 0x00, 0x80, 0x40, 0xc0, 0x20, 0xa0, 0x60, 0xe0,
+ 0x10, 0x90, 0x50, 0xd0, 0x30, 0xb0, 0x70, 0xf0,
+ 0x08, 0x88, 0x48, 0xc8, 0x28, 0xa8, 0x68, 0xe8,
+ 0x18, 0x98, 0x58, 0xd8, 0x38, 0xb8, 0x78, 0xf8,
+ 0x04, 0x84, 0x44, 0xc4, 0x24, 0xa4, 0x64, 0xe4,
+ 0x14, 0x94, 0x54, 0xd4, 0x34, 0xb4, 0x74, 0xf4,
+ 0x0c, 0x8c, 0x4c, 0xcc, 0x2c, 0xac, 0x6c, 0xec,
+ 0x1c, 0x9c, 0x5c, 0xdc, 0x3c, 0xbc, 0x7c, 0xfc,
+ 0x02, 0x82, 0x42, 0xc2, 0x22, 0xa2, 0x62, 0xe2,
+ 0x12, 0x92, 0x52, 0xd2, 0x32, 0xb2, 0x72, 0xf2,
+ 0x0a, 0x8a, 0x4a, 0xca, 0x2a, 0xaa, 0x6a, 0xea,
+ 0x1a, 0x9a, 0x5a, 0xda, 0x3a, 0xba, 0x7a, 0xfa,
+ 0x06, 0x86, 0x46, 0xc6, 0x26, 0xa6, 0x66, 0xe6,
+ 0x16, 0x96, 0x56, 0xd6, 0x36, 0xb6, 0x76, 0xf6,
+ 0x0e, 0x8e, 0x4e, 0xce, 0x2e, 0xae, 0x6e, 0xee,
+ 0x1e, 0x9e, 0x5e, 0xde, 0x3e, 0xbe, 0x7e, 0xfe,
+ 0x01, 0x81, 0x41, 0xc1, 0x21, 0xa1, 0x61, 0xe1,
+ 0x11, 0x91, 0x51, 0xd1, 0x31, 0xb1, 0x71, 0xf1,
+ 0x09, 0x89, 0x49, 0xc9, 0x29, 0xa9, 0x69, 0xe9,
+ 0x19, 0x99, 0x59, 0xd9, 0x39, 0xb9, 0x79, 0xf9,
+ 0x05, 0x85, 0x45, 0xc5, 0x25, 0xa5, 0x65, 0xe5,
+ 0x15, 0x95, 0x55, 0xd5, 0x35, 0xb5, 0x75, 0xf5,
+ 0x0d, 0x8d, 0x4d, 0xcd, 0x2d, 0xad, 0x6d, 0xed,
+ 0x1d, 0x9d, 0x5d, 0xdd, 0x3d, 0xbd, 0x7d, 0xfd,
+ 0x03, 0x83, 0x43, 0xc3, 0x23, 0xa3, 0x63, 0xe3,
+ 0x13, 0x93, 0x53, 0xd3, 0x33, 0xb3, 0x73, 0xf3,
+ 0x0b, 0x8b, 0x4b, 0xcb, 0x2b, 0xab, 0x6b, 0xeb,
+ 0x1b, 0x9b, 0x5b, 0xdb, 0x3b, 0xbb, 0x7b, 0xfb,
+ 0x07, 0x87, 0x47, 0xc7, 0x27, 0xa7, 0x67, 0xe7,
+ 0x17, 0x97, 0x57, 0xd7, 0x37, 0xb7, 0x77, 0xf7,
+ 0x0f, 0x8f, 0x4f, 0xcf, 0x2f, 0xaf, 0x6f, 0xef,
+ 0x1f, 0x9f, 0x5f, 0xdf, 0x3f, 0xbf, 0x7f, 0xff
+};
+
+/*
+ * Invert bit order within each BYTE of an array.
+ */
+void
+BitOrderInvert(unsigned char *buf, int nbytes)
+{
+ unsigned char *rev = _reverse_byte;
+
+ for (; --nbytes >= 0; buf++)
+ *buf = rev[*buf];
+}
+
+/*
+ * Invert byte order within each 16-bits of an array.
+ */
+void
+TwoByteSwap(unsigned char *buf, int nbytes)
+{
+ unsigned char c;
+
+ for (; nbytes > 0; nbytes -= 2, buf += 2)
+ {
+ c = buf[0];
+ buf[0] = buf[1];
+ buf[1] = c;
+ }
+}
+
+/*
+ * Invert byte order within each 32-bits of an array.
+ */
+void
+FourByteSwap(unsigned char *buf, int nbytes)
+{
+ unsigned char c;
+
+ for (; nbytes > 0; nbytes -= 4, buf += 4)
+ {
+ c = buf[0];
+ buf[0] = buf[3];
+ buf[3] = c;
+ c = buf[1];
+ buf[1] = buf[2];
+ buf[2] = c;
+ }
+}
+
+/*
+ * Repad a bitmap
+ */
+
+int
+RepadBitmap (char *pSrc, char *pDst,
+ unsigned int srcPad, unsigned int dstPad,
+ int width, int height)
+{
+ int srcWidthBytes,dstWidthBytes;
+ int row,col;
+ char *pTmpSrc,*pTmpDst;
+
+ switch (srcPad) {
+ case 1:
+ srcWidthBytes = (width+7)>>3;
+ break;
+ case 2:
+ srcWidthBytes = ((width+15)>>4)<<1;
+ break;
+ case 4:
+ srcWidthBytes = ((width+31)>>5)<<2;
+ break;
+ case 8:
+ srcWidthBytes = ((width+63)>>6)<<3;
+ break;
+ default:
+ return 0;
+ }
+ switch (dstPad) {
+ case 1:
+ dstWidthBytes = (width+7)>>3;
+ break;
+ case 2:
+ dstWidthBytes = ((width+15)>>4)<<1;
+ break;
+ case 4:
+ dstWidthBytes = ((width+31)>>5)<<2;
+ break;
+ case 8:
+ dstWidthBytes = ((width+63)>>6)<<3;
+ break;
+ default:
+ return 0;
+ }
+
+ width = srcWidthBytes;
+ if (width > dstWidthBytes)
+ width = dstWidthBytes;
+ pTmpSrc= pSrc;
+ pTmpDst= pDst;
+ for (row = 0; row < height; row++)
+ {
+ for (col = 0; col < width; col++)
+ *pTmpDst++ = *pTmpSrc++;
+ while (col < dstWidthBytes)
+ {
+ *pTmpDst++ = '\0';
+ col++;
+ }
+ pTmpSrc += srcWidthBytes - width;
+ }
+ return dstWidthBytes * height;
+}
+
+