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/bitmap | |
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/bitmap')
-rw-r--r-- | libXfont/src/bitmap/Makefile.am | 19 | ||||
-rw-r--r-- | libXfont/src/bitmap/Makefile.in | 473 | ||||
-rw-r--r-- | libXfont/src/bitmap/bdfread.c | 967 | ||||
-rw-r--r-- | libXfont/src/bitmap/bdfutils.c | 340 | ||||
-rw-r--r-- | libXfont/src/bitmap/bitmap.c | 160 | ||||
-rw-r--r-- | libXfont/src/bitmap/bitmapfunc.c | 265 | ||||
-rw-r--r-- | libXfont/src/bitmap/bitmaputil.c | 232 | ||||
-rw-r--r-- | libXfont/src/bitmap/bitscale.c | 1987 | ||||
-rw-r--r-- | libXfont/src/bitmap/fontink.c | 219 | ||||
-rw-r--r-- | libXfont/src/bitmap/pcfread.c | 1024 | ||||
-rw-r--r-- | libXfont/src/bitmap/pcfwrite.c | 468 | ||||
-rw-r--r-- | libXfont/src/bitmap/snfread.c | 514 | ||||
-rw-r--r-- | libXfont/src/bitmap/snfstr.h | 184 |
13 files changed, 6852 insertions, 0 deletions
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 */ |