diff options
author | marha <marha@users.sourceforge.net> | 2009-06-28 22:07:26 +0000 |
---|---|---|
committer | marha <marha@users.sourceforge.net> | 2009-06-28 22:07:26 +0000 |
commit | 3562e78743202e43aec8727005182a2558117eca (patch) | |
tree | 8f9113a77d12470c5c851a2a8e4cb02e89df7d43 /libXfont/src | |
download | vcxsrv-3562e78743202e43aec8727005182a2558117eca.tar.gz vcxsrv-3562e78743202e43aec8727005182a2558117eca.tar.bz2 vcxsrv-3562e78743202e43aec8727005182a2558117eca.zip |
Checked in the following released items:
xkeyboard-config-1.4.tar.gz
ttf-bitstream-vera-1.10.tar.gz
font-alias-1.0.1.tar.gz
font-sun-misc-1.0.0.tar.gz
font-sun-misc-1.0.0.tar.gz
font-sony-misc-1.0.0.tar.gz
font-schumacher-misc-1.0.0.tar.gz
font-mutt-misc-1.0.0.tar.gz
font-misc-misc-1.0.0.tar.gz
font-misc-meltho-1.0.0.tar.gz
font-micro-misc-1.0.0.tar.gz
font-jis-misc-1.0.0.tar.gz
font-isas-misc-1.0.0.tar.gz
font-dec-misc-1.0.0.tar.gz
font-daewoo-misc-1.0.0.tar.gz
font-cursor-misc-1.0.0.tar.gz
font-arabic-misc-1.0.0.tar.gz
font-winitzki-cyrillic-1.0.0.tar.gz
font-misc-cyrillic-1.0.0.tar.gz
font-cronyx-cyrillic-1.0.0.tar.gz
font-screen-cyrillic-1.0.1.tar.gz
font-xfree86-type1-1.0.1.tar.gz
font-adobe-utopia-type1-1.0.1.tar.gz
font-ibm-type1-1.0.0.tar.gz
font-bitstream-type1-1.0.0.tar.gz
font-bitstream-speedo-1.0.0.tar.gz
font-bh-ttf-1.0.0.tar.gz
font-bh-type1-1.0.0.tar.gz
font-bitstream-100dpi-1.0.0.tar.gz
font-bh-lucidatypewriter-100dpi-1.0.0.tar.gz
font-bh-100dpi-1.0.0.tar.gz
font-adobe-utopia-100dpi-1.0.1.tar.gz
font-adobe-100dpi-1.0.0.tar.gz
font-util-1.0.1.tar.gz
font-bitstream-75dpi-1.0.0.tar.gz
font-bh-lucidatypewriter-75dpi-1.0.0.tar.gz
font-adobe-utopia-75dpi-1.0.1.tar.gz
font-bh-75dpi-1.0.0.tar.gz
bdftopcf-1.0.1.tar.gz
font-adobe-75dpi-1.0.0.tar.gz
mkfontscale-1.0.6.tar.gz
openssl-0.9.8k.tar.gz
bigreqsproto-1.0.2.tar.gz
xtrans-1.2.2.tar.gz
resourceproto-1.0.2.tar.gz
inputproto-1.4.4.tar.gz
compositeproto-0.4.tar.gz
damageproto-1.1.0.tar.gz
zlib-1.2.3.tar.gz
xkbcomp-1.0.5.tar.gz
freetype-2.3.9.tar.gz
pthreads-w32-2-8-0-release.tar.gz
pixman-0.12.0.tar.gz
kbproto-1.0.3.tar.gz
evieext-1.0.2.tar.gz
fixesproto-4.0.tar.gz
recordproto-1.13.2.tar.gz
randrproto-1.2.2.tar.gz
scrnsaverproto-1.1.0.tar.gz
renderproto-0.9.3.tar.gz
xcmiscproto-1.1.2.tar.gz
fontsproto-2.0.2.tar.gz
xextproto-7.0.3.tar.gz
xproto-7.0.14.tar.gz
libXdmcp-1.0.2.tar.gz
libxkbfile-1.0.5.tar.gz
libfontenc-1.0.4.tar.gz
libXfont-1.3.4.tar.gz
libX11-1.1.5.tar.gz
libXau-1.0.4.tar.gz
libxcb-1.1.tar.gz
xorg-server-1.5.3.tar.gz
Diffstat (limited to 'libXfont/src')
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, ®); +#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 = ¤t_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 = ¤tworkarea[-iy]; + R->edgeYstop = TOFRACTPEL(ydiff + iy) + FPHALF; + } + else { + R->edge = ¤tworkarea[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; +} + + |