aboutsummaryrefslogtreecommitdiff
path: root/libXfont/src/FreeType
diff options
context:
space:
mode:
authormarha <marha@users.sourceforge.net>2011-03-25 15:37:13 +0000
committermarha <marha@users.sourceforge.net>2011-03-25 15:37:13 +0000
commit41a502478a2972358dec934d82ee401c61a5cd36 (patch)
tree3fda8100e6da9b4a2863789e393016a750502067 /libXfont/src/FreeType
parent81aeaf653a832c4054d9a40b1cc796911521a739 (diff)
parent272e57235cd60a2e65ac8258d96a02eb3939b687 (diff)
downloadvcxsrv-41a502478a2972358dec934d82ee401c61a5cd36.tar.gz
vcxsrv-41a502478a2972358dec934d82ee401c61a5cd36.tar.bz2
vcxsrv-41a502478a2972358dec934d82ee401c61a5cd36.zip
svn merge ^/branches/released .
Diffstat (limited to 'libXfont/src/FreeType')
-rw-r--r--libXfont/src/FreeType/Makefile.in482
-rw-r--r--libXfont/src/FreeType/ft.h178
-rw-r--r--libXfont/src/FreeType/ftenc.c479
-rw-r--r--libXfont/src/FreeType/ftfuncs.c7867
-rw-r--r--libXfont/src/FreeType/ftfuncs.h379
-rw-r--r--libXfont/src/FreeType/fttools.c282
-rw-r--r--libXfont/src/FreeType/xttcap.c1411
-rw-r--r--libXfont/src/FreeType/xttcap.h261
8 files changed, 5418 insertions, 5921 deletions
diff --git a/libXfont/src/FreeType/Makefile.in b/libXfont/src/FreeType/Makefile.in
deleted file mode 100644
index e93178b79..000000000
--- a/libXfont/src/FreeType/Makefile.in
+++ /dev/null
@@ -1,482 +0,0 @@
-# Makefile.in generated by automake 1.10.2 from Makefile.am.
-# @configure_input@
-
-# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
-# 2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc.
-# This Makefile.in is free software; the Free Software Foundation
-# gives unlimited permission to copy and/or distribute it,
-# with or without modifications, as long as this notice is preserved.
-
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
-# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
-# PARTICULAR PURPOSE.
-
-@SET_MAKE@
-
-VPATH = @srcdir@
-pkgdatadir = $(datadir)/@PACKAGE@
-pkglibdir = $(libdir)/@PACKAGE@
-pkgincludedir = $(includedir)/@PACKAGE@
-am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
-install_sh_DATA = $(install_sh) -c -m 644
-install_sh_PROGRAM = $(install_sh) -c
-install_sh_SCRIPT = $(install_sh) -c
-INSTALL_HEADER = $(INSTALL_DATA)
-transform = $(program_transform_name)
-NORMAL_INSTALL = :
-PRE_INSTALL = :
-POST_INSTALL = :
-NORMAL_UNINSTALL = :
-PRE_UNINSTALL = :
-POST_UNINSTALL = :
-build_triplet = @build@
-host_triplet = @host@
-subdir = src/FreeType
-DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in
-ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
-am__aclocal_m4_deps = $(top_srcdir)/configure.ac
-am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
- $(ACLOCAL_M4)
-mkinstalldirs = $(install_sh) -d
-CONFIG_HEADER = $(top_builddir)/config.h \
- $(top_builddir)/include/X11/fonts/fontconf.h
-CONFIG_CLEAN_FILES =
-LTLIBRARIES = $(noinst_LTLIBRARIES)
-libft_la_LIBADD =
-am_libft_la_OBJECTS = ftenc.lo ftfuncs.lo fttools.lo xttcap.lo
-libft_la_OBJECTS = $(am_libft_la_OBJECTS)
-DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) -I$(top_builddir)/include/X11/fonts
-depcomp = $(SHELL) $(top_srcdir)/depcomp
-am__depfiles_maybe = depfiles
-COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
- $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
-LTCOMPILE = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
- --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \
- $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
-CCLD = $(CC)
-LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
- --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \
- $(LDFLAGS) -o $@
-SOURCES = $(libft_la_SOURCES)
-DIST_SOURCES = $(libft_la_SOURCES)
-ETAGS = etags
-CTAGS = ctags
-DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
-ACLOCAL = @ACLOCAL@
-ADMIN_MAN_DIR = @ADMIN_MAN_DIR@
-ADMIN_MAN_SUFFIX = @ADMIN_MAN_SUFFIX@
-AMTAR = @AMTAR@
-AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
-APP_MAN_DIR = @APP_MAN_DIR@
-APP_MAN_SUFFIX = @APP_MAN_SUFFIX@
-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@
-CYGPATH_W = @CYGPATH_W@
-DEFS = @DEFS@
-DEPDIR = @DEPDIR@
-DRIVER_MAN_DIR = @DRIVER_MAN_DIR@
-DRIVER_MAN_SUFFIX = @DRIVER_MAN_SUFFIX@
-DSYMUTIL = @DSYMUTIL@
-DUMPBIN = @DUMPBIN@
-ECHO_C = @ECHO_C@
-ECHO_N = @ECHO_N@
-ECHO_T = @ECHO_T@
-EGREP = @EGREP@
-EXEEXT = @EXEEXT@
-FGREP = @FGREP@
-FILE_MAN_DIR = @FILE_MAN_DIR@
-FILE_MAN_SUFFIX = @FILE_MAN_SUFFIX@
-FOP = @FOP@
-FREETYPE_CFLAGS = @FREETYPE_CFLAGS@
-FREETYPE_LIBS = @FREETYPE_LIBS@
-FREETYPE_REQUIRES = @FREETYPE_REQUIRES@
-GREP = @GREP@
-INSTALL = @INSTALL@
-INSTALL_CMD = @INSTALL_CMD@
-INSTALL_DATA = @INSTALL_DATA@
-INSTALL_PROGRAM = @INSTALL_PROGRAM@
-INSTALL_SCRIPT = @INSTALL_SCRIPT@
-INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
-LD = @LD@
-LDFLAGS = @LDFLAGS@
-LIBOBJS = @LIBOBJS@
-LIBS = @LIBS@
-LIBTOOL = @LIBTOOL@
-LIB_MAN_DIR = @LIB_MAN_DIR@
-LIB_MAN_SUFFIX = @LIB_MAN_SUFFIX@
-LIPO = @LIPO@
-LN_S = @LN_S@
-LTLIBOBJS = @LTLIBOBJS@
-MAINT = @MAINT@
-MAKEINFO = @MAKEINFO@
-MAN_SUBSTS = @MAN_SUBSTS@
-MATH_LIBS = @MATH_LIBS@
-MISC_MAN_DIR = @MISC_MAN_DIR@
-MISC_MAN_SUFFIX = @MISC_MAN_SUFFIX@
-MKDIR_P = @MKDIR_P@
-NM = @NM@
-NMEDIT = @NMEDIT@
-OBJDUMP = @OBJDUMP@
-OBJEXT = @OBJEXT@
-OS_CFLAGS = @OS_CFLAGS@
-OTOOL = @OTOOL@
-OTOOL64 = @OTOOL64@
-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@
-SED = @SED@
-SET_MAKE = @SET_MAKE@
-SHELL = @SHELL@
-STRIP = @STRIP@
-VERSION = @VERSION@
-XFONT_CFLAGS = @XFONT_CFLAGS@
-XFONT_LIBS = @XFONT_LIBS@
-XMLTO = @XMLTO@
-XORG_MAN_PAGE = @XORG_MAN_PAGE@
-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_DUMPBIN = @ac_ct_DUMPBIN@
-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@
-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@
-lt_ECHO = @lt_ECHO@
-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_build_prefix = @top_build_prefix@
-top_builddir = @top_builddir@
-top_srcdir = @top_srcdir@
-INCLUDES = \
- -I${top_srcdir}/include
-
-noinst_LTLIBRARIES = libft.la
-AM_CFLAGS = $(FREETYPE_CFLAGS) $(XFONT_CFLAGS) $(OS_CFLAGS) $(CWARNFLAGS)
-libft_la_SOURCES = \
- ft.h \
- ftfuncs.h \
- xttcap.h \
- ftenc.c \
- ftfuncs.c \
- fttools.c \
- xttcap.c
-
-all: all-am
-
-.SUFFIXES:
-.SUFFIXES: .c .lo .o .obj
-$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps)
- @for dep in $?; do \
- case '$(am__configure_deps)' in \
- *$$dep*) \
- ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
- && { if test -f $@; then exit 0; else break; fi; }; \
- exit 1;; \
- esac; \
- done; \
- echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign src/FreeType/Makefile'; \
- cd $(top_srcdir) && \
- $(AUTOMAKE) --foreign src/FreeType/Makefile
-.PRECIOUS: Makefile
-Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
- @case '$?' in \
- *config.status*) \
- cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
- *) \
- echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
- cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
- esac;
-
-$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
- cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
-
-$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps)
- cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
-$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps)
- cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
-
-clean-noinstLTLIBRARIES:
- -test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES)
- @list='$(noinst_LTLIBRARIES)'; for p in $$list; do \
- dir="`echo $$p | sed -e 's|/[^/]*$$||'`"; \
- test "$$dir" != "$$p" || dir=.; \
- echo "rm -f \"$${dir}/so_locations\""; \
- rm -f "$${dir}/so_locations"; \
- done
-libft.la: $(libft_la_OBJECTS) $(libft_la_DEPENDENCIES)
- $(LINK) $(libft_la_OBJECTS) $(libft_la_LIBADD) $(LIBS)
-
-mostlyclean-compile:
- -rm -f *.$(OBJEXT)
-
-distclean-compile:
- -rm -f *.tab.c
-
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ftenc.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ftfuncs.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fttools.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/xttcap.Plo@am__quote@
-
-.c.o:
-@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
-@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@ $(COMPILE) -c $<
-
-.c.obj:
-@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'`
-@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@ $(COMPILE) -c `$(CYGPATH_W) '$<'`
-
-.c.lo:
-@am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
-@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@ $(LTCOMPILE) -c -o $@ $<
-
-mostlyclean-libtool:
- -rm -f *.lo
-
-clean-libtool:
- -rm -rf .libs _libs
-
-ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
- list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
- unique=`for i in $$list; do \
- if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
- done | \
- $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
- END { if (nonempty) { 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; nonempty = 1; } \
- END { if (nonempty) { 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=; \
- 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; nonempty = 1; } \
- END { if (nonempty) { for (i in files) print i; }; }'`; \
- test -z "$(CTAGS_ARGS)$$tags$$unique" \
- || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
- $$tags $$unique
-
-GTAGS:
- here=`$(am__cd) $(top_builddir) && pwd` \
- && cd $(top_srcdir) \
- && gtags -i $(GTAGS_ARGS) $$here
-
-distclean-tags:
- -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
-
-distdir: $(DISTFILES)
- @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
- topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
- list='$(DISTFILES)'; \
- dist_files=`for file in $$list; do echo $$file; done | \
- sed -e "s|^$$srcdirstrip/||;t" \
- -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
- case $$dist_files in \
- */*) $(MKDIR_P) `echo "$$dist_files" | \
- sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
- sort -u` ;; \
- esac; \
- for file in $$dist_files; do \
- if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
- if test -d $$d/$$file; then \
- dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
- if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
- cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \
- fi; \
- cp -pR $$d/$$file $(distdir)$$dir || exit 1; \
- else \
- test -f $(distdir)/$$file \
- || cp -p $$d/$$file $(distdir)/$$file \
- || exit 1; \
- fi; \
- done
-check-am: all-am
-check: check-am
-all-am: Makefile $(LTLIBRARIES)
-installdirs:
-install: install-am
-install-exec: install-exec-am
-install-data: install-data-am
-uninstall: uninstall-am
-
-install-am: all-am
- @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
-
-installcheck: installcheck-am
-install-strip:
- $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
- install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
- `test -z '$(STRIP)' || \
- echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
-mostlyclean-generic:
-
-clean-generic:
-
-distclean-generic:
- -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
-
-maintainer-clean-generic:
- @echo "This command is intended for maintainers to use"
- @echo "it deletes files that may require special tools to rebuild."
-clean: clean-am
-
-clean-am: clean-generic clean-libtool clean-noinstLTLIBRARIES \
- mostlyclean-am
-
-distclean: distclean-am
- -rm -rf ./$(DEPDIR)
- -rm -f Makefile
-distclean-am: clean-am distclean-compile distclean-generic \
- distclean-tags
-
-dvi: dvi-am
-
-dvi-am:
-
-html: html-am
-
-info: info-am
-
-info-am:
-
-install-data-am:
-
-install-dvi: install-dvi-am
-
-install-exec-am:
-
-install-html: install-html-am
-
-install-info: install-info-am
-
-install-man:
-
-install-pdf: install-pdf-am
-
-install-ps: install-ps-am
-
-installcheck-am:
-
-maintainer-clean: maintainer-clean-am
- -rm -rf ./$(DEPDIR)
- -rm -f Makefile
-maintainer-clean-am: distclean-am maintainer-clean-generic
-
-mostlyclean: mostlyclean-am
-
-mostlyclean-am: mostlyclean-compile mostlyclean-generic \
- mostlyclean-libtool
-
-pdf: pdf-am
-
-pdf-am:
-
-ps: ps-am
-
-ps-am:
-
-uninstall-am:
-
-.MAKE: install-am install-strip
-
-.PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \
- clean-libtool clean-noinstLTLIBRARIES ctags distclean \
- distclean-compile distclean-generic distclean-libtool \
- distclean-tags distdir dvi dvi-am html html-am info info-am \
- install install-am install-data install-data-am install-dvi \
- install-dvi-am install-exec install-exec-am install-html \
- install-html-am install-info install-info-am install-man \
- install-pdf install-pdf-am install-ps install-ps-am \
- install-strip installcheck installcheck-am installdirs \
- maintainer-clean maintainer-clean-generic mostlyclean \
- mostlyclean-compile mostlyclean-generic mostlyclean-libtool \
- pdf pdf-am ps ps-am tags uninstall uninstall-am
-
-# Tell versions [3.59,3.63) of GNU make to not export all variables.
-# Otherwise a system limit (for SysV at least) may be exceeded.
-.NOEXPORT:
diff --git a/libXfont/src/FreeType/ft.h b/libXfont/src/FreeType/ft.h
index d5d789ec6..300496fd0 100644
--- a/libXfont/src/FreeType/ft.h
+++ b/libXfont/src/FreeType/ft.h
@@ -1,91 +1,87 @@
-/*
-Copyright (c) 1997 by Mark Leisher
-Copyright (c) 1998-2002 by Juliusz Chroboczek
-
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in
-all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-THE SOFTWARE.
-*/
-
-/* $XFree86: xc/lib/font/FreeType/ft.h,v 1.22 2003/06/08 15:41:13 herrb Exp $ */
-
-#ifndef _FT_H_
-#define _FT_H_
-
-#include <X11/Xfuncproto.h>
-
-#define FREETYPE_VERSION (FREETYPE_MAJOR * 1000000 + FREETYPE_MINOR * 1000 + FREETYPE_PATCH)
-
-#undef DEBUG_TRUETYPE
-
-#ifdef DEBUG_TRUETYPE
-#define MUMBLE(s) (ErrorF((s)))
-#define MUMBLE1(s,x) (ErrorF((s),(x)))
-#else
-#define MUMBLE(s)
-#define MUMBLE1(s,x)
-#endif
-
-#undef MAX
-#define MAX(h,i) ((h) > (i) ? (h) : (i))
-#define ADJUSTMAX(m,v) if((v)>(m)) (m)=(v)
-#undef MIN
-#define MIN(l,o) ((l) < (o) ? (l) : (o))
-#define ADJUSTMIN(m,v) if ((v)<(m)) (m)=(v)
-
-/* When comparing floating point values, we want to ignore small errors. */
-#define NEGLIGIBLE ((double)0.001)
-/* Are x and y significantly different? */
-#define DIFFER(x,y) (fabs((x)-(y))>=NEGLIGIBLE*fabs(x))
-/* Is x significantly different from 0 w.r.t. y? */
-#define DIFFER0(x,y) (fabs(x)>=NEGLIGIBLE*fabs(y))
-
-#ifndef ABS
-#define ABS(x) ((x) >= 0 ? (x) : -(x))
-#endif
-
-/* Two to the sixteenth power, as a double. */
-#define TWO_SIXTEENTH ((double)(1<<16))
-#define TWO_SIXTH ((double)(1<<6))
-
-/* Data structures used across files */
-
-typedef struct _FTMapping
-{
- int named;
- FT_CharMap cmap;
- int base;
- struct _FontMap *mapping; /* allow inclusion without fontenc.h */
-} FTMappingRec, *FTMappingPtr;
-
-/* Prototypes */
-
-/* ftfuncs.c */
-
-/* ftenc.c */
-
-int FTPickMapping(char*, int, char*, FT_Face, FTMappingPtr);
-unsigned FTRemap(FT_Face face, FTMappingPtr, unsigned code);
-
-/* fttools.c */
-
-int FTtoXReturnCode(int);
-int FTGetEnglishName(FT_Face, int, char *, int);
-
-extern void ErrorF(const char*, ...);
-
-#endif /* _FT_H_ */
+/*
+Copyright (c) 1997 by Mark Leisher
+Copyright (c) 1998-2002 by Juliusz Chroboczek
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
+*/
+
+#ifndef _FT_H_
+#define _FT_H_
+
+#include <X11/Xfuncproto.h>
+
+#define FREETYPE_VERSION (FREETYPE_MAJOR * 1000000 + FREETYPE_MINOR * 1000 + FREETYPE_PATCH)
+
+#undef DEBUG_TRUETYPE
+
+#ifdef DEBUG_TRUETYPE
+#define MUMBLE ErrorF
+#else
+#define MUMBLE(...)
+#endif
+
+#undef MAX
+#define MAX(h,i) ((h) > (i) ? (h) : (i))
+#define ADJUSTMAX(m,v) if((v)>(m)) (m)=(v)
+#undef MIN
+#define MIN(l,o) ((l) < (o) ? (l) : (o))
+#define ADJUSTMIN(m,v) if ((v)<(m)) (m)=(v)
+
+/* When comparing floating point values, we want to ignore small errors. */
+#define NEGLIGIBLE ((double)0.001)
+/* Are x and y significantly different? */
+#define DIFFER(x,y) (fabs((x)-(y))>=NEGLIGIBLE*fabs(x))
+/* Is x significantly different from 0 w.r.t. y? */
+#define DIFFER0(x,y) (fabs(x)>=NEGLIGIBLE*fabs(y))
+
+#ifndef ABS
+#define ABS(x) ((x) >= 0 ? (x) : -(x))
+#endif
+
+/* Two to the sixteenth power, as a double. */
+#define TWO_SIXTEENTH ((double)(1<<16))
+#define TWO_SIXTH ((double)(1<<6))
+
+/* Data structures used across files */
+
+typedef struct _FTMapping
+{
+ int named;
+ FT_CharMap cmap;
+ int base;
+ struct _FontMap *mapping; /* allow inclusion without fontenc.h */
+} FTMappingRec, *FTMappingPtr;
+
+/* Prototypes */
+
+/* ftfuncs.c */
+
+/* ftenc.c */
+
+int FTPickMapping(char*, int, char*, FT_Face, FTMappingPtr);
+unsigned FTRemap(FT_Face face, FTMappingPtr, unsigned code);
+
+/* fttools.c */
+
+int FTtoXReturnCode(int);
+int FTGetEnglishName(FT_Face, int, char *, int);
+
+extern void ErrorF(const char*, ...);
+
+#endif /* _FT_H_ */
diff --git a/libXfont/src/FreeType/ftenc.c b/libXfont/src/FreeType/ftenc.c
index d8529d47f..57de53b3a 100644
--- a/libXfont/src/FreeType/ftenc.c
+++ b/libXfont/src/FreeType/ftenc.c
@@ -1,240 +1,239 @@
-/*
-Copyright (c) 1998-2003 by Juliusz Chroboczek
-
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in
-all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-THE SOFTWARE.
-*/
-/* $XFree86: xc/lib/font/FreeType/ftenc.c,v 1.24 2003/10/19 18:53:49 dawes Exp $ */
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-#include <string.h>
-
-#include <X11/fonts/fntfilst.h>
-#include <X11/fonts/fontutil.h>
-#include <X11/fonts/FSproto.h>
-
-#include <X11/fonts/fontmisc.h>
-#include <X11/fonts/fontenc.h>
-#include <config/ftheader.h>
-#include FT_FREETYPE_H
-#include FT_TRUETYPE_IDS_H
-#include FT_TRUETYPE_TABLES_H
-#include FT_TYPE1_TABLES_H
-#include FT_BDF_H
-#include FT_XFREE86_H
-#include "ft.h"
-
-static int find_cmap(int, int, int, FT_Face, FT_CharMap *);
-
-static int
-FTEncFontSpecific(char *encoding)
-{
- char *p = encoding;
-
- if(strcasecmp(encoding, "microsoft-symbol") == 0)
- return 1;
-
- while(*p != '-') {
- if(*p == '\0')
- return 0;
- p++;
- }
- p++;
- return (strcasecmp(p, "fontspecific") == 0);
-}
-
-int
-FTPickMapping(char *xlfd, int length, char *filename, FT_Face face,
- FTMappingPtr tm)
-{
- FontEncPtr encoding;
- FontMapPtr mapping;
- FT_CharMap cmap;
- int ftrc;
- int symbol = 0;
- const char *enc, *reg;
- char *encoding_name = 0;
- char buf[20];
-
- if(xlfd)
- encoding_name = FontEncFromXLFD(xlfd, length);
- if(!encoding_name)
- encoding_name = "iso8859-1";
-
- symbol = FTEncFontSpecific(encoding_name);
-
-#if XFONT_BDFFORMAT
- ftrc = FT_Get_BDF_Charset_ID(face, &enc, &reg);
-#else
- ftrc = -1;
-#endif
- if(ftrc == 0) {
- /* Disable reencoding for non-Unicode fonts. This will
- currently only work for BDFs. */
- if(strlen(enc) + strlen(reg) > 18)
- goto native;
- strcpy(buf, enc);
- strcat(buf, "-");
- strcat(buf, reg);
- ErrorF("%s %s\n", buf, encoding_name);
- if(strcasecmp(buf, "iso10646-1") != 0) {
- if(strcasecmp(buf, encoding_name) == 0)
- goto native;
- return BadFontFormat;
- }
- } else if(symbol) {
- ftrc = FT_Select_Charmap(face, ft_encoding_adobe_custom);
- if(ftrc == 0)
- goto native;
- }
-
- encoding = FontEncFind(encoding_name, filename);
- if(symbol && encoding == NULL)
- encoding = FontEncFind("microsoft-symbol", filename);
- if(encoding == NULL) {
- ErrorF("FreeType: couldn't find encoding '%s' for '%s'\n",
- encoding_name, filename);
- return BadFontName;
- }
-
- if(FT_Has_PS_Glyph_Names(face)) {
- for(mapping = encoding->mappings; mapping; mapping = mapping->next) {
- if(mapping->type == FONT_ENCODING_POSTSCRIPT) {
- tm->named = 1;
- tm->base = 0;
- tm->mapping = mapping;
- return Successful;
- }
- }
- }
-
- for(mapping = encoding->mappings; mapping; mapping = mapping->next) {
- if(find_cmap(mapping->type, mapping->pid, mapping->eid, face,
- &cmap)) {
- tm->named = 0;
- tm->cmap = cmap;
- if(symbol) {
- /* deal with an undocumented ``feature'' of the
- Microsft-Symbol cmap */
- TT_OS2 *os2;
- os2 = FT_Get_Sfnt_Table(face, ft_sfnt_os2);
- if(os2)
- tm->base = os2->usFirstCharIndex - 0x20;
- else
- tm->base = 0;
- } else
- tm->base = 0;
- tm->mapping = mapping;
- return Successful;
- }
- }
-
- return BadFontFormat;
-
- native:
- tm->named = 0;
- tm->cmap = face->charmap;
- tm->base = 0;
- tm->mapping = NULL;
- return Successful;
-}
-
-static int
-find_cmap(int type, int pid, int eid, FT_Face face, FT_CharMap *cmap_return)
-{
- int i, n;
- FT_CharMap cmap = NULL;
-
- n = face->num_charmaps;
-
- switch(type) {
- case FONT_ENCODING_TRUETYPE: /* specific cmap */
- for(i=0; i<n; i++) {
- cmap = face->charmaps[i];
- if(cmap->platform_id == pid && cmap->encoding_id == eid) {
- *cmap_return = cmap;
- return 1;
- }
- }
- break;
- case FONT_ENCODING_UNICODE: /* any Unicode cmap */
- /* prefer Microsoft Unicode */
- for(i=0; i<n; i++) {
- cmap = face->charmaps[i];
- if(cmap->platform_id == TT_PLATFORM_MICROSOFT &&
- cmap->encoding_id == TT_MS_ID_UNICODE_CS) {
- *cmap_return = cmap;
- return 1;
- }
- }
- break;
- /* Try Apple Unicode */
- for(i=0; i<n; i++) {
- cmap = face->charmaps[i];
- if(cmap->platform_id == TT_PLATFORM_APPLE_UNICODE) {
- *cmap_return = cmap;
- return 1;
- }
- }
- /* ISO Unicode? */
- for(i=0; i<n; i++) {
- cmap = face->charmaps[i];
- if(cmap->platform_id == TT_PLATFORM_ISO) {
- *cmap_return = cmap;
- return 1;
- }
- }
- break;
- default:
- return 0;
- }
- return 0;
-}
-
-unsigned
-FTRemap(FT_Face face, FTMappingPtr tm, unsigned code)
-{
- unsigned index;
- char *name;
- unsigned glyph_index;
-
- if(tm->mapping) {
- if(tm->named) {
- name = FontEncName(code, tm->mapping);
- if(!name)
- return 0;
- glyph_index = FT_Get_Name_Index(face, name);
- return glyph_index;
- } else {
- index = FontEncRecode(code, tm->mapping) + tm->base;
- FT_Set_Charmap(face, tm->cmap);
- glyph_index = FT_Get_Char_Index(face, index);
- return glyph_index;
- }
- } else {
- if(code < 0x100) {
- index = code;
- FT_Set_Charmap(face, tm->cmap);
- glyph_index = FT_Get_Char_Index(face, index);
- return glyph_index;
- } else
- return 0;
- }
-}
+/*
+Copyright (c) 1998-2003 by Juliusz Chroboczek
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include <string.h>
+
+#include <X11/fonts/fntfilst.h>
+#include <X11/fonts/fontutil.h>
+#include <X11/fonts/FSproto.h>
+
+#include <X11/fonts/fontmisc.h>
+#include <X11/fonts/fontenc.h>
+#include <config/ftheader.h>
+#include FT_FREETYPE_H
+#include FT_TRUETYPE_IDS_H
+#include FT_TRUETYPE_TABLES_H
+#include FT_TYPE1_TABLES_H
+#include FT_BDF_H
+#include FT_XFREE86_H
+#include "ft.h"
+
+static int find_cmap(int, int, int, FT_Face, FT_CharMap *);
+
+static int
+FTEncFontSpecific(char *encoding)
+{
+ char *p = encoding;
+
+ if(strcasecmp(encoding, "microsoft-symbol") == 0)
+ return 1;
+
+ while(*p != '-') {
+ if(*p == '\0')
+ return 0;
+ p++;
+ }
+ p++;
+ return (strcasecmp(p, "fontspecific") == 0);
+}
+
+int
+FTPickMapping(char *xlfd, int length, char *filename, FT_Face face,
+ FTMappingPtr tm)
+{
+ FontEncPtr encoding;
+ FontMapPtr mapping;
+ FT_CharMap cmap;
+ int ftrc;
+ int symbol = 0;
+ const char *enc, *reg;
+ char *encoding_name = 0;
+ char buf[20];
+
+ if(xlfd)
+ encoding_name = FontEncFromXLFD(xlfd, length);
+ if(!encoding_name)
+ encoding_name = "iso8859-1";
+
+ symbol = FTEncFontSpecific(encoding_name);
+
+#if XFONT_BDFFORMAT
+ ftrc = FT_Get_BDF_Charset_ID(face, &enc, &reg);
+#else
+ ftrc = -1;
+#endif
+ if(ftrc == 0) {
+ /* Disable reencoding for non-Unicode fonts. This will
+ currently only work for BDFs. */
+ if(strlen(enc) + strlen(reg) > 18)
+ goto native;
+ strcpy(buf, enc);
+ strcat(buf, "-");
+ strcat(buf, reg);
+ ErrorF("%s %s\n", buf, encoding_name);
+ if(strcasecmp(buf, "iso10646-1") != 0) {
+ if(strcasecmp(buf, encoding_name) == 0)
+ goto native;
+ return BadFontFormat;
+ }
+ } else if(symbol) {
+ ftrc = FT_Select_Charmap(face, ft_encoding_adobe_custom);
+ if(ftrc == 0)
+ goto native;
+ }
+
+ encoding = FontEncFind(encoding_name, filename);
+ if(symbol && encoding == NULL)
+ encoding = FontEncFind("microsoft-symbol", filename);
+ if(encoding == NULL) {
+ ErrorF("FreeType: couldn't find encoding '%s' for '%s'\n",
+ encoding_name, filename);
+ return BadFontName;
+ }
+
+ if(FT_Has_PS_Glyph_Names(face)) {
+ for(mapping = encoding->mappings; mapping; mapping = mapping->next) {
+ if(mapping->type == FONT_ENCODING_POSTSCRIPT) {
+ tm->named = 1;
+ tm->base = 0;
+ tm->mapping = mapping;
+ return Successful;
+ }
+ }
+ }
+
+ for(mapping = encoding->mappings; mapping; mapping = mapping->next) {
+ if(find_cmap(mapping->type, mapping->pid, mapping->eid, face,
+ &cmap)) {
+ tm->named = 0;
+ tm->cmap = cmap;
+ if(symbol) {
+ /* deal with an undocumented ``feature'' of the
+ Microsft-Symbol cmap */
+ TT_OS2 *os2;
+ os2 = FT_Get_Sfnt_Table(face, ft_sfnt_os2);
+ if(os2)
+ tm->base = os2->usFirstCharIndex - 0x20;
+ else
+ tm->base = 0;
+ } else
+ tm->base = 0;
+ tm->mapping = mapping;
+ return Successful;
+ }
+ }
+
+ return BadFontFormat;
+
+ native:
+ tm->named = 0;
+ tm->cmap = face->charmap;
+ tm->base = 0;
+ tm->mapping = NULL;
+ return Successful;
+}
+
+static int
+find_cmap(int type, int pid, int eid, FT_Face face, FT_CharMap *cmap_return)
+{
+ int i, n;
+ FT_CharMap cmap = NULL;
+
+ n = face->num_charmaps;
+
+ switch(type) {
+ case FONT_ENCODING_TRUETYPE: /* specific cmap */
+ for(i=0; i<n; i++) {
+ cmap = face->charmaps[i];
+ if(cmap->platform_id == pid && cmap->encoding_id == eid) {
+ *cmap_return = cmap;
+ return 1;
+ }
+ }
+ break;
+ case FONT_ENCODING_UNICODE: /* any Unicode cmap */
+ /* prefer Microsoft Unicode */
+ for(i=0; i<n; i++) {
+ cmap = face->charmaps[i];
+ if(cmap->platform_id == TT_PLATFORM_MICROSOFT &&
+ cmap->encoding_id == TT_MS_ID_UNICODE_CS) {
+ *cmap_return = cmap;
+ return 1;
+ }
+ }
+ break;
+ /* Try Apple Unicode */
+ for(i=0; i<n; i++) {
+ cmap = face->charmaps[i];
+ if(cmap->platform_id == TT_PLATFORM_APPLE_UNICODE) {
+ *cmap_return = cmap;
+ return 1;
+ }
+ }
+ /* ISO Unicode? */
+ for(i=0; i<n; i++) {
+ cmap = face->charmaps[i];
+ if(cmap->platform_id == TT_PLATFORM_ISO) {
+ *cmap_return = cmap;
+ return 1;
+ }
+ }
+ break;
+ default:
+ return 0;
+ }
+ return 0;
+}
+
+unsigned
+FTRemap(FT_Face face, FTMappingPtr tm, unsigned code)
+{
+ unsigned index;
+ char *name;
+ unsigned glyph_index;
+
+ if(tm->mapping) {
+ if(tm->named) {
+ name = FontEncName(code, tm->mapping);
+ if(!name)
+ return 0;
+ glyph_index = FT_Get_Name_Index(face, name);
+ return glyph_index;
+ } else {
+ index = FontEncRecode(code, tm->mapping) + tm->base;
+ FT_Set_Charmap(face, tm->cmap);
+ glyph_index = FT_Get_Char_Index(face, index);
+ return glyph_index;
+ }
+ } else {
+ if(code < 0x100) {
+ index = code;
+ FT_Set_Charmap(face, tm->cmap);
+ glyph_index = FT_Get_Char_Index(face, index);
+ return glyph_index;
+ } else
+ return 0;
+ }
+}
diff --git a/libXfont/src/FreeType/ftfuncs.c b/libXfont/src/FreeType/ftfuncs.c
index 655afa407..f06ebb40d 100644
--- a/libXfont/src/FreeType/ftfuncs.c
+++ b/libXfont/src/FreeType/ftfuncs.c
@@ -1,3939 +1,3928 @@
-/*
-Copyright (c) 1997 by Mark Leisher
-Copyright (c) 1998-2003 by Juliusz Chroboczek
-Copyright (c) 1998 Go Watanabe, All rights reserved.
-Copyright (c) 1998 Kazushi (Jam) Marukawa, All rights reserved.
-Copyright (c) 1998 Takuya SHIOZAKI, All rights reserved.
-Copyright (c) 1998 X-TrueType Server Project, All rights reserved.
-Copyright (c) 2003-2004 After X-TT Project, All rights reserved.
-
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in
-all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-THE SOFTWARE.
-*/
-/* $XdotOrg: xc/lib/font/FreeType/ftfuncs.c,v 1.11 2005/07/03 07:00:58 daniels Exp $ */
-
-/* $XFree86: xc/lib/font/FreeType/ftfuncs.c,v 1.43 2004/02/07 04:37:18 dawes Exp $ */
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-#include <X11/fonts/fontmisc.h>
-
-#include <string.h>
-#include <math.h>
-#include <ctype.h>
-#include <unistd.h>
-
-#include <X11/fonts/fntfilst.h>
-#include <X11/fonts/fontutil.h>
-#include <X11/fonts/FSproto.h>
-#include <ft2build.h>
-#include FT_FREETYPE_H
-#include FT_SIZES_H
-#include FT_TRUETYPE_IDS_H
-#include FT_TRUETYPE_TABLES_H
-#include FT_TYPE1_TABLES_H
-#include FT_XFREE86_H
-#include FT_BBOX_H
-#include FT_TRUETYPE_TAGS_H
-/*
- * If you want to use FT_Outline_Get_CBox instead of
- * FT_Outline_Get_BBox, define here.
- */
-/* #define USE_GET_CBOX */
-#ifdef USE_GET_CBOX
-#include FT_OUTLINE_H
-#endif
-
-#include <X11/fonts/fontenc.h>
-#include "ft.h"
-#include "ftfuncs.h"
-#include "xttcap.h"
-
-/* Work around FreeType bug */
-#define WORK_AROUND_UPM 2048
-
-#ifndef True
-#define True (-1)
-#endif /* True */
-#ifndef False
-#define False (0)
-#endif /* False */
-
-#define FLOOR64(x) ((x) & -64)
-#define CEIL64(x) (((x) + 64 - 1) & -64)
-
-/*
- * If you want very lazy method(vl=y) AS DEFAULT when
- * handling large charset, define here.
- */
-/* #define DEFAULT_VERY_LAZY 1 */ /* Always */
-#define DEFAULT_VERY_LAZY 2 /* Multi-byte only */
-/* #define DEFAULT_VERY_LAZY 256 */ /* Unicode only */
-
-/* Does the X accept noSuchChar? */
-#define X_ACCEPTS_NO_SUCH_CHAR
-/* Does the XAA accept NULL noSuchChar.bits?(dangerous) */
-/* #define XAA_ACCEPTS_NULL_BITS */
-
-#ifdef X_ACCEPTS_NO_SUCH_CHAR
-static CharInfoRec noSuchChar = { /* metrics */{0,0,0,0,0,0},
- /* bits */ NULL };
-#endif
-
-/* The propery names for all the XLFD properties. */
-
-static char *xlfd_props[] = {
- "FOUNDRY",
- "FAMILY_NAME",
- "WEIGHT_NAME",
- "SLANT",
- "SETWIDTH_NAME",
- "ADD_STYLE_NAME",
- "PIXEL_SIZE",
- "POINT_SIZE",
- "RESOLUTION_X",
- "RESOLUTION_Y",
- "SPACING",
- "AVERAGE_WIDTH",
- "CHARSET_REGISTRY",
- "CHARSET_ENCODING",
-};
-
-
-/* read 2-byte value from a SFNT table */
-static FT_UShort
-sfnt_get_ushort( FT_Face face,
- FT_ULong table_tag,
- FT_ULong table_offset )
-{
- FT_Byte buff[2];
- FT_ULong len = sizeof(buff);
- FT_UShort result = 0;
-
- if ( !FT_Load_Sfnt_Table( face, table_tag, table_offset, buff, &len ) );
- result = (FT_UShort)( (buff[0] << 8) | buff[1] );
-
- return result;
-}
-
-#define sfnt_get_short(f,t,o) ((FT_Short)sfnt_get_ushort((f),(t),(o)))
-
-#ifdef _MSC_VER
-#define hypot _hypot
-#endif
-
-static int ftypeInitP = 0; /* is the engine initialised? */
-FT_Library ftypeLibrary;
-
-static FTFacePtr faceTable[NUMFACEBUCKETS];
-
-static unsigned
-hash(char *string)
-{
- int i;
- unsigned u = 0;
- for(i = 0; string[i] != '\0'; i++)
- u = (u<<5) + (u >> (NUMFACEBUCKETS - 5)) + (unsigned char)string[i];
- return u;
-}
-
-static int
-ifloor(int x, int y)
-{
- if(x >= 0)
- return x/y;
- else
- return x/y - 1;
-}
-
-static int
-iceil(int x, int y)
-{
- return ifloor(x + y - 1, y);
-}
-
-static int
-FreeTypeOpenFace(FTFacePtr *facep, char *FTFileName, char *realFileName, int faceNumber)
-{
- FT_Error ftrc;
- int bucket;
- FTFacePtr face, otherFace;
-
- if (!ftypeInitP) {
- ftrc = FT_Init_FreeType(&ftypeLibrary);
- if (ftrc != 0) {
- ErrorF("FreeType: error initializing ftypeEngine: %d\n", ftrc);
- return AllocError;
- }
- ftypeInitP = 1;
- }
-
- /* Try to find a matching face in the hashtable */
- bucket = hash(FTFileName)%NUMFACEBUCKETS;
- otherFace = faceTable[bucket];
- while(otherFace) {
- if( strcmp(otherFace->filename, FTFileName) == 0 ) break;
- otherFace = otherFace->next;
- }
- if(otherFace) {
- MUMBLE1("Returning cached face: %s\n", otherFace->filename);
- *facep = otherFace;
- return Successful;
- }
-
- /* No cached match; need to make a new one */
- face = calloc(1, sizeof(FTFaceRec));
- if (face == NULL) {
- return AllocError;
- }
-
- face->filename = strdup(FTFileName);
- if (face->filename == NULL) {
- free(face);
- return AllocError;
- }
-
- ftrc = FT_New_Face(ftypeLibrary, realFileName, faceNumber, &face->face);
- if(ftrc != 0) {
- ErrorF("FreeType: couldn't open face %s: %d\n", FTFileName, ftrc);
- free(face->filename);
- free(face);
- return BadFontName;
- }
-
- face->bitmap = ((face->face->face_flags & FT_FACE_FLAG_SCALABLE) == 0);
- if(!face->bitmap) {
- TT_MaxProfile *maxp;
- maxp = FT_Get_Sfnt_Table(face->face, ft_sfnt_maxp);
- if(maxp && maxp->maxContours == 0)
- face->bitmap = 1;
- }
-
- face->num_hmetrics = (FT_UInt) sfnt_get_ushort( face->face,
- TTAG_hhea, 34 );
-
- /* Insert face in hashtable and return it */
- face->next = faceTable[bucket];
- faceTable[bucket] = face;
- *facep = face;
- return Successful;
-}
-
-static void
-FreeTypeFreeFace(FTFacePtr face)
-{
- int bucket;
- FTFacePtr otherFace;
-
- if(!face->instances) {
- bucket = hash(face->filename) % NUMFACEBUCKETS;
- if(faceTable[bucket] == face)
- faceTable[bucket] = face->next;
- else {
- otherFace = faceTable[bucket];
- while(otherFace) {
- if(otherFace->next == face)
- break;
- otherFace = otherFace->next;
- }
- if(otherFace && otherFace->next)
- otherFace->next = otherFace->next->next;
- else
- ErrorF("FreeType: freeing unknown face\n");
- }
- MUMBLE1("Closing face: %s\n", face->filename);
- FT_Done_Face(face->face);
- free(face->filename);
- free(face);
- }
-}
-
-static int
-TransEqual(FTNormalisedTransformationPtr t1, FTNormalisedTransformationPtr t2)
-{
- if(t1->scale != t2->scale)
- return 0;
- else if(t1->xres != t2->xres || t1->yres != t2->yres)
- return 0;
- else if(t1->nonIdentity != t2->nonIdentity)
- return 0;
- else if(t1->nonIdentity && t2->nonIdentity) {
- return
- t1->matrix.xx == t2->matrix.xx &&
- t1->matrix.yx == t2->matrix.yx &&
- t1->matrix.yy == t2->matrix.yy &&
- t1->matrix.xy == t2->matrix.xy;
- } else
- return 1;
-}
-
-static int
-BitmapFormatEqual(FontBitmapFormatPtr f1, FontBitmapFormatPtr f2)
-{
- return
- f1->bit == f2->bit &&
- f1->byte == f2->byte &&
- f1->glyph == f2->glyph;
-}
-
-static int
-TTCapEqual(struct TTCapInfo *t1, struct TTCapInfo *t2)
-{
- return
- t1->autoItalic == t2->autoItalic &&
- t1->scaleWidth == t2->scaleWidth &&
- t1->scaleBBoxWidth == t2->scaleBBoxWidth &&
- t1->scaleBBoxHeight == t2->scaleBBoxHeight &&
- t1->doubleStrikeShift == t2->doubleStrikeShift &&
- t1->adjustBBoxWidthByPixel == t2->adjustBBoxWidthByPixel &&
- t1->adjustLeftSideBearingByPixel == t2->adjustLeftSideBearingByPixel &&
- t1->adjustRightSideBearingByPixel == t2->adjustRightSideBearingByPixel &&
- t1->flags == t2->flags &&
- t1->scaleBitmap == t2->scaleBitmap &&
- /*
- If we use forceConstantSpacing,
- we *MUST* allocate new instance.
- */
- t1->forceConstantSpacingEnd < 0 &&
- t2->forceConstantSpacingEnd < 0;
-}
-
-static int
-FTInstanceMatch(FTInstancePtr instance,
- char *FTFileName, FTNormalisedTransformationPtr trans,
- int spacing, FontBitmapFormatPtr bmfmt,
- struct TTCapInfo *tmp_ttcap, FT_Int32 load_flags)
-{
- if(strcmp(instance->face->filename, FTFileName) != 0) {
- return 0;
- } else if(!TransEqual(&instance->transformation, trans)) {
- return 0;
- } else if( spacing != instance->spacing ) {
- return 0;
- } else if( load_flags != instance->load_flags ) {
- return 0;
- } else if(!BitmapFormatEqual(&instance->bmfmt, bmfmt)) {
- return 0;
- } else if(!TTCapEqual(&instance->ttcap, tmp_ttcap)) {
- return 0;
- } else {
- return 1;
- }
-}
-
-static int
-FreeTypeActivateInstance(FTInstancePtr instance)
-{
- FT_Error ftrc;
- if(instance->face->active_instance == instance)
- return Successful;
-
- ftrc = FT_Activate_Size(instance->size);
- if(ftrc != 0) {
- instance->face->active_instance = NULL;
- ErrorF("FreeType: couldn't activate instance: %d\n", ftrc);
- return FTtoXReturnCode(ftrc);
- }
- FT_Set_Transform(instance->face->face,
- instance->transformation.nonIdentity ?
- &instance->transformation.matrix : 0,
- 0);
-
- instance->face->active_instance = instance;
- return Successful;
-}
-
-static int
-FTFindSize(FT_Face face, FTNormalisedTransformationPtr trans,
- int *x_return, int *y_return)
-{
- int tx, ty, x, y;
- int i, j;
- int d, dd;
-
- if(trans->nonIdentity)
- return BadFontName;
-
- tx = (int)(trans->scale * trans->xres / 72.0 + 0.5);
- ty = (int)(trans->scale * trans->yres / 72.0 + 0.5);
-
- d = 100;
- j = -1;
- for(i = 0; i < face->num_fixed_sizes; i++) {
- x = face->available_sizes[i].width;
- y = face->available_sizes[i].height;
- if(ABS(x - tx) <= 1 && ABS(y - ty) <= 1) {
- dd = ABS(x - tx) * ABS(x - tx) + ABS(y - ty) * ABS(y - ty);
- if(dd < d) {
- j = i;
- d = dd;
- }
- }
- }
- if(j < 0)
- return BadFontName;
-
- *x_return = face->available_sizes[j].width;
- *y_return = face->available_sizes[j].height;
- return Successful;
-}
-
-static int
-FreeTypeOpenInstance(FTInstancePtr *instance_return, FTFacePtr face,
- char *FTFileName, FTNormalisedTransformationPtr trans,
- int spacing, FontBitmapFormatPtr bmfmt,
- struct TTCapInfo *tmp_ttcap, FT_Int32 load_flags)
-{
- FT_Error ftrc;
- int xrc;
- FTInstancePtr instance, otherInstance;
-
- /* Search for a matching instance */
- for(otherInstance = face->instances;
- otherInstance;
- otherInstance = otherInstance->next) {
- if(FTInstanceMatch(otherInstance, FTFileName, trans, spacing, bmfmt,
- tmp_ttcap, load_flags)) break;
- }
- if(otherInstance) {
- MUMBLE("Returning cached instance\n");
- otherInstance->refcount++;
- *instance_return = otherInstance;
- return Successful;
- }
-
- /* None matching found */
- instance = malloc(sizeof(FTInstanceRec));
- if(instance == NULL) {
- return AllocError;
- }
-
- instance->refcount = 1;
- instance->face = face;
-
- instance->load_flags = load_flags;
- instance->spacing = spacing; /* Actual spacing */
- instance->pixel_size =0;
- instance->pixel_width_unit_x =0;
- instance->pixel_width_unit_y =0;
- instance->charcellMetrics = NULL;
- instance->averageWidth = 0;
- instance->rawAverageWidth = 0;
- instance->forceConstantMetrics = NULL;
-
- instance->transformation = *trans;
- instance->bmfmt = *bmfmt;
- instance->glyphs = NULL;
- instance->available = NULL;
-
- if( 0 <= tmp_ttcap->forceConstantSpacingEnd )
- instance->nglyphs = 2 * instance->face->face->num_glyphs;
- else
- instance->nglyphs = instance->face->face->num_glyphs;
-
- /* Store the TTCap info. */
- memcpy((char*)&instance->ttcap, (char*)tmp_ttcap,
- sizeof(struct TTCapInfo));
-
- ftrc = FT_New_Size(instance->face->face, &instance->size);
- if(ftrc != 0) {
- ErrorF("FreeType: couldn't create size object: %d\n", ftrc);
- free(instance);
- return FTtoXReturnCode(ftrc);
- }
- FreeTypeActivateInstance(instance);
- if(!face->bitmap) {
- ftrc = FT_Set_Char_Size(instance->face->face,
- (int)(trans->scale*(1<<6) + 0.5),
- (int)(trans->scale*(1<<6) + 0.5),
- trans->xres, trans->yres);
- } else {
- int xsize, ysize;
- xrc = FTFindSize(face->face, trans, &xsize, &ysize);
- if(xrc != Successful) {
- free(instance);
- return xrc;
- }
- ftrc = FT_Set_Pixel_Sizes(instance->face->face, xsize, ysize);
- }
- if(ftrc != 0) {
- FT_Done_Size(instance->size);
- free(instance);
- return FTtoXReturnCode(ftrc);
- }
-
- if( FT_IS_SFNT( face->face ) ) {
-#if 1
- FT_F26Dot6 tt_char_width, tt_char_height, tt_dim_x, tt_dim_y;
- FT_UInt nn;
-
- instance->strike_index=0xFFFFU;
-
- tt_char_width = (FT_F26Dot6)(trans->scale*(1<<6) + 0.5);
- tt_char_height = (FT_F26Dot6)(trans->scale*(1<<6) + 0.5);
-
- tt_dim_x = FLOOR64( ( tt_char_width * trans->xres + 36 ) / 72 + 32 );
- tt_dim_y = FLOOR64( ( tt_char_height * trans->yres + 36 ) / 72 + 32 );
-
- if ( tt_dim_x && !tt_dim_y )
- tt_dim_y = tt_dim_x;
- else if ( !tt_dim_x && tt_dim_y )
- tt_dim_x = tt_dim_y;
-
- for ( nn = 0; nn < face->face->num_fixed_sizes; nn++ )
- {
- FT_Bitmap_Size* sz = &face->face->available_sizes[nn];
-
- if ( tt_dim_x == FLOOR64(sz->x_ppem + 32) && tt_dim_y == FLOOR64(sz->y_ppem + 32) )
- {
- instance->strike_index = nn;
- break;
- }
- }
-#else
- /* See Set_Char_Sizes() in ttdriver.c */
- FT_Error err;
- TT_Face tt_face;
- FT_Long tt_dim_x, tt_dim_y;
- FT_UShort tt_x_ppem, tt_y_ppem;
- FT_F26Dot6 tt_char_width, tt_char_height;
- SFNT_Service sfnt;
- tt_face=(TT_Face)face->face;
- tt_char_width = (int)(trans->scale*(1<<6) + 0.5);
- tt_char_height = (int)(trans->scale*(1<<6) + 0.5);
- if ( ( tt_face->header.Flags & 8 ) != 0 ) {
- tt_dim_x = ( ( tt_char_width * trans->xres + (36+32*72) ) / 72 ) & -64;
- tt_dim_y = ( ( tt_char_height * trans->yres + (36+32*72) ) / 72 ) & -64;
- }
- else{
- tt_dim_x = ( ( tt_char_width * trans->xres + 36 ) / 72 );
- tt_dim_y = ( ( tt_char_height * trans->yres + 36 ) / 72 );
- }
- tt_x_ppem = (FT_UShort)( tt_dim_x >> 6 );
- tt_y_ppem = (FT_UShort)( tt_dim_y >> 6 );
- /* See Reset_SBit_Size() in ttobjs.c */
- sfnt = (SFNT_Service)tt_face->sfnt;
- err = sfnt->set_sbit_strike(tt_face,tt_x_ppem,tt_y_ppem,&instance->strike_index);
- if ( err ) instance->strike_index=0xFFFFU;
-#endif
- }
-
- /* maintain a linked list of instances */
- instance->next = instance->face->instances;
- instance->face->instances = instance;
-
- *instance_return = instance;
- return Successful;
-}
-
-static void
-FreeTypeFreeInstance(FTInstancePtr instance)
-{
- FTInstancePtr otherInstance;
-
- if( instance == NULL ) return;
-
- if(instance->face->active_instance == instance)
- instance->face->active_instance = NULL;
- instance->refcount--;
- if(instance->refcount <= 0) {
- int i,j;
-
- if(instance->face->instances == instance)
- instance->face->instances = instance->next;
- else {
- for(otherInstance = instance->face->instances;
- otherInstance;
- otherInstance = otherInstance->next)
- if(otherInstance->next == instance) {
- otherInstance->next = instance->next;
- break;
- }
- }
-
- FT_Done_Size(instance->size);
- FreeTypeFreeFace(instance->face);
-
- if(instance->charcellMetrics) {
- free(instance->charcellMetrics);
- }
- if(instance->forceConstantMetrics) {
- free(instance->forceConstantMetrics);
- }
- if(instance->glyphs) {
- for(i = 0; i < iceil(instance->nglyphs, FONTSEGMENTSIZE); i++) {
- if(instance->glyphs[i]) {
- for(j = 0; j < FONTSEGMENTSIZE; j++) {
- if(instance->available[i][j] ==
- FT_AVAILABLE_RASTERISED)
- free(instance->glyphs[i][j].bits);
- }
- free(instance->glyphs[i]);
- }
- }
- free(instance->glyphs);
- }
- if(instance->available) {
- for(i = 0; i < iceil(instance->nglyphs, FONTSEGMENTSIZE); i++) {
- if(instance->available[i])
- free(instance->available[i]);
- }
- free(instance->available);
- }
- free(instance);
- }
-}
-
-static int
-FreeTypeInstanceFindGlyph(unsigned idx_in, int flags, FTInstancePtr instance,
- CharInfoPtr **glyphs, int ***available,
- int *found, int *segmentP, int *offsetP)
-{
- int segment, offset;
- unsigned idx = idx_in;
-
- if( 0 <= instance->ttcap.forceConstantSpacingEnd ){
- if( (flags & FT_FORCE_CONSTANT_SPACING) )
- idx += instance->nglyphs / 2 ;
- }
-
- if(idx > instance->nglyphs) {
- *found = 0;
- return Successful;
- }
-
- if(*available == NULL) {
- *available = calloc(iceil(instance->nglyphs, FONTSEGMENTSIZE),
- sizeof(int *));
- if(*available == NULL)
- return AllocError;
- }
-
- segment = ifloor(idx, FONTSEGMENTSIZE);
- offset = idx - segment * FONTSEGMENTSIZE;
-
- if((*available)[segment] == NULL) {
- (*available)[segment] = calloc(FONTSEGMENTSIZE, sizeof(int *));
- if((*available)[segment] == NULL)
- return AllocError;
- }
-
- if(*glyphs == NULL) {
- *glyphs = calloc(iceil(instance->nglyphs, FONTSEGMENTSIZE),
- sizeof(CharInfoPtr));
- if(*glyphs == NULL)
- return AllocError;
- }
-
- if((*glyphs)[segment] == NULL) {
- (*glyphs)[segment] = malloc(sizeof(CharInfoRec) * FONTSEGMENTSIZE);
- if((*glyphs)[segment] == NULL)
- return AllocError;
- }
-
- *found = 1;
- *segmentP = segment;
- *offsetP = offset;
- return Successful;
-}
-
-static int
-FreeTypeInstanceGetGlyph(unsigned idx, int flags, CharInfoPtr *g, FTInstancePtr instance)
-{
- int found, segment, offset;
- int xrc;
- int ***available;
- CharInfoPtr **glyphs;
-
- available = &instance->available;
- glyphs = &instance->glyphs;
-
- xrc = FreeTypeInstanceFindGlyph(idx, flags, instance, glyphs, available,
- &found, &segment, &offset);
- if(xrc != Successful)
- return xrc;
-
- if(!found || (*available)[segment][offset] == FT_AVAILABLE_NO) {
- *g = NULL;
- return Successful;
- }
-
- if((*available)[segment][offset] == FT_AVAILABLE_RASTERISED) {
- *g = &(*glyphs)[segment][offset];
- return Successful;
- }
-
- flags |= FT_GET_GLYPH_BOTH;
-
- xrc = FreeTypeRasteriseGlyph(idx, flags,
- &(*glyphs)[segment][offset], instance,
- (*available)[segment][offset] >= FT_AVAILABLE_METRICS);
- if(xrc != Successful && (*available)[segment][offset] >= FT_AVAILABLE_METRICS) {
- ErrorF("Warning: FreeTypeRasteriseGlyph() returns an error,\n");
- ErrorF("\tso the backend tries to set a white space.\n");
- xrc = FreeTypeRasteriseGlyph(idx, flags | FT_GET_DUMMY,
- &(*glyphs)[segment][offset], instance,
- (*available)[segment][offset] >= FT_AVAILABLE_METRICS);
- }
- if(xrc == Successful) {
- (*available)[segment][offset] = FT_AVAILABLE_RASTERISED;
- /* return the glyph */
- *g = &(*glyphs)[segment][offset];
- }
- return xrc;
-}
-
-static int
-FreeTypeInstanceGetGlyphMetrics(unsigned idx, int flags,
- xCharInfo **metrics, FTInstancePtr instance )
-{
- int xrc;
- int found, segment, offset;
-
- /* Char cell */
- if(instance->spacing == FT_CHARCELL) {
- *metrics = instance->charcellMetrics;
- return Successful;
- }
- /* Force constant metrics */
- if( flags & FT_FORCE_CONSTANT_SPACING) {
- *metrics = instance->forceConstantMetrics;
- return Successful;
- }
-
- /* Not char cell */
-
- xrc = FreeTypeInstanceFindGlyph(idx, flags, instance,
- &instance->glyphs, &instance->available,
- &found, &segment, &offset);
- if(xrc != Successful)
- return xrc;
- if(!found) {
- *metrics = NULL;
- return Successful;
- }
- if( instance->available[segment][offset] == FT_AVAILABLE_NO ) {
- *metrics = NULL;
- return Successful;
- }
-
- if( instance->available[segment][offset] >= FT_AVAILABLE_METRICS ) {
- *metrics = &instance->glyphs[segment][offset].metrics;
- return Successful;
- }
-
- flags |= FT_GET_GLYPH_METRICS_ONLY;
-
- xrc = FreeTypeRasteriseGlyph(idx, flags,
- &instance->glyphs[segment][offset],
- instance, 0);
- if(xrc == Successful) {
- instance->available[segment][offset] = FT_AVAILABLE_METRICS;
- *metrics = &instance->glyphs[segment][offset].metrics;
- }
- return xrc;
-}
-
-/*
- * Pseudo enbolding similar as Microsoft Windows.
- * It is useful but poor.
- */
-static void
-ft_make_up_bold_bitmap( char *raster, int bpr, int ht, int ds_mode)
-{
- int x, y;
- unsigned char *p = (unsigned char *)raster;
- if ( ds_mode & TTCAP_DOUBLE_STRIKE_MKBOLD_EDGE_LEFT ) {
- for (y=0; y<ht; y++) {
- unsigned char rev_pat=0;
- unsigned char lsb = 0;
- for (x=0; x<bpr; x++) {
- unsigned char tmp = *p<<7;
- if ( (rev_pat & 0x01) && (*p & 0x80) ) p[-1] &= 0xfe;
- rev_pat = ~(*p);
- *p |= (*p>>1) | lsb;
- *p &= ~(rev_pat & (*p << 1));
- lsb = tmp;
- p++;
- }
- }
- }
- else {
- for (y=0; y<ht; y++) {
- unsigned char lsb = 0;
- for (x=0; x<bpr; x++) {
- unsigned char tmp = *p<<7;
- *p |= (*p>>1) | lsb;
- lsb = tmp;
- p++;
- }
- }
- }
-}
-
-static void
-ft_make_up_italic_bitmap( char *raster, int bpr, int ht, int shift,
- int h_total, int h_offset, double a_italic)
-{
- int x, y;
- unsigned char *p = (unsigned char *)raster;
- if ( a_italic < 0 ) shift = -shift;
- for (y=0; y<ht; y++) {
- unsigned char *tmp_p = p + y*bpr;
- int tmp_shift = shift * (h_total -1 -(y+h_offset)) / h_total;
- int tmp_byte_shift;
- if ( 0 <= tmp_shift ) {
- tmp_byte_shift = tmp_shift/8;
- tmp_shift %= 8;
- if ( tmp_shift ) {
- for (x=bpr-1;0<=x;x--) {
- if ( x != bpr-1 )
- tmp_p[x+1] |= tmp_p[x]<<(8-tmp_shift);
- tmp_p[x]>>=tmp_shift;
- }
- }
- if ( tmp_byte_shift ) {
- for (x=bpr-1;0<x;x--) {
- tmp_p[x] = tmp_p[x-1];
- }
- tmp_p[x]=0;
- }
- }
- else {
- tmp_shift = -tmp_shift;
- tmp_byte_shift = tmp_shift/8;
- tmp_shift %= 8;
- if ( tmp_shift ) {
- for (x=0;x<bpr;x++) {
- if ( x != 0 )
- tmp_p[x-1] |= tmp_p[x]>>(8-tmp_shift);
- tmp_p[x]<<=tmp_shift;
- }
- }
- if ( tmp_byte_shift ) {
- for (x=0;x<bpr-1;x++) {
- tmp_p[x] = tmp_p[x+1];
- }
- tmp_p[x]=0;
- }
- }
- }
-}
-
-/*
- * The very lazy method,
- * parse the htmx field in TrueType font.
- */
-
-static void
-tt_get_metrics( FT_Face face,
- FT_UInt idx,
- FT_UInt num_hmetrics,
- FT_Short* bearing,
- FT_UShort* advance )
-{
- /* read the metrics directly from the horizontal header, we
- * parse the SFNT table directly through the standard FreeType API.
- * this works with any version of the library and doesn't need to
- * peek at its internals. Maybe a bit less
- */
- FT_UInt count = num_hmetrics;
- FT_ULong length = 0;
- FT_ULong offset = 0;
- FT_Error error;
-
- error = FT_Load_Sfnt_Table( face, TTAG_hmtx, 0, NULL, &length );
-
- if ( count == 0 || error )
- {
- *advance = 0;
- *bearing = 0;
- }
- else if ( idx < count )
- {
- offset = idx * 4L;
- if ( offset + 4 > length )
- {
- *advance = 0;
- *bearing = 0;
- }
- else
- {
- *advance = sfnt_get_ushort( face, TTAG_hmtx, offset );
- *bearing = sfnt_get_short ( face, TTAG_hmtx, offset+2 );
- }
- }
- else
- {
- offset = 4L * (count - 1);
- if ( offset + 4 > length )
- {
- *advance = 0;
- *bearing = 0;
- }
- else
- {
- *advance = sfnt_get_ushort ( face, TTAG_hmtx, offset );
- offset += 4 + 2 * ( idx - count );
- if ( offset + 2 > length)
- *bearing = 0;
- else
- *bearing = sfnt_get_short ( face, TTAG_hmtx, offset );
- }
- }
-}
-
-static int
-ft_get_very_lazy_bbox( FT_UInt index,
- FT_Face face,
- FT_Size size,
- FT_UInt num_hmetrics,
- double slant,
- FT_Matrix *matrix,
- FT_BBox *bbox,
- FT_Long *horiAdvance,
- FT_Long *vertAdvance)
-{
- if ( FT_IS_SFNT( face ) ) {
- FT_Size_Metrics *smetrics = &size->metrics;
- FT_Short leftBearing = 0;
- FT_UShort advance = 0;
- FT_Vector p0, p1, p2, p3;
-
- /* horizontal */
- tt_get_metrics( face, index, num_hmetrics,
- &leftBearing, &advance );
-
-#if 0
- fprintf(stderr,"x_scale=%f y_scale=%f\n",
- (double)smetrics->x_scale,(double)smetrics->y_scale);
-#endif
- bbox->xMax = *horiAdvance =
- FT_MulFix( advance, smetrics->x_scale );
- bbox->xMin =
- FT_MulFix( leftBearing, smetrics->x_scale );
- /* vertical */
- bbox->yMin = FT_MulFix( face->bbox.yMin,
- smetrics->y_scale );
- bbox->yMax = FT_MulFix( face->bbox.yMax,
- smetrics->y_scale );
- /* slant */
- if( 0 < slant ) {
- bbox->xMax += slant * bbox->yMax;
- bbox->xMin += slant * bbox->yMin;
- }
- else if( slant < 0 ) {
- bbox->xMax += slant * bbox->yMin;
- bbox->xMin += slant * bbox->yMax;
- }
-
- *vertAdvance = -1; /* We don't support */
-
- p0.x = p2.x = bbox->xMin;
- p1.x = p3.x = bbox->xMax;
- p0.y = p1.y = bbox->yMin;
- p2.y = p3.y = bbox->yMax;
-
- FT_Vector_Transform(&p0, matrix);
- FT_Vector_Transform(&p1, matrix);
- FT_Vector_Transform(&p2, matrix);
- FT_Vector_Transform(&p3, matrix);
-
-#if 0
- fprintf(stderr,
- "->(%.1f %.1f) (%.1f %.1f)"
- " (%.1f %.1f) (%.1f %.1f)\n",
- p0.x / 64.0, p0.y / 64.0,
- p1.x / 64.0, p1.y / 64.0,
- p2.x / 64.0, p2.y / 64.0,
- p3.x / 64.0, p3.y / 64.0);
-#endif
- bbox->xMin = MIN(p0.x, MIN(p1.x, MIN(p2.x, p3.x)));
- bbox->xMax = MAX(p0.x, MAX(p1.x, MAX(p2.x, p3.x)));
- bbox->yMin = MIN(p0.y, MIN(p1.y, MIN(p2.y, p3.y)));
- bbox->yMax = MAX(p0.y, MAX(p1.y, MAX(p2.y, p3.y)));
- return 0; /* Successful */
- }
- return -1;
-}
-
-static FT_Error
-FT_Do_SBit_Metrics( FT_Face ft_face, FT_Size ft_size, FT_ULong strike_index,
- FT_UShort glyph_index, FT_Glyph_Metrics *metrics_return,
- int *sbitchk_incomplete_but_exist )
-{
-#if 1
- if ( strike_index != 0xFFFFU && ft_face->available_sizes != NULL )
- {
- FT_Error error;
- FT_Bitmap_Size* sz = &ft_face->available_sizes[strike_index];
-
- error = FT_Set_Pixel_Sizes( ft_face, sz->x_ppem/64, sz->y_ppem/64 );
- if ( !error )
- {
- error = FT_Load_Glyph( ft_face, glyph_index, FT_LOAD_SBITS_ONLY );
- if ( !error )
- {
- if ( metrics_return != NULL )
- *metrics_return = ft_face->glyph->metrics;
-
- return 0;
- }
- }
- }
- return -1;
-#elif (FREETYPE_VERSION >= 2001008)
- SFNT_Service sfnt;
- TT_Face face;
- FT_Error error;
- FT_Stream stream;
- TT_SBit_Strike strike;
- TT_SBit_Range range;
- TT_SBit_MetricsRec elem_metrics;
- FT_ULong ebdt_pos;
- FT_ULong glyph_offset;
- ;
-
- if ( ! FT_IS_SFNT( ft_face ) )
- {
- error=-1;
- goto Exit;
- }
-
- face = (TT_Face)ft_face;
- sfnt = (SFNT_Service)face->sfnt;
-
- if (strike_index != 0xFFFFU && sfnt && sfnt->find_sbit_image &&
- sfnt->load_sbits) {
- /* Check whether there is a glyph sbit for the current index */
- error = sfnt->find_sbit_image( face, glyph_index, strike_index,
- &range, &strike, &glyph_offset );
- }
- else error=-1;
- if ( error ) goto Exit;
-
- if ( metrics_return == NULL ) goto Exit;
-
- stream = face->root.stream;
-
- /* now, find the location of the `EBDT' table in */
- /* the font file */
- error = face->goto_table( face, TTAG_EBDT, stream, 0 );
- if ( error )
- error = face->goto_table( face, TTAG_bdat, stream, 0 );
- if (error)
- goto Exit;
-
- ebdt_pos = FT_STREAM_POS();
-
- /* place stream at beginning of glyph data and read metrics */
- if ( FT_STREAM_SEEK( ebdt_pos + glyph_offset ) )
- goto Exit;
-
- error = sfnt->load_sbit_metrics( stream, range, &elem_metrics );
- if ( error )
- goto Exit;
-
- metrics_return->width = (FT_Pos)elem_metrics.width << 6;
- metrics_return->height = (FT_Pos)elem_metrics.height << 6;
-
- metrics_return->horiBearingX = (FT_Pos)elem_metrics.horiBearingX << 6;
- metrics_return->horiBearingY = (FT_Pos)elem_metrics.horiBearingY << 6;
- metrics_return->horiAdvance = (FT_Pos)elem_metrics.horiAdvance << 6;
-
- metrics_return->vertBearingX = (FT_Pos)elem_metrics.vertBearingX << 6;
- metrics_return->vertBearingY = (FT_Pos)elem_metrics.vertBearingY << 6;
- metrics_return->vertAdvance = (FT_Pos)elem_metrics.vertAdvance << 6;
-
- Exit:
- return error;
-#else /* if (FREETYPE_VERSION < 2001008) */
- TT_Face face;
- SFNT_Service sfnt;
- if ( ! FT_IS_SFNT( ft_face ) ) return -1;
- face = (TT_Face)ft_face;
- sfnt = (SFNT_Service)face->sfnt;
- if ( strike_index != 0xFFFFU && sfnt->load_sbits ) {
- if ( sbitchk_incomplete_but_exist ) *sbitchk_incomplete_but_exist=1;
- }
- return -1;
-#endif
-}
-
-int
-FreeTypeRasteriseGlyph(unsigned idx, int flags, CharInfoPtr tgp,
- FTInstancePtr instance, int hasMetrics)
-{
- FTFacePtr face;
- FT_BBox bbox;
- FT_Long outline_hori_advance, outline_vert_advance;
- FT_Glyph_Metrics sbit_metrics;
- FT_Glyph_Metrics *bitmap_metrics=NULL, *metrics = NULL;
- char *raster;
- int wd, ht, bpr; /* width, height, bytes per row */
- int wd_actual, ht_actual;
- int ftrc, is_outline, correct, b_shift=0;
- int dx, dy;
- int leftSideBearing, rightSideBearing, characterWidth, rawCharacterWidth,
- ascent, descent;
- int sbitchk_incomplete_but_exist;
- double bbox_center_raw;
-
- face = instance->face;
-
- FreeTypeActivateInstance(instance);
-
- if(!tgp) return AllocError;
-
- /*
- * PREPARE METRICS
- */
-
- if(!hasMetrics) {
- if( instance->spacing == FT_CHARCELL || flags & FT_GET_DUMMY ){
- memcpy((char*)&tgp->metrics,
- (char*)instance->charcellMetrics,
- sizeof(xCharInfo));
- }
- else if( flags & FT_FORCE_CONSTANT_SPACING ) {
- memcpy((char*)&tgp->metrics,
- (char*)instance->forceConstantMetrics,
- sizeof(xCharInfo));
- }
- /* mono or prop. */
- else{
- int new_width;
- double ratio;
-
- sbitchk_incomplete_but_exist=0;
- if( ! (instance->load_flags & FT_LOAD_NO_BITMAP) ) {
- if( FT_Do_SBit_Metrics(face->face,instance->size,instance->strike_index,
- idx,&sbit_metrics,&sbitchk_incomplete_but_exist)==0 ) {
- bitmap_metrics = &sbit_metrics;
- }
- }
- if( bitmap_metrics == NULL ) {
- if ( sbitchk_incomplete_but_exist==0 && (instance->ttcap.flags & TTCAP_IS_VERY_LAZY) ) {
- if( ft_get_very_lazy_bbox( idx, face->face, instance->size,
- face->num_hmetrics,
- instance->ttcap.vl_slant,
- &instance->transformation.matrix,
- &bbox, &outline_hori_advance,
- &outline_vert_advance ) == 0 ) {
- goto bbox_ok; /* skip exact calculation */
- }
- }
- ftrc = FT_Load_Glyph(instance->face->face, idx,
- instance->load_flags);
- if(ftrc != 0) return FTtoXReturnCode(ftrc);
- metrics = &face->face->glyph->metrics;
- if( face->face->glyph->format == FT_GLYPH_FORMAT_BITMAP ) {
- bitmap_metrics = metrics;
- }
- }
-
- if( bitmap_metrics ) {
- FT_Pos factor;
-
- leftSideBearing = bitmap_metrics->horiBearingX / 64;
- rightSideBearing = (bitmap_metrics->width + bitmap_metrics->horiBearingX) / 64;
- bbox_center_raw = (2.0 * bitmap_metrics->horiBearingX + bitmap_metrics->width)/2.0/64.0;
- characterWidth = (int)floor(bitmap_metrics->horiAdvance
- * instance->ttcap.scaleBBoxWidth / 64.0 + .5);
- ascent = bitmap_metrics->horiBearingY / 64;
- descent = (bitmap_metrics->height - bitmap_metrics->horiBearingY) / 64 ;
- /* */
- new_width = characterWidth;
- if( instance->ttcap.flags & TTCAP_DOUBLE_STRIKE_CORRECT_B_BOX_WIDTH )
- new_width += instance->ttcap.doubleStrikeShift;
- new_width += instance->ttcap.adjustBBoxWidthByPixel;
- ratio = (double)new_width/characterWidth;
- characterWidth = new_width;
- /* adjustment by pixel unit */
- if( instance->ttcap.flags & TTCAP_DOUBLE_STRIKE )
- rightSideBearing += instance->ttcap.doubleStrikeShift;
- rightSideBearing += instance->ttcap.adjustRightSideBearingByPixel;
- leftSideBearing += instance->ttcap.adjustLeftSideBearingByPixel;
- rightSideBearing += instance->ttcap.rsbShiftOfBitmapAutoItalic;
- leftSideBearing += instance->ttcap.lsbShiftOfBitmapAutoItalic;
- /* */
- factor = bitmap_metrics->horiAdvance;
- rawCharacterWidth = (unsigned short)(short)(floor(1000 * factor
- * instance->ttcap.scaleBBoxWidth * ratio / 64.
- / instance->pixel_size));
- }
- else {
- /* Outline */
-#ifdef USE_GET_CBOX
- /* Very fast?? */
- FT_Outline_Get_CBox(&face->face->glyph->outline, &bbox);
- ftrc=0; /* FT_Outline_Get_CBox returns nothing. */
-#else
- /* Calculate exact metrics */
- ftrc=FT_Outline_Get_BBox(&face->face->glyph->outline, &bbox);
-#endif
- if( ftrc != 0 ) return FTtoXReturnCode(ftrc);
- outline_hori_advance = metrics->horiAdvance;
- outline_vert_advance = metrics->vertAdvance;
- bbox_ok:
- descent = CEIL64(-bbox.yMin - 32) / 64;
- leftSideBearing = FLOOR64(bbox.xMin + 32) / 64;
- ascent = FLOOR64(bbox.yMax + 32) / 64;
- rightSideBearing = FLOOR64(bbox.xMax + 32) / 64;
- bbox_center_raw = (double)(bbox.xMax + bbox.xMin)/2.0/64.;
- if ( instance->pixel_width_unit_x != 0 )
- characterWidth =
- (int)floor( outline_hori_advance
- * instance->ttcap.scaleBBoxWidth
- * instance->pixel_width_unit_x / 64. + .5);
- else {
- characterWidth =
- (int)floor( outline_vert_advance
- * instance->ttcap.scaleBBoxHeight
- * instance->pixel_width_unit_y / 64. + .5);
- if(characterWidth <= 0)
- characterWidth = instance->charcellMetrics->characterWidth;
- }
- /* */
- new_width = characterWidth;
- if( instance->ttcap.flags & TTCAP_DOUBLE_STRIKE_CORRECT_B_BOX_WIDTH )
- new_width += instance->ttcap.doubleStrikeShift;
- new_width += instance->ttcap.adjustBBoxWidthByPixel;
- ratio = (double)new_width/characterWidth;
- characterWidth = new_width;
- if ( instance->pixel_width_unit_x != 0 )
- rawCharacterWidth =
- (unsigned short)(short)(floor(1000 * outline_hori_advance
- * instance->ttcap.scaleBBoxWidth * ratio
- * instance->pixel_width_unit_x / 64.));
- else {
- rawCharacterWidth =
- (unsigned short)(short)(floor(1000 * outline_vert_advance
- * instance->ttcap.scaleBBoxHeight * ratio
- * instance->pixel_width_unit_y / 64.));
- if(rawCharacterWidth <= 0)
- rawCharacterWidth = instance->charcellMetrics->attributes;
- }
- /* adjustment by pixel unit */
- if( instance->ttcap.flags & TTCAP_DOUBLE_STRIKE )
- rightSideBearing += instance->ttcap.doubleStrikeShift;
- rightSideBearing += instance->ttcap.adjustRightSideBearingByPixel;
- leftSideBearing += instance->ttcap.adjustLeftSideBearingByPixel;
- }
-
- /* Set the glyph metrics. */
- tgp->metrics.attributes = (unsigned short)((short)rawCharacterWidth);
- tgp->metrics.leftSideBearing = leftSideBearing;
- tgp->metrics.rightSideBearing = rightSideBearing;
- tgp->metrics.characterWidth = characterWidth;
- tgp->metrics.ascent = ascent;
- tgp->metrics.descent = descent;
- /* Update the width to match the width of the font */
- if( instance->spacing != FT_PROPORTIONAL )
- tgp->metrics.characterWidth = instance->charcellMetrics->characterWidth;
- if(instance->ttcap.flags & TTCAP_MONO_CENTER){
- b_shift = (int)floor((instance->advance/2.0-bbox_center_raw) + .5);
- tgp->metrics.leftSideBearing += b_shift;
- tgp->metrics.rightSideBearing += b_shift;
- }
- }
- }
-
- if( flags & FT_GET_GLYPH_METRICS_ONLY ) return Successful;
-
- /*
- * CHECK THE NECESSITY OF BITMAP POSITION'S CORRECTION
- */
-
- correct=0;
- if( instance->spacing == FT_CHARCELL ) correct=1;
- else if( flags & FT_FORCE_CONSTANT_SPACING ) correct=1;
- else{
- int sbit_available=0;
- sbitchk_incomplete_but_exist=0;
- if( !(instance->load_flags & FT_LOAD_NO_BITMAP) ) {
- if( FT_Do_SBit_Metrics(face->face,instance->size,
- instance->strike_index,idx,NULL,
- &sbitchk_incomplete_but_exist)==0 ) {
- sbit_available=1;
- }
- }
- if( sbit_available == 0 ) {
- if ( sbitchk_incomplete_but_exist==0 && (instance->ttcap.flags & TTCAP_IS_VERY_LAZY) ) {
- if( FT_IS_SFNT(face->face) ) correct=1;
- }
- }
- }
-
- /*
- * RENDER AND ALLOCATE BUFFER
- */
-
- if( flags & FT_GET_DUMMY ) is_outline = -1;
- else {
- if( !metrics ) {
- ftrc = FT_Load_Glyph(instance->face->face, idx,
- instance->load_flags);
- metrics = &face->face->glyph->metrics;
-
- if(ftrc != 0) return FTtoXReturnCode(ftrc);
- }
-
- if( face->face->glyph->format != FT_GLYPH_FORMAT_BITMAP ) {
-#ifdef USE_GET_CBOX
- FT_Outline_Get_CBox(&face->face->glyph->outline, &bbox);
- ftrc = 0;
-#else
- ftrc = FT_Outline_Get_BBox(&face->face->glyph->outline, &bbox);
-#endif
- if( ftrc != 0 ) return FTtoXReturnCode(ftrc);
- bbox.yMin = FLOOR64( bbox.yMin );
- bbox.yMax = CEIL64 ( bbox.yMax );
- ht_actual = ( bbox.yMax - bbox.yMin ) >> 6;
- /* FreeType think a glyph with 0 height control box is invalid.
- * So just let X to create a empty bitmap instead. */
- if ( ht_actual == 0 )
- is_outline = -1;
- else
- {
- ftrc = FT_Render_Glyph(face->face->glyph,FT_RENDER_MODE_MONO);
- if( ftrc != 0 ) return FTtoXReturnCode(ftrc);
- is_outline = 1;
- }
- }
- else{
- is_outline=0;
- }
- }
-
- /* Spacial case */
- if( (instance->ttcap.flags & TTCAP_MONO_CENTER) && hasMetrics ) {
- if( is_outline == 1 ){
- if( correct ){
- if( ft_get_very_lazy_bbox( idx, face->face, instance->size,
- face->num_hmetrics,
- instance->ttcap.vl_slant,
- &instance->transformation.matrix,
- &bbox, &outline_hori_advance,
- &outline_vert_advance ) != 0 ){
- is_outline = -1; /* <- error */
- }
- }
- else {
-#ifdef USE_GET_CBOX
- FT_Outline_Get_CBox(&face->face->glyph->outline, &bbox);
- ftrc=0;
-#else
- ftrc=FT_Outline_Get_BBox(&face->face->glyph->outline, &bbox);
-#endif
- if( ftrc != 0 ) return FTtoXReturnCode(ftrc);
- }
- bbox_center_raw = (double)(bbox.xMax + bbox.xMin)/2.0/64.;
- }
- else if( is_outline == 0 )
- bbox_center_raw = (2.0 * metrics->horiBearingX + metrics->width)/2.0/64.0;
- else
- bbox_center_raw = 0;
- b_shift = (int)floor((instance->advance/2.0-bbox_center_raw) + .5);
- }
-
- wd_actual = tgp->metrics.rightSideBearing - tgp->metrics.leftSideBearing;
- ht_actual = tgp->metrics.ascent + tgp->metrics.descent;
-
- /* The X convention is to consider a character with an empty
- * bounding box as undefined. This convention is broken. */
-
- if(wd_actual <= 0) wd = 1;
- else wd=wd_actual;
- if(ht_actual <= 0) ht = 1;
- else ht=ht_actual;
-
- bpr = (((wd + (instance->bmfmt.glyph<<3) - 1) >> 3) &
- -instance->bmfmt.glyph);
- raster = calloc(1, ht * bpr);
- if(raster == NULL)
- return AllocError;
-
- tgp->bits = raster;
-
- /* If FT_GET_DUMMY is set, we return white space. */
- if ( is_outline == -1 ) return Successful;
-
- if ( wd_actual <= 0 || ht_actual <= 0 ) return Successful;
-
- /*
- * CALCULATE OFFSET, dx AND dy.
- */
-
- dx = face->face->glyph->bitmap_left - tgp->metrics.leftSideBearing;
- dy = tgp->metrics.ascent - face->face->glyph->bitmap_top;
-
- if(instance->ttcap.flags & TTCAP_MONO_CENTER)
- dx += b_shift;
-
- /* To prevent chipped bitmap, we correct dx and dy if needed. */
- if( correct && is_outline==1 ){
- int lsb, rsb, asc, des;
- int chip_left,chip_right,chip_top,chip_bot;
-#ifdef USE_GET_CBOX
- FT_Outline_Get_CBox(&face->face->glyph->outline, &bbox);
- ftrc=0;
-#else
- ftrc=FT_Outline_Get_BBox(&face->face->glyph->outline, &bbox);
-#endif
- if( ftrc != 0 ) return FTtoXReturnCode(ftrc);
- des = CEIL64(-bbox.yMin - 32) / 64;
- lsb = FLOOR64(bbox.xMin + 32) / 64;
- asc = FLOOR64(bbox.yMax + 32) / 64;
- rsb = FLOOR64(bbox.xMax + 32) / 64;
- rightSideBearing = tgp->metrics.rightSideBearing;
- leftSideBearing = tgp->metrics.leftSideBearing;
- if( instance->ttcap.flags & TTCAP_DOUBLE_STRIKE )
- rightSideBearing -= instance->ttcap.doubleStrikeShift;
- /* special case */
- if(instance->ttcap.flags & TTCAP_MONO_CENTER){
- leftSideBearing -= b_shift;
- rightSideBearing -= b_shift;
- }
- chip_left = lsb - leftSideBearing;
- chip_right = rightSideBearing - rsb;
- if( flags & FT_FORCE_CONSTANT_SPACING ){
- if( instance->ttcap.force_c_adjust_lsb_by_pixel != 0 ||
- instance->ttcap.force_c_adjust_rsb_by_pixel != 0 ){
- chip_left=0;
- chip_right=0;
- }
- }
- else{
- if( instance->ttcap.adjustRightSideBearingByPixel != 0 ||
- instance->ttcap.adjustLeftSideBearingByPixel != 0 ){
- chip_left=0;
- chip_right=0;
- }
- }
- chip_top = tgp->metrics.ascent - asc;
- chip_bot = tgp->metrics.descent - des;
- if( chip_left < 0 && 0 < chip_right ) dx++;
- else if( chip_right < 0 && 0 < chip_left ) dx--;
- if( chip_top < 0 && 0 < chip_bot ) dy++;
- else if( chip_bot < 0 && 0 < chip_top ) dy--;
- }
-
- /*
- * COPY RASTER
- */
-
- {
- FT_Bitmap *bitmap;
- int i, j;
- unsigned char *current_raster;
- unsigned char *current_buffer;
- int mod_dx0,mod_dx1;
- int div_dx;
- bitmap = &face->face->glyph->bitmap;
- if( 0 <= dx ){
- div_dx = dx / 8;
- mod_dx0 = dx % 8;
- mod_dx1 = 8-mod_dx0;
- }
- else{
- div_dx = dx / 8 -1;
- mod_dx1 = -dx % 8;
- mod_dx0 = 8-mod_dx1;
- }
- for( i = MAX(0, dy) ; i<ht ; i++ ){
- int prev_jj,jj;
- if( bitmap->rows <= i-dy ) break;
- current_buffer=(unsigned char *)(bitmap->buffer+bitmap->pitch*(i-dy));
- current_raster=(unsigned char *)(raster+i*bpr);
- j = MAX(0,div_dx);
- jj = j-div_dx;
- prev_jj = jj-1;
- if( j<bpr ){
- if( 0 <= prev_jj && prev_jj < bitmap->pitch )
- current_raster[j]|=current_buffer[prev_jj]<<mod_dx1;
- if( 0 <= jj && jj < bitmap->pitch ){
- current_raster[j]|=current_buffer[jj]>>mod_dx0;
- j++; prev_jj++; jj++;
- for( ; j<bpr ; j++,prev_jj++,jj++ ){
- current_raster[j]|=current_buffer[prev_jj]<<mod_dx1;
- if( bitmap->pitch <= jj ) break;
- current_raster[j]|=current_buffer[jj]>>mod_dx0;
- }
- }
- }
- }
- }
-
- /* by TTCap */
- if ( instance->ttcap.flags & TTCAP_DOUBLE_STRIKE ) {
- int i;
- for( i=0 ; i < instance->ttcap.doubleStrikeShift ; i++ )
- ft_make_up_bold_bitmap( raster, bpr, ht, instance->ttcap.flags);
- }
- if ( is_outline == 0 &&
- ( instance->ttcap.lsbShiftOfBitmapAutoItalic != 0 ||
- instance->ttcap.rsbShiftOfBitmapAutoItalic != 0 ) ) {
- ft_make_up_italic_bitmap( raster, bpr, ht,
- - instance->ttcap.lsbShiftOfBitmapAutoItalic
- + instance->ttcap.rsbShiftOfBitmapAutoItalic,
- instance->charcellMetrics->ascent
- + instance->charcellMetrics->descent,
- instance->charcellMetrics->ascent
- - tgp->metrics.ascent,
- instance->ttcap.autoItalic);
- }
-
- if(instance->bmfmt.bit == LSBFirst) {
- BitOrderInvert((unsigned char*)(tgp->bits), ht*bpr);
- }
-
- if(instance->bmfmt.byte != instance->bmfmt.bit) {
- switch(instance->bmfmt.scan) {
- case 1:
- break;
- case 2:
- TwoByteSwap((unsigned char*)(tgp->bits), ht*bpr);
- break;
- case 4:
- FourByteSwap((unsigned char*)(tgp->bits), ht*bpr);
- break;
- default:
- ;
- }
- }
-
- return Successful;
-}
-
-static void
-FreeTypeFreeFont(FTFontPtr font)
-{
- FreeTypeFreeInstance(font->instance);
- if(font->ranges)
- free(font->ranges);
- if(font->dummy_char.bits)
- free(font->dummy_char.bits);
- free(font);
-}
-
-/* Free a font. If freeProps is 0, don't free the properties. */
-
-static void
-FreeTypeFreeXFont(FontPtr pFont, int freeProps)
-{
- FTFontPtr tf;
-
- if(pFont) {
- if((tf = (FTFontPtr)pFont->fontPrivate)) {
- FreeTypeFreeFont(tf);
- }
- if(freeProps && pFont->info.nprops>0) {
- free(pFont->info.isStringProp);
- free(pFont->info.props);
- }
- DestroyFontRec(pFont);
- }
-}
-
-
-/* Unload a font */
-
-static void
-FreeTypeUnloadXFont(FontPtr pFont)
-{
- MUMBLE("Unloading\n");
- FreeTypeFreeXFont(pFont, 1);
-}
-
-/* Add the font properties, including the Font name, the XLFD
- properties, some strings from the font, and various typographical
- data. We only provide data readily available in the tables in the
- font for now, altough FIGURE_WIDTH would be a good idea as it is
- used by Xaw. */
-
-static int
-FreeTypeAddProperties(FTFontPtr font, FontScalablePtr vals, FontInfoPtr info,
- char *fontname, int rawAverageWidth, Bool font_properties)
-{
- int i, j, maxprops;
- char *sp, *ep, val[MAXFONTNAMELEN], *vp;
- FTFacePtr face;
- FTInstancePtr instance;
- FTNormalisedTransformationPtr trans;
- int upm;
- TT_OS2 *os2;
- TT_Postscript *post;
- PS_FontInfoRec t1info_rec, *t1info;
- int xlfdProps = 0;
- int ftrc;
-
- instance = font->instance;
- face = instance->face;
- trans = &instance->transformation;
- upm = face->face->units_per_EM;
- if(upm == 0) {
- /* Work around FreeType bug */
- upm = WORK_AROUND_UPM;
- }
-
- os2 = FT_Get_Sfnt_Table(face->face, ft_sfnt_os2);
- post = FT_Get_Sfnt_Table(face->face, ft_sfnt_post);
- ftrc = FT_Get_PS_Font_Info(face->face, &t1info_rec);
- if(ftrc == 0)
- t1info = &t1info_rec;
- else
- t1info = NULL;
-
- if(t1info) {
- os2 = NULL;
- post = NULL;
- }
-
- info->nprops = 0; /* in case we abort */
-
- strcpy(val, fontname);
- if(FontParseXLFDName(val, vals, FONT_XLFD_REPLACE_VALUE)) {
- xlfdProps = 1;
- } else {
- MUMBLE("Couldn't parse XLFD\n");
- xlfdProps = 0;
- }
-
- maxprops=
- 1 + /* NAME */
- (xlfdProps ? 14 : 0) + /* from XLFD */
- 5 +
- ( !face->bitmap ? 3 : 0 ) + /* raw_av,raw_asc,raw_dec */
- ( font_properties ? 2 : 0 ) + /* asc,dec */
- ( (font_properties && os2) ? 6 : 0 ) +
- ( (font_properties && (post || t1info)) ? 3 : 0 ) +
- 2; /* type */
-
- info->props = malloc(maxprops * sizeof(FontPropRec));
- if(info->props == NULL)
- return AllocError;
-
- info->isStringProp = malloc(maxprops);
- if(info->isStringProp == NULL) {
- free(info->props);
- return AllocError;
- }
-
- memset((char *)info->isStringProp, 0, maxprops);
-
- i = 0;
-
- info->props[i].name = MakeAtom("FONT", 4, TRUE);
- info->props[i].value = MakeAtom(val, strlen(val), TRUE);
- info->isStringProp[i] = 1;
- i++;
-
- if(*val && *(sp = val + 1)) {
- for (j = 0, sp = val + 1; j < 14; j++) {
- if (j == 13)
- /* Handle the case of the final field containing a subset
- specification. */
- for (ep = sp; *ep && *ep != '['; ep++);
- else
- for (ep = sp; *ep && *ep != '-'; ep++);
-
- info->props[i].name =
- MakeAtom(xlfd_props[j], strlen(xlfd_props[j]), TRUE);
-
- switch(j) {
- case 6: /* pixel size */
- info->props[i].value =
- (int)(fabs(vals->pixel_matrix[3]) + 0.5);
- i++;
- break;
- case 7: /* point size */
- info->props[i].value =
- (int)(fabs(vals->point_matrix[3])*10.0 + 0.5);
- i++;
- break;
- case 8: /* resolution x */
- info->props[i].value = vals->x;
- i++;
- break;
- case 9: /* resolution y */
- info->props[i].value = vals->y;
- i++;
- break;
- case 11: /* average width */
- info->props[i].value = vals->width;
- i++;
- break;
- default: /* a string */
- info->props[i].value = MakeAtom(sp, ep - sp, TRUE);
- info->isStringProp[i] = 1;
- i++;
- }
- sp = ++ep;
- }
- }
-
- info->props[i].name = MakeAtom("RAW_PIXEL_SIZE", 14, TRUE);
- info->props[i].value = 1000;
- i++;
-
- info->props[i].name = MakeAtom("RAW_POINT_SIZE", 14, TRUE);
- info->props[i].value = (long)(72270.0 / (double)vals->y + .5);
- i++;
-
- if(!face->bitmap) {
- info->props[i].name = MakeAtom("RAW_AVERAGE_WIDTH", 17, TRUE);
- info->props[i].value = rawAverageWidth;
- i++;
- }
-
- if ( font_properties ) {
- info->props[i].name = MakeAtom("FONT_ASCENT", 11, TRUE);
- info->props[i].value = info->fontAscent;
- i++;
- }
-
- if(!face->bitmap) {
- info->props[i].name = MakeAtom("RAW_ASCENT", 10, TRUE);
- info->props[i].value =
- ((double)face->face->ascender/(double)upm*1000.0);
- i++;
- }
-
- if ( font_properties ) {
- info->props[i].name = MakeAtom("FONT_DESCENT", 12, TRUE);
- info->props[i].value = info->fontDescent;
- i++;
- }
-
- if(!face->bitmap) {
- info->props[i].name = MakeAtom("RAW_DESCENT", 11, TRUE);
- info->props[i].value =
- -((double)face->face->descender/(double)upm*1000.0);
- i++;
- }
-
- j = FTGetEnglishName(face->face, TT_NAME_ID_COPYRIGHT,
- val, MAXFONTNAMELEN);
- vp = val;
- if (j < 0) {
- if(t1info && t1info->notice) {
- vp = t1info->notice;
- j = strlen(vp);
- }
- }
- if(j > 0) {
- info->props[i].name = MakeAtom("COPYRIGHT", 9, TRUE);
- info->props[i].value = MakeAtom(vp, j, TRUE);
- info->isStringProp[i] = 1;
- i++;
- }
-
- j = FTGetEnglishName(face->face, TT_NAME_ID_FULL_NAME,
- val, MAXFONTNAMELEN);
- vp = val;
- if (j < 0) {
- if(t1info && t1info->full_name) {
- vp = t1info->full_name;
- j = strlen(vp);
- }
- }
- if(j > 0) {
- info->props[i].name = MakeAtom("FACE_NAME", 9, TRUE);
- info->props[i].value = MakeAtom(vp, j, TRUE);
- info->isStringProp[i] = 1;
- i++;
- }
-
- vp = (char *)FT_Get_Postscript_Name(face->face);
- if (vp) {
- j = strlen(vp);
- } else {
- j = -1;
- }
- if (j < 0) {
- j = FTGetEnglishName(face->face, TT_NAME_ID_PS_NAME,
- val, MAXFONTNAMELEN);
- vp = val;
- }
- if (j < 0) {
- if(t1info && t1info->full_name) {
- vp = t1info->full_name;
- j = strlen(vp);
- }
- }
- if(j > 0) {
- info->props[i].name = MakeAtom("_ADOBE_POSTSCRIPT_FONTNAME", 26, TRUE);
- info->props[i].value = MakeAtom(vp, j, TRUE);
- info->isStringProp[i] = 1;
- i++;
- }
-
- /* These macros handle the case of a diagonal matrix. They convert
- FUnits into pixels. */
-#define TRANSFORM_FUNITS_X(xval) \
- ((int) \
- floor( ((double)(xval)/(double)upm) * (double)vals->pixel_matrix[0] + 0.5 ) )
-
-#define TRANSFORM_FUNITS_Y(yval) \
- ((int) \
- floor( ((double)(yval)/(double)upm) * (double)vals->pixel_matrix[3] + 0.5 ) )
-
- /* In what follows, we assume the matrix is diagonal. In the rare
- case when it is not, the values will be somewhat wrong. */
-
- if( font_properties && os2 ) {
- info->props[i].name = MakeAtom("SUBSCRIPT_SIZE",14,TRUE);
- info->props[i].value =
- TRANSFORM_FUNITS_Y(os2->ySubscriptYSize);
- i++;
- info->props[i].name = MakeAtom("SUBSCRIPT_X",11,TRUE);
- info->props[i].value =
- TRANSFORM_FUNITS_X(os2->ySubscriptXOffset);
- i++;
- info->props[i].name = MakeAtom("SUBSCRIPT_Y",11,TRUE);
- info->props[i].value =
- TRANSFORM_FUNITS_Y(os2->ySubscriptYOffset);
- i++;
- info->props[i].name = MakeAtom("SUPERSCRIPT_SIZE",16,TRUE);
- info->props[i].value =
- TRANSFORM_FUNITS_Y(os2->ySuperscriptYSize);
- i++;
- info->props[i].name = MakeAtom("SUPERSCRIPT_X",13,TRUE);
- info->props[i].value =
- TRANSFORM_FUNITS_X(os2->ySuperscriptXOffset);
- i++;
- info->props[i].name = MakeAtom("SUPERSCRIPT_Y",13,TRUE);
- info->props[i].value =
- TRANSFORM_FUNITS_Y(os2->ySuperscriptYOffset);
- i++;
- }
-
- if( font_properties && (post || t1info) ) {
- int underlinePosition, underlineThickness;
-
- /* Raw underlineposition counts upwards,
- but UNDERLINE_POSITION counts downwards. */
- if(post) {
- underlinePosition = TRANSFORM_FUNITS_Y(-post->underlinePosition);
- underlineThickness = TRANSFORM_FUNITS_Y(post->underlineThickness);
- } else {
- underlinePosition =
- TRANSFORM_FUNITS_Y(-t1info->underline_position);
- underlineThickness =
- TRANSFORM_FUNITS_Y(t1info->underline_thickness);
- }
- if(underlineThickness <= 0)
- underlineThickness = 1;
-
- info->props[i].name = MakeAtom("UNDERLINE_THICKNESS",19,TRUE);
- info->props[i].value = underlineThickness;
- i++;
-
- info->props[i].name = MakeAtom("UNDERLINE_POSITION",18,TRUE);
-
- info->props[i].value = underlinePosition;
-
- i++;
-
- /* The italic angle is often unreliable for Type 1 fonts */
- if(post && trans->matrix.xx == trans->matrix.yy) {
- info->props[i].name = MakeAtom("ITALIC_ANGLE",12,TRUE);
- info->props[i].value =
- /* Convert from TT_Fixed to
- 64th of a degree counterclockwise from 3 o'clock */
- 90*64+(post->italicAngle >> 10);
- i++;
- }
-#undef TRANSFORM_FUNITS_X
-#undef TRANSFORM_FUNITS_Y
- }
-
- info->props[i].name = MakeAtom("FONT_TYPE", 9, TRUE);
- vp = (char *)FT_Get_X11_Font_Format(face->face);
- info->props[i].value = MakeAtom(vp, strlen(vp), TRUE);
- info->isStringProp[i] = 1;
- i++;
-
- info->props[i].name = MakeAtom("RASTERIZER_NAME", 15, TRUE);
- info->props[i].value = MakeAtom("FreeType", 10, TRUE);
- info->isStringProp[i] = 1;
- i++;
-
- info->nprops = i;
- return Successful;
-}
-
-static int
-ft_get_index(unsigned code, FTFontPtr font, unsigned *idx)
-{
-
- /* As a special case, we pass 0 even when it is not in the ranges;
- this will allow for the default glyph, which should exist in any
- TrueType font. */
-
- /* This is not required...
- if(code > 0 && font->nranges) {
- int i;
- for(i = 0; i < font->nranges; i++)
- if((code >=
- font->ranges[i].min_char_low+
- (font->ranges[i].min_char_high<<8)) &&
- (code <=
- font->ranges[i].max_char_low +
- (font->ranges[i].max_char_high<<8)))
- break;
- if(i == font->nranges) {
- *idx = font->zero_idx;
- return -1;
- }
- }
- */
- if( font->info ) {
- if( !( font->info->firstCol <= (code & 0x000ff) &&
- (code & 0x000ff) <= font->info->lastCol &&
- font->info->firstRow <= (code >> 8) &&
- (code >> 8) <= font->info->lastRow ) ) {
- *idx = font->zero_idx;
- /* Error: The code has not been parsed in ft_compute_bounds()!
- We should not return any metrics. */
- return -1;
- }
- }
-
- *idx = FTRemap(font->instance->face->face, &font->mapping, code);
-
- return 0;
-}
-
-static int
-FreeTypeFontGetGlyph(unsigned code, int flags, CharInfoPtr *g, FTFontPtr font)
-{
- unsigned idx = 0;
- int xrc;
-
-#ifdef X_ACCEPTS_NO_SUCH_CHAR
- if( ft_get_index(code,font,&idx) || idx == 0 || idx == font->zero_idx ) {
- *g = NULL;
- flags &= ~FT_FORCE_CONSTANT_SPACING;
- /* if( font->instance->spacing != FT_CHARCELL ) */
- return Successful;
- }
-#else
- if( ft_get_index(code,font,&idx) ) {
- /* The code has not been parsed! */
- *g = NULL;
- flags &= ~FT_FORCE_CONSTANT_SPACING;
- }
-#endif
-
- xrc = FreeTypeInstanceGetGlyph(idx, flags, g, font->instance);
- if( xrc == Successful && *g != NULL )
- return Successful;
- if( font->zero_idx != idx ) {
- xrc = FreeTypeInstanceGetGlyph(font->zero_idx, flags, g, font->instance);
- if( xrc == Successful && *g != NULL )
- return Successful;
- }
- return FreeTypeInstanceGetGlyph(font->zero_idx, flags|FT_GET_DUMMY, g, font->instance);
-}
-
-static int
-FreeTypeFontGetGlyphMetrics(unsigned code, int flags, xCharInfo **metrics, FTFontPtr font)
-{
- unsigned idx = 0;
- int xrc;
-
-#ifdef X_ACCEPTS_NO_SUCH_CHAR
- if ( ft_get_index(code,font,&idx) || idx == 0 || idx == font->zero_idx ) {
- *metrics = NULL;
- flags &= ~FT_FORCE_CONSTANT_SPACING;
- /* if( font->instance->spacing != FT_CHARCELL ) */
- return Successful;
- }
-#else
- if ( ft_get_index(code,font,&idx) || idx == 0 || idx == font->zero_idx ) {
- /* The code has not been parsed! */
- *metrics = NULL;
- flags &= ~FT_FORCE_CONSTANT_SPACING;
- }
-#endif
-
- xrc = FreeTypeInstanceGetGlyphMetrics(idx, flags, metrics, font->instance);
- if( xrc == Successful && *metrics != NULL )
- return Successful;
- if( font->zero_idx != idx ) {
- xrc = FreeTypeInstanceGetGlyphMetrics(font->zero_idx, flags,
- metrics, font->instance);
- if( xrc == Successful && *metrics != NULL )
- return Successful;
- }
- return FreeTypeInstanceGetGlyphMetrics(font->zero_idx, flags|FT_GET_DUMMY, metrics, font->instance);
-}
-
-/*
- * restrict code range
- *
- * boolean for the numeric zone:
- * results = results & (ranges[0] | ranges[1] | ... ranges[nranges-1])
- */
-
-static void
-restrict_code_range(unsigned short *refFirstCol,
- unsigned short *refFirstRow,
- unsigned short *refLastCol,
- unsigned short *refLastRow,
- fsRange const *ranges, int nRanges)
-{
- if (nRanges) {
- int minCol = 256, minRow = 256, maxCol = -1, maxRow = -1;
- fsRange const *r = ranges;
- int i;
-
- for (i=0; i<nRanges; i++) {
- if (r->min_char_high != r->max_char_high) {
- minCol = 0x00;
- maxCol = 0xff;
- } else {
- if (minCol > r->min_char_low)
- minCol = r->min_char_low;
- if (maxCol < r->max_char_low)
- maxCol = r->max_char_low;
- }
- if (minRow > r->min_char_high)
- minRow = r->min_char_high;
- if (maxRow < r->max_char_high)
- maxRow = r->max_char_high;
- r++;
- }
-
- if (minCol > *refLastCol)
- *refFirstCol = *refLastCol;
- else if (minCol > *refFirstCol)
- *refFirstCol = minCol;
-
- if (maxCol < *refFirstCol)
- *refLastCol = *refFirstCol;
- else if (maxCol < *refLastCol)
- *refLastCol = maxCol;
-
- if (minRow > *refLastRow) {
- *refFirstRow = *refLastRow;
- *refFirstCol = *refLastCol;
- } else if (minRow > *refFirstRow)
- *refFirstRow = minRow;
-
- if (maxRow < *refFirstRow) {
- *refLastRow = *refFirstRow;
- *refLastCol = *refFirstCol;
- } else if (maxRow < *refLastRow)
- *refLastRow = maxRow;
- }
-}
-
-
-static int
-restrict_code_range_by_str(int count,unsigned short *refFirstCol,
- unsigned short *refFirstRow,
- unsigned short *refLastCol,
- unsigned short *refLastRow,
- char const *str)
-{
- int nRanges = 0;
- int result = 0;
- fsRange *ranges = NULL;
- char const *p, *q;
-
- p = q = str;
- for (;;) {
- int minpoint=0, maxpoint=65535;
- long val;
-
- /* skip comma and/or space */
- while (',' == *p || isspace(*p))
- p++;
-
- /* begin point */
- if ('-' != *p) {
- val = strtol(p, (char **)&q, 0);
- if (p == q)
- /* end or illegal */
- break;
- if (val<0 || val>65535) {
- /* out of zone */
- break;
- }
- minpoint = val;
- p=q;
- }
-
- /* skip space */
- while (isspace(*p))
- p++;
-
- if (',' != *p && '\0' != *p) {
- /* contiune */
- if ('-' == *p)
- /* hyphon */
- p++;
- else
- /* end or illegal */
- break;
-
- /* skip space */
- while (isspace(*p))
- p++;
-
- val = strtol(p, (char **)&q, 0);
- if (p != q) {
- if (val<0 || val>65535)
- break;
- maxpoint = val;
- } else if (',' != *p && '\0' != *p)
- /* end or illegal */
- break;
- p=q;
- } else
- /* comma - single code */
- maxpoint = minpoint;
-
- if ( count <= 0 && minpoint>maxpoint ) {
- int tmp;
- tmp = minpoint;
- minpoint = maxpoint;
- maxpoint = tmp;
- }
-
- /* add range */
-#if 0
- fprintf(stderr, "zone: 0x%04X - 0x%04X\n", minpoint, maxpoint);
- fflush(stderr);
-#endif
- nRanges++;
- ranges = realloc(ranges, nRanges*sizeof(*ranges));
- if (NULL == ranges)
- break;
- {
- fsRange *r = ranges+nRanges-1;
-
- r->min_char_low = minpoint & 0xff;
- r->max_char_low = maxpoint & 0xff;
- r->min_char_high = (minpoint>>8) & 0xff;
- r->max_char_high = (maxpoint>>8) & 0xff;
- }
- }
-
- if (ranges) {
- if ( count <= 0 ) {
- restrict_code_range(refFirstCol, refFirstRow, refLastCol, refLastRow,
- ranges, nRanges);
- }
- else {
- int i;
- fsRange *r;
- for ( i=0 ; i<nRanges ; i++ ) {
- if ( count <= i ) break;
- r = ranges+i;
- refFirstCol[i] = r->min_char_low;
- refLastCol[i] = r->max_char_low;
- refFirstRow[i] = r->min_char_high;
- refLastRow[i] = r->max_char_high;
- }
- result=i;
- }
- free(ranges);
- }
- return result;
-}
-
-/* *face_number and *spacing are initialized but *load_flags is NOT. */
-static int
-FreeTypeSetUpTTCap( char *fileName, FontScalablePtr vals,
- char **dynStrRealFileName, char **dynStrFTFileName,
- struct TTCapInfo *ret, int *face_number, FT_Int32 *load_flags,
- int *spacing, Bool *font_properties, char **dynStrTTCapCodeRange )
-{
- int result = Successful;
- SDynPropRecValList listPropRecVal;
- SPropRecValContainer contRecValue;
- Bool hinting=True;
- Bool isEmbeddedBitmap = True;
- Bool alwaysEmbeddedBitmap = False;
- int pixel = vals->pixel;
-
- *font_properties=True;
- *dynStrRealFileName=NULL;
- *dynStrFTFileName=NULL;
- *dynStrTTCapCodeRange=NULL;
-
- if (SPropRecValList_new(&listPropRecVal)) {
- return AllocError;
- }
-
- {
- int len = strlen(fileName);
- char *capHead = NULL;
- {
- /* font cap */
- char *p1=NULL, *p2=NULL;
-
- p1=strrchr(fileName, '/');
- if ( p1 == NULL ) p1 = fileName;
- else p1++;
- if (NULL != (p2=strrchr(p1, ':'))) {
- /* colon exist in the right side of slash. */
- int dirLen = p1-fileName;
- int baseLen = fileName+len - p2 -1;
-
- *dynStrRealFileName = malloc(dirLen+baseLen+1);
- if( *dynStrRealFileName == NULL ) {
- result = AllocError;
- goto quit;
- }
- if ( 0 < dirLen )
- memcpy(*dynStrRealFileName, fileName, dirLen);
- strcpy(*dynStrRealFileName+dirLen, p2+1);
- capHead = p1;
- } else {
- *dynStrRealFileName = xstrdup(fileName);
- if( *dynStrRealFileName == NULL ) {
- result = AllocError;
- goto quit;
- }
- }
- }
-
- /* font cap */
- if (capHead) {
- if (SPropRecValList_add_by_font_cap(&listPropRecVal,
- capHead)) {
- result = BadFontPath;
- goto quit;
- }
- }
- }
-
- *face_number=0;
- *spacing=0;
- ret->autoItalic=0.0;
- ret->scaleWidth=1.0;
- ret->scaleBBoxWidth = 1.0;
- ret->scaleBBoxHeight = 1.0;
- ret->doubleStrikeShift = 1;
- ret->adjustBBoxWidthByPixel = 0;
- ret->adjustLeftSideBearingByPixel = 0;
- ret->adjustRightSideBearingByPixel = 0;
- ret->flags = 0;
- ret->scaleBitmap = 0.0;
- ret->forceConstantSpacingBegin = -1;
- ret->forceConstantSpacingEnd = -1;
- ret->force_c_representative_metrics_char_code = -2;
- ret->force_c_scale_b_box_width = 1.0;
- ret->force_c_scale_b_box_height = 1.0;
- ret->force_c_adjust_width_by_pixel = 0;
- ret->force_c_adjust_lsb_by_pixel = 0;
- ret->force_c_adjust_rsb_by_pixel = 0;
- ret->force_c_scale_lsb = 0.0;
- ret->force_c_scale_rsb = 1.0;
- /* */
- ret->vl_slant=0;
- ret->lsbShiftOfBitmapAutoItalic=0;
- ret->rsbShiftOfBitmapAutoItalic=0;
- /* face number */
- {
- char *beginptr=NULL,*endptr;
- if ( SPropRecValList_search_record(&listPropRecVal,
- &contRecValue,
- "FaceNumber")) {
- int lv;
- beginptr = SPropContainer_value_str(contRecValue);
- lv=strtol(beginptr, &endptr, 10);
- if ( *beginptr != '\0' && *endptr == '\0' ) {
- if ( 0 < lv ) *face_number = lv;
- }
- }
- if( beginptr && 0 < *face_number ) {
- char *slash;
- *dynStrFTFileName = /* add -> ':'+strlen0+':'+strlen1+'\0' */
- malloc(1+strlen(beginptr)+1+strlen(*dynStrRealFileName)+1);
- if( *dynStrFTFileName == NULL ){
- result = AllocError;
- goto quit;
- }
- **dynStrFTFileName = '\0';
- slash = strrchr(*dynStrRealFileName,'/');
- if( slash ) {
- char *p;
- strcat(*dynStrFTFileName,*dynStrRealFileName);
- p = strrchr(*dynStrFTFileName,'/');
- p[1] = '\0';
- strcat(*dynStrFTFileName,":");
- strcat(*dynStrFTFileName,beginptr);
- strcat(*dynStrFTFileName,":");
- strcat(*dynStrFTFileName,slash+1);
- }
- else{
- strcat(*dynStrFTFileName,":");
- strcat(*dynStrFTFileName,beginptr);
- strcat(*dynStrFTFileName,":");
- strcat(*dynStrFTFileName,*dynStrRealFileName);
- }
- }
- else{
- *dynStrFTFileName = malloc(strlen(*dynStrRealFileName)+1);
- if( *dynStrFTFileName == NULL ){
- result = AllocError;
- goto quit;
- }
- **dynStrFTFileName = '\0';
- strcat(*dynStrFTFileName,*dynStrRealFileName);
- }
- }
- /*
- fprintf(stderr,"[Filename:%s]\n",fileName);
- fprintf(stderr,"[RealFilename:%s]\n",*dynStrRealFileName);
- fprintf(stderr,"[FTFilename:%s]\n",*dynStrFTFileName);
- */
- /* slant control */
- if (SPropRecValList_search_record(&listPropRecVal,
- &contRecValue,
- "AutoItalic"))
- ret->autoItalic = SPropContainer_value_dbl(contRecValue);
- /* hinting control */
- if (SPropRecValList_search_record(&listPropRecVal,
- &contRecValue,
- "Hinting"))
- hinting = SPropContainer_value_bool(contRecValue);
- /* scaling */
- if (SPropRecValList_search_record(&listPropRecVal,
- &contRecValue,
- "ScaleWidth")) {
- ret->scaleWidth = SPropContainer_value_dbl(contRecValue);
- if (ret->scaleWidth<=0.0) {
- fprintf(stderr, "ScaleWitdh needs plus.\n");
- result = BadFontName;
- goto quit;
- }
- }
- /* bbox adjustment */
- if (SPropRecValList_search_record(&listPropRecVal,
- &contRecValue,
- "ScaleBBoxWidth")) {
- /* Scaling to Bounding Box Width */
- int lv;
- char *endptr,*beginptr;
- double v,scaleBBoxWidth=1.0,scaleBBoxHeight=1.0;
- beginptr = SPropContainer_value_str(contRecValue);
- do {
- if ( strlen(beginptr) < 1 ) break;
- v=strtod(beginptr, &endptr);
- if ( endptr!=beginptr ) {
- scaleBBoxWidth = v;
- }
- if ( *endptr != ';' && *endptr != ',' ) break;
- if ( *endptr == ',' ) {
- beginptr=endptr+1;
- v=strtod(beginptr, &endptr);
- if ( endptr!=beginptr ) {
- scaleBBoxHeight = v;
- }
- }
- if ( *endptr != ';' && *endptr != ',' ) break;
- beginptr=endptr+1;
- lv=strtol(beginptr, &endptr, 10);
- if ( endptr!=beginptr ) {
- ret->adjustBBoxWidthByPixel = lv;
- }
- if ( *endptr != ',' ) break;
- beginptr=endptr+1;
- lv=strtol(beginptr, &endptr, 10);
- if ( endptr!=beginptr ) {
- ret->adjustLeftSideBearingByPixel = lv;
- }
- if ( *endptr != ',' ) break;
- beginptr=endptr+1;
- lv=strtol(beginptr, &endptr, 10);
- if ( endptr!=beginptr ) {
- ret->adjustRightSideBearingByPixel = lv;
- }
- } while ( 0 );
- if (scaleBBoxWidth<=0.0) {
- fprintf(stderr, "ScaleBBoxWitdh needs plus.\n");
- result = BadFontName;
- goto quit;
- }
- if (scaleBBoxHeight<=0.0) {
- fprintf(stderr, "ScaleBBoxHeight needs plus.\n");
- result = BadFontName;
- goto quit;
- }
- ret->scaleBBoxWidth = scaleBBoxWidth;
- ret->scaleBBoxHeight = scaleBBoxHeight;
- }
- /* spacing */
- if (SPropRecValList_search_record(&listPropRecVal,
- &contRecValue,
- "ForceSpacing")) {
- char *strSpace = SPropContainer_value_str(contRecValue);
- Bool err = False;
- if (1 != strlen(strSpace))
- err = True;
- else
- switch (strSpace[0]) {
- case 'M':
- ret->flags |= TTCAP_MONO_CENTER;
- *spacing = 'm';
- break;
- case 'm':
- case 'p':
- case 'c':
- *spacing = strSpace[0];
- break;
- default:
- err = True;
- }
- if (err) {
- result = BadFontName;
- goto quit;
- }
- }
- /* doube striking */
- if (SPropRecValList_search_record(&listPropRecVal,
- &contRecValue,
- "DoubleStrike")) {
- /* Set or Reset Auto Bold Flag */
- char *strDoubleStrike = SPropContainer_value_str(contRecValue);
- Bool err = False;
- if ( 0 < strlen(strDoubleStrike) ) {
- switch (strDoubleStrike[0]) {
- case 'm':
- case 'M':
- case 'l':
- case 'L':
- ret->flags |= TTCAP_DOUBLE_STRIKE;
- ret->flags |= TTCAP_DOUBLE_STRIKE_MKBOLD_EDGE_LEFT;
- break;
- case 'y':
- case 'Y':
- ret->flags |= TTCAP_DOUBLE_STRIKE;
- break;
- case 'n':
- case 'N':
- ret->flags &= ~TTCAP_DOUBLE_STRIKE;
- ret->flags &= ~TTCAP_DOUBLE_STRIKE_MKBOLD_EDGE_LEFT;
- ret->flags &= ~TTCAP_DOUBLE_STRIKE_CORRECT_B_BOX_WIDTH;
- break;
- default:
- err = True;
- }
- if ( err != True ) {
- if ( strDoubleStrike[1] ) {
- switch (strDoubleStrike[1]) {
- case 'b':
- case 'B':
- case 'p':
- case 'P':
- case 'y':
- case 'Y':
- ret->flags |= TTCAP_DOUBLE_STRIKE_CORRECT_B_BOX_WIDTH;
- break;
- default:
- break;
- }
- }
- do {
- char *comma_ptr=strchr(strDoubleStrike,';');
- if ( !comma_ptr ) comma_ptr=strchr(strDoubleStrike,',');
- if ( !comma_ptr ) break;
- if ( comma_ptr[1] ) {
- char *endptr;
- int mkboldMaxPixel;
- mkboldMaxPixel=strtol(comma_ptr+1, &endptr, 10);
- if ( endptr != comma_ptr+1 && mkboldMaxPixel <= pixel ) {
- ret->flags &= ~TTCAP_DOUBLE_STRIKE_MKBOLD_EDGE_LEFT;
- }
- }
- comma_ptr=strchr(comma_ptr+1,',');
- if ( !comma_ptr ) break;
- if ( comma_ptr[1] ) {
- char *endptr;
- int max_pixel;
- max_pixel=strtol(comma_ptr+1, &endptr, 10);
- if ( endptr != comma_ptr+1 && max_pixel <= pixel ) {
- if( ret->flags & TTCAP_DOUBLE_STRIKE )
- ret->doubleStrikeShift += pixel / max_pixel;
- }
- }
- } while(0);
- }
- }
- else
- err = True;
- if (err) {
- result = BadFontName;
- goto quit;
- }
- }
- /* very lazy metrics */
- if (SPropRecValList_search_record(&listPropRecVal,
- &contRecValue,
- "VeryLazyMetrics")){
- Bool isVeryLazy = SPropContainer_value_bool(contRecValue);
- ret->flags |= TTCAP_DISABLE_DEFAULT_VERY_LAZY;
- if( isVeryLazy == True )
- ret->flags |= TTCAP_IS_VERY_LAZY;
- else
- ret->flags &= ~TTCAP_IS_VERY_LAZY;
- }
- /* embedded bitmap */
- if (SPropRecValList_search_record(&listPropRecVal,
- &contRecValue,
- "EmbeddedBitmap")) {
- char *strEmbeddedBitmap = SPropContainer_value_str(contRecValue);
- Bool err = False;
- if ( 1 == strlen(strEmbeddedBitmap) ) {
- switch (strEmbeddedBitmap[0]) {
- case 'y':
- case 'Y':
- isEmbeddedBitmap = True;
- alwaysEmbeddedBitmap = True;
- break;
- case 'u':
- case 'U':
- isEmbeddedBitmap = True;
- alwaysEmbeddedBitmap = False;
- break;
- case 'n':
- case 'N':
- isEmbeddedBitmap = False;
- break;
- default:
- err = True;
- }
- }
- else
- err = True;
- if (err) {
- result = BadFontName;
- goto quit;
- }
- }
- /* scale bitmap */
- if((ret->flags & TTCAP_IS_VERY_LAZY) &&
- SPropRecValList_search_record(&listPropRecVal,
- &contRecValue,
- "VeryLazyBitmapWidthScale")) {
- /* Scaling to Bitmap Bounding Box Width */
- double scaleBitmapWidth = SPropContainer_value_dbl(contRecValue);
-
- fprintf(stderr, "Warning: `bs' option is not required in X-TT version 2.\n");
-#if 0
- if (scaleBitmapWidth<=0.0) {
- fprintf(stderr, "ScaleBitmapWitdh needs plus.\n");
- result = BadFontName;
- goto quit;
- }
-#endif
- ret->scaleBitmap = scaleBitmapWidth;
- }
- /* restriction of the code range */
- if (SPropRecValList_search_record(&listPropRecVal,
- &contRecValue,
- "CodeRange")) {
- *dynStrTTCapCodeRange = xstrdup(SPropContainer_value_str(contRecValue));
- if( *dynStrTTCapCodeRange == NULL ) {
- result = AllocError;
- goto quit;
- }
- }
- /* forceConstantSpacing{Begin,End} */
- if ( 1 /* ft->spacing == 'p' */ ){
- unsigned short first_col=0,last_col=0x00ff;
- unsigned short first_row=0,last_row=0x00ff;
- if (SPropRecValList_search_record(&listPropRecVal,
- &contRecValue,
- "ForceConstantSpacingCodeRange")) {
- if ( restrict_code_range_by_str(1,&first_col, &first_row,
- &last_col, &last_row,
- SPropContainer_value_str(contRecValue)) == 1 ) {
- ret->forceConstantSpacingBegin = (int)( first_row<<8 | first_col );
- ret->forceConstantSpacingEnd = (int)( last_row<<8 | last_col );
- if ( ret->forceConstantSpacingBegin <= ret->forceConstantSpacingEnd )
- ret->flags &= ~TTCAP_FORCE_C_OUTSIDE;
- else ret->flags |= TTCAP_FORCE_C_OUTSIDE;
- }
- }
- }
- /* */
- if ( 1 ){
- unsigned short first_col=0, last_col=0x0ff;
- unsigned short first_row=0, last_row=0x0ff;
- if ( SPropRecValList_search_record(&listPropRecVal,
- &contRecValue,
- "ForceConstantSpacingMetrics")) {
- char *strMetrics;
- strMetrics = SPropContainer_value_str(contRecValue);
- if ( strMetrics ) {
- char *comma_ptr,*period_ptr,*semic_ptr;
- semic_ptr=strchr(strMetrics,';');
- comma_ptr=strchr(strMetrics,',');
- period_ptr=strchr(strMetrics,'.');
- if ( semic_ptr && comma_ptr )
- if ( semic_ptr < comma_ptr ) comma_ptr=NULL;
- if ( semic_ptr && period_ptr )
- if ( semic_ptr < period_ptr ) period_ptr=NULL;
- if ( !comma_ptr && !period_ptr && strMetrics != semic_ptr ) {
- if ( restrict_code_range_by_str(1,&first_col, &first_row,
- &last_col, &last_row,
- SPropContainer_value_str(contRecValue)) == 1 ) {
- ret->force_c_representative_metrics_char_code =
- (int)( first_row<<8 | first_col );
- }
- }
- else {
- double v;
- char *endptr,*beginptr=strMetrics;
- do {
- v=strtod(beginptr, &endptr);
- if ( endptr!=beginptr ) {
- ret->force_c_scale_b_box_width = v;
- }
- if ( *endptr != ',' ) break;
- beginptr=endptr+1;
- v=strtod(beginptr, &endptr);
- if ( endptr!=beginptr ) {
- ret->force_c_scale_lsb = v;
- ret->flags |= TTCAP_FORCE_C_LSB_FLAG;
- }
- if ( *endptr != ',' ) break;
- beginptr=endptr+1;
- v=strtod(beginptr, &endptr);
- if ( endptr!=beginptr ) {
- ret->force_c_scale_rsb = v;
- ret->flags |= TTCAP_FORCE_C_RSB_FLAG;
- }
- if ( *endptr != ',' ) break;
- beginptr=endptr+1;
- v=strtod(beginptr, &endptr);
- if ( endptr!=beginptr ) {
- ret->force_c_scale_b_box_height = v;
- }
- } while (0);
- }
- if ( semic_ptr ) {
- int lv;
- char *endptr,*beginptr=semic_ptr+1;
- do {
- lv=strtol(beginptr, &endptr, 10);
- if ( endptr!=beginptr ) {
- ret->force_c_adjust_width_by_pixel=lv;
- }
- if ( *endptr != ',' ) break;
- beginptr=endptr+1;
- lv=strtol(beginptr, &endptr, 10);
- if ( endptr!=beginptr ) {
- ret->force_c_adjust_lsb_by_pixel=lv;
- }
- if ( *endptr != ',' ) break;
- beginptr=endptr+1;
- lv=strtol(beginptr, &endptr, 10);
- if ( endptr!=beginptr ) {
- ret->force_c_adjust_rsb_by_pixel=lv;
- }
- } while (0);
- }
- }
- }
- }
-
- if (SPropRecValList_search_record(&listPropRecVal,
- &contRecValue,
- "FontProperties")) {
- /* Set or Reset the Flag of FontProperties */
- *font_properties=SPropContainer_value_bool(contRecValue);
- }
-
- ret->force_c_scale_b_box_width *= ret->scaleBBoxWidth;
- ret->force_c_scale_b_box_height *= ret->scaleBBoxHeight;
-
- ret->force_c_scale_b_box_width *= ret->scaleWidth;
- ret->scaleBBoxWidth *= ret->scaleWidth;
-
- ret->force_c_adjust_rsb_by_pixel += ret->adjustRightSideBearingByPixel;
- ret->force_c_adjust_lsb_by_pixel += ret->adjustLeftSideBearingByPixel;
-
- /* scaleWidth, scaleBBoxWidth, force_c_scale_b_box_width, force_c_scale_b_box_width */
-
- /* by TTCap */
- if( hinting == False ) *load_flags |= FT_LOAD_NO_HINTING;
- if( isEmbeddedBitmap == False ) *load_flags |= FT_LOAD_NO_BITMAP;
- if( ret->autoItalic != 0 && alwaysEmbeddedBitmap == False )
- *load_flags |= FT_LOAD_NO_BITMAP;
-
- quit:
- return result;
-}
-
-static int
-ft_get_trans_from_vals( FontScalablePtr vals, FTNormalisedTransformationPtr trans )
-{
- /* Compute the transformation matrix. We use floating-point
- arithmetic for simplicity */
-
- trans->xres = vals->x;
- trans->yres = vals->y;
-
- /* This value cannot be 0. */
- trans->scale = hypot(vals->point_matrix[2], vals->point_matrix[3]);
- trans->nonIdentity = 0;
-
- /* Try to round stuff. We want approximate zeros to be exact zeros,
- and if the elements on the diagonal are approximately equal, we
- want them equal. We do this to avoid breaking hinting. */
- if(DIFFER(vals->point_matrix[0], vals->point_matrix[3])) {
- trans->nonIdentity = 1;
- trans->matrix.xx =
- (int)((vals->point_matrix[0]*(double)TWO_SIXTEENTH)/trans->scale);
- trans->matrix.yy =
- (int)((vals->point_matrix[3]*(double)TWO_SIXTEENTH)/trans->scale);
- } else {
- trans->matrix.xx = trans->matrix.yy =
- ((vals->point_matrix[0] + vals->point_matrix[3])/2*
- (double)TWO_SIXTEENTH)/trans->scale;
- }
-
- if(DIFFER0(vals->point_matrix[1], trans->scale)) {
- trans->matrix.yx =
- (int)((vals->point_matrix[1]*(double)TWO_SIXTEENTH)/trans->scale);
- trans->nonIdentity = 1;
- } else
- trans->matrix.yx = 0;
-
- if(DIFFER0(vals->point_matrix[2], trans->scale)) {
- trans->matrix.xy =
- (int)((vals->point_matrix[2]*(double)TWO_SIXTEENTH)/trans->scale);
- trans->nonIdentity = 1;
- } else
- trans->matrix.xy=0;
- return 0;
-}
-
-
-static int
-is_fixed_width(FT_Face face)
-{
- PS_FontInfoRec t1info_rec;
- int ftrc;
-
- if(FT_IS_FIXED_WIDTH(face)) {
- return 1;
- }
-
- ftrc = FT_Get_PS_Font_Info(face, &t1info_rec);
- if(ftrc == 0 && t1info_rec.is_fixed_pitch) {
- return 1;
- }
-
- return 0;
-}
-
-static int
-FreeTypeLoadFont(FTFontPtr font, FontInfoPtr info, FTFacePtr face,
- char *FTFileName, FontScalablePtr vals, FontEntryPtr entry,
- FontBitmapFormatPtr bmfmt, FT_Int32 load_flags,
- struct TTCapInfo *tmp_ttcap, char *dynStrTTCapCodeRange,
- int ttcap_spacing )
-{
- int xrc;
- FTNormalisedTransformationRec trans;
- int spacing, actual_spacing, zero_code;
- long lastCode, firstCode;
- TT_Postscript *post;
-
- ft_get_trans_from_vals(vals,&trans);
-
- /* Check for charcell in XLFD */
- spacing = FT_PROPORTIONAL;
- if(entry->name.ndashes == 14) {
- char *p;
- int dashes = 0;
- for(p = entry->name.name;
- p <= entry->name.name + entry->name.length - 2;
- p++) {
- if(*p == '-') {
- dashes++;
- if(dashes == 11) {
- if(p[1]=='c' && p[2]=='-')
- spacing=FT_CHARCELL;
- else if(p[1]=='m' && p[2]=='-')
- spacing=FT_MONOSPACED;
- break;
- }
- }
- }
- }
- /* by TTCap */
- if( ttcap_spacing != 0 ) {
- if( ttcap_spacing == 'c' ) spacing=FT_CHARCELL;
- else if( ttcap_spacing == 'm' ) spacing=FT_MONOSPACED;
- else spacing=FT_PROPORTIONAL;
- }
-
- actual_spacing = spacing;
- if( spacing == FT_PROPORTIONAL ) {
- if( is_fixed_width(face->face) )
- actual_spacing = FT_MONOSPACED;
- }
-
- if(entry->name.ndashes == 14) {
- xrc = FTPickMapping(entry->name.name, entry->name.length, FTFileName,
- face->face, &font->mapping);
- if (xrc != Successful)
- return xrc;
- } else {
- xrc = FTPickMapping(0, 0, FTFileName,
- face->face, &font->mapping);
- if (xrc != Successful)
- return xrc;
- }
-
- font->nranges = vals->nranges;
- font->ranges = 0;
- if(font->nranges) {
- font->ranges = malloc(vals->nranges*sizeof(fsRange));
- if(font->ranges == NULL)
- return AllocError;
- memcpy((char*)font->ranges, (char*)vals->ranges,
- vals->nranges*sizeof(fsRange));
- }
-
- zero_code=-1;
- if(info) {
- firstCode = 0;
- lastCode = 0xFFFFL;
- if(!font->mapping.mapping ||
- font->mapping.mapping->encoding->row_size == 0) {
- /* linear indexing */
- lastCode=MIN(lastCode,
- font->mapping.mapping ?
- font->mapping.mapping->encoding->size-1 :
- 0xFF);
- if(font->mapping.mapping && font->mapping.mapping->encoding->first)
- firstCode = font->mapping.mapping->encoding->first;
- info->firstRow = firstCode/0x100;
- info->lastRow = lastCode/0x100;
- info->firstCol =
- (info->firstRow || info->lastRow) ? 0 : (firstCode & 0xFF);
- info->lastCol = info->lastRow ? 0xFF : (lastCode & 0xFF);
- if ( firstCode == 0 ) zero_code=0;
- } else {
- /* matrix indexing */
- info->firstRow = font->mapping.mapping->encoding->first;
- info->lastRow = MIN(font->mapping.mapping->encoding->size-1,
- lastCode/0x100);
- info->firstCol = font->mapping.mapping->encoding->first_col;
- info->lastCol = MIN(font->mapping.mapping->encoding->row_size-1,
- lastCode<0x100?lastCode:0xFF);
- if( info->firstRow == 0 && info->firstCol == 0 ) zero_code=0;
- }
-
- /* firstCode and lastCode are not valid in case of a matrix
- encoding */
-
- if( dynStrTTCapCodeRange ) {
- restrict_code_range_by_str(0,&info->firstCol, &info->firstRow,
- &info->lastCol, &info->lastRow,
- dynStrTTCapCodeRange);
- }
- restrict_code_range(&info->firstCol, &info->firstRow,
- &info->lastCol, &info->lastRow,
- font->ranges, font->nranges);
- }
- font->info = info;
-
- /* zero code is frequently used. */
- if ( zero_code < 0 ) {
- /* The fontenc should have the information of DefaultCh.
- But we do not have such a information.
- So we cannot but set 0. */
- font->zero_idx = 0;
- }
- else
- font->zero_idx = FTRemap(face->face,
- &font->mapping, zero_code);
-
- post = FT_Get_Sfnt_Table(face->face, ft_sfnt_post);
-
-#ifdef DEFAULT_VERY_LAZY
- if( !( tmp_ttcap->flags & TTCAP_DISABLE_DEFAULT_VERY_LAZY ) )
- if( DEFAULT_VERY_LAZY <= 1 + info->lastRow - info->firstRow ) {
- if( post ){
- tmp_ttcap->flags |= TTCAP_IS_VERY_LAZY;
- }
- }
-#endif
- /* We should always reset. */
- tmp_ttcap->flags &= ~TTCAP_DISABLE_DEFAULT_VERY_LAZY;
-
- if ( face->bitmap || actual_spacing == FT_CHARCELL )
- tmp_ttcap->flags &= ~TTCAP_IS_VERY_LAZY;
- /* "vl=y" is available when TrueType or OpenType only */
- if ( !face->bitmap && !(FT_IS_SFNT( face->face )) )
- tmp_ttcap->flags &= ~TTCAP_IS_VERY_LAZY;
-
- if( post ) {
- if( post->italicAngle != 0 )
- tmp_ttcap->vl_slant = -sin( (post->italicAngle/1024./5760.)*1.57079632679489661923 );
- /* fprintf(stderr,"angle=%g(%g)\n",tmp_ttcap->vl_slant,(post->italicAngle/1024./5760.)*90); */
- }
-
- xrc = FreeTypeOpenInstance(&font->instance, face,
- FTFileName, &trans, actual_spacing, bmfmt,
- tmp_ttcap, load_flags );
- return xrc;
-}
-
-static void
-adjust_min_max(xCharInfo *minc, xCharInfo *maxc, xCharInfo *tmp)
-{
-#define MINMAX(field,ci) \
- if (minc->field > (ci)->field) \
- minc->field = (ci)->field; \
- if (maxc->field < (ci)->field) \
- maxc->field = (ci)->field;
-
- MINMAX(ascent, tmp);
- MINMAX(descent, tmp);
- MINMAX(leftSideBearing, tmp);
- MINMAX(rightSideBearing, tmp);
- MINMAX(characterWidth, tmp);
-
- if ((INT16)minc->attributes > (INT16)tmp->attributes)
- minc->attributes = tmp->attributes;
- if ((INT16)maxc->attributes < (INT16)tmp->attributes)
- maxc->attributes = tmp->attributes;
-#undef MINMAX
-}
-
-static void
-ft_compute_bounds(FTFontPtr font, FontInfoPtr pinfo, FontScalablePtr vals )
-{
- FTInstancePtr instance;
- int row, col;
- unsigned int c;
- xCharInfo minchar, maxchar, *tmpchar = NULL;
- int overlap, maxOverlap;
- long swidth = 0;
- long total_width = 0;
- int num_cols, num_chars = 0;
- int flags, skip_ok = 0;
- int force_c_outside ;
-
- instance = font->instance;
- force_c_outside = instance->ttcap.flags & TTCAP_FORCE_C_OUTSIDE;
-
- minchar.ascent = minchar.descent =
- minchar.leftSideBearing = minchar.rightSideBearing =
- minchar.characterWidth = minchar.attributes = 32767;
- maxchar.ascent = maxchar.descent =
- maxchar.leftSideBearing = maxchar.rightSideBearing =
- maxchar.characterWidth = maxchar.attributes = -32767;
- maxOverlap = -32767;
-
- /* Parse all glyphs */
- num_cols = 1 + pinfo->lastCol - pinfo->firstCol;
- for (row = pinfo->firstRow; row <= pinfo->lastRow; row++) {
- if ( skip_ok && tmpchar ) {
- if ( !force_c_outside ) {
- if ( instance->ttcap.forceConstantSpacingBegin < row<<8
- && row<<8 < (instance->ttcap.forceConstantSpacingEnd & 0x0ff00) ) {
- if (tmpchar->characterWidth) {
- num_chars += num_cols;
- swidth += ABS(tmpchar->characterWidth)*num_cols;
- total_width += tmpchar->characterWidth*num_cols;
- continue;
- }
- }
- else skip_ok=0;
- }
- else { /* for GB18030 proportional */
- if ( instance->ttcap.forceConstantSpacingBegin < row<<8
- || row<<8 < (instance->ttcap.forceConstantSpacingEnd & 0x0ff00) ) {
- if (tmpchar->characterWidth) {
- num_chars += num_cols;
- swidth += ABS(tmpchar->characterWidth)*num_cols;
- total_width += tmpchar->characterWidth*num_cols;
- continue;
- }
- }
- else skip_ok=0;
- }
- }
- for (col = pinfo->firstCol; col <= pinfo->lastCol; col++) {
- c = row<<8|col;
- flags=0;
- if ( !force_c_outside ) {
- if ( c <= instance->ttcap.forceConstantSpacingEnd
- && instance->ttcap.forceConstantSpacingBegin <= c )
- flags|=FT_FORCE_CONSTANT_SPACING;
- }
- else { /* for GB18030 proportional */
- if ( c <= instance->ttcap.forceConstantSpacingEnd
- || instance->ttcap.forceConstantSpacingBegin <= c )
- flags|=FT_FORCE_CONSTANT_SPACING;
- }
-#if 0
- fprintf(stderr, "comp_bounds: %x ->", c);
-#endif
- if ( skip_ok == 0 || flags == 0 ){
- tmpchar=NULL;
-#if 0
- fprintf(stderr, "%x\n", c);
-#endif
- if( FreeTypeFontGetGlyphMetrics(c, flags, &tmpchar, font) != Successful )
- continue;
- }
- if ( !tmpchar ) continue;
- adjust_min_max(&minchar, &maxchar, tmpchar);
- overlap = tmpchar->rightSideBearing - tmpchar->characterWidth;
- if (maxOverlap < overlap)
- maxOverlap = overlap;
-
- if (!tmpchar->characterWidth)
- continue;
- num_chars++;
- swidth += ABS(tmpchar->characterWidth);
- total_width += tmpchar->characterWidth;
-
- if ( flags & FT_FORCE_CONSTANT_SPACING ) skip_ok=1;
- }
- }
-
-#ifndef X_ACCEPTS_NO_SUCH_CHAR
- /* Check code 0 */
- if( FreeTypeInstanceGetGlyphMetrics(font->zero_idx, 0, &tmpchar, font->instance) != Successful || tmpchar == NULL)
- if( FreeTypeInstanceGetGlyphMetrics(font->zero_idx, FT_GET_DUMMY, &tmpchar, font->instance) != Successful )
- tmpchar = NULL;
- if ( tmpchar ) {
- adjust_min_max(&minchar, &maxchar, tmpchar);
- overlap = tmpchar->rightSideBearing - tmpchar->characterWidth;
- if (maxOverlap < overlap)
- maxOverlap = overlap;
- }
-#endif
-
- /* AVERAGE_WIDTH ... 1/10 pixel unit */
- if (num_chars > 0) {
- swidth = (swidth * 10.0 + num_chars / 2.0) / num_chars;
- if (total_width < 0)
- swidth = -swidth;
- vals->width = swidth;
- } else
- vals->width = 0;
-
- /*
- if (char_width.pixel) {
- maxchar.characterWidth = char_width.pixel;
- minchar.characterWidth = char_width.pixel;
- }
- */
-
- pinfo->maxbounds = maxchar;
- pinfo->minbounds = minchar;
- pinfo->ink_maxbounds = maxchar;
- pinfo->ink_minbounds = minchar;
- pinfo->maxOverlap = maxOverlap;
-}
-
-static int
-compute_new_extents( FontScalablePtr vals, double scale, double lsb, double rsb, double desc, double asc,
- int *lsb_result, int *rsb_result, int *desc_result, int *asc_result )
-{
-#define TRANSFORM_POINT(matrix, x, y, dest) \
- ((dest)[0] = (matrix)[0] * (x) + (matrix)[2] * (y), \
- (dest)[1] = (matrix)[1] * (x) + (matrix)[3] * (y))
-
-#define CHECK_EXTENT(lsb, rsb, desc, asc, data) \
- ((lsb) > (data)[0] ? (lsb) = (data)[0] : 0 , \
- (rsb) < (data)[0] ? (rsb) = (data)[0] : 0, \
- (-desc) > (data)[1] ? (desc) = -(data)[1] : 0 , \
- (asc) < (data)[1] ? (asc) = (data)[1] : 0)
- double newlsb, newrsb, newdesc, newasc;
- double point[2];
-
- /* Compute new extents for this glyph */
- TRANSFORM_POINT(vals->pixel_matrix, lsb, -desc, point);
- newlsb = point[0];
- newrsb = newlsb;
- newdesc = -point[1];
- newasc = -newdesc;
- TRANSFORM_POINT(vals->pixel_matrix, lsb, asc, point);
- CHECK_EXTENT(newlsb, newrsb, newdesc, newasc, point);
- TRANSFORM_POINT(vals->pixel_matrix, rsb, -desc, point);
- CHECK_EXTENT(newlsb, newrsb, newdesc, newasc, point);
- TRANSFORM_POINT(vals->pixel_matrix, rsb, asc, point);
- CHECK_EXTENT(newlsb, newrsb, newdesc, newasc, point);
-
- /* ???: lsb = (int)floor(newlsb * scale); */
- *lsb_result = (int)floor(newlsb * scale + 0.5);
- *rsb_result = (int)floor(newrsb * scale + 0.5);
- *desc_result = (int)ceil(newdesc * scale - 0.5);
- *asc_result = (int)floor(newasc * scale + 0.5);
-
- return 0;
-#undef CHECK_EXTENT
-#undef TRANSFORM_POINT
-}
-
-static int
-is_matrix_unit(FontScalablePtr vals)
-{
- double base_size;
- FT_Matrix m;
-
- base_size = hypot(vals->point_matrix[2], vals->point_matrix[3]);
-
- m.xx = vals->point_matrix[0] / base_size * 65536;
- m.xy = vals->point_matrix[2] / base_size * 65536;
- m.yx = vals->point_matrix[1] / base_size * 65536;
- m.yy = vals->point_matrix[3] / base_size * 65536;
-
- return (m.xx == 65536) && (m.yx == 0) &&
- (m.xy == 0) && (m.yy == 65536);
-}
-
-/* Do all the real work for OpenFont or FontInfo */
-/* xf->info is only accessed through info, and xf might be null */
-
-static int
-FreeTypeLoadXFont(char *fileName,
- FontScalablePtr vals, FontPtr xf, FontInfoPtr info,
- FontBitmapFormatPtr bmfmt, FontEntryPtr entry)
-{
- FTFontPtr font = NULL;
- FTFacePtr face = NULL;
- FTInstancePtr instance;
- FT_Size_Metrics *smetrics;
- int xrc=Successful;
- int charcell;
- long rawWidth = 0, rawAverageWidth = 0;
- int upm, minLsb, maxRsb, ascent, descent, width, averageWidth;
- double scale, base_width, base_height;
- Bool orig_is_matrix_unit, font_properties;
- int face_number, ttcap_spacing;
- struct TTCapInfo tmp_ttcap;
- struct TTCapInfo *ins_ttcap;
- FT_Int32 load_flags = FT_LOAD_DEFAULT; /* orig: FT_LOAD_RENDER | FT_LOAD_MONOCHROME */
- char *dynStrRealFileName = NULL; /* foo.ttc */
- char *dynStrFTFileName = NULL; /* :1:foo.ttc */
- char *dynStrTTCapCodeRange = NULL;
-
- font = calloc(1, sizeof(FTFontRec));
- if(font == NULL) {
- xrc = AllocError;
- goto quit;
- }
-
- xrc = FreeTypeSetUpTTCap(fileName, vals,
- &dynStrRealFileName, &dynStrFTFileName,
- &tmp_ttcap, &face_number,
- &load_flags, &ttcap_spacing,
- &font_properties, &dynStrTTCapCodeRange);
- if ( xrc != Successful ) {
- goto quit;
- }
-
- xrc = FreeTypeOpenFace(&face, dynStrFTFileName, dynStrRealFileName, face_number);
- if(xrc != Successful) {
- goto quit;
- }
-
- if( is_matrix_unit(vals) )
- orig_is_matrix_unit = True;
- else {
- orig_is_matrix_unit = False;
- /* Turn off EmbeddedBitmap when original matrix is not diagonal. */
- load_flags |= FT_LOAD_NO_BITMAP;
- }
-
- if( face->bitmap ) load_flags &= ~FT_LOAD_NO_BITMAP;
-
- /* Slant control by TTCap */
- if(!face->bitmap) {
- vals->pixel_matrix[2] +=
- vals->pixel_matrix[0] * tmp_ttcap.autoItalic;
- vals->point_matrix[2] +=
- vals->point_matrix[0] * tmp_ttcap.autoItalic;
- vals->pixel_matrix[3] +=
- vals->pixel_matrix[1] * tmp_ttcap.autoItalic;
- vals->point_matrix[3] +=
- vals->point_matrix[1] * tmp_ttcap.autoItalic;
- }
-
- base_width=hypot(vals->pixel_matrix[0], vals->pixel_matrix[1]);
- base_height=hypot(vals->pixel_matrix[2], vals->pixel_matrix[3]);
- if(MAX(base_width, base_height) < 1.0 ) {
- xrc = BadFontName;
- goto quit;
- }
-
- xrc = FreeTypeLoadFont(font, info, face, dynStrFTFileName, vals, entry, bmfmt,
- load_flags, &tmp_ttcap, dynStrTTCapCodeRange,
- ttcap_spacing );
- if(xrc != Successful) {
- goto quit;
- }
-
- instance = font->instance;
- smetrics = &instance->size->metrics;
- ins_ttcap = &instance->ttcap;
-
- upm = face->face->units_per_EM;
- if(upm == 0) {
- /* Work around FreeType bug */
- upm = WORK_AROUND_UPM;
- }
- scale = 1.0 / upm;
-
- charcell = (instance->spacing == FT_CHARCELL);
-
- if( instance->charcellMetrics == NULL ) {
-
- /* New instance */
-
- long force_c_rawWidth = 0;
- int force_c_lsb,force_c_rsb,force_c_width;
- double unit_x=0,unit_y=0,advance;
- CharInfoPtr tmpglyph;
-
- /*
- * CALCULATE HEADER'S METRICS
- */
-
- /* for OUTLINE fonts */
- if(!face->bitmap) {
- int new_width;
- double ratio,force_c_ratio;
- double width_x=0,width_y=0;
- double force_c_width_x, force_c_rsb_x, force_c_lsb_x;
- double tmp_rsb,tmp_lsb,tmp_asc,tmp_des;
- double max_advance_height;
- tmp_asc = face->face->bbox.yMax;
- tmp_des = -(face->face->bbox.yMin);
- if ( tmp_asc < face->face->ascender ) tmp_asc = face->face->ascender;
- if ( tmp_des < -(face->face->descender) ) tmp_des = -(face->face->descender);
- tmp_lsb = face->face->bbox.xMin;
- tmp_rsb = face->face->bbox.xMax;
- if ( tmp_rsb < face->face->max_advance_width ) tmp_rsb = face->face->max_advance_width;
- /* apply scaleBBoxWidth */
- /* we should not ...??? */
- tmp_lsb *= ins_ttcap->scaleBBoxWidth;
- tmp_rsb *= ins_ttcap->scaleBBoxWidth;
- /* transform and rescale */
- compute_new_extents( vals, scale, tmp_lsb, tmp_rsb, tmp_des, tmp_asc,
- &minLsb, &maxRsb, &descent, &ascent );
- /* */
- /* Consider vertical layouts */
- if( 0 < face->face->max_advance_height )
- max_advance_height = face->face->max_advance_height;
- else
- max_advance_height = tmp_asc + tmp_des;
- if( vals->pixel_matrix[1] == 0 ){
- unit_x = fabs(vals->pixel_matrix[0]);
- unit_y = 0;
- width_x = face->face->max_advance_width * ins_ttcap->scaleBBoxWidth * unit_x;
- }
- else if( vals->pixel_matrix[3] == 0 ){
- unit_y = fabs(vals->pixel_matrix[2]);
- unit_x = 0;
- width_x = max_advance_height * ins_ttcap->scaleBBoxHeight * unit_y;
- }
- else{
- unit_x = fabs(vals->pixel_matrix[0] -
- vals->pixel_matrix[1]*vals->pixel_matrix[2]/vals->pixel_matrix[3]);
- unit_y = fabs(vals->pixel_matrix[2] -
- vals->pixel_matrix[3]*vals->pixel_matrix[0]/vals->pixel_matrix[1]);
- width_x = face->face->max_advance_width * ins_ttcap->scaleBBoxWidth * unit_x;
- width_y = max_advance_height * ins_ttcap->scaleBBoxHeight * unit_y;
- if( width_y < width_x ){
- width_x = width_y;
- unit_x = 0;
- }
- else{
- unit_y = 0;
- }
- }
- /* calculate correction ratio */
- width = (int)floor( (advance = width_x * scale) + 0.5);
- new_width = width;
- if( ins_ttcap->flags & TTCAP_DOUBLE_STRIKE_CORRECT_B_BOX_WIDTH )
- new_width += ins_ttcap->doubleStrikeShift;
- new_width += ins_ttcap->adjustBBoxWidthByPixel;
- ratio = (double)new_width/width;
- width = new_width;
- /* force constant */
- if( unit_x != 0 ) {
- force_c_width_x = face->face->max_advance_width
- * ins_ttcap->force_c_scale_b_box_width * unit_x;
- force_c_lsb_x = face->face->max_advance_width
- * ins_ttcap->force_c_scale_lsb * unit_x;
- force_c_rsb_x = face->face->max_advance_width
- * ins_ttcap->force_c_scale_rsb * unit_x;
- }
- else {
- force_c_width_x = max_advance_height
- * ins_ttcap->force_c_scale_b_box_height * unit_y;
- force_c_lsb_x = max_advance_height
- * ins_ttcap->force_c_scale_lsb * unit_y;
- force_c_rsb_x = max_advance_height
- * ins_ttcap->force_c_scale_rsb * unit_y;
- }
- /* calculate correction ratio */
- force_c_width = (int)floor(force_c_width_x * scale + 0.5);
- new_width = force_c_width;
- if( ins_ttcap->flags & TTCAP_DOUBLE_STRIKE_CORRECT_B_BOX_WIDTH )
- force_c_width += ins_ttcap->doubleStrikeShift;
- new_width += ins_ttcap->force_c_adjust_width_by_pixel;
- force_c_ratio = (double)new_width/force_c_width;
- force_c_width = new_width;
- /* force_c_lsb, force_c_rsb */
- if( ins_ttcap->flags & TTCAP_FORCE_C_LSB_FLAG )
- force_c_lsb = (int)floor( force_c_lsb_x * scale + 0.5 );
- else
- force_c_lsb = minLsb;
- if( ins_ttcap->flags & TTCAP_FORCE_C_RSB_FLAG )
- force_c_rsb = (int)floor( force_c_rsb_x * scale + 0.5 );
- else
- force_c_rsb = maxRsb;
- /* calculate shift of BitmapAutoItalic
- (when diagonal matrix only) */
- if( orig_is_matrix_unit == True ) {
- if( ins_ttcap->autoItalic != 0 ) {
- double ai;
- int ai_lsb,ai_rsb,ai_total;
- if( 0 < ins_ttcap->autoItalic ) ai=ins_ttcap->autoItalic;
- else ai = -ins_ttcap->autoItalic;
- ai_total = (int)( (ascent+descent) * ai + 0.5);
- ai_rsb = (int)((double)ai_total * ascent / ( ascent + descent ) + 0.5 );
- ai_lsb = -(ai_total - ai_rsb);
- if( 0 < ins_ttcap->autoItalic ) {
- ins_ttcap->lsbShiftOfBitmapAutoItalic = ai_lsb;
- ins_ttcap->rsbShiftOfBitmapAutoItalic = ai_rsb;
- }
- else {
- ins_ttcap->lsbShiftOfBitmapAutoItalic = -ai_rsb;
- ins_ttcap->rsbShiftOfBitmapAutoItalic = -ai_lsb;
- }
- }
- }
- /* integer adjustment by TTCap */
- if( ins_ttcap->flags & TTCAP_DOUBLE_STRIKE )
- maxRsb += ins_ttcap->doubleStrikeShift;
- maxRsb += ins_ttcap->adjustRightSideBearingByPixel;
- minLsb += ins_ttcap->adjustLeftSideBearingByPixel;
- /* */
- if( ins_ttcap->flags & TTCAP_DOUBLE_STRIKE )
- force_c_rsb += ins_ttcap->doubleStrikeShift;
- force_c_rsb += ins_ttcap->force_c_adjust_rsb_by_pixel;
- force_c_lsb += ins_ttcap->force_c_adjust_lsb_by_pixel;
- /* apply to rawWidth */
- averageWidth = (int)floor(10 * width_x * scale
- * ratio + 0.5);
- rawWidth = floor(width_x * scale
- * ratio * 1000. / base_height + 0.5);
- rawAverageWidth = floor(width_x * scale * ratio * 10.
- * 1000. / base_height + 0.5);
- force_c_rawWidth = floor(force_c_width_x * scale
- * force_c_ratio * 1000. / base_height + 0.5);
- /* */
- }
- /* for BITMAP fonts [if(face->bitmap)] */
- else {
- /* These values differ from actual when outline,
- so we must use them ONLY FOR BITMAP. */
- width = (int)floor(smetrics->max_advance * ins_ttcap->scaleBBoxWidth / 64.0 + .5);
- descent = -smetrics->descender / 64;
- ascent = smetrics->ascender / 64;
- /* force constant */
- force_c_width = (int)floor(smetrics->max_advance
- * ins_ttcap->force_c_scale_b_box_width / 64.0 + .5);
- /* Preserve average width for bitmap fonts */
- if(vals->width != 0)
- averageWidth = (int)floor(vals->width * ins_ttcap->scaleBBoxWidth +.5);
- else
- averageWidth = (int)floor(10.0 * smetrics->max_advance
- * ins_ttcap->scaleBBoxWidth / 64.0 + .5);
- rawWidth = 0;
- rawAverageWidth = 0;
- force_c_rawWidth = 0;
- /* We don't consider vertical layouts */
- advance = (int)floor(smetrics->max_advance / 64.0 +.5);
- unit_x = vals->pixel_matrix[0];
- unit_y = 0;
- /* We can use 'width' only when bitmap.
- This should not be set when outline. */
- minLsb = 0;
- maxRsb = width;
- /* force constant */
- if( ins_ttcap->flags & TTCAP_FORCE_C_LSB_FLAG )
- force_c_lsb = (int)floor(smetrics->max_advance
- * ins_ttcap->force_c_scale_lsb / 64.0 + .5);
- else
- force_c_lsb = minLsb;
- if( ins_ttcap->flags & TTCAP_FORCE_C_RSB_FLAG )
- force_c_rsb = (int)floor(smetrics->max_advance
- * ins_ttcap->force_c_scale_rsb / 64.0 + .5);
- else
- force_c_rsb = maxRsb;
- /* calculate shift of BitmapAutoItalic */
- if( ins_ttcap->autoItalic != 0 ) {
- double ai;
- int ai_lsb,ai_rsb,ai_total;
- if( 0 < ins_ttcap->autoItalic ) ai=ins_ttcap->autoItalic;
- else ai = -ins_ttcap->autoItalic;
- ai_total = (int)( (ascent+descent) * ai + 0.5);
- ai_rsb = (int)((double)ai_total * ascent / ( ascent + descent ) + 0.5 );
- ai_lsb = -(ai_total - ai_rsb);
- if( 0 < ins_ttcap->autoItalic ) {
- ins_ttcap->lsbShiftOfBitmapAutoItalic = ai_lsb;
- ins_ttcap->rsbShiftOfBitmapAutoItalic = ai_rsb;
- }
- else {
- ins_ttcap->lsbShiftOfBitmapAutoItalic = -ai_rsb;
- ins_ttcap->rsbShiftOfBitmapAutoItalic = -ai_lsb;
- }
- }
- /* integer adjustment by TTCap */
- if( ins_ttcap->flags & TTCAP_DOUBLE_STRIKE_CORRECT_B_BOX_WIDTH )
- width += ins_ttcap->doubleStrikeShift;
- if( ins_ttcap->flags & TTCAP_DOUBLE_STRIKE )
- maxRsb += ins_ttcap->doubleStrikeShift;
- maxRsb += ins_ttcap->adjustRightSideBearingByPixel;
- minLsb += ins_ttcap->adjustLeftSideBearingByPixel;
- /* We have not carried out matrix calculation, so this is done. */
- maxRsb += ins_ttcap->rsbShiftOfBitmapAutoItalic;
- minLsb += ins_ttcap->lsbShiftOfBitmapAutoItalic;
- /* force constant */
- if( ins_ttcap->flags & TTCAP_DOUBLE_STRIKE )
- force_c_rsb += ins_ttcap->doubleStrikeShift;
- force_c_rsb += ins_ttcap->force_c_adjust_rsb_by_pixel;
- force_c_lsb += ins_ttcap->force_c_adjust_lsb_by_pixel;
- force_c_rsb += ins_ttcap->rsbShiftOfBitmapAutoItalic;
- force_c_lsb += ins_ttcap->lsbShiftOfBitmapAutoItalic;
- }
-
- /* SET CALCULATED VALUES TO INSTANCE */
-
- /* Set actual height and cosine */
- instance->pixel_size = base_height;
- instance->advance = advance;
- if ( unit_x != 0 ){
- instance->pixel_width_unit_x = unit_x/base_height;
- instance->pixel_width_unit_y = 0;
- }
- else{
- instance->pixel_width_unit_x = 0;
- instance->pixel_width_unit_y = unit_y/base_height;
- }
-
- /* header's metrics */
- instance->charcellMetrics = malloc(sizeof(xCharInfo));
- if(instance->charcellMetrics == NULL) {
- xrc = AllocError;
- goto quit;
- }
- instance->charcellMetrics->ascent = ascent;
- instance->charcellMetrics->descent = descent;
- instance->charcellMetrics->attributes = rawWidth;
- instance->charcellMetrics->rightSideBearing = maxRsb;
- instance->charcellMetrics->leftSideBearing = minLsb;
- instance->charcellMetrics->characterWidth = width;
- instance->averageWidth = averageWidth;
- instance->rawAverageWidth = rawAverageWidth;
-
- /* Check code 0 */
- if( FreeTypeInstanceGetGlyph(font->zero_idx, 0, &tmpglyph, font->instance) != Successful
- || tmpglyph == NULL)
- if( FreeTypeInstanceGetGlyph(font->zero_idx, FT_GET_DUMMY, &tmpglyph, font->instance)
- != Successful )
- tmpglyph = NULL;
- if ( !tmpglyph ) {
- xrc = AllocError;
- goto quit;
- }
-
- /* FORCE CONSTANT METRICS */
- if( 0 <= ins_ttcap->forceConstantSpacingEnd ) {
- xCharInfo *tmpchar = NULL;
- int c = ins_ttcap->force_c_representative_metrics_char_code;
- /* header's metrics */
- if( instance->forceConstantMetrics == NULL ){
- instance->forceConstantMetrics = malloc(sizeof(xCharInfo));
- if(instance->forceConstantMetrics == NULL) {
- xrc = AllocError;
- goto quit;
- }
- }
- /* Get Representative Metrics */
- if ( 0 <= c ) {
- if( FreeTypeFontGetGlyphMetrics(c, 0, &tmpchar, font) != Successful )
- tmpchar = NULL;
- }
- if ( tmpchar && 0 < tmpchar->characterWidth ) {
- instance->forceConstantMetrics->leftSideBearing = tmpchar->leftSideBearing;
- instance->forceConstantMetrics->rightSideBearing = tmpchar->rightSideBearing;
- instance->forceConstantMetrics->characterWidth = tmpchar->characterWidth;
- instance->forceConstantMetrics->ascent = tmpchar->ascent;
- instance->forceConstantMetrics->descent = tmpchar->descent;
- instance->forceConstantMetrics->attributes = tmpchar->attributes;
- }
- else {
- instance->forceConstantMetrics->leftSideBearing = force_c_lsb;
- instance->forceConstantMetrics->rightSideBearing = force_c_rsb;
- instance->forceConstantMetrics->characterWidth = force_c_width;
- instance->forceConstantMetrics->ascent = ascent;
- instance->forceConstantMetrics->descent = descent;
- instance->forceConstantMetrics->attributes = force_c_rawWidth;
- }
- /* Check code 0 */
- if( FreeTypeInstanceGetGlyph(font->zero_idx, FT_FORCE_CONSTANT_SPACING,
- &tmpglyph, font->instance) != Successful
- || tmpglyph == NULL)
- if( FreeTypeInstanceGetGlyph(font->zero_idx, FT_FORCE_CONSTANT_SPACING | FT_GET_DUMMY,
- &tmpglyph, font->instance)
- != Successful )
- tmpglyph = NULL;
- if ( !tmpglyph ) {
- xrc = AllocError;
- goto quit;
- }
- }
- }
- else{
-
- /*
- * CACHED VALUES
- */
-
- width = instance->charcellMetrics->characterWidth;
- ascent = instance->charcellMetrics->ascent;
- descent = instance->charcellMetrics->descent;
- rawWidth = instance->charcellMetrics->attributes;
- maxRsb = instance->charcellMetrics->rightSideBearing;
- minLsb = instance->charcellMetrics->leftSideBearing;
- averageWidth = instance->averageWidth;
- rawAverageWidth = instance->rawAverageWidth;
-
- }
-
- /*
- * SET maxbounds, minbounds ...
- */
-
- if( !charcell ) { /* NOT CHARCELL */
- if( info ){
- /*
- Calculate all glyphs' metrics.
- maxbounds.ascent and maxbounds.descent are quite important values
- for XAA. If ascent/descent of each glyph exceeds
- maxbounds.ascent/maxbounds.descent, XAA causes SERVER CRASH.
- Therefore, THIS MUST BE DONE.
- */
- ft_compute_bounds(font,info,vals);
- }
- }
- else{ /* CHARCELL */
-
- /*
- * SET CALCULATED OR CACHED VARIABLES
- */
-
- vals->width = averageWidth;
-
- if( info ){
-
- info->maxbounds.leftSideBearing = minLsb;
- info->maxbounds.rightSideBearing = maxRsb;
- info->maxbounds.characterWidth = width;
- info->maxbounds.ascent = ascent;
- info->maxbounds.descent = descent;
- info->maxbounds.attributes =
- (unsigned short)(short)rawWidth;
-
- info->minbounds = info->maxbounds;
- }
- }
-
- /* set info */
-
- if( info ){
- /*
- info->fontAscent = ascent;
- info->fontDescent = descent;
- */
- info->fontAscent = info->maxbounds.ascent;
- info->fontDescent = info->maxbounds.descent;
- /* Glyph metrics are accurate */
- info->inkMetrics=1;
-
- memcpy((char *)&info->ink_maxbounds,
- (char *)&info->maxbounds, sizeof(xCharInfo));
- memcpy((char *)&info->ink_minbounds,
- (char *)&info->minbounds, sizeof(xCharInfo));
-
- /* XXX - hack */
- info->defaultCh=0;
-
- /* Set the pInfo flags */
- /* Properties set by FontComputeInfoAccelerators:
- pInfo->noOverlap;
- pInfo->terminalFont;
- pInfo->constantMetrics;
- pInfo->constantWidth;
- pInfo->inkInside;
- */
- /* from lib/font/util/fontaccel.c */
- FontComputeInfoAccelerators(info);
- }
-
- if(xf)
- xf->fontPrivate = (void*)font;
-
- if(info) {
- xrc = FreeTypeAddProperties(font, vals, info, entry->name.name,
- rawAverageWidth, font_properties);
- if (xrc != Successful) {
- goto quit;
- }
- }
-
- quit:
- if ( dynStrTTCapCodeRange ) free(dynStrTTCapCodeRange);
- if ( dynStrFTFileName ) free(dynStrFTFileName);
- if ( dynStrRealFileName ) free(dynStrRealFileName);
- if ( xrc != Successful ) {
- if( font ){
- if( face && font->instance == NULL ) FreeTypeFreeFace(face);
- FreeTypeFreeFont(font);
- }
- }
- return xrc;
-}
-
-/* Routines used by X11 to get info and glyphs from the font. */
-
-static int
-FreeTypeGetMetrics(FontPtr pFont, unsigned long count, unsigned char *chars,
- FontEncoding charEncoding, unsigned long *metricCount,
- xCharInfo **metrics)
-{
- unsigned int code = 0;
- int flags = 0;
- FTFontPtr tf;
- struct TTCapInfo *ttcap;
- xCharInfo **mp, *m;
-
- /* MUMBLE1("Get metrics for %ld characters\n", count);*/
-
- tf = (FTFontPtr)pFont->fontPrivate;
- ttcap = &tf->instance->ttcap;
- mp = metrics;
-
- while (count-- > 0) {
- switch (charEncoding) {
- case Linear8Bit:
- case TwoD8Bit:
- code = *chars++;
- break;
- case Linear16Bit:
- case TwoD16Bit:
- code = (*chars++ << 8);
- code |= *chars++;
- /* */
- if ( !(ttcap->flags & TTCAP_FORCE_C_OUTSIDE) ) {
- if ( (int)code <= ttcap->forceConstantSpacingEnd
- && ttcap->forceConstantSpacingBegin <= (int)code )
- flags|=FT_FORCE_CONSTANT_SPACING;
- else flags=0;
- }
- else { /* for GB18030 proportional */
- if ( (int)code <= ttcap->forceConstantSpacingEnd
- || ttcap->forceConstantSpacingBegin <= (int)code )
- flags|=FT_FORCE_CONSTANT_SPACING;
- else flags=0;
- }
- break;
- }
-
- if(FreeTypeFontGetGlyphMetrics(code, flags, &m, tf) == Successful && m!=NULL) {
- *mp++ = m;
- }
-#ifdef X_ACCEPTS_NO_SUCH_CHAR
- else *mp++ = &noSuchChar.metrics;
-#endif
- }
-
- *metricCount = mp - metrics;
- return Successful;
-}
-
-static int
-FreeTypeGetGlyphs(FontPtr pFont, unsigned long count, unsigned char *chars,
- FontEncoding charEncoding, unsigned long *glyphCount,
- CharInfoPtr *glyphs)
-{
- unsigned int code = 0;
- int flags = 0;
- FTFontPtr tf;
- CharInfoPtr *gp;
- CharInfoPtr g;
- struct TTCapInfo *ttcap;
-
- tf = (FTFontPtr)pFont->fontPrivate;
- ttcap = &tf->instance->ttcap;
- gp = glyphs;
-
- while (count-- > 0) {
- switch (charEncoding) {
- case Linear8Bit: case TwoD8Bit:
- code = *chars++;
- break;
- case Linear16Bit: case TwoD16Bit:
- code = *chars++ << 8;
- code |= *chars++;
- /* */
- if ( !(ttcap->flags & TTCAP_FORCE_C_OUTSIDE) ) {
- if ( (int)code <= ttcap->forceConstantSpacingEnd
- && ttcap->forceConstantSpacingBegin <= (int)code )
- flags|=FT_FORCE_CONSTANT_SPACING;
- else flags=0;
- }
- else { /* for GB18030 proportional */
- if ( (int)code <= ttcap->forceConstantSpacingEnd
- || ttcap->forceConstantSpacingBegin <= (int)code )
- flags|=FT_FORCE_CONSTANT_SPACING;
- else flags=0;
- }
- break;
- }
-
- if(FreeTypeFontGetGlyph(code, flags, &g, tf) == Successful && g!=NULL) {
- *gp++ = g;
- }
-#ifdef X_ACCEPTS_NO_SUCH_CHAR
- else {
-#ifdef XAA_ACCEPTS_NULL_BITS
- *gp++ = &noSuchChar;
-#else
- if ( tf->dummy_char.bits ) {
- *gp++ = &tf->dummy_char;
- }
- else {
- char *raster = NULL;
- int wd_actual, ht_actual, wd, ht, bpr;
- wd_actual = tf->info->maxbounds.rightSideBearing - tf->info->maxbounds.leftSideBearing;
- ht_actual = tf->info->maxbounds.ascent + tf->info->maxbounds.descent;
- if(wd_actual <= 0) wd = 1;
- else wd=wd_actual;
- if(ht_actual <= 0) ht = 1;
- else ht=ht_actual;
- bpr = (((wd + (tf->instance->bmfmt.glyph<<3) - 1) >> 3) &
- -tf->instance->bmfmt.glyph);
- raster = calloc(1, ht * bpr);
- if(raster) {
- tf->dummy_char.bits = raster;
- *gp++ = &tf->dummy_char;
- }
- }
-#endif
- }
-#endif
- }
-
- *glyphCount = gp - glyphs;
- return Successful;
-}
-
-static int
-FreeTypeSetUpFont(FontPathElementPtr fpe, FontPtr xf, FontInfoPtr info,
- fsBitmapFormat format, fsBitmapFormatMask fmask,
- FontBitmapFormatPtr bmfmt)
-{
- int xrc;
- int image;
-
- /* Get the default bitmap format information for this X installation.
- Also update it for the client if running in the font server. */
- FontDefaultFormat(&bmfmt->bit, &bmfmt->byte, &bmfmt->glyph, &bmfmt->scan);
- if ((xrc = CheckFSFormat(format, fmask, &bmfmt->bit, &bmfmt->byte,
- &bmfmt->scan, &bmfmt->glyph,
- &image)) != Successful) {
- MUMBLE1("Aborting after checking FS format: %d\n", xrc);
- return xrc;
- }
-
- if(xf) {
- xf->refcnt = 0;
- xf->bit = bmfmt->bit;
- xf->byte = bmfmt->byte;
- xf->glyph = bmfmt->glyph;
- xf->scan = bmfmt->scan;
- xf->format = format;
- xf->get_glyphs = FreeTypeGetGlyphs;
- xf->get_metrics = FreeTypeGetMetrics;
- xf->unload_font = FreeTypeUnloadXFont;
- xf->unload_glyphs = 0;
- xf->fpe = fpe;
- xf->svrPrivate = 0;
- xf->fontPrivate = 0; /* we'll set it later */
- xf->fpePrivate = 0;
- }
-
- info->defaultCh = 0;
- info->noOverlap = 0; /* not updated */
- info->terminalFont = 0; /* not updated */
- info->constantMetrics = 0; /* we'll set it later */
- info->constantWidth = 0; /* we'll set it later */
- info->inkInside = 1;
- info->inkMetrics = 1;
- info->allExist=0; /* not updated */
- info->drawDirection = LeftToRight; /* we'll set it later */
- info->cachable = 1; /* we don't do licensing */
- info->anamorphic = 0; /* can hinting lead to anamorphic scaling? */
- info->maxOverlap = 0; /* we'll set it later. */
- info->pad = 0; /* ??? */
- return Successful;
-}
-
-/* Functions exported by the backend */
-
-static int
-FreeTypeOpenScalable(FontPathElementPtr fpe, FontPtr *ppFont, int flags,
- FontEntryPtr entry, char *fileName, FontScalablePtr vals,
- fsBitmapFormat format, fsBitmapFormatMask fmask,
- FontPtr non_cachable_font)
-{
- int xrc;
- FontPtr xf;
- FontBitmapFormatRec bmfmt;
-
- MUMBLE1("Open Scalable %s, XLFD=",fileName);
-#ifdef DEBUG_TRUETYPE
- fwrite(entry->name.name, entry->name.length, 1, stdout);
-#endif
- MUMBLE("\n");
-
- xf = CreateFontRec();
- if (xf == NULL)
- return AllocError;
-
- xrc = FreeTypeSetUpFont(fpe, xf, &xf->info, format, fmask, &bmfmt);
- if(xrc != Successful) {
- DestroyFontRec(xf);
- return xrc;
- }
- xrc = FreeTypeLoadXFont(fileName, vals, xf, &xf->info, &bmfmt, entry);
- if(xrc != Successful) {
- MUMBLE1("Error during load: %d\n",xrc);
- DestroyFontRec(xf);
- return xrc;
- }
-
- *ppFont = xf;
-
- return xrc;
-}
-
-/* Routine to get requested font info. */
-
-static int
-FreeTypeGetInfoScalable(FontPathElementPtr fpe, FontInfoPtr info,
- FontEntryPtr entry, FontNamePtr fontName,
- char *fileName, FontScalablePtr vals)
-{
- int xrc;
- FontBitmapFormatRec bmfmt;
-
- MUMBLE("Get info, XLFD= ");
-#ifdef DEBUG_TRUETYPE
- fwrite(entry->name.name, entry->name.length, 1, stdout);
-#endif
- MUMBLE("\n");
-
- xrc = FreeTypeSetUpFont(fpe, 0, info, 0, 0, &bmfmt);
- if(xrc != Successful) {
- return xrc;
- }
-
- bmfmt.glyph <<= 3;
-
- xrc = FreeTypeLoadXFont(fileName, vals, 0, info, &bmfmt, entry);
- if(xrc != Successful) {
- MUMBLE1("Error during load: %d\n", xrc);
- return xrc;
- }
-
- return Successful;
-}
-
-/* Renderer registration. */
-
-/* Set the capabilities of this renderer. */
-#define CAPABILITIES (CAP_CHARSUBSETTING | CAP_MATRIX)
-
-/* Set it up so file names with either upper or lower case can be
- loaded. We don't support compressed fonts. */
-static FontRendererRec renderers[] = {
- {".ttf", 4, 0, FreeTypeOpenScalable, 0,
- FreeTypeGetInfoScalable, 0, CAPABILITIES},
- {".ttc", 4, 0, FreeTypeOpenScalable, 0,
- FreeTypeGetInfoScalable, 0, CAPABILITIES},
- {".otf", 4, 0, FreeTypeOpenScalable, 0,
- FreeTypeGetInfoScalable, 0, CAPABILITIES},
- {".otc", 4, 0, FreeTypeOpenScalable, 0,
- FreeTypeGetInfoScalable, 0, CAPABILITIES},
- {".pfa", 4, 0, FreeTypeOpenScalable, 0,
- FreeTypeGetInfoScalable, 0, CAPABILITIES},
- {".pfb", 4, 0, FreeTypeOpenScalable, 0,
- FreeTypeGetInfoScalable, 0, CAPABILITIES},
-};
-static int num_renderers = sizeof(renderers) / sizeof(renderers[0]);
-
-static FontRendererRec alt_renderers[] = {
- {".bdf", 4, 0, FreeTypeOpenScalable, 0,
- FreeTypeGetInfoScalable, 0, CAPABILITIES},
- {".pcf", 4, 0, FreeTypeOpenScalable, 0,
- FreeTypeGetInfoScalable, 0, CAPABILITIES},
-};
-
-static int num_alt_renderers =
-sizeof(alt_renderers) / sizeof(alt_renderers[0]);
-
-
-void
-FreeTypeRegisterFontFileFunctions(void)
-{
- int i;
-
- for (i = 0; i < num_renderers; i++)
- FontFileRegisterRenderer(&renderers[i]);
-
- for (i = 0; i < num_alt_renderers; i++)
- FontFilePriorityRegisterRenderer(&alt_renderers[i], -10);
-}
+/*
+Copyright (c) 1997 by Mark Leisher
+Copyright (c) 1998-2003 by Juliusz Chroboczek
+Copyright (c) 1998 Go Watanabe, All rights reserved.
+Copyright (c) 1998 Kazushi (Jam) Marukawa, All rights reserved.
+Copyright (c) 1998 Takuya SHIOZAKI, All rights reserved.
+Copyright (c) 1998 X-TrueType Server Project, All rights reserved.
+Copyright (c) 2003-2004 After X-TT Project, All rights reserved.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include <X11/fonts/fontmisc.h>
+
+#include <string.h>
+#include <math.h>
+#include <ctype.h>
+#include <unistd.h>
+
+#include <X11/fonts/fntfilst.h>
+#include <X11/fonts/fontutil.h>
+#include <X11/fonts/FSproto.h>
+#include <ft2build.h>
+#include FT_FREETYPE_H
+#include FT_SIZES_H
+#include FT_TRUETYPE_IDS_H
+#include FT_TRUETYPE_TABLES_H
+#include FT_TYPE1_TABLES_H
+#include FT_XFREE86_H
+#include FT_BBOX_H
+#include FT_TRUETYPE_TAGS_H
+/*
+ * If you want to use FT_Outline_Get_CBox instead of
+ * FT_Outline_Get_BBox, define here.
+ */
+/* #define USE_GET_CBOX */
+#ifdef USE_GET_CBOX
+#include FT_OUTLINE_H
+#endif
+
+#include <X11/fonts/fontenc.h>
+#include "ft.h"
+#include "ftfuncs.h"
+#include "xttcap.h"
+
+/* Work around FreeType bug */
+#define WORK_AROUND_UPM 2048
+
+#ifndef True
+#define True (-1)
+#endif /* True */
+#ifndef False
+#define False (0)
+#endif /* False */
+
+#define FLOOR64(x) ((x) & -64)
+#define CEIL64(x) (((x) + 64 - 1) & -64)
+
+/*
+ * If you want very lazy method(vl=y) AS DEFAULT when
+ * handling large charset, define here.
+ */
+/* #define DEFAULT_VERY_LAZY 1 */ /* Always */
+#define DEFAULT_VERY_LAZY 2 /* Multi-byte only */
+/* #define DEFAULT_VERY_LAZY 256 */ /* Unicode only */
+
+/* Does the X accept noSuchChar? */
+#define X_ACCEPTS_NO_SUCH_CHAR
+/* Does the XAA accept NULL noSuchChar.bits?(dangerous) */
+/* #define XAA_ACCEPTS_NULL_BITS */
+
+#ifdef X_ACCEPTS_NO_SUCH_CHAR
+static CharInfoRec noSuchChar = { /* metrics */{0,0,0,0,0,0},
+ /* bits */ NULL };
+#endif
+
+/* The propery names for all the XLFD properties. */
+
+static char *xlfd_props[] = {
+ "FOUNDRY",
+ "FAMILY_NAME",
+ "WEIGHT_NAME",
+ "SLANT",
+ "SETWIDTH_NAME",
+ "ADD_STYLE_NAME",
+ "PIXEL_SIZE",
+ "POINT_SIZE",
+ "RESOLUTION_X",
+ "RESOLUTION_Y",
+ "SPACING",
+ "AVERAGE_WIDTH",
+ "CHARSET_REGISTRY",
+ "CHARSET_ENCODING",
+};
+
+
+/* read 2-byte value from a SFNT table */
+static FT_UShort
+sfnt_get_ushort( FT_Face face,
+ FT_ULong table_tag,
+ FT_ULong table_offset )
+{
+ FT_Byte buff[2];
+ FT_ULong len = sizeof(buff);
+ FT_UShort result = 0;
+
+ if ( !FT_Load_Sfnt_Table( face, table_tag, table_offset, buff, &len ) );
+ result = (FT_UShort)( (buff[0] << 8) | buff[1] );
+
+ return result;
+}
+
+#define sfnt_get_short(f,t,o) ((FT_Short)sfnt_get_ushort((f),(t),(o)))
+
+#ifdef _MSC_VER
+#define hypot _hypot
+#endif
+
+static int ftypeInitP = 0; /* is the engine initialised? */
+FT_Library ftypeLibrary;
+
+static FTFacePtr faceTable[NUMFACEBUCKETS];
+
+static unsigned
+hash(char *string)
+{
+ int i;
+ unsigned u = 0;
+ for(i = 0; string[i] != '\0'; i++)
+ u = (u<<5) + (u >> (NUMFACEBUCKETS - 5)) + (unsigned char)string[i];
+ return u;
+}
+
+static int
+ifloor(int x, int y)
+{
+ if(x >= 0)
+ return x/y;
+ else
+ return x/y - 1;
+}
+
+static int
+iceil(int x, int y)
+{
+ return ifloor(x + y - 1, y);
+}
+
+static int
+FreeTypeOpenFace(FTFacePtr *facep, char *FTFileName, char *realFileName, int faceNumber)
+{
+ FT_Error ftrc;
+ int bucket;
+ FTFacePtr face, otherFace;
+
+ if (!ftypeInitP) {
+ ftrc = FT_Init_FreeType(&ftypeLibrary);
+ if (ftrc != 0) {
+ ErrorF("FreeType: error initializing ftypeEngine: %d\n", ftrc);
+ return AllocError;
+ }
+ ftypeInitP = 1;
+ }
+
+ /* Try to find a matching face in the hashtable */
+ bucket = hash(FTFileName)%NUMFACEBUCKETS;
+ otherFace = faceTable[bucket];
+ while(otherFace) {
+ if( strcmp(otherFace->filename, FTFileName) == 0 ) break;
+ otherFace = otherFace->next;
+ }
+ if(otherFace) {
+ MUMBLE("Returning cached face: %s\n", otherFace->filename);
+ *facep = otherFace;
+ return Successful;
+ }
+
+ /* No cached match; need to make a new one */
+ face = calloc(1, sizeof(FTFaceRec));
+ if (face == NULL) {
+ return AllocError;
+ }
+
+ face->filename = strdup(FTFileName);
+ if (face->filename == NULL) {
+ free(face);
+ return AllocError;
+ }
+
+ ftrc = FT_New_Face(ftypeLibrary, realFileName, faceNumber, &face->face);
+ if(ftrc != 0) {
+ ErrorF("FreeType: couldn't open face %s: %d\n", FTFileName, ftrc);
+ free(face->filename);
+ free(face);
+ return BadFontName;
+ }
+
+ face->bitmap = ((face->face->face_flags & FT_FACE_FLAG_SCALABLE) == 0);
+ if(!face->bitmap) {
+ TT_MaxProfile *maxp;
+ maxp = FT_Get_Sfnt_Table(face->face, ft_sfnt_maxp);
+ if(maxp && maxp->maxContours == 0)
+ face->bitmap = 1;
+ }
+
+ face->num_hmetrics = (FT_UInt) sfnt_get_ushort( face->face,
+ TTAG_hhea, 34 );
+
+ /* Insert face in hashtable and return it */
+ face->next = faceTable[bucket];
+ faceTable[bucket] = face;
+ *facep = face;
+ return Successful;
+}
+
+static void
+FreeTypeFreeFace(FTFacePtr face)
+{
+ int bucket;
+ FTFacePtr otherFace;
+
+ if(!face->instances) {
+ bucket = hash(face->filename) % NUMFACEBUCKETS;
+ if(faceTable[bucket] == face)
+ faceTable[bucket] = face->next;
+ else {
+ otherFace = faceTable[bucket];
+ while(otherFace) {
+ if(otherFace->next == face)
+ break;
+ otherFace = otherFace->next;
+ }
+ if(otherFace && otherFace->next)
+ otherFace->next = otherFace->next->next;
+ else
+ ErrorF("FreeType: freeing unknown face\n");
+ }
+ MUMBLE("Closing face: %s\n", face->filename);
+ FT_Done_Face(face->face);
+ free(face->filename);
+ free(face);
+ }
+}
+
+static int
+TransEqual(FTNormalisedTransformationPtr t1, FTNormalisedTransformationPtr t2)
+{
+ if(t1->scale != t2->scale)
+ return 0;
+ else if(t1->xres != t2->xres || t1->yres != t2->yres)
+ return 0;
+ else if(t1->nonIdentity != t2->nonIdentity)
+ return 0;
+ else if(t1->nonIdentity && t2->nonIdentity) {
+ return
+ t1->matrix.xx == t2->matrix.xx &&
+ t1->matrix.yx == t2->matrix.yx &&
+ t1->matrix.yy == t2->matrix.yy &&
+ t1->matrix.xy == t2->matrix.xy;
+ } else
+ return 1;
+}
+
+static int
+BitmapFormatEqual(FontBitmapFormatPtr f1, FontBitmapFormatPtr f2)
+{
+ return
+ f1->bit == f2->bit &&
+ f1->byte == f2->byte &&
+ f1->glyph == f2->glyph;
+}
+
+static int
+TTCapEqual(struct TTCapInfo *t1, struct TTCapInfo *t2)
+{
+ return
+ t1->autoItalic == t2->autoItalic &&
+ t1->scaleWidth == t2->scaleWidth &&
+ t1->scaleBBoxWidth == t2->scaleBBoxWidth &&
+ t1->scaleBBoxHeight == t2->scaleBBoxHeight &&
+ t1->doubleStrikeShift == t2->doubleStrikeShift &&
+ t1->adjustBBoxWidthByPixel == t2->adjustBBoxWidthByPixel &&
+ t1->adjustLeftSideBearingByPixel == t2->adjustLeftSideBearingByPixel &&
+ t1->adjustRightSideBearingByPixel == t2->adjustRightSideBearingByPixel &&
+ t1->flags == t2->flags &&
+ t1->scaleBitmap == t2->scaleBitmap &&
+ /*
+ If we use forceConstantSpacing,
+ we *MUST* allocate new instance.
+ */
+ t1->forceConstantSpacingEnd < 0 &&
+ t2->forceConstantSpacingEnd < 0;
+}
+
+static int
+FTInstanceMatch(FTInstancePtr instance,
+ char *FTFileName, FTNormalisedTransformationPtr trans,
+ int spacing, FontBitmapFormatPtr bmfmt,
+ struct TTCapInfo *tmp_ttcap, FT_Int32 load_flags)
+{
+ if(strcmp(instance->face->filename, FTFileName) != 0) {
+ return 0;
+ } else if(!TransEqual(&instance->transformation, trans)) {
+ return 0;
+ } else if( spacing != instance->spacing ) {
+ return 0;
+ } else if( load_flags != instance->load_flags ) {
+ return 0;
+ } else if(!BitmapFormatEqual(&instance->bmfmt, bmfmt)) {
+ return 0;
+ } else if(!TTCapEqual(&instance->ttcap, tmp_ttcap)) {
+ return 0;
+ } else {
+ return 1;
+ }
+}
+
+static int
+FreeTypeActivateInstance(FTInstancePtr instance)
+{
+ FT_Error ftrc;
+ if(instance->face->active_instance == instance)
+ return Successful;
+
+ ftrc = FT_Activate_Size(instance->size);
+ if(ftrc != 0) {
+ instance->face->active_instance = NULL;
+ ErrorF("FreeType: couldn't activate instance: %d\n", ftrc);
+ return FTtoXReturnCode(ftrc);
+ }
+ FT_Set_Transform(instance->face->face,
+ instance->transformation.nonIdentity ?
+ &instance->transformation.matrix : 0,
+ 0);
+
+ instance->face->active_instance = instance;
+ return Successful;
+}
+
+static int
+FTFindSize(FT_Face face, FTNormalisedTransformationPtr trans,
+ int *x_return, int *y_return)
+{
+ int tx, ty, x, y;
+ int i, j;
+ int d, dd;
+
+ if(trans->nonIdentity)
+ return BadFontName;
+
+ tx = (int)(trans->scale * trans->xres / 72.0 + 0.5);
+ ty = (int)(trans->scale * trans->yres / 72.0 + 0.5);
+
+ d = 100;
+ j = -1;
+ for(i = 0; i < face->num_fixed_sizes; i++) {
+ x = face->available_sizes[i].width;
+ y = face->available_sizes[i].height;
+ if(ABS(x - tx) <= 1 && ABS(y - ty) <= 1) {
+ dd = ABS(x - tx) * ABS(x - tx) + ABS(y - ty) * ABS(y - ty);
+ if(dd < d) {
+ j = i;
+ d = dd;
+ }
+ }
+ }
+ if(j < 0)
+ return BadFontName;
+
+ *x_return = face->available_sizes[j].width;
+ *y_return = face->available_sizes[j].height;
+ return Successful;
+}
+
+static int
+FreeTypeOpenInstance(FTInstancePtr *instance_return, FTFacePtr face,
+ char *FTFileName, FTNormalisedTransformationPtr trans,
+ int spacing, FontBitmapFormatPtr bmfmt,
+ struct TTCapInfo *tmp_ttcap, FT_Int32 load_flags)
+{
+ FT_Error ftrc;
+ int xrc;
+ FTInstancePtr instance, otherInstance;
+
+ /* Search for a matching instance */
+ for(otherInstance = face->instances;
+ otherInstance;
+ otherInstance = otherInstance->next) {
+ if(FTInstanceMatch(otherInstance, FTFileName, trans, spacing, bmfmt,
+ tmp_ttcap, load_flags)) break;
+ }
+ if(otherInstance) {
+ MUMBLE("Returning cached instance\n");
+ otherInstance->refcount++;
+ *instance_return = otherInstance;
+ return Successful;
+ }
+
+ /* None matching found */
+ instance = malloc(sizeof(FTInstanceRec));
+ if(instance == NULL) {
+ return AllocError;
+ }
+
+ instance->refcount = 1;
+ instance->face = face;
+
+ instance->load_flags = load_flags;
+ instance->spacing = spacing; /* Actual spacing */
+ instance->pixel_size =0;
+ instance->pixel_width_unit_x =0;
+ instance->pixel_width_unit_y =0;
+ instance->charcellMetrics = NULL;
+ instance->averageWidth = 0;
+ instance->rawAverageWidth = 0;
+ instance->forceConstantMetrics = NULL;
+
+ instance->transformation = *trans;
+ instance->bmfmt = *bmfmt;
+ instance->glyphs = NULL;
+ instance->available = NULL;
+
+ if( 0 <= tmp_ttcap->forceConstantSpacingEnd )
+ instance->nglyphs = 2 * instance->face->face->num_glyphs;
+ else
+ instance->nglyphs = instance->face->face->num_glyphs;
+
+ /* Store the TTCap info. */
+ memcpy((char*)&instance->ttcap, (char*)tmp_ttcap,
+ sizeof(struct TTCapInfo));
+
+ ftrc = FT_New_Size(instance->face->face, &instance->size);
+ if(ftrc != 0) {
+ ErrorF("FreeType: couldn't create size object: %d\n", ftrc);
+ free(instance);
+ return FTtoXReturnCode(ftrc);
+ }
+ FreeTypeActivateInstance(instance);
+ if(!face->bitmap) {
+ ftrc = FT_Set_Char_Size(instance->face->face,
+ (int)(trans->scale*(1<<6) + 0.5),
+ (int)(trans->scale*(1<<6) + 0.5),
+ trans->xres, trans->yres);
+ } else {
+ int xsize, ysize;
+ xrc = FTFindSize(face->face, trans, &xsize, &ysize);
+ if(xrc != Successful) {
+ free(instance);
+ return xrc;
+ }
+ ftrc = FT_Set_Pixel_Sizes(instance->face->face, xsize, ysize);
+ }
+ if(ftrc != 0) {
+ FT_Done_Size(instance->size);
+ free(instance);
+ return FTtoXReturnCode(ftrc);
+ }
+
+ if( FT_IS_SFNT( face->face ) ) {
+#if 1
+ FT_F26Dot6 tt_char_width, tt_char_height, tt_dim_x, tt_dim_y;
+ FT_UInt nn;
+
+ instance->strike_index=0xFFFFU;
+
+ tt_char_width = (FT_F26Dot6)(trans->scale*(1<<6) + 0.5);
+ tt_char_height = (FT_F26Dot6)(trans->scale*(1<<6) + 0.5);
+
+ tt_dim_x = FLOOR64( ( tt_char_width * trans->xres + 36 ) / 72 + 32 );
+ tt_dim_y = FLOOR64( ( tt_char_height * trans->yres + 36 ) / 72 + 32 );
+
+ if ( tt_dim_x && !tt_dim_y )
+ tt_dim_y = tt_dim_x;
+ else if ( !tt_dim_x && tt_dim_y )
+ tt_dim_x = tt_dim_y;
+
+ for ( nn = 0; nn < face->face->num_fixed_sizes; nn++ )
+ {
+ FT_Bitmap_Size* sz = &face->face->available_sizes[nn];
+
+ if ( tt_dim_x == FLOOR64(sz->x_ppem + 32) && tt_dim_y == FLOOR64(sz->y_ppem + 32) )
+ {
+ instance->strike_index = nn;
+ break;
+ }
+ }
+#else
+ /* See Set_Char_Sizes() in ttdriver.c */
+ FT_Error err;
+ TT_Face tt_face;
+ FT_Long tt_dim_x, tt_dim_y;
+ FT_UShort tt_x_ppem, tt_y_ppem;
+ FT_F26Dot6 tt_char_width, tt_char_height;
+ SFNT_Service sfnt;
+ tt_face=(TT_Face)face->face;
+ tt_char_width = (int)(trans->scale*(1<<6) + 0.5);
+ tt_char_height = (int)(trans->scale*(1<<6) + 0.5);
+ if ( ( tt_face->header.Flags & 8 ) != 0 ) {
+ tt_dim_x = ( ( tt_char_width * trans->xres + (36+32*72) ) / 72 ) & -64;
+ tt_dim_y = ( ( tt_char_height * trans->yres + (36+32*72) ) / 72 ) & -64;
+ }
+ else{
+ tt_dim_x = ( ( tt_char_width * trans->xres + 36 ) / 72 );
+ tt_dim_y = ( ( tt_char_height * trans->yres + 36 ) / 72 );
+ }
+ tt_x_ppem = (FT_UShort)( tt_dim_x >> 6 );
+ tt_y_ppem = (FT_UShort)( tt_dim_y >> 6 );
+ /* See Reset_SBit_Size() in ttobjs.c */
+ sfnt = (SFNT_Service)tt_face->sfnt;
+ err = sfnt->set_sbit_strike(tt_face,tt_x_ppem,tt_y_ppem,&instance->strike_index);
+ if ( err ) instance->strike_index=0xFFFFU;
+#endif
+ }
+
+ /* maintain a linked list of instances */
+ instance->next = instance->face->instances;
+ instance->face->instances = instance;
+
+ *instance_return = instance;
+ return Successful;
+}
+
+static void
+FreeTypeFreeInstance(FTInstancePtr instance)
+{
+ FTInstancePtr otherInstance;
+
+ if( instance == NULL ) return;
+
+ if(instance->face->active_instance == instance)
+ instance->face->active_instance = NULL;
+ instance->refcount--;
+ if(instance->refcount <= 0) {
+ int i,j;
+
+ if(instance->face->instances == instance)
+ instance->face->instances = instance->next;
+ else {
+ for(otherInstance = instance->face->instances;
+ otherInstance;
+ otherInstance = otherInstance->next)
+ if(otherInstance->next == instance) {
+ otherInstance->next = instance->next;
+ break;
+ }
+ }
+
+ FT_Done_Size(instance->size);
+ FreeTypeFreeFace(instance->face);
+
+ if(instance->charcellMetrics) {
+ free(instance->charcellMetrics);
+ }
+ if(instance->forceConstantMetrics) {
+ free(instance->forceConstantMetrics);
+ }
+ if(instance->glyphs) {
+ for(i = 0; i < iceil(instance->nglyphs, FONTSEGMENTSIZE); i++) {
+ if(instance->glyphs[i]) {
+ for(j = 0; j < FONTSEGMENTSIZE; j++) {
+ if(instance->available[i][j] ==
+ FT_AVAILABLE_RASTERISED)
+ free(instance->glyphs[i][j].bits);
+ }
+ free(instance->glyphs[i]);
+ }
+ }
+ free(instance->glyphs);
+ }
+ if(instance->available) {
+ for(i = 0; i < iceil(instance->nglyphs, FONTSEGMENTSIZE); i++) {
+ if(instance->available[i])
+ free(instance->available[i]);
+ }
+ free(instance->available);
+ }
+ free(instance);
+ }
+}
+
+static int
+FreeTypeInstanceFindGlyph(unsigned idx_in, int flags, FTInstancePtr instance,
+ CharInfoPtr **glyphs, int ***available,
+ int *found, int *segmentP, int *offsetP)
+{
+ int segment, offset;
+ unsigned idx = idx_in;
+
+ if( 0 <= instance->ttcap.forceConstantSpacingEnd ){
+ if( (flags & FT_FORCE_CONSTANT_SPACING) )
+ idx += instance->nglyphs / 2 ;
+ }
+
+ if(idx > instance->nglyphs) {
+ *found = 0;
+ return Successful;
+ }
+
+ if(*available == NULL) {
+ *available = calloc(iceil(instance->nglyphs, FONTSEGMENTSIZE),
+ sizeof(int *));
+ if(*available == NULL)
+ return AllocError;
+ }
+
+ segment = ifloor(idx, FONTSEGMENTSIZE);
+ offset = idx - segment * FONTSEGMENTSIZE;
+
+ if((*available)[segment] == NULL) {
+ (*available)[segment] = calloc(FONTSEGMENTSIZE, sizeof(int *));
+ if((*available)[segment] == NULL)
+ return AllocError;
+ }
+
+ if(*glyphs == NULL) {
+ *glyphs = calloc(iceil(instance->nglyphs, FONTSEGMENTSIZE),
+ sizeof(CharInfoPtr));
+ if(*glyphs == NULL)
+ return AllocError;
+ }
+
+ if((*glyphs)[segment] == NULL) {
+ (*glyphs)[segment] = malloc(sizeof(CharInfoRec) * FONTSEGMENTSIZE);
+ if((*glyphs)[segment] == NULL)
+ return AllocError;
+ }
+
+ *found = 1;
+ *segmentP = segment;
+ *offsetP = offset;
+ return Successful;
+}
+
+static int
+FreeTypeInstanceGetGlyph(unsigned idx, int flags, CharInfoPtr *g, FTInstancePtr instance)
+{
+ int found, segment, offset;
+ int xrc;
+ int ***available;
+ CharInfoPtr **glyphs;
+
+ available = &instance->available;
+ glyphs = &instance->glyphs;
+
+ xrc = FreeTypeInstanceFindGlyph(idx, flags, instance, glyphs, available,
+ &found, &segment, &offset);
+ if(xrc != Successful)
+ return xrc;
+
+ if(!found || (*available)[segment][offset] == FT_AVAILABLE_NO) {
+ *g = NULL;
+ return Successful;
+ }
+
+ if((*available)[segment][offset] == FT_AVAILABLE_RASTERISED) {
+ *g = &(*glyphs)[segment][offset];
+ return Successful;
+ }
+
+ flags |= FT_GET_GLYPH_BOTH;
+
+ xrc = FreeTypeRasteriseGlyph(idx, flags,
+ &(*glyphs)[segment][offset], instance,
+ (*available)[segment][offset] >= FT_AVAILABLE_METRICS);
+ if(xrc != Successful && (*available)[segment][offset] >= FT_AVAILABLE_METRICS) {
+ ErrorF("Warning: FreeTypeRasteriseGlyph() returns an error,\n");
+ ErrorF("\tso the backend tries to set a white space.\n");
+ xrc = FreeTypeRasteriseGlyph(idx, flags | FT_GET_DUMMY,
+ &(*glyphs)[segment][offset], instance,
+ (*available)[segment][offset] >= FT_AVAILABLE_METRICS);
+ }
+ if(xrc == Successful) {
+ (*available)[segment][offset] = FT_AVAILABLE_RASTERISED;
+ /* return the glyph */
+ *g = &(*glyphs)[segment][offset];
+ }
+ return xrc;
+}
+
+static int
+FreeTypeInstanceGetGlyphMetrics(unsigned idx, int flags,
+ xCharInfo **metrics, FTInstancePtr instance )
+{
+ int xrc;
+ int found, segment, offset;
+
+ /* Char cell */
+ if(instance->spacing == FT_CHARCELL) {
+ *metrics = instance->charcellMetrics;
+ return Successful;
+ }
+ /* Force constant metrics */
+ if( flags & FT_FORCE_CONSTANT_SPACING) {
+ *metrics = instance->forceConstantMetrics;
+ return Successful;
+ }
+
+ /* Not char cell */
+
+ xrc = FreeTypeInstanceFindGlyph(idx, flags, instance,
+ &instance->glyphs, &instance->available,
+ &found, &segment, &offset);
+ if(xrc != Successful)
+ return xrc;
+ if(!found) {
+ *metrics = NULL;
+ return Successful;
+ }
+ if( instance->available[segment][offset] == FT_AVAILABLE_NO ) {
+ *metrics = NULL;
+ return Successful;
+ }
+
+ if( instance->available[segment][offset] >= FT_AVAILABLE_METRICS ) {
+ *metrics = &instance->glyphs[segment][offset].metrics;
+ return Successful;
+ }
+
+ flags |= FT_GET_GLYPH_METRICS_ONLY;
+
+ xrc = FreeTypeRasteriseGlyph(idx, flags,
+ &instance->glyphs[segment][offset],
+ instance, 0);
+ if(xrc == Successful) {
+ instance->available[segment][offset] = FT_AVAILABLE_METRICS;
+ *metrics = &instance->glyphs[segment][offset].metrics;
+ }
+ return xrc;
+}
+
+/*
+ * Pseudo enbolding similar as Microsoft Windows.
+ * It is useful but poor.
+ */
+static void
+ft_make_up_bold_bitmap( char *raster, int bpr, int ht, int ds_mode)
+{
+ int x, y;
+ unsigned char *p = (unsigned char *)raster;
+ if ( ds_mode & TTCAP_DOUBLE_STRIKE_MKBOLD_EDGE_LEFT ) {
+ for (y=0; y<ht; y++) {
+ unsigned char rev_pat=0;
+ unsigned char lsb = 0;
+ for (x=0; x<bpr; x++) {
+ unsigned char tmp = *p<<7;
+ if ( (rev_pat & 0x01) && (*p & 0x80) ) p[-1] &= 0xfe;
+ rev_pat = ~(*p);
+ *p |= (*p>>1) | lsb;
+ *p &= ~(rev_pat & (*p << 1));
+ lsb = tmp;
+ p++;
+ }
+ }
+ }
+ else {
+ for (y=0; y<ht; y++) {
+ unsigned char lsb = 0;
+ for (x=0; x<bpr; x++) {
+ unsigned char tmp = *p<<7;
+ *p |= (*p>>1) | lsb;
+ lsb = tmp;
+ p++;
+ }
+ }
+ }
+}
+
+static void
+ft_make_up_italic_bitmap( char *raster, int bpr, int ht, int shift,
+ int h_total, int h_offset, double a_italic)
+{
+ int x, y;
+ unsigned char *p = (unsigned char *)raster;
+ if ( a_italic < 0 ) shift = -shift;
+ for (y=0; y<ht; y++) {
+ unsigned char *tmp_p = p + y*bpr;
+ int tmp_shift = shift * (h_total -1 -(y+h_offset)) / h_total;
+ int tmp_byte_shift;
+ if ( 0 <= tmp_shift ) {
+ tmp_byte_shift = tmp_shift/8;
+ tmp_shift %= 8;
+ if ( tmp_shift ) {
+ for (x=bpr-1;0<=x;x--) {
+ if ( x != bpr-1 )
+ tmp_p[x+1] |= tmp_p[x]<<(8-tmp_shift);
+ tmp_p[x]>>=tmp_shift;
+ }
+ }
+ if ( tmp_byte_shift ) {
+ for (x=bpr-1;0<x;x--) {
+ tmp_p[x] = tmp_p[x-1];
+ }
+ tmp_p[x]=0;
+ }
+ }
+ else {
+ tmp_shift = -tmp_shift;
+ tmp_byte_shift = tmp_shift/8;
+ tmp_shift %= 8;
+ if ( tmp_shift ) {
+ for (x=0;x<bpr;x++) {
+ if ( x != 0 )
+ tmp_p[x-1] |= tmp_p[x]>>(8-tmp_shift);
+ tmp_p[x]<<=tmp_shift;
+ }
+ }
+ if ( tmp_byte_shift ) {
+ for (x=0;x<bpr-1;x++) {
+ tmp_p[x] = tmp_p[x+1];
+ }
+ tmp_p[x]=0;
+ }
+ }
+ }
+}
+
+/*
+ * The very lazy method,
+ * parse the htmx field in TrueType font.
+ */
+
+static void
+tt_get_metrics( FT_Face face,
+ FT_UInt idx,
+ FT_UInt num_hmetrics,
+ FT_Short* bearing,
+ FT_UShort* advance )
+{
+ /* read the metrics directly from the horizontal header, we
+ * parse the SFNT table directly through the standard FreeType API.
+ * this works with any version of the library and doesn't need to
+ * peek at its internals. Maybe a bit less
+ */
+ FT_UInt count = num_hmetrics;
+ FT_ULong length = 0;
+ FT_ULong offset = 0;
+ FT_Error error;
+
+ error = FT_Load_Sfnt_Table( face, TTAG_hmtx, 0, NULL, &length );
+
+ if ( count == 0 || error )
+ {
+ *advance = 0;
+ *bearing = 0;
+ }
+ else if ( idx < count )
+ {
+ offset = idx * 4L;
+ if ( offset + 4 > length )
+ {
+ *advance = 0;
+ *bearing = 0;
+ }
+ else
+ {
+ *advance = sfnt_get_ushort( face, TTAG_hmtx, offset );
+ *bearing = sfnt_get_short ( face, TTAG_hmtx, offset+2 );
+ }
+ }
+ else
+ {
+ offset = 4L * (count - 1);
+ if ( offset + 4 > length )
+ {
+ *advance = 0;
+ *bearing = 0;
+ }
+ else
+ {
+ *advance = sfnt_get_ushort ( face, TTAG_hmtx, offset );
+ offset += 4 + 2 * ( idx - count );
+ if ( offset + 2 > length)
+ *bearing = 0;
+ else
+ *bearing = sfnt_get_short ( face, TTAG_hmtx, offset );
+ }
+ }
+}
+
+static int
+ft_get_very_lazy_bbox( FT_UInt index,
+ FT_Face face,
+ FT_Size size,
+ FT_UInt num_hmetrics,
+ double slant,
+ FT_Matrix *matrix,
+ FT_BBox *bbox,
+ FT_Long *horiAdvance,
+ FT_Long *vertAdvance)
+{
+ if ( FT_IS_SFNT( face ) ) {
+ FT_Size_Metrics *smetrics = &size->metrics;
+ FT_Short leftBearing = 0;
+ FT_UShort advance = 0;
+ FT_Vector p0, p1, p2, p3;
+
+ /* horizontal */
+ tt_get_metrics( face, index, num_hmetrics,
+ &leftBearing, &advance );
+
+#if 0
+ fprintf(stderr,"x_scale=%f y_scale=%f\n",
+ (double)smetrics->x_scale,(double)smetrics->y_scale);
+#endif
+ bbox->xMax = *horiAdvance =
+ FT_MulFix( advance, smetrics->x_scale );
+ bbox->xMin =
+ FT_MulFix( leftBearing, smetrics->x_scale );
+ /* vertical */
+ bbox->yMin = FT_MulFix( face->bbox.yMin,
+ smetrics->y_scale );
+ bbox->yMax = FT_MulFix( face->bbox.yMax,
+ smetrics->y_scale );
+ /* slant */
+ if( 0 < slant ) {
+ bbox->xMax += slant * bbox->yMax;
+ bbox->xMin += slant * bbox->yMin;
+ }
+ else if( slant < 0 ) {
+ bbox->xMax += slant * bbox->yMin;
+ bbox->xMin += slant * bbox->yMax;
+ }
+
+ *vertAdvance = -1; /* We don't support */
+
+ p0.x = p2.x = bbox->xMin;
+ p1.x = p3.x = bbox->xMax;
+ p0.y = p1.y = bbox->yMin;
+ p2.y = p3.y = bbox->yMax;
+
+ FT_Vector_Transform(&p0, matrix);
+ FT_Vector_Transform(&p1, matrix);
+ FT_Vector_Transform(&p2, matrix);
+ FT_Vector_Transform(&p3, matrix);
+
+#if 0
+ fprintf(stderr,
+ "->(%.1f %.1f) (%.1f %.1f)"
+ " (%.1f %.1f) (%.1f %.1f)\n",
+ p0.x / 64.0, p0.y / 64.0,
+ p1.x / 64.0, p1.y / 64.0,
+ p2.x / 64.0, p2.y / 64.0,
+ p3.x / 64.0, p3.y / 64.0);
+#endif
+ bbox->xMin = MIN(p0.x, MIN(p1.x, MIN(p2.x, p3.x)));
+ bbox->xMax = MAX(p0.x, MAX(p1.x, MAX(p2.x, p3.x)));
+ bbox->yMin = MIN(p0.y, MIN(p1.y, MIN(p2.y, p3.y)));
+ bbox->yMax = MAX(p0.y, MAX(p1.y, MAX(p2.y, p3.y)));
+ return 0; /* Successful */
+ }
+ return -1;
+}
+
+static FT_Error
+FT_Do_SBit_Metrics( FT_Face ft_face, FT_Size ft_size, FT_ULong strike_index,
+ FT_UShort glyph_index, FT_Glyph_Metrics *metrics_return,
+ int *sbitchk_incomplete_but_exist )
+{
+#if 1
+ if ( strike_index != 0xFFFFU && ft_face->available_sizes != NULL )
+ {
+ FT_Error error;
+ FT_Bitmap_Size* sz = &ft_face->available_sizes[strike_index];
+
+ error = FT_Set_Pixel_Sizes( ft_face, sz->x_ppem/64, sz->y_ppem/64 );
+ if ( !error )
+ {
+ error = FT_Load_Glyph( ft_face, glyph_index, FT_LOAD_SBITS_ONLY );
+ if ( !error )
+ {
+ if ( metrics_return != NULL )
+ *metrics_return = ft_face->glyph->metrics;
+
+ return 0;
+ }
+ }
+ }
+ return -1;
+#elif (FREETYPE_VERSION >= 2001008)
+ SFNT_Service sfnt;
+ TT_Face face;
+ FT_Error error;
+ FT_Stream stream;
+ TT_SBit_Strike strike;
+ TT_SBit_Range range;
+ TT_SBit_MetricsRec elem_metrics;
+ FT_ULong ebdt_pos;
+ FT_ULong glyph_offset;
+ ;
+
+ if ( ! FT_IS_SFNT( ft_face ) )
+ {
+ error=-1;
+ goto Exit;
+ }
+
+ face = (TT_Face)ft_face;
+ sfnt = (SFNT_Service)face->sfnt;
+
+ if (strike_index != 0xFFFFU && sfnt && sfnt->find_sbit_image &&
+ sfnt->load_sbits) {
+ /* Check whether there is a glyph sbit for the current index */
+ error = sfnt->find_sbit_image( face, glyph_index, strike_index,
+ &range, &strike, &glyph_offset );
+ }
+ else error=-1;
+ if ( error ) goto Exit;
+
+ if ( metrics_return == NULL ) goto Exit;
+
+ stream = face->root.stream;
+
+ /* now, find the location of the `EBDT' table in */
+ /* the font file */
+ error = face->goto_table( face, TTAG_EBDT, stream, 0 );
+ if ( error )
+ error = face->goto_table( face, TTAG_bdat, stream, 0 );
+ if (error)
+ goto Exit;
+
+ ebdt_pos = FT_STREAM_POS();
+
+ /* place stream at beginning of glyph data and read metrics */
+ if ( FT_STREAM_SEEK( ebdt_pos + glyph_offset ) )
+ goto Exit;
+
+ error = sfnt->load_sbit_metrics( stream, range, &elem_metrics );
+ if ( error )
+ goto Exit;
+
+ metrics_return->width = (FT_Pos)elem_metrics.width << 6;
+ metrics_return->height = (FT_Pos)elem_metrics.height << 6;
+
+ metrics_return->horiBearingX = (FT_Pos)elem_metrics.horiBearingX << 6;
+ metrics_return->horiBearingY = (FT_Pos)elem_metrics.horiBearingY << 6;
+ metrics_return->horiAdvance = (FT_Pos)elem_metrics.horiAdvance << 6;
+
+ metrics_return->vertBearingX = (FT_Pos)elem_metrics.vertBearingX << 6;
+ metrics_return->vertBearingY = (FT_Pos)elem_metrics.vertBearingY << 6;
+ metrics_return->vertAdvance = (FT_Pos)elem_metrics.vertAdvance << 6;
+
+ Exit:
+ return error;
+#else /* if (FREETYPE_VERSION < 2001008) */
+ TT_Face face;
+ SFNT_Service sfnt;
+ if ( ! FT_IS_SFNT( ft_face ) ) return -1;
+ face = (TT_Face)ft_face;
+ sfnt = (SFNT_Service)face->sfnt;
+ if ( strike_index != 0xFFFFU && sfnt->load_sbits ) {
+ if ( sbitchk_incomplete_but_exist ) *sbitchk_incomplete_but_exist=1;
+ }
+ return -1;
+#endif
+}
+
+int
+FreeTypeRasteriseGlyph(unsigned idx, int flags, CharInfoPtr tgp,
+ FTInstancePtr instance, int hasMetrics)
+{
+ FTFacePtr face;
+ FT_BBox bbox;
+ FT_Long outline_hori_advance, outline_vert_advance;
+ FT_Glyph_Metrics sbit_metrics;
+ FT_Glyph_Metrics *bitmap_metrics=NULL, *metrics = NULL;
+ char *raster;
+ int wd, ht, bpr; /* width, height, bytes per row */
+ int wd_actual, ht_actual;
+ int ftrc, is_outline, correct, b_shift=0;
+ int dx, dy;
+ int leftSideBearing, rightSideBearing, characterWidth, rawCharacterWidth,
+ ascent, descent;
+ int sbitchk_incomplete_but_exist;
+ double bbox_center_raw;
+
+ face = instance->face;
+
+ FreeTypeActivateInstance(instance);
+
+ if(!tgp) return AllocError;
+
+ /*
+ * PREPARE METRICS
+ */
+
+ if(!hasMetrics) {
+ if( instance->spacing == FT_CHARCELL || flags & FT_GET_DUMMY ){
+ memcpy((char*)&tgp->metrics,
+ (char*)instance->charcellMetrics,
+ sizeof(xCharInfo));
+ }
+ else if( flags & FT_FORCE_CONSTANT_SPACING ) {
+ memcpy((char*)&tgp->metrics,
+ (char*)instance->forceConstantMetrics,
+ sizeof(xCharInfo));
+ }
+ /* mono or prop. */
+ else{
+ int new_width;
+ double ratio;
+
+ sbitchk_incomplete_but_exist=0;
+ if( ! (instance->load_flags & FT_LOAD_NO_BITMAP) ) {
+ if( FT_Do_SBit_Metrics(face->face,instance->size,instance->strike_index,
+ idx,&sbit_metrics,&sbitchk_incomplete_but_exist)==0 ) {
+ bitmap_metrics = &sbit_metrics;
+ }
+ }
+ if( bitmap_metrics == NULL ) {
+ if ( sbitchk_incomplete_but_exist==0 && (instance->ttcap.flags & TTCAP_IS_VERY_LAZY) ) {
+ if( ft_get_very_lazy_bbox( idx, face->face, instance->size,
+ face->num_hmetrics,
+ instance->ttcap.vl_slant,
+ &instance->transformation.matrix,
+ &bbox, &outline_hori_advance,
+ &outline_vert_advance ) == 0 ) {
+ goto bbox_ok; /* skip exact calculation */
+ }
+ }
+ ftrc = FT_Load_Glyph(instance->face->face, idx,
+ instance->load_flags);
+ if(ftrc != 0) return FTtoXReturnCode(ftrc);
+ metrics = &face->face->glyph->metrics;
+ if( face->face->glyph->format == FT_GLYPH_FORMAT_BITMAP ) {
+ bitmap_metrics = metrics;
+ }
+ }
+
+ if( bitmap_metrics ) {
+ FT_Pos factor;
+
+ leftSideBearing = bitmap_metrics->horiBearingX / 64;
+ rightSideBearing = (bitmap_metrics->width + bitmap_metrics->horiBearingX) / 64;
+ bbox_center_raw = (2.0 * bitmap_metrics->horiBearingX + bitmap_metrics->width)/2.0/64.0;
+ characterWidth = (int)floor(bitmap_metrics->horiAdvance
+ * instance->ttcap.scaleBBoxWidth / 64.0 + .5);
+ ascent = bitmap_metrics->horiBearingY / 64;
+ descent = (bitmap_metrics->height - bitmap_metrics->horiBearingY) / 64 ;
+ /* */
+ new_width = characterWidth;
+ if( instance->ttcap.flags & TTCAP_DOUBLE_STRIKE_CORRECT_B_BOX_WIDTH )
+ new_width += instance->ttcap.doubleStrikeShift;
+ new_width += instance->ttcap.adjustBBoxWidthByPixel;
+ ratio = (double)new_width/characterWidth;
+ characterWidth = new_width;
+ /* adjustment by pixel unit */
+ if( instance->ttcap.flags & TTCAP_DOUBLE_STRIKE )
+ rightSideBearing += instance->ttcap.doubleStrikeShift;
+ rightSideBearing += instance->ttcap.adjustRightSideBearingByPixel;
+ leftSideBearing += instance->ttcap.adjustLeftSideBearingByPixel;
+ rightSideBearing += instance->ttcap.rsbShiftOfBitmapAutoItalic;
+ leftSideBearing += instance->ttcap.lsbShiftOfBitmapAutoItalic;
+ /* */
+ factor = bitmap_metrics->horiAdvance;
+ rawCharacterWidth = (unsigned short)(short)(floor(1000 * factor
+ * instance->ttcap.scaleBBoxWidth * ratio / 64.
+ / instance->pixel_size));
+ }
+ else {
+ /* Outline */
+#ifdef USE_GET_CBOX
+ /* Very fast?? */
+ FT_Outline_Get_CBox(&face->face->glyph->outline, &bbox);
+ ftrc=0; /* FT_Outline_Get_CBox returns nothing. */
+#else
+ /* Calculate exact metrics */
+ ftrc=FT_Outline_Get_BBox(&face->face->glyph->outline, &bbox);
+#endif
+ if( ftrc != 0 ) return FTtoXReturnCode(ftrc);
+ outline_hori_advance = metrics->horiAdvance;
+ outline_vert_advance = metrics->vertAdvance;
+ bbox_ok:
+ descent = CEIL64(-bbox.yMin - 32) / 64;
+ leftSideBearing = FLOOR64(bbox.xMin + 32) / 64;
+ ascent = FLOOR64(bbox.yMax + 32) / 64;
+ rightSideBearing = FLOOR64(bbox.xMax + 32) / 64;
+ bbox_center_raw = (double)(bbox.xMax + bbox.xMin)/2.0/64.;
+ if ( instance->pixel_width_unit_x != 0 )
+ characterWidth =
+ (int)floor( outline_hori_advance
+ * instance->ttcap.scaleBBoxWidth
+ * instance->pixel_width_unit_x / 64. + .5);
+ else {
+ characterWidth =
+ (int)floor( outline_vert_advance
+ * instance->ttcap.scaleBBoxHeight
+ * instance->pixel_width_unit_y / 64. + .5);
+ if(characterWidth <= 0)
+ characterWidth = instance->charcellMetrics->characterWidth;
+ }
+ /* */
+ new_width = characterWidth;
+ if( instance->ttcap.flags & TTCAP_DOUBLE_STRIKE_CORRECT_B_BOX_WIDTH )
+ new_width += instance->ttcap.doubleStrikeShift;
+ new_width += instance->ttcap.adjustBBoxWidthByPixel;
+ ratio = (double)new_width/characterWidth;
+ characterWidth = new_width;
+ if ( instance->pixel_width_unit_x != 0 )
+ rawCharacterWidth =
+ (unsigned short)(short)(floor(1000 * outline_hori_advance
+ * instance->ttcap.scaleBBoxWidth * ratio
+ * instance->pixel_width_unit_x / 64.));
+ else {
+ rawCharacterWidth =
+ (unsigned short)(short)(floor(1000 * outline_vert_advance
+ * instance->ttcap.scaleBBoxHeight * ratio
+ * instance->pixel_width_unit_y / 64.));
+ if(rawCharacterWidth <= 0)
+ rawCharacterWidth = instance->charcellMetrics->attributes;
+ }
+ /* adjustment by pixel unit */
+ if( instance->ttcap.flags & TTCAP_DOUBLE_STRIKE )
+ rightSideBearing += instance->ttcap.doubleStrikeShift;
+ rightSideBearing += instance->ttcap.adjustRightSideBearingByPixel;
+ leftSideBearing += instance->ttcap.adjustLeftSideBearingByPixel;
+ }
+
+ /* Set the glyph metrics. */
+ tgp->metrics.attributes = (unsigned short)((short)rawCharacterWidth);
+ tgp->metrics.leftSideBearing = leftSideBearing;
+ tgp->metrics.rightSideBearing = rightSideBearing;
+ tgp->metrics.characterWidth = characterWidth;
+ tgp->metrics.ascent = ascent;
+ tgp->metrics.descent = descent;
+ /* Update the width to match the width of the font */
+ if( instance->spacing != FT_PROPORTIONAL )
+ tgp->metrics.characterWidth = instance->charcellMetrics->characterWidth;
+ if(instance->ttcap.flags & TTCAP_MONO_CENTER){
+ b_shift = (int)floor((instance->advance/2.0-bbox_center_raw) + .5);
+ tgp->metrics.leftSideBearing += b_shift;
+ tgp->metrics.rightSideBearing += b_shift;
+ }
+ }
+ }
+
+ if( flags & FT_GET_GLYPH_METRICS_ONLY ) return Successful;
+
+ /*
+ * CHECK THE NECESSITY OF BITMAP POSITION'S CORRECTION
+ */
+
+ correct=0;
+ if( instance->spacing == FT_CHARCELL ) correct=1;
+ else if( flags & FT_FORCE_CONSTANT_SPACING ) correct=1;
+ else{
+ int sbit_available=0;
+ sbitchk_incomplete_but_exist=0;
+ if( !(instance->load_flags & FT_LOAD_NO_BITMAP) ) {
+ if( FT_Do_SBit_Metrics(face->face,instance->size,
+ instance->strike_index,idx,NULL,
+ &sbitchk_incomplete_but_exist)==0 ) {
+ sbit_available=1;
+ }
+ }
+ if( sbit_available == 0 ) {
+ if ( sbitchk_incomplete_but_exist==0 && (instance->ttcap.flags & TTCAP_IS_VERY_LAZY) ) {
+ if( FT_IS_SFNT(face->face) ) correct=1;
+ }
+ }
+ }
+
+ /*
+ * RENDER AND ALLOCATE BUFFER
+ */
+
+ if( flags & FT_GET_DUMMY ) is_outline = -1;
+ else {
+ if( !metrics ) {
+ ftrc = FT_Load_Glyph(instance->face->face, idx,
+ instance->load_flags);
+ metrics = &face->face->glyph->metrics;
+
+ if(ftrc != 0) return FTtoXReturnCode(ftrc);
+ }
+
+ if( face->face->glyph->format != FT_GLYPH_FORMAT_BITMAP ) {
+#ifdef USE_GET_CBOX
+ FT_Outline_Get_CBox(&face->face->glyph->outline, &bbox);
+ ftrc = 0;
+#else
+ ftrc = FT_Outline_Get_BBox(&face->face->glyph->outline, &bbox);
+#endif
+ if( ftrc != 0 ) return FTtoXReturnCode(ftrc);
+ bbox.yMin = FLOOR64( bbox.yMin );
+ bbox.yMax = CEIL64 ( bbox.yMax );
+ ht_actual = ( bbox.yMax - bbox.yMin ) >> 6;
+ /* FreeType think a glyph with 0 height control box is invalid.
+ * So just let X to create a empty bitmap instead. */
+ if ( ht_actual == 0 )
+ is_outline = -1;
+ else
+ {
+ ftrc = FT_Render_Glyph(face->face->glyph,FT_RENDER_MODE_MONO);
+ if( ftrc != 0 ) return FTtoXReturnCode(ftrc);
+ is_outline = 1;
+ }
+ }
+ else{
+ is_outline=0;
+ }
+ }
+
+ /* Spacial case */
+ if( (instance->ttcap.flags & TTCAP_MONO_CENTER) && hasMetrics ) {
+ if( is_outline == 1 ){
+ if( correct ){
+ if( ft_get_very_lazy_bbox( idx, face->face, instance->size,
+ face->num_hmetrics,
+ instance->ttcap.vl_slant,
+ &instance->transformation.matrix,
+ &bbox, &outline_hori_advance,
+ &outline_vert_advance ) != 0 ){
+ is_outline = -1; /* <- error */
+ }
+ }
+ else {
+#ifdef USE_GET_CBOX
+ FT_Outline_Get_CBox(&face->face->glyph->outline, &bbox);
+ ftrc=0;
+#else
+ ftrc=FT_Outline_Get_BBox(&face->face->glyph->outline, &bbox);
+#endif
+ if( ftrc != 0 ) return FTtoXReturnCode(ftrc);
+ }
+ bbox_center_raw = (double)(bbox.xMax + bbox.xMin)/2.0/64.;
+ }
+ else if( is_outline == 0 )
+ bbox_center_raw = (2.0 * metrics->horiBearingX + metrics->width)/2.0/64.0;
+ else
+ bbox_center_raw = 0;
+ b_shift = (int)floor((instance->advance/2.0-bbox_center_raw) + .5);
+ }
+
+ wd_actual = tgp->metrics.rightSideBearing - tgp->metrics.leftSideBearing;
+ ht_actual = tgp->metrics.ascent + tgp->metrics.descent;
+
+ /* The X convention is to consider a character with an empty
+ * bounding box as undefined. This convention is broken. */
+
+ if(wd_actual <= 0) wd = 1;
+ else wd=wd_actual;
+ if(ht_actual <= 0) ht = 1;
+ else ht=ht_actual;
+
+ bpr = (((wd + (instance->bmfmt.glyph<<3) - 1) >> 3) &
+ -instance->bmfmt.glyph);
+ raster = calloc(1, ht * bpr);
+ if(raster == NULL)
+ return AllocError;
+
+ tgp->bits = raster;
+
+ /* If FT_GET_DUMMY is set, we return white space. */
+ if ( is_outline == -1 ) return Successful;
+
+ if ( wd_actual <= 0 || ht_actual <= 0 ) return Successful;
+
+ /*
+ * CALCULATE OFFSET, dx AND dy.
+ */
+
+ dx = face->face->glyph->bitmap_left - tgp->metrics.leftSideBearing;
+ dy = tgp->metrics.ascent - face->face->glyph->bitmap_top;
+
+ if(instance->ttcap.flags & TTCAP_MONO_CENTER)
+ dx += b_shift;
+
+ /* To prevent chipped bitmap, we correct dx and dy if needed. */
+ if( correct && is_outline==1 ){
+ int lsb, rsb, asc, des;
+ int chip_left,chip_right,chip_top,chip_bot;
+#ifdef USE_GET_CBOX
+ FT_Outline_Get_CBox(&face->face->glyph->outline, &bbox);
+ ftrc=0;
+#else
+ ftrc=FT_Outline_Get_BBox(&face->face->glyph->outline, &bbox);
+#endif
+ if( ftrc != 0 ) return FTtoXReturnCode(ftrc);
+ des = CEIL64(-bbox.yMin - 32) / 64;
+ lsb = FLOOR64(bbox.xMin + 32) / 64;
+ asc = FLOOR64(bbox.yMax + 32) / 64;
+ rsb = FLOOR64(bbox.xMax + 32) / 64;
+ rightSideBearing = tgp->metrics.rightSideBearing;
+ leftSideBearing = tgp->metrics.leftSideBearing;
+ if( instance->ttcap.flags & TTCAP_DOUBLE_STRIKE )
+ rightSideBearing -= instance->ttcap.doubleStrikeShift;
+ /* special case */
+ if(instance->ttcap.flags & TTCAP_MONO_CENTER){
+ leftSideBearing -= b_shift;
+ rightSideBearing -= b_shift;
+ }
+ chip_left = lsb - leftSideBearing;
+ chip_right = rightSideBearing - rsb;
+ if( flags & FT_FORCE_CONSTANT_SPACING ){
+ if( instance->ttcap.force_c_adjust_lsb_by_pixel != 0 ||
+ instance->ttcap.force_c_adjust_rsb_by_pixel != 0 ){
+ chip_left=0;
+ chip_right=0;
+ }
+ }
+ else{
+ if( instance->ttcap.adjustRightSideBearingByPixel != 0 ||
+ instance->ttcap.adjustLeftSideBearingByPixel != 0 ){
+ chip_left=0;
+ chip_right=0;
+ }
+ }
+ chip_top = tgp->metrics.ascent - asc;
+ chip_bot = tgp->metrics.descent - des;
+ if( chip_left < 0 && 0 < chip_right ) dx++;
+ else if( chip_right < 0 && 0 < chip_left ) dx--;
+ if( chip_top < 0 && 0 < chip_bot ) dy++;
+ else if( chip_bot < 0 && 0 < chip_top ) dy--;
+ }
+
+ /*
+ * COPY RASTER
+ */
+
+ {
+ FT_Bitmap *bitmap;
+ int i, j;
+ unsigned char *current_raster;
+ unsigned char *current_buffer;
+ int mod_dx0,mod_dx1;
+ int div_dx;
+ bitmap = &face->face->glyph->bitmap;
+ if( 0 <= dx ){
+ div_dx = dx / 8;
+ mod_dx0 = dx % 8;
+ mod_dx1 = 8-mod_dx0;
+ }
+ else{
+ div_dx = dx / 8 -1;
+ mod_dx1 = -dx % 8;
+ mod_dx0 = 8-mod_dx1;
+ }
+ for( i = MAX(0, dy) ; i<ht ; i++ ){
+ int prev_jj,jj;
+ if( bitmap->rows <= i-dy ) break;
+ current_buffer=(unsigned char *)(bitmap->buffer+bitmap->pitch*(i-dy));
+ current_raster=(unsigned char *)(raster+i*bpr);
+ j = MAX(0,div_dx);
+ jj = j-div_dx;
+ prev_jj = jj-1;
+ if( j<bpr ){
+ if( 0 <= prev_jj && prev_jj < bitmap->pitch )
+ current_raster[j]|=current_buffer[prev_jj]<<mod_dx1;
+ if( 0 <= jj && jj < bitmap->pitch ){
+ current_raster[j]|=current_buffer[jj]>>mod_dx0;
+ j++; prev_jj++; jj++;
+ for( ; j<bpr ; j++,prev_jj++,jj++ ){
+ current_raster[j]|=current_buffer[prev_jj]<<mod_dx1;
+ if( bitmap->pitch <= jj ) break;
+ current_raster[j]|=current_buffer[jj]>>mod_dx0;
+ }
+ }
+ }
+ }
+ }
+
+ /* by TTCap */
+ if ( instance->ttcap.flags & TTCAP_DOUBLE_STRIKE ) {
+ int i;
+ for( i=0 ; i < instance->ttcap.doubleStrikeShift ; i++ )
+ ft_make_up_bold_bitmap( raster, bpr, ht, instance->ttcap.flags);
+ }
+ if ( is_outline == 0 &&
+ ( instance->ttcap.lsbShiftOfBitmapAutoItalic != 0 ||
+ instance->ttcap.rsbShiftOfBitmapAutoItalic != 0 ) ) {
+ ft_make_up_italic_bitmap( raster, bpr, ht,
+ - instance->ttcap.lsbShiftOfBitmapAutoItalic
+ + instance->ttcap.rsbShiftOfBitmapAutoItalic,
+ instance->charcellMetrics->ascent
+ + instance->charcellMetrics->descent,
+ instance->charcellMetrics->ascent
+ - tgp->metrics.ascent,
+ instance->ttcap.autoItalic);
+ }
+
+ if(instance->bmfmt.bit == LSBFirst) {
+ BitOrderInvert((unsigned char*)(tgp->bits), ht*bpr);
+ }
+
+ if(instance->bmfmt.byte != instance->bmfmt.bit) {
+ switch(instance->bmfmt.scan) {
+ case 1:
+ break;
+ case 2:
+ TwoByteSwap((unsigned char*)(tgp->bits), ht*bpr);
+ break;
+ case 4:
+ FourByteSwap((unsigned char*)(tgp->bits), ht*bpr);
+ break;
+ default:
+ ;
+ }
+ }
+
+ return Successful;
+}
+
+static void
+FreeTypeFreeFont(FTFontPtr font)
+{
+ FreeTypeFreeInstance(font->instance);
+ if(font->ranges)
+ free(font->ranges);
+ if(font->dummy_char.bits)
+ free(font->dummy_char.bits);
+ free(font);
+}
+
+/* Free a font. If freeProps is 0, don't free the properties. */
+
+static void
+FreeTypeFreeXFont(FontPtr pFont, int freeProps)
+{
+ FTFontPtr tf;
+
+ if(pFont) {
+ if((tf = (FTFontPtr)pFont->fontPrivate)) {
+ FreeTypeFreeFont(tf);
+ }
+ if(freeProps && pFont->info.nprops>0) {
+ free(pFont->info.isStringProp);
+ free(pFont->info.props);
+ }
+ DestroyFontRec(pFont);
+ }
+}
+
+
+/* Unload a font */
+
+static void
+FreeTypeUnloadXFont(FontPtr pFont)
+{
+ MUMBLE("Unloading\n");
+ FreeTypeFreeXFont(pFont, 1);
+}
+
+/* Add the font properties, including the Font name, the XLFD
+ properties, some strings from the font, and various typographical
+ data. We only provide data readily available in the tables in the
+ font for now, altough FIGURE_WIDTH would be a good idea as it is
+ used by Xaw. */
+
+static int
+FreeTypeAddProperties(FTFontPtr font, FontScalablePtr vals, FontInfoPtr info,
+ char *fontname, int rawAverageWidth, Bool font_properties)
+{
+ int i, j, maxprops;
+ char *sp, *ep, val[MAXFONTNAMELEN], *vp;
+ FTFacePtr face;
+ FTInstancePtr instance;
+ FTNormalisedTransformationPtr trans;
+ int upm;
+ TT_OS2 *os2;
+ TT_Postscript *post;
+ PS_FontInfoRec t1info_rec, *t1info;
+ int xlfdProps = 0;
+ int ftrc;
+
+ instance = font->instance;
+ face = instance->face;
+ trans = &instance->transformation;
+ upm = face->face->units_per_EM;
+ if(upm == 0) {
+ /* Work around FreeType bug */
+ upm = WORK_AROUND_UPM;
+ }
+
+ os2 = FT_Get_Sfnt_Table(face->face, ft_sfnt_os2);
+ post = FT_Get_Sfnt_Table(face->face, ft_sfnt_post);
+ ftrc = FT_Get_PS_Font_Info(face->face, &t1info_rec);
+ if(ftrc == 0)
+ t1info = &t1info_rec;
+ else
+ t1info = NULL;
+
+ if(t1info) {
+ os2 = NULL;
+ post = NULL;
+ }
+
+ info->nprops = 0; /* in case we abort */
+
+ strcpy(val, fontname);
+ if(FontParseXLFDName(val, vals, FONT_XLFD_REPLACE_VALUE)) {
+ xlfdProps = 1;
+ } else {
+ MUMBLE("Couldn't parse XLFD\n");
+ xlfdProps = 0;
+ }
+
+ maxprops=
+ 1 + /* NAME */
+ (xlfdProps ? 14 : 0) + /* from XLFD */
+ 5 +
+ ( !face->bitmap ? 3 : 0 ) + /* raw_av,raw_asc,raw_dec */
+ ( font_properties ? 2 : 0 ) + /* asc,dec */
+ ( (font_properties && os2) ? 6 : 0 ) +
+ ( (font_properties && (post || t1info)) ? 3 : 0 ) +
+ 2; /* type */
+
+ info->props = malloc(maxprops * sizeof(FontPropRec));
+ if(info->props == NULL)
+ return AllocError;
+
+ info->isStringProp = malloc(maxprops);
+ if(info->isStringProp == NULL) {
+ free(info->props);
+ return AllocError;
+ }
+
+ memset((char *)info->isStringProp, 0, maxprops);
+
+ i = 0;
+
+ info->props[i].name = MakeAtom("FONT", 4, TRUE);
+ info->props[i].value = MakeAtom(val, strlen(val), TRUE);
+ info->isStringProp[i] = 1;
+ i++;
+
+ if(*val && *(sp = val + 1)) {
+ for (j = 0, sp = val + 1; j < 14; j++) {
+ if (j == 13)
+ /* Handle the case of the final field containing a subset
+ specification. */
+ for (ep = sp; *ep && *ep != '['; ep++);
+ else
+ for (ep = sp; *ep && *ep != '-'; ep++);
+
+ info->props[i].name =
+ MakeAtom(xlfd_props[j], strlen(xlfd_props[j]), TRUE);
+
+ switch(j) {
+ case 6: /* pixel size */
+ info->props[i].value =
+ (int)(fabs(vals->pixel_matrix[3]) + 0.5);
+ i++;
+ break;
+ case 7: /* point size */
+ info->props[i].value =
+ (int)(fabs(vals->point_matrix[3])*10.0 + 0.5);
+ i++;
+ break;
+ case 8: /* resolution x */
+ info->props[i].value = vals->x;
+ i++;
+ break;
+ case 9: /* resolution y */
+ info->props[i].value = vals->y;
+ i++;
+ break;
+ case 11: /* average width */
+ info->props[i].value = vals->width;
+ i++;
+ break;
+ default: /* a string */
+ info->props[i].value = MakeAtom(sp, ep - sp, TRUE);
+ info->isStringProp[i] = 1;
+ i++;
+ }
+ sp = ++ep;
+ }
+ }
+
+ info->props[i].name = MakeAtom("RAW_PIXEL_SIZE", 14, TRUE);
+ info->props[i].value = 1000;
+ i++;
+
+ info->props[i].name = MakeAtom("RAW_POINT_SIZE", 14, TRUE);
+ info->props[i].value = (long)(72270.0 / (double)vals->y + .5);
+ i++;
+
+ if(!face->bitmap) {
+ info->props[i].name = MakeAtom("RAW_AVERAGE_WIDTH", 17, TRUE);
+ info->props[i].value = rawAverageWidth;
+ i++;
+ }
+
+ if ( font_properties ) {
+ info->props[i].name = MakeAtom("FONT_ASCENT", 11, TRUE);
+ info->props[i].value = info->fontAscent;
+ i++;
+ }
+
+ if(!face->bitmap) {
+ info->props[i].name = MakeAtom("RAW_ASCENT", 10, TRUE);
+ info->props[i].value =
+ ((double)face->face->ascender/(double)upm*1000.0);
+ i++;
+ }
+
+ if ( font_properties ) {
+ info->props[i].name = MakeAtom("FONT_DESCENT", 12, TRUE);
+ info->props[i].value = info->fontDescent;
+ i++;
+ }
+
+ if(!face->bitmap) {
+ info->props[i].name = MakeAtom("RAW_DESCENT", 11, TRUE);
+ info->props[i].value =
+ -((double)face->face->descender/(double)upm*1000.0);
+ i++;
+ }
+
+ j = FTGetEnglishName(face->face, TT_NAME_ID_COPYRIGHT,
+ val, MAXFONTNAMELEN);
+ vp = val;
+ if (j < 0) {
+ if(t1info && t1info->notice) {
+ vp = t1info->notice;
+ j = strlen(vp);
+ }
+ }
+ if(j > 0) {
+ info->props[i].name = MakeAtom("COPYRIGHT", 9, TRUE);
+ info->props[i].value = MakeAtom(vp, j, TRUE);
+ info->isStringProp[i] = 1;
+ i++;
+ }
+
+ j = FTGetEnglishName(face->face, TT_NAME_ID_FULL_NAME,
+ val, MAXFONTNAMELEN);
+ vp = val;
+ if (j < 0) {
+ if(t1info && t1info->full_name) {
+ vp = t1info->full_name;
+ j = strlen(vp);
+ }
+ }
+ if(j > 0) {
+ info->props[i].name = MakeAtom("FACE_NAME", 9, TRUE);
+ info->props[i].value = MakeAtom(vp, j, TRUE);
+ info->isStringProp[i] = 1;
+ i++;
+ }
+
+ vp = (char *)FT_Get_Postscript_Name(face->face);
+ if (vp) {
+ j = strlen(vp);
+ } else {
+ j = -1;
+ }
+ if (j < 0) {
+ j = FTGetEnglishName(face->face, TT_NAME_ID_PS_NAME,
+ val, MAXFONTNAMELEN);
+ vp = val;
+ }
+ if (j < 0) {
+ if(t1info && t1info->full_name) {
+ vp = t1info->full_name;
+ j = strlen(vp);
+ }
+ }
+ if(j > 0) {
+ info->props[i].name = MakeAtom("_ADOBE_POSTSCRIPT_FONTNAME", 26, TRUE);
+ info->props[i].value = MakeAtom(vp, j, TRUE);
+ info->isStringProp[i] = 1;
+ i++;
+ }
+
+ /* These macros handle the case of a diagonal matrix. They convert
+ FUnits into pixels. */
+#define TRANSFORM_FUNITS_X(xval) \
+ ((int) \
+ floor( ((double)(xval)/(double)upm) * (double)vals->pixel_matrix[0] + 0.5 ) )
+
+#define TRANSFORM_FUNITS_Y(yval) \
+ ((int) \
+ floor( ((double)(yval)/(double)upm) * (double)vals->pixel_matrix[3] + 0.5 ) )
+
+ /* In what follows, we assume the matrix is diagonal. In the rare
+ case when it is not, the values will be somewhat wrong. */
+
+ if( font_properties && os2 ) {
+ info->props[i].name = MakeAtom("SUBSCRIPT_SIZE",14,TRUE);
+ info->props[i].value =
+ TRANSFORM_FUNITS_Y(os2->ySubscriptYSize);
+ i++;
+ info->props[i].name = MakeAtom("SUBSCRIPT_X",11,TRUE);
+ info->props[i].value =
+ TRANSFORM_FUNITS_X(os2->ySubscriptXOffset);
+ i++;
+ info->props[i].name = MakeAtom("SUBSCRIPT_Y",11,TRUE);
+ info->props[i].value =
+ TRANSFORM_FUNITS_Y(os2->ySubscriptYOffset);
+ i++;
+ info->props[i].name = MakeAtom("SUPERSCRIPT_SIZE",16,TRUE);
+ info->props[i].value =
+ TRANSFORM_FUNITS_Y(os2->ySuperscriptYSize);
+ i++;
+ info->props[i].name = MakeAtom("SUPERSCRIPT_X",13,TRUE);
+ info->props[i].value =
+ TRANSFORM_FUNITS_X(os2->ySuperscriptXOffset);
+ i++;
+ info->props[i].name = MakeAtom("SUPERSCRIPT_Y",13,TRUE);
+ info->props[i].value =
+ TRANSFORM_FUNITS_Y(os2->ySuperscriptYOffset);
+ i++;
+ }
+
+ if( font_properties && (post || t1info) ) {
+ int underlinePosition, underlineThickness;
+
+ /* Raw underlineposition counts upwards,
+ but UNDERLINE_POSITION counts downwards. */
+ if(post) {
+ underlinePosition = TRANSFORM_FUNITS_Y(-post->underlinePosition);
+ underlineThickness = TRANSFORM_FUNITS_Y(post->underlineThickness);
+ } else {
+ underlinePosition =
+ TRANSFORM_FUNITS_Y(-t1info->underline_position);
+ underlineThickness =
+ TRANSFORM_FUNITS_Y(t1info->underline_thickness);
+ }
+ if(underlineThickness <= 0)
+ underlineThickness = 1;
+
+ info->props[i].name = MakeAtom("UNDERLINE_THICKNESS",19,TRUE);
+ info->props[i].value = underlineThickness;
+ i++;
+
+ info->props[i].name = MakeAtom("UNDERLINE_POSITION",18,TRUE);
+
+ info->props[i].value = underlinePosition;
+
+ i++;
+
+ /* The italic angle is often unreliable for Type 1 fonts */
+ if(post && trans->matrix.xx == trans->matrix.yy) {
+ info->props[i].name = MakeAtom("ITALIC_ANGLE",12,TRUE);
+ info->props[i].value =
+ /* Convert from TT_Fixed to
+ 64th of a degree counterclockwise from 3 o'clock */
+ 90*64+(post->italicAngle >> 10);
+ i++;
+ }
+#undef TRANSFORM_FUNITS_X
+#undef TRANSFORM_FUNITS_Y
+ }
+
+ info->props[i].name = MakeAtom("FONT_TYPE", 9, TRUE);
+ vp = (char *)FT_Get_X11_Font_Format(face->face);
+ info->props[i].value = MakeAtom(vp, strlen(vp), TRUE);
+ info->isStringProp[i] = 1;
+ i++;
+
+ info->props[i].name = MakeAtom("RASTERIZER_NAME", 15, TRUE);
+ info->props[i].value = MakeAtom("FreeType", 10, TRUE);
+ info->isStringProp[i] = 1;
+ i++;
+
+ info->nprops = i;
+ return Successful;
+}
+
+static int
+ft_get_index(unsigned code, FTFontPtr font, unsigned *idx)
+{
+
+ /* As a special case, we pass 0 even when it is not in the ranges;
+ this will allow for the default glyph, which should exist in any
+ TrueType font. */
+
+ /* This is not required...
+ if(code > 0 && font->nranges) {
+ int i;
+ for(i = 0; i < font->nranges; i++)
+ if((code >=
+ font->ranges[i].min_char_low+
+ (font->ranges[i].min_char_high<<8)) &&
+ (code <=
+ font->ranges[i].max_char_low +
+ (font->ranges[i].max_char_high<<8)))
+ break;
+ if(i == font->nranges) {
+ *idx = font->zero_idx;
+ return -1;
+ }
+ }
+ */
+ if( font->info ) {
+ if( !( font->info->firstCol <= (code & 0x000ff) &&
+ (code & 0x000ff) <= font->info->lastCol &&
+ font->info->firstRow <= (code >> 8) &&
+ (code >> 8) <= font->info->lastRow ) ) {
+ *idx = font->zero_idx;
+ /* Error: The code has not been parsed in ft_compute_bounds()!
+ We should not return any metrics. */
+ return -1;
+ }
+ }
+
+ *idx = FTRemap(font->instance->face->face, &font->mapping, code);
+
+ return 0;
+}
+
+static int
+FreeTypeFontGetGlyph(unsigned code, int flags, CharInfoPtr *g, FTFontPtr font)
+{
+ unsigned idx = 0;
+ int xrc;
+
+#ifdef X_ACCEPTS_NO_SUCH_CHAR
+ if( ft_get_index(code,font,&idx) || idx == 0 || idx == font->zero_idx ) {
+ *g = NULL;
+ flags &= ~FT_FORCE_CONSTANT_SPACING;
+ /* if( font->instance->spacing != FT_CHARCELL ) */
+ return Successful;
+ }
+#else
+ if( ft_get_index(code,font,&idx) ) {
+ /* The code has not been parsed! */
+ *g = NULL;
+ flags &= ~FT_FORCE_CONSTANT_SPACING;
+ }
+#endif
+
+ xrc = FreeTypeInstanceGetGlyph(idx, flags, g, font->instance);
+ if( xrc == Successful && *g != NULL )
+ return Successful;
+ if( font->zero_idx != idx ) {
+ xrc = FreeTypeInstanceGetGlyph(font->zero_idx, flags, g, font->instance);
+ if( xrc == Successful && *g != NULL )
+ return Successful;
+ }
+ return FreeTypeInstanceGetGlyph(font->zero_idx, flags|FT_GET_DUMMY, g, font->instance);
+}
+
+static int
+FreeTypeFontGetGlyphMetrics(unsigned code, int flags, xCharInfo **metrics, FTFontPtr font)
+{
+ unsigned idx = 0;
+ int xrc;
+
+#ifdef X_ACCEPTS_NO_SUCH_CHAR
+ if ( ft_get_index(code,font,&idx) || idx == 0 || idx == font->zero_idx ) {
+ *metrics = NULL;
+ flags &= ~FT_FORCE_CONSTANT_SPACING;
+ /* if( font->instance->spacing != FT_CHARCELL ) */
+ return Successful;
+ }
+#else
+ if ( ft_get_index(code,font,&idx) || idx == 0 || idx == font->zero_idx ) {
+ /* The code has not been parsed! */
+ *metrics = NULL;
+ flags &= ~FT_FORCE_CONSTANT_SPACING;
+ }
+#endif
+
+ xrc = FreeTypeInstanceGetGlyphMetrics(idx, flags, metrics, font->instance);
+ if( xrc == Successful && *metrics != NULL )
+ return Successful;
+ if( font->zero_idx != idx ) {
+ xrc = FreeTypeInstanceGetGlyphMetrics(font->zero_idx, flags,
+ metrics, font->instance);
+ if( xrc == Successful && *metrics != NULL )
+ return Successful;
+ }
+ return FreeTypeInstanceGetGlyphMetrics(font->zero_idx, flags|FT_GET_DUMMY, metrics, font->instance);
+}
+
+/*
+ * restrict code range
+ *
+ * boolean for the numeric zone:
+ * results = results & (ranges[0] | ranges[1] | ... ranges[nranges-1])
+ */
+
+static void
+restrict_code_range(unsigned short *refFirstCol,
+ unsigned short *refFirstRow,
+ unsigned short *refLastCol,
+ unsigned short *refLastRow,
+ fsRange const *ranges, int nRanges)
+{
+ if (nRanges) {
+ int minCol = 256, minRow = 256, maxCol = -1, maxRow = -1;
+ fsRange const *r = ranges;
+ int i;
+
+ for (i=0; i<nRanges; i++) {
+ if (r->min_char_high != r->max_char_high) {
+ minCol = 0x00;
+ maxCol = 0xff;
+ } else {
+ if (minCol > r->min_char_low)
+ minCol = r->min_char_low;
+ if (maxCol < r->max_char_low)
+ maxCol = r->max_char_low;
+ }
+ if (minRow > r->min_char_high)
+ minRow = r->min_char_high;
+ if (maxRow < r->max_char_high)
+ maxRow = r->max_char_high;
+ r++;
+ }
+
+ if (minCol > *refLastCol)
+ *refFirstCol = *refLastCol;
+ else if (minCol > *refFirstCol)
+ *refFirstCol = minCol;
+
+ if (maxCol < *refFirstCol)
+ *refLastCol = *refFirstCol;
+ else if (maxCol < *refLastCol)
+ *refLastCol = maxCol;
+
+ if (minRow > *refLastRow) {
+ *refFirstRow = *refLastRow;
+ *refFirstCol = *refLastCol;
+ } else if (minRow > *refFirstRow)
+ *refFirstRow = minRow;
+
+ if (maxRow < *refFirstRow) {
+ *refLastRow = *refFirstRow;
+ *refLastCol = *refFirstCol;
+ } else if (maxRow < *refLastRow)
+ *refLastRow = maxRow;
+ }
+}
+
+
+static int
+restrict_code_range_by_str(int count,unsigned short *refFirstCol,
+ unsigned short *refFirstRow,
+ unsigned short *refLastCol,
+ unsigned short *refLastRow,
+ char const *str)
+{
+ int nRanges = 0;
+ int result = 0;
+ fsRange *ranges = NULL;
+ char const *p, *q;
+
+ p = q = str;
+ for (;;) {
+ int minpoint=0, maxpoint=65535;
+ long val;
+
+ /* skip comma and/or space */
+ while (',' == *p || isspace(*p))
+ p++;
+
+ /* begin point */
+ if ('-' != *p) {
+ val = strtol(p, (char **)&q, 0);
+ if (p == q)
+ /* end or illegal */
+ break;
+ if (val<0 || val>65535) {
+ /* out of zone */
+ break;
+ }
+ minpoint = val;
+ p=q;
+ }
+
+ /* skip space */
+ while (isspace(*p))
+ p++;
+
+ if (',' != *p && '\0' != *p) {
+ /* contiune */
+ if ('-' == *p)
+ /* hyphon */
+ p++;
+ else
+ /* end or illegal */
+ break;
+
+ /* skip space */
+ while (isspace(*p))
+ p++;
+
+ val = strtol(p, (char **)&q, 0);
+ if (p != q) {
+ if (val<0 || val>65535)
+ break;
+ maxpoint = val;
+ } else if (',' != *p && '\0' != *p)
+ /* end or illegal */
+ break;
+ p=q;
+ } else
+ /* comma - single code */
+ maxpoint = minpoint;
+
+ if ( count <= 0 && minpoint>maxpoint ) {
+ int tmp;
+ tmp = minpoint;
+ minpoint = maxpoint;
+ maxpoint = tmp;
+ }
+
+ /* add range */
+#if 0
+ fprintf(stderr, "zone: 0x%04X - 0x%04X\n", minpoint, maxpoint);
+ fflush(stderr);
+#endif
+ nRanges++;
+ ranges = realloc(ranges, nRanges*sizeof(*ranges));
+ if (NULL == ranges)
+ break;
+ {
+ fsRange *r = ranges+nRanges-1;
+
+ r->min_char_low = minpoint & 0xff;
+ r->max_char_low = maxpoint & 0xff;
+ r->min_char_high = (minpoint>>8) & 0xff;
+ r->max_char_high = (maxpoint>>8) & 0xff;
+ }
+ }
+
+ if (ranges) {
+ if ( count <= 0 ) {
+ restrict_code_range(refFirstCol, refFirstRow, refLastCol, refLastRow,
+ ranges, nRanges);
+ }
+ else {
+ int i;
+ fsRange *r;
+ for ( i=0 ; i<nRanges ; i++ ) {
+ if ( count <= i ) break;
+ r = ranges+i;
+ refFirstCol[i] = r->min_char_low;
+ refLastCol[i] = r->max_char_low;
+ refFirstRow[i] = r->min_char_high;
+ refLastRow[i] = r->max_char_high;
+ }
+ result=i;
+ }
+ free(ranges);
+ }
+ return result;
+}
+
+/* *face_number and *spacing are initialized but *load_flags is NOT. */
+static int
+FreeTypeSetUpTTCap( char *fileName, FontScalablePtr vals,
+ char **dynStrRealFileName, char **dynStrFTFileName,
+ struct TTCapInfo *ret, int *face_number, FT_Int32 *load_flags,
+ int *spacing, Bool *font_properties, char **dynStrTTCapCodeRange )
+{
+ int result = Successful;
+ SDynPropRecValList listPropRecVal;
+ SPropRecValContainer contRecValue;
+ Bool hinting=True;
+ Bool isEmbeddedBitmap = True;
+ Bool alwaysEmbeddedBitmap = False;
+ int pixel = vals->pixel;
+
+ *font_properties=True;
+ *dynStrRealFileName=NULL;
+ *dynStrFTFileName=NULL;
+ *dynStrTTCapCodeRange=NULL;
+
+ if (SPropRecValList_new(&listPropRecVal)) {
+ return AllocError;
+ }
+
+ {
+ int len = strlen(fileName);
+ char *capHead = NULL;
+ {
+ /* font cap */
+ char *p1=NULL, *p2=NULL;
+
+ p1=strrchr(fileName, '/');
+ if ( p1 == NULL ) p1 = fileName;
+ else p1++;
+ if (NULL != (p2=strrchr(p1, ':'))) {
+ /* colon exist in the right side of slash. */
+ int dirLen = p1-fileName;
+ int baseLen = fileName+len - p2 -1;
+
+ *dynStrRealFileName = malloc(dirLen+baseLen+1);
+ if( *dynStrRealFileName == NULL ) {
+ result = AllocError;
+ goto quit;
+ }
+ if ( 0 < dirLen )
+ memcpy(*dynStrRealFileName, fileName, dirLen);
+ strcpy(*dynStrRealFileName+dirLen, p2+1);
+ capHead = p1;
+ } else {
+ *dynStrRealFileName = xstrdup(fileName);
+ if( *dynStrRealFileName == NULL ) {
+ result = AllocError;
+ goto quit;
+ }
+ }
+ }
+
+ /* font cap */
+ if (capHead) {
+ if (SPropRecValList_add_by_font_cap(&listPropRecVal,
+ capHead)) {
+ result = BadFontPath;
+ goto quit;
+ }
+ }
+ }
+
+ *face_number=0;
+ *spacing=0;
+ ret->autoItalic=0.0;
+ ret->scaleWidth=1.0;
+ ret->scaleBBoxWidth = 1.0;
+ ret->scaleBBoxHeight = 1.0;
+ ret->doubleStrikeShift = 1;
+ ret->adjustBBoxWidthByPixel = 0;
+ ret->adjustLeftSideBearingByPixel = 0;
+ ret->adjustRightSideBearingByPixel = 0;
+ ret->flags = 0;
+ ret->scaleBitmap = 0.0;
+ ret->forceConstantSpacingBegin = -1;
+ ret->forceConstantSpacingEnd = -1;
+ ret->force_c_representative_metrics_char_code = -2;
+ ret->force_c_scale_b_box_width = 1.0;
+ ret->force_c_scale_b_box_height = 1.0;
+ ret->force_c_adjust_width_by_pixel = 0;
+ ret->force_c_adjust_lsb_by_pixel = 0;
+ ret->force_c_adjust_rsb_by_pixel = 0;
+ ret->force_c_scale_lsb = 0.0;
+ ret->force_c_scale_rsb = 1.0;
+ /* */
+ ret->vl_slant=0;
+ ret->lsbShiftOfBitmapAutoItalic=0;
+ ret->rsbShiftOfBitmapAutoItalic=0;
+ /* face number */
+ {
+ char *beginptr=NULL,*endptr;
+ if ( SPropRecValList_search_record(&listPropRecVal,
+ &contRecValue,
+ "FaceNumber")) {
+ int lv;
+ beginptr = SPropContainer_value_str(contRecValue);
+ lv=strtol(beginptr, &endptr, 10);
+ if ( *beginptr != '\0' && *endptr == '\0' ) {
+ if ( 0 < lv ) *face_number = lv;
+ }
+ }
+ if( beginptr && 0 < *face_number ) {
+ char *slash;
+ *dynStrFTFileName = /* add -> ':'+strlen0+':'+strlen1+'\0' */
+ malloc(1+strlen(beginptr)+1+strlen(*dynStrRealFileName)+1);
+ if( *dynStrFTFileName == NULL ){
+ result = AllocError;
+ goto quit;
+ }
+ **dynStrFTFileName = '\0';
+ slash = strrchr(*dynStrRealFileName,'/');
+ if( slash ) {
+ char *p;
+ strcat(*dynStrFTFileName,*dynStrRealFileName);
+ p = strrchr(*dynStrFTFileName,'/');
+ p[1] = '\0';
+ strcat(*dynStrFTFileName,":");
+ strcat(*dynStrFTFileName,beginptr);
+ strcat(*dynStrFTFileName,":");
+ strcat(*dynStrFTFileName,slash+1);
+ }
+ else{
+ strcat(*dynStrFTFileName,":");
+ strcat(*dynStrFTFileName,beginptr);
+ strcat(*dynStrFTFileName,":");
+ strcat(*dynStrFTFileName,*dynStrRealFileName);
+ }
+ }
+ else{
+ *dynStrFTFileName = malloc(strlen(*dynStrRealFileName)+1);
+ if( *dynStrFTFileName == NULL ){
+ result = AllocError;
+ goto quit;
+ }
+ **dynStrFTFileName = '\0';
+ strcat(*dynStrFTFileName,*dynStrRealFileName);
+ }
+ }
+ /*
+ fprintf(stderr,"[Filename:%s]\n",fileName);
+ fprintf(stderr,"[RealFilename:%s]\n",*dynStrRealFileName);
+ fprintf(stderr,"[FTFilename:%s]\n",*dynStrFTFileName);
+ */
+ /* slant control */
+ if (SPropRecValList_search_record(&listPropRecVal,
+ &contRecValue,
+ "AutoItalic"))
+ ret->autoItalic = SPropContainer_value_dbl(contRecValue);
+ /* hinting control */
+ if (SPropRecValList_search_record(&listPropRecVal,
+ &contRecValue,
+ "Hinting"))
+ hinting = SPropContainer_value_bool(contRecValue);
+ /* scaling */
+ if (SPropRecValList_search_record(&listPropRecVal,
+ &contRecValue,
+ "ScaleWidth")) {
+ ret->scaleWidth = SPropContainer_value_dbl(contRecValue);
+ if (ret->scaleWidth<=0.0) {
+ fprintf(stderr, "ScaleWitdh needs plus.\n");
+ result = BadFontName;
+ goto quit;
+ }
+ }
+ /* bbox adjustment */
+ if (SPropRecValList_search_record(&listPropRecVal,
+ &contRecValue,
+ "ScaleBBoxWidth")) {
+ /* Scaling to Bounding Box Width */
+ int lv;
+ char *endptr,*beginptr;
+ double v,scaleBBoxWidth=1.0,scaleBBoxHeight=1.0;
+ beginptr = SPropContainer_value_str(contRecValue);
+ do {
+ if ( strlen(beginptr) < 1 ) break;
+ v=strtod(beginptr, &endptr);
+ if ( endptr!=beginptr ) {
+ scaleBBoxWidth = v;
+ }
+ if ( *endptr != ';' && *endptr != ',' ) break;
+ if ( *endptr == ',' ) {
+ beginptr=endptr+1;
+ v=strtod(beginptr, &endptr);
+ if ( endptr!=beginptr ) {
+ scaleBBoxHeight = v;
+ }
+ }
+ if ( *endptr != ';' && *endptr != ',' ) break;
+ beginptr=endptr+1;
+ lv=strtol(beginptr, &endptr, 10);
+ if ( endptr!=beginptr ) {
+ ret->adjustBBoxWidthByPixel = lv;
+ }
+ if ( *endptr != ',' ) break;
+ beginptr=endptr+1;
+ lv=strtol(beginptr, &endptr, 10);
+ if ( endptr!=beginptr ) {
+ ret->adjustLeftSideBearingByPixel = lv;
+ }
+ if ( *endptr != ',' ) break;
+ beginptr=endptr+1;
+ lv=strtol(beginptr, &endptr, 10);
+ if ( endptr!=beginptr ) {
+ ret->adjustRightSideBearingByPixel = lv;
+ }
+ } while ( 0 );
+ if (scaleBBoxWidth<=0.0) {
+ fprintf(stderr, "ScaleBBoxWitdh needs plus.\n");
+ result = BadFontName;
+ goto quit;
+ }
+ if (scaleBBoxHeight<=0.0) {
+ fprintf(stderr, "ScaleBBoxHeight needs plus.\n");
+ result = BadFontName;
+ goto quit;
+ }
+ ret->scaleBBoxWidth = scaleBBoxWidth;
+ ret->scaleBBoxHeight = scaleBBoxHeight;
+ }
+ /* spacing */
+ if (SPropRecValList_search_record(&listPropRecVal,
+ &contRecValue,
+ "ForceSpacing")) {
+ char *strSpace = SPropContainer_value_str(contRecValue);
+ Bool err = False;
+ if (1 != strlen(strSpace))
+ err = True;
+ else
+ switch (strSpace[0]) {
+ case 'M':
+ ret->flags |= TTCAP_MONO_CENTER;
+ *spacing = 'm';
+ break;
+ case 'm':
+ case 'p':
+ case 'c':
+ *spacing = strSpace[0];
+ break;
+ default:
+ err = True;
+ }
+ if (err) {
+ result = BadFontName;
+ goto quit;
+ }
+ }
+ /* doube striking */
+ if (SPropRecValList_search_record(&listPropRecVal,
+ &contRecValue,
+ "DoubleStrike")) {
+ /* Set or Reset Auto Bold Flag */
+ char *strDoubleStrike = SPropContainer_value_str(contRecValue);
+ Bool err = False;
+ if ( 0 < strlen(strDoubleStrike) ) {
+ switch (strDoubleStrike[0]) {
+ case 'm':
+ case 'M':
+ case 'l':
+ case 'L':
+ ret->flags |= TTCAP_DOUBLE_STRIKE;
+ ret->flags |= TTCAP_DOUBLE_STRIKE_MKBOLD_EDGE_LEFT;
+ break;
+ case 'y':
+ case 'Y':
+ ret->flags |= TTCAP_DOUBLE_STRIKE;
+ break;
+ case 'n':
+ case 'N':
+ ret->flags &= ~TTCAP_DOUBLE_STRIKE;
+ ret->flags &= ~TTCAP_DOUBLE_STRIKE_MKBOLD_EDGE_LEFT;
+ ret->flags &= ~TTCAP_DOUBLE_STRIKE_CORRECT_B_BOX_WIDTH;
+ break;
+ default:
+ err = True;
+ }
+ if ( err != True ) {
+ if ( strDoubleStrike[1] ) {
+ switch (strDoubleStrike[1]) {
+ case 'b':
+ case 'B':
+ case 'p':
+ case 'P':
+ case 'y':
+ case 'Y':
+ ret->flags |= TTCAP_DOUBLE_STRIKE_CORRECT_B_BOX_WIDTH;
+ break;
+ default:
+ break;
+ }
+ }
+ do {
+ char *comma_ptr=strchr(strDoubleStrike,';');
+ if ( !comma_ptr ) comma_ptr=strchr(strDoubleStrike,',');
+ if ( !comma_ptr ) break;
+ if ( comma_ptr[1] ) {
+ char *endptr;
+ int mkboldMaxPixel;
+ mkboldMaxPixel=strtol(comma_ptr+1, &endptr, 10);
+ if ( endptr != comma_ptr+1 && mkboldMaxPixel <= pixel ) {
+ ret->flags &= ~TTCAP_DOUBLE_STRIKE_MKBOLD_EDGE_LEFT;
+ }
+ }
+ comma_ptr=strchr(comma_ptr+1,',');
+ if ( !comma_ptr ) break;
+ if ( comma_ptr[1] ) {
+ char *endptr;
+ int max_pixel;
+ max_pixel=strtol(comma_ptr+1, &endptr, 10);
+ if ( endptr != comma_ptr+1 && max_pixel <= pixel ) {
+ if( ret->flags & TTCAP_DOUBLE_STRIKE )
+ ret->doubleStrikeShift += pixel / max_pixel;
+ }
+ }
+ } while(0);
+ }
+ }
+ else
+ err = True;
+ if (err) {
+ result = BadFontName;
+ goto quit;
+ }
+ }
+ /* very lazy metrics */
+ if (SPropRecValList_search_record(&listPropRecVal,
+ &contRecValue,
+ "VeryLazyMetrics")){
+ Bool isVeryLazy = SPropContainer_value_bool(contRecValue);
+ ret->flags |= TTCAP_DISABLE_DEFAULT_VERY_LAZY;
+ if( isVeryLazy == True )
+ ret->flags |= TTCAP_IS_VERY_LAZY;
+ else
+ ret->flags &= ~TTCAP_IS_VERY_LAZY;
+ }
+ /* embedded bitmap */
+ if (SPropRecValList_search_record(&listPropRecVal,
+ &contRecValue,
+ "EmbeddedBitmap")) {
+ char *strEmbeddedBitmap = SPropContainer_value_str(contRecValue);
+ Bool err = False;
+ if ( 1 == strlen(strEmbeddedBitmap) ) {
+ switch (strEmbeddedBitmap[0]) {
+ case 'y':
+ case 'Y':
+ isEmbeddedBitmap = True;
+ alwaysEmbeddedBitmap = True;
+ break;
+ case 'u':
+ case 'U':
+ isEmbeddedBitmap = True;
+ alwaysEmbeddedBitmap = False;
+ break;
+ case 'n':
+ case 'N':
+ isEmbeddedBitmap = False;
+ break;
+ default:
+ err = True;
+ }
+ }
+ else
+ err = True;
+ if (err) {
+ result = BadFontName;
+ goto quit;
+ }
+ }
+ /* scale bitmap */
+ if((ret->flags & TTCAP_IS_VERY_LAZY) &&
+ SPropRecValList_search_record(&listPropRecVal,
+ &contRecValue,
+ "VeryLazyBitmapWidthScale")) {
+ /* Scaling to Bitmap Bounding Box Width */
+ double scaleBitmapWidth = SPropContainer_value_dbl(contRecValue);
+
+ fprintf(stderr, "Warning: `bs' option is not required in X-TT version 2.\n");
+#if 0
+ if (scaleBitmapWidth<=0.0) {
+ fprintf(stderr, "ScaleBitmapWitdh needs plus.\n");
+ result = BadFontName;
+ goto quit;
+ }
+#endif
+ ret->scaleBitmap = scaleBitmapWidth;
+ }
+ /* restriction of the code range */
+ if (SPropRecValList_search_record(&listPropRecVal,
+ &contRecValue,
+ "CodeRange")) {
+ *dynStrTTCapCodeRange = xstrdup(SPropContainer_value_str(contRecValue));
+ if( *dynStrTTCapCodeRange == NULL ) {
+ result = AllocError;
+ goto quit;
+ }
+ }
+ /* forceConstantSpacing{Begin,End} */
+ if ( 1 /* ft->spacing == 'p' */ ){
+ unsigned short first_col=0,last_col=0x00ff;
+ unsigned short first_row=0,last_row=0x00ff;
+ if (SPropRecValList_search_record(&listPropRecVal,
+ &contRecValue,
+ "ForceConstantSpacingCodeRange")) {
+ if ( restrict_code_range_by_str(1,&first_col, &first_row,
+ &last_col, &last_row,
+ SPropContainer_value_str(contRecValue)) == 1 ) {
+ ret->forceConstantSpacingBegin = (int)( first_row<<8 | first_col );
+ ret->forceConstantSpacingEnd = (int)( last_row<<8 | last_col );
+ if ( ret->forceConstantSpacingBegin <= ret->forceConstantSpacingEnd )
+ ret->flags &= ~TTCAP_FORCE_C_OUTSIDE;
+ else ret->flags |= TTCAP_FORCE_C_OUTSIDE;
+ }
+ }
+ }
+ /* */
+ if ( 1 ){
+ unsigned short first_col=0, last_col=0x0ff;
+ unsigned short first_row=0, last_row=0x0ff;
+ if ( SPropRecValList_search_record(&listPropRecVal,
+ &contRecValue,
+ "ForceConstantSpacingMetrics")) {
+ char *strMetrics;
+ strMetrics = SPropContainer_value_str(contRecValue);
+ if ( strMetrics ) {
+ char *comma_ptr,*period_ptr,*semic_ptr;
+ semic_ptr=strchr(strMetrics,';');
+ comma_ptr=strchr(strMetrics,',');
+ period_ptr=strchr(strMetrics,'.');
+ if ( semic_ptr && comma_ptr )
+ if ( semic_ptr < comma_ptr ) comma_ptr=NULL;
+ if ( semic_ptr && period_ptr )
+ if ( semic_ptr < period_ptr ) period_ptr=NULL;
+ if ( !comma_ptr && !period_ptr && strMetrics != semic_ptr ) {
+ if ( restrict_code_range_by_str(1,&first_col, &first_row,
+ &last_col, &last_row,
+ SPropContainer_value_str(contRecValue)) == 1 ) {
+ ret->force_c_representative_metrics_char_code =
+ (int)( first_row<<8 | first_col );
+ }
+ }
+ else {
+ double v;
+ char *endptr,*beginptr=strMetrics;
+ do {
+ v=strtod(beginptr, &endptr);
+ if ( endptr!=beginptr ) {
+ ret->force_c_scale_b_box_width = v;
+ }
+ if ( *endptr != ',' ) break;
+ beginptr=endptr+1;
+ v=strtod(beginptr, &endptr);
+ if ( endptr!=beginptr ) {
+ ret->force_c_scale_lsb = v;
+ ret->flags |= TTCAP_FORCE_C_LSB_FLAG;
+ }
+ if ( *endptr != ',' ) break;
+ beginptr=endptr+1;
+ v=strtod(beginptr, &endptr);
+ if ( endptr!=beginptr ) {
+ ret->force_c_scale_rsb = v;
+ ret->flags |= TTCAP_FORCE_C_RSB_FLAG;
+ }
+ if ( *endptr != ',' ) break;
+ beginptr=endptr+1;
+ v=strtod(beginptr, &endptr);
+ if ( endptr!=beginptr ) {
+ ret->force_c_scale_b_box_height = v;
+ }
+ } while (0);
+ }
+ if ( semic_ptr ) {
+ int lv;
+ char *endptr,*beginptr=semic_ptr+1;
+ do {
+ lv=strtol(beginptr, &endptr, 10);
+ if ( endptr!=beginptr ) {
+ ret->force_c_adjust_width_by_pixel=lv;
+ }
+ if ( *endptr != ',' ) break;
+ beginptr=endptr+1;
+ lv=strtol(beginptr, &endptr, 10);
+ if ( endptr!=beginptr ) {
+ ret->force_c_adjust_lsb_by_pixel=lv;
+ }
+ if ( *endptr != ',' ) break;
+ beginptr=endptr+1;
+ lv=strtol(beginptr, &endptr, 10);
+ if ( endptr!=beginptr ) {
+ ret->force_c_adjust_rsb_by_pixel=lv;
+ }
+ } while (0);
+ }
+ }
+ }
+ }
+
+ if (SPropRecValList_search_record(&listPropRecVal,
+ &contRecValue,
+ "FontProperties")) {
+ /* Set or Reset the Flag of FontProperties */
+ *font_properties=SPropContainer_value_bool(contRecValue);
+ }
+
+ ret->force_c_scale_b_box_width *= ret->scaleBBoxWidth;
+ ret->force_c_scale_b_box_height *= ret->scaleBBoxHeight;
+
+ ret->force_c_scale_b_box_width *= ret->scaleWidth;
+ ret->scaleBBoxWidth *= ret->scaleWidth;
+
+ ret->force_c_adjust_rsb_by_pixel += ret->adjustRightSideBearingByPixel;
+ ret->force_c_adjust_lsb_by_pixel += ret->adjustLeftSideBearingByPixel;
+
+ /* scaleWidth, scaleBBoxWidth, force_c_scale_b_box_width, force_c_scale_b_box_width */
+
+ /* by TTCap */
+ if( hinting == False ) *load_flags |= FT_LOAD_NO_HINTING;
+ if( isEmbeddedBitmap == False ) *load_flags |= FT_LOAD_NO_BITMAP;
+ if( ret->autoItalic != 0 && alwaysEmbeddedBitmap == False )
+ *load_flags |= FT_LOAD_NO_BITMAP;
+
+ quit:
+ return result;
+}
+
+static int
+ft_get_trans_from_vals( FontScalablePtr vals, FTNormalisedTransformationPtr trans )
+{
+ /* Compute the transformation matrix. We use floating-point
+ arithmetic for simplicity */
+
+ trans->xres = vals->x;
+ trans->yres = vals->y;
+
+ /* This value cannot be 0. */
+ trans->scale = hypot(vals->point_matrix[2], vals->point_matrix[3]);
+ trans->nonIdentity = 0;
+
+ /* Try to round stuff. We want approximate zeros to be exact zeros,
+ and if the elements on the diagonal are approximately equal, we
+ want them equal. We do this to avoid breaking hinting. */
+ if(DIFFER(vals->point_matrix[0], vals->point_matrix[3])) {
+ trans->nonIdentity = 1;
+ trans->matrix.xx =
+ (int)((vals->point_matrix[0]*(double)TWO_SIXTEENTH)/trans->scale);
+ trans->matrix.yy =
+ (int)((vals->point_matrix[3]*(double)TWO_SIXTEENTH)/trans->scale);
+ } else {
+ trans->matrix.xx = trans->matrix.yy =
+ ((vals->point_matrix[0] + vals->point_matrix[3])/2*
+ (double)TWO_SIXTEENTH)/trans->scale;
+ }
+
+ if(DIFFER0(vals->point_matrix[1], trans->scale)) {
+ trans->matrix.yx =
+ (int)((vals->point_matrix[1]*(double)TWO_SIXTEENTH)/trans->scale);
+ trans->nonIdentity = 1;
+ } else
+ trans->matrix.yx = 0;
+
+ if(DIFFER0(vals->point_matrix[2], trans->scale)) {
+ trans->matrix.xy =
+ (int)((vals->point_matrix[2]*(double)TWO_SIXTEENTH)/trans->scale);
+ trans->nonIdentity = 1;
+ } else
+ trans->matrix.xy=0;
+ return 0;
+}
+
+
+static int
+is_fixed_width(FT_Face face)
+{
+ PS_FontInfoRec t1info_rec;
+ int ftrc;
+
+ if(FT_IS_FIXED_WIDTH(face)) {
+ return 1;
+ }
+
+ ftrc = FT_Get_PS_Font_Info(face, &t1info_rec);
+ if(ftrc == 0 && t1info_rec.is_fixed_pitch) {
+ return 1;
+ }
+
+ return 0;
+}
+
+static int
+FreeTypeLoadFont(FTFontPtr font, FontInfoPtr info, FTFacePtr face,
+ char *FTFileName, FontScalablePtr vals, FontEntryPtr entry,
+ FontBitmapFormatPtr bmfmt, FT_Int32 load_flags,
+ struct TTCapInfo *tmp_ttcap, char *dynStrTTCapCodeRange,
+ int ttcap_spacing )
+{
+ int xrc;
+ FTNormalisedTransformationRec trans;
+ int spacing, actual_spacing, zero_code;
+ long lastCode, firstCode;
+ TT_Postscript *post;
+
+ ft_get_trans_from_vals(vals,&trans);
+
+ /* Check for charcell in XLFD */
+ spacing = FT_PROPORTIONAL;
+ if(entry->name.ndashes == 14) {
+ char *p;
+ int dashes = 0;
+ for(p = entry->name.name;
+ p <= entry->name.name + entry->name.length - 2;
+ p++) {
+ if(*p == '-') {
+ dashes++;
+ if(dashes == 11) {
+ if(p[1]=='c' && p[2]=='-')
+ spacing=FT_CHARCELL;
+ else if(p[1]=='m' && p[2]=='-')
+ spacing=FT_MONOSPACED;
+ break;
+ }
+ }
+ }
+ }
+ /* by TTCap */
+ if( ttcap_spacing != 0 ) {
+ if( ttcap_spacing == 'c' ) spacing=FT_CHARCELL;
+ else if( ttcap_spacing == 'm' ) spacing=FT_MONOSPACED;
+ else spacing=FT_PROPORTIONAL;
+ }
+
+ actual_spacing = spacing;
+ if( spacing == FT_PROPORTIONAL ) {
+ if( is_fixed_width(face->face) )
+ actual_spacing = FT_MONOSPACED;
+ }
+
+ if(entry->name.ndashes == 14) {
+ xrc = FTPickMapping(entry->name.name, entry->name.length, FTFileName,
+ face->face, &font->mapping);
+ if (xrc != Successful)
+ return xrc;
+ } else {
+ xrc = FTPickMapping(0, 0, FTFileName,
+ face->face, &font->mapping);
+ if (xrc != Successful)
+ return xrc;
+ }
+
+ font->nranges = vals->nranges;
+ font->ranges = 0;
+ if(font->nranges) {
+ font->ranges = malloc(vals->nranges*sizeof(fsRange));
+ if(font->ranges == NULL)
+ return AllocError;
+ memcpy((char*)font->ranges, (char*)vals->ranges,
+ vals->nranges*sizeof(fsRange));
+ }
+
+ zero_code=-1;
+ if(info) {
+ firstCode = 0;
+ lastCode = 0xFFFFL;
+ if(!font->mapping.mapping ||
+ font->mapping.mapping->encoding->row_size == 0) {
+ /* linear indexing */
+ lastCode=MIN(lastCode,
+ font->mapping.mapping ?
+ font->mapping.mapping->encoding->size-1 :
+ 0xFF);
+ if(font->mapping.mapping && font->mapping.mapping->encoding->first)
+ firstCode = font->mapping.mapping->encoding->first;
+ info->firstRow = firstCode/0x100;
+ info->lastRow = lastCode/0x100;
+ info->firstCol =
+ (info->firstRow || info->lastRow) ? 0 : (firstCode & 0xFF);
+ info->lastCol = info->lastRow ? 0xFF : (lastCode & 0xFF);
+ if ( firstCode == 0 ) zero_code=0;
+ } else {
+ /* matrix indexing */
+ info->firstRow = font->mapping.mapping->encoding->first;
+ info->lastRow = MIN(font->mapping.mapping->encoding->size-1,
+ lastCode/0x100);
+ info->firstCol = font->mapping.mapping->encoding->first_col;
+ info->lastCol = MIN(font->mapping.mapping->encoding->row_size-1,
+ lastCode<0x100?lastCode:0xFF);
+ if( info->firstRow == 0 && info->firstCol == 0 ) zero_code=0;
+ }
+
+ /* firstCode and lastCode are not valid in case of a matrix
+ encoding */
+
+ if( dynStrTTCapCodeRange ) {
+ restrict_code_range_by_str(0,&info->firstCol, &info->firstRow,
+ &info->lastCol, &info->lastRow,
+ dynStrTTCapCodeRange);
+ }
+ restrict_code_range(&info->firstCol, &info->firstRow,
+ &info->lastCol, &info->lastRow,
+ font->ranges, font->nranges);
+ }
+ font->info = info;
+
+ /* zero code is frequently used. */
+ if ( zero_code < 0 ) {
+ /* The fontenc should have the information of DefaultCh.
+ But we do not have such a information.
+ So we cannot but set 0. */
+ font->zero_idx = 0;
+ }
+ else
+ font->zero_idx = FTRemap(face->face,
+ &font->mapping, zero_code);
+
+ post = FT_Get_Sfnt_Table(face->face, ft_sfnt_post);
+
+#ifdef DEFAULT_VERY_LAZY
+ if( !( tmp_ttcap->flags & TTCAP_DISABLE_DEFAULT_VERY_LAZY ) )
+ if( DEFAULT_VERY_LAZY <= 1 + info->lastRow - info->firstRow ) {
+ if( post ){
+ tmp_ttcap->flags |= TTCAP_IS_VERY_LAZY;
+ }
+ }
+#endif
+ /* We should always reset. */
+ tmp_ttcap->flags &= ~TTCAP_DISABLE_DEFAULT_VERY_LAZY;
+
+ if ( face->bitmap || actual_spacing == FT_CHARCELL )
+ tmp_ttcap->flags &= ~TTCAP_IS_VERY_LAZY;
+ /* "vl=y" is available when TrueType or OpenType only */
+ if ( !face->bitmap && !(FT_IS_SFNT( face->face )) )
+ tmp_ttcap->flags &= ~TTCAP_IS_VERY_LAZY;
+
+ if( post ) {
+ if( post->italicAngle != 0 )
+ tmp_ttcap->vl_slant = -sin( (post->italicAngle/1024./5760.)*1.57079632679489661923 );
+ /* fprintf(stderr,"angle=%g(%g)\n",tmp_ttcap->vl_slant,(post->italicAngle/1024./5760.)*90); */
+ }
+
+ xrc = FreeTypeOpenInstance(&font->instance, face,
+ FTFileName, &trans, actual_spacing, bmfmt,
+ tmp_ttcap, load_flags );
+ return xrc;
+}
+
+static void
+adjust_min_max(xCharInfo *minc, xCharInfo *maxc, xCharInfo *tmp)
+{
+#define MINMAX(field,ci) \
+ if (minc->field > (ci)->field) \
+ minc->field = (ci)->field; \
+ if (maxc->field < (ci)->field) \
+ maxc->field = (ci)->field;
+
+ MINMAX(ascent, tmp);
+ MINMAX(descent, tmp);
+ MINMAX(leftSideBearing, tmp);
+ MINMAX(rightSideBearing, tmp);
+ MINMAX(characterWidth, tmp);
+
+ if ((INT16)minc->attributes > (INT16)tmp->attributes)
+ minc->attributes = tmp->attributes;
+ if ((INT16)maxc->attributes < (INT16)tmp->attributes)
+ maxc->attributes = tmp->attributes;
+#undef MINMAX
+}
+
+static void
+ft_compute_bounds(FTFontPtr font, FontInfoPtr pinfo, FontScalablePtr vals )
+{
+ FTInstancePtr instance;
+ int row, col;
+ unsigned int c;
+ xCharInfo minchar, maxchar, *tmpchar = NULL;
+ int overlap, maxOverlap;
+ long swidth = 0;
+ long total_width = 0;
+ int num_cols, num_chars = 0;
+ int flags, skip_ok = 0;
+ int force_c_outside ;
+
+ instance = font->instance;
+ force_c_outside = instance->ttcap.flags & TTCAP_FORCE_C_OUTSIDE;
+
+ minchar.ascent = minchar.descent =
+ minchar.leftSideBearing = minchar.rightSideBearing =
+ minchar.characterWidth = minchar.attributes = 32767;
+ maxchar.ascent = maxchar.descent =
+ maxchar.leftSideBearing = maxchar.rightSideBearing =
+ maxchar.characterWidth = maxchar.attributes = -32767;
+ maxOverlap = -32767;
+
+ /* Parse all glyphs */
+ num_cols = 1 + pinfo->lastCol - pinfo->firstCol;
+ for (row = pinfo->firstRow; row <= pinfo->lastRow; row++) {
+ if ( skip_ok && tmpchar ) {
+ if ( !force_c_outside ) {
+ if ( instance->ttcap.forceConstantSpacingBegin < row<<8
+ && row<<8 < (instance->ttcap.forceConstantSpacingEnd & 0x0ff00) ) {
+ if (tmpchar->characterWidth) {
+ num_chars += num_cols;
+ swidth += ABS(tmpchar->characterWidth)*num_cols;
+ total_width += tmpchar->characterWidth*num_cols;
+ continue;
+ }
+ }
+ else skip_ok=0;
+ }
+ else { /* for GB18030 proportional */
+ if ( instance->ttcap.forceConstantSpacingBegin < row<<8
+ || row<<8 < (instance->ttcap.forceConstantSpacingEnd & 0x0ff00) ) {
+ if (tmpchar->characterWidth) {
+ num_chars += num_cols;
+ swidth += ABS(tmpchar->characterWidth)*num_cols;
+ total_width += tmpchar->characterWidth*num_cols;
+ continue;
+ }
+ }
+ else skip_ok=0;
+ }
+ }
+ for (col = pinfo->firstCol; col <= pinfo->lastCol; col++) {
+ c = row<<8|col;
+ flags=0;
+ if ( !force_c_outside ) {
+ if ( c <= instance->ttcap.forceConstantSpacingEnd
+ && instance->ttcap.forceConstantSpacingBegin <= c )
+ flags|=FT_FORCE_CONSTANT_SPACING;
+ }
+ else { /* for GB18030 proportional */
+ if ( c <= instance->ttcap.forceConstantSpacingEnd
+ || instance->ttcap.forceConstantSpacingBegin <= c )
+ flags|=FT_FORCE_CONSTANT_SPACING;
+ }
+#if 0
+ fprintf(stderr, "comp_bounds: %x ->", c);
+#endif
+ if ( skip_ok == 0 || flags == 0 ){
+ tmpchar=NULL;
+#if 0
+ fprintf(stderr, "%x\n", c);
+#endif
+ if( FreeTypeFontGetGlyphMetrics(c, flags, &tmpchar, font) != Successful )
+ continue;
+ }
+ if ( !tmpchar ) continue;
+ adjust_min_max(&minchar, &maxchar, tmpchar);
+ overlap = tmpchar->rightSideBearing - tmpchar->characterWidth;
+ if (maxOverlap < overlap)
+ maxOverlap = overlap;
+
+ if (!tmpchar->characterWidth)
+ continue;
+ num_chars++;
+ swidth += ABS(tmpchar->characterWidth);
+ total_width += tmpchar->characterWidth;
+
+ if ( flags & FT_FORCE_CONSTANT_SPACING ) skip_ok=1;
+ }
+ }
+
+#ifndef X_ACCEPTS_NO_SUCH_CHAR
+ /* Check code 0 */
+ if( FreeTypeInstanceGetGlyphMetrics(font->zero_idx, 0, &tmpchar, font->instance) != Successful || tmpchar == NULL)
+ if( FreeTypeInstanceGetGlyphMetrics(font->zero_idx, FT_GET_DUMMY, &tmpchar, font->instance) != Successful )
+ tmpchar = NULL;
+ if ( tmpchar ) {
+ adjust_min_max(&minchar, &maxchar, tmpchar);
+ overlap = tmpchar->rightSideBearing - tmpchar->characterWidth;
+ if (maxOverlap < overlap)
+ maxOverlap = overlap;
+ }
+#endif
+
+ /* AVERAGE_WIDTH ... 1/10 pixel unit */
+ if (num_chars > 0) {
+ swidth = (swidth * 10.0 + num_chars / 2.0) / num_chars;
+ if (total_width < 0)
+ swidth = -swidth;
+ vals->width = swidth;
+ } else
+ vals->width = 0;
+
+ /*
+ if (char_width.pixel) {
+ maxchar.characterWidth = char_width.pixel;
+ minchar.characterWidth = char_width.pixel;
+ }
+ */
+
+ pinfo->maxbounds = maxchar;
+ pinfo->minbounds = minchar;
+ pinfo->ink_maxbounds = maxchar;
+ pinfo->ink_minbounds = minchar;
+ pinfo->maxOverlap = maxOverlap;
+}
+
+static int
+compute_new_extents( FontScalablePtr vals, double scale, double lsb, double rsb, double desc, double asc,
+ int *lsb_result, int *rsb_result, int *desc_result, int *asc_result )
+{
+#define TRANSFORM_POINT(matrix, x, y, dest) \
+ ((dest)[0] = (matrix)[0] * (x) + (matrix)[2] * (y), \
+ (dest)[1] = (matrix)[1] * (x) + (matrix)[3] * (y))
+
+#define CHECK_EXTENT(lsb, rsb, desc, asc, data) \
+ ((lsb) > (data)[0] ? (lsb) = (data)[0] : 0 , \
+ (rsb) < (data)[0] ? (rsb) = (data)[0] : 0, \
+ (-desc) > (data)[1] ? (desc) = -(data)[1] : 0 , \
+ (asc) < (data)[1] ? (asc) = (data)[1] : 0)
+ double newlsb, newrsb, newdesc, newasc;
+ double point[2];
+
+ /* Compute new extents for this glyph */
+ TRANSFORM_POINT(vals->pixel_matrix, lsb, -desc, point);
+ newlsb = point[0];
+ newrsb = newlsb;
+ newdesc = -point[1];
+ newasc = -newdesc;
+ TRANSFORM_POINT(vals->pixel_matrix, lsb, asc, point);
+ CHECK_EXTENT(newlsb, newrsb, newdesc, newasc, point);
+ TRANSFORM_POINT(vals->pixel_matrix, rsb, -desc, point);
+ CHECK_EXTENT(newlsb, newrsb, newdesc, newasc, point);
+ TRANSFORM_POINT(vals->pixel_matrix, rsb, asc, point);
+ CHECK_EXTENT(newlsb, newrsb, newdesc, newasc, point);
+
+ /* ???: lsb = (int)floor(newlsb * scale); */
+ *lsb_result = (int)floor(newlsb * scale + 0.5);
+ *rsb_result = (int)floor(newrsb * scale + 0.5);
+ *desc_result = (int)ceil(newdesc * scale - 0.5);
+ *asc_result = (int)floor(newasc * scale + 0.5);
+
+ return 0;
+#undef CHECK_EXTENT
+#undef TRANSFORM_POINT
+}
+
+static int
+is_matrix_unit(FontScalablePtr vals)
+{
+ double base_size;
+ FT_Matrix m;
+
+ base_size = hypot(vals->point_matrix[2], vals->point_matrix[3]);
+
+ m.xx = vals->point_matrix[0] / base_size * 65536;
+ m.xy = vals->point_matrix[2] / base_size * 65536;
+ m.yx = vals->point_matrix[1] / base_size * 65536;
+ m.yy = vals->point_matrix[3] / base_size * 65536;
+
+ return (m.xx == 65536) && (m.yx == 0) &&
+ (m.xy == 0) && (m.yy == 65536);
+}
+
+/* Do all the real work for OpenFont or FontInfo */
+/* xf->info is only accessed through info, and xf might be null */
+
+static int
+FreeTypeLoadXFont(char *fileName,
+ FontScalablePtr vals, FontPtr xf, FontInfoPtr info,
+ FontBitmapFormatPtr bmfmt, FontEntryPtr entry)
+{
+ FTFontPtr font = NULL;
+ FTFacePtr face = NULL;
+ FTInstancePtr instance;
+ FT_Size_Metrics *smetrics;
+ int xrc=Successful;
+ int charcell;
+ long rawWidth = 0, rawAverageWidth = 0;
+ int upm, minLsb, maxRsb, ascent, descent, width, averageWidth;
+ double scale, base_width, base_height;
+ Bool orig_is_matrix_unit, font_properties;
+ int face_number, ttcap_spacing;
+ struct TTCapInfo tmp_ttcap;
+ struct TTCapInfo *ins_ttcap;
+ FT_Int32 load_flags = FT_LOAD_DEFAULT; /* orig: FT_LOAD_RENDER | FT_LOAD_MONOCHROME */
+ char *dynStrRealFileName = NULL; /* foo.ttc */
+ char *dynStrFTFileName = NULL; /* :1:foo.ttc */
+ char *dynStrTTCapCodeRange = NULL;
+
+ font = calloc(1, sizeof(FTFontRec));
+ if(font == NULL) {
+ xrc = AllocError;
+ goto quit;
+ }
+
+ xrc = FreeTypeSetUpTTCap(fileName, vals,
+ &dynStrRealFileName, &dynStrFTFileName,
+ &tmp_ttcap, &face_number,
+ &load_flags, &ttcap_spacing,
+ &font_properties, &dynStrTTCapCodeRange);
+ if ( xrc != Successful ) {
+ goto quit;
+ }
+
+ xrc = FreeTypeOpenFace(&face, dynStrFTFileName, dynStrRealFileName, face_number);
+ if(xrc != Successful) {
+ goto quit;
+ }
+
+ if( is_matrix_unit(vals) )
+ orig_is_matrix_unit = True;
+ else {
+ orig_is_matrix_unit = False;
+ /* Turn off EmbeddedBitmap when original matrix is not diagonal. */
+ load_flags |= FT_LOAD_NO_BITMAP;
+ }
+
+ if( face->bitmap ) load_flags &= ~FT_LOAD_NO_BITMAP;
+
+ /* Slant control by TTCap */
+ if(!face->bitmap) {
+ vals->pixel_matrix[2] +=
+ vals->pixel_matrix[0] * tmp_ttcap.autoItalic;
+ vals->point_matrix[2] +=
+ vals->point_matrix[0] * tmp_ttcap.autoItalic;
+ vals->pixel_matrix[3] +=
+ vals->pixel_matrix[1] * tmp_ttcap.autoItalic;
+ vals->point_matrix[3] +=
+ vals->point_matrix[1] * tmp_ttcap.autoItalic;
+ }
+
+ base_width=hypot(vals->pixel_matrix[0], vals->pixel_matrix[1]);
+ base_height=hypot(vals->pixel_matrix[2], vals->pixel_matrix[3]);
+ if(MAX(base_width, base_height) < 1.0 ) {
+ xrc = BadFontName;
+ goto quit;
+ }
+
+ xrc = FreeTypeLoadFont(font, info, face, dynStrFTFileName, vals, entry, bmfmt,
+ load_flags, &tmp_ttcap, dynStrTTCapCodeRange,
+ ttcap_spacing );
+ if(xrc != Successful) {
+ goto quit;
+ }
+
+ instance = font->instance;
+ smetrics = &instance->size->metrics;
+ ins_ttcap = &instance->ttcap;
+
+ upm = face->face->units_per_EM;
+ if(upm == 0) {
+ /* Work around FreeType bug */
+ upm = WORK_AROUND_UPM;
+ }
+ scale = 1.0 / upm;
+
+ charcell = (instance->spacing == FT_CHARCELL);
+
+ if( instance->charcellMetrics == NULL ) {
+
+ /* New instance */
+
+ long force_c_rawWidth = 0;
+ int force_c_lsb,force_c_rsb,force_c_width;
+ double unit_x=0,unit_y=0,advance;
+ CharInfoPtr tmpglyph;
+
+ /*
+ * CALCULATE HEADER'S METRICS
+ */
+
+ /* for OUTLINE fonts */
+ if(!face->bitmap) {
+ int new_width;
+ double ratio,force_c_ratio;
+ double width_x=0,width_y=0;
+ double force_c_width_x, force_c_rsb_x, force_c_lsb_x;
+ double tmp_rsb,tmp_lsb,tmp_asc,tmp_des;
+ double max_advance_height;
+ tmp_asc = face->face->bbox.yMax;
+ tmp_des = -(face->face->bbox.yMin);
+ if ( tmp_asc < face->face->ascender ) tmp_asc = face->face->ascender;
+ if ( tmp_des < -(face->face->descender) ) tmp_des = -(face->face->descender);
+ tmp_lsb = face->face->bbox.xMin;
+ tmp_rsb = face->face->bbox.xMax;
+ if ( tmp_rsb < face->face->max_advance_width ) tmp_rsb = face->face->max_advance_width;
+ /* apply scaleBBoxWidth */
+ /* we should not ...??? */
+ tmp_lsb *= ins_ttcap->scaleBBoxWidth;
+ tmp_rsb *= ins_ttcap->scaleBBoxWidth;
+ /* transform and rescale */
+ compute_new_extents( vals, scale, tmp_lsb, tmp_rsb, tmp_des, tmp_asc,
+ &minLsb, &maxRsb, &descent, &ascent );
+ /* */
+ /* Consider vertical layouts */
+ if( 0 < face->face->max_advance_height )
+ max_advance_height = face->face->max_advance_height;
+ else
+ max_advance_height = tmp_asc + tmp_des;
+ if( vals->pixel_matrix[1] == 0 ){
+ unit_x = fabs(vals->pixel_matrix[0]);
+ unit_y = 0;
+ width_x = face->face->max_advance_width * ins_ttcap->scaleBBoxWidth * unit_x;
+ }
+ else if( vals->pixel_matrix[3] == 0 ){
+ unit_y = fabs(vals->pixel_matrix[2]);
+ unit_x = 0;
+ width_x = max_advance_height * ins_ttcap->scaleBBoxHeight * unit_y;
+ }
+ else{
+ unit_x = fabs(vals->pixel_matrix[0] -
+ vals->pixel_matrix[1]*vals->pixel_matrix[2]/vals->pixel_matrix[3]);
+ unit_y = fabs(vals->pixel_matrix[2] -
+ vals->pixel_matrix[3]*vals->pixel_matrix[0]/vals->pixel_matrix[1]);
+ width_x = face->face->max_advance_width * ins_ttcap->scaleBBoxWidth * unit_x;
+ width_y = max_advance_height * ins_ttcap->scaleBBoxHeight * unit_y;
+ if( width_y < width_x ){
+ width_x = width_y;
+ unit_x = 0;
+ }
+ else{
+ unit_y = 0;
+ }
+ }
+ /* calculate correction ratio */
+ width = (int)floor( (advance = width_x * scale) + 0.5);
+ new_width = width;
+ if( ins_ttcap->flags & TTCAP_DOUBLE_STRIKE_CORRECT_B_BOX_WIDTH )
+ new_width += ins_ttcap->doubleStrikeShift;
+ new_width += ins_ttcap->adjustBBoxWidthByPixel;
+ ratio = (double)new_width/width;
+ width = new_width;
+ /* force constant */
+ if( unit_x != 0 ) {
+ force_c_width_x = face->face->max_advance_width
+ * ins_ttcap->force_c_scale_b_box_width * unit_x;
+ force_c_lsb_x = face->face->max_advance_width
+ * ins_ttcap->force_c_scale_lsb * unit_x;
+ force_c_rsb_x = face->face->max_advance_width
+ * ins_ttcap->force_c_scale_rsb * unit_x;
+ }
+ else {
+ force_c_width_x = max_advance_height
+ * ins_ttcap->force_c_scale_b_box_height * unit_y;
+ force_c_lsb_x = max_advance_height
+ * ins_ttcap->force_c_scale_lsb * unit_y;
+ force_c_rsb_x = max_advance_height
+ * ins_ttcap->force_c_scale_rsb * unit_y;
+ }
+ /* calculate correction ratio */
+ force_c_width = (int)floor(force_c_width_x * scale + 0.5);
+ new_width = force_c_width;
+ if( ins_ttcap->flags & TTCAP_DOUBLE_STRIKE_CORRECT_B_BOX_WIDTH )
+ force_c_width += ins_ttcap->doubleStrikeShift;
+ new_width += ins_ttcap->force_c_adjust_width_by_pixel;
+ force_c_ratio = (double)new_width/force_c_width;
+ force_c_width = new_width;
+ /* force_c_lsb, force_c_rsb */
+ if( ins_ttcap->flags & TTCAP_FORCE_C_LSB_FLAG )
+ force_c_lsb = (int)floor( force_c_lsb_x * scale + 0.5 );
+ else
+ force_c_lsb = minLsb;
+ if( ins_ttcap->flags & TTCAP_FORCE_C_RSB_FLAG )
+ force_c_rsb = (int)floor( force_c_rsb_x * scale + 0.5 );
+ else
+ force_c_rsb = maxRsb;
+ /* calculate shift of BitmapAutoItalic
+ (when diagonal matrix only) */
+ if( orig_is_matrix_unit == True ) {
+ if( ins_ttcap->autoItalic != 0 ) {
+ double ai;
+ int ai_lsb,ai_rsb,ai_total;
+ if( 0 < ins_ttcap->autoItalic ) ai=ins_ttcap->autoItalic;
+ else ai = -ins_ttcap->autoItalic;
+ ai_total = (int)( (ascent+descent) * ai + 0.5);
+ ai_rsb = (int)((double)ai_total * ascent / ( ascent + descent ) + 0.5 );
+ ai_lsb = -(ai_total - ai_rsb);
+ if( 0 < ins_ttcap->autoItalic ) {
+ ins_ttcap->lsbShiftOfBitmapAutoItalic = ai_lsb;
+ ins_ttcap->rsbShiftOfBitmapAutoItalic = ai_rsb;
+ }
+ else {
+ ins_ttcap->lsbShiftOfBitmapAutoItalic = -ai_rsb;
+ ins_ttcap->rsbShiftOfBitmapAutoItalic = -ai_lsb;
+ }
+ }
+ }
+ /* integer adjustment by TTCap */
+ if( ins_ttcap->flags & TTCAP_DOUBLE_STRIKE )
+ maxRsb += ins_ttcap->doubleStrikeShift;
+ maxRsb += ins_ttcap->adjustRightSideBearingByPixel;
+ minLsb += ins_ttcap->adjustLeftSideBearingByPixel;
+ /* */
+ if( ins_ttcap->flags & TTCAP_DOUBLE_STRIKE )
+ force_c_rsb += ins_ttcap->doubleStrikeShift;
+ force_c_rsb += ins_ttcap->force_c_adjust_rsb_by_pixel;
+ force_c_lsb += ins_ttcap->force_c_adjust_lsb_by_pixel;
+ /* apply to rawWidth */
+ averageWidth = (int)floor(10 * width_x * scale
+ * ratio + 0.5);
+ rawWidth = floor(width_x * scale
+ * ratio * 1000. / base_height + 0.5);
+ rawAverageWidth = floor(width_x * scale * ratio * 10.
+ * 1000. / base_height + 0.5);
+ force_c_rawWidth = floor(force_c_width_x * scale
+ * force_c_ratio * 1000. / base_height + 0.5);
+ /* */
+ }
+ /* for BITMAP fonts [if(face->bitmap)] */
+ else {
+ /* These values differ from actual when outline,
+ so we must use them ONLY FOR BITMAP. */
+ width = (int)floor(smetrics->max_advance * ins_ttcap->scaleBBoxWidth / 64.0 + .5);
+ descent = -smetrics->descender / 64;
+ ascent = smetrics->ascender / 64;
+ /* force constant */
+ force_c_width = (int)floor(smetrics->max_advance
+ * ins_ttcap->force_c_scale_b_box_width / 64.0 + .5);
+ /* Preserve average width for bitmap fonts */
+ if(vals->width != 0)
+ averageWidth = (int)floor(vals->width * ins_ttcap->scaleBBoxWidth +.5);
+ else
+ averageWidth = (int)floor(10.0 * smetrics->max_advance
+ * ins_ttcap->scaleBBoxWidth / 64.0 + .5);
+ rawWidth = 0;
+ rawAverageWidth = 0;
+ force_c_rawWidth = 0;
+ /* We don't consider vertical layouts */
+ advance = (int)floor(smetrics->max_advance / 64.0 +.5);
+ unit_x = vals->pixel_matrix[0];
+ unit_y = 0;
+ /* We can use 'width' only when bitmap.
+ This should not be set when outline. */
+ minLsb = 0;
+ maxRsb = width;
+ /* force constant */
+ if( ins_ttcap->flags & TTCAP_FORCE_C_LSB_FLAG )
+ force_c_lsb = (int)floor(smetrics->max_advance
+ * ins_ttcap->force_c_scale_lsb / 64.0 + .5);
+ else
+ force_c_lsb = minLsb;
+ if( ins_ttcap->flags & TTCAP_FORCE_C_RSB_FLAG )
+ force_c_rsb = (int)floor(smetrics->max_advance
+ * ins_ttcap->force_c_scale_rsb / 64.0 + .5);
+ else
+ force_c_rsb = maxRsb;
+ /* calculate shift of BitmapAutoItalic */
+ if( ins_ttcap->autoItalic != 0 ) {
+ double ai;
+ int ai_lsb,ai_rsb,ai_total;
+ if( 0 < ins_ttcap->autoItalic ) ai=ins_ttcap->autoItalic;
+ else ai = -ins_ttcap->autoItalic;
+ ai_total = (int)( (ascent+descent) * ai + 0.5);
+ ai_rsb = (int)((double)ai_total * ascent / ( ascent + descent ) + 0.5 );
+ ai_lsb = -(ai_total - ai_rsb);
+ if( 0 < ins_ttcap->autoItalic ) {
+ ins_ttcap->lsbShiftOfBitmapAutoItalic = ai_lsb;
+ ins_ttcap->rsbShiftOfBitmapAutoItalic = ai_rsb;
+ }
+ else {
+ ins_ttcap->lsbShiftOfBitmapAutoItalic = -ai_rsb;
+ ins_ttcap->rsbShiftOfBitmapAutoItalic = -ai_lsb;
+ }
+ }
+ /* integer adjustment by TTCap */
+ if( ins_ttcap->flags & TTCAP_DOUBLE_STRIKE_CORRECT_B_BOX_WIDTH )
+ width += ins_ttcap->doubleStrikeShift;
+ if( ins_ttcap->flags & TTCAP_DOUBLE_STRIKE )
+ maxRsb += ins_ttcap->doubleStrikeShift;
+ maxRsb += ins_ttcap->adjustRightSideBearingByPixel;
+ minLsb += ins_ttcap->adjustLeftSideBearingByPixel;
+ /* We have not carried out matrix calculation, so this is done. */
+ maxRsb += ins_ttcap->rsbShiftOfBitmapAutoItalic;
+ minLsb += ins_ttcap->lsbShiftOfBitmapAutoItalic;
+ /* force constant */
+ if( ins_ttcap->flags & TTCAP_DOUBLE_STRIKE )
+ force_c_rsb += ins_ttcap->doubleStrikeShift;
+ force_c_rsb += ins_ttcap->force_c_adjust_rsb_by_pixel;
+ force_c_lsb += ins_ttcap->force_c_adjust_lsb_by_pixel;
+ force_c_rsb += ins_ttcap->rsbShiftOfBitmapAutoItalic;
+ force_c_lsb += ins_ttcap->lsbShiftOfBitmapAutoItalic;
+ }
+
+ /* SET CALCULATED VALUES TO INSTANCE */
+
+ /* Set actual height and cosine */
+ instance->pixel_size = base_height;
+ instance->advance = advance;
+ if ( unit_x != 0 ){
+ instance->pixel_width_unit_x = unit_x/base_height;
+ instance->pixel_width_unit_y = 0;
+ }
+ else{
+ instance->pixel_width_unit_x = 0;
+ instance->pixel_width_unit_y = unit_y/base_height;
+ }
+
+ /* header's metrics */
+ instance->charcellMetrics = malloc(sizeof(xCharInfo));
+ if(instance->charcellMetrics == NULL) {
+ xrc = AllocError;
+ goto quit;
+ }
+ instance->charcellMetrics->ascent = ascent;
+ instance->charcellMetrics->descent = descent;
+ instance->charcellMetrics->attributes = rawWidth;
+ instance->charcellMetrics->rightSideBearing = maxRsb;
+ instance->charcellMetrics->leftSideBearing = minLsb;
+ instance->charcellMetrics->characterWidth = width;
+ instance->averageWidth = averageWidth;
+ instance->rawAverageWidth = rawAverageWidth;
+
+ /* Check code 0 */
+ if( FreeTypeInstanceGetGlyph(font->zero_idx, 0, &tmpglyph, font->instance) != Successful
+ || tmpglyph == NULL)
+ if( FreeTypeInstanceGetGlyph(font->zero_idx, FT_GET_DUMMY, &tmpglyph, font->instance)
+ != Successful )
+ tmpglyph = NULL;
+ if ( !tmpglyph ) {
+ xrc = AllocError;
+ goto quit;
+ }
+
+ /* FORCE CONSTANT METRICS */
+ if( 0 <= ins_ttcap->forceConstantSpacingEnd ) {
+ xCharInfo *tmpchar = NULL;
+ int c = ins_ttcap->force_c_representative_metrics_char_code;
+ /* header's metrics */
+ if( instance->forceConstantMetrics == NULL ){
+ instance->forceConstantMetrics = malloc(sizeof(xCharInfo));
+ if(instance->forceConstantMetrics == NULL) {
+ xrc = AllocError;
+ goto quit;
+ }
+ }
+ /* Get Representative Metrics */
+ if ( 0 <= c ) {
+ if( FreeTypeFontGetGlyphMetrics(c, 0, &tmpchar, font) != Successful )
+ tmpchar = NULL;
+ }
+ if ( tmpchar && 0 < tmpchar->characterWidth ) {
+ instance->forceConstantMetrics->leftSideBearing = tmpchar->leftSideBearing;
+ instance->forceConstantMetrics->rightSideBearing = tmpchar->rightSideBearing;
+ instance->forceConstantMetrics->characterWidth = tmpchar->characterWidth;
+ instance->forceConstantMetrics->ascent = tmpchar->ascent;
+ instance->forceConstantMetrics->descent = tmpchar->descent;
+ instance->forceConstantMetrics->attributes = tmpchar->attributes;
+ }
+ else {
+ instance->forceConstantMetrics->leftSideBearing = force_c_lsb;
+ instance->forceConstantMetrics->rightSideBearing = force_c_rsb;
+ instance->forceConstantMetrics->characterWidth = force_c_width;
+ instance->forceConstantMetrics->ascent = ascent;
+ instance->forceConstantMetrics->descent = descent;
+ instance->forceConstantMetrics->attributes = force_c_rawWidth;
+ }
+ /* Check code 0 */
+ if( FreeTypeInstanceGetGlyph(font->zero_idx, FT_FORCE_CONSTANT_SPACING,
+ &tmpglyph, font->instance) != Successful
+ || tmpglyph == NULL)
+ if( FreeTypeInstanceGetGlyph(font->zero_idx, FT_FORCE_CONSTANT_SPACING | FT_GET_DUMMY,
+ &tmpglyph, font->instance)
+ != Successful )
+ tmpglyph = NULL;
+ if ( !tmpglyph ) {
+ xrc = AllocError;
+ goto quit;
+ }
+ }
+ }
+ else{
+
+ /*
+ * CACHED VALUES
+ */
+
+ width = instance->charcellMetrics->characterWidth;
+ ascent = instance->charcellMetrics->ascent;
+ descent = instance->charcellMetrics->descent;
+ rawWidth = instance->charcellMetrics->attributes;
+ maxRsb = instance->charcellMetrics->rightSideBearing;
+ minLsb = instance->charcellMetrics->leftSideBearing;
+ averageWidth = instance->averageWidth;
+ rawAverageWidth = instance->rawAverageWidth;
+
+ }
+
+ /*
+ * SET maxbounds, minbounds ...
+ */
+
+ if( !charcell ) { /* NOT CHARCELL */
+ if( info ){
+ /*
+ Calculate all glyphs' metrics.
+ maxbounds.ascent and maxbounds.descent are quite important values
+ for XAA. If ascent/descent of each glyph exceeds
+ maxbounds.ascent/maxbounds.descent, XAA causes SERVER CRASH.
+ Therefore, THIS MUST BE DONE.
+ */
+ ft_compute_bounds(font,info,vals);
+ }
+ }
+ else{ /* CHARCELL */
+
+ /*
+ * SET CALCULATED OR CACHED VARIABLES
+ */
+
+ vals->width = averageWidth;
+
+ if( info ){
+
+ info->maxbounds.leftSideBearing = minLsb;
+ info->maxbounds.rightSideBearing = maxRsb;
+ info->maxbounds.characterWidth = width;
+ info->maxbounds.ascent = ascent;
+ info->maxbounds.descent = descent;
+ info->maxbounds.attributes =
+ (unsigned short)(short)rawWidth;
+
+ info->minbounds = info->maxbounds;
+ }
+ }
+
+ /* set info */
+
+ if( info ){
+ /*
+ info->fontAscent = ascent;
+ info->fontDescent = descent;
+ */
+ info->fontAscent = info->maxbounds.ascent;
+ info->fontDescent = info->maxbounds.descent;
+ /* Glyph metrics are accurate */
+ info->inkMetrics=1;
+
+ memcpy((char *)&info->ink_maxbounds,
+ (char *)&info->maxbounds, sizeof(xCharInfo));
+ memcpy((char *)&info->ink_minbounds,
+ (char *)&info->minbounds, sizeof(xCharInfo));
+
+ /* XXX - hack */
+ info->defaultCh=0;
+
+ /* Set the pInfo flags */
+ /* Properties set by FontComputeInfoAccelerators:
+ pInfo->noOverlap;
+ pInfo->terminalFont;
+ pInfo->constantMetrics;
+ pInfo->constantWidth;
+ pInfo->inkInside;
+ */
+ /* from lib/font/util/fontaccel.c */
+ FontComputeInfoAccelerators(info);
+ }
+
+ if(xf)
+ xf->fontPrivate = (void*)font;
+
+ if(info) {
+ xrc = FreeTypeAddProperties(font, vals, info, entry->name.name,
+ rawAverageWidth, font_properties);
+ if (xrc != Successful) {
+ goto quit;
+ }
+ }
+
+ quit:
+ if ( dynStrTTCapCodeRange ) free(dynStrTTCapCodeRange);
+ if ( dynStrFTFileName ) free(dynStrFTFileName);
+ if ( dynStrRealFileName ) free(dynStrRealFileName);
+ if ( xrc != Successful ) {
+ if( font ){
+ if( face && font->instance == NULL ) FreeTypeFreeFace(face);
+ FreeTypeFreeFont(font);
+ }
+ }
+ return xrc;
+}
+
+/* Routines used by X11 to get info and glyphs from the font. */
+
+static int
+FreeTypeGetMetrics(FontPtr pFont, unsigned long count, unsigned char *chars,
+ FontEncoding charEncoding, unsigned long *metricCount,
+ xCharInfo **metrics)
+{
+ unsigned int code = 0;
+ int flags = 0;
+ FTFontPtr tf;
+ struct TTCapInfo *ttcap;
+ xCharInfo **mp, *m;
+
+ /* MUMBLE("Get metrics for %ld characters\n", count);*/
+
+ tf = (FTFontPtr)pFont->fontPrivate;
+ ttcap = &tf->instance->ttcap;
+ mp = metrics;
+
+ while (count-- > 0) {
+ switch (charEncoding) {
+ case Linear8Bit:
+ case TwoD8Bit:
+ code = *chars++;
+ break;
+ case Linear16Bit:
+ case TwoD16Bit:
+ code = (*chars++ << 8);
+ code |= *chars++;
+ /* */
+ if ( !(ttcap->flags & TTCAP_FORCE_C_OUTSIDE) ) {
+ if ( (int)code <= ttcap->forceConstantSpacingEnd
+ && ttcap->forceConstantSpacingBegin <= (int)code )
+ flags|=FT_FORCE_CONSTANT_SPACING;
+ else flags=0;
+ }
+ else { /* for GB18030 proportional */
+ if ( (int)code <= ttcap->forceConstantSpacingEnd
+ || ttcap->forceConstantSpacingBegin <= (int)code )
+ flags|=FT_FORCE_CONSTANT_SPACING;
+ else flags=0;
+ }
+ break;
+ }
+
+ if(FreeTypeFontGetGlyphMetrics(code, flags, &m, tf) == Successful && m!=NULL) {
+ *mp++ = m;
+ }
+#ifdef X_ACCEPTS_NO_SUCH_CHAR
+ else *mp++ = &noSuchChar.metrics;
+#endif
+ }
+
+ *metricCount = mp - metrics;
+ return Successful;
+}
+
+static int
+FreeTypeGetGlyphs(FontPtr pFont, unsigned long count, unsigned char *chars,
+ FontEncoding charEncoding, unsigned long *glyphCount,
+ CharInfoPtr *glyphs)
+{
+ unsigned int code = 0;
+ int flags = 0;
+ FTFontPtr tf;
+ CharInfoPtr *gp;
+ CharInfoPtr g;
+ struct TTCapInfo *ttcap;
+
+ tf = (FTFontPtr)pFont->fontPrivate;
+ ttcap = &tf->instance->ttcap;
+ gp = glyphs;
+
+ while (count-- > 0) {
+ switch (charEncoding) {
+ case Linear8Bit: case TwoD8Bit:
+ code = *chars++;
+ break;
+ case Linear16Bit: case TwoD16Bit:
+ code = *chars++ << 8;
+ code |= *chars++;
+ /* */
+ if ( !(ttcap->flags & TTCAP_FORCE_C_OUTSIDE) ) {
+ if ( (int)code <= ttcap->forceConstantSpacingEnd
+ && ttcap->forceConstantSpacingBegin <= (int)code )
+ flags|=FT_FORCE_CONSTANT_SPACING;
+ else flags=0;
+ }
+ else { /* for GB18030 proportional */
+ if ( (int)code <= ttcap->forceConstantSpacingEnd
+ || ttcap->forceConstantSpacingBegin <= (int)code )
+ flags|=FT_FORCE_CONSTANT_SPACING;
+ else flags=0;
+ }
+ break;
+ }
+
+ if(FreeTypeFontGetGlyph(code, flags, &g, tf) == Successful && g!=NULL) {
+ *gp++ = g;
+ }
+#ifdef X_ACCEPTS_NO_SUCH_CHAR
+ else {
+#ifdef XAA_ACCEPTS_NULL_BITS
+ *gp++ = &noSuchChar;
+#else
+ if ( tf->dummy_char.bits ) {
+ *gp++ = &tf->dummy_char;
+ }
+ else {
+ char *raster = NULL;
+ int wd_actual, ht_actual, wd, ht, bpr;
+ wd_actual = tf->info->maxbounds.rightSideBearing - tf->info->maxbounds.leftSideBearing;
+ ht_actual = tf->info->maxbounds.ascent + tf->info->maxbounds.descent;
+ if(wd_actual <= 0) wd = 1;
+ else wd=wd_actual;
+ if(ht_actual <= 0) ht = 1;
+ else ht=ht_actual;
+ bpr = (((wd + (tf->instance->bmfmt.glyph<<3) - 1) >> 3) &
+ -tf->instance->bmfmt.glyph);
+ raster = calloc(1, ht * bpr);
+ if(raster) {
+ tf->dummy_char.bits = raster;
+ *gp++ = &tf->dummy_char;
+ }
+ }
+#endif
+ }
+#endif
+ }
+
+ *glyphCount = gp - glyphs;
+ return Successful;
+}
+
+static int
+FreeTypeSetUpFont(FontPathElementPtr fpe, FontPtr xf, FontInfoPtr info,
+ fsBitmapFormat format, fsBitmapFormatMask fmask,
+ FontBitmapFormatPtr bmfmt)
+{
+ int xrc;
+ int image;
+
+ /* Get the default bitmap format information for this X installation.
+ Also update it for the client if running in the font server. */
+ FontDefaultFormat(&bmfmt->bit, &bmfmt->byte, &bmfmt->glyph, &bmfmt->scan);
+ if ((xrc = CheckFSFormat(format, fmask, &bmfmt->bit, &bmfmt->byte,
+ &bmfmt->scan, &bmfmt->glyph,
+ &image)) != Successful) {
+ MUMBLE("Aborting after checking FS format: %d\n", xrc);
+ return xrc;
+ }
+
+ if(xf) {
+ xf->refcnt = 0;
+ xf->bit = bmfmt->bit;
+ xf->byte = bmfmt->byte;
+ xf->glyph = bmfmt->glyph;
+ xf->scan = bmfmt->scan;
+ xf->format = format;
+ xf->get_glyphs = FreeTypeGetGlyphs;
+ xf->get_metrics = FreeTypeGetMetrics;
+ xf->unload_font = FreeTypeUnloadXFont;
+ xf->unload_glyphs = 0;
+ xf->fpe = fpe;
+ xf->svrPrivate = 0;
+ xf->fontPrivate = 0; /* we'll set it later */
+ xf->fpePrivate = 0;
+ }
+
+ info->defaultCh = 0;
+ info->noOverlap = 0; /* not updated */
+ info->terminalFont = 0; /* not updated */
+ info->constantMetrics = 0; /* we'll set it later */
+ info->constantWidth = 0; /* we'll set it later */
+ info->inkInside = 1;
+ info->inkMetrics = 1;
+ info->allExist=0; /* not updated */
+ info->drawDirection = LeftToRight; /* we'll set it later */
+ info->cachable = 1; /* we don't do licensing */
+ info->anamorphic = 0; /* can hinting lead to anamorphic scaling? */
+ info->maxOverlap = 0; /* we'll set it later. */
+ info->pad = 0; /* ??? */
+ return Successful;
+}
+
+/* Functions exported by the backend */
+
+static int
+FreeTypeOpenScalable(FontPathElementPtr fpe, FontPtr *ppFont, int flags,
+ FontEntryPtr entry, char *fileName, FontScalablePtr vals,
+ fsBitmapFormat format, fsBitmapFormatMask fmask,
+ FontPtr non_cachable_font)
+{
+ int xrc;
+ FontPtr xf;
+ FontBitmapFormatRec bmfmt;
+
+ MUMBLE("Open Scalable %s, XLFD=%s\n",fileName, entry->name.length ? entry->name.name : "");
+
+ xf = CreateFontRec();
+ if (xf == NULL)
+ return AllocError;
+
+ xrc = FreeTypeSetUpFont(fpe, xf, &xf->info, format, fmask, &bmfmt);
+ if(xrc != Successful) {
+ DestroyFontRec(xf);
+ return xrc;
+ }
+ xrc = FreeTypeLoadXFont(fileName, vals, xf, &xf->info, &bmfmt, entry);
+ if(xrc != Successful) {
+ MUMBLE("Error during load: %d\n",xrc);
+ DestroyFontRec(xf);
+ return xrc;
+ }
+
+ *ppFont = xf;
+
+ return xrc;
+}
+
+/* Routine to get requested font info. */
+
+static int
+FreeTypeGetInfoScalable(FontPathElementPtr fpe, FontInfoPtr info,
+ FontEntryPtr entry, FontNamePtr fontName,
+ char *fileName, FontScalablePtr vals)
+{
+ int xrc;
+ FontBitmapFormatRec bmfmt;
+
+ MUMBLE("Get info, XLFD=%s\n", entry->name.length ? entry->name.name : "");
+
+ xrc = FreeTypeSetUpFont(fpe, 0, info, 0, 0, &bmfmt);
+ if(xrc != Successful) {
+ return xrc;
+ }
+
+ bmfmt.glyph <<= 3;
+
+ xrc = FreeTypeLoadXFont(fileName, vals, 0, info, &bmfmt, entry);
+ if(xrc != Successful) {
+ MUMBLE("Error during load: %d\n", xrc);
+ return xrc;
+ }
+
+ return Successful;
+}
+
+/* Renderer registration. */
+
+/* Set the capabilities of this renderer. */
+#define CAPABILITIES (CAP_CHARSUBSETTING | CAP_MATRIX)
+
+/* Set it up so file names with either upper or lower case can be
+ loaded. We don't support compressed fonts. */
+static FontRendererRec renderers[] = {
+ {".ttf", 4, 0, FreeTypeOpenScalable, 0,
+ FreeTypeGetInfoScalable, 0, CAPABILITIES},
+ {".ttc", 4, 0, FreeTypeOpenScalable, 0,
+ FreeTypeGetInfoScalable, 0, CAPABILITIES},
+ {".otf", 4, 0, FreeTypeOpenScalable, 0,
+ FreeTypeGetInfoScalable, 0, CAPABILITIES},
+ {".otc", 4, 0, FreeTypeOpenScalable, 0,
+ FreeTypeGetInfoScalable, 0, CAPABILITIES},
+ {".pfa", 4, 0, FreeTypeOpenScalable, 0,
+ FreeTypeGetInfoScalable, 0, CAPABILITIES},
+ {".pfb", 4, 0, FreeTypeOpenScalable, 0,
+ FreeTypeGetInfoScalable, 0, CAPABILITIES},
+};
+static int num_renderers = sizeof(renderers) / sizeof(renderers[0]);
+
+static FontRendererRec alt_renderers[] = {
+ {".bdf", 4, 0, FreeTypeOpenScalable, 0,
+ FreeTypeGetInfoScalable, 0, CAPABILITIES},
+ {".pcf", 4, 0, FreeTypeOpenScalable, 0,
+ FreeTypeGetInfoScalable, 0, CAPABILITIES},
+};
+
+static int num_alt_renderers =
+sizeof(alt_renderers) / sizeof(alt_renderers[0]);
+
+
+void
+FreeTypeRegisterFontFileFunctions(void)
+{
+ int i;
+
+ for (i = 0; i < num_renderers; i++)
+ FontFileRegisterRenderer(&renderers[i]);
+
+ for (i = 0; i < num_alt_renderers; i++)
+ FontFilePriorityRegisterRenderer(&alt_renderers[i], -10);
+}
diff --git a/libXfont/src/FreeType/ftfuncs.h b/libXfont/src/FreeType/ftfuncs.h
index e522dded8..a39271e1c 100644
--- a/libXfont/src/FreeType/ftfuncs.h
+++ b/libXfont/src/FreeType/ftfuncs.h
@@ -1,190 +1,189 @@
-/*
-Copyright (c) 1998-2002 by Juliusz Chroboczek
-Copyright (c) 2003 After X-TT Project, All rights reserved.
-
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in
-all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-THE SOFTWARE.
-*/
-/* $XFree86: xc/lib/font/FreeType/ftfuncs.h,v 1.17 2003/12/21 04:02:07 dawes Exp $ */
-
-/* Number of buckets in the hashtable holding faces */
-#define NUMFACEBUCKETS 32
-
-/* Glyphs are held in segments of this size */
-#define FONTSEGMENTSIZE 16
-
-/* A structure that holds bitmap order and padding info. */
-
-typedef struct {
- int bit; /* bit order */
- int byte; /* byte order */
- int glyph; /* glyph pad size */
- int scan; /* machine word size */
-} FontBitmapFormatRec, *FontBitmapFormatPtr;
-
-struct FTSize_s;
-
-/* At the lowest level, there is face; FTFaces are in one-to-one
- correspondence with TrueType faces. Multiple instance may share
- the same face. */
-
-typedef struct _FTFace {
- char *filename;
- FT_Face face;
- int bitmap;
- FT_UInt num_hmetrics;
- struct _FTInstance *instances;
- struct _FTInstance *active_instance;
- struct _FTFace *next; /* link to next face in bucket */
-} FTFaceRec, *FTFacePtr;
-
-/* A transformation matrix with resolution information */
-typedef struct _FTNormalisedTransformation {
- double scale;
- int nonIdentity; /* if 0, matrix is the identity */
- FT_Matrix matrix;
- int xres, yres;
-} FTNormalisedTransformationRec, *FTNormalisedTransformationPtr;
-
-#define FT_PROPORTIONAL 0
-#define FT_MONOSPACED 1
-#define FT_CHARCELL 2
-
-#define FT_AVAILABLE_UNKNOWN 0
-#define FT_AVAILABLE_NO 1
-#define FT_AVAILABLE_METRICS 2
-#define FT_AVAILABLE_RASTERISED 3
-
-#define FT_GET_GLYPH_BOTH 0x01
-#define FT_GET_GLYPH_METRICS_ONLY 0x02
-#define FT_GET_DUMMY 0x04
-#define FT_FORCE_CONSTANT_SPACING 0x08
-
-#define TTCAP_DOUBLE_STRIKE 0x0001
-#define TTCAP_DOUBLE_STRIKE_MKBOLD_EDGE_LEFT 0x0002
-#define TTCAP_DOUBLE_STRIKE_CORRECT_B_BOX_WIDTH 0x0008
-#define TTCAP_IS_VERY_LAZY 0x0010
-#define TTCAP_DISABLE_DEFAULT_VERY_LAZY 0x0020
-#define TTCAP_FORCE_C_LSB_FLAG 0x0100
-#define TTCAP_FORCE_C_RSB_FLAG 0x0200
-#define TTCAP_FORCE_C_OUTSIDE 0x0400
-#define TTCAP_MONO_CENTER 0x0800
-
-/* TTCap */
-struct TTCapInfo {
- long flags;
- double autoItalic;
- double scaleWidth;
- double scaleBBoxWidth;
- double scaleBBoxHeight;
- int doubleStrikeShift;
- int adjustBBoxWidthByPixel;
- int adjustLeftSideBearingByPixel;
- int adjustRightSideBearingByPixel;
- double scaleBitmap;
- int forceConstantSpacingBegin;
- int forceConstantSpacingEnd;
- /* We don't compare */
- int force_c_adjust_width_by_pixel;
- int force_c_adjust_lsb_by_pixel;
- int force_c_adjust_rsb_by_pixel;
- int force_c_representative_metrics_char_code;
- double force_c_scale_b_box_width;
- double force_c_scale_b_box_height;
- double force_c_scale_lsb;
- double force_c_scale_rsb;
- double vl_slant;
- int lsbShiftOfBitmapAutoItalic;
- int rsbShiftOfBitmapAutoItalic;
-};
-
-/* An instance builds on a face by specifying the transformation
- matrix. Multiple fonts may share the same instance. */
-
-/* This structure caches bitmap data */
-typedef struct _FTInstance {
- FTFacePtr face; /* the associated face */
- FT_Size size;
- FTNormalisedTransformationRec transformation;
- FT_Int32 load_flags;
- FT_ULong strike_index;
- int spacing; /* actual spacing */
- double pixel_size; /* to calc attributes (actual height) */
- double pixel_width_unit_x; /* to calc horiz. width (cosine) */
- double pixel_width_unit_y; /* to calc vert. width (cosine) */
- xCharInfo *charcellMetrics; /* the header's metrics */
- int averageWidth; /* the header's metrics */
- long rawAverageWidth; /* the header's metrics */
- double advance; /* the header's metrics */
- xCharInfo *forceConstantMetrics;
- FontBitmapFormatRec bmfmt;
- unsigned nglyphs;
- CharInfoPtr *glyphs; /* glyphs and available are used in parallel */
- int **available;
- struct TTCapInfo ttcap;
- int refcount;
- struct _FTInstance *next; /* link to next instance */
-} FTInstanceRec, *FTInstancePtr;
-
-/* A font is an instance with coding information; fonts are in
- one-to-one correspondence with X fonts */
-typedef struct _FTFont{
- FTInstancePtr instance;
- FTMappingRec mapping;
- unsigned zero_idx;
- FontInfoPtr info;
- int nranges;
- CharInfoRec dummy_char;
- fsRange *ranges;
-} FTFontRec, *FTFontPtr;
-
-#ifndef NOT_IN_FTFUNCS
-
-/* Prototypes for some local functions */
-
-static int FreeTypeOpenFace(FTFacePtr *facep, char *FTFileName, char *realFileName, int faceNumber);
-static void FreeTypeFreeFace(FTFacePtr face);
-static int
-FreeTypeOpenInstance(FTInstancePtr *instancep, FTFacePtr face,
- char *FTFileName, FTNormalisedTransformationPtr trans,
- int spacing, FontBitmapFormatPtr bmfmt,
- struct TTCapInfo *tmp_ttcap, FT_Int32 load_flags);
-static void FreeTypeFreeInstance(FTInstancePtr instance);
-static int
-FreeTypeInstanceGetGlyph(unsigned idx, int flags, CharInfoPtr *g, FTInstancePtr instance);
-static int
-FreeTypeInstanceGetGlyphMetrics(unsigned idx, int flags,
- xCharInfo **metrics, FTInstancePtr instance );
-static int
-FreeTypeRasteriseGlyph(unsigned idx, int flags, CharInfoPtr tgp,
- FTInstancePtr instance, int hasMetrics );
-static void FreeTypeFreeFont(FTFontPtr font);
-static void FreeTypeFreeXFont(FontPtr pFont, int freeProps);
-static void FreeTypeUnloadXFont(FontPtr pFont);
-static int
-FreeTypeAddProperties(FTFontPtr font, FontScalablePtr vals, FontInfoPtr info,
- char *fontname, int rawAverageWidth, Bool font_properties);
-static int FreeTypeFontGetGlyph(unsigned code, int flags, CharInfoPtr *g, FTFontPtr font);
-static int
-FreeTypeLoadFont(FTFontPtr font, FontInfoPtr info, FTFacePtr face,
- char *FTFileName, FontScalablePtr vals, FontEntryPtr entry,
- FontBitmapFormatPtr bmfmt, FT_Int32 load_flags,
- struct TTCapInfo *tmp_ttcap, char *dynStrTTCapCodeRange,
- int ttcap_spacing );
-
-#endif /* NOT_IN_FTFUNCS */
+/*
+Copyright (c) 1998-2002 by Juliusz Chroboczek
+Copyright (c) 2003 After X-TT Project, All rights reserved.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
+*/
+
+/* Number of buckets in the hashtable holding faces */
+#define NUMFACEBUCKETS 32
+
+/* Glyphs are held in segments of this size */
+#define FONTSEGMENTSIZE 16
+
+/* A structure that holds bitmap order and padding info. */
+
+typedef struct {
+ int bit; /* bit order */
+ int byte; /* byte order */
+ int glyph; /* glyph pad size */
+ int scan; /* machine word size */
+} FontBitmapFormatRec, *FontBitmapFormatPtr;
+
+struct FTSize_s;
+
+/* At the lowest level, there is face; FTFaces are in one-to-one
+ correspondence with TrueType faces. Multiple instance may share
+ the same face. */
+
+typedef struct _FTFace {
+ char *filename;
+ FT_Face face;
+ int bitmap;
+ FT_UInt num_hmetrics;
+ struct _FTInstance *instances;
+ struct _FTInstance *active_instance;
+ struct _FTFace *next; /* link to next face in bucket */
+} FTFaceRec, *FTFacePtr;
+
+/* A transformation matrix with resolution information */
+typedef struct _FTNormalisedTransformation {
+ double scale;
+ int nonIdentity; /* if 0, matrix is the identity */
+ FT_Matrix matrix;
+ int xres, yres;
+} FTNormalisedTransformationRec, *FTNormalisedTransformationPtr;
+
+#define FT_PROPORTIONAL 0
+#define FT_MONOSPACED 1
+#define FT_CHARCELL 2
+
+#define FT_AVAILABLE_UNKNOWN 0
+#define FT_AVAILABLE_NO 1
+#define FT_AVAILABLE_METRICS 2
+#define FT_AVAILABLE_RASTERISED 3
+
+#define FT_GET_GLYPH_BOTH 0x01
+#define FT_GET_GLYPH_METRICS_ONLY 0x02
+#define FT_GET_DUMMY 0x04
+#define FT_FORCE_CONSTANT_SPACING 0x08
+
+#define TTCAP_DOUBLE_STRIKE 0x0001
+#define TTCAP_DOUBLE_STRIKE_MKBOLD_EDGE_LEFT 0x0002
+#define TTCAP_DOUBLE_STRIKE_CORRECT_B_BOX_WIDTH 0x0008
+#define TTCAP_IS_VERY_LAZY 0x0010
+#define TTCAP_DISABLE_DEFAULT_VERY_LAZY 0x0020
+#define TTCAP_FORCE_C_LSB_FLAG 0x0100
+#define TTCAP_FORCE_C_RSB_FLAG 0x0200
+#define TTCAP_FORCE_C_OUTSIDE 0x0400
+#define TTCAP_MONO_CENTER 0x0800
+
+/* TTCap */
+struct TTCapInfo {
+ long flags;
+ double autoItalic;
+ double scaleWidth;
+ double scaleBBoxWidth;
+ double scaleBBoxHeight;
+ int doubleStrikeShift;
+ int adjustBBoxWidthByPixel;
+ int adjustLeftSideBearingByPixel;
+ int adjustRightSideBearingByPixel;
+ double scaleBitmap;
+ int forceConstantSpacingBegin;
+ int forceConstantSpacingEnd;
+ /* We don't compare */
+ int force_c_adjust_width_by_pixel;
+ int force_c_adjust_lsb_by_pixel;
+ int force_c_adjust_rsb_by_pixel;
+ int force_c_representative_metrics_char_code;
+ double force_c_scale_b_box_width;
+ double force_c_scale_b_box_height;
+ double force_c_scale_lsb;
+ double force_c_scale_rsb;
+ double vl_slant;
+ int lsbShiftOfBitmapAutoItalic;
+ int rsbShiftOfBitmapAutoItalic;
+};
+
+/* An instance builds on a face by specifying the transformation
+ matrix. Multiple fonts may share the same instance. */
+
+/* This structure caches bitmap data */
+typedef struct _FTInstance {
+ FTFacePtr face; /* the associated face */
+ FT_Size size;
+ FTNormalisedTransformationRec transformation;
+ FT_Int32 load_flags;
+ FT_ULong strike_index;
+ int spacing; /* actual spacing */
+ double pixel_size; /* to calc attributes (actual height) */
+ double pixel_width_unit_x; /* to calc horiz. width (cosine) */
+ double pixel_width_unit_y; /* to calc vert. width (cosine) */
+ xCharInfo *charcellMetrics; /* the header's metrics */
+ int averageWidth; /* the header's metrics */
+ long rawAverageWidth; /* the header's metrics */
+ double advance; /* the header's metrics */
+ xCharInfo *forceConstantMetrics;
+ FontBitmapFormatRec bmfmt;
+ unsigned nglyphs;
+ CharInfoPtr *glyphs; /* glyphs and available are used in parallel */
+ int **available;
+ struct TTCapInfo ttcap;
+ int refcount;
+ struct _FTInstance *next; /* link to next instance */
+} FTInstanceRec, *FTInstancePtr;
+
+/* A font is an instance with coding information; fonts are in
+ one-to-one correspondence with X fonts */
+typedef struct _FTFont{
+ FTInstancePtr instance;
+ FTMappingRec mapping;
+ unsigned zero_idx;
+ FontInfoPtr info;
+ int nranges;
+ CharInfoRec dummy_char;
+ fsRange *ranges;
+} FTFontRec, *FTFontPtr;
+
+#ifndef NOT_IN_FTFUNCS
+
+/* Prototypes for some local functions */
+
+static int FreeTypeOpenFace(FTFacePtr *facep, char *FTFileName, char *realFileName, int faceNumber);
+static void FreeTypeFreeFace(FTFacePtr face);
+static int
+FreeTypeOpenInstance(FTInstancePtr *instancep, FTFacePtr face,
+ char *FTFileName, FTNormalisedTransformationPtr trans,
+ int spacing, FontBitmapFormatPtr bmfmt,
+ struct TTCapInfo *tmp_ttcap, FT_Int32 load_flags);
+static void FreeTypeFreeInstance(FTInstancePtr instance);
+static int
+FreeTypeInstanceGetGlyph(unsigned idx, int flags, CharInfoPtr *g, FTInstancePtr instance);
+static int
+FreeTypeInstanceGetGlyphMetrics(unsigned idx, int flags,
+ xCharInfo **metrics, FTInstancePtr instance );
+static int
+FreeTypeRasteriseGlyph(unsigned idx, int flags, CharInfoPtr tgp,
+ FTInstancePtr instance, int hasMetrics );
+static void FreeTypeFreeFont(FTFontPtr font);
+static void FreeTypeFreeXFont(FontPtr pFont, int freeProps);
+static void FreeTypeUnloadXFont(FontPtr pFont);
+static int
+FreeTypeAddProperties(FTFontPtr font, FontScalablePtr vals, FontInfoPtr info,
+ char *fontname, int rawAverageWidth, Bool font_properties);
+static int FreeTypeFontGetGlyph(unsigned code, int flags, CharInfoPtr *g, FTFontPtr font);
+static int
+FreeTypeLoadFont(FTFontPtr font, FontInfoPtr info, FTFacePtr face,
+ char *FTFileName, FontScalablePtr vals, FontEntryPtr entry,
+ FontBitmapFormatPtr bmfmt, FT_Int32 load_flags,
+ struct TTCapInfo *tmp_ttcap, char *dynStrTTCapCodeRange,
+ int ttcap_spacing );
+
+#endif /* NOT_IN_FTFUNCS */
diff --git a/libXfont/src/FreeType/fttools.c b/libXfont/src/FreeType/fttools.c
index 7277273fd..24e78ce24 100644
--- a/libXfont/src/FreeType/fttools.c
+++ b/libXfont/src/FreeType/fttools.c
@@ -1,142 +1,140 @@
-/*
- Copyright (c) 1997 by Mark Leisher
- Copyright (c) 1998-2002 by Juliusz Chroboczek
-
- Permission is hereby granted, free of charge, to any person obtaining a copy
- of this software and associated documentation files (the "Software"), to deal
- in the Software without restriction, including without limitation the rights
- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- copies of the Software, and to permit persons to whom the Software is
- furnished to do so, subject to the following conditions:
-
- The above copyright notice and this permission notice shall be included in
- all copies or substantial portions of the Software.
-
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- THE SOFTWARE.
-*/
-
-/* $XFree86: xc/lib/font/FreeType/fttools.c,v 1.6 2003/06/08 15:41:13 herrb Exp $ */
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-#include <X11/fonts/fontmisc.h>
-#include <ctype.h>
-#include <string.h>
-
-#include <X11/fonts/font.h>
-#include <ft2build.h>
-#include FT_FREETYPE_H
-#include FT_SFNT_NAMES_H
-#include FT_TRUETYPE_IDS_H
-#include "ft.h"
-
-#ifndef LSBFirst
-#define LSBFirst 0
-#define MSBFirst 1
-#endif
-
-#define LOBYTE(s,byte) ((byte)==LSBFirst?*(char*)(s):*((char*)(s)+1))
-#define HIBYTE(s,byte) ((byte)==LSBFirst?*((char*)(s)+1):*(char*)(s))
-
-int FTtoXReturnCode(int rc)
-{
- if(rc == 0x40)
- return AllocError;
- /* Anything else stops the font matching mechanism */
- else return BadFontName;
-
-}
-
-/* Convert slen bytes from UCS-2 to ISO 8859-1. Byte specifies the
- endianness of the string, max the maximum number of bytes written into
- to. */
-static int
-FTu2a(int slen, FT_Byte *from, char *to, int byte, int max)
-{
- int i, n;
-
- n = 0;
- for (i = 0; i < slen; i += 2) {
- if(n >= max - 1)
- break;
- if(HIBYTE(from+i, byte)!=0)
- *to++='?';
- else
- *to++ = LOBYTE(from+i,byte);
- n++;
- }
- *to = 0;
- return n;
-}
-
-static int
-FTGetName(FT_Face face, int nid, int pid, int eid, FT_SfntName *name_return)
-{
- FT_SfntName name;
- int n, i;
-
- n = FT_Get_Sfnt_Name_Count(face);
- if(n <= 0)
- return 0;
-
- for(i = 0; i < n; i++) {
- if(FT_Get_Sfnt_Name(face, i, &name))
- continue;
- if(name.name_id == nid &&
- name.platform_id == pid &&
- (eid < 0 || name.encoding_id == eid)) {
- switch(name.platform_id) {
- case TT_PLATFORM_APPLE_UNICODE:
- case TT_PLATFORM_MACINTOSH:
- if(name.language_id != TT_MAC_LANGID_ENGLISH)
- continue;
- break;
- case TT_PLATFORM_MICROSOFT:
- if(name.language_id != TT_MS_LANGID_ENGLISH_UNITED_STATES &&
- name.language_id != TT_MS_LANGID_ENGLISH_UNITED_KINGDOM)
- break;
- continue;
- break;
- default:
- break;
- }
- *name_return = name;
- return 1;
- }
- }
- return 0;
-}
-
-int
-FTGetEnglishName(FT_Face face, int nid, char *name_return, int name_len)
-{
- FT_SfntName name;
- int len;
-
- if(FTGetName(face, nid,
- TT_PLATFORM_MICROSOFT, TT_MS_ID_UNICODE_CS, &name) ||
- FTGetName(face, nid,
- TT_PLATFORM_APPLE_UNICODE, -1, &name))
- return FTu2a(name.string_len, name.string, name_return,
- MSBFirst, name_len);
-
- /* Pretend that Apple Roman is ISO 8859-1. */
- if(FTGetName(face, nid, TT_PLATFORM_MACINTOSH, TT_MAC_ID_ROMAN, &name)) {
- len = name.string_len;
- if(len > name_len - 1)
- len = name_len - 1;
- memcpy(name_return, name.string, len);
- name_return[len] = '\0'; /* ensure nul terminaison */
- return len;
- }
-
- /* Must be some font that can only be named in Polish or something. */
- return -1;
-}
+/*
+ Copyright (c) 1997 by Mark Leisher
+ Copyright (c) 1998-2002 by Juliusz Chroboczek
+
+ Permission is hereby granted, free of charge, to any person obtaining a copy
+ of this software and associated documentation files (the "Software"), to deal
+ in the Software without restriction, including without limitation the rights
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ copies of the Software, and to permit persons to whom the Software is
+ furnished to do so, subject to the following conditions:
+
+ The above copyright notice and this permission notice shall be included in
+ all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ THE SOFTWARE.
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include <X11/fonts/fontmisc.h>
+#include <ctype.h>
+#include <string.h>
+
+#include <X11/fonts/font.h>
+#include <ft2build.h>
+#include FT_FREETYPE_H
+#include FT_SFNT_NAMES_H
+#include FT_TRUETYPE_IDS_H
+#include "ft.h"
+
+#ifndef LSBFirst
+#define LSBFirst 0
+#define MSBFirst 1
+#endif
+
+#define LOBYTE(s,byte) ((byte)==LSBFirst?*(char*)(s):*((char*)(s)+1))
+#define HIBYTE(s,byte) ((byte)==LSBFirst?*((char*)(s)+1):*(char*)(s))
+
+int FTtoXReturnCode(int rc)
+{
+ if(rc == 0x40)
+ return AllocError;
+ /* Anything else stops the font matching mechanism */
+ else return BadFontName;
+
+}
+
+/* Convert slen bytes from UCS-2 to ISO 8859-1. Byte specifies the
+ endianness of the string, max the maximum number of bytes written into
+ to. */
+static int
+FTu2a(int slen, FT_Byte *from, char *to, int byte, int max)
+{
+ int i, n;
+
+ n = 0;
+ for (i = 0; i < slen; i += 2) {
+ if(n >= max - 1)
+ break;
+ if(HIBYTE(from+i, byte)!=0)
+ *to++='?';
+ else
+ *to++ = LOBYTE(from+i,byte);
+ n++;
+ }
+ *to = 0;
+ return n;
+}
+
+static int
+FTGetName(FT_Face face, int nid, int pid, int eid, FT_SfntName *name_return)
+{
+ FT_SfntName name;
+ int n, i;
+
+ n = FT_Get_Sfnt_Name_Count(face);
+ if(n <= 0)
+ return 0;
+
+ for(i = 0; i < n; i++) {
+ if(FT_Get_Sfnt_Name(face, i, &name))
+ continue;
+ if(name.name_id == nid &&
+ name.platform_id == pid &&
+ (eid < 0 || name.encoding_id == eid)) {
+ switch(name.platform_id) {
+ case TT_PLATFORM_APPLE_UNICODE:
+ case TT_PLATFORM_MACINTOSH:
+ if(name.language_id != TT_MAC_LANGID_ENGLISH)
+ continue;
+ break;
+ case TT_PLATFORM_MICROSOFT:
+ if(name.language_id != TT_MS_LANGID_ENGLISH_UNITED_STATES &&
+ name.language_id != TT_MS_LANGID_ENGLISH_UNITED_KINGDOM)
+ break;
+ continue;
+ break;
+ default:
+ break;
+ }
+ *name_return = name;
+ return 1;
+ }
+ }
+ return 0;
+}
+
+int
+FTGetEnglishName(FT_Face face, int nid, char *name_return, int name_len)
+{
+ FT_SfntName name;
+ int len;
+
+ if(FTGetName(face, nid,
+ TT_PLATFORM_MICROSOFT, TT_MS_ID_UNICODE_CS, &name) ||
+ FTGetName(face, nid,
+ TT_PLATFORM_APPLE_UNICODE, -1, &name))
+ return FTu2a(name.string_len, name.string, name_return,
+ MSBFirst, name_len);
+
+ /* Pretend that Apple Roman is ISO 8859-1. */
+ if(FTGetName(face, nid, TT_PLATFORM_MACINTOSH, TT_MAC_ID_ROMAN, &name)) {
+ len = name.string_len;
+ if(len > name_len - 1)
+ len = name_len - 1;
+ memcpy(name_return, name.string, len);
+ name_return[len] = '\0'; /* ensure nul terminaison */
+ return len;
+ }
+
+ /* Must be some font that can only be named in Polish or something. */
+ return -1;
+}
diff --git a/libXfont/src/FreeType/xttcap.c b/libXfont/src/FreeType/xttcap.c
index 89e092b0e..95426f11e 100644
--- a/libXfont/src/FreeType/xttcap.c
+++ b/libXfont/src/FreeType/xttcap.c
@@ -1,706 +1,705 @@
-/* ===EmacsMode: -*- Mode: C; tab-width:4; c-basic-offset: 4; -*- === */
-/* ===FileName: ===
- Copyright (c) 1998 Takuya SHIOZAKI, All Rights reserved.
- Copyright (c) 1998 X-TrueType Server Project, All rights reserved.
- Copyright (c) 2003 After X-TT Project, All rights reserved.
-
-===Notice
- Redistribution and use in source and binary forms, with or without
- modification, are permitted provided that the following conditions
- are met:
- 1. Redistributions of source code must retain the above copyright
- notice, this list of conditions and the following disclaimer.
- 2. Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in the
- documentation and/or other materials provided with the distribution.
-
- THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
- ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
- FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- SUCH DAMAGE.
-
- Major Release ID: X-TrueType Server Version 1.4 [Charles's Wain Release 0]
-
-Notice===
- */
-/* $XFree86: xc/lib/font/FreeType/xttcap.c,v 1.1 2003/10/19 18:53:50 dawes Exp $ */
-
-/*
-#include "xttversion.h"
-
-static char const * const releaseID =
- _XTT_RELEASE_NAME;
-*/
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-#include <X11/fonts/fontmisc.h>
-#include <string.h>
-#include <ctype.h>
-#include <math.h>
-
-#ifndef True
-#define True (-1)
-#endif /* True */
-#ifndef False
-#define False (0)
-#endif /* False */
-
-#include "xttcap.h"
-
-
-/**************************************************************************
- Private Data Types
- */
-
-/* Property Record List */
-/* List Node */
-typedef struct TagSPropRecValListNodeP
-{
- SPropRecValContainerEntityP containerE;
- struct TagSPropRecValListNodeP *nextNode;
-} SPropRecValListNodeP;
-
-
-/**************************************************************************
- Tables
- */
-
-/* valid record field */
-static SPropertyRecord const validRecords[] =
-{
- { "FontFile", eRecTypeString },
- { "FaceNumber", eRecTypeString },
- { "AutoItalic", eRecTypeDouble },
- { "DoubleStrike", eRecTypeString },
- { "FontProperties", eRecTypeBool },
- { "ForceSpacing", eRecTypeString },
- { "ScaleBBoxWidth", eRecTypeString },
- { "ScaleWidth", eRecTypeDouble },
- { "EncodingOptions", eRecTypeString },
- { "Hinting", eRecTypeBool },
- { "VeryLazyMetrics", eRecTypeBool },
- { "CodeRange", eRecTypeString },
- { "EmbeddedBitmap", eRecTypeString },
- { "VeryLazyBitmapWidthScale", eRecTypeDouble },
- { "ForceConstantSpacingCodeRange", eRecTypeString },
- { "ForceConstantSpacingMetrics", eRecTypeString },
- { "Dummy", eRecTypeVoid }
-};
-static int const
-numOfValidRecords = sizeof(validRecords)/sizeof(validRecords[0]);
-
-/* correspondence between record name and cap variable name */
-static struct {
- char const * capVariable;
- char const * recordName;
-} const correspondRelations[] = {
- { "fn", "FaceNumber" },
- { "ai", "AutoItalic" },
- { "ds", "DoubleStrike" },
- { "fp", "FontProperties" },
- { "fs", "ForceSpacing" },
- { "bw", "ScaleBBoxWidth" },
- { "sw", "ScaleWidth" },
- { "eo", "EncodingOptions" },
- { "vl", "VeryLazyMetrics" },
- { "bs", "VeryLazyBitmapWidthScale" },
- { "cr", "CodeRange" },
- { "eb", "EmbeddedBitmap" },
- { "hi", "Hinting" },
- { "fc", "ForceConstantSpacingCodeRange" },
- { "fm", "ForceConstantSpacingMetrics" }
-};
-static int const
-numOfCorrespondRelations
-= sizeof(correspondRelations)/sizeof(correspondRelations[0]);
-
-/**************************************************************************
- Functions
- */
-
-/* get property record type by record name */
-static Bool /* True == Found, False == Not Found */
-get_record_type_by_name(SPropertyRecord const ** const refRefRecord, /*result*/
- char const *strName)
-{
- Bool result = False;
- int i;
-
- *refRefRecord = NULL;
- for (i=0; i<numOfValidRecords; i++) {
- if (!strcasecmp(validRecords[i].strRecordName, strName)) {
- result = True;
- *refRefRecord = &validRecords[i];
- break;
- }
- }
-
- return result;
-}
-
-/* Add Property Record Value */
-static Bool /* True == Error, False == Success */
-SPropRecValList_add_record(SDynPropRecValList *pThisList,
- char const * const recordName,
- char const * const strValue)
-{
- Bool result = False;
- SPropRecValContainerEntityP tmpContainerE;
-
- if (get_record_type_by_name(&tmpContainerE.refRecordType, recordName)) {
- switch (tmpContainerE.refRecordType->recordType) {
- case eRecTypeInteger:
- {
- int val;
- char *endPtr;
-
- val = strtol(strValue, &endPtr, 0);
- if ('\0' != *endPtr) {
- fprintf(stderr,
- "truetype font property : "
- "%s record needs integer value.\n",
- recordName);
- result = True;
- goto quit;
- }
- SPropContainer_value_int(&tmpContainerE) = val;
- }
- break;
- case eRecTypeDouble:
- {
- double val;
- char *endPtr;
-
- val = strtod(strValue, &endPtr);
- if ('\0' != *endPtr) {
- fprintf(stderr,
- "truetype font property : "
- "%s record needs floating point value.\n",
- recordName);
- result = True;
- goto quit;
- }
- SPropContainer_value_dbl(&tmpContainerE) = val;
- }
- break;
- case eRecTypeBool:
- {
- Bool val;
-
- if (!strcasecmp(strValue, "yes"))
- val = True;
- else if (!strcasecmp(strValue, "y"))
- val = True;
- else if (!strcasecmp(strValue, "on"))
- val = True;
- else if (!strcasecmp(strValue, "true"))
- val = True;
- else if (!strcasecmp(strValue, "t"))
- val = True;
- else if (!strcasecmp(strValue, "ok"))
- val = True;
- else if (!strcasecmp(strValue, "no"))
- val = False;
- else if (!strcasecmp(strValue, "n"))
- val = False;
- else if (!strcasecmp(strValue, "off"))
- val = False;
- else if (!strcasecmp(strValue, "false"))
- val = False;
- else if (!strcasecmp(strValue, "f"))
- val = False;
- else if (!strcasecmp(strValue, "bad"))
- val = False;
- else {
- fprintf(stderr,
- "truetype font property : "
- "%s record needs boolean value.\n",
- recordName);
- result = True;
- goto quit;
- }
- SPropContainer_value_bool(&tmpContainerE) = val;
- }
- break;
- case eRecTypeString:
- {
- char *p;
-
- if (NULL == (p = malloc(strlen(strValue)+1))) {
- fprintf(stderr,
- "truetype font property : "
- "cannot allocate memory.\n");
- result = True;
- goto quit;
- }
- strcpy(p, strValue);
- SPropContainer_value_str(&tmpContainerE) = p;
- }
- break;
- case eRecTypeVoid:
- if ('\0' != *strValue) {
- fprintf(stderr,
- "truetype font property : "
- "%s record needs void.\n", recordName);
- result = True;
- }
- break;
- }
- {
- /* add to list */
- SPropRecValListNodeP *newNode;
-
- if (NULL == (newNode = malloc(sizeof(*newNode)))) {
- fprintf(stderr,
- "truetype font property : "
- "cannot allocate memory.\n");
- result = True;
- goto quit;
- }
- newNode->nextNode = pThisList->headNode;
- newNode->containerE = tmpContainerE;
- tmpContainerE.refRecordType = NULL; /* invalidate --
- disown value handle. */
- pThisList->headNode = newNode;
- }
- } else {
- /* invalid record name */
- fprintf(stderr,
- "truetype font : "
- "invalid record name \"%s.\"\n", recordName);
- result = True;
- }
-
- quit:
- return result;
-}
-
-#ifdef USE_TTP_FILE
-
-#ifndef LEN_LINEBUF
-#define LEN_LINEBUF 2048
-#endif /* !def LEN_LINEBUF */
-
-/* get one line */
-static Bool /* True == Error, False == Success */
-get_one_line(FILE *is, char *buf)
-{
- Bool result = False;
- int count = 0;
- Bool flHead = True;
- Bool flSpace = False;
- Bool flInSingleQuote = False;
- Bool flInDoubleQuote = False;
- Bool flBackSlash = False;
- Bool flFirstElement = True;
-
- *buf = '\0';
- for (;;) {
- int c = fgetc(is);
-
- if (ferror(is)) {
- fprintf(stderr, "truetype font property file : read error.\n");
- result = True;
- break;
- }
-
- if (EOF == c) {
- if (flInSingleQuote || flInDoubleQuote) {
- fprintf(stderr,
- "truetype font property file : unmatched quote.\n");
- result = True;
- }
- break;
- }
- if (flInSingleQuote) {
- if ('\'' == c) {
- /* end of single quoted string */
- flInSingleQuote = False;
- c = -1; /* NOT extract to buffer. */
- } else
- /* others, extract all character to buffer unconditionally. */
- ;
- goto trans;
- }
- if (flBackSlash) {
- /* escape --- when just before character is backslash,
- next character is escaped. */
- flBackSlash = False;
- if ('n' == c)
- /* newline */
- c = '\n';
- if ('\n' == c)
- /* ignore newline */
- c = -1;
- else
- /* others, extract all character to buffer unconditionally. */
- ;
- goto trans;
- }
- if ('\\' == c) {
- /* set flag to escape next character. */
- flBackSlash = True;
- c = -1; /* NOT extract to buffer. */
- goto trans;
- }
- if (flInDoubleQuote) {
- if ('"' == c) {
- /* end of double quoted string */
- flInDoubleQuote = False;
- c = -1; /* NOT extract to buffer. */
- } else
- /* others, extract all character to buffer unconditionally. */
- ;
- goto trans;
- }
- if ('#' == c) {
- /* skip comment till end of line. */
- while ('\n' != c) {
- c = fgetc(is);
- if (ferror(is)) {
- fprintf(stderr,
- "truetype font property file : read error.\n");
- result = True;
- break;
- }
- if (EOF == c) {
- break;
- }
- }
- break;
- }
- if ('\'' == c) {
- /* into single quoted string */
- flInSingleQuote = True;
- c = -1; /* NOT extract to buffer. */
- goto trans;
- }
- if ('"' == c) {
- /* into double quoted string */
- flInDoubleQuote = True;
- c = -1; /* NOT extract to buffer. */
- goto trans;
- }
- if ('\n' == c)
- /* End of Line */
- break;
- if (isspace(c)) {
- /* convine multiple spaces */
- if (!flHead)
- /* except space at the head of line */
- flSpace = True;
- continue;
- }
- trans:
- /* set flHead to False, since current character is not white space
- when reaches here. */
- flHead = False;
- do {
- if (count>=LEN_LINEBUF-1) {
- /* overflow */
- fprintf(stderr,
- "truetype font property file : too long line.\n");
- result = True;
- goto quit;
- }
- if (flSpace) {
- /* just before characters is white space, but
- current character is not WS. */
- if (flFirstElement) {
- /* this spaces is the first cell(?) of white spaces. */
- flFirstElement = False;
- /* separate record name and record value */
- *buf = (char)0xff;
- } else
- *buf = ' ';
- flSpace = False;
- } else
- if (-1 != c) {
- *buf = c;
- c = -1; /* invalidate */
- } else
- /* skip */
- buf--;
- buf++;
- } while (-1 != c); /* when 'c' is not -1, it means
- that 'c' contains an untreated character. */
- }
- *buf = '\0';
-
- quit:
- return result;
-}
-
-/* parse one line */
-static Bool /* True == Error, False == Success */
-parse_one_line(SDynPropRecValList *pThisList, FILE *is)
-{
- Bool result = False;
- char *buf = NULL;
- char *recordHead, *valueHead = NULL;
-
- if (NULL == (buf = malloc(LEN_LINEBUF))) {
- fprintf(stderr,
- "truetype font property file : cannot allocate memory.\n");
- result = True;
- goto abort;
- }
- {
- recordHead = buf;
-/* refRecordValue->refRecordType = NULL;*/
- do {
- if (get_one_line(is, buf)) {
- result = True;
- goto quit;
- }
- if (feof(is)) {
- if ('\0' == *buf)
- goto quit;
- break;
- }
- } while ('\0' == *buf);
-
- if (NULL != (valueHead = strchr(buf, 0xff))) {
- *valueHead = '\0';
- valueHead++;
- } else
- valueHead = buf+strlen(buf);
-#if 0
- fprintf(stderr,
- "truetype font property file : \n"
- "recName:\"%s\"\nvalue:\"%s\"\n",
- recordHead, valueHead);
-#endif
- result = SPropRecValList_add_record(pThisList, recordHead, valueHead);
- }
- quit:
- free(buf);
- abort:
- return result;
-}
-
-/* Read Property File */
-Bool /* True == Error, False == Success */
-SPropRecValList_read_prop_file(SDynPropRecValList *pThisList,
- char const * const strFileName)
-{
- Bool result = False;
- FILE *is;
-
-#if 1
- if (!strcmp(strFileName, "-"))
- is = stdin;
- else
-#endif
- is = fopen(strFileName, "r");
- if (NULL == is) {
- fprintf(stderr, "truetype font property : cannot open file %s.\n",
- strFileName);
- result = True;
- goto abort;
- }
- {
- for (;;) {
- if (False != (result = parse_one_line(pThisList, is)))
- goto quit;
- if (feof(is))
- break;
- }
- }
- quit:
-#if 1
- if (strcmp(strFileName, "-"))
-#endif
- fclose(is);
- abort:
- return result;
-}
-#endif /* USE_TTP_FILE */
-
-/* Constructor for Container Node */
-Bool /* True == Error, False == Success */
-SPropRecValList_new(SDynPropRecValList *pThisList)
-{
- Bool result = False;
-
- pThisList->headNode = NULL;
-
- return result;
-}
-
-#ifdef DUMP
-void
-SPropRecValList_dump(SRefPropRecValList *pThisList)
-{
- SPropRecValListNodeP *p;
- for (p=pThisList->headNode; NULL!=p; p=p->nextNode) {
- switch (p->containerE.refRecordType->recordType) {
- case eRecTypeInteger:
- fprintf(stderr, "%s = %d\n",
- p->containerE.refRecordType->strRecordName,
- p->containerE.uValue.integerValue);
- break;
- case eRecTypeDouble:
- fprintf(stderr, "%s = %f\n",
- p->containerE.refRecordType->strRecordName,
- p->containerE.uValue.doubleValue);
- break;
- case eRecTypeBool:
- fprintf(stderr, "%s = %s\n",
- p->containerE.refRecordType->strRecordName,
- p->containerE.uValue.boolValue
- ? "True":"False");
- break;
- case eRecTypeString:
- fprintf(stderr, "%s = \"%s\"\n",
- p->containerE.refRecordType->strRecordName,
- p->containerE.uValue.dynStringValue);
- break;
- case eRecTypeVoid:
- fprintf(stderr, "%s = void\n",
- p->containerE.refRecordType->strRecordName);
- break;
- }
- }
-}
-#endif
-
-
-/* Search Property Record */
-Bool /* True == Hit, False == Miss */
-SPropRecValList_search_record(SRefPropRecValList *pThisList,
- SPropRecValContainer *refRecValue,
- char const * const recordName)
-{
- Bool result = False;
- SPropRecValListNodeP *p;
-
- *refRecValue = NULL;
- for (p=pThisList->headNode; NULL!=p; p=p->nextNode) {
- if (!strcasecmp(p->containerE.refRecordType->strRecordName,
- recordName)) {
- *refRecValue = &p->containerE;
- result = True;
- break;
- }
- }
-
- return result;
-}
-
-
-/* Parse TTCap */
-Bool /* True == Error, False == Success */
-SPropRecValList_add_by_font_cap(SDynPropRecValList *pThisList,
- char const *strCapHead)
-{
- Bool result = False;
- /* SPropertyRecord const *refRecordType; */
- char const *term;
-
- if (NULL == (term = strrchr(strCapHead, ':')))
- goto abort;
-
- {
- /* for xfsft compatible */
- char const *p;
- for (p=term-1; p>=strCapHead; p--) {
- if ( ':'==*p ) {
- /*
- * :num:filename
- * ^p ^term
- */
- if ( p!=term ) {
- int len = term-p-1;
- char *value;
-
- len = term-p-1;
- value=malloc(len+1);
- memcpy(value, p+1, len);
- value[len]='\0';
- SPropRecValList_add_record(pThisList,
- "FaceNumber",
- value);
- free(value);
- term=p;
- }
- break;
- }
- if ( !isdigit(*p) )
- break;
- }
- }
-
- while (strCapHead<term) {
- int i;
- char const *nextColon = strchr(strCapHead, ':');
- if (0<nextColon-strCapHead) {
- char *duplicated = malloc((nextColon-strCapHead)+1);
- {
- char *value;
-
- memcpy(duplicated, strCapHead, nextColon-strCapHead);
- duplicated[nextColon-strCapHead] = '\0';
- if (NULL != (value=strchr(duplicated, '='))) {
- *value = '\0';
- value++;
- } else
- value = &duplicated[nextColon-strCapHead];
-
- for (i=0; i<numOfCorrespondRelations; i++) {
- if (!strcasecmp(correspondRelations[i].capVariable,
- duplicated)) {
- if (SPropRecValList_add_record(pThisList,
- correspondRelations[i]
- .recordName,
- value))
- break;
- goto next;
- }
- }
- fprintf(stderr, "truetype font : Illegal Font Cap.\n");
- result = True;
- break;
- next:
- ;
- }
- free(duplicated);
- }
- strCapHead = nextColon+1;
- }
-
- /* quit: */
- abort:
- return result;
-}
-
-
-/**************************************************************************
- Functions (xttmisc)
- */
-
-/* strdup clone with using the allocator of X server */
-char *
-XttXstrdup(char const *str)
-{
- char *result;
-
- result = malloc(strlen(str)+1);
-
- if (result)
- strcpy(result, str);
-
- return result;
-}
-
-
-/* end of file */
+/* ===EmacsMode: -*- Mode: C; tab-width:4; c-basic-offset: 4; -*- === */
+/* ===FileName: ===
+ Copyright (c) 1998 Takuya SHIOZAKI, All Rights reserved.
+ Copyright (c) 1998 X-TrueType Server Project, All rights reserved.
+ Copyright (c) 2003 After X-TT Project, All rights reserved.
+
+===Notice
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions
+ are met:
+ 1. Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ 2. Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+
+ THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ SUCH DAMAGE.
+
+ Major Release ID: X-TrueType Server Version 1.4 [Charles's Wain Release 0]
+
+Notice===
+ */
+
+/*
+#include "xttversion.h"
+
+static char const * const releaseID =
+ _XTT_RELEASE_NAME;
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include <X11/fonts/fontmisc.h>
+#include <string.h>
+#include <ctype.h>
+#include <math.h>
+
+#ifndef True
+#define True (-1)
+#endif /* True */
+#ifndef False
+#define False (0)
+#endif /* False */
+
+#include "xttcap.h"
+
+
+/**************************************************************************
+ Private Data Types
+ */
+
+/* Property Record List */
+/* List Node */
+typedef struct TagSPropRecValListNodeP
+{
+ SPropRecValContainerEntityP containerE;
+ struct TagSPropRecValListNodeP *nextNode;
+} SPropRecValListNodeP;
+
+
+/**************************************************************************
+ Tables
+ */
+
+/* valid record field */
+static SPropertyRecord const validRecords[] =
+{
+ { "FontFile", eRecTypeString },
+ { "FaceNumber", eRecTypeString },
+ { "AutoItalic", eRecTypeDouble },
+ { "DoubleStrike", eRecTypeString },
+ { "FontProperties", eRecTypeBool },
+ { "ForceSpacing", eRecTypeString },
+ { "ScaleBBoxWidth", eRecTypeString },
+ { "ScaleWidth", eRecTypeDouble },
+ { "EncodingOptions", eRecTypeString },
+ { "Hinting", eRecTypeBool },
+ { "VeryLazyMetrics", eRecTypeBool },
+ { "CodeRange", eRecTypeString },
+ { "EmbeddedBitmap", eRecTypeString },
+ { "VeryLazyBitmapWidthScale", eRecTypeDouble },
+ { "ForceConstantSpacingCodeRange", eRecTypeString },
+ { "ForceConstantSpacingMetrics", eRecTypeString },
+ { "Dummy", eRecTypeVoid }
+};
+static int const
+numOfValidRecords = sizeof(validRecords)/sizeof(validRecords[0]);
+
+/* correspondence between record name and cap variable name */
+static struct {
+ char const * capVariable;
+ char const * recordName;
+} const correspondRelations[] = {
+ { "fn", "FaceNumber" },
+ { "ai", "AutoItalic" },
+ { "ds", "DoubleStrike" },
+ { "fp", "FontProperties" },
+ { "fs", "ForceSpacing" },
+ { "bw", "ScaleBBoxWidth" },
+ { "sw", "ScaleWidth" },
+ { "eo", "EncodingOptions" },
+ { "vl", "VeryLazyMetrics" },
+ { "bs", "VeryLazyBitmapWidthScale" },
+ { "cr", "CodeRange" },
+ { "eb", "EmbeddedBitmap" },
+ { "hi", "Hinting" },
+ { "fc", "ForceConstantSpacingCodeRange" },
+ { "fm", "ForceConstantSpacingMetrics" }
+};
+static int const
+numOfCorrespondRelations
+= sizeof(correspondRelations)/sizeof(correspondRelations[0]);
+
+/**************************************************************************
+ Functions
+ */
+
+/* get property record type by record name */
+static Bool /* True == Found, False == Not Found */
+get_record_type_by_name(SPropertyRecord const ** const refRefRecord, /*result*/
+ char const *strName)
+{
+ Bool result = False;
+ int i;
+
+ *refRefRecord = NULL;
+ for (i=0; i<numOfValidRecords; i++) {
+ if (!strcasecmp(validRecords[i].strRecordName, strName)) {
+ result = True;
+ *refRefRecord = &validRecords[i];
+ break;
+ }
+ }
+
+ return result;
+}
+
+/* Add Property Record Value */
+static Bool /* True == Error, False == Success */
+SPropRecValList_add_record(SDynPropRecValList *pThisList,
+ char const * const recordName,
+ char const * const strValue)
+{
+ Bool result = False;
+ SPropRecValContainerEntityP tmpContainerE;
+
+ if (get_record_type_by_name(&tmpContainerE.refRecordType, recordName)) {
+ switch (tmpContainerE.refRecordType->recordType) {
+ case eRecTypeInteger:
+ {
+ int val;
+ char *endPtr;
+
+ val = strtol(strValue, &endPtr, 0);
+ if ('\0' != *endPtr) {
+ fprintf(stderr,
+ "truetype font property : "
+ "%s record needs integer value.\n",
+ recordName);
+ result = True;
+ goto quit;
+ }
+ SPropContainer_value_int(&tmpContainerE) = val;
+ }
+ break;
+ case eRecTypeDouble:
+ {
+ double val;
+ char *endPtr;
+
+ val = strtod(strValue, &endPtr);
+ if ('\0' != *endPtr) {
+ fprintf(stderr,
+ "truetype font property : "
+ "%s record needs floating point value.\n",
+ recordName);
+ result = True;
+ goto quit;
+ }
+ SPropContainer_value_dbl(&tmpContainerE) = val;
+ }
+ break;
+ case eRecTypeBool:
+ {
+ Bool val;
+
+ if (!strcasecmp(strValue, "yes"))
+ val = True;
+ else if (!strcasecmp(strValue, "y"))
+ val = True;
+ else if (!strcasecmp(strValue, "on"))
+ val = True;
+ else if (!strcasecmp(strValue, "true"))
+ val = True;
+ else if (!strcasecmp(strValue, "t"))
+ val = True;
+ else if (!strcasecmp(strValue, "ok"))
+ val = True;
+ else if (!strcasecmp(strValue, "no"))
+ val = False;
+ else if (!strcasecmp(strValue, "n"))
+ val = False;
+ else if (!strcasecmp(strValue, "off"))
+ val = False;
+ else if (!strcasecmp(strValue, "false"))
+ val = False;
+ else if (!strcasecmp(strValue, "f"))
+ val = False;
+ else if (!strcasecmp(strValue, "bad"))
+ val = False;
+ else {
+ fprintf(stderr,
+ "truetype font property : "
+ "%s record needs boolean value.\n",
+ recordName);
+ result = True;
+ goto quit;
+ }
+ SPropContainer_value_bool(&tmpContainerE) = val;
+ }
+ break;
+ case eRecTypeString:
+ {
+ char *p;
+
+ if (NULL == (p = malloc(strlen(strValue)+1))) {
+ fprintf(stderr,
+ "truetype font property : "
+ "cannot allocate memory.\n");
+ result = True;
+ goto quit;
+ }
+ strcpy(p, strValue);
+ SPropContainer_value_str(&tmpContainerE) = p;
+ }
+ break;
+ case eRecTypeVoid:
+ if ('\0' != *strValue) {
+ fprintf(stderr,
+ "truetype font property : "
+ "%s record needs void.\n", recordName);
+ result = True;
+ }
+ break;
+ }
+ {
+ /* add to list */
+ SPropRecValListNodeP *newNode;
+
+ if (NULL == (newNode = malloc(sizeof(*newNode)))) {
+ fprintf(stderr,
+ "truetype font property : "
+ "cannot allocate memory.\n");
+ result = True;
+ goto quit;
+ }
+ newNode->nextNode = pThisList->headNode;
+ newNode->containerE = tmpContainerE;
+ tmpContainerE.refRecordType = NULL; /* invalidate --
+ disown value handle. */
+ pThisList->headNode = newNode;
+ }
+ } else {
+ /* invalid record name */
+ fprintf(stderr,
+ "truetype font : "
+ "invalid record name \"%s.\"\n", recordName);
+ result = True;
+ }
+
+ quit:
+ return result;
+}
+
+#ifdef USE_TTP_FILE
+
+#ifndef LEN_LINEBUF
+#define LEN_LINEBUF 2048
+#endif /* !def LEN_LINEBUF */
+
+/* get one line */
+static Bool /* True == Error, False == Success */
+get_one_line(FILE *is, char *buf)
+{
+ Bool result = False;
+ int count = 0;
+ Bool flHead = True;
+ Bool flSpace = False;
+ Bool flInSingleQuote = False;
+ Bool flInDoubleQuote = False;
+ Bool flBackSlash = False;
+ Bool flFirstElement = True;
+
+ *buf = '\0';
+ for (;;) {
+ int c = fgetc(is);
+
+ if (ferror(is)) {
+ fprintf(stderr, "truetype font property file : read error.\n");
+ result = True;
+ break;
+ }
+
+ if (EOF == c) {
+ if (flInSingleQuote || flInDoubleQuote) {
+ fprintf(stderr,
+ "truetype font property file : unmatched quote.\n");
+ result = True;
+ }
+ break;
+ }
+ if (flInSingleQuote) {
+ if ('\'' == c) {
+ /* end of single quoted string */
+ flInSingleQuote = False;
+ c = -1; /* NOT extract to buffer. */
+ } else
+ /* others, extract all character to buffer unconditionally. */
+ ;
+ goto trans;
+ }
+ if (flBackSlash) {
+ /* escape --- when just before character is backslash,
+ next character is escaped. */
+ flBackSlash = False;
+ if ('n' == c)
+ /* newline */
+ c = '\n';
+ if ('\n' == c)
+ /* ignore newline */
+ c = -1;
+ else
+ /* others, extract all character to buffer unconditionally. */
+ ;
+ goto trans;
+ }
+ if ('\\' == c) {
+ /* set flag to escape next character. */
+ flBackSlash = True;
+ c = -1; /* NOT extract to buffer. */
+ goto trans;
+ }
+ if (flInDoubleQuote) {
+ if ('"' == c) {
+ /* end of double quoted string */
+ flInDoubleQuote = False;
+ c = -1; /* NOT extract to buffer. */
+ } else
+ /* others, extract all character to buffer unconditionally. */
+ ;
+ goto trans;
+ }
+ if ('#' == c) {
+ /* skip comment till end of line. */
+ while ('\n' != c) {
+ c = fgetc(is);
+ if (ferror(is)) {
+ fprintf(stderr,
+ "truetype font property file : read error.\n");
+ result = True;
+ break;
+ }
+ if (EOF == c) {
+ break;
+ }
+ }
+ break;
+ }
+ if ('\'' == c) {
+ /* into single quoted string */
+ flInSingleQuote = True;
+ c = -1; /* NOT extract to buffer. */
+ goto trans;
+ }
+ if ('"' == c) {
+ /* into double quoted string */
+ flInDoubleQuote = True;
+ c = -1; /* NOT extract to buffer. */
+ goto trans;
+ }
+ if ('\n' == c)
+ /* End of Line */
+ break;
+ if (isspace(c)) {
+ /* convine multiple spaces */
+ if (!flHead)
+ /* except space at the head of line */
+ flSpace = True;
+ continue;
+ }
+ trans:
+ /* set flHead to False, since current character is not white space
+ when reaches here. */
+ flHead = False;
+ do {
+ if (count>=LEN_LINEBUF-1) {
+ /* overflow */
+ fprintf(stderr,
+ "truetype font property file : too long line.\n");
+ result = True;
+ goto quit;
+ }
+ if (flSpace) {
+ /* just before characters is white space, but
+ current character is not WS. */
+ if (flFirstElement) {
+ /* this spaces is the first cell(?) of white spaces. */
+ flFirstElement = False;
+ /* separate record name and record value */
+ *buf = (char)0xff;
+ } else
+ *buf = ' ';
+ flSpace = False;
+ } else
+ if (-1 != c) {
+ *buf = c;
+ c = -1; /* invalidate */
+ } else
+ /* skip */
+ buf--;
+ buf++;
+ } while (-1 != c); /* when 'c' is not -1, it means
+ that 'c' contains an untreated character. */
+ }
+ *buf = '\0';
+
+ quit:
+ return result;
+}
+
+/* parse one line */
+static Bool /* True == Error, False == Success */
+parse_one_line(SDynPropRecValList *pThisList, FILE *is)
+{
+ Bool result = False;
+ char *buf = NULL;
+ char *recordHead, *valueHead = NULL;
+
+ if (NULL == (buf = malloc(LEN_LINEBUF))) {
+ fprintf(stderr,
+ "truetype font property file : cannot allocate memory.\n");
+ result = True;
+ goto abort;
+ }
+ {
+ recordHead = buf;
+/* refRecordValue->refRecordType = NULL;*/
+ do {
+ if (get_one_line(is, buf)) {
+ result = True;
+ goto quit;
+ }
+ if (feof(is)) {
+ if ('\0' == *buf)
+ goto quit;
+ break;
+ }
+ } while ('\0' == *buf);
+
+ if (NULL != (valueHead = strchr(buf, 0xff))) {
+ *valueHead = '\0';
+ valueHead++;
+ } else
+ valueHead = buf+strlen(buf);
+#if 0
+ fprintf(stderr,
+ "truetype font property file : \n"
+ "recName:\"%s\"\nvalue:\"%s\"\n",
+ recordHead, valueHead);
+#endif
+ result = SPropRecValList_add_record(pThisList, recordHead, valueHead);
+ }
+ quit:
+ free(buf);
+ abort:
+ return result;
+}
+
+/* Read Property File */
+Bool /* True == Error, False == Success */
+SPropRecValList_read_prop_file(SDynPropRecValList *pThisList,
+ char const * const strFileName)
+{
+ Bool result = False;
+ FILE *is;
+
+#if 1
+ if (!strcmp(strFileName, "-"))
+ is = stdin;
+ else
+#endif
+ is = fopen(strFileName, "r");
+ if (NULL == is) {
+ fprintf(stderr, "truetype font property : cannot open file %s.\n",
+ strFileName);
+ result = True;
+ goto abort;
+ }
+ {
+ for (;;) {
+ if (False != (result = parse_one_line(pThisList, is)))
+ goto quit;
+ if (feof(is))
+ break;
+ }
+ }
+ quit:
+#if 1
+ if (strcmp(strFileName, "-"))
+#endif
+ fclose(is);
+ abort:
+ return result;
+}
+#endif /* USE_TTP_FILE */
+
+/* Constructor for Container Node */
+Bool /* True == Error, False == Success */
+SPropRecValList_new(SDynPropRecValList *pThisList)
+{
+ Bool result = False;
+
+ pThisList->headNode = NULL;
+
+ return result;
+}
+
+#ifdef DUMP
+void
+SPropRecValList_dump(SRefPropRecValList *pThisList)
+{
+ SPropRecValListNodeP *p;
+ for (p=pThisList->headNode; NULL!=p; p=p->nextNode) {
+ switch (p->containerE.refRecordType->recordType) {
+ case eRecTypeInteger:
+ fprintf(stderr, "%s = %d\n",
+ p->containerE.refRecordType->strRecordName,
+ p->containerE.uValue.integerValue);
+ break;
+ case eRecTypeDouble:
+ fprintf(stderr, "%s = %f\n",
+ p->containerE.refRecordType->strRecordName,
+ p->containerE.uValue.doubleValue);
+ break;
+ case eRecTypeBool:
+ fprintf(stderr, "%s = %s\n",
+ p->containerE.refRecordType->strRecordName,
+ p->containerE.uValue.boolValue
+ ? "True":"False");
+ break;
+ case eRecTypeString:
+ fprintf(stderr, "%s = \"%s\"\n",
+ p->containerE.refRecordType->strRecordName,
+ p->containerE.uValue.dynStringValue);
+ break;
+ case eRecTypeVoid:
+ fprintf(stderr, "%s = void\n",
+ p->containerE.refRecordType->strRecordName);
+ break;
+ }
+ }
+}
+#endif
+
+
+/* Search Property Record */
+Bool /* True == Hit, False == Miss */
+SPropRecValList_search_record(SRefPropRecValList *pThisList,
+ SPropRecValContainer *refRecValue,
+ char const * const recordName)
+{
+ Bool result = False;
+ SPropRecValListNodeP *p;
+
+ *refRecValue = NULL;
+ for (p=pThisList->headNode; NULL!=p; p=p->nextNode) {
+ if (!strcasecmp(p->containerE.refRecordType->strRecordName,
+ recordName)) {
+ *refRecValue = &p->containerE;
+ result = True;
+ break;
+ }
+ }
+
+ return result;
+}
+
+
+/* Parse TTCap */
+Bool /* True == Error, False == Success */
+SPropRecValList_add_by_font_cap(SDynPropRecValList *pThisList,
+ char const *strCapHead)
+{
+ Bool result = False;
+ /* SPropertyRecord const *refRecordType; */
+ char const *term;
+
+ if (NULL == (term = strrchr(strCapHead, ':')))
+ goto abort;
+
+ {
+ /* for xfsft compatible */
+ char const *p;
+ for (p=term-1; p>=strCapHead; p--) {
+ if ( ':'==*p ) {
+ /*
+ * :num:filename
+ * ^p ^term
+ */
+ if ( p!=term ) {
+ int len = term-p-1;
+ char *value;
+
+ len = term-p-1;
+ value=malloc(len+1);
+ memcpy(value, p+1, len);
+ value[len]='\0';
+ SPropRecValList_add_record(pThisList,
+ "FaceNumber",
+ value);
+ free(value);
+ term=p;
+ }
+ break;
+ }
+ if ( !isdigit(*p) )
+ break;
+ }
+ }
+
+ while (strCapHead<term) {
+ int i;
+ char const *nextColon = strchr(strCapHead, ':');
+ if (0<nextColon-strCapHead) {
+ char *duplicated = malloc((nextColon-strCapHead)+1);
+ {
+ char *value;
+
+ memcpy(duplicated, strCapHead, nextColon-strCapHead);
+ duplicated[nextColon-strCapHead] = '\0';
+ if (NULL != (value=strchr(duplicated, '='))) {
+ *value = '\0';
+ value++;
+ } else
+ value = &duplicated[nextColon-strCapHead];
+
+ for (i=0; i<numOfCorrespondRelations; i++) {
+ if (!strcasecmp(correspondRelations[i].capVariable,
+ duplicated)) {
+ if (SPropRecValList_add_record(pThisList,
+ correspondRelations[i]
+ .recordName,
+ value))
+ break;
+ goto next;
+ }
+ }
+ fprintf(stderr, "truetype font : Illegal Font Cap.\n");
+ result = True;
+ break;
+ next:
+ ;
+ }
+ free(duplicated);
+ }
+ strCapHead = nextColon+1;
+ }
+
+ /* quit: */
+ abort:
+ return result;
+}
+
+
+/**************************************************************************
+ Functions (xttmisc)
+ */
+
+/* strdup clone with using the allocator of X server */
+char *
+XttXstrdup(char const *str)
+{
+ char *result;
+
+ result = malloc(strlen(str)+1);
+
+ if (result)
+ strcpy(result, str);
+
+ return result;
+}
+
+
+/* end of file */
diff --git a/libXfont/src/FreeType/xttcap.h b/libXfont/src/FreeType/xttcap.h
index e91e5232a..480a623ca 100644
--- a/libXfont/src/FreeType/xttcap.h
+++ b/libXfont/src/FreeType/xttcap.h
@@ -1,131 +1,130 @@
-/* ===EmacsMode: -*- Mode: C; tab-width:4; c-basic-offset: 4; -*- === */
-/* ===FileName: ===
- Copyright (c) 1998 Takuya SHIOZAKI, All Rights reserved.
- Copyright (c) 1998 X-TrueType Server Project, All rights reserved.
- Copyright (c) 2003 After X-TT Project, All rights reserved.
-
-===Notice
- Redistribution and use in source and binary forms, with or without
- modification, are permitted provided that the following conditions
- are met:
- 1. Redistributions of source code must retain the above copyright
- notice, this list of conditions and the following disclaimer.
- 2. Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in the
- documentation and/or other materials provided with the distribution.
-
- THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
- ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
- FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- SUCH DAMAGE.
-
- Major Release ID: X-TrueType Server Version 1.3 [Aoi MATSUBARA Release 3]
-
-Notice===
- */
-/* $XFree86: xc/extras/X-TrueType/xttcap.h,v 1.2 2001/08/01 00:44:33 tsi Exp $ */
-
-#ifndef _XTTCAP_H_
-#define _XTTCAP_H_ (1)
-
-#include <X11/Xdefs.h>
-
-/*******************************************************************
- Data Types
- */
-
-/* Record Type */
-typedef enum
-{
- eRecTypeInteger,
- eRecTypeDouble,
- eRecTypeBool,
- eRecTypeString,
- eRecTypeVoid=-1
-} ERecType;
-
-/* Record Name vs Record Type */
-typedef struct
-{
- char const *strRecordName;
- ERecType const recordType;
-} SPropertyRecord;
-
-/* Record Value Container */
-typedef struct
-{
- SPropertyRecord const *refRecordType;
- union {
- int integerValue;
- double doubleValue;
- Bool boolValue;
- char *dynStringValue;
- } uValue;
-} SPropRecValContainerEntityP, *SPropRecValContainer;
-
-/* Record Value List */
-typedef struct TagSPropRecValListNodeP SPropRecValListNode;
-typedef struct
-{
- SPropRecValListNode *headNode;
-} SDynPropRecValList;
-typedef SDynPropRecValList const SRefPropRecValList;
-
-
-/*******************************************************************
- Functions
- */
-
-/* Constructor for Rec Val List */
-extern Bool /* True == Error, False == Success */
-SPropRecValList_new(SDynPropRecValList *pThisList);
-/* Destructor for Rec Val List */
-extern Bool /* True == Error, False == Success */
-SPropRecValList_delete(SDynPropRecValList *pThisList);
-/* Read Property File */
-extern Bool /* True == Error, False == Success */
-SPropRecValList_read_prop_file(SDynPropRecValList *pThisList,
- char const * const strFileName);
-/* Search Property Record */
-extern Bool /* True == Hit, False == Miss */
-SPropRecValList_search_record(SRefPropRecValList *pThisList,
- SPropRecValContainer *refContRecVal,
- char const * const recordName);
-/* Add by Font Cap */
-extern Bool /* True == Error, False == Success */
-SPropRecValList_add_by_font_cap(SDynPropRecValList *pThisList,
- char const *strCapHead);
-
-#ifdef DUMP
-void
-SPropRecValList_dump(SRefPropRecValList *refList);
-#endif
-
-#define SPropContainer_value_int(contRecVal)\
- ((contRecVal)->uValue.integerValue)
-#define SPropContainer_value_dbl(contRecVal)\
- ((contRecVal)->uValue.doubleValue)
-#define SPropContainer_value_bool(contRecVal)\
- ((contRecVal)->uValue.boolValue)
-#define SPropContainer_value_str(contRecVal)\
- ((contRecVal)->uValue.dynStringValue)
-
-/******************************************************
- Prototypes (xttmisc)
- */
-
-/* strdup clone */
-char * XttXstrdup(char const *str);
-#undef xstrdup
-#define xstrdup(s) XttXstrdup((char const*)s)
-
-#endif /* !def _XTTCAP_H_ */
-
-/* end of file */
+/* ===EmacsMode: -*- Mode: C; tab-width:4; c-basic-offset: 4; -*- === */
+/* ===FileName: ===
+ Copyright (c) 1998 Takuya SHIOZAKI, All Rights reserved.
+ Copyright (c) 1998 X-TrueType Server Project, All rights reserved.
+ Copyright (c) 2003 After X-TT Project, All rights reserved.
+
+===Notice
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions
+ are met:
+ 1. Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ 2. Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+
+ THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ SUCH DAMAGE.
+
+ Major Release ID: X-TrueType Server Version 1.3 [Aoi MATSUBARA Release 3]
+
+Notice===
+ */
+
+#ifndef _XTTCAP_H_
+#define _XTTCAP_H_ (1)
+
+#include <X11/Xdefs.h>
+
+/*******************************************************************
+ Data Types
+ */
+
+/* Record Type */
+typedef enum
+{
+ eRecTypeInteger,
+ eRecTypeDouble,
+ eRecTypeBool,
+ eRecTypeString,
+ eRecTypeVoid=-1
+} ERecType;
+
+/* Record Name vs Record Type */
+typedef struct
+{
+ char const *strRecordName;
+ ERecType const recordType;
+} SPropertyRecord;
+
+/* Record Value Container */
+typedef struct
+{
+ SPropertyRecord const *refRecordType;
+ union {
+ int integerValue;
+ double doubleValue;
+ Bool boolValue;
+ char *dynStringValue;
+ } uValue;
+} SPropRecValContainerEntityP, *SPropRecValContainer;
+
+/* Record Value List */
+typedef struct TagSPropRecValListNodeP SPropRecValListNode;
+typedef struct
+{
+ SPropRecValListNode *headNode;
+} SDynPropRecValList;
+typedef SDynPropRecValList const SRefPropRecValList;
+
+
+/*******************************************************************
+ Functions
+ */
+
+/* Constructor for Rec Val List */
+extern Bool /* True == Error, False == Success */
+SPropRecValList_new(SDynPropRecValList *pThisList);
+/* Destructor for Rec Val List */
+extern Bool /* True == Error, False == Success */
+SPropRecValList_delete(SDynPropRecValList *pThisList);
+/* Read Property File */
+extern Bool /* True == Error, False == Success */
+SPropRecValList_read_prop_file(SDynPropRecValList *pThisList,
+ char const * const strFileName);
+/* Search Property Record */
+extern Bool /* True == Hit, False == Miss */
+SPropRecValList_search_record(SRefPropRecValList *pThisList,
+ SPropRecValContainer *refContRecVal,
+ char const * const recordName);
+/* Add by Font Cap */
+extern Bool /* True == Error, False == Success */
+SPropRecValList_add_by_font_cap(SDynPropRecValList *pThisList,
+ char const *strCapHead);
+
+#ifdef DUMP
+void
+SPropRecValList_dump(SRefPropRecValList *refList);
+#endif
+
+#define SPropContainer_value_int(contRecVal)\
+ ((contRecVal)->uValue.integerValue)
+#define SPropContainer_value_dbl(contRecVal)\
+ ((contRecVal)->uValue.doubleValue)
+#define SPropContainer_value_bool(contRecVal)\
+ ((contRecVal)->uValue.boolValue)
+#define SPropContainer_value_str(contRecVal)\
+ ((contRecVal)->uValue.dynStringValue)
+
+/******************************************************
+ Prototypes (xttmisc)
+ */
+
+/* strdup clone */
+char * XttXstrdup(char const *str);
+#undef xstrdup
+#define xstrdup(s) XttXstrdup((char const*)s)
+
+#endif /* !def _XTTCAP_H_ */
+
+/* end of file */